/* ORSI.digital — a thin theme layer on top of Bootstrap (plan 2.2). No
   embedded <style> block per screen: every screen uses these shared
   classes instead of inventing its own CSS (that was exactly the DNN
   pitfall). */

:root,
[data-bs-theme="light"] {
    
    
    
    
    
    
    

    /* Bootstrap variables overridden with the ORSI tokens, so the
       ready-made Bootstrap components (buttons, badges, tabs, ...) are
       immediately recognizable as ORSI without having to restyle each
       component individually. */
    --bs-primary: var(--orsi-blue);
    --bs-primary-rgb: 1, 125, 197;
    --bs-body-font-family: "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
    --bs-link-color: var(--orsi-blue);
    --bs-link-hover-color: var(--orsi-deep);
    --bs-body-color: var(--orsi-ink);
    --bs-border-color: var(--orsi-line);
}

body {
    margin: 0;
    background: var(--orsi-surface);
    color: var(--orsi-ink);
}

/* ---- Point 12 (UI changes batch, 10 August 2026): font consistency ----
   Dirk's example ("Lock until previous unit is complete" vs. the
   Owner dropdown next to it) turned out, on investigation, not to be an
   isolated one-off on that single element, but a structural pattern: almost
   every input field on these screens uses Bootstrap's smaller -sm variant
   (form-control-sm/form-select-sm, font-size 0.875rem), while the caption
   next to it (.form-label/.form-check-label) never has its own font-size
   and so stays at Bootstrap's default size (1rem) - hence the noticeable
   difference. Fixed at the same 0.875rem as the -sm fields, so labels and
   fields look consistent everywhere. The separate font-size rules further
   down in this file (badges, tags, breadcrumb, navigation, etc.) are
   deliberately left untouched - those are different kinds of UI chrome
   that are rightly smaller than body/field text, not an inconsistency of
   the same element. */
:root,
[data-bs-theme="light"] {
    --orsi-form-text-size: 0.875rem;
}
.form-label,
.form-check-label {
    font-size: var(--orsi-form-text-size);
}

/* The ValidationSummaryTagHelper always renders the <div>, even without
   errors (class "validation-summary-valid" instead of
   "validation-summary-errors") - without this rule, every clean form would
   show an empty red bar. */
.validation-summary-valid {
    display: none;
}

/* ---- Accessibility: skip link + visible focus (WCAG 2.2 AA, plan 2.2) ---- */
.orsi-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 2000;
    background: var(--orsi-deep);
    color: var(--orsi-card);
    padding: 0.6rem 1rem;
    border-radius: 0 0 6px 0;
}
.orsi-skip-link:focus {
    left: 0;
}
:focus-visible {
    outline: 3px solid var(--orsi-orange);
    outline-offset: 2px;
}

/* ---- Anonymous screen (login) — no shell, just a centered card ---- */
.orsi-anon-main {
    min-height: 100vh;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    background: var(--orsi-surface);
}

/* ---- Shell: sidebar + main area ---- */
.orsi-shell {
    display: flex;
    min-height: 100vh;
}

.orsi-sidebar-backdrop {
    display: none;
}

/* Point 9 (UI changes batch, 10 August 2026): "the menu should stay fixed
   instead of scrolling along with the page; if the menu doesn't fit on a
   screen it should stay scrollable within the menu" - the sidebar used
   to be a plain flex item in .orsi-shell's row, so on a tall page it simply
   stretched (via the row's default align-items: stretch) to the row's full
   height instead of staying pinned to the viewport, and .orsi-sidebar__nav's
   own "flex: 1; overflow-y: auto" never actually kicked in because the
   column always had as much height as it needed. Fixed by taking the sidebar
   out of the flow (position: fixed, height: 100vh) - .orsi-sidebar__nav's
   existing overflow-y: auto now does what it was always meant to do. See
   .orsi-shell__main below for the matching margin-left that keeps the main
   content from sliding underneath it, and the mobile media query further
   down for how the existing off-canvas behaviour still layers on top of this. */
.orsi-sidebar {
    width: 260px;
    flex: 0 0 260px;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    height: 100vh;
    z-index: 1020;
    background: var(--orsi-deep);
    color: var(--orsi-card);
    display: flex;
    flex-direction: column;
    transition: width 0.15s ease, flex-basis 0.15s ease;
}

.orsi-sidebar__brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1rem 1.1rem;
    font-weight: var(--orsi-weight-strong);
    font-size: 1.05rem;
    border-bottom: 1px solid color-mix(in srgb, var(--orsi-card) 12.000%, transparent);
}
.orsi-sidebar__brand-group {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
    /* Point 6 (UI changes batch, 10 August 2026): now an <a>, not a <span> -
       reset the link styling so it still looks exactly like plain brand text. */
    color: inherit;
    text-decoration: none;
}
.orsi-sidebar__brand-group:hover,
.orsi-sidebar__brand-group:focus-visible {
    color: inherit;
    text-decoration: none;
}
.orsi-sidebar__brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 7px;
    background: var(--orsi-orange);
    color: var(--orsi-card);
    font-weight: var(--orsi-weight-strong);
    flex-shrink: 0;
}

/* Sidebar collapse/expand button. Used to sit next to the logo, in the
   (dark) sidebar itself - moved to the (light) topbar (Dirk, 9 August 2026
   test change: "the arrows next to OrsiDigital should be in the right pane
   above tracks") - hence the colors below matching a white background
   (var(--orsi-line)/var(--orsi-ink), the same tokens as
   .orsi-topbar__menu-btn below) instead of the previous white text/border
   on the dark sidebar background. Size (34x34) now also aligned with the
   other topbar buttons, was previously smaller (26x26) back when it sat
   among the sidebar navigation items. Two arrow icons inside it, CSS
   switches which one is visible based on .orsi-shell.is-collapsed (site.js
   only toggles the class, no separate icon-swap script needed). */
.orsi-sidebar__collapse-btn {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--orsi-line);
    border-radius: 6px;
    background: var(--orsi-card);
    color: var(--orsi-ink);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
}
.orsi-sidebar__collapse-btn:hover,
.orsi-sidebar__collapse-btn:focus-visible {
    background: var(--orsi-surface);
    color: var(--orsi-ink);
}
.orsi-sidebar__collapse-icon--expand {
    display: none;
}
.orsi-shell.is-collapsed .orsi-sidebar__collapse-icon--collapse {
    display: none;
}
.orsi-shell.is-collapsed .orsi-sidebar__collapse-icon--expand {
    display: inline;
}
/* Only relevant on desktop - on mobile, the separate #orsiNavToggle (same
   spot in the topbar) opens/closes the off-canvas menu (see site.js for the
   full explanation of why these are two separate buttons/handlers). */
@media (max-width: 991.98px) {
    .orsi-sidebar__collapse-btn {
        display: none;
    }
}

.orsi-sidebar__nav {
    flex: 1;
    overflow-y: auto;
    padding: 0.75rem 0.6rem 1rem;
}

.orsi-nav-section {
    margin-bottom: 1.1rem;
}
.orsi-nav-section__title {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    /* Contrast increased (Dirk, feedback round, point 6.1: "adjust the
       contrast of the menu font so it becomes more readable") - 0.55 was
       too faint against the --orsi-deep background. */
    color: color-mix(in srgb, var(--orsi-card) 75.000%, transparent);
    padding: 0.3rem 0.6rem;
}

.orsi-nav-link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.6rem;
    border-radius: 7px;
    /* Contrast increased, same reason as .orsi-nav-section__title above. */
    color: color-mix(in srgb, var(--orsi-card) 94.000%, transparent);
    text-decoration: none;
    font-size: 0.9rem;
    width: 100%;
    border: none;
    background: none;
    text-align: left;
    font-family: inherit;
}
.orsi-nav-link:hover,
.orsi-nav-link:focus-visible {
    background: color-mix(in srgb, var(--orsi-card) 10.000%, transparent);
    color: var(--orsi-card);
}
.orsi-nav-link.active {
    background: var(--orsi-blue);
    color: var(--orsi-card);
    font-weight: var(--orsi-weight-emphasis);
}
.orsi-nav-link--disabled {
    /* Contrast increased, same reason - 0.4 was nearly invisible. */
    color: color-mix(in srgb, var(--orsi-card) 55.000%, transparent);
    cursor: not-allowed;
}
.orsi-nav-link__icon {
    width: 1.1em;
    text-align: center;
}
.orsi-nav-link__text {
    flex: 1;
}
.orsi-nav-link__tag {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: color-mix(in srgb, var(--orsi-card) 14.000%, transparent);
    padding: 0.12rem 0.4rem;
    border-radius: 10px;
}

.orsi-shell__main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    /* Matches .orsi-sidebar's width now that it's position: fixed (see above) -
       keeps the main content from sliding underneath it. Collapsed-state
       override sits with the other .orsi-shell.is-collapsed rules below. */
    margin-left: 260px;
    transition: margin-left 0.15s ease;
}

.orsi-topbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 1.25rem;
    background: var(--orsi-card);
    border-bottom: 1px solid var(--orsi-line);
    position: sticky;
    top: 0;
    z-index: 10;
}
.orsi-topbar__menu-btn {
    border: 1px solid var(--orsi-line);
    background: var(--orsi-card);
    border-radius: 6px;
    width: 34px;
    height: 34px;
    font-size: 1rem;
    line-height: 1;
}
/* Mobile-only since the feedback round (point 6.1) - the desktop collapse
   button (.orsi-sidebar__collapse-btn, now also here in the topbar, right
   before this button - see above) occupies the same spot on desktop; only
   this hamburger button still opens the off-canvas menu on narrow screens.
   See site.js for the full explanation. */
@media (min-width: 992px) {
    .orsi-topbar__menu-btn {
        display: none;
    }
}
.orsi-topbar__spacer {
    flex: 1;
}
.orsi-topbar__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 6px;
}
.orsi-topbar__action.disabled {
    opacity: 0.35;
    cursor: not-allowed;
}
a.orsi-topbar__action {
    color: var(--orsi-ink);
    text-decoration: none;
}
a.orsi-topbar__action:hover,
a.orsi-topbar__action:focus-visible {
    background: var(--orsi-surface);
}
.orsi-topbar__install-btn {
    border: 0;
    background: transparent;
    color: var(--orsi-ink);
    cursor: pointer;
    font: inherit;
}
.orsi-topbar__install-btn:hover,
.orsi-topbar__install-btn:focus-visible {
    background: var(--orsi-surface);
}

