/* ─────────────────────────────────────────────────────────────────────────
   Media Studio — shared stylesheet (global).
   Historically these ms-* classes lived inside MediaStudioDialog.razor's
   scoped <style> block; they moved here so the dedicated studio PAGE and the
   legacy dialog share one definition.
   ───────────────────────────────────────────────────────────────────────── */

/* ── legacy dialog scoped bits (still used while dialogs remain) ── */
.media-studio-dialog .ms-title-caption {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* One height for every text button, matching the 40px input boxes. */
.media-studio-dialog button.mud-button {
    height: 40px;
}

/* ── studio page shell ─────────────────────────────────────────────── */

.ms-studio {
    display: flex;
    flex-direction: column;
    height: calc(100dvh - var(--mud-appbar-height, 64px));
    overflow: hidden;
    background: var(--mud-palette-background);
}

.ms-topbar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    flex: 0 0 auto;
    padding: 12px 10px 8px 16px;
    background: var(--mud-palette-surface);
    background: color-mix(in srgb, var(--mud-palette-text-primary) 4%, var(--mud-palette-surface));
    border-bottom: 0px solid var(--mud-palette-lines-default);
}

.ms-modules {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 2px;
    flex: 0 1 auto;
    min-width: 0;
    align-self: stretch;
    /* Span the topbar's vertical padding AND its border row (bottom -9px) so the tabs sit ON
       the bar's hairline and the active tab's -1px overhang covers it; the 1px padding-bottom
       keeps that overhang inside the (horizontal-scroll) overflow clip. The strip is the
       topbar's only child and centers via the topbar's justify-content. */
    margin: -8px 0 -9px;
    padding-bottom: 1px;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
}

.ms-modules::-webkit-scrollbar {
    display: none;
}

/* Module switcher: traditional editor-style tabs (same language as .ms-rtab / global MudTabs). */
.ms-module {
    appearance: none;
    border: none;
    background: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    padding: 7px 12px 6px 12px;
    border-radius: 6px 6px 0 0;
    margin-bottom: -1px;
    color: var(--mud-palette-text-secondary);
    font: inherit;
    font-weight: 500;
    font-size: 0.8125rem;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.12s ease, color 0.12s ease;
    background-color: var(--mud-palette-lines-default);
}

.ms-module .mud-icon-root {
    font-size: 16px;
    opacity: 0.9;
}

.ms-module:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

.ms-module:hover {
    background: rgba(128, 128, 128, 0.14);
    background: color-mix(in srgb, var(--mud-palette-text-primary) 8%, transparent);
    color: var(--mud-palette-text-primary);
}

/* Active tab: pane surface fill; it covers the bar's hairline beneath it. */
.ms-module.is-active {
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
}

/* ── multiline fields: drag to grow vertically ───────────────────────── */

/* Prompts, instructions and notes live in fixed 2–4-row boxes; a long text must not be
   read through a keyhole. Every multiline field in the studio — side panels, properties
   panel and AI pane (inside .ms-studio) plus the media dialogs — can be dragged taller.
   MudBlazor's reset ships `resize: none` on every textarea, so opt back in; a non-visible
   overflow (auto) is also what makes the native bottom-right grip appear at all. */
.ms-studio textarea.mud-input-root,
.media-studio-dialog textarea.mud-input-root {
    resize: vertical;
    overflow-y: auto;
}

/* ── Preferences module (last tab): tenant media profile + today's usage ────────────── */

.ms-preferences {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    padding: 20px 24px 32px;
}

.ms-preferences-inner {
    max-width: 980px;
    margin: 0 auto;
}

.ms-pref-usage {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 10px;
}

.ms-pref-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 18px;
}

.ms-studio-body {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
}

/* ── side panels ───────────────────────────────────────────────────── */

.ms-side {
    position: relative;
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow-y: auto;
    background: var(--mud-palette-surface);
}

.ms-side-left {
    width: var(--ms-left-w, 280px);
    max-width: 48vw;
    border-right: 1px solid var(--mud-palette-lines-default);
}

.ms-side-right {
    width: 340px;
    border-left: 1px solid var(--mud-palette-lines-default);
}

.ms-side-inner {
    padding: 14px;
}

/* ── Pinned side-panel footer (create actions) ────────────────────────────
   The scrollport is .ms-side, so the footer works twice over:
   - flex column + margin-top:auto pins it to the panel bottom when content is short;
   - position:sticky keeps it pinned while long content scrolls beneath it. */

.ms-side-inner.ms-side-inner--pin {
    display: flex;
    flex-direction: column;
    min-height: 100%;
}

/* MudBlazor controls carry their own flex-grow — inside a pinned column that would
   stretch dividers/inputs vertically. Keep every direct child at its natural size;
   the footer alone claims the free space via margin-top: auto. */
.ms-side-inner--pin > * {
    flex: 0 0 auto;
}

.ms-side-footer {
    position: sticky;
    bottom: 0;
    z-index: 2;
    flex: 0 0 auto;
    margin: auto -14px -14px;
    padding: 10px 14px;
    background: var(--mud-palette-surface);
    border-top: 1px solid var(--mud-palette-lines-default);
}

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

/* Full-width primary create button inside a pinned side-panel footer ("+ New …"). */
.ms-side-footer .ms-new-btn {
    width: 100%;
    justify-content: center;
}

/* Optional secondary footer row under the New button (Scan, New folder, …). */
.ms-side-footer-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
}

/* ── Nav lists (left panels of entity tabs: the list drives canvas selection) ────── */

.ms-navlist {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ms-navlist-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 7px 10px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--mud-palette-text-primary);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.ms-navlist-item:hover {
    background: rgba(128, 128, 128, 0.14);
    background: color-mix(in srgb, var(--mud-palette-text-primary) 8%, transparent);
}

.ms-navlist-item:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

.ms-navlist-item.is-selected {
    background: color-mix(in srgb, var(--mud-palette-primary) 16%, transparent);
}

.ms-navlist-item .ms-navlist-thumb {
    width: 28px;
    height: 28px;
    border-radius: 6px;
    object-fit: cover;
    flex: 0 0 auto;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-gray);
}

.ms-navlist-item .ms-navlist-icon {
    flex: 0 0 auto;
    opacity: 0.75;
}

.ms-navlist-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 0.84rem;
    font-weight: 500;
}

.ms-navlist-item.is-selected .ms-navlist-name {
    color: var(--mud-palette-primary);
}

.ms-navlist-chip {
    flex: 0 0 auto;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 1px 6px;
    border-radius: 999px;
    color: var(--mud-palette-text-secondary);
    background: color-mix(in srgb, var(--mud-palette-text-primary) 8%, transparent);
}

.ms-navlist-empty {
    padding: 10px 4px;
    color: var(--mud-palette-text-secondary);
    font-size: 0.78rem;
    line-height: 1.5;
}

/* ── Right rail tabs: Inspector (properties) ⇄ AI assistant ─────────── */

