/* Desktop shell v3.3.5 — ops(left) | chat(right), player locked to chat column */

:root {
  --ops-map-width: 520px;
  --chats-drawer-width: 320px;
  --shell-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --stage-gutter: 16px;
}

@media (min-width: 768px) {
  /*
   * Layout tracks are physical L→R (direction:ltr on body).
   * Columns: [ ops map | chat stage ]
   * Content inside keeps RTL.
   */
  body.desktop-chat {
    --sidebar-width: 0px !important;
    /* THE STAGE IS THE COLUMN, AND THE COLUMN IS THE MEASURE.
       780px was a free-standing number, and after the measure was re-derived to
       460px (chat-canvas.css, 2026-09-02) it stopped describing anything: the
       stage stayed 780 while the answer inside it shrank to 460 and stuck to the
       stage's RTL start edge. Measured on the real page at 1440x900 the whole
       conversation lived in x 613..1110 — centre of mass 861 against a viewport
       centre of 720 — with 45% of the window empty on the left and the composer
       (780) 320px wider than the words above it on its start side. That is the
       "متن چسبیده به گوشهٔ راست" the owner reported on desktop.

       The stage is now derived instead of chosen: measure + the avatar gutter
       the row actually spends (the mark + the row's own gap, +2px of slack so
       `flex: 1 1 auto` on the body never has to shrink it).

       2026-09-04: that gutter used to be the literal 40 that 28px + 10px came
       to, so growing the mark to 34px squeezed the answer's own measure to 456
       while the reader's bubble kept its 460px cap — the two speakers stopped
       sharing a column edge, which is the one thing three separate comments in
       chat-canvas.css exist to prevent. It now reads the same tokens the row
       spends, so the next change to the mark cannot re-open it. The pair
       [avatar][answer] therefore fills the stage exactly, so #messages, the
       composer, the ask bar, the hint line and the TTS player all centre on one
       column and share both edges — at every viewport width, and for a typeface
       that carries a different measure (data-typeface="sans" reads 560 and the
       stage follows to 600) without anyone editing a second number. */
    /* 2026-09-04 — the paragraphs above are the history of a knot, and this line
       is where it was cut. The stage used to be DERIVED from the measure, which
       made "widen the app" and "lengthen the reading line" the same edit; see
       the THREE NUMBERS block in chat-canvas.css for the whole account and the
       measurement. The stage is now its own token with its own ceiling (820px),
       the measure stays 460px and caps only the sentences, and the avatar gutter
       is spent inside the row instead of being priced into the column.
       Everything the old formula protected still holds — the two speakers share
       a column edge, and a typeface that carries a different measure needs no
       second edit — because none of that depended on the stage being derived,
       only on the measure being one number. */
    --stage-max: var(--nbgc-stage);
    --composer-max: var(--stage-max) !important;
    --thread-max: var(--stage-max) !important;
    --stage-col-width: var(--nbgc-stage);
    direction: ltr !important;
    /* THE RAIL IS THE LAST TRACK, PHYSICALLY RIGHT (tracks are L→R here).
       It is a real track and not an overlay, so the stage's own `100% - 32px`
       is measured against a track the rail has already been taken out of — no
       double subtraction, and nothing floats over the canvas to buy it.
       --nbgc-rail is 0 until body carries .nabgol-workbench-on, so a robot with
       no learner chrome collapses the track to nothing and keeps the full 820. */
    grid-template-columns: minmax(0, 1fr) var(--nbgc-rail, 0px) !important;
    /* header · chat-main · chat-input · tts-player.
       The 5th row was #nabgolAskBar's; the bar is gone (its tools moved into the
       rail, where vertical space is free) and with it the 92px it took off the
       canvas — 131px in parent mode, where it also carried a banner. */
    /* 2026-09-05, work 8 — THE COMPOSER'S ROW IS 0px, AND THAT IS THE POINT.
       The composer used to own a track, so every pixel of it — bar, hint,
       disclaimer, and the 60px dossier band that was living inside it — came
       straight off the height of the conversation. It is now an `align-self:end`
       item in a zero-height track: it still lands exactly where it always did
       (bottom of the chat column, above the player's track), it still moves up
       when the player opens, and it no longer BUYS that place with reading
       height. The canvas pays for it once, as padding, below.
       Three rows would have been the tidier edit and it is not the one made
       here: four other rules across two stylesheets address the player as
       `grid-row: 4`, and renumbering them is a bigger blast radius than one
       track set to zero. */
    /* 2026-09-07 — REVERTED, BY THE OWNER, AND THE REASON IS WORTH KEEPING.
       At `auto` this track IS a band: opening the player inserts a 67px strip
       the full width of the window and the conversation pays for it
       (.chat-main 844 -> 777 at 1440). That measurement stands. What was tried
       on 2026-09-06 was to collapse the track to 0px and let the bar float on
       `align-self: end` like the composer — and the result put the player in
       the middle of the chat, which is worse than the band it removed. The bar
       is a control the reader steers with; it belongs on the page's own edge.
       If the 67px is ever bought back, it will not be by floating this bar.
       Dead below: the old note that argued for 0px. */
    /* (2026-09-06, superseded)
       Owner: «وقتی پلیر باز میشه یک عرض تمام صفحه با خودش اضافه میشه در حالی که
       قرار بوده هیچ چیزی از کادر چت بیرون نزند».
       At `auto` this track was the whole WINDOW wide the moment the player
       opened — measured live at 1440 and at 1920: a 67px band running from the
       left gutter, under the 820px bar, past the right gutter and beneath the
       میز کار rail — and the conversation paid for every pixel of it
       (.chat-main 844px -> 777px at 1440). At 0px the player becomes what the
       composer already is: an `align-self: end` item that lands at the bottom
       of the chat column, inside the stage's own track, and takes nothing off
       `1fr`. It buys its place in padding instead — --nabgol-tts-reserve. */
    grid-template-rows: var(--header-height, 64px) minmax(0, 1fr) 0px auto !important;
    /* THE LIFT IS PADDING INSIDE THE BAR, NOT SPACE ABOVE IT — and the first
       draft of this had it the other way round, which
       test_controls_always_reachable.js rejected twice in one run:
         · the fade was a ::before, so the bar's own paint measured 0 and the
           audit read a message's ویرایش/حذف chips as "readable but dead" under a
           cover that paints nothing — the see-through-scrim failure this project
           has shipped before. The gradient is on .chat-input itself now.
         · #scrollBottomBtn sat 28px ABOVE the bar it belongs to, and "a control
           inside a bar must fit inside that bar" is the rule that once caught
           the settings gear falling out of the header. It fits now.
       So the band IS the bar: 52px of transparent-to-canvas padding at its top,
       enough for the 44px jump button to live inside, and --nabgol-composer-offset
       measures the whole of it. */
    --nbgc-composer-lift: 52px;
    /* --nabgol-composer-offset is the bar's MEASURED height + 8px
       (assets/script.js, syncComposerOffsetVar — re-read on resize, on every
       generation state change, and by a ResizeObserver on the bar itself, so a
       composer that grows a line while the reader types moves this with it).
       The reserve is what #messages spends at its own bottom so the last line
       of an answer stops above the bar instead of under it. */
    /* The player is a band again, so it takes its own height off `1fr` and
       needs no reserve: only the composer floats over the canvas.
       assets/script.js still publishes --nabgol-tts-reserve; nothing reads it
       now, and it is left in place because it is inert and one revert should
       not also rewrite the 419KB file next door. */
    --nbgc-canvas-reserve: var(--nabgol-composer-offset, 76px);
  }

  /* THE PLAYER SITS ON TOP OF THE COMPOSER, NOT UNDER THE PAGE.
     Its track is 0px (above), so `align-self: end` puts its bottom edge on the
     bottom of the chat column and the margin lifts it clear of the bar — the
     same two lines the composer uses. It stays a grid item of column 1, so it
     follows the stage on its own when the dossier opens or the rail collapses;
     nothing here has to know where the stage is. */

  body.desktop-chat.nabgol-workspace-open {
    grid-template-columns: var(--ops-map-width) minmax(0, 1fr) var(--nbgc-rail, 0px) !important;
  }

  /* THE RAIL NEVER SHRINKS; THE DOSSIER DOES.
     At 1008px with the dossier open the three tracks do not fit at their
     preferred sizes (1008 − 520 − 200 = 288px of stage). One of them has to
     give, and it is not the rail: the rail carries rule 1 ("always in the same
     place") and the dossier already has a width handle and a stored width.
     1008 resolves to 248px here, leaving 528px of stage — wider than the ~502px
     the same window with the same open dossier produced before this change.
     The clamp is written into the TRACK and not into --ops-map-width itself,
     because applyOpsMapWidth() writes that variable inline on <html>: a `body`
     declaration would win over the inline one by inheritance and the width
     handle would go dead. Here the dragged value stays the preferred width and
     only the ceiling is imposed. That function clamps to the same arithmetic —
     both have to agree, or the handle can drag the stage down to nothing. */
  body.desktop-chat.nabgol-workspace-open.nabgol-workbench-on {
    grid-template-columns:
      min(var(--ops-map-width), 100% - var(--nbgc-rail) - 560px)
      minmax(0, 1fr)
      var(--nbgc-rail, 0px) !important;
  }

  /* Fullscreen ops: dossier dominates, chat stays as a narrow companion column */
  body.desktop-chat.nabgol-workspace-open.nabgol-workspace-full {
    grid-template-columns: minmax(0, 1fr) minmax(260px, 32%) var(--nbgc-rail, 0px) !important;
  }


  body.desktop-chat .desktop-right-rail {
    display: none !important;
  }

  /* Restore RTL for all user-facing chrome */
  body.desktop-chat .chat-header,
  body.desktop-chat .chat-main,
  body.desktop-chat .chat-input,
  body.desktop-chat .tts-player,
  body.desktop-chat #splitPanel,
  body.desktop-chat .sidebar,
  body.desktop-chat .sidebar-overlay,
  body.desktop-chat .message,
  body.desktop-chat .message-body,
  body.desktop-chat .message-bubble,
  body.desktop-chat .message .text {
    direction: rtl !important;
  }

  body.desktop-chat .message .text,
  body.desktop-chat .message .text p,
  body.desktop-chat .message .text li {
    text-align: right !important;
  }

  /* Header spans full width */
  body.desktop-chat .chat-header {
    grid-column: 1 / -1 !important;
    grid-row: 1 !important;
    width: 100% !important;
    max-width: none !important;
    justify-self: stretch !important;
    overflow: visible !important;
  }

  body.desktop-chat .chat-header .header-actions {
    overflow: visible !important;
    display: flex !important;
    align-items: center !important;
    flex-wrap: nowrap !important;
    gap: 6px !important;
  }

  /* Chat column — track 1, or track 2 once the dossier opens. NEVER `1 / -1`
     any more: the rail is the last track, and a span to -1 would put the
     conversation underneath it. */
  body.desktop-chat .chat-main,
  body.desktop-chat .chat-input {
    grid-column: 1 / 2 !important;
    width: 100% !important;
    max-width: none !important;
    justify-self: stretch !important;
    box-sizing: border-box !important;
    min-width: 0 !important;
  }

  body.desktop-chat.nabgol-workspace-open .chat-main,
  body.desktop-chat.nabgol-workspace-open .chat-input {
    grid-column: 2 / 3 !important;
  }

  body.desktop-chat .chat-main {
    grid-row: 2 !important;
    position: relative;
    overflow: hidden;
  }

  /* #nabgolAskBar no longer has a row of its own here — it is a section inside
     the workbench rail now (chat-workbench.css). Its old track cost the canvas
     92px of height on every tutor page, 131px with the parent-mode banner, for
     four of nine tools behind a horizontal scroller. */

  /* padding-inline: 0, and this matters. --nbgc-stage resolves `100%` against
     the USE SITE's containing block, so .input-wrapper inside a padded
     .chat-input would compute a stage 32px narrower than #messages and the
     composer would stop sharing the column's edges (the exact defect the
     `--stage-col-width` block below exists to prevent). The 32px of breathing
     room is already inside the stage formula; paying for it twice is what
     misaligns the two. */
  body.desktop-chat .chat-input {
    grid-row: 3 !important;
    padding-inline: 0 !important;
    /* THE ONE FLOATING THING ON THIS PAGE, AND THE CONTRACT THAT MAKES IT LEGAL.
       Rule 4 of the master plan forbids a floating control at the bottom of the
       canvas because it covers the last words of a reply FOREVER. The composer
       is exempt for one reason and it is checkable, not rhetorical: #messages
       reserves --nbgc-canvas-reserve of padding at its own bottom, which is this
       bar's measured height plus its fade. Scroll to the very end and the last
       line stops above the bar; there is nothing under it to cover.
       The gate asserts exactly that (test_chat_stage_workbench_gate.js,
       NO_FLOATING_OVER_CANVAS), and it asserts it for EVERY element in the band
       — the exception is the band, not this element's name. */
    align-self: end !important;
    position: relative !important;
    z-index: 6 !important;
    padding-top: var(--nbgc-composer-lift) !important;
    border-top: none !important;
    /* The bar's PAINT is chat-composer.css's, not this file's: that file loads
       after this one and already declares `background: none !important` on the
       same selector shape, so a gradient written here would lose in silence.
       Layout here, colour there — the same split the two files already keep. */
  }

  /* THE CANVAS PAYS FOR THE BAND — and it pays for it in chat-canvas.css, not
     here. That file's `body.desktop-chat #messages.chat-messages` is an id+class
     shorthand that loads after this one, so a `padding-bottom` longhand written
     here loses in silence: measured 2026-09-05, scroll-padding-bottom took the
     new value while padding-bottom stayed 30px and the last line of an answer
     sat 49px under the bar. Both declarations are in chat-canvas.css beside the
     rule that was winning; `--nbgc-canvas-reserve` above is what they read.
     `padding-bottom` and not only `scroll-padding-bottom`, and that is not
     belt-and-braces: scroll padding moves what a scrollIntoView() aims at, it
     adds no scrollable pixel, so on its own it leaves the last line exactly
     where it was. */

  /* WORK 11.1 — «پرش به آخرین پیام» rides with the composer now.
     It used to be an absolute child of .chat-main sitting 24px above the
     conversation's bottom edge, i.e. on top of whatever message happened to be
     there while the reader was scrolled up. assets/script.js moves the node
     into .chat-input on desktop; here it is placed inside the band, straddling
     the bar's top edge, where the fade is already paying for the pixels.
     Everything about when it shows and what it does is untouched. */
  body.desktop-chat .chat-input > .scroll-bottom-btn {
    position: absolute !important;
    top: 4px !important;               /* 4 + 44 = 48, inside the 52px band */
    bottom: auto !important;
    left: 50% !important;
    right: auto !important;
    z-index: 2 !important;
  }

  /* Player lives in same grid column as chat → never under the ops map */
  body.desktop-chat .tts-player.tts-player-dock.show {
    grid-column: 1 / 2 !important;
    grid-row: 4 !important;
    position: relative !important;
    display: flex !important;
    flex-direction: column !important;
    left: auto !important;
    right: auto !important;
    inset: auto !important;
    width: var(--stage-col-width) !important;
    max-width: min(var(--stage-col-width), 100%) !important;
    /* (2026-09-06, superseded — reverted 2026-09-07 by the owner)
       Row 4 is 0px now, so `align-self: end` drops this bar's bottom edge onto
       the bottom of the chat column and the margin lifts it clear of the bar
       below — the same two lines .chat-input has used since work 8. What it
       buys: no page-wide band, and .chat-main keeps all 844px at 1440 instead
       of falling to 777px. What it costs: the bar now floats over the canvas,
       so #messages reserves --nabgol-tts-reserve as well (rule 4's exception is
       the BAND, not an element's name — the gate measures exactly that).
       It is still a grid item of the stage's own column, so it follows the
       stage when the dossier opens without being told where the stage is. */
    margin: 0 auto !important;
    margin-inline: auto !important;
    padding: 12px 18px 10px !important;
    box-sizing: border-box !important;
    overflow: hidden !important;
    /* Top corners only: it is welded to the bottom edge of the window again. */
    border-radius: 14px 14px 0 0 !important;
    justify-self: center !important;
    z-index: 4 !important;
    transition: width 0.28s var(--shell-ease), max-width 0.28s var(--shell-ease);
  }

  body.desktop-chat.nabgol-workspace-open .tts-player.tts-player-dock.show {
    grid-column: 2 / 3 !important;
  }

  body.desktop-chat .tts-player.tts-player-dock.show .tts-player-row,
  body.desktop-chat .tts-player.tts-player-dock.show .tts-subtitle {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    box-sizing: border-box !important;
  }

  body.desktop-chat .tts-player.tts-player-dock.show .tts-close-btn {
    right: 10px !important;
    left: auto !important;
    transform: translateY(-50%) !important;
  }

  body.desktop-chat .tts-player.tts-player-dock.show .tts-minimize-btn {
    right: 46px !important;
    left: auto !important;
    transform: translateY(-50%) !important;
  }

  /* Stage content centered inside chat column.
     Every DIRECT child of .chat-input is listed, because .chat-input's own
     padding-inline is now 0 (see above): anything left out would run the full
     width of the track and stop sharing the column's edges. When a new row is
     added to the composer it belongs in this list. */
  body.desktop-chat .chat-messages,
  body.desktop-chat .chat-input .input-wrapper,
  body.desktop-chat .chat-input .file-preview,
  body.desktop-chat .chat-input > .plant-analysis-picker,
  body.desktop-chat .chat-input > .plant-organ-picker,
  /* .composer-hint and .composer-ai-disclaimer used to be listed here as two
     separate direct children. They are now both inside .composer-chrome (work 8,
     §21.3) and must NOT be stretched individually — a stage-wide <p> cannot sit
     on a row beside another stage-wide <p>. The wrapper is the child that gets
     the column's edges; the row inside it centres. */
  body.desktop-chat .composer-chrome {
    width: var(--stage-col-width) !important;
    max-width: var(--stage-col-width) !important;
    margin-left: auto !important;
    margin-right: auto !important;
    box-sizing: border-box !important;
    transition: width 0.28s var(--shell-ease), max-width 0.28s var(--shell-ease);
  }

  body.desktop-chat .chat-messages {
    padding-inline: 0 !important;
    overflow-x: hidden !important;
  }

  /* Think ritual — centered column; never collapse in flex */
  body.desktop-chat .chat-messages > .typing-indicator,
  body.desktop-chat .chat-messages > .typing-indicator.show {
    align-self: stretch !important;
    width: 100% !important;
    max-width: 100% !important;
    flex: 0 0 auto !important;
    min-height: auto !important;
    margin: 12px 0 18px !important;
    margin-inline: 0 !important;
    padding: 0 !important;
    box-sizing: border-box !important;
    overflow: visible !important;
    position: relative !important;
    inset: auto !important;
    transform: none !important;
    left: auto !important;
    right: auto !important;
    display: none;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 0 !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
  }

  body.desktop-chat .chat-messages > .typing-indicator.show {
    display: flex !important;
    min-height: 200px !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
  }

  body.desktop-chat .chat-messages > .typing-indicator .nabgol-think-stage,
  body.desktop-chat .chat-messages > .typing-indicator .nabgol-think-row {
    max-width: min(100%, 420px) !important;
    margin-inline: auto !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
  }

  body.desktop-chat .chat-messages > .typing-indicator .nabgol-think-video {
    background: transparent !important;
  }

  body.desktop-chat .chat-messages > .typing-indicator .stop-btn,
  body.desktop-chat .chat-messages > .typing-indicator .typing-dots {
    display: none !important;
  }

  /* Workflow badge spacing — not stuck to message above */
  body.desktop-chat .nabgol-workflow-badge {
    display: inline-flex !important;
    margin: 16px 0 12px !important;
  }

  /* Chats history dropdown — fixed + JS clamp keeps panel inside the viewport */
  body.desktop-chat .chats-menu-wrap {
    position: relative !important;
    display: inline-flex !important;
    align-items: center;
    flex-shrink: 0;
    overflow: visible !important;
  }

  body.desktop-chat .chat-header,
  body.desktop-chat .chat-header .header-actions {
    overflow: visible !important;
  }

  body.desktop-chat .chat-header .header-actions .desktop-toolbar {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  body.desktop-chat .chats-menu-btn {
    display: inline-flex !important;
    align-items: center;
    gap: 8px;
  }

  body.desktop-chat .chats-menu-btn .btn-label,
  body.desktop-chat .new-chat-header-btn .btn-label {
    max-width: 12rem !important;
    opacity: 1 !important;
    margin-inline-start: 2px !important;
  }

  body.desktop-chat .chats-menu-btn[aria-expanded="true"] {
    background: rgba(16, 185, 129, 0.16) !important;
    color: #6ee7b7 !important;
    border-color: rgba(52, 211, 153, 0.35) !important;
  }

  body.desktop-chat .chats-menu-wrap .sidebar,
  body.desktop-chat .sidebar {
    position: fixed !important;
    inset: auto !important;
    /* Anchored to the bar, not to the number the bar used to be. Step 5 took
       the desktop header from 64px to 56px (chat-header.css §9) and a literal
       here would have left this popover floating 8px below its own button. */
    top: var(--header-height, 64px) !important;
    left: 8px !important;
    right: auto !important;
    bottom: auto !important;
    width: min(92vw, 340px) !important;
    max-width: min(92vw, 340px) !important;
    height: auto !important;
    max-height: min(70vh, 520px) !important;
    grid-column: auto !important;
    grid-row: auto !important;
    z-index: 1200 !important;
    border: 1px solid rgba(148, 163, 184, 0.22) !important;
    border-radius: 14px !important;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.42) !important;
    background: rgba(11, 18, 32, 0.98) !important;
    transform: translateY(-6px) scale(0.98);
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
    overflow: hidden !important;
    display: flex !important;
    flex-direction: column !important;
    transition:
      opacity 0.22s var(--shell-ease),
      transform 0.26s var(--shell-ease),
      visibility 0.26s;
  }

  body.desktop-chat.nabgol-chats-open .chats-menu-wrap .sidebar,
  body.desktop-chat.nabgol-chats-open .sidebar,
  body.desktop-chat .sidebar.open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0) scale(1);
  }

  /* Forever (2026-08-20): this popover's background is a fixed dark glass card in
     BOTH day and night themes (see rgba(11,18,32,.98) above). Everything inside it
     must therefore use fixed light-on-dark colors too — the normal var(--text)/
     var(--text-secondary) tokens flip to near-black in light theme and silently
     erase every title/input here (measured: chat title + search box unreadable,
     ~1.3:1 contrast). Never swap these back to theme variables. */
  body.desktop-chat .sidebar .brand-name,
  body.desktop-chat .sidebar .sidebar-header h3,
  body.desktop-chat .sidebar .chat-name {
    color: #f3f6fa !important;
  }
  body.desktop-chat .sidebar .brand-desc,
  body.desktop-chat .sidebar .chat-date {
    color: rgba(243, 246, 250, 0.68) !important;
  }
  body.desktop-chat .sidebar .sidebar-section-title {
    color: rgba(243, 246, 250, 0.55) !important;
  }
  body.desktop-chat .sidebar-close-mobile,
  body.desktop-chat .sidebar .chat-delete,
  body.desktop-chat .sidebar .history-delete,
  body.desktop-chat .sidebar .chat-edit {
    color: rgba(243, 246, 250, 0.75) !important;
  }
  body.desktop-chat .sidebar .chat-edit:hover {
    color: #4ade80 !important;
    background: rgba(34, 197, 94, 0.14) !important;
  }
  body.desktop-chat .sidebar-close-mobile:hover {
    color: #fff !important;
    background: rgba(255, 255, 255, 0.1) !important;
  }
  body.desktop-chat .sidebar .search-input-wrap input,
  body.desktop-chat .sidebar .search-box input {
    color: #f3f6fa !important;
    background: rgba(255, 255, 255, 0.06) !important;
    border-color: rgba(255, 255, 255, 0.14) !important;
  }
  body.desktop-chat .sidebar .search-input-wrap input::placeholder,
  body.desktop-chat .sidebar .search-box input::placeholder {
    color: rgba(243, 246, 250, 0.5) !important;
  }

  body.desktop-chat .sidebar #chatList {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  body.desktop-chat .sidebar .sidebar-new-chat,
  body.desktop-chat .sidebar .new-chat-sidebar {
    flex: 0 0 auto !important;
  }

  /* When dossier is open, history is a chat-column popover — never a second full-screen layer */
  body.desktop-chat.nabgol-workspace-open.nabgol-chats-open .sidebar-overlay,
  body.desktop-chat.nabgol-workspace-open .sidebar-overlay.show {
    opacity: 0 !important;
    pointer-events: none !important;
  }

  body.desktop-chat.nabgol-workspace-open .sidebar {
    z-index: 1200 !important;
  }

  /* U10 — empty welcome must not sit behind an open dossier */
  body.desktop-chat.nabgol-workspace-open #emptyState,
  body.desktop-chat.nabgol-workspace-open .chat-messages > .empty {
    display: none !important;
  }

  body.desktop-chat .sidebar-overlay {
    position: fixed !important;
    inset: 0 !important;
    z-index: 70 !important;
    background: rgba(2, 6, 23, 0.28) !important;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s var(--shell-ease);
  }

  body.desktop-chat .sidebar-overlay.show {
    opacity: 1;
    pointer-events: auto;
  }

  body.desktop-chat .sidebar-close-mobile {
    display: inline-flex !important;
  }

  body.desktop-chat .sidebar #chatList {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
  }

  /*
   * Ops map = grid column 1 = physical LEFT.
   * Resizable via .nabgol-width-handle on the chat-facing (right) edge.
   */
  body.desktop-chat #splitPanel,
  body.desktop-chat #splitPanel.split-panel,
  body.desktop-chat #splitPanel.nabgol-workspace-v2 {
    position: relative !important;
    top: auto !important;
    bottom: auto !important;
    left: auto !important;
    right: auto !important;
    inset: auto !important;
    grid-column: 1 / 2 !important;
    grid-row: 2 / -1 !important;
    width: 100% !important;
    max-width: none !important;
    min-width: 0 !important;
    height: auto !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    flex: none !important;
    z-index: 5 !important;
    box-sizing: border-box !important;
    transform: none !important;
  }

  body.desktop-chat #splitPanel:not(.open),
  body.desktop-chat #splitPanel.nabgol-workspace-v2:not(.open) {
    display: none !important;
    width: 0 !important;
    overflow: hidden !important;
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
  }

  body.desktop-chat #splitPanel.open,
  body.desktop-chat #splitPanel.nabgol-workspace-v2.open {
    display: flex !important;
    flex-direction: column !important;
    width: 100% !important;
    background: #0b1220 !important;
    border-right: 1px solid rgba(148, 163, 184, 0.28) !important;
    border-left: 0 !important;
    box-shadow: 12px 0 36px rgba(0, 0, 0, 0.35) !important;
    opacity: 1;
    pointer-events: auto;
    visibility: visible;
    overflow: hidden !important;
  }

  body.desktop-chat #splitPanel.nabgol-resizing {
    transition: none !important;
  }

  /*
   * THE WORKBENCH RAIL — «میزِ کار».
   * `-2 / -1` is the last track whichever template is in force: two tracks with
   * the dossier closed, three with it open, four when the control surface is
   * out. Written as a negative span on purpose — an absolute number here would
   * have to be edited again by whoever adds the next column, and would silently
   * land on the wrong one until someone looked at a screenshot.
   * Row 2 to the end: it starts under the header and runs to the bottom of the
   * window, past the composer. It is a column, not a floating card, so nothing
   * it contains can ever cover the last line of an answer (rule 4).
   */
  body.desktop-chat #nabgolWorkbench {
    grid-column: -2 / -1 !important;
    grid-row: 2 / -1 !important;
    min-width: 0 !important;
    z-index: 6;
  }

  /* No rail mounted → no track, and the stage takes the whole window. */
  body.desktop-chat:not(.nabgol-workbench-on) #nabgolWorkbench {
    display: none !important;
  }
}