/* Name + Log out (point 4, UI changes batch 10 August 2026) - back in the
   topbar, on the right, after the action icons. Replaces the earlier
   sidebar footer (.orsi-sidebar__footer, removed - see the note at
   .orsi-sidebar). */
/* Role-switcher control (point 3b, UI changes batch 10 August 2026) - a
   small link, same visual weight as the name next to it, not a full button
   (this is an occasional action, not a primary one). */
.orsi-topbar__active-role {
    font-size: 0.78rem;
    color: var(--orsi-muted);
    text-decoration: none;
    white-space: nowrap;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.orsi-topbar__active-role:hover,
.orsi-topbar__active-role:focus-visible {
    color: var(--orsi-blue);
}
@media (max-width: 767.98px) {
    .orsi-topbar__active-role {
        display: none;
    }
}

.orsi-topbar__user {
    padding: 0 0.3rem;
    max-width: 220px;
}
.orsi-topbar__username-text {
    display: block;
    font-size: 0.85rem;
    font-weight: var(--orsi-weight-emphasis);
    color: var(--orsi-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.orsi-topbar__logout-form {
    display: inline-flex;
}
.orsi-topbar__logout-btn {
    border: 1px solid var(--orsi-line);
    background: var(--orsi-card);
    border-radius: 6px;
    width: 34px;
    height: 34px;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
.orsi-topbar__logout-btn:hover,
.orsi-topbar__logout-btn:focus-visible {
    background: var(--orsi-surface);
}
/* On narrow screens the topbar has little room left next to the mobile menu
   button - the name text is dropped there, Log out (icon-only, already
   compact) stays. */
@media (max-width: 575.98px) {
    .orsi-topbar__user {
        display: none;
    }
}

/* Flash banners as a fixed popup (Dirk, 6 August, general remark spanning
   all screens): _FlashBanners.cshtml used to sit in the normal document
   flow at the top of the page content, so it scrolled out of view as soon
   as you scrolled down. position: fixed, centered at the top of the
   viewport, with a z-index above .orsi-topbar (which itself has
   position: sticky; z-index: 10) - that now keeps the message in view at
   all times, on every screen that includes the partial. No ancestor in the
   layout uses transform/filter (that would create its own containing block
   and break position: fixed) - only .orsi-sidebar does on mobile, and that
   is not an ancestor of the page content. */
.orsi-flash-toast-container {
    position: fixed;
    top: 1rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1080;
    width: min(560px, calc(100vw - 2rem));
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.orsi-flash-toast-container .alert {
    margin-bottom: 0;
    box-shadow: 0 8px 22px color-mix(in srgb, var(--orsi-ink) 18.000%, transparent);
}

.orsi-main {
    padding: 1.25rem 1.5rem 2.5rem;
    width: 100%;
}

.orsi-breadcrumb-nav .breadcrumb {
    font-size: 0.82rem;
    margin-bottom: 0.9rem;
}
/* Breadcrumb removed on all screens (Dirk, 6 August) - the section is
   still rendered in _Layout.cshtml (@await RenderSectionAsync stays in
   place, otherwise Razor throws a "section not rendered" error on every
   screen that defines @section Breadcrumb), but is hidden globally here
   instead of removing the @section blocks on each screen individually. */
.orsi-breadcrumb-nav {
    display: none;
}

/* ---- Collapsed (desktop icon-rail) state ---- */
.orsi-shell.is-collapsed .orsi-sidebar {
    width: 64px;
    flex-basis: 64px;
}
.orsi-shell.is-collapsed .orsi-shell__main {
    margin-left: 64px;
}
.orsi-shell.is-collapsed .orsi-sidebar__brand-text,
.orsi-shell.is-collapsed .orsi-nav-section__title,
.orsi-shell.is-collapsed .orsi-nav-link__text,
.orsi-shell.is-collapsed .orsi-nav-link__tag {
    display: none;
}

/* ---- Mobile / off-canvas ---- */
@media (max-width: 991.98px) {
    .orsi-sidebar {
        /* position: fixed and height already come from the base rule above
           (point 9) - only the off-canvas-specific bits stay here. */
        inset: 0 auto 0 0;
        z-index: 1050;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
    }
    .orsi-shell.is-nav-open .orsi-sidebar {
        transform: translateX(0);
    }
    .orsi-sidebar-backdrop {
        display: none;
        position: fixed;
        inset: 0;
        background: color-mix(in srgb, var(--orsi-ink) 45.000%, transparent);
        z-index: 1040;
    }
    .orsi-shell.is-nav-open .orsi-sidebar-backdrop {
        display: block;
    }
    /* Off-canvas on mobile - the sidebar no longer sits in the document flow
       pushing content aside, so .orsi-shell__main must not reserve space for
       it (unlike the desktop margin-left set above). */
    .orsi-shell__main {
        margin-left: 0;
    }
    .orsi-main {
        padding: 1rem 1rem 2rem;
    }
}

/* ---- Shared page patterns (2.2bis) ---- */
.orsi-page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}
.orsi-page-header__title {
    margin: 0 0 0.2rem;
}
.orsi-page-header__subtitle {
    margin: 0;
    color: var(--orsi-muted);
    font-size: 0.9rem;
}

.orsi-card {
    background: var(--orsi-card);
    border: 1px solid var(--orsi-line);
    border-radius: 10px;
}

/* Summary bar above the tabset (Track UI redesign, point 3, 8 August,
   Dirk's request: "Place above the tabs: Track details | Reference | Title
   (EN) | Status ... (pipes included)"). One line, with a vertical bar
   between each segment instead of a separate <span>|</span> each time
   (same visual result, less markup noise in Edit.cshtml). */
.orsi-summary-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    font-size: 0.85rem;
}
.orsi-summary-bar__title {
    font-weight: var(--orsi-weight-emphasis);
}
.orsi-summary-bar__sep {
    color: var(--orsi-line);
}
.orsi-summary-bar__label {
    color: var(--orsi-muted);
}
/* Program Detail heading made the same size as 'Programs' on the list
   (Dirk, 13 August 2026, point 3a) - a deliberate dedicated modifier
   instead of adjusting .orsi-summary-bar__label itself: that class is also
   used for Track/Module/Unit/Block's own small "Track"/"Module"/"Unit"/
   "Block" labels in their summary bars (Tracks/Edit.cshtml), which must
   not inherit this change. Same size/weight as .h3 (Bootstrap), the class
   that "Programs" carries on Programs/Index.cshtml. */
.orsi-summary-bar__label--heading {
    font-size: 1.75rem;
    font-weight: var(--orsi-weight-body);
}

.orsi-empty-state {
    text-align: center;
    padding: 2.5rem 1.5rem;
    color: var(--orsi-muted);
}
.orsi-empty-state__icon {
    font-size: 2rem;
    margin-bottom: 0.5rem;
}

.orsi-filterbar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}
.orsi-filterbar__search {
    flex: 1;
    min-width: 220px;
    max-width: 420px;
}

/* ---- Light list filter bar (Library → Tracks overview, pattern 1):
   status chips + owner dropdown, real server-side filtering (hides
   non-matching rows), as opposed to the dimming version on the Track
   detail screen which DOES sit on a dark background (.orsi-track-context)
   - hence a separate, light class set instead of reusing .orsi-status-chk. ---- */
.orsi-list-filters {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding-top: 0.75rem;
    margin-top: 0.75rem;
    border-top: 1px solid var(--orsi-line);
}
.orsi-list-filters__group {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}
.orsi-list-filters__label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--orsi-muted);
}
.orsi-chip-filter {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.8rem;
    background: var(--orsi-surface);
    border: 1px solid var(--orsi-line);
    border-radius: 14px;
    padding: 0.2rem 0.6rem 0.2rem 0.45rem;
    cursor: pointer;
}
.orsi-list-filters__select {
    width: auto;
    display: inline-block;
}

/* ---- Sortable column headers (same overview screen) ---- */
.orsi-sortable-col {
    color: inherit;
    text-decoration: none;
    display: inline-block;
}
.orsi-sortable-col:hover {
    color: var(--orsi-blue);
    text-decoration: underline;
}

.orsi-actionbar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding-top: 1rem;
    margin-top: 1rem;
    border-top: 1px solid var(--orsi-line);
}
.orsi-actionbar__spacer {
    flex: 1;
}
/* ---- Compact Save/Cancel bar (6 August, eighth round — Dirk's request
   "place save and cancel buttons at the top (top right) within all
   entities... only clickable once changes have actually been made";
   moved next to the tab strip in a later feedback round, point 1, see
   .orsi-block-tabs-row above - it previously sat IN the card header next
   to the title, but disappeared along with it whenever a different tab
   became active). No top border/margin like the regular .orsi-actionbar
   (which belongs at the bottom of a form) - see the generic
   [data-dirty-form] script at the bottom of Edit.cshtml for the logic
   that enables/disables the buttons. */
.orsi-actionbar--compact {
    padding-top: 0;
    margin-top: 0;
    border-top: none;
    flex-shrink: 0;
}
.orsi-card__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

/* ---- Status badge — color is never the only signal (text + dot, WCAG) ---- */
.orsi-status {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.65rem;
    border-radius: 20px;
    font-size: 0.78rem;
    font-weight: var(--orsi-weight-emphasis);
    background: var(--orsi-blue-050);
    color: var(--orsi-ink-soft);
}
.orsi-status__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
}
.orsi-status--draft { background: var(--orsi-blue-050); color: var(--orsi-muted); }
.orsi-status--review { background: var(--orsi-warning-bg); color: var(--orsi-warning-fg); }
.orsi-status--approved { background: var(--orsi-success-bg); color: var(--orsi-success-fg); }
.orsi-status--changes { background: var(--orsi-error-bg); color: var(--orsi-error-fg); }
.orsi-status--retired { background: var(--orsi-purple-050); color: var(--orsi-purple); }
.orsi-status--replaced { background: var(--orsi-disabled-bg); color: var(--orsi-ink-soft); }
.orsi-status--idea { background: var(--orsi-blue-050); color: var(--orsi-blue-700); }
.orsi-status--unknown { background: var(--orsi-blue-050); color: var(--orsi-muted); }
/* The little dot in the regular StatusBadge pill (ninth round, Dirk: "I
   also expected a dot... next to owner/status within the block") -
   .orsi-status__dot inherits currentColor by default (the same,
   deliberately muted text color above, because this component also
   appears on ~26 other screens and the pill text/background must stay
   unchanged there). Only the DOT itself gets the same saturated colors
   here as .orsi-status-icon--X (the Structure tree) and StatusInfo.Icon
   (the status dropdowns), so a given status carries the same recognizable
   color everywhere without changing the existing badge styling elsewhere. */