/* Sticky so the tabs stay reachable while the inspector content (or mobile drawer) scrolls.
   Traditional editor tabs (à la VS Code): rounded tops, the active tab merges into the pane
   below, and the strip's bottom border breaks away under it. */
.ms-right-tabs {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: stretch;
    flex: 0 0 auto;
    gap: 2px;
    padding: 6px 8px 0;
    background: var(--mud-palette-surface);
    background: color-mix(in srgb, var(--mud-palette-text-primary) 4%, var(--mud-palette-surface));
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.ms-rtab {
    appearance: none;
    border: none;
    background: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex: 1 1 0;
    min-width: 0;
    padding: 7px 10px 6px;
    border-radius: 6px 6px 0 0;
    margin-bottom: -1px;
    color: var(--mud-palette-text-secondary);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.12s ease, color 0.12s ease;
    background-color: var(--mud-palette-lines-default);
}

.ms-rtab .mud-icon-root {
    font-size: 15px;
    opacity: 0.9;
}

.ms-rtab:hover {
    background: rgba(128, 128, 128, 0.15);
    background: color-mix(in srgb, var(--mud-palette-text-primary) 8%, transparent);
    color: var(--mud-palette-text-primary);
}

.ms-rtab:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

/* The active tab reads as part of the pane below: pane surface, thin top accent, and it
   covers the strip's border line so the two visually merge. */
.ms-rtab.is-active {
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
}

/* Pulsing badge on the AI tab while a generation turn runs (visible when on the Inspector tab). */
.ms-rtab-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--mud-palette-primary);
    flex: 0 0 auto;
    animation: ms-rtab-pulse 1.2s ease-in-out infinite;
}

@keyframes ms-rtab-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}

.ms-rtab-close {
    flex: 0 0 auto;
    align-self: center;
    margin: 4px 0 4px 4px;
}

/* ── center canvas — follows the app light/dark mode ────────────── */

.ms-canvas {
    position: relative;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    background: var(--mud-palette-surface);
}

.ms-canvas-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    flex: 0 0 auto;
    padding: 10px 14px;
    color: var(--mud-palette-text-primary);
    background: var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.ms-canvas-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 14px;
}

/* ── library grid + loupe ──────────────────────────────────────────── */

.ms-studio-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 12px;
}

.ms-loupe {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.ms-loupe-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    padding: 8px 14px;
    color: var(--mud-palette-text-primary);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.ms-loupe-bar .mud-icon-button,
.ms-loupe-bar .mud-button-text {
    color: var(--mud-palette-text-primary);
}

.ms-loupe-counter {
    color: var(--mud-palette-text-primary);
    opacity: 0.85;
    white-space: nowrap;
}

.ms-loupe-title {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    opacity: 0.85;
    margin-right: 8px;
}

.ms-loupe-body {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
    padding: 10px;
    overflow: hidden;
}

.ms-loupe-body img {
    display: block;
    margin: auto;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.ms-loupe-body.is-actual {
    overflow: auto;
}

.ms-loupe-body.is-actual img {
    max-width: none;
    max-height: none;
}

/* ── non-navigating asset preview dialog (Recent filmstrip + Generate thumbnails) ── */

.ms-asset-view-title {
    min-width: 0;
}

.ms-asset-view-title .mud-typography {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ms-asset-view-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 240px;
}

.ms-asset-view-body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 240px;
    max-height: 68vh;
    padding: 12px;
    overflow: hidden;
    border-radius: 8px;
    background: var(--mud-palette-background-gray);
}

.ms-asset-view-body img,
.ms-asset-view-body video {
    display: block;
    max-width: 100%;
    max-height: calc(68vh - 24px);
    object-fit: contain;
}

.ms-asset-view-audio {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    width: 100%;
    padding: 32px 12px;
}

.ms-asset-view-audio audio {
    width: 100%;
    max-width: 560px;
}

.ms-asset-view-meta {
    margin-top: 12px;
    max-height: 30vh;
    overflow: auto;
}

.ms-asset-view-prompt {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    max-height: 96px;
    overflow-y: auto;
    font-size: 0.8rem;
    line-height: 1.45;
    opacity: 0.9;
}

/* ── filmstrip (recent media, always at the bottom) ────────────────── */

.ms-filmstrip {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    /* The right padding is roomier so a trailing tile's hover slide (+24px) stays on-screen
       at the scroll end; the vertical padding gives the strip breathing room (overflow-x
       also clips Y). */
    padding: 12px 36px 12px 12px;
    overflow-x: auto;
    background: var(--mud-palette-surface);
    border-top: 1px solid var(--mud-palette-lines-default);
}

.ms-film-label {
    flex: 0 0 auto;
    margin-right: 12px;
    white-space: nowrap;
}

.ms-film-item {
    position: relative;
    flex: 0 0 auto;
    width: 68px;
    height: 68px;
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-surface);
    transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}

/* Overlapping-cards strip: every tile tucks under the previous one… */
.ms-film-item + .ms-film-item {
    margin-left: -36px;
}

/* …and on hover the deck opens sideways instead of zooming: the tiles BEFORE the hovered one
   slide left, the ones AFTER slide right (16px overlap + an 8px breathing gap). The hovered
   tile itself never moves — it rises above the deck and takes the accent ring. */
.ms-film-item:has(~ .ms-film-item:hover) {
    transform: translateX(-24px);
}

.ms-film-item:hover ~ .ms-film-item {
    transform: translateX(24px);
}

.ms-film-item:hover {
    z-index: 3;
    border-color: var(--mud-palette-primary);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}

.ms-film-item.is-active {
    border-color: var(--mud-palette-primary);
}

.ms-film-item img,
.ms-film-item video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ms-film-item .ms-film-kind {
    position: absolute;
    right: 15px;
    bottom: 3px;
    color: #fff;
    background: rgba(0, 0, 0, 0.55);
    border-radius: 4px;
    padding: 0 4px;
    font-size: 10px;
    line-height: 14px;
}

/* ── inspector rows ────────────────────────────────────────────────── */

.ms-inspector-row {
    display: flex;
    gap: 10px;
    padding: 4px 0;
    border-bottom: 1px dashed var(--mud-palette-lines-default);
}

.ms-inspector-row:last-child {
    border-bottom: none;
}

.ms-inspector-label {
    flex: 0 0 96px;
    color: var(--mud-palette-text-secondary);
}

.ms-inspector-value {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* ── legacy shared bits (dialog + page use the same cards) ─────────── */

.ms-panel {
    padding: 16px 4px 8px 4px !important;
}

/* Buttons and switches that sit in a row of fields line up with the input boxes
   (inside a grid item the input box starts 16px down and is 40px tall). */
.ms-field-action {
    padding-top: 8px;
}

.ms-field-action--switch {
    padding-top: 9px;
}

/* The style-strength block sits level with the 40px select boxes next to it. */
.ms-slider-field {
    margin-top: -3px;
}

/* Pin each table's actions column to the right edge, like the other action buttons. */
.ms-table th:last-child,
.ms-table td:last-child {
    text-align: right;
    white-space: nowrap;
    width: 1%;
}

/* One card + header pattern for every section. */
.ms-card {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 12px;
    padding: 16px;
    margin-bottom: 16px;
}

.ms-section-head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 12px;
}