body.nabgol-resizing-ops,
body.nabgol-resizing-ops * {
  cursor: col-resize !important;
  user-select: none !important;
}

.nabgol-width-handle {
  position: absolute;
  top: 0;
  right: 0;
  left: auto;
  width: 10px;
  height: 100%;
  cursor: col-resize;
  z-index: 8;
  background: linear-gradient(270deg, rgba(56, 189, 248, 0.0), rgba(56, 189, 248, 0.22));
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.nabgol-width-handle::after {
  content: '';
  position: absolute;
  top: 50%;
  right: 3px;
  left: auto;
  width: 3px;
  height: 48px;
  margin-top: -24px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.55);
  box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.35);
}

.nabgol-width-handle:hover,
#splitPanel.nabgol-resizing .nabgol-width-handle {
  background: rgba(56, 189, 248, 0.38);
}

.nabgol-width-handle:hover::after,
#splitPanel.nabgol-resizing .nabgol-width-handle::after {
  background: #38bdf8;
}

/* Process chart */
.nabgol-process-chart {
  overflow-x: auto;
  margin: 0 0 14px;
  padding: 4px 2px 2px;
}

.nabgol-process-svg {
  width: 100%;
  min-width: 260px;
  height: 86px;
  display: block;
}

.nabgol-process-link {
  stroke: rgba(148, 163, 184, 0.35);
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
}