.orsi-status--draft .orsi-status__dot { background: var(--orsi-disabled-ink); }
.orsi-status--review .orsi-status__dot { background: var(--orsi-warning-fg); }
.orsi-status--approved .orsi-status__dot { background: var(--orsi-green-600); }
.orsi-status--changes .orsi-status__dot { background: var(--orsi-error-fg); }
.orsi-status--retired .orsi-status__dot { background: var(--orsi-purple); }
.orsi-status--replaced .orsi-status__dot { background: var(--orsi-orange-text); }
.orsi-status--idea .orsi-status__dot { background: var(--orsi-blue); }
.orsi-status--unknown .orsi-status__dot { background: var(--orsi-ink); }

/* ---- Status icon — a compact dot variant of .orsi-status, used only for
   the Structure tree (StatusIconViewComponent, 6 August, eighth round,
   Dirk's request "replace the status badge with an icon to save space").
   The title tooltip (native browser, no JS) and the .visually-hidden text
   inside the component itself carry the meaning that the dropped label
   text used to convey here.
   Colors made more vivid (ninth round, Dirk: "the colors of the dots
   aren't explicit enough") - the original version reused the same
   (deliberately muted) colors as the text of .orsi-status--X above,
   perfectly readable as text but not distinctive enough as a 9px dot. Now
   eight clearly different, saturated colors, in the same order/color
   family as StatusInfo.Icon's circle emoji in the status dropdowns
   (⚪🟠🟢🔴🟣🟤🔵⚫) - so the same status carries the same recognizable
   color everywhere (tree + dropdown). */
.orsi-status-icon {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--orsi-ink) 18.000%, transparent) inset;
}
.orsi-status-icon--draft { background: var(--orsi-disabled-ink); }
.orsi-status-icon--review { background: var(--orsi-warning-fg); }
.orsi-status-icon--approved { background: var(--orsi-green-600); }
.orsi-status-icon--changes { background: var(--orsi-error-fg); }
.orsi-status-icon--retired { background: var(--orsi-purple); }
.orsi-status-icon--replaced { background: var(--orsi-orange-text); }
.orsi-status-icon--idea { background: var(--orsi-blue); }
.orsi-status-icon--unknown { background: var(--orsi-ink); }
/* Live/Test switch (UI changes batch, 10 August 2026, point 2) - same
   colors as .orsi-status-icon--approved/--changes above (green/red already
   mean "good"/"needs attention" everywhere else on this screen), reusing
   the same 9px dot instead of inventing a second dot system. */
.orsi-status-icon--live { background: var(--orsi-green-600); }
.orsi-status-icon--test { background: var(--orsi-error-fg); }

/* Live/Test switch control on the track detail screen. */
.orsi-live-switch {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 1.6rem;
    padding-left: 2.5rem;
}
.orsi-live-switch .form-check-input {
    margin-left: -2.5rem;
}
.orsi-live-switch__label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

/* ---- Audit info block (2.2bis) ---- */
.orsi-audit__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.75rem 1.5rem;
}
.orsi-audit__label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--orsi-muted);
}
.orsi-audit__value {
    font-size: 0.88rem;
}

/* ---- Concurrency warning (2.2ter) ---- */
.orsi-concurrency {
    background: var(--orsi-warning-bg);
    border: 1px solid var(--orsi-warning-line);
    border-radius: 8px;
    padding: 0.9rem 1.1rem;
    margin-bottom: 1rem;
}
.orsi-concurrency__title {
    font-weight: var(--orsi-weight-strong);
    color: var(--orsi-warning-fg);
    margin-bottom: 0.3rem;
}
.orsi-concurrency__actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 0.6rem;
}

/* ---- Readonly note (owner gate — "everyone can see, only the responsible
   person can edit", plan section 4.1) ---- */
.orsi-readonly-note {
    background: var(--orsi-surface);
    border: 1px dashed var(--orsi-progress-todo);
    border-radius: 8px;
    padding: 0.7rem 0.9rem;
    font-size: 0.85rem;
    color: var(--orsi-ink-soft);
    margin-bottom: 1rem;
}

/* ================================================================
   Track master-detail workspace (plan section 4.1, "Track final design
   v3" — Dirk's instruction 5 August, "matching final design V3"). Fixed
   track header (tiles + dimming status/manager filter, taken directly
   from the existing DNN filter pattern) plus tree on the left/detail on
   the right, rendered by
   Pages/Library/Tracks/Edit.cshtml + wwwroot/js/track-workspace.js.
   ================================================================ */

/* Revised 6 August (Dirk's request): the previous dark gradient block
   ("busy blue block", on which the "Change owner" button became unreadable
   - gray text on blue) is gone. Header/counts/filters now use the same
   light card style (.orsi-page-header, .orsi-card,
   .orsi-list-filters/.orsi-chip-filter - reused from the Tracks overview)
   as the rest of the app. */
.orsi-count-badge {
    display: inline-flex;
    align-items: center;
    font-size: 0.72rem;
    font-weight: var(--orsi-weight-emphasis);
    color: var(--orsi-muted);
    background: var(--orsi-surface);
    border: 1px solid var(--orsi-line);
    border-radius: 20px;
    padding: 0.2rem 0.65rem;
}
.orsi-readonly-pill {
    display: inline-block;
    font-size: 0.7rem;
    background: var(--orsi-surface);
    border: 1px solid var(--orsi-line);
    color: var(--orsi-muted);
    border-radius: 20px;
    padding: 0.15rem 0.6rem;
}

/* Preview eye / magnifying-glass icon buttons (13 August 2026, Dirk's
   request: "bigger eye, eye and magnifying glass the same size everywhere
   with no border around them, reference = the magnifying glass on the
   Program screen"). .orsi-icon-btn itself had no CSS of its own until now
   - its size came purely from Bootstrap's .btn.btn-sm. This modifier
   applies only to the preview eye and the "Open" magnifying glass (not to
   the other orsi-icon-btn buttons such as edit/delete/lock, which fall
   outside this request and therefore remain unchanged). The border
   (btn-outline-secondary) has been removed separately for each of these
   links, directly in the markup. */
.orsi-icon-btn.orsi-icon-btn--preview {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    line-height: 1;
}
.orsi-icon-btn.orsi-icon-btn--preview > span:first-child {
    font-size: 1.3rem;
}

.orsi-owner-change__form {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.orsi-owner-change__form select {
    width: auto;
}
/* Reviewers tab dropdown (Track UI redesign, 8 August, Dirk's feedback:
   "make the dropdown wider") - .orsi-owner-change__form select
   { width: auto } above lets it shrink to the width of the visible option;
   this modifier gives the reviewer picker its own minimum width so that a
   long name/email doesn't look truncated either. */
.orsi-reviewer-select {
    width: auto;
    min-width: 20rem;
}

/* .orsi-status-actions/.orsi-status-actions__form (separate status button
   row at the top) are gone (Dirk, 6 August) — Status is now a dropdown in
   the card, reusing .orsi-owner-change__form above. */

/* Status/manager filter on the detail screen (the checkbox input remains
   .orsi-status-chk-input for track-workspace.js - only the surrounding
   styling applies here, no JS change needed). */
.orsi-status-chk-input {
    transform: scale(0.85);
}
.orsi-filter-clear-link {
    font-size: 0.78rem;
}

.orsi-workspace {
    display: grid;
    /* The middle column is the drag handle (point 4, Dirk's request 6
       August, "widen/narrow the structure list by dragging") -
       track-workspace.js sets the first width here inline after a drag
       gesture, and reads a previously saved width back on load
       (orsiTreePaneWidth in localStorage, not a session-/server-bound
       setting). 300px is the unchanged default width from before. */
    grid-template-columns: 300px 6px 1fr;
    min-height: 420px;
    background: var(--orsi-card);
    border: 1px solid var(--orsi-line);
    border-top: none;
    border-radius: 0 0 10px 10px;
    overflow: hidden;
    margin-bottom: 1.5rem;
}
@media (max-width: 900px) {
    .orsi-workspace {
        /* On narrow screens everything already stacks (1 column) - dragging
           has no meaning there, so the drag-handle column is dropped
           along with it. */
        grid-template-columns: 1fr;
    }
    .orsi-workspace__resizer {
        display: none;
    }
}

/* Drag handle between Structure and the detail pane (point 4, Dirk's
   request 6 August). A narrow, transparent column with a thin line inside
   it - wider and blue on hover/while dragging, so the click zone is more
   generous than just the visible line (easier to hit than a 1px border). */
.orsi-workspace__resizer {
    position: relative;
    cursor: col-resize;
    background: transparent;
    touch-action: none;
}
.orsi-workspace__resizer::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 1px;
    background: var(--orsi-line);
    transform: translateX(-50%);
}
.orsi-workspace__resizer:hover::after,
.orsi-workspace.is-resizing .orsi-workspace__resizer::after {
    width: 3px;
    background: var(--orsi-blue);
}

.orsi-tree-pane {
    /* No border-right of its own anymore - the dividing line now comes
       from .orsi-workspace__resizer between them (point 4, making it
       draggable). */
    background: var(--orsi-card);
    padding: 0.9rem 0.6rem;
    overflow-y: auto;
    min-width: 0;
}
.orsi-tree-pane__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin: 0.25rem 0.5rem 0.6rem;
}
.orsi-tree-pane__title {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--orsi-muted);
    margin: 0;
}
.orsi-tree-pane__hint {
    text-transform: none;
    font-weight: var(--orsi-weight-body);
}
.orsi-tree-pane__add-btn {
    font-size: 0.72rem;
    padding: 0;
}