.ms-section-head .mud-icon-root {
    margin-top: 2px;
}

.ms-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}

.ms-asset-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px;
}

/* Bulk-selection checkbox overlay (Library grid, opt-in via MsAssetCard.Selectable). */
.ms-card-check {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(12, 14, 18, 0.62);
    color: #e9eaec;
    cursor: pointer;
    opacity: 0.9;
    transition: opacity 0.12s ease, background 0.12s ease;
}

.ms-card-check:hover {
    opacity: 1;
    background: rgba(12, 14, 18, 0.88);
}

.ms-card-check.is-on {
    opacity: 1;
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary);
}

/* Bulk-selection app picker (Library right panel). */
.ms-bulk-app {
    width: 100%;
}

/* Library picker dialog — thumbnail grid for choosing one stored image. */
.ms-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 10px;
    max-height: 52vh;
    overflow-y: auto;
    padding: 2px;
}

.ms-picker-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    cursor: pointer;
    transition: border-color 0.12s ease, background 0.12s ease;
}

.ms-picker-item:hover {
    border-color: var(--mud-palette-primary);
    background: rgba(89, 74, 226, 0.08);
}

.ms-picker-item.is-selected {
    border-color: var(--mud-palette-primary);
    outline: 2px solid var(--mud-palette-primary);
    background: rgba(89, 74, 226, 0.14);
}

.ms-picker-item img {
    width: 100%;
    height: 110px;
    object-fit: contain;
    border-radius: 6px;
    background: var(--mud-palette-background-gray);
}

/* Poster-less video / audio entries in the picker grid: a quiet icon tile instead of a broken image. */
.ms-picker-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 110px;
    border-radius: 6px;
    background: var(--mud-palette-background-gray);
    color: var(--mud-palette-text-secondary);
}

.ms-picker-name {
    font-size: 11px;
    line-height: 1.3;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ms-asset-card img,
.ms-asset-card video {
    width: 100%;
    max-height: 220px;
    object-fit: contain;
    border-radius: 8px;
    background: var(--mud-palette-background-gray);
}

.ms-asset-card audio {
    width: 100%;
}

.ms-asset-meta {
    min-width: 0;
    word-break: break-all;
}

.ms-asset-name {
    word-break: break-all;
}

.ms-asset-actions {
    display: flex;
    justify-content: flex-end;
}

/* Gallery pager — count on the left, page controls on the right. */
.ms-gallery-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 12px;
}

/* Gallery images open the full-size viewer. */
.ms-card-image {
    cursor: zoom-in;
}

.ms-card-image img {
    display: block;
}

/* ── legacy full-size viewer overlay (dialog) ──────────────────────── */

.ms-viewer {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    background: rgba(8, 10, 14, 0.92);
}

.ms-viewer-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    background: rgba(0, 0, 0, 0.55);
}

.ms-viewer-bar .mud-icon-button,
.ms-viewer-bar .mud-button-text {
    color: #fff;
}

.ms-viewer-counter {
    color: #fff;
    opacity: 0.85;
    white-space: nowrap;
}

.ms-viewer-title {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #fff;
    opacity: 0.85;
    margin-right: 8px;
}

.ms-viewer-body {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
    padding: 12px;
}

.ms-viewer-body img {
    display: block;
    margin: auto;
}

/* Fit: the whole image as large as the window allows. */
.ms-viewer-body.is-fit {
    overflow: hidden;
}

.ms-viewer-body.is-fit img {
    max-width: calc(100vw - 32px);
    max-height: calc(100vh - 90px); /* viewer bar + padding */
    object-fit: contain;
}

/* Actual size: 1:1 pixels with scrollbars to pan. */
.ms-viewer-body.is-actual {
    overflow: auto;
}

/* ── responsive: width steps, compact topbar, stacked layout ───────── */

/* Panel widths adapt before the layout stacks. */
@media (max-width: 1280px) {
    .ms-studio {
        --ms-left-w: 250px;
    }

    .ms-side-right {
        width: 300px;
    }
}

@media (max-width: 1100px) {
    .ms-studio {
        --ms-left-w: 232px;
    }

    .ms-side-right {
        width: 280px;
    }

    .ms-side-inner {
        padding: 12px;
    }
}

/* Compact topbar: module switcher centered on a single row. */
@media (max-width: 760px) {
    .ms-topbar {
        flex-wrap: wrap;
        row-gap: 4px;
        padding-bottom: 0px;
        border-bottom: 0px;
    }

    .ms-modules {
        order: 3;
        flex-basis: 100%;
        /* Wrapped layout: no hairline merge — the tabs just sit in their own row. */
        margin: 0;
        padding-bottom: 0;
    }

    .ms-module-label {
        display: none;
    }

    .ms-module {
        padding: 7px 10px 6px 10px;
        margin-bottom: 0;
    }
}

/* Stacked layout: canvas first, then filters, then inspector (the page scrolls). */
@media (max-width: 960px) {
    .ms-studio {
        height: auto;
        min-height: calc(100dvh - var(--mud-appbar-height, 64px));
        overflow: visible;
    }

    .ms-studio-body {
        flex-direction: column;
    }

    .ms-canvas {
        order: 1;
        min-height: 60vh;
    }

    .ms-canvas-scroll {
        overflow: visible;
    }

    .ms-side-left {
        order: 2;
    }

    .ms-side-right {
        order: 3;
    }

    .ms-side-left,
    .ms-side-right {
        width: 100%;
        max-width: none;
        max-height: none;
        overflow: visible;
        border-right: none;
        border-left: none;
        border-top: 1px solid var(--mud-palette-lines-default);
    }
}

/* Small screens: denser grid, smaller film tiles, wrapped loupe bar. */
@media (max-width: 640px) {
    .ms-studio-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 8px;
    }

    .ms-film-item {
        width: 56px;
        height: 56px;
    }

    .ms-film-item + .ms-film-item {
        margin-left: -12px;
    }

    /* Smaller overlap → smaller slides; the padding keeps the first tile's leftward slide
       on-screen (the "Recent" label is hidden here, so nothing shields it). */
    .ms-film-item:has(~ .ms-film-item:hover) {
        transform: translateX(-20px);
    }

    .ms-film-item:hover ~ .ms-film-item {
        transform: translateX(20px);
    }

    .ms-filmstrip {
        padding-left: 28px;
    }

    .ms-film-label {
        display: none;
    }

    .ms-loupe-bar {
        flex-wrap: wrap;
        row-gap: 4px;
    }

    .ms-canvas-scroll,
    .ms-side-inner {
        padding: 10px;
    }

    .ms-canvas-head,
    .ms-typebar {
        padding: 8px 10px;
    }
}

/* ── Media workflows (Generate module: node-graph workspace) ───────── */

/* Workflows tab: cards pin their action row to the bottom as a footer bar so the
   buttons line up across cards (content rows vary — description, stats, last run). */