.nabgol-process-link.is-done {
  stroke: rgba(52, 211, 153, 0.7);
}

.nabgol-process-node { stroke-width: 2; }
.nabgol-process-node.is-done { fill: rgba(16, 185, 129, 0.25); stroke: #34d399; }
.nabgol-process-node.is-active { fill: rgba(14, 165, 233, 0.28); stroke: #38bdf8; }
.nabgol-process-node.is-pending { fill: rgba(15, 23, 42, 0.5); stroke: rgba(148, 163, 184, 0.45); }

.nabgol-process-num {
  fill: #e2e8f0;
  font-size: 11px;
  font-weight: 700;
  font-family: Vazirmatn, Tahoma, sans-serif;
}

.nabgol-process-label {
  fill: #94a3b8;
  font-size: 10px;
  font-family: Vazirmatn, Tahoma, sans-serif;
}

.nabgol-pipeline-ico {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.nabgol-step-ico {
  width: 22px;
  height: 22px;
  display: block;
}

.nabgol-pipeline-step.is-done .nabgol-step-ico { color: #34d399; }
.nabgol-pipeline-step.is-active .nabgol-step-ico { color: #38bdf8; }
.nabgol-pipeline-step.is-pending .nabgol-step-ico { color: #64748b; }

.nabgol-pipeline-copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.nabgol-pipeline-status {
  font-size: 11px;
  opacity: 0.75;
}

.nabgol-pipeline-step .nabgol-pipeline-index {
  display: none;
}

body.desktop-chat .version-controls .prev-version,
body.desktop-chat .version-controls .next-version {
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
}
body.desktop-chat .version-controls .prev-version .ico,
body.desktop-chat .version-controls .next-version .ico {
  width: 14px !important;
  height: 14px !important;
}
body.desktop-chat .tts-speed-btn .ico {
  width: 16px !important;
  height: 16px !important;
}
body.desktop-chat .tts-speed-btn .speed-emoji {
  display: none !important;
}