/* Point 4.3 (Dirk's request 6 August, fourth round, "provide a collapse
   all / expand all"): the two buttons sit next to the "Structure" title in
   the same header row (which already has display:flex/justify-content:
   space-between, see .orsi-tree-pane__header above) - this wrapper keeps
   them together on the right with a small gap between them. */
.orsi-tree-pane__header-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-shrink: 0;
}
.orsi-tree-pane__header-actions .btn-link {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* "On this page" navigation on Help/Index (Dirk, 9 August 2026: "place the
   'on this page' the same way as on the tracks screen (structure pane)")
   - to the left of the content, just like .orsi-tree-pane on the Track
   workspace above. Deliberately a separate, smaller class set instead of
   reusing .orsi-tree-pane itself: Help/Index is one long page, not a
   resizable/scrolling master-detail workspace, so sticky positioning is
   enough instead of the full .orsi-workspace mechanics. */
.orsi-help-layout {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 1.5rem;
    align-items: start;
}
@media (max-width: 900px) {
    .orsi-help-layout {
        grid-template-columns: 1fr;
    }
    .orsi-help-toc {
        position: static;
    }
}
.orsi-help-toc {
    position: sticky;
    top: 1rem;
    background: var(--orsi-card);
    border: 1px solid var(--orsi-line);
    border-radius: 10px;
    padding: 0.9rem;
}
.orsi-help-toc__list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.orsi-help-toc__list a {
    display: block;
    padding: 0.3rem 0.5rem;
    border-radius: 6px;
    color: var(--orsi-ink);
    text-decoration: none;
    font-size: 0.85rem;
}
.orsi-help-toc__list a:hover,
.orsi-help-toc__list a:focus-visible {
    background: color-mix(in srgb, var(--orsi-blue) 8.000%, transparent);
    color: var(--orsi-blue);
}

/* "New module" form (Dirk, 6 August, point 5 — first step towards module
   reordering: being able to create one before there's anything to
   reorder). Briefly moved to the "Track details" card (point 3), then
   later that same day back to the tree column (first with scope-bound
   visibility, then when that turned out to be a "moving target", back to
   a fixed spot - see .orsi-structure-actions further down). Same fields
   as Dirk mentioned: Reference/Owner/Title (EN), nothing more. Since
   point 3 (6 August, fifth round) also reused by "New unit"
   (.orsi-new-unit-form carries this class too - same three fields, same
   appearance). */
.orsi-new-module-form {
    background: var(--orsi-card);
    border: 1px solid var(--orsi-line);
    border-radius: 8px;
    padding: 0.75rem;
    margin: 0.5rem 0 0;
}

/* "Copy…" row action in the Modules tab (Track UI redesign, 8 August) -
   the popup form (.orsi-new-module-form above for the card look) floats
   right-aligned below the button instead of stretching the table
   column/row, so the table doesn't jump around unattractively when the
   form opens. */
.orsi-copy-row-wrapper {
    position: relative;
    display: inline-block;
}
.orsi-copy-module-row-form {
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 20;
    width: 260px;
    margin-top: 0.35rem;
    box-shadow: 0 6px 18px color-mix(in srgb, var(--orsi-ink) 12.000%, transparent);
}

/* Per-module wrapper around "New unit" (point 3, 6 August, fifth round) -
   needs no styling of its own (the form inside it, .orsi-new-unit-form,
   reuses .orsi-new-module-form above); it only carries data-scope-parent
   so that exactly one of the N module wrappers is visible
   ([data-scope-parent] rules, further down in this file). */
.orsi-new-child-block {
    margin: 0;
}

.orsi-tree-node {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.5rem;
    border-radius: 6px;
    font-size: 0.82rem;
    cursor: pointer;
    user-select: none;
}
.orsi-tree-node:hover {
    background: var(--orsi-blue-050);
}
.orsi-tree-node.is-active {
    background: var(--orsi-blue);
    color: var(--orsi-card);
}
.orsi-tree-node.is-active .orsi-badge-count {
    background: color-mix(in srgb, var(--orsi-card) 25.000%, transparent);
    color: var(--orsi-card);
}
.orsi-tree-node.is-dimmed {
    opacity: 0.32;
}
/* Clickable expand/collapse toggle, separate from row selection (Dirk, 6
   August, "click behavior like Windows Explorer") - a slightly wider
   click zone than just the arrow glyph itself, so it's easier to hit.
   Enlarged (Track UI redesign, point 3, 8 August - Dirk noted this hadn't
   been implemented yet): 16px/0.6rem was too subtle to read as "Explorer
   style" - now 22px/0.95rem, same centering/hover behavior. */
.orsi-tree-node__caret {
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    color: var(--orsi-muted);
    flex-shrink: 0;
    border-radius: 4px;
    cursor: pointer;
}
.orsi-tree-node__caret:hover {
    background: color-mix(in srgb, var(--orsi-blue) 12.000%, transparent);
    color: var(--orsi-blue);
}
.orsi-tree-node.is-active .orsi-tree-node__caret {
    color: color-mix(in srgb, var(--orsi-card) 80.000%, transparent);
}
.orsi-tree-node.is-active .orsi-tree-node__caret:hover {
    background: color-mix(in srgb, var(--orsi-card) 18.000%, transparent);
    color: var(--orsi-card);
}
.orsi-tree-node__label {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.orsi-tree-node--module {
    font-weight: var(--orsi-weight-emphasis);
}
.orsi-tree-node--unit {
    padding-left: 1.5rem;
}
.orsi-tree-node--block {
    padding-left: 2.6rem;
    font-size: 0.78rem;
}
.orsi-tree-children {
    display: none;
}
.orsi-tree-children.is-open {
    display: block;
}
.orsi-badge-count {
    font-size: 0.65rem;
    background: var(--orsi-info-bg);
    color: var(--orsi-muted);
    border-radius: 10px;
    padding: 0.05rem 0.4rem;
}
/* Structure row parity with DNN (_PIN_PR_MT_Track.cshtml module summary:
   lock icon, status pill, manager badge - 6 August, second round, "what
   should appear on the track detail screen when you click a module...
   matching the view (both in structure and in the detail block)"). A more
   compact version of .orsi-status specifically for the tree row - the
   regular size (used elsewhere, in the detail pane) doesn't fit next to
   the caret/label/arrows in the narrow tree column. */
.orsi-lock-icon {
    font-size: 0.7rem;
    flex-shrink: 0;
}
.orsi-tree-node__status {
    flex-shrink: 0;
}
.orsi-tree-node__status .orsi-status {
    padding: 0.1rem 0.5rem;
    font-size: 0.65rem;
    gap: 0.25rem;
}
.orsi-tree-node__status .orsi-status__dot {
    width: 6px;
    height: 6px;
}
.orsi-mgr-badge {
    font-size: 0.65rem;
    background: var(--orsi-blue-050);
    color: var(--orsi-blue);
    border-radius: 10px;
    padding: 0.05rem 0.5rem;
    flex-shrink: 0;
    white-space: nowrap;
    max-width: 90px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.orsi-tree-node.is-active .orsi-mgr-badge {
    background: color-mix(in srgb, var(--orsi-card) 25.000%, transparent);
    color: var(--orsi-card);
}

/* Module detail pane (6 August, second round): each pane reuses the same
   .orsi-card/.orsi-crumbs/.orsi-level-tag/.orsi-detail-title classes as
   the existing Track detail and the client-rendered Unit/Block pane -
   so no further new layout rules are needed, only the generic
   [data-scope-parent] visibility (above) controls showing/hiding. */

.orsi-no-edit-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--orsi-progress-todo);
    display: inline-block;
    margin-left: 0.25rem;
    flex-shrink: 0;
}

/* "Only show this on the parent entity" visibility (Dirk, 6 August): now
   only used for the reorder arrows themselves (.orsi-reorder-form below) -
   the "New module" wrapper briefly used this too, but turned out to become
   a "moving target" as soon as you selected a different item in the tree
   (the whole block appeared/disappeared and the rest of the list shifted
   along with it) - see .orsi-tree-pane__actions below, which now
   deliberately has a FIXED spot, no longer data-scope-parent. Every
   element with data-scope-parent is hidden by default; track-workspace.js's
   applyScopedVisibility() sets .is-visible only on the element whose
   data-scope-parent matches the current selection. */
[data-scope-parent] {
    display: none;
}
[data-scope-parent].is-visible {
    display: block;
}

/* Point 4.4 (Dirk's request 6 August, fourth round): make "New module"
   (and later "New unit"/"New block") scope-bound visible again - "New
   module should only be visible when a track has been clicked... if a
   block is selected nothing should show, but provide a placeholder so
   the panel doesn't feel like it's floating". The previous round (see the
   old .orsi-tree-pane__actions above, now renamed) deliberately chose a
   fixed, always-visible spot specifically to avoid the "moving target"
   effect of data-scope-parent (see above) - but that problem was actually
   caused by the whole block appearing/disappearing (reflowing the rest of
   the tree column below it). This time the OUTER container itself always
   stays present and the same height (min-height below, tuned to the
   smallest content - the one-line placeholders); only the four child
   containers inside it switch from d-none to visible (track-workspace.js,
   applyStructureActionsVisibility()). This keeps the tree column below it
   stable, regardless of which level is selected. */
.orsi-structure-actions {
    margin: 0 0.5rem 0.6rem;
    min-height: 2.25rem;
}
.orsi-structure-actions__placeholder {
    padding: 0.4rem 0;
}

/* Module reordering (Dirk, 6 August, "next step"): two small arrow
   buttons at the end of a module row, independent of the row itself
   (which otherwise stays selectable/expandable/collapsible as before -
   see the stopPropagation script in Edit.cshtml). */
.orsi-reorder-form {
    gap: 0.15rem;
    margin-left: 0.4rem;
    flex-shrink: 0;
}
.orsi-reorder-form.is-visible {
    display: inline-flex;
}
.orsi-reorder-btn {
    width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.55rem;
    line-height: 1;
    padding: 0;
    border: 1px solid var(--orsi-line);
    border-radius: 4px;
    background: var(--orsi-card);
    color: var(--orsi-muted);
    cursor: pointer;
}
.orsi-reorder-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--orsi-blue) 12.000%, transparent);
    color: var(--orsi-blue);
}
.orsi-reorder-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}
/* On an active (blue) row, the buttons must stay readable - the same
   "white on blue" adjustment as .orsi-badge-count above. */