.mw-workflow-card {
    padding-bottom: 0;
}

/* Workflows tab: bulk-selection checkbox pinned to the card header (clicks never select/open). */
.mw-workflow-check {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
}

.mw-workflow-check .mud-checkbox {
    margin: 0;
}

.mw-card-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: auto;
    padding: 8px 0 10px;
    border-top: 1px solid var(--mud-palette-lines-default);
}

.mw-save-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
}

.mw-palette-filter {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 4px;
}

.mw-palette-group {
    margin-top: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}

.mw-palette-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    margin: 2px 0;
    border-radius: 6px;
    border: 1px solid transparent;
    cursor: grab;
    user-select: none;
}

.mw-palette-item:hover {
    background: var(--mud-palette-background-gray);
    border-color: var(--mud-palette-lines-default);
}

.mw-palette-item:active {
    cursor: grabbing;
}

.mw-toolbar {
    gap: 8px;
    flex-wrap: wrap;
    row-gap: 4px;
}

/* Generate toolbar: the palette + inspector openers only matter as mobile drawers. */
.ms-tool-mobile {
    align-items: center;
    gap: 8px;
}

.mw-canvas-host {
    position: relative;
    flex: 1 1 auto;
    min-height: 320px;
    min-width: 0;
}

.mw-canvas {
    position: absolute;
    inset: 0;
}

.mw-empty {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--mud-palette-text-secondary);
    pointer-events: none;
    text-align: center;
    padding: 0 24px;
}

.mw-node-actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.mw-param {
    margin-bottom: 8px;
}

.mw-thumb-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.mw-thumb {
    width: 84px;
    height: 56px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--mud-palette-lines-default);
}

.mw-thumb-click {
    cursor: pointer;
}

.mw-thumb-click:hover {
    outline: 2px solid var(--mud-palette-primary);
}

/* Poster-less video / audio results: an icon tile keeps the strip layout intact. */
.mw-thumb-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--mud-palette-background-gray);
    color: var(--mud-palette-text-secondary);
}

.mw-report-line {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 1px 0;
}

/* Compact “Last run” output summary — the full log opens in the RunReportDialog. */
.mw-run-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.mw-thumb-more {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--mud-palette-background-gray);
    color: var(--mud-palette-text-secondary);
}

/* ── Run log dialog ─────────────────────────────────────────────────── */
.mw-runlog {
    max-height: 62vh;
    overflow-y: auto;
    padding-right: 4px;
    scrollbar-width: thin;
}

.mw-runlog-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.mw-runlog-chips .mud-chip {
    height: 22px;
    font-size: 11px;
}

.mw-runlog-warn {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    padding: 4px 8px;
    margin-bottom: 4px;
    border-left: 3px solid var(--mud-palette-warning);
    background: rgba(255, 152, 0, 0.08);
    border-radius: 4px;
    overflow-wrap: anywhere;
}

.mw-runlog-warn .mud-icon-root {
    flex: 0 0 auto;
    margin-top: 2px;
    color: var(--mud-palette-warning);
}

.mw-runlog-nodes {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.mw-runlog-node {
    display: grid;
    grid-template-columns: 96px 96px 1fr;
    align-items: start;
    gap: 8px;
    padding: 2px 0;
}

.mw-runlog-node-id {
    font-weight: 600;
}

.mw-runlog-node .mud-chip {
    height: 20px;
    margin: 0;
    font-size: 11px;
    justify-self: start;
}

.mw-runlog-node-detail {
    overflow-wrap: anywhere;
}

.mw-runlog-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 10px;
}

.mw-runlog-asset {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    cursor: pointer;
}

.mw-runlog-asset:hover {
    border-color: var(--mud-palette-primary);
}

.mw-runlog-asset img,
.mw-runlog-asset-icon {
    width: 100%;
    height: 82px;
    object-fit: cover;
    border-radius: 6px;
}

.mw-runlog-asset-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--mud-palette-background-gray);
    color: var(--mud-palette-text-secondary);
}

.mw-runlog-asset-name {
    font-size: 11px;
    line-height: 1.25;
    color: var(--mud-palette-text-secondary);
    overflow-wrap: anywhere;
}

/* Sub-workflow bindings panel (workflow.call inspector). */
.mw-binding-summary {
    overflow-wrap: anywhere;
}

.mw-binding-summary + .mud-input-control,
.mw-binding-summary ~ .mud-input-control {
    margin-top: 8px;
}

/* ── interaction + density polish ──────────────────────────────────── */

/* Panels scroll with a slim scrollbar. */
.ms-side,
.ms-canvas-scroll,
.ms-picker-grid {
    scrollbar-width: thin;
    scrollbar-color: var(--mud-palette-lines-default) transparent;
}

/* Topbar usage chip: icon + value groups. */
.ms-usage-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.ms-usage-chip .mud-icon-root {
    font-size: 15px;
    opacity: 0.75;
    margin-left: 6px;
}

.ms-usage-chip .mud-icon-root:first-child {
    margin-left: 0;
}

/* Library type filter (All / Images / Videos / Music / Voice / Sound effects). */
.ms-typebar {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    padding: 8px 14px;
    overflow-x: auto;
    scrollbar-width: none;
    background: var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.ms-typebar::-webkit-scrollbar {
    display: none;
}

.ms-type-chip {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    padding: 4px 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 999px;
    background: transparent;
    color: var(--mud-palette-text-secondary);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}

.ms-type-chip .mud-icon-root {
    font-size: 16px;
}

.ms-type-chip:hover {
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-text-primary);
}

.ms-type-chip.is-active {
    background: var(--mud-palette-primary);
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
}

.ms-type-chip.is-active .mud-icon-root {
    color: var(--mud-palette-primary-text);
}

.ms-type-chip:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

.ms-type-count {
    opacity: 0.7;
    font-variant-numeric: tabular-nums;
}

/* Card type badge (Image / Video / Music / Voice / Sound effect). */
.ms-type-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.ms-type-badge .mud-icon-root {
    font-size: 14px;
}

/* Uniform media cards: fixed media frame + single-line title. */
.ms-card-frame {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: 8px;
    background: var(--mud-palette-background-gray);
    color: var(--mud-palette-text-secondary);
}

.ms-card-frame img {
    display: block;
    width: 100%;
    height: 100%;
    max-height: none;
    object-fit: cover;
}

.ms-card-frame .ms-card-flag {
    position: absolute;
    top: 8px;
    right: 8px;
}

.ms-card-title {
    display: flex;
    align-items: center;
    min-width: 0;
}

.ms-card-title-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 500;
}

/* Cards: hover + selected states (defined once, not inline). */
.ms-asset-card {
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.ms-asset-card.is-clickable {
    cursor: pointer;
}

.ms-asset-card.is-clickable:hover {
    border-color: var(--mud-palette-primary);
    box-shadow: var(--mud-elevation-2);
}

.ms-asset-card.is-selected,
.ms-asset-card.is-checked {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 0;
}

/* Filmstrip: centered type icon for non-image tiles. */
.ms-film-icon {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #cfd1d4;
}

/* Shared empty state. */
.ms-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 48px 16px;
    color: var(--mud-palette-text-secondary);
    text-align: center;
}