.orsi-tree-node.is-active .orsi-reorder-btn {
    border-color: color-mix(in srgb, var(--orsi-card) 40.000%, transparent);
    color: color-mix(in srgb, var(--orsi-card) 85.000%, transparent);
}
.orsi-tree-node.is-active .orsi-reorder-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--orsi-card) 18.000%, transparent);
    color: var(--orsi-card);
}
.orsi-type-chip {
    font-size: 0.65rem;
    color: var(--orsi-muted);
    background: var(--orsi-blue-050);
    border-radius: 4px;
    padding: 0.05rem 0.35rem;
}

.orsi-detail-pane {
    padding: 1.1rem 1.4rem 1.4rem;
    min-width: 0;
}
.orsi-crumbs {
    font-size: 0.78rem;
    color: var(--orsi-muted);
    margin-bottom: 0.5rem;
}
.orsi-crumb-link {
    color: var(--orsi-blue);
    text-decoration: none;
}
.orsi-crumb-sep {
    margin: 0 0.35rem;
}
.orsi-level-tag {
    display: inline-block;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: var(--orsi-weight-strong);
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    margin-bottom: 0.4rem;
}
.orsi-level-tag--module { background: var(--orsi-blue-050); color: var(--orsi-blue); }
.orsi-level-tag--unit { background: var(--orsi-warning-bg); color: var(--orsi-orange-text); }
.orsi-level-tag--block { background: var(--orsi-success-bg); color: var(--orsi-success-fg); }
.orsi-detail-title {
    font-size: 1.1rem;
    margin: 0.1rem 0 0.25rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.orsi-detail-sub {
    font-size: 0.82rem;
    color: var(--orsi-muted);
    margin-bottom: 0.8rem;
}
.orsi-detail-note {
    font-size: 0.78rem;
    color: var(--orsi-muted);
    margin: 0.4rem 0 1rem;
}

.orsi-field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 0.9rem;
    margin-bottom: 0.5rem;
}
.orsi-field-group label {
    display: block;
    font-size: 0.7rem;
    font-weight: var(--orsi-weight-emphasis);
    color: var(--orsi-muted);
    margin-bottom: 0.25rem;
}
.orsi-field-group input {
    width: 100%;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--orsi-line);
    border-radius: 6px;
    font-size: 0.85rem;
    background: var(--orsi-disabled-bg);
    color: var(--orsi-muted);
}

/* "Lock until previous ... is complete" checkbox (Track/Module/Unit/Block,
   each with its own .lock-inline-label) - Bootstrap's default
   .form-check-input border (color-mix(in srgb, var(--orsi-ink) 25.000%, transparent)) is barely visible against
   the white card background when UNCHECKED (Dirk, feedback round, point
   3: "not enough contrast when unchecked"). Only the border is darkened -
   CHECKED (Bootstrap's own blue background color) stays unchanged, that
   contrast was already sufficient. */
.lock-inline .form-check-input {
    border-color: var(--orsi-muted);
}
.lock-inline .form-check-input:checked {
    border-color: var(--orsi-blue);
}

/* ---- Title/Subtitle per language (Track detail screen, point 3.6, 6
   August) — compact language-code tag + two text fields per row, the same
   grid width for the header as for each row so Title/Subtitle line up
   neatly. ---- */
.orsi-translations__header,
.orsi-translations__row {
    display: grid;
    grid-template-columns: 44px 1fr 1fr;
    gap: 0.5rem;
    align-items: center;
}
.orsi-translations__header {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--orsi-muted);
    margin-bottom: 0.35rem;
}
.orsi-translations__row + .orsi-translations__row {
    margin-top: 0.5rem;
}
/* EN reference row (13 August 2026, Program's Languages tab, Dirk's
   request: "set EN as a reference to make translating easier") -
   read-only, lightly tinted so it's immediately clear this is the source,
   not another language to edit. No name attribute on the fields: nothing
   from this row is ever posted, it's purely a reference alongside the
   real, editable rows below it. */
.orsi-translations__row--reference {
    background: var(--orsi-surface);
    border-radius: 6px;
    padding: 0.35rem 0.5rem;
    margin-bottom: 0.35rem;
}
.orsi-translations__row--reference .orsi-translations__lang-tag {
    background: var(--orsi-blue-050);
}
.orsi-translations__lang-tag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72rem;
    font-weight: var(--orsi-weight-strong);
    color: var(--orsi-muted);
    background: var(--orsi-surface);
    border: 1px solid var(--orsi-line);
    border-radius: 4px;
    padding: 0.3rem 0;
}
.orsi-child-panel-title {
    font-size: 0.82rem;
    font-weight: var(--orsi-weight-strong);
    color: var(--orsi-deep);
    margin: 0.6rem 0 0.5rem;
}
/* Child table column headers on the detail pane are deliberately NOT
   sortable (Dirk, 5 August: the SEQNR order is strictly fixed and may
   only be changed by the manager through an actual reordering action -
   freely clickable sorting would suggest a capability nobody actually has
   here). No more cursor:pointer/hover highlight/arrow, see
   track-workspace.js renderChildTable. */
.orsi-sortable-table th {
    font-size: 0.68rem;
    text-transform: uppercase;
}

/* "Copy" button next to "Detail" on Management -> Error log (Dirk, 6
   August - "shouldn't always have to select everything"). Same small,
   dimmed style as the "Detail" label next to it, no visual weight of its
   own until you need it. */
.orsi-errorlog-copy-btn {
    font-size: 0.72rem;
    text-decoration: none;
}
.orsi-errorlog-copy-btn:hover {
    text-decoration: underline;
}

/* Block tab strip (6 August, sixth round — Dirk's forwarded UI sketch
   proposal: Content/Items/Questions/History as tabs at the top of the
   Block detail pane). Simple, hand-written tabs (no Bootstrap tab
   component, see track-workspace.js) - .is-active toggles both the
   button and its associated panel. Each block gets its own
   .orsi-block-tabset (data-block-tabset), so multiple blocks can
   independently sit on a different tab. */
.orsi-block-tabs {
    display: flex;
    gap: 0.25rem;
    border-bottom: 1px solid var(--orsi-line);
    margin-bottom: 1rem;
    flex-wrap: wrap;
}
/* Row wrapping .orsi-block-tabs + the per-entity Save/Cancel bar (Dirk,
   feedback round, point 1: "the save/cancel buttons next to the tabs ...
   so that they stay visible" - previously Save/Cancel only sat in the
   header of the Content tab panel, and so disappeared along with it
   whenever a different tab became active). The border/margin that used
   to sit on .orsi-block-tabs itself moves to this row, so tabs and button
   bar together sit on one line above the same border; .orsi-block-tabs
   loses that border/margin again when it's inside this row (rule below),
   but stays unchanged in places where this row isn't used (there aren't
   any left, but this keeps .orsi-block-tabs perfectly usable on its own
   too). */
.orsi-block-tabs-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    border-bottom: 1px solid var(--orsi-line);
    margin-bottom: 1rem;
}
.orsi-block-tabs-row .orsi-block-tabs {
    border-bottom: none;
    margin-bottom: 0;
}
.orsi-block-tabs-row .orsi-actionbar--compact {
    margin-bottom: 0.4rem;
}
.orsi-block-tab {
    appearance: none;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 0.5rem 0.9rem;
    font-size: 0.85rem;
    font-weight: var(--orsi-weight-emphasis);
    color: var(--orsi-muted);
    cursor: pointer;
}
.orsi-block-tab:hover {
    color: var(--orsi-ink);
}
.orsi-block-tab.is-active {
    color: var(--orsi-blue);
    border-bottom-color: var(--orsi-blue);
}
.orsi-block-tab-panel {
    display: none;
}
.orsi-block-tab-panel.is-active {
    display: block;
}

/* History tab (6 August, sixth round) — reads directly from
   adb.OD905_CHANGE_LOG, see EditModel.LoadBlockHistoryAsync. Compact
   list, not a table: each row is a short, unstructured sentence
   (who/what/when), not something that needs sorting/filtering like the
   child tables elsewhere. */
.orsi-history-list {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.85rem;
}
.orsi-history-list li {
    padding: 0.5rem 0;
    border-top: 1px solid var(--orsi-line);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: baseline;
}
.orsi-history-list li:first-child {
    border-top: none;
}
.orsi-history-list__when {
    color: var(--orsi-muted);
    font-size: 0.75rem;
    white-space: nowrap;
}
.orsi-history-list__who {
    font-weight: var(--orsi-weight-emphasis);
    white-space: nowrap;
}
.orsi-history-list__what {
    color: var(--orsi-ink);
}

/* Items/Questions/Answers CRUD (6 August, seventh round — "Items/
   Questions/Answers CRUD"). .orsi-translations's grid-template-columns is
   fixed at "44px 1fr 1fr" (lang tag + 2 data columns, for Block's
   Title/Eyebrow) - Item has a THIRD data column (Body), Question/Answer
   each have only ONE (Question resp. Answer). Two modifier classes
   instead of changing the existing base behavior (which would also
   affect Block's own Title/Eyebrow grid). */
.orsi-translations--1col {
    grid-template-columns: 44px 1fr;
}
.orsi-translations--3col {
    grid-template-columns: 44px 1fr 1fr 1fr;
}

/* Each Item/Question/Answer row on the Items/Questions tabs (Edit.cshtml)
   is its own .orsi-card, nested inside the tab panel card - slightly
   smaller padding than the outer cards, and the nested Answers list per
   Question gets a left border so the hierarchy (Question > Answers) is
   also visually clear without an extra heading per level. */
.orsi-block-tab-panel .orsi-card .orsi-card {
    background: var(--orsi-surface);
}
.orsi-answers-list {
    border-left: 2px dashed var(--orsi-line);
    padding-left: 0.75rem;
    margin-top: 0.75rem;
}

/* Landing page hero (7 August, later, "more like the DNN welcome screen")
   - same color palette (--orsi-deep/--orsi-blue) as the rest of the app,
   instead of the separate inline-CSS style of the DNN reference. Color is
   deliberately set directly ON each element, never just relying on
   inheritance - otherwise an <a>/<span> in the hero could inherit the
   global link color/body text color instead of staying white on the
   gradient. */
.orsi-welcome-hero {
    background: linear-gradient(120deg, var(--orsi-deep), var(--orsi-blue));
    color: var(--orsi-card);
    border-radius: 10px;
    padding: 1.5rem 1.75rem;
}
.orsi-welcome-hero h1,
.orsi-welcome-hero p,
.orsi-welcome-hero strong {
    color: var(--orsi-card) !important;
}
.orsi-welcome-hero__note {
    opacity: 0.85;
    font-size: 0.85rem;
}
.orsi-welcome-hero__stats {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-top: 0.75rem;
    font-size: 0.9rem;
}
.orsi-welcome-hero__stats strong {
    font-size: 1.1rem;
}
.orsi-welcome-hero__stat-sub {
    opacity: 0.8;
    font-weight: var(--orsi-weight-body);
}
.orsi-welcome-hero__error {
    margin-top: 0.75rem;
    background: color-mix(in srgb, var(--orsi-card) 15.000%, transparent);
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
    font-size: 0.85rem;
    color: var(--orsi-card) !important;
}

.orsi-welcome-tile {
    display: block;
    background: var(--orsi-card);
    border: 1px solid var(--orsi-line);
    border-radius: 10px;
    padding: 0.9rem 1.1rem;
    text-decoration: none !important;
    color: var(--orsi-text, var(--orsi-ink)) !important;
    height: 100%;
}
.orsi-welcome-tile:hover {
    border-color: var(--orsi-blue);
}
.orsi-welcome-tile strong {
    color: var(--orsi-deep) !important;
    display: block;
    margin-bottom: 0.15rem;
}
.orsi-welcome-tile--accent {
    border-left: 4px solid var(--orsi-blue);
}

/* ================================================================
   Program workspace (Library → Programs, 10 August 2026 build) — Pages/
   Library/Programs/Edit.cshtml(.cs) + wwwroot/js/program-workspace.js.
   Deliberately built on the SAME classes as Track's own workspace wherever
   the shape matches (.orsi-card/.orsi-block-tabset/.orsi-block-tab*/
   .orsi-translations__*/.orsi-history-list*/.orsi-owner-change__form/
   .lock-inline/.orsi-reorder-btn/[data-scope-parent] — see Track's own CSS
   above for all of those) - only the two rules below have no existing
   equivalent, both purely cosmetic (neither is load-bearing for function).
   ================================================================ */
.orsi-program-track-role-select {
    min-width: 12rem;
}
.orsi-program-track-edit-btn.is-active {
    background: var(--orsi-blue);
    color: var(--orsi-card);
    border-color: var(--orsi-blue);
}

/* UI Foundation reference-gallery layer v94. */
/* ---- afscherming: alles hieronder geldt uitsluitend binnen .odi-bt ---- */
.odi-bt,.odi-bt *{box-sizing:border-box}
.odi-bt h1,.odi-bt h2,.odi-bt h3,.odi-bt h4,.odi-bt p,.odi-bt ul,.odi-bt ol,.odi-bt li,.odi-bt dl,.odi-bt dt,.odi-bt dd,
.odi-bt figure,.odi-bt figcaption,.odi-bt table,.odi-bt thead,.odi-bt tbody,.odi-bt tr,.odi-bt th,.odi-bt td,
.odi-bt aside,.odi-bt section,.odi-bt article,.odi-bt header,.odi-bt footer,.odi-bt div,.odi-bt span{
  margin:0;padding:0;border:0;background:none;font:inherit;color:inherit;
  text-transform:none;letter-spacing:normal;text-align:left;list-style:none;
  float:none;position:static;box-shadow:none}
.odi-bt table{border-collapse:collapse;border-spacing:0;width:auto}
.odi-bt button{margin:0;padding:0;font:inherit;color:inherit;background:none;border:0;
  text-transform:none;box-shadow:none;-webkit-appearance:none;appearance:none;cursor:pointer}
.odi-bt a{text-decoration:none;color:inherit}
.odi-bt svg{display:inline-block;vertical-align:middle}
.odi-bt::before,.odi-bt::after,.odi-bt *::before,.odi-bt *::after{box-sizing:border-box}