.ms-empty .mud-icon-root {
    opacity: 0.6;
}

/* Card metadata stacks vertically (badge, name, style, alt). */
.ms-asset-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    word-break: normal;
    overflow-wrap: anywhere;
}

.ms-asset-name {
    word-break: normal;
    overflow-wrap: anywhere;
}

/* Alt text: keep cards compact with a two-line clamp. */
.ms-alt {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Coarse pointers get comfortable touch targets. */
@media (pointer: coarse) {
    .ms-type-chip {
        padding: 8px 14px;
    }

    .ms-card-check {
        width: 32px;
        height: 32px;
    }
}

/* ── Generate module: mobile flyout panels ─────────────────────────── */

/* Desktop: drawer chrome stays hidden; the panels sit in the flex row. */
.ms-drawer-backdrop,
.ms-mobile-only,
.ms-drawer-head {
    display: none;
}

@media (max-width: 960px) {
    /* The node canvas stays full-bleed; palette and inspector become drawers. */
    .ms-studio-body.is-generate .ms-canvas {
        order: 1;
        min-height: calc(100dvh - 190px);
    }

    .ms-studio-body.is-generate .ms-side {
        position: fixed;
        /* The app's fixed header height (measured by media-workflow.js) so the drawer
           head stays visible on layouts with a fixed top bar (e.g. the admin appbar). */
        top: var(--ms-drawer-top, 0px);
        bottom: 0;
        z-index: 1210;
        width: min(340px, 88vw);
        max-width: none;
        max-height: none;
        overflow-y: auto;
        overscroll-behavior: contain;
        box-shadow: var(--mud-elevation-8);
        transition: transform 0.22s ease;
    }

    .ms-studio-body.is-generate .ms-side-left {
        left: 0;
        width: min(320px, 88vw);
        border: none;
        transform: translateX(-104%);
    }

    .ms-studio-body.is-generate .ms-side-right {
        right: 0;
        border: none;
        transform: translateX(104%);
    }

    .ms-studio-body.is-generate .ms-side.is-open {
        transform: translateX(0);
    }

    .ms-studio-body.is-generate .ms-drawer-backdrop.is-visible {
        display: block;
        position: fixed;
        top: var(--ms-drawer-top, 0px);
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1200;
        background: rgba(0, 0, 0, 0.45);
    }

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

    .ms-mobile-only {
        display: inline-flex;
    }
}

/* Generate toolbar: secondary tools live in the overflow menu on mobile. */
@media (max-width: 960px) {
    .mw-tool-sec {
        display: none !important;
    }
}

/* Generate toolbar: compact single row on phones; long workflow names truncate. */
@media (max-width: 960px) {
    .mw-toolbar.ms-canvas-head {
        gap: 8px;
        row-gap: 6px;
    }

    .mw-tool-name {
        min-width: 0;
        flex: 0 1 auto;
        max-width: 130px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* ── AI assistant pane (Generate module, right rail) ───────────────────── */

.ms-side.is-ai {
    overflow: hidden;
}

/* The mobile media query re-asserts overflow on .ms-studio-body.is-generate .ms-side — win it. */
.ms-studio-body.is-generate .ms-side.is-ai {
    overflow: hidden;
}

.ms-side-inner.mw-ai-pane {
    padding: 0;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.mw-ai-hidden {
    display: none !important;
}

.mw-ai {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    height: 100%;
}

.mw-ai-head {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    padding: 6px 8px 0;
    flex: 0 0 auto;
}

.mw-ai-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    overscroll-behavior: contain;
}

.mw-ai-empty {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.mw-ai-msg {
    border-radius: 10px;
    padding: 8px 10px;
    font-size: 0.86rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

.mw-ai-user {
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    align-self: flex-end;
    max-width: 92%;
    white-space: pre-wrap;
}

.mw-ai-assistant {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    align-self: stretch;
}

/* Assistant replies are rendered markdown (block-level HTML from Markdig) — compact chat
   typography sized for the narrow rail. Keep the same look as the AgentChat markdown styles. */
.mw-ai-text > :first-child { margin-top: 0; }
.mw-ai-text > :last-child { margin-bottom: 0; }

.mw-ai-text p { margin: 0 0 0.6em; }

.mw-ai-text h1, .mw-ai-text h2, .mw-ai-text h3, .mw-ai-text h4, .mw-ai-text h5, .mw-ai-text h6 {
    font-size: 0.92rem;
    font-weight: 650;
    line-height: 1.3;
    margin: 0.9em 0 0.4em;
}
.mw-ai-text h1 { font-size: 1rem; }
.mw-ai-text h2 { font-size: 0.95rem; }

.mw-ai-text ul, .mw-ai-text ol {
    margin: 0 0 0.6em;
    padding-left: 1.35em;
}
.mw-ai-text li { margin: 0.15em 0; }
.mw-ai-text li > p { margin: 0 0 0.2em; }
.mw-ai-text ul > li::marker { color: var(--mud-palette-primary); }
.mw-ai-text ol > li::marker { color: var(--mud-palette-primary); font-weight: 600; }

.mw-ai-text code {
    font-family: 'JetBrains Mono', 'Cascadia Code', 'Consolas', 'SF Mono', Menlo, monospace;
    font-size: 0.8em;
    background: var(--mud-palette-background-gray);
    padding: 0.1em 0.35em;
    border-radius: 4px;
}

.mw-ai-text pre {
    background: var(--mud-palette-background-gray);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 6px;
    padding: 8px 10px;
    margin: 0 0 0.6em;
    overflow-x: auto;
    line-height: 1.5;
}
.mw-ai-text pre code {
    background: transparent;
    padding: 0;
    border-radius: 0;
    font-size: 0.78rem;
    white-space: pre;
    display: block;
}

.mw-ai-text blockquote {
    border-left: 3px solid var(--mud-palette-primary);
    background: rgba(128, 128, 128, 0.06);
    background: color-mix(in srgb, var(--mud-palette-primary) 6%, transparent);
    margin: 0 0 0.6em;
    padding: 0.35em 0.8em;
    color: var(--mud-palette-text-secondary);
    border-radius: 0 4px 4px 0;
}
.mw-ai-text blockquote p { margin: 0.25em 0; }

.mw-ai-text a { color: var(--mud-palette-primary); text-decoration: none; }
.mw-ai-text a:hover { text-decoration: underline; }

.mw-ai-text hr {
    border: none;
    border-top: 1px solid var(--mud-palette-divider);
    margin: 0.7em 0;
}

.mw-ai-text strong { font-weight: 650; }

.mw-ai-text table {
    display: block;
    overflow-x: auto;
    border-collapse: collapse;
    margin: 0 0 0.6em;
}
.mw-ai-text th, .mw-ai-text td {
    border: 1px solid var(--mud-palette-lines-default);
    padding: 3px 8px;
    text-align: left;
}
.mw-ai-text th { background: var(--mud-palette-background-gray); font-weight: 600; white-space: nowrap; }

.mw-ai-text img { max-width: 100%; border-radius: 6px; }

.mw-ai-typing {
    padding: 2px 0;
}

.mw-ai-steps {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-bottom: 6px;
}

.mw-ai-step {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.76rem;
    color: var(--mud-palette-text-secondary);
}

.mw-ai-step .mud-icon-root {
    font-size: 0.95rem;
}

.mw-ai-step-label {
    flex: 0 0 auto;
}

.mw-ai-step-detail {
    min-width: 0;
    opacity: 0.75;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mw-ai-status {
    margin-top: 8px;
    font-size: 0.76rem;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    color: var(--mud-palette-info);
    white-space: pre-wrap;
}

.mw-ai-status.is-error {
    color: var(--mud-palette-error);
}

.mw-ai-warn {
    margin-top: 3px;
    font-size: 0.74rem;
    color: var(--mud-palette-warning);
    overflow-wrap: anywhere;
}

.mw-ai-input {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 10px 12px;
    border-top: 1px solid var(--mud-palette-lines-default);
    flex: 0 0 auto;
}

/* The text field's control root is a direct child of the flex row — flex the CONTROL, never the
   MudTextField Style attribute (styles land on the inner input and become a bogus height).
   The dense control's 4px vertical margins would also make flex-end align the action button to
   the MARGIN edge (4px BELOW the visual box) — zero them and inset the button instead. */
.mw-ai-input > .mud-input-control {
    flex: 1 1 0;
    min-width: 0;
    margin-top: 0;
    margin-bottom: 0;
}

/* MudTooltip wraps each action button (Send/Stop) — inset it so the button sits inside the
   input box's bottom edge (~6px) instead of hanging below it. */
.mw-ai-input > .mud-tooltip-root {
    flex: 0 0 auto;
    margin-bottom: 6px;
}

.mw-ai-hint {
    padding: 0 12px 10px;
    flex: 0 0 auto;
    opacity: 0.7;
}

/* ── Image-op pass (upscale / cutout / resize): transparency + setup cues ── */

/* Checkerboard backdrop for images with an alpha channel (library entries with HasAlpha).
   Applied to the <img>/card element — transparent pixels composite over the pattern. */
.ms-checker {
    background-color: #f4f5f7;
    background-image:
        linear-gradient(45deg, #d9dde2 25%, transparent 25%),
        linear-gradient(-45deg, #d9dde2 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #d9dde2 75%),
        linear-gradient(-45deg, transparent 75%, #d9dde2 75%);
    background-size: 16px 16px;
    background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}

/* Inspector “served by” indicator: which integration will run an audio node (Speech / Music). */
.mw-integration-note {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    margin-top: 8px;
    padding: 8px 10px;
    border: 1px solid color-mix(in srgb, var(--mud-palette-primary) 35%, transparent);
    background: color-mix(in srgb, var(--mud-palette-primary) 7%, transparent);
    border-radius: 6px;
}

.mw-integration-note.is-elevenlabs {
    border-color: color-mix(in srgb, var(--mud-palette-tertiary) 50%, transparent);
    background: color-mix(in srgb, var(--mud-palette-tertiary) 10%, transparent);
}

.mw-integration-note > .mud-icon-root {
    color: var(--mud-palette-primary);
    flex: 0 0 auto;
    margin-top: 2px;
}

.mw-integration-note.is-elevenlabs > .mud-icon-root {
    color: var(--mud-palette-tertiary);
}

.mw-integration-note-body {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.mw-integration-provider {
    font-weight: 600;
}

/* Inspector warning: the node's AI model is not set up (Integration Hub quicklink inside). */
.mw-setup-warn {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    margin-top: 10px;
    padding: 8px 10px;
    border: 1px solid color-mix(in srgb, var(--mud-palette-warning) 45%, transparent);
    background: color-mix(in srgb, var(--mud-palette-warning) 10%, transparent);
    border-radius: 6px;
}

.mw-setup-warn > .mud-icon-root {
    color: var(--mud-palette-warning);
    flex: 0 0 auto;
    margin-top: 2px;
}

.mw-setup-warn-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.mw-setup-warn-body .mud-button-root {
    align-self: flex-start;
    padding-left: 0;
    padding-right: 0;
}

/* ── Library folder tree (Explorer-style, category-rooted) ─────────────── */

.ms-libtree {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.ms-libtree-head {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 2px 2px;
}

.ms-libtree-list {
    max-height: 44vh;
    overflow-y: auto;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 4px 2px;
}

.ms-libtree-row {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding-right: 6px;
    border-radius: 6px;
    cursor: pointer;
    user-select: none;
    color: var(--mud-palette-text-primary);
}

.ms-libtree-row:hover {
    background: var(--mud-palette-action-default-hover);
}

.ms-libtree-row.is-selected {
    background: var(--mud-palette-action-selected);
}

.ms-libtree-row.is-drop-active {
    background: var(--mud-palette-action-selected);
    outline: 1.5px dashed var(--mud-palette-primary);
    outline-offset: -2px;
}

.ms-libtree-row.is-disabled {
    opacity: 0.45;
    cursor: default;
}

.ms-libtree-row.is-category {
    font-weight: 500;
}

.ms-libtree-arrow {
    width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: 4px;
}

.ms-libtree-arrow .mud-icon-root {
    transition: transform 0.15s ease;
}

.ms-libtree-arrow.is-open .mud-icon-root {
    transform: rotate(90deg);
}

.ms-libtree-arrow.is-placeholder {
    visibility: hidden;
}

.ms-libtree-icon {
    flex: 0 0 auto;
    opacity: 0.9;
}

.ms-libtree-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.82rem;
}

.ms-libtree-count {
    flex: 0 0 auto;
    font-size: 0.7rem;
    color: var(--mud-palette-text-secondary);
    background: var(--mud-palette-action-default-hover);
    border-radius: 999px;
    padding: 1px 7px;
}

.ms-libtree-hint {
    display: block;
    padding: 6px 8px;
}

.ms-libtree.is-picker .ms-libtree-list {
    max-height: 46vh;
}

.ms-libtree-menu-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1399;
}

.ms-libtree-menu {
    position: fixed;
    z-index: 1400;
    min-width: 170px;
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 4px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
    display: flex;
    flex-direction: column;
}

.ms-libtree-menu button {
    text-align: left;
    background: none;
    border: none;
    color: var(--mud-palette-text-primary);
    font: inherit;
    font-size: 0.82rem;
    padding: 7px 10px;
    border-radius: 6px;
    cursor: pointer;
}

.ms-libtree-menu button:hover {
    background: var(--mud-palette-action-default-hover);
}

.ms-libtree-menu button.is-danger {
    color: var(--mud-palette-error);
}

/* breadcrumb row above the grid */

.ms-crumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    padding: 2px 14px 0;
}

.ms-crumb {
    background: none;
    border: none;
    color: var(--mud-palette-primary);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
    padding: 2px 4px;
    border-radius: 4px;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ms-crumb:hover:not(:disabled) {
    background: var(--mud-palette-action-default-hover);
}

.ms-crumb.is-current {
    color: var(--mud-palette-text-primary);
    cursor: default;
}

.ms-crumb-sep {
    color: var(--mud-palette-text-secondary);
    font-size: 0.8rem;
}

.ms-crumb-toggle {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: 1px dashed var(--mud-palette-lines-default);
    color: var(--mud-palette-text-secondary);
    font: inherit;
    font-size: 0.75rem;
    padding: 2px 8px;
    border-radius: 999px;
    cursor: pointer;
}

.ms-crumb-toggle.is-on {
    border-style: solid;
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary);
}

/* card drag affordances */

.ms-card-drag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
    opacity: 0.55;
    color: var(--mud-palette-text-secondary);
}

.ms-card-drag:hover {
    opacity: 1;
}

.ms-card-drag:active {
    cursor: grabbing;
}

.ms-card-drag.is-overlay {
    position: absolute;
    top: 6px;
    right: 6px;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    border-radius: 6px;
    padding: 1px;
    opacity: 0.75;
}

.ms-card-image[draggable="true"] {
    cursor: grab;
}

.ms-card-image[draggable="true"]:active {
    cursor: grabbing;
}

/* move-to-folder dialog tree */

.ms-move-tree {
    max-height: 52vh;
    overflow: auto;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 6px;
}

.ms-move-tree .ms-libtree-list {
    max-height: none;
    border: none;
    padding: 0;
}

/* ── floating upload (Library center panel) ───────────────────────────
   Desktop uses the left-panel footer button; the floating action button only exists
   on stacked/mobile layouts where the left panel is a closed drawer. */

.ms-upload-fab {
    display: none;
    position: absolute;
    left: 50%;
    bottom: 16px;
    transform: translateX(-50%);
    z-index: 6;
    align-items: center;
}

.ms-upload-fab .ms-upload-fab-btn {
    border-radius: 999px;
    padding-inline: 16px;
    letter-spacing: 0.02em;
}

/* Stacked layout: the whole page scrolls, so pin the button to the viewport. */
@media (max-width: 960px) {
    .ms-upload-fab {
        display: flex;
        position: fixed;
        bottom: 14px;
        z-index: 40;
    }

    .ms-canvas:has(.ms-upload-fab) .ms-canvas-scroll {
        padding-bottom: 70px;
    }
}

/* ── Upload dialog drop zone (the invisible file input covers the whole zone) ── */

.ms-upload-zone {
    position: relative;
    border: 1.5px dashed var(--mud-palette-lines-default);
    border-radius: 10px;
    padding: 22px 14px;
    margin-top: 10px;
    text-align: center;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.ms-upload-zone:hover {
    border-color: var(--mud-palette-primary);
    background: color-mix(in srgb, var(--mud-palette-primary) 6%, transparent);
}

.ms-upload-zone-inner {
    pointer-events: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    color: var(--mud-palette-text-secondary);
}

/* MudBlazor wraps the hidden file input in TWO zero-height, position:relative containers
   (.mud-file-upload > .mud-input-control-input-container). Those wrappers become the
   input's containing block, so its inline `position:absolute; inset:0` resolved to a
   ZERO-HEIGHT box and the drop zone never received clicks or drag-drops (the reported
   "upload button does not work"). Making the wrappers static lets the input stretch to
   .ms-upload-zone (the nearest positioned ancestor) and cover the whole zone. */
.ms-upload-zone .mud-file-upload,
.ms-upload-zone .mud-file-upload .mud-input-control-input-container {
    position: static;
}

/* Fallback chooser button inside the zone: it sits AFTER the pointer-events:none inner block,
   so it stays clickable even when the overlay-input geometry breaks (stale stylesheets). */
.ms-upload-zone .ms-upload-choose {
    display: flex;
    justify-content: center;
    margin-top: 10px;
}

/* ── Resizable left panel (drag handle sits between the panel and the canvas) ── */

.ms-resizer {
    flex: 0 0 auto;
    width: 6px;
    margin-left: -6px;
    z-index: 6;
    cursor: col-resize;
    touch-action: none;
}

.ms-resizer::after {
    content: '';
    display: block;
    width: 2px;
    height: 100%;
    margin: 0 auto;
    background: transparent;
    transition: background 0.15s ease;
}

.ms-resizer:hover::after,
body.ms-resizing .ms-resizer::after {
    background: var(--mud-palette-primary);
}

body.ms-resizing {
    cursor: col-resize;
    user-select: none;
}

/* ── Library: the folder tree fills the panel's remaining height ────────── */

.ms-library-side {
    overflow: hidden;
}

.ms-library-inner {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.ms-library-treewrap {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.ms-library-treewrap .ms-libtree {
    flex: 1 1 auto;
    min-height: 0;
}

.ms-library-treewrap .ms-libtree-list {
    max-height: none;
    flex: 1 1 auto;
    min-height: 0;
}

/* ── Mobile: Library panels become overlay drawers (ms-has-drawers) ─────── */

@media (max-width: 960px) {
    .ms-resizer {
        display: none;
    }

    /* The studio keeps the viewport height; the panels slide over the grid instead of
       stacking below it (the desktop-resize variable no longer applies). */
    .ms-studio.ms-has-drawers {
        height: calc(100dvh - var(--mud-appbar-height, 64px));
        min-height: 0;
        overflow: hidden;
    }

    .ms-studio-body.ms-has-drawers {
        flex-direction: row;
    }

    .ms-studio-body.ms-has-drawers .ms-canvas {
        order: 0;
        min-height: 0;
    }

    .ms-studio-body.ms-has-drawers .ms-canvas-scroll {
        overflow-y: auto;
    }

    .ms-studio-body.ms-has-drawers .ms-side {
        position: fixed;
        top: var(--ms-drawer-top, 0px);
        bottom: 0;
        z-index: 1210;
        width: min(340px, 88vw);
        max-width: none;
        max-height: none;
        overflow-y: auto;
        overscroll-behavior: contain;
        border: none;
        box-shadow: var(--mud-elevation-8);
        transition: transform 0.22s ease;
    }

    .ms-studio-body.ms-has-drawers .ms-side-left {
        left: 0;
        width: min(320px, 88vw);
        order: 0;
        transform: translateX(-104%);
    }

    .ms-studio-body.ms-has-drawers .ms-side-right {
        right: 0;
        order: 0;
        transform: translateX(104%);
    }

    .ms-studio-body.ms-has-drawers .ms-side.is-open {
        transform: translateX(0);
    }

    .ms-studio-body.ms-has-drawers .ms-drawer-backdrop.is-visible {
        display: block;
        position: fixed;
        top: var(--ms-drawer-top, 0px);
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1200;
        background: rgba(0, 0, 0, 0.45);
    }
}

/* ── Inspector prompt preview (requester text only; "Read more" for long notes) ── */

.ms-prompt-text {
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}

.ms-prompt-more {
    display: inline-block;
    margin-top: 2px;
    padding: 0;
    border: none;
    background: none;
    color: var(--mud-palette-primary);
    font: inherit;
    font-size: 0.78rem;
    cursor: pointer;
}

.ms-prompt-more:hover {
    text-decoration: underline;
}

/* ── Generate right rail: pinned document bar (name + Save + unsaved) ────── */

.mw-rail-head {
    position: sticky;
    top: 0;
    z-index: 3;
    flex: 0 0 auto;
    background: var(--mud-palette-surface);
}

/* The tabs now sit inside the pinned head — the head owns the sticking. */
.mw-rail-head .ms-right-tabs {
    position: static;
}

.mw-doc-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 8px 4px;
    background: color-mix(in srgb, var(--mud-palette-text-primary) 4%, var(--mud-palette-surface));
}

.mw-doc-bar .mw-doc-name {
    flex: 1 1 auto;
    min-width: 0;
}

/* ── Assets browse: grouped grid (style → kind) ─────────────────────────── */

.ms-asset-group-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 18px 0 10px;
}

.ms-asset-group-head .mud-chip {
    height: 20px;
}

.ms-asset-kind-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 10px 0 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.ms-asset-kind-head .mud-typography {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    opacity: 0.75;
}

/* ── View sheets: breadcrumb, style tree, sheet filmstrip, add-view tile ── */

.ms-crumbs {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    min-width: 0;
}

.ms-crumb {
    cursor: pointer;
    opacity: 0.85;
}

.ms-crumb:hover {
    text-decoration: underline;
    color: var(--mud-palette-primary);
}

.ms-crumb-sep {
    opacity: 0.5;
}

.ms-crumb-here {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.ms-tree-thumb {
    width: 22px;
    height: 22px;
    object-fit: cover;
    border-radius: 4px;
    border: 1px solid var(--mud-palette-lines-default);
    background: #20232a;
    flex: 0 0 auto;
}

.ms-sheet-strip {
    display: flex;
    align-items: center;
    gap: 3px;
    margin-top: 6px;
    overflow: hidden;
}

.ms-sheet-strip img {
    width: 26px;
    height: 34px;
    object-fit: cover;
    border-radius: 3px;
    border: 1px solid var(--mud-palette-lines-default);
    background: #20232a;
    flex: 0 0 auto;
}

.ms-sheet-strip-more {
    font-size: 0.68rem;
    color: var(--mud-palette-text-secondary);
    margin-left: 2px;
}

/* Uniform, responsive sheet tiles: every slot + the Add tile live on ONE grid —
   equal column widths, equal row heights; the media area absorbs slack so tiles
   stay the same size whatever the content (chips, status line, wrapped actions). */

.ms-view-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    grid-auto-rows: 1fr;
    gap: 12px;
    align-items: stretch;
}

.ms-view-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.ms-view-head {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: nowrap;
    overflow: hidden;
    min-height: 24px;
}

.ms-view-head .mud-chip {
    flex: 0 0 auto;
    height: 20px;
}

.ms-view-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

.ms-view-media {
    flex: 1 1 auto;
    position: relative;
    min-height: 150px;
    overflow: hidden;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    background: #20232a;
}

.ms-view-media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ms-view-media.is-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    background: transparent;
    border-style: dashed;
    color: var(--mud-palette-text-secondary);
}

.ms-view-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex-wrap: wrap;
    margin-top: 4px;
}

.ms-addview-tile {
    width: 100%;
    height: 100%;
    min-height: 210px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: 1px dashed var(--mud-palette-lines-default);
    border-radius: 6px;
    background: transparent;
    color: var(--mud-palette-text-secondary);
    font: inherit;
    cursor: pointer;
}

.ms-addview-tile:hover:not(:disabled) {
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary);
}

.ms-addview-tile:disabled {
    opacity: 0.55;
    cursor: default;
}

.ms-addview-tile small {
    opacity: 0.7;
}

/* ── Shared library explorer (picker dialog + inline pickers) ───────────
   Folder tree + breadcrumbs + search + thumbnail grid — the Library module's
   browsing experience, embedded wherever one stored item must be picked
   (workflow Image node, mask painter, "choose from the library" dialog). */

.ms-explorer {
    display: flex;
    gap: 12px;
    height: min(58vh, 520px);
    min-height: 300px;
}

.ms-explorer-tree {
    flex: 0 0 auto;
    width: 210px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    border-right: 1px solid var(--mud-palette-lines-default);
    padding-right: 10px;
}

.ms-explorer-tree .ms-libtree {
    flex: 1 1 auto;
    min-height: 0;
}

.ms-explorer-tree .ms-libtree-list {
    max-height: none;
    flex: 1 1 auto;
    min-height: 0;
}

/* The folder-managing hint does not apply inside pickers (no folder button). */
.ms-explorer .ms-libtree-hint {
    display: none;
}

.ms-explorer-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.ms-explorer-search {
    flex: 0 0 auto;
}

.ms-explorer-crumbs {
    padding: 4px 0 6px;
}

.ms-explorer-grid {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.ms-explorer .ms-picker-grid {
    max-height: none;
}

@media (max-width: 700px) {
    .ms-explorer {
        flex-direction: column;
        height: min(66vh, 600px);
    }

    .ms-explorer-tree {
        width: auto;
        max-height: 40%;
        border-right: none;
        border-bottom: 1px solid var(--mud-palette-lines-default);
        padding-right: 0;
        padding-bottom: 8px;
    }
}

/* ── Image-picker node param (Generate inspector) ─────────────────────── */

.mw-img-param-label {
    display: block;
    margin-bottom: 4px;
    opacity: 0.85;
}

.mw-img-param {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.mw-img-param-thumb {
    flex: 0 0 auto;
    width: 84px;
    height: 84px;
    object-fit: contain;
    border-radius: 8px;
    border: 1px solid var(--mud-palette-lines-default);
    background: var(--mud-palette-background-gray);
    cursor: pointer;
}

img.mw-img-param-thumb:hover {
    border-color: var(--mud-palette-primary);
}

.mw-img-param-none {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--mud-palette-text-secondary);
    cursor: default;
}

.mw-img-param-side {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.mw-img-param-name {
    overflow-wrap: anywhere;
}

.mw-img-param-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

.mw-img-param-help {
    display: block;
    margin-top: 6px;
}

/* ── LoRAs module: local-server scan result chips ─────────────────────── */

.ms-lora-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 6px;
    max-height: 170px;
    overflow-y: auto;
}

.ms-lora-chip {
    background: none;
    border: 1px dashed var(--mud-palette-lines-default);
    color: var(--mud-palette-text-secondary);
    font: inherit;
    font-size: 0.72rem;
    padding: 2px 8px;
    border-radius: 999px;
    cursor: pointer;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ms-lora-chip:hover:not(:disabled) {
    border-style: solid;
    border-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary);
}

.ms-lora-chip.is-registered {
    border-style: solid;
    opacity: 0.55;
    cursor: default;
}