/* ---- gallery ---- */
.odi-bt{
    
    
    
}.odi-bt{margin:0;font-family:Poppins,'Segoe UI',system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;background:var(--orsi-surface);color:var(--orsi-ink);line-height:1.55}.odi-bt .bt-wrap{max-width:1180px;margin:0 auto;padding:0 20px 80px}.odi-bt header.bt-top{background:linear-gradient(100deg,var(--orsi-deep),var(--orsi-blue));color:var(--orsi-card);padding:44px 0 38px;margin-bottom:0}.odi-bt header.bt-top .bt-wrap{padding-bottom:0}.odi-bt .bt-kicker{font-size:11.5px;font-weight:var(--orsi-weight-strong);letter-spacing:2px;text-transform:uppercase;opacity:.85;margin:0 0 8px}.odi-bt header.bt-top h1{margin:0 0 10px;font-size:32px;font-weight:var(--orsi-weight-strong);letter-spacing:-.4px}.odi-bt header.bt-top p{margin:0;max-width:70ch;opacity:.93;font-size:15px}.odi-bt .bt-statbar{display:flex;flex-wrap:wrap;gap:10px;margin-top:22px}.odi-bt .bt-statbar div{background:color-mix(in srgb, var(--orsi-card) 14.000%, transparent);border:1px solid color-mix(in srgb, var(--orsi-card) 22.000%, transparent);border-radius:10px;padding:9px 14px;font-size:13px;font-weight:var(--orsi-weight-emphasis)}.odi-bt .bt-statbar b{font-size:17px;font-weight:var(--orsi-weight-strong);display:block;line-height:1.2}.odi-bt .bt-toolbar{position:sticky;top:0;z-index:20;background:color-mix(in srgb, var(--orsi-surface) 94.000%, transparent);backdrop-filter:blur(8px);border-bottom:1px solid var(--orsi-line);padding:12px 0;margin-bottom:26px}.odi-bt .bt-toolbar .bt-wrap{display:flex;flex-wrap:wrap;gap:7px;align-items:center;padding-bottom:0}.odi-bt .bt-fbtn{border:1px solid var(--orsi-line);background:var(--orsi-card);color:var(--orsi-ink);border-radius:999px;padding:6px 13px;font:var(--orsi-weight-emphasis) 12.5px Poppins,'Segoe UI',system-ui,sans-serif;cursor:pointer}.odi-bt .bt-fbtn:hover{border-color:var(--orsi-blue)}.odi-bt .bt-fbtn.bt-on{background:var(--orsi-deep);color:var(--orsi-card);border-color:var(--orsi-deep)}.odi-bt .bt-fbtn small{opacity:.65;font-weight:var(--orsi-weight-emphasis)}.odi-bt h2.bt-sec{font-size:13px;font-weight:var(--orsi-weight-strong);letter-spacing:1.6px;text-transform:uppercase;color:var(--orsi-muted);margin:38px 0 14px;padding-bottom:8px;border-bottom:1px solid var(--orsi-line)}.odi-bt .bt-card{background:var(--orsi-card);border:1px solid var(--orsi-line);border-radius:14px;margin-bottom:16px;overflow:hidden;box-shadow:0 1px 2px color-mix(in srgb, var(--orsi-ink) 4.000%, transparent)}.odi-bt .bt-card__hd{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:15px 20px;border-bottom:1px solid var(--orsi-line);background:var(--orsi-card)}.odi-bt .bt-card__hd h3{margin:0;font-size:16.5px;font-weight:var(--orsi-weight-strong)}.odi-bt .bt-code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px;background:var(--orsi-blue-050);border:1px solid var(--orsi-line);border-radius:6px;padding:2px 7px;color:var(--orsi-deep)}.odi-bt .bt-st{font-size:10.5px;font-weight:var(--orsi-weight-strong);letter-spacing:.9px;text-transform:uppercase;border-radius:999px;padding:3px 10px;margin-left:auto}.odi-bt .bt-st-ok{background:color-mix(in srgb, var(--orsi-green-600) 13.000%, transparent);color:var(--orsi-success-fg)}.odi-bt .bt-st-render{background:color-mix(in srgb, var(--orsi-blue) 13.000%, transparent);color:var(--orsi-blue-700)}.odi-bt .bt-st-nieuw{background:color-mix(in srgb, var(--orsi-action) 14.000%, transparent);color:var(--orsi-orange-text)}.odi-bt .bt-st-kolom{background:color-mix(in srgb, var(--orsi-deep) 13.000%, transparent);color:var(--orsi-deep)}.odi-bt .bt-st-schrap{background:var(--orsi-surface);color:var(--orsi-muted)}.odi-bt .bt-card__bd{display:grid;grid-template-columns:1.15fr .85fr;gap:0}@media(max-width:820px){.odi-bt .bt-card__bd{grid-template-columns:1fr}}.odi-bt .bt-demo{padding:22px 20px;border-right:1px solid var(--orsi-line)}@media(max-width:820px){.odi-bt .bt-demo{border-right:0;border-bottom:1px solid var(--orsi-line)}}.odi-bt .bt-spec{padding:22px 20px;background:var(--orsi-card);font-size:13px}.odi-bt .bt-spec dl{margin:0;display:grid;grid-template-columns:auto 1fr;gap:5px 12px}.odi-bt .bt-spec dt{font-weight:var(--orsi-weight-strong);color:var(--orsi-muted);font-size:11px;letter-spacing:.7px;text-transform:uppercase;padding-top:2px}.odi-bt .bt-spec dd{margin:0}.odi-bt .bt-spec .bt-why{margin:14px 0 0;padding:11px 13px;background:var(--orsi-card);border:1px solid var(--orsi-line);border-left:3px solid var(--orsi-orange);border-radius:0 8px 8px 0;font-size:12.5px;color:var(--orsi-ink-soft)}.odi-bt .bt-spec code{font-family:ui-monospace,Menlo,monospace;font-size:11.8px;background:var(--orsi-blue-050);padding:1px 5px;border-radius:4px}.odi-bt .bt-blk__eyebrow{font-size:11px;font-weight:var(--orsi-weight-strong);letter-spacing:1.7px;text-transform:uppercase;color:var(--orsi-blue);margin:0 0 5px}.odi-bt .bt-blk__title{font-size:19px;font-weight:var(--orsi-weight-strong);margin:0 0 9px;letter-spacing:-.2px}.odi-bt .bt-demo p{margin:0 0 9px;font-size:14px}.odi-bt .bt-demo p.bt-lede{font-size:15.5px;color:var(--orsi-ink-soft);font-weight:var(--orsi-weight-body)}.odi-bt .bt-demo p.bt-note{font-size:12.5px;color:var(--orsi-muted)}.odi-bt .bt-demo p.bt-q{font-weight:var(--orsi-weight-emphasis)}.odi-bt ul.bt-objectives{list-style:none;padding:0;margin:10px 0 0}.odi-bt ul.bt-objectives li{position:relative;padding:5px 0 5px 26px;font-size:13.6px;border-bottom:1px dashed var(--orsi-line)}.odi-bt ul.bt-objectives li:before{content:"";position:absolute;left:2px;top:12px;width:9px;height:9px;border-radius:50%;background:var(--orsi-blue)}.odi-bt .bt-char{display:flex;gap:13px;align-items:flex-start;background:var(--orsi-surface);border:1px solid var(--orsi-line);border-left:4px solid var(--orsi-blue);border-radius:0 12px 12px 0;padding:13px 15px;margin:12px 0 0}.odi-bt .bt-char--odi{border-left-color:var(--orsi-orange);background:var(--orsi-warning-bg)}.odi-bt .bt-char__ph{flex:0 0 54px;height:54px;border-radius:50%;background:linear-gradient(140deg,var(--orsi-deep),var(--orsi-blue));color:var(--orsi-card);display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:9px;font-weight:var(--orsi-weight-strong);letter-spacing:.5px;text-align:center;line-height:1.15}.odi-bt .bt-char--odi .bt-char__ph{background:linear-gradient(140deg,var(--orsi-orange),var(--orsi-action))}.odi-bt .bt-char__eb{font-size:10px;font-weight:var(--orsi-weight-strong);letter-spacing:1.4px;text-transform:uppercase;color:var(--orsi-deep);margin:0 0 3px}.odi-bt .bt-char--odi .bt-char__eb{color:var(--orsi-orange-text)}.odi-bt .bt-char p{font-size:13.4px;margin:0}.odi-bt .bt-mdef__r{display:flex;gap:12px;padding:7px 0;border-bottom:1px dashed var(--orsi-line);font-size:13.4px}.odi-bt .bt-mdef__t{flex:0 0 118px;font-weight:var(--orsi-weight-strong);color:var(--orsi-deep)}.odi-bt .bt-band{display:flex;align-items:center;gap:12px;background:var(--orsi-card);border:1px solid var(--orsi-line);border-radius:12px;padding:11px 14px;margin:8px 0}.odi-bt .bt-band .bt-num{flex:0 0 30px;height:30px;border-radius:50%;background:var(--orsi-deep);color:var(--orsi-card);display:flex;align-items:center;justify-content:center;font-weight:var(--orsi-weight-strong);font-size:14px}.odi-bt .bt-band .bt-t{font-weight:var(--orsi-weight-strong);font-size:14px}.odi-bt .bt-band .bt-m{font-size:11.5px;color:var(--orsi-muted);margin-left:auto;text-align:right;max-width:46%}.odi-bt .bt-stat-hero{background:linear-gradient(120deg,var(--orsi-deep),var(--orsi-blue));color:var(--orsi-card);border-radius:14px;padding:20px 22px;display:flex;gap:18px;align-items:center;margin-top:10px}.odi-bt .bt-stat-hero .bt-big{font-size:40px;font-weight:var(--orsi-weight-strong);line-height:1;letter-spacing:-1.5px}.odi-bt .bt-stat-hero .bt-lab{font-size:13.4px;opacity:.95}.odi-bt .bt-struct__r{display:flex;gap:11px;align-items:flex-start;padding:7px 0 7px 0;font-size:13.3px}.odi-bt .bt-struct__r--1{padding-left:20px}.odi-bt .bt-struct__r--2{padding-left:40px}.odi-bt .bt-struct__r--3{padding-left:60px}.odi-bt .bt-struct__k{flex:0 0 62px;font-size:9.5px;font-weight:var(--orsi-weight-strong);letter-spacing:1.1px;text-transform:uppercase;color:var(--orsi-card);background:var(--orsi-deep);border-radius:5px;padding:3px 0;text-align:center;margin-top:2px}.odi-bt .bt-struct__r--3 .bt-struct__k{background:var(--orsi-orange)}.odi-bt .bt-struct__c b{display:block}.odi-bt .bt-struct__c span{color:var(--orsi-muted);font-size:12.4px}.odi-bt ol.bt-steps{margin:10px 0 0;padding-left:0;counter-reset:s;list-style:none}.odi-bt ol.bt-steps li{counter-increment:s;position:relative;padding:7px 0 7px 36px;font-size:13.5px;border-bottom:1px dashed var(--orsi-line)}.odi-bt ol.bt-steps li:before{content:counter(s);position:absolute;left:0;top:7px;width:24px;height:24px;border-radius:50%;background:var(--orsi-blue-050);color:var(--orsi-deep);font-weight:var(--orsi-weight-strong);font-size:12px;display:flex;align-items:center;justify-content:center}.odi-bt ul.bt-tkl{list-style:none;padding:0;margin:10px 0 0}.odi-bt ul.bt-tkl li{display:flex;gap:11px;padding:8px 0;border-bottom:1px dashed var(--orsi-line);font-size:13.4px}.odi-bt ul.bt-tkl .bt-tkl__ic{flex:0 0 20px;height:20px;border-radius:50%;background:color-mix(in srgb, var(--orsi-green-600) 14.000%, transparent);color:var(--orsi-success-fg);display:flex;align-items:center;justify-content:center;font-weight:var(--orsi-weight-strong);font-size:12px;margin-top:2px}.odi-bt ul.bt-tkl b{display:block}.odi-bt ul.bt-tkl .bt-tkl__tx{color:var(--orsi-muted);font-size:12.6px}.odi-bt .bt-tips .bt-tip{display:flex;gap:11px;align-items:center;padding:8px 0;border-bottom:1px dashed var(--orsi-line);font-size:13.4px}.odi-bt .bt-tips .bt-n{flex:0 0 24px;height:24px;border-radius:50%;background:var(--orsi-blue);color:var(--orsi-card);display:flex;align-items:center;justify-content:center;font-weight:var(--orsi-weight-strong);font-size:12px}.odi-bt .bt-rev__i{border:1px solid var(--orsi-line);border-radius:10px;margin:8px 0;overflow:hidden}.odi-bt .bt-rev__q{width:100%;text-align:left;background:var(--orsi-card);border:0;padding:11px 14px;font:var(--orsi-weight-emphasis) 13.5px Poppins,'Segoe UI',system-ui,sans-serif;color:var(--orsi-ink);cursor:pointer;display:flex;justify-content:space-between;gap:10px}.odi-bt .bt-rev__q:after{content:"+";color:var(--orsi-blue);font-weight:var(--orsi-weight-strong)}.odi-bt .bt-rev__i.bt-on .bt-rev__q:after{content:"–"}.odi-bt .bt-rev__a{display:none;padding:11px 14px;font-size:13.3px;border-top:1px solid var(--orsi-line)}.odi-bt .bt-rev__i.bt-on .bt-rev__a{display:block}.odi-bt .bt-car{border:1px solid var(--orsi-line);border-radius:12px;padding:15px;margin-top:10px;background:var(--orsi-card)}.odi-bt .bt-car__n{font-size:11px;font-weight:var(--orsi-weight-strong);letter-spacing:1.2px;text-transform:uppercase;color:var(--orsi-muted)}.odi-bt .bt-car__step{display:flex;gap:13px;align-items:flex-start;margin:9px 0}.odi-bt .bt-car__num{flex:0 0 34px;height:34px;border-radius:50%;background:var(--orsi-deep);color:var(--orsi-card);display:flex;align-items:center;justify-content:center;font-weight:var(--orsi-weight-strong)}.odi-bt .bt-car__t{font-weight:var(--orsi-weight-strong);font-size:14px}.odi-bt .bt-car__d{font-size:13.2px;color:var(--orsi-ink-soft)}.odi-bt .bt-car__ctrl{display:flex;gap:8px;align-items:center;justify-content:space-between;border-top:1px solid var(--orsi-line);padding-top:10px}.odi-bt .bt-cbtn{border:1px solid var(--orsi-line);background:var(--orsi-card);border-radius:8px;padding:5px 12px;font:var(--orsi-weight-emphasis) 12.5px Poppins,'Segoe UI',system-ui,sans-serif;cursor:pointer;color:var(--orsi-deep)}.odi-bt .bt-cbtn[disabled]{opacity:.4;cursor:default}.odi-bt .bt-car__dot{width:7px;height:7px;border-radius:50%;background:var(--orsi-line);display:inline-block;margin:0 2px}.odi-bt .bt-car__dot.bt-on{background:var(--orsi-blue)}.odi-bt .bt-opts{margin:9px 0 0}.odi-bt .bt-opt{display:flex;gap:11px;width:100%;text-align:left;background:var(--orsi-card);border:1px solid var(--orsi-line);border-radius:10px;padding:10px 13px;margin-bottom:7px;font:var(--orsi-weight-body) 13.4px Poppins,'Segoe UI',system-ui,sans-serif;color:var(--orsi-ink);cursor:pointer}.odi-bt .bt-opt:hover{border-color:var(--orsi-blue)}.odi-bt .bt-opt .bt-k{flex:0 0 22px;height:22px;border-radius:6px;background:var(--orsi-blue-050);color:var(--orsi-deep);font-weight:var(--orsi-weight-strong);font-size:11.5px;display:flex;align-items:center;justify-content:center}.odi-bt .bt-opt.bt-good{border-color:var(--orsi-success-fg);background:color-mix(in srgb, var(--orsi-green-600) 7.000%, transparent)}.odi-bt .bt-opt.bt-bad{border-color:var(--orsi-orange);background:color-mix(in srgb, var(--orsi-action) 7.000%, transparent)}.odi-bt .bt-fb{display:none;margin-top:8px;padding:11px 13px;border-radius:10px;font-size:13.2px;background:var(--orsi-surface);border:1px solid var(--orsi-line);border-left:3px solid var(--orsi-blue)}.odi-bt .bt-fb.bt-on{display:block}.odi-bt .bt-kcc__head{display:flex;justify-content:space-between;align-items:center;font-size:11px;font-weight:var(--orsi-weight-strong);letter-spacing:1.2px;text-transform:uppercase;color:var(--orsi-muted);margin-bottom:8px}.odi-bt .bt-kcdot{width:7px;height:7px;border-radius:50%;background:var(--orsi-line);display:inline-block;margin-left:4px}.odi-bt .bt-kcdot.bt-on{background:var(--orsi-blue)}.odi-bt .bt-ord__pool{display:flex;flex-wrap:wrap;gap:7px;margin-top:9px}.odi-bt .bt-oc{border:1px solid var(--orsi-line);background:var(--orsi-card);border-radius:999px;padding:6px 13px;font:var(--orsi-weight-emphasis) 12.6px Poppins,'Segoe UI',system-ui,sans-serif;cursor:pointer;color:var(--orsi-ink)}.odi-bt .bt-oc .bt-seq{display:none}.odi-bt .bt-oc.bt-on{background:var(--orsi-deep);color:var(--orsi-card);border-color:var(--orsi-deep)}.odi-bt .bt-oc.bt-on .bt-seq{display:inline;font-weight:var(--orsi-weight-strong);margin-right:6px;opacity:.75}.odi-bt table.bt-mx{width:100%;border-collapse:collapse;margin-top:9px;font-size:13px}.odi-bt table.bt-mx th{background:var(--orsi-blue-050);color:var(--orsi-deep);font-size:11px;letter-spacing:.8px;text-transform:uppercase;padding:7px 9px;text-align:left;border:1px solid var(--orsi-line)}.odi-bt table.bt-mx td{padding:7px 9px;border:1px solid var(--orsi-line)}.odi-bt .bt-g--ok{color:var(--orsi-success-fg);font-weight:var(--orsi-weight-strong)}.odi-bt .bt-g--bad{color:var(--orsi-orange);font-weight:var(--orsi-weight-strong)}.odi-bt .bt-panel{background:var(--orsi-surface);border:1px solid var(--orsi-line);border-radius:12px;padding:14px 16px;margin-top:8px}.odi-bt .bt-panel--dbrief{background:var(--orsi-warning-bg);border-left:4px solid var(--orsi-orange);border-radius:0 12px 12px 0}.odi-bt .bt-vstage{border:1px solid var(--orsi-line);border-radius:12px;overflow:hidden;margin-top:9px;background:var(--orsi-ink);color:var(--orsi-card);aspect-ratio:16/9;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px}.odi-bt .bt-pbtn{width:52px;height:52px;border-radius:50%;background:color-mix(in srgb, var(--orsi-card) 16.000%, transparent);display:flex;align-items:center;justify-content:center}.odi-bt .bt-pbtn svg{width:20px;height:20px;fill:var(--orsi-card);margin-left:3px}.odi-bt .bt-vstage .bt-t{font-size:13px;font-weight:var(--orsi-weight-emphasis)}.odi-bt .bt-vstage .bt-h{font-size:11.5px;opacity:.7}.odi-bt .bt-vgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:9px}.odi-bt .bt-vcard{border:1px solid var(--orsi-line);border-radius:10px;overflow:hidden}.odi-bt .bt-video-slot{background:var(--orsi-ink);aspect-ratio:16/9;display:flex;align-items:center;justify-content:center}.odi-bt .bt-vtabs{display:flex;gap:4px;padding:6px 8px 0;background:var(--orsi-card);border-bottom:1px solid var(--orsi-line)}.odi-bt .bt-vtab{border:1px solid var(--orsi-line);border-bottom:0;background:var(--orsi-card);border-radius:7px 7px 0 0;padding:4px 10px;font:var(--orsi-weight-emphasis) 11.5px Poppins,'Segoe UI',system-ui,sans-serif;color:var(--orsi-muted);cursor:pointer}.odi-bt .bt-vtab.bt-on{background:var(--orsi-deep);color:var(--orsi-card);border-color:var(--orsi-deep)}.odi-bt .bt-vlabel{padding:8px 10px;font-size:12.4px;font-weight:var(--orsi-weight-emphasis)}.odi-bt .bt-vq{padding:0 10px 9px;font-size:11.8px;color:var(--orsi-muted)}.odi-bt figure.bt-fig{margin:9px 0 0;border:1px solid var(--orsi-line);border-radius:12px;overflow:hidden;background:var(--orsi-card)}.odi-bt figure.bt-fig .bt-ph{aspect-ratio:16/9;background:repeating-linear-gradient(45deg,var(--orsi-blue-050),var(--orsi-blue-050) 12px,var(--orsi-info-bg) 12px,var(--orsi-info-bg) 24px);display:flex;align-items:center;justify-content:center;color:var(--orsi-muted);font-size:12px;font-weight:var(--orsi-weight-emphasis)}.odi-bt figure.bt-fig figcaption{padding:9px 12px;font-size:12.4px;color:var(--orsi-muted)}.odi-bt .bt-hand{background:var(--orsi-card);border:1px dashed var(--orsi-blue);border-radius:12px;padding:14px 16px;margin-top:9px;display:flex;gap:12px;align-items:center;font-size:13.2px}.odi-bt .bt-hand__b{margin-left:auto;background:var(--orsi-blue);color:var(--orsi-card);border:0;border-radius:8px;padding:7px 14px;font:var(--orsi-weight-strong) 12.5px Poppins,'Segoe UI',system-ui,sans-serif;cursor:pointer}.odi-bt table.bt-cmp{width:100%;border-collapse:collapse;margin-top:9px;font-size:13px}.odi-bt table.bt-cmp th,.odi-bt table.bt-cmp td{border:1px solid var(--orsi-line);padding:7px 10px;text-align:left}.odi-bt table.bt-cmp th{background:var(--orsi-blue-050);font-size:11.5px;letter-spacing:.6px;text-transform:uppercase;color:var(--orsi-deep)}.odi-bt .bt-tb{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}.odi-bt .bt-tb span{border:1px solid var(--orsi-line);background:var(--orsi-card);border-radius:7px;padding:4px 9px;font-size:11.8px;font-weight:var(--orsi-weight-emphasis)}.odi-bt .bt-tb span.bt-no{background:var(--orsi-disabled-bg);color:var(--orsi-disabled-ink);text-decoration:line-through;border-style:dashed}.odi-bt footer.bt-bot{margin-top:44px;padding-top:20px;border-top:1px solid var(--orsi-line);font-size:12.5px;color:var(--orsi-muted)}.odi-bt .bt-scn{border:1px solid var(--orsi-line);border-radius:12px;overflow:hidden;margin-top:9px;background:var(--orsi-card)}.odi-bt .bt-scn__hd{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;background:var(--orsi-blue-050);font-size:11px;font-weight:var(--orsi-weight-strong);letter-spacing:1.1px;text-transform:uppercase;color:var(--orsi-deep)}.odi-bt .bt-scn__v{background:var(--orsi-ink);aspect-ratio:16/9;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;color:var(--orsi-card)}.odi-bt .bt-scn__v .bt-t{font-size:12.5px;font-weight:var(--orsi-weight-emphasis)}.odi-bt .bt-scn__v .bt-h{font-size:11px;opacity:.65}.odi-bt .bt-scn__q{padding:12px}.odi-bt .bt-scn__hl{display:none;margin-top:9px;padding:10px 12px;border:1px dashed var(--orsi-orange);border-radius:9px;font-size:12.6px;background:var(--orsi-warning-bg);align-items:center;gap:10px}.odi-bt .bt-scn__hl.bt-on{display:flex}.odi-bt .bt-scn__hl b{color:var(--orsi-orange-text)}.odi-bt .bt-scn__hlb{margin-left:auto;background:var(--orsi-orange);color:var(--orsi-card);border:0;border-radius:7px;padding:6px 12px;font:var(--orsi-weight-strong) 12px Poppins,'Segoe UI',system-ui,sans-serif;cursor:pointer}.odi-bt .bt-cust{border:2px dashed var(--orsi-orange);border-radius:12px;overflow:hidden;background:var(--orsi-card)}.odi-bt .bt-cust__hd{display:flex;align-items:center;gap:8px;padding:9px 12px;background:var(--orsi-warning-bg);font-size:11.5px;font-weight:var(--orsi-weight-strong);letter-spacing:.6px;text-transform:uppercase;color:var(--orsi-orange-text)}.odi-bt .bt-cust__ic{font-size:14px}.odi-bt .bt-cust__role{margin-left:auto;font-size:10.5px;font-weight:var(--orsi-weight-strong);letter-spacing:.4px;color:var(--orsi-muted);text-transform:none}.odi-bt .bt-cust__frame{padding:12px}.odi-bt .bt-cust__demo{border:1px solid var(--orsi-line);border-radius:9px;background:repeating-linear-gradient(45deg,var(--orsi-card),var(--orsi-card) 10px,var(--orsi-card) 10px,var(--orsi-card) 20px);padding:26px 12px;text-align:center;font-size:12.8px;font-weight:var(--orsi-weight-emphasis);color:var(--orsi-muted)}.odi-bt .bt-cust__rules{display:flex;flex-wrap:wrap;gap:6px;padding:0 12px 12px}.odi-bt .bt-cust__r{font-size:11px;font-weight:var(--orsi-weight-strong);background:var(--orsi-card);border:1px solid var(--orsi-line);border-radius:999px;padding:4px 10px;color:var(--orsi-deep)}.odi-bt .bt-hidden{display:none!important}

