/* ============================================================================
   THE WORKBENCH — «میزِ کار»  ·  chat-workbench.css
   docs/CHAT_REDESIGN_MASTER_PLAN.md §5 (کارِ ۲، دسکتاپ) · §6 و §17 (کارِ ۳، موبایل)

   ONE DOOR, NOT FOUR.
   Before this file a tutor chat had four separate controls leading into one
   learner's capabilities, and three of them were conditional:

     #nabgolProgressChip   header, `hidden` until a progress report exists
     #nabgolDossierChip    header (desktop) / FLOATING (phone), only once a
                           document has been written
     #nabgolCsDock         FLOATING, bottom-right, over the last line of the
                           newest answer, labelled «استودیو» until first opened
     #nabgolAskBar         a 92px horizontal band above the composer (131px in
                           parent mode) showing 4 of 9 tools behind a scroller;
                           on the phone, a bottom sheet behind an unlabelled
                           composer button that did not exist until the first
                           reply

   The workbench replaces the arrangement rather than adding a fifth door. Its
   sections are built from the SAME capability registry the old surfaces read
   (chat-workspace.js listCapabilitiesByHome), so a capability added next year
   appears with no edit to this file and no new door. The order of the sections
   is fixed and never reorders itself:
   special mode · guidance · ask the teacher · progress · reports · settings.

   TWO SHAPES OF ONE PLACE.
     desktop  #nabgolWorkbench      a real grid track (chat-desktop-shell.css),
                                    always open beside the conversation
     phone    #nabgolWorkbenchSheet a top-dropdown panel behind ONE fixed header
                                    icon, using the #moreSheet mechanism that
                                    already existed (chat-mobile-flagship.css)
   A phone has no 200px of horizontal room to give away, so the same column
   arrives behind one press instead of standing open. Everything about WHAT is
   in it is shared: this file's `.nabgol-wb-*` shape rules are written once,
   outside any media query, and each shell only adds the geometry of its own
   container. A rule that lives in one shell's block and not the other is how
   the two drift apart, and this surface must not drift — §17.

   WHY A COLUMN AND NOT A CARD. Vertical space is free in both shapes, so every
   one of the nine tools shows with its own one-line explanation instead of four
   pills and a «بیشتر…» that a 60px row label could push off the edge. And a
   column can never sit on top of the conversation, which is the whole of rule 4.

   THEME. Every colour is a --nbgc-* token from chat-canvas.css with a night
   fallback, because this surface exists in both themes and a hardcoded dark
   value here is the same defect that made the ask bar unreadable in day mode
   (see the contrast block in chat-workspace.css). Gate: the contrast half of
   live/tools/test_ask_bar_theme_gate.js.
   ========================================================================== */

#nabgolWorkbench {
  display: none;
}

/* ── THE WORKBENCH'S OWN QUIET INK, AND WHY IT IS NOT --nbgc-ink-soft ───────
   MEASURED, not chosen (test_ask_bar_theme_gate.js, desktop-light): the quiet
   token is derived against the page's own canvas, where it is 6.4:1. In the
   rail it lands on a button surface on top of a tinted column — two translucent
   washes over the day canvas compose to rgb(221,224,228) — and the same ink
   measures 4.42:1 there. Under the platform's floor, on the surface that
   explains what every tool does.
   Two stacked surfaces is a different background, so it gets a different ink.
   #4b5563 measures 5.70:1 on that composite. Night is unchanged: the dark rail
   reads 5.54:1 with the ordinary token and needs no help.
   The phone panel stacks the same two washes, so it takes the same ink. */
:root {
  --nbgw-rail-muted: #94a3b6;
}

html[data-theme="light"] {
  --nbgw-rail-muted: #4b5563;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-state,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section-title,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn-hint,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-progress-streak,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-empty,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn-hint,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-help {
  color: var(--nbgw-rail-muted) !important;
}

/* ══ SHARED SHAPE — written once, used by both shells ═══════════════════════
   None of these class names exists outside a workbench host, so they need no
   `body.desktop-chat` / `body.mobile-chat` scope; giving them one would only
   invite the next edit to fix one copy and leave the other. */

/* The name lives here and not in the header bar — the header has a fixed
   budget (docs/ROUTER.md §1) and «افزودنِ چیزی به نوارِ بالا» is refused by
   §13 of the master plan. On the phone this is also why the door is an icon
   with no text beside it. */
.nabgol-wb-head {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 12px 10px;
  border-bottom: 1px solid var(--nbgc-hairline, rgba(148, 168, 200, 0.16));
}

.nabgol-wb-title {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--nbgc-ink-strong, #f3f7fb);
}

/* "A special mode is on" — the first of the three places §7 asks for it to be
   visible. The other two are the per-message badge and the accent line below;
   the amber banner that used to carry this alone cost the canvas 39px of
   height and disappeared the moment the ask bar was hidden. */
.nabgol-wb-state {
  margin: 0;
  font-size: 0.74rem;
  line-height: 1.4;
  color: var(--nbgc-ink-soft, #94a3b6);
}

/* ── ANY SPECIAL MODE, NOT ONLY THE PARENT ONE ──────────────────────────────
   `teacher_mode` became a real toggle in e2424ab while every «a mode is on»
   signal still read `parent_mode`, so a user in teacher mode had NOTHING on
   screen saying so. chat-workspace.js::syncAudienceModeFlag now stamps
   `nabgol-special-mode-on` plus `data-nabgol-mode`, and these read that.
   The two modes get different marks on purpose: an identical amber for both
   would say «a mode is on» while still refusing to say which.

   TEACHER'S PAIR IS NOT HERE. It was, twice — and both copies were dead,
   because the §30 block at the foot of this file redeclares it. Two live
   sources for one colour is how §34-10-د-۹ gets broken by accident: a session
   changes the copy it found first and measures a value the page never paints.
   Parent's pair lives here; teacher's lives in §36-4-۱ below, once. */
:root {
  --nbgw-mode-mark: #fbbf24;
  --nbgw-mode-ink: #fde68a;
}

html[data-theme="light"] {
  /* MEASURED, not picked: on the day panel composite (rgb(221,224,228)) the
     night ink above is ~1.4:1 and unreadable. #92400e is 6.13:1 there. */
  --nbgw-mode-ink: #92400e;
}

body.nabgol-special-mode-on :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-state {
  color: var(--nbgw-mode-ink, #fde68a) !important;
  font-weight: 600;
}

.nabgol-wb-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  padding: 4px 10px 16px;
}

.nabgol-wb-section {
  padding: 10px 0 2px;
  border-bottom: 1px solid var(--nbgc-hairline, rgba(148, 168, 200, 0.16));
}

.nabgol-wb-section:last-child {
  border-bottom: 0;
}

.nabgol-wb-section-title {
  margin: 0 0 6px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--nbgc-ink-soft, #94a3b6);
}

.nabgol-wb-stack {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* One button shape for reports, settings and progress. The tools in «از معلم
   بخواه» reuse .nabgol-ask-bar-btn instead, so they keep the class the
   registry gates already assert on. */
.nabgol-wb-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  box-sizing: border-box;
  appearance: none;
  text-align: right;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid var(--nbgc-hairline-strong, rgba(148, 168, 200, 0.26));
  background: var(--nbgc-surface-2, rgba(148, 168, 200, 0.11));
  color: var(--nbgc-ink, inherit);
  font-family: inherit;
  font-size: 0.82rem;
  line-height: 1.35;
  cursor: pointer;
}

.nabgol-wb-btn:hover,
.nabgol-wb-btn:focus-visible {
  border-color: var(--nbgc-accent-edge, rgba(52, 211, 153, 0.28));
  background: var(--nbgc-accent-wash, rgba(52, 211, 153, 0.10));
  outline: none;
}

.nabgol-wb-btn:focus-visible {
  outline: 2px solid var(--nbgc-accent, #34d399);
  outline-offset: 2px;
}

.nabgol-wb-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.nabgol-wb-btn-label { font-weight: 600; }

.nabgol-wb-btn-hint {
  font-size: 0.72rem;
  color: var(--nbgc-ink-soft, #94a3b6);
  line-height: 1.35;
}

/* Progress summary — the header chip's two lines, in the workbench, where they
   are visible without opening anything on desktop and behind one press on a
   phone. Pressing it opens the same progress pane tutor-quest.js has always
   mounted; nothing about that pane changes. */
.nabgol-wb-progress-line {
  display: block;
  font-weight: 600;
}

.nabgol-wb-progress-streak {
  display: block;
  font-size: 0.72rem;
  color: var(--nbgc-ink-soft, #94a3b6);
}

.nabgol-wb-empty {
  margin: 0;
  font-size: 0.74rem;
  line-height: 1.45;
  color: var(--nbgc-ink-soft, #94a3b6);
}

/* ── THE DOSSIER DOOR (work 7, master plan §20) ────────────────────────────
   The reader's own open document, first in «گزارش‌ها», above the tools that make
   new ones. It reads as the section's subject rather than one more tool, so it
   carries the accent EDGE — one step of weight, never a fill: the accent budget
   is spent on the composer's send button and on the canvas's closing question,
   and a workbench button that shouted louder than either would be chrome talking
   over content.

   Shared shape, like everything else in this block: the desktop rail is where
   §20 puts it, and a phone panel that later wants the same button gets it with
   no second copy to keep in step.

   The title is written by the model and can be a long Persian sentence, so the
   label is clamped to two lines rather than truncated to a width nobody can
   predict — the 1216px band this replaced never had to answer that question and
   a 179px column does. */
.nabgol-wb-btn.nabgol-wb-dossier {
  border-color: var(--nbgc-accent-edge, rgba(52, 211, 153, 0.28));
}

.nabgol-wb-btn.nabgol-wb-dossier .nabgol-wb-btn-label {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

.nabgol-wb-dossier-count {
  font-size: 0.72rem;
  color: var(--nbgw-rail-muted, #94a3b6);
  line-height: 1.35;
}

/* ── THE ASK SECTION, RE-LAID AS A COLUMN ──────────────────────────────────
   #nabgolAskBar (desktop) and #nabgolAskSheet (phone) keep their ids and every
   class inside them: the registry, the click handlers, the busy/disabled
   behaviour and eight test files address them by those names, and none of that
   was what was wrong with them. What was wrong was where they sat and how much
   they showed. Here it is a plain block inside a section — no band, no border,
   no background of its own, no 4-item cap, no horizontal scroller and no
   «بیشتر…» to be pushed off an edge. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-ask-bar, .nabgol-wbm-ask) {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  gap: 0;
}

/* The nine tools become a column in both shells: each one carries a sentence of
   its own, and a sentence does not fit in a pill on a shared row. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex-wrap: nowrap;
  gap: 6px;
  overflow: visible;
  min-width: 0;
}

/* THE TWO CHOICES STAY SEGMENTED ROWS — and only the rail stacks them.
   «حالتِ ویژه» is two words and «کمکم کن» is three; they are a choice among
   peers, which a segmented row says and a stack of full-width buttons does not.
   Stacking them costs about 150px, and the phone panel is capped at a fraction
   of the screen — measured at 390px, stacking pushed «از معلم بخواه» below the
   fold, so the panel opened onto two settings and none of the nine tools. The
   rail has a whole column's height and no such pressure, so it keeps the stack
   it was designed with. */
#nabgolWorkbench .nabgol-ask-prefs-row,
#nabgolWorkbench .nabgol-audience-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex-wrap: nowrap;
  gap: 6px;
  overflow: visible;
  min-width: 0;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-ask-bar, .nabgol-wbm-ask) > * + * {
  margin-top: 10px;
}

/* The rows carry their own inline name («کمکم کن:», «حالت ویژه:») for the
   shells that have no section heading above them — any cached DOM still
   painting the old docked bar or the old bottom sheet. In the workbench the
   heading says it once, so the inline copy is hidden rather than removed: the
   element is part of the row's shape and two gates read it. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-prefs-label {
  display: none;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-ask-bar, .nabgol-wbm-ask) > .nabgol-wb-section-title {
  margin-top: 14px;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn,
#nabgolWorkbench .nabgol-ask-pref-btn,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-sheet-item {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  box-sizing: border-box;
  white-space: normal;
  text-align: right;
  border-radius: 10px;
  padding: 8px 10px;
  line-height: 1.35;
}

/* ONE PANEL, ONE BUTTON SHAPE.
   The nine tools arrive as .sheet-item, which in a bottom sheet is a flat text
   row with no card — right for a list of four commands, wrong beside the
   bordered pills «حالتِ ویژه» and «کمکم کن» render as. Inside the panel every
   pressable thing gets the same card, so the surface reads as one thing rather
   than as two menus stacked. */
#nabgolWorkbenchSheet .nabgol-ask-sheet-item {
  border: 1px solid var(--nbgc-hairline-strong, rgba(148, 168, 200, 0.26));
  background: var(--nbgc-surface-2, rgba(148, 168, 200, 0.11));
  color: var(--nbgc-ink, inherit);
  margin-bottom: 6px;
}

#nabgolWorkbenchSheet .nabgol-ask-sheet-item:hover,
#nabgolWorkbenchSheet .nabgol-ask-sheet-item:focus-visible {
  border-color: var(--nbgc-accent-edge, rgba(52, 211, 153, 0.28));
  background: var(--nbgc-accent-wash, rgba(52, 211, 153, 0.10));
  outline: none;
}

#nabgolWorkbenchSheet .nabgol-ask-sheet-item:focus-visible {
  outline: 2px solid var(--nbgc-accent, #34d399);
  outline-offset: 2px;
}

/* The sheet's rows padded themselves against a full-bleed bottom sheet; inside
   a card column that padding is a second, wrong margin. */
#nabgolWorkbenchSheet :is(.nabgol-ask-prefs-row, .nabgol-audience-row).nabgol-ask-sheet-prefs {
  padding-inline: 0;
  padding-block: 4px 8px;
  border-bottom: 0;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-help {
  margin: 6px 0 0;
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--nbgc-ink-soft, #94a3b6);
}

/* The banner keeps its class and its wording, so test_parent_mode.js still
   recognises it; it costs the canvas nothing here. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-parent-mode-banner {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  margin-bottom: 10px;
  padding: 8px 10px;
  border-radius: 10px;
  line-height: 1.4;
}

/* ══ DESKTOP — the rail's own geometry ══════════════════════════════════════ */
@media (min-width: 768px) {
  body.desktop-chat.nabgol-workbench-on #nabgolWorkbench {
    display: flex;
    flex-direction: column;
    min-height: 0;
    box-sizing: border-box;
    direction: rtl;
    background: var(--nbgc-surface, rgba(148, 168, 200, 0.07));
    border-inline-start: 1px solid var(--nbgc-hairline, rgba(148, 168, 200, 0.16));
    color: var(--nbgc-ink, #e8eef6);
    font-family: inherit;
  }

  /* ── ONE PROGRESS SURFACE, AND CSS DECIDES IT ────────────────────────────
     tutor-quest.js also hides the header chip when a workbench is mounted, and
     that is the honest place for the decision — but it is a decision made by
     script, and a script decision has a window before it runs. The chip was
     caught painted in exactly that window in a live capture (the probe shot the
     page mid-boot), showing «کارِ امروز ۰ از ۱» in the header while the rail's
     own line said «۰ از ۸» — two doors AND two different numbers, for one
     frame. A stylesheet has no such window: this holds from first paint, so the
     flash cannot happen at all. The JS stays as well, because it is what keeps
     the chip working on every shell that has no workbench. */
  body.desktop-chat.nabgol-workbench-on #nabgolProgressChip {
    display: none !important;
  }

  /* THE XOR IS OVER, AND ONLY HERE.
     chat-workspace.css hides #nabgolAskBar whenever the control surface is open,
     and that was right while the bar lived in the composer's chrome: the studio
     footer owned that strip, and two owners of one strip is a fight. In the rail
     they are different columns — the pane opens as its own track BESIDE the
     rail (control-surface.css) — so hiding the tools there would blank the top
     third of a panel the student is looking at, for no conflict at all. Written
     as a re-enable rather than by narrowing the original rule, because that
     rule is asserted verbatim by live/tools/test_composer_bar_budget.js and is
     still exactly right for every shell that has no rail. */
  body.desktop-chat.nabgol-workbench-on.nabgol-control-surface-open #nabgolAskBar {
    display: block !important;
  }

  /* ── THE THIRD PLACE THE MODE IS VISIBLE ─────────────────────────────────
     A 3px rule along the top of the conversation column. It is not chrome that
     can be scrolled away, it costs no height that the canvas would otherwise
     use (the header's own border-box already reserved the line), and it is the
     one signal that is in the reader's field of view while they are reading the
     answer rather than while they are operating a panel. */
  body.desktop-chat.nabgol-special-mode-on .chat-main::before {
    content: '';
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 3px;
    background: var(--nbgw-mode-mark, #fbbf24);
    z-index: 3;
    pointer-events: none;
  }
}

/* ══ PHONE — the panel, the door, and the dot ═══════════════════════════════
   §6 · §17. The panel's open/close geometry is #moreSheet's own, generalised in
   chat-mobile-flagship.css rather than reimplemented here; what follows is only
   what is particular to this panel. */
@media (max-width: 767.98px) {
  body.mobile-chat.nabgol-workbench-on #nabgolWorkbenchSheet {
    display: flex;
    flex-direction: column;
    direction: rtl;
    color: var(--nbgc-ink, #e8eef6);
  }

  /* Same one-progress-surface rule as desktop, and for the same reason: a
     script's decision has a window before it runs, a stylesheet's does not.
     On the phone this is also what makes the swap ONE FOR ONE — the door takes
     the chip's slot in .header-actions, so the header carries the same number
     of controls it did before (ROUTER.md §1, «هدر بودجهٔ ثابت دارد»). */
  body.mobile-chat.nabgol-workbench-on #nabgolProgressChip {
    display: none !important;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-head {
    padding: 0 4px 8px;
  }

  /* §34-3الف — THE SCROLLPORT IS A LAYER OF ITS OWN, NOT THE PANEL.
     Until now the panel itself was the scrollport (`.bottom-sheet` carries
     `overflow-y: auto !important`) and the head was `position: sticky` inside
     it. That works, but it makes the head's height part of the scrolled
     content, so the panel could not carry anything pinned to its own bottom
     edge — and it is why the only labelled way out ended up at the foot of a
     1853px column, 1393px below the fold.
     Three flex layers instead: grab + head are `flex: 0 0 auto`,
     [data-wb-scroll] is `flex: 1 1 auto` and is the ONLY thing that scrolls.
     `min-height: 0` is not optional — without it a flex child refuses to
     shrink below its content and the body paints straight over the head
     («flex body in max-height panel», already paid for once in §33). */
  body.mobile-chat #nabgolWorkbenchSheet {
    overflow: hidden !important;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    scrollbar-width: none;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-scroll::-webkit-scrollbar {
    display: none;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-body {
    padding: 0 2px 4px;
    flex: 0 0 auto;
    overflow: visible;
  }

  /* The drag handle. 36×4, and it is the affordance that says «this can be
     pulled down» before anyone has pulled it — chat-workbench.js reads the top
     56px band (this plus the head) as the gesture's start zone. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-grab {
    flex: 0 0 auto;
    width: 36px;
    height: 4px;
    margin: 2px auto 6px;
    border-radius: 999px;
    background: var(--nbgc-sheet-handle, rgba(148, 168, 200, 0.45));
  }

  /* §34-3پ — THE SPACE ABOVE THE PANEL IS THE CONVERSATION, AND IT SHOULD
     LOOK LIKE IT. #sheetOverlay is shared with #moreSheet and #cameraSheet, so
     it is not changed globally; openSheet stamps body[data-sheet-open] and only
     this panel's state drops the blur and lightens the wash. The area stays a
     real control — one tap on it still closes the panel (§34-4-۵). */
  body.mobile-chat[data-sheet-open="nabgolWorkbenchSheet"] .sheet-overlay.show {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    background: rgba(2, 6, 23, 0.22) !important;
  }

  html[data-theme="light"] body.mobile-chat[data-sheet-open="nabgolWorkbenchSheet"] .sheet-overlay.show {
    background: rgba(15, 23, 42, 0.14) !important;
  }

  /* §34-3ث — the vertical indicator. Absolute against the panel, from just
     under the head to 8px short of the floor, on the left edge. Track and thumb
     are both solid: a fading hairline is exactly the thing the phone's own
     overlay scrollbar already is, and it told the reader nothing. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-vrail {
    position: absolute;
    left: 5px;
    width: 3px;
    border-radius: 999px;
    background: #64748b;
    pointer-events: none;
    z-index: 3;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-vrail[hidden] {
    display: none;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-vthumb {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 3px;
    border-radius: 999px;
    background: #e2e8f0;
    will-change: transform;
  }

  html[data-theme="light"] body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-vthumb {
    background: #0f172a;
  }

  /* A TOUCH TARGET IS 44px, AND EVERY ROW HERE IS ONE.
     The rail's 8px/0.82rem rows are a mouse's dimensions. On a phone the same
     rows must be pressable by a thumb, so the padding grows and the type does
     — vertical room inside a dropdown is cheap, and a row that is readable but
     not reliably pressable is the fault ROUTER.md §1 («کنترلی که دیده می‌شود
     باید کار کند») names. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item) {
    min-height: 44px;
    justify-content: center;
    padding: 9px 12px;
    font-size: 0.88rem;
  }

  /* The segmented pills are pressable too, without being full-width rows. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-pref-btn, .nabgol-audience-btn) {
    min-height: 44px;
    font-size: 0.86rem;
  }

  /* THE PANEL IS TALLER THAN THE GEAR MENU, AND HAS TO BE.
     #moreSheet holds four rows; this one holds six sections and every learner
     capability the registry offers. At the gear's 420px cap a 390px phone
     opened onto «حالتِ ویژه» and half of «کمکم کن» — the nine tools the panel
     exists to make reachable were all below the fold. The panel still scrolls,
     still stops short of the composer, and still leaves the newest message
     visible behind it. */
  /* §33-5الف — the number is unchanged; only the selector is. The panel used
     to be a `.top-dropdown`, and this rule was written against that class. The
     door moved to the work band above the composer and the panel now rises
     from the bottom edge like every other sheet on this shell, so a rule keyed
     on `.top-dropdown` would have silently handed the panel back the generic
     82dvh and quietly undone the measurement above. */
  /* §34-3ت — «AS TALL AS ITS CONTENT, WITH A CEILING». 620px was a fixed
     height in practice: the panel was that tall whether the robot offered
     nine tools or three. `height: auto` lets a smaller robot get a smaller
     panel, and the ceiling goes to 700 because after §34-3ج the content is
     ~800px — 700 is nearly all of it in one look, and still leaves 144px of
     conversation showing above the panel. */
  /* THE THIRD TERM IS NOT DECORATION — it was measured. On a 320×568 phone
     82dvh is 465.8px, which put the panel's top edge at y=102 with the header
     ending at y=94: EIGHT PIXELS of conversation left showing. That defeats
     §34-3پ outright — the whole reason the scrim stopped blurring is so the
     reader can see this is still their conversation. A percentage cannot say
     «leave room above»; a subtraction can. 148px is the phone header (94px at
     320) plus the special-mode band (30px) plus a visible sliver of the last
     bubble. On 390×844 and 430×932 this term is never the smallest one, so
     the tall phones are unchanged. */
  body.mobile-chat #nabgolWorkbenchSheet {
    height: auto !important;
    /* §34-8: the special-mode band is 34px now (it carries a full sentence and
       a worded way out, §34-3چ), and the sliver of conversation that has to
       stay visible is 16px — the last bubble's edge. 94 + 34 + 16 = 144. */
    max-height: min(82dvh, 700px, 100dvh - 144px) !important;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section-title {
    font-size: 0.78rem;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-btn-hint,
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-bar-btn-hint,
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-audience-help,
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-progress-streak {
    font-size: 0.76rem;
  }

  /* «پرونده» lives in the reports section now (§17-5), not pinned over the
     canvas. It arrives carrying .nabgol-dossier-chip's fixed-position rules, so
     they are undone here rather than in that file — chat-mobile-flagship.css
     still owns how the chip looks on a shell with no panel. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-dossier-chip {
    position: static !important;
    inset: auto !important;
    width: 100% !important;
    max-width: none !important;
    min-height: 44px !important;
    justify-content: flex-start !important;
    border-radius: 10px !important;
    margin: 0 !important;
  }

  /* THE «بستن» ROW AT THE FOOT IS GONE (§34-3الف). Its job is done by the ✕
     in the head, which — now that the head is outside the scrollport — is in
     the same place at scrollTop 0 and at scrollTop max. Deleting it gives 53px
     of the panel back to the tools. */

  /* ── THE DOOR ────────────────────────────────────────────────────────────
     One header icon, fixed size, no text label: measured on the live phone at
     360px the header already runs six controls once a conversation starts, and
     it was a wide label that pushed the settings gear clean out of the bar in
     2026-08-30. */
  body.mobile-chat .nabgol-wbm-btn {
    position: relative;
  }

  body.mobile-chat .nabgol-wbm-btn[aria-expanded="true"] {
    color: var(--m-accent, #34d399) !important;
    background: rgba(52, 211, 153, 0.14) !important;
  }

  body.mobile-chat .nabgol-wbm-btn .ico {
    width: 20px !important;
    height: 20px !important;
  }

  /* The mode dot — §6's «یک نقطهٔ رنگیِ کوچک روی آیکن». It is not the only
     signal (the panel's title and state line name the mode in words, and the
     3px rule runs along the top of the canvas), because colour alone cannot
     say WHICH mode is on, and to a colour-blind reader it cannot say anything. */
  body.mobile-chat .nabgol-wbm-dot {
    display: none;
    position: absolute;
    top: 6px;
    inset-inline-end: 6px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--nbgw-mode-mark, #fbbf24);
    box-shadow: 0 0 0 2px var(--nbgc-header-face, rgba(11, 18, 32, 0.92));
  }

  body.mobile-chat .nabgol-wbm-btn.has-mode .nabgol-wbm-dot {
    display: block;
  }

  /* The same 3px rule the desktop column gets — the mode has to be visible
     while the answer is being READ, not only while the panel is open. */
  body.mobile-chat.nabgol-special-mode-on .chat-main::before {
    content: '';
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 3px;
    background: var(--nbgw-mode-mark, #fbbf24);
    z-index: 3;
    pointer-events: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   §30 — «حالتِ ویژه باید دیده شود، و دکمه‌ها باید یک خانواده باشند»
   docs/CHAT_REDESIGN_MASTER_PLAN.md §30 (۲۰۲۶-۰۹-۰۵)

   Four things, all reported by the owner and all measured before being changed:

   1. THE TEACHER MODE'S COLOUR IS RED. It was #60a5fa — a calm, informational
      blue, the colour a product uses for «this is a tip». Teacher mode rewrites
      every answer for an adult who is preparing a lesson, and a nine-year-old
      can turn it on by pressing one pill. That state is not a tip. Parent mode
      keeps its amber, because the two must still be told apart at a glance and
      «والدین» is the gentler of the two.
      ⇒ SUPERSEDED BY §36-4 (below, «the marks»): the correction was right about
        «a tip is too quiet» and wrong about which hue says so. Red is the one
        colour a product may not spend on a chosen state, because it is the one
        it needs for a failure. The state is now indigo — louder than the old
        blue, and not a warning. The five contrast numbers were re-measured.

   2. A THIN LINE UNDER THE HEADER SAYS WHICH MODE IS ON, IN WORDS. §7 removed
      an always-present amber banner and replaced it with three quiet signals.
      That was right about the cost and wrong about the reader: colour cannot
      say WHAT happened or HOW to undo it. The line is back at 28px instead of
      84, carries its own off-switch, and exists only while a mode is on.

   3. EVERY PRESSABLE THING IN THE WORKBENCH IS THE SAME FAMILY. The panel was
      painting three different button vocabularies at once (rail cards, sheet
      rows, segmented pills), each with its own border, radius and hover. They
      now all read from the platform's own button tokens — the --nab-btn-*
      block in chat-action-buttons.css, which is the one place in this codebase
      where a button's day and night surfaces were actually measured rather
      than picked. Nothing is re-derived here; the tokens are used as they are.
      The pills stay visibly different from the cards ON PURPOSE: a segmented
      control says «یکی را انتخاب کن» and a card says «این کار را انجام بده»,
      and flattening that difference would cost more than the tidiness it buys.

   4. A HEADING WITH NO SENTENCE, AND A DIAL WITH NO SUBJECT. «کمکم کن» over
      three words («کم · متوسط · زیاد») is not an explanation on a touch screen,
      where the `title` those pills have always carried is never shown at all.
      Section ledes and the live «الان: …» line are built in chat-workspace.js;
      this file only gives them a shape.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · the marks ─────────────────────────────────────────────────────────
   §36-4 — THE TEACHER MODE IS NO LONGER RED, AND THE REASON IS NOT TASTE.
   Red means error / danger / delete in every interface a child has ever used.
   Here it meant «you are the teacher»: a state a nine-year-old switches on by
   pressing one pill, painted like a system warning — and it held the one hue
   the product must keep free for a real failure.
   Indigo is the «professional / organisational» family: it cannot be read as
   an error, and against the parent mode's amber it is the safest pair there
   is for a colour-blind reader (blue-violet vs yellow-orange), where red vs
   amber was the worst.

   §34-10-د-۹ IS THE LAW HERE: a new hue is re-measured on the SAME four
   combinations the red was measured on, with the same probe, before and after.
   Measured 2026-09-11 on the live origin, `dabir-riazi-8` (before → after):
     mobile night panel  #fca5a5 → #c7d2fe on rgb(15,23,42)     9.41 → 11.97
     mobile day   panel  #b91c1c → #3730a3 on rgb(255,255,255)  6.47 →  9.93
     desktop day  panel  #b91c1c → #3730a3 on rgb(237,239,242)  5.61 →  8.75
     night band ink #e8eef6 on the tinted band itself          13.06 → 12.32
     day   band ink  #7f1d1d → #312e81 on its band              8.58 →  9.84
   Every combination rose except the night band, which loses 0.74 of 13 and is
   still three times the floor. test_wb_visual_language.js re-reads all five
   off the rendered page, so the next hue cannot be picked without them. */
body[data-nabgol-mode="teacher_mode"] {
  --nbgw-mode-mark: #818cf8;
  --nbgw-mode-ink: #c7d2fe;
}

html[data-theme="light"] body[data-nabgol-mode="teacher_mode"] {
  --nbgw-mode-mark: #4f46e5;
  --nbgw-mode-ink: #3730a3;
}

:root {
  --nbgw-band-face: rgba(251, 191, 36, 0.16);
  --nbgw-band-edge: rgba(251, 191, 36, 0.40);
  --nbgw-band-ink: var(--nbgc-ink, #e8eef6);
}

body[data-nabgol-mode="teacher_mode"] {
  --nbgw-band-face: rgba(99, 102, 241, 0.18);
  --nbgw-band-edge: rgba(99, 102, 241, 0.46);
}

html[data-theme="light"] {
  --nbgw-band-face: rgba(217, 119, 6, 0.12);
  --nbgw-band-edge: rgba(217, 119, 6, 0.40);
  --nbgw-band-ink: #78350f;
}

html[data-theme="light"] body[data-nabgol-mode="teacher_mode"] {
  --nbgw-band-face: rgba(79, 70, 229, 0.10);
  --nbgw-band-edge: rgba(79, 70, 229, 0.42);
  --nbgw-band-ink: #312e81;
}

/* ── 2 · the bar ───────────────────────────────────────────────────────────
   One row, one sentence, one way out. `hidden` when no mode is on, so the
   ordinary student screen is exactly the height it was. */
.nabgol-mode-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  box-sizing: border-box;
  min-height: 28px;
  padding: 4px 12px;
  border-bottom: 1px solid var(--nbgw-band-edge);
  background: var(--nbgw-band-face);
  color: var(--nbgw-band-ink);
  font-size: 0.76rem;
  line-height: 1.35;
  direction: rtl;
  text-align: right;
}

.nabgol-mode-bar[hidden] { display: none; }

.nabgol-mode-bar-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--nbgw-mode-mark, #fbbf24);
}

.nabgol-mode-bar-text {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
}

/* The off-switch is on the SAME line as the sentence that explains why it is
   there. A person who did not mean to be in this mode should not have to find
   a panel to leave it — that is the whole complaint this bar answers. */
.nabgol-mode-bar-off {
  flex: 0 0 auto;
  appearance: none;
  min-height: 24px;
  padding: 2px 10px;
  border: 1px solid var(--nbgw-band-edge);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: 0.74rem;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.nabgol-mode-bar-off:hover,
.nabgol-mode-bar-off:focus-visible {
  background: var(--nbgw-band-edge);
  outline: none;
}

.nabgol-mode-bar-off:focus-visible {
  outline: 2px solid var(--nbgw-mode-mark, #fbbf24);
  outline-offset: 2px;
}

/* THE 3px RULE IS THIS BAR'S TOP EDGE, NOT A SECOND LINE.
   .chat-main::before is position:absolute at top:0 of the same box, so with no
   border-top here it paints exactly along the bar's upper edge — one mark, and
   no :has() (an Android WebView old enough to miss it would have dropped the
   whole rule and left two lines). */

/* ── 3 · the quick strip ───────────────────────────────────────────────────
   In the flow, above the composer, only while a special mode is on. A row of
   pills that scrolls sideways when the mode has more tools than fit — and its
   overflow is honest: `scroll-padding` plus a gradient-free edge, because a
   nowrap row that hides its own last item is the fault ROUTER.md §1 names. */
.nabgol-quick-strip {
  display: flex;
  align-items: center;
  gap: 6px;
  box-sizing: border-box;
  width: 100%;
  padding: 6px 12px;
  border-top: 1px solid var(--nbgw-band-edge);
  background: var(--nbgw-band-face);
  direction: rtl;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

.nabgol-quick-strip[hidden] { display: none; }
.nabgol-quick-strip::-webkit-scrollbar { display: none; }

.nabgol-quick-strip-label {
  flex: 0 0 auto;
  color: var(--nbgw-band-ink);
  font-size: 0.74rem;
  font-weight: 700;
  opacity: 0.9;
}

.nabgol-quick-strip-btn {
  flex: 0 0 auto;
  appearance: none;
  min-height: 36px;
  padding: 6px 12px;
  border: 1px solid var(--nab-btn-edge, rgba(148, 163, 184, 0.26));
  border-radius: var(--nab-btn-radius-sm, 12px);
  background-color: var(--nab-btn-face-2, #161d29);
  background-image: linear-gradient(180deg, var(--nab-btn-face-1, #1e2736) 0%, var(--nab-btn-face-2, #161d29) 100%);
  box-shadow: inset 0 1px 0 var(--nab-btn-face-hi, rgba(255, 255, 255, 0.10)), var(--nab-btn-lift);
  color: var(--nab-btn-ink, #eaf0f7);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.18s var(--nab-btn-ease, ease), border-color 0.18s ease, color 0.18s ease;
}

.nabgol-quick-strip-btn:hover,
.nabgol-quick-strip-btn:focus-visible {
  border-color: var(--nab-btn-edge-hover, rgba(52, 211, 153, 0.62));
  color: var(--nab-btn-ink-hover, #ffffff);
  outline: none;
}

.nabgol-quick-strip-btn:focus-visible {
  outline: 2px solid var(--nab-btn-win-2, #10b981);
  outline-offset: 2px;
}

.nabgol-quick-strip-btn:active:not(:disabled) {
  transform: translateY(1px) scale(0.98);
}

.nabgol-quick-strip-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ── 4 · one button family ─────────────────────────────────────────────────
   Every card in the workbench reads from --nab-btn-*, so the panel and the
   buttons a robot writes into the conversation are visibly the same product.
   The tokens are re-used, never re-derived: their day/night contrast was
   measured in chat-action-buttons.css and copying the numbers here would be
   two sources for one decision. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn,
#nabgolWorkbenchSheet .nabgol-ask-sheet-item,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn {
  border: 1px solid var(--nab-btn-edge, rgba(148, 163, 184, 0.26));
  border-radius: var(--nab-btn-radius-sm, 12px);
  background-color: var(--nab-btn-face-2, #161d29);
  background-image: linear-gradient(180deg, var(--nab-btn-face-1, #1e2736) 0%, var(--nab-btn-face-2, #161d29) 100%);
  box-shadow: inset 0 1px 0 var(--nab-btn-face-hi, rgba(255, 255, 255, 0.10)), var(--nab-btn-lift);
  color: var(--nab-btn-ink, #eaf0f7);
  transition: transform 0.2s var(--nab-btn-ease, ease), border-color 0.2s ease,
    box-shadow 0.22s ease, color 0.18s ease;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn:hover,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn:focus-visible,
#nabgolWorkbenchSheet .nabgol-ask-sheet-item:hover,
#nabgolWorkbenchSheet .nabgol-ask-sheet-item:focus-visible,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn:hover,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn:focus-visible {
  border-color: var(--nab-btn-edge-hover, rgba(52, 211, 153, 0.62));
  background-color: var(--nab-btn-face-2, #161d29);
  background-image: linear-gradient(180deg, var(--nab-btn-face-1, #1e2736) 0%, var(--nab-btn-face-2, #161d29) 100%);
  box-shadow: inset 0 1px 0 var(--nab-btn-face-hi, rgba(255, 255, 255, 0.10)), var(--nab-btn-lift-hover);
  color: var(--nab-btn-ink-hover, #ffffff);
  outline: none;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn:active:not(:disabled),
#nabgolWorkbenchSheet .nabgol-ask-sheet-item:active:not(:disabled),
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn:active:not(:disabled) {
  transform: translateY(1px) scale(0.985);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.22);
  transition-duration: 0.06s;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn:focus-visible,
#nabgolWorkbenchSheet .nabgol-ask-sheet-item:focus-visible,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn:focus-visible {
  outline: 2px solid var(--nab-btn-win-2, #10b981);
  outline-offset: 2px;
}

/* The label is the loud half and the hint is the quiet half — the shape the
   owner asked for («عنوان بولد و خوانا و زیرش توضیح کوتاه ریز») and the shape
   the in-chat buttons already use. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn-label,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-bar-btn-label {
  font-weight: 700;
  color: var(--nab-btn-ink, #eaf0f7);
}

/* ── the segmented controls: same family, deliberately not the same shape ── */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-pref-btn {
  border: 1px solid var(--nab-btn-edge, rgba(148, 163, 184, 0.26));
  background-color: var(--nab-btn-face-2, #161d29);
  background-image: linear-gradient(180deg, var(--nab-btn-face-1, #1e2736) 0%, var(--nab-btn-face-2, #161d29) 100%);
  color: var(--nab-btn-ink, #eaf0f7);
  font-weight: 650;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-pref-btn.is-active,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-pref-btn[aria-pressed="true"] {
  /* «چیزی که انتخاب شده» is the accent event, the same one a chosen option in
     the conversation gets — one colour for one meaning, everywhere. */
  border-color: var(--nab-btn-win-2, #10b981);
  background-color: var(--nab-btn-win-2, #10b981);
  background-image: linear-gradient(180deg, var(--nab-btn-win-1, #34d399) 0%, var(--nab-btn-win-2, #10b981) 100%);
  color: var(--nab-btn-win-ink, #012014);
  box-shadow: 0 0 0 3px var(--nab-btn-win-ring, rgba(52, 211, 153, 0.42));
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-pref-btn.has-cap {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  text-align: right;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-pref-btn-label {
  font-weight: 700;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-ask-pref-btn-cap {
  font-size: 0.7rem;
  font-weight: 500;
  opacity: 0.85;
}

/* ── the words: a lede under each heading, and a live line under the dial ── */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section-head {
  margin: 0 0 6px;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section-head .nabgol-wb-section-title {
  margin: 0;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section-lede,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-guidance-help {
  margin: 2px 0 0;
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--nbgw-rail-muted) !important;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-guidance-help {
  margin: 6px 0 0;
  font-weight: 600;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-ask-bar, .nabgol-wbm-ask) > .nabgol-wb-section-head {
  margin-top: 14px;
}

/* ── 5 · the way out that cannot scroll away (phone panel) ─────────────────
   §34-3الف — it is no longer sticky, because it is no longer inside anything
   that scrolls: the head is a fixed row of the panel's own flex column and
   [data-wb-scroll] is the scrollport beneath it. `position: sticky` bought the
   same guarantee at the cost of making the panel one long scroll with nothing
   pinnable to its floor; this is the cheaper shape and it is what lets the
   foot's «بستن» row disappear. */
@media (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-head {
    flex: 0 0 auto;
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    column-gap: 8px;
    background: var(--nbgc-sheet-face, #0f172a);
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-title {
    flex: 1 1 auto;
    min-width: 0;
    order: 1;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-state {
    flex: 1 1 100%;
    order: 3;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-x {
    order: 2;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44×44 — the standard, and this time the box is bought outright rather
       than faked with a `::after` hit-slop, whose vertical half is covered by
       whatever sibling paints next (§33-11-ت, twenty-four hours of a control
       that looked pressable and was not). The circle is the whole button. */
    width: 44px;
    height: 44px;
    min-width: 44px;
    margin: -2px 0 0 0;
    padding: 0;
    border: 1px solid var(--nbgc-hairline-strong, rgba(148, 168, 200, 0.26));
    border-radius: 50%;
    background: var(--nbgc-surface-raised, rgba(148, 168, 200, 0.17));
    color: var(--nbgc-ink, #e8eef6);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-x svg {
    width: 19px;
    height: 19px;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-x:focus-visible {
    outline: 2px solid var(--nbgc-accent, #34d399);
    outline-offset: 2px;
  }

  html[data-theme="light"] body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-head {
    background: var(--nbgc-sheet-face, #ffffff);
  }

  html[data-theme="light"] body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-x {
    color: #1f2937;
    background: rgba(15, 23, 42, 0.06);
    border-color: rgba(15, 23, 42, 0.16);
  }

  /* The dial is three words on a phone too — the line under it is not optional
     there, since a touch screen never shows the `title` the pills carry. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn {
    min-height: 44px;
    border-radius: 999px;
    padding-inline: 14px;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn.has-cap {
    border-radius: var(--nab-btn-radius-sm, 12px);
    padding: 7px 12px;
  }
}

/* ── 6 · the desktop column gets a row for the bar ─────────────────────────
   .chat-main is a flex ROW on desktop with one flex child (#messages); the bar
   is a second child and has to sit ABOVE it, not beside it. Turning the axis is
   the whole change — with one child the two directions render identically, so
   this costs nothing on a page with no mode on. */
@media (min-width: 768px) {
  body.desktop-chat .chat-main {
    flex-direction: column;
  }

  /* No rule for #messages here, deliberately: chat-workbench.css loads AFTER
     chat-canvas.css, and test_chat_canvas_gate forbids anything downstream of
     the canvas sheet from carrying a selector that reaches into it. The column
     axis alone is enough — #messages is already flex: 1 1 0% with its own
     overflow, measured at 592px under a 37px bar and a 52px strip on a 900px
     desktop (probe: _mode_chrome_probe.js). */

  body.desktop-chat .nabgol-mode-bar {
    padding-inline: var(--nbgc-gutter-lg, 16px);
  }
}

/* ── 7 · the two segmented rows wrap inside the panel; they do not scroll ───
   `overflow-x: visible` next to `overflow-y: hidden` is not visible — CSS
   promotes it to `auto`, so both rows were computed scrollers even though
   flex-wrap already made them wrap. A nowrap-looking scroller in a panel is one
   edit away from hiding its own last pill (ROUTER.md §1), so both axes are
   declared together and neither can drift. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-ask-prefs-row, .nabgol-audience-row) {
  flex-wrap: wrap;
  overflow-x: visible;
  overflow-y: visible;
}

/* ── 8 · «انتخاب‌شده» is green; «حالتِ ویژه روشن است» is the mode's own colour ─
   The accent green means «this is the option you picked» everywhere in this
   product, and that is right for the guidance dial: کم/متوسط/زیاد are three
   ordinary settings. It is wrong for the audience row. A green «معلم» beside a
   red bar saying «حالت معلم روشن است» is one state painted two ways, and the
   pill is the control a child presses by accident — it has to look like the
   thing the bar is warning about, not like a tick.

   MEASURED (a solid pill's own ink, so the page theme does not change it):
     white on #b45309 (والدین) = 5.02:1 · white on #4338ca (معلم) = 7.90:1.
   §36-4: the teacher pill follows the mode out of red into indigo with the
   rest of the marks — it is the same state, so it cannot be a second hue. */
body[data-nabgol-mode] {
  --nbgw-mode-solid: #b45309;
}

body[data-nabgol-mode="teacher_mode"] {
  --nbgw-mode-solid: #4338ca;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-row .nabgol-ask-pref-btn.is-active,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-row .nabgol-ask-pref-btn[aria-pressed="true"] {
  border-color: var(--nbgw-mode-solid, #b45309);
  background-color: var(--nbgw-mode-solid, #b45309);
  background-image: none;
  color: #ffffff;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--nbgw-mode-solid, #b45309) 40%, transparent);
}

/* color-mix is recent; an engine without it drops only the ring, never the
   fill — the pill still reads as the mode's colour. */
@supports not (box-shadow: 0 0 0 3px color-mix(in srgb, red 40%, transparent)) {
  :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-row .nabgol-ask-pref-btn.is-active,
  :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-row .nabgol-ask-pref-btn[aria-pressed="true"] {
    box-shadow: none;
  }
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-row .nabgol-ask-pref-btn.is-active .nabgol-ask-pref-btn-cap,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-row .nabgol-ask-pref-btn[aria-pressed="true"] .nabgol-ask-pref-btn-cap {
  opacity: 1;
}

/* ── 9 · the strip scrolls, and it looks like it scrolls ───────────────────
   Five teacher tools do not fit in 366px and never will; the row is a
   carousel, and the honest version of a carousel shows part of the next item
   so a thumb knows to push. Snap points make that push land on a whole chip
   rather than half of one. The gate asserts the last chip can be REACHED
   (scroll to the end and it is fully inside), which is the property that
   matters — not that everything is visible at once. */
.nabgol-quick-strip {
  flex-wrap: nowrap;
  scroll-snap-type: x proximity;
  scroll-padding-inline: 12px;
}

.nabgol-quick-strip-btn {
  scroll-snap-align: end;
}

@media (max-width: 767.98px) {
  /* One more chip fits per screen at these numbers, and 36px is still a real
     touch target for a control that is one tap from the composer. */
  .nabgol-quick-strip {
    padding-inline: 10px;
    gap: 5px;
  }

  .nabgol-quick-strip-btn {
    padding-inline: 10px;
    font-size: 0.8rem;
  }
}

/* ══ §34-8 · THE PANEL'S CONTENT — ONE GRAMMAR, THREE WEIGHTS ═══════════════
 *
 * Session A gave the phone panel a skeleton (three layers, three ways out, two
 * indicators). What it deliberately did NOT touch is what is INSIDE: 22 tools
 * as 22 full-width rows, 1713px of column in a 582px scrollport — SEVEN of the
 * twenty-two in view at 390px, THREE at 320px (§34-9-ب, measured).
 *
 * The owner's ask is the whole brief of this step: «یک‌دست‌سازی یعنی تکراری و
 * یکنواخت نیست اصلاً؛ یک بازطراحیِ شیک که دانش‌آموزِ کم‌سن گیج نشود.» So the
 * answer is NOT one card shape repeated twenty-two times. Role decides shape
 * (§34-3ج): one special card («پیشرفتِ من» — the only row with live data), two
 * segmented tracks («حالتِ ویژه» / «کمکم کن» — they change STATE, they do not
 * send anything), and everything that DOES something is a tile in a grid.
 *
 * THREE COLUMNS, AND THAT IS A DEVIATION THE MEASUREMENT FORCED.
 * §34-3ج writes `repeat(auto-fill, minmax(132px, 1fr))`, i.e. two columns below
 * 430px. Measured against this panel's real content, two columns cap the
 * density at 82% with no mode on and 60% in teacher mode at 390px, and at 50%
 * at 320px — under the plan's OWN targets (≥80% / ≥62%), which is the number
 * the gate reads. The target wins over the constant, so the phone gets three
 * columns at every width and `minmax(0, 1fr)` (auto-fill cannot be told «three
 * whatever the width» — at 320px `minmax(132px)` silently returns two).
 * The fleet's longest label — «جلبِ توجه و آرام‌سازیِ کلاس», 147px at 13.1px,
 * and its widest single word 51px — was measured with canvas.measureText
 * (tools/_wb_tile_probe.js) against the narrowest tile this produces: 92px at
 * 320px, 80px of text box. 147/80 = two lines, 51 < 80 so no word is ever
 * wider than its tile. That is why the clamp below is VERTICAL
 * (-webkit-line-clamp) and never `text-overflow: ellipsis`: a horizontal
 * ellipsis makes scrollWidth > clientWidth, which is exactly the §33 clipped-
 * sentence rule the gate's group 7 measures on every text leaf in here.
 *
 * WHAT COSTS WHAT, at 320×568 (the worst case: a 420px panel, 309px of
 * scrollport before this step): the head was 98.6px of a 420px panel — a 44px
 * ✕, a title and a state line, each on its own line. Beside the ✕ they are 44px
 * in total, and the panel gets 35px back for free. Below 361px the hint row and
 * the audience captions come off the tiles (the text stays in `title`) and the
 * two help lines go: at 292px of width and 44px of tile, a second line inside
 * the tile costs one whole ROW of tools — nine tools in view instead of twelve,
 * which is 60% against a 62% floor. Above 360px there is room for all of it.
 */
@media (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet {
    /* One place to change the grid's rhythm; both breakpoints read these. */
    --nbg-wb-gap: 4px;
    --nbg-wb-tile-label: 0.76rem;
    /* The generic .bottom-sheet padding (8px 14px 12px) was written for a menu
       of four rows. Measured here it is 14px of vertical room and 12px of tile
       width — one whole column of text on a 320px phone. */
    padding: 0 8px 4px !important;
  }

  /* ── 1 · the head: the ✕ beside the words, not above them ──────────────
     The markup is untouched (✕ · title · state, in that order); the grid
     places the button in a 44px column of its own that spans both text rows,
     so the head's height is the ✕'s own 44px and nothing more. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-head {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-rows: auto auto;
    align-items: center;
    align-content: center;
    column-gap: 10px;
    row-gap: 0;
    padding: 3px 6px 5px;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-x {
    grid-column: 1;
    grid-row: 1 / span 2;
    margin: 0;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-title {
    grid-column: 2;
    grid-row: 1;
    font-size: 0.9rem;
    line-height: 1.25;
  }

  /* NOT CLAMPED, AND THAT IS DELIBERATE. In a special mode this line is the
     one place the mode's FULL sentence is read whole — that is where it went
     when §33-11 shortened the bar, and test_chat_stage_workbench_gate
     asserts it («the state line is painted whole, not ellipsised»). A
     2-line clamp here bought 15px of panel height and was reverted: it cut
     the sentence the panel exists to keep. It wraps, and the head grows by
     the 15px it needs. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-state {
    grid-column: 2;
    grid-row: 2;
    font-size: 0.7rem;
    line-height: 1.32;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-grab {
    margin: 3px auto 4px;
  }

  /* ── 2 · the grid itself ───────────────────────────────────────────────
     Two containers, one rule: the ask surface (its four sections) and every
     `[data-wb-stack]` the workbench builds. Section heads, tracks, help lines
     and the special card span the whole row; a tile takes one cell. Nothing
     here names a capability id — a tool added next year lands in the grid. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-body {
    padding: 0 6px 6px;
  }

  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-wbm-ask, .nabgol-wb-stack) {
    display: grid;
    /* FOUR COLUMNS ON THE NARROWEST PHONE, THREE EVERYWHERE ELSE, and that is
       arithmetic rather than taste. At 320×568 the panel is 424px and its
       scrollport 345px; two segmented tracks and three section heads take
       160px of it, which leaves room for exactly three rows of tiles. Three
       columns × three rows is nine tools in view — 60% in teacher mode,
       against a 62% floor. A fourth column is twelve, i.e. 72%, and it is the
       lever §34-3ج names («اگر جا کم آمد، ستون اضافه می‌شود یا متن کوتاه، نه
       دکمه»): the touch target stays 44px either way. The cost is measured
       too: at 71px a tile has 55px of text box, wider than the fleet's widest
       single word (51px, canvas.measureText over all 32 labels), so no word is
       ever cut mid-word; the four longest labels of the 32 reach a third line
       and are clamped at two. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--nbg-wb-gap);
    align-items: stretch;
  }

  /* The column shape those two containers had: `> * + * { margin-top: 10px }`
     plus a 14px top margin on every heading. In a grid a margin is a second,
     invisible gap that no longer lines up with anything. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-wbm-ask, .nabgol-wb-stack) > * + * {
    margin-top: 0;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wbm-ask > :is(.nabgol-wb-section-title, .nabgol-wb-section-head) {
    margin-top: 2px;
  }

  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-wbm-ask, .nabgol-wb-stack) > :is(
      .sheet-title,
      .nabgol-wb-section-head,
      .nabgol-wb-section-title,
      .nabgol-ask-prefs-row,
      .nabgol-audience-row,
      .nabgol-audience-help,
      .nabgol-guidance-help,
      .nabgol-parent-mode-banner,
      .nabgol-wb-empty,
      .nabgol-dossier-chip,
      [data-wb-progress-btn],
      [data-wb-dossier-btn]
    ) {
    grid-column: 1 / -1;
  }

  /* ── 3 · section heads: a name, its sentence, and a hairline ───────────
     One line instead of two blocks. The rule runs to the end of the row and
     is the only thing separating the sections, so the panel reads as one
     surface with a rhythm rather than six stacked cards (§34-3ج). */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section {
    padding: 2px 0 0;
    border-bottom: 0;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section-head {
    display: flex;
    /* baseline alignment of a 11.5px title against a 10.6px lede adds 6px of
       leading to every head; centred they are one 15px line. */
    align-items: center;
    column-gap: 6px;
    flex-wrap: nowrap;
    min-width: 0;
    margin: 0 0 2px;
    padding-bottom: 2px;
    border-bottom: 1px solid var(--nbgc-hairline, rgba(148, 168, 200, 0.16));
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section-head .nabgol-wb-section-title {
    flex: 0 0 auto;
    margin: 0;
    font-size: 0.72rem;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section-lede {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    overflow: hidden;
    font-size: 0.66rem;
    line-height: 1.3;
    color: var(--nbgc-ink-soft, #94a3b6);
  }

  /* «مدیریتِ کلاس» has no lede in the registry, so its heading arrives as a
     bare <h3> rather than inside a head block. It gets the same hairline. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-wbm-ask, .nabgol-wb-stack) > .nabgol-wb-section-title {
    margin-bottom: 2px;
    padding-bottom: 2px;
    border-bottom: 1px solid var(--nbgc-hairline, rgba(148, 168, 200, 0.16));
    font-size: 0.72rem;
  }

  /* ── 4 · the tile — everything that DOES something ─────────────────────
     Same card, one cell wide. `min-height: 44px` is the floor §34-4-۳ sets:
     density is bought with a column, never by shrinking a touch target. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-sheet-item, .nabgol-wb-btn) {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 1px;
    width: 100%;
    min-height: 44px !important;
    box-sizing: border-box;
    margin: 0 !important;
    padding: 6px 8px !important;
    border-radius: 14px !important;
    font-size: var(--nbg-wb-tile-label) !important;
    line-height: 1.25;
    text-align: start;
    white-space: normal;
    overflow-wrap: anywhere;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-sheet-item-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    width: 100%;
    min-width: 0;
  }

  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-sheet-item-label, .nabgol-wb-btn-label) {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    font-size: var(--nbg-wb-tile-label);
    line-height: 1.25;
    font-weight: 650;
  }

  /* Below 361px the hint line comes off the tile and stays in `title` — see
     the header: on a 92px tile it costs a whole row of tools. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-sheet-item-hint, .nabgol-wb-btn-hint) {
    display: none;
  }

  /* ── 5 · the two segmented tracks — state, not an errand ───────────────
     One track, equal segments, no gap between them: that shape says «pick
     one of these» where a stack of cards says «here are three separate
     errands». The inline label («حالت ویژه:») is already hidden inside the
     panel (the heading says it once); it stays in the DOM because two gates
     read it. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-prefs-row, .nabgol-audience-row) {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
    margin: 0 0 2px;
    padding: 0;
    border: 1px solid var(--nbgc-hairline-strong, rgba(148, 168, 200, 0.26));
    border-radius: 12px;
    background: var(--nbgc-surface-2, rgba(148, 168, 200, 0.11));
    overflow: hidden;
  }

  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-prefs-row, .nabgol-audience-row).nabgol-ask-sheet-prefs {
    padding-block: 0;
  }

  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-pref-btn, .nabgol-ask-pref-btn.has-cap) {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    min-height: 44px;
    padding: 4px 6px;
    border: 0;
    border-radius: 0;
    font-size: 0.76rem;
    line-height: 1.25;
    text-align: center;
    white-space: normal;
    overflow-wrap: anywhere;
  }

  /* «WHICH ONE IS ON» IS ALREADY PAINTED, AND REPAINTING IT WAS A BUG.
     The chosen segment is a solid emerald gradient with near-black ink
     («چیزی که انتخاب شده» — one accent for one meaning, §3 of this file), and
     that is already exactly the «سگمنتِ فعال پُر با رنگِ لهجه» §34-3ج asks
     for. The first pass here made every pill `background: transparent` so the
     track's own face would show through — which also erased the chosen one's
     fill and left its near-black ink on a 10%-alpha tint: 1.41:1, in the dark
     theme, caught by test_controls_always_reachable.js.
     So the see-through face is declared for the UNSELECTED segments only, and
     the selected one keeps the single producer of that look 550 lines above.
     («Cascade trace is not a measurement» — the wash read fine in the rule and
     was unreadable on the screen.) */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn:not(.is-active):not([aria-pressed="true"]) {
    background: transparent;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn:not(.is-active) + .nabgol-ask-pref-btn:not(.is-active) {
    border-inline-start: 1px solid var(--nbgc-hairline, rgba(148, 168, 200, 0.16));
  }

  /* The chosen segment's 3px focus-style ring is what it wore as a free-
     standing pill; inside a track with `overflow: hidden` it would be clipped
     on three sides out of four. The fill says «this one» on its own. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn.is-active {
    box-shadow: none;
    font-weight: 700;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn-cap {
    display: none;
  }

  /* ── 6 · the one special card — «پیشرفتِ من» ───────────────────────────
     The only control in this panel with live data behind it (today's work and
     the streak), so it is the only one that is not a tile: full width, its own
     radius, and a chevron that says it opens something rather than sending
     something. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-btn[data-wb-progress-btn] {
    position: relative;
    min-height: 54px;
    padding: 8px 12px;
    padding-inline-end: 30px;
    border-radius: 16px;
    background: var(--nbgc-surface-raised, rgba(148, 168, 200, 0.17));
    font-size: 0.82rem;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-btn[data-wb-progress-btn]::after {
    content: '';
    position: absolute;
    inset-inline-end: 13px;
    top: 50%;
    width: 7px;
    height: 7px;
    /* A CHEVRON POINTS THE WAY THE READER TRAVELS. Two borders make an «L»;
       rotated +45deg its vertex points DOWN (which read as «expand»), and this
       card opens the progress pane rather than unfolding in place. -45deg puts
       the vertex at the inline end — leftwards in an RTL column, the direction
       everything else in this panel moves when it opens something. */
    border-inline-start: 2px solid var(--nbgc-ink-soft, #94a3b6);
    border-bottom: 2px solid var(--nbgc-ink-soft, #94a3b6);
    transform: translateY(-50%) rotate(-45deg);
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-progress-line {
    font-size: 0.84rem;
    font-weight: 700;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-progress-streak {
    display: block;
    font-size: 0.7rem;
  }

  /* The dossier door keeps the full-width row it earned in §17-5 — it names a
     document, not a tool, and its count sits at the end of the line. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-btn[data-wb-dossier-btn] {
    flex-direction: row;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    font-size: 0.8rem;
  }

  /* Two help lines: one says what «هیچ‌کدام روشن نیست» means, the other names
     the guidance level that is on. Both are section-level sentences, not
     control hints, and below 361px they come off in favour of a row of tools
     (the pills keep their own `title`). */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-audience-help, .nabgol-guidance-help) {
    display: none;
  }
}

/* ── the same panel, from 361px up: room for the second line ───────────────
   Every phone the fleet actually meets except the 320px class (§34-1's
   narrowest case). The hint row, the audience captions and the two help lines
   are what a parent reads over the student's shoulder, so they are on wherever
   the arithmetic allows: measured at 390×844, 15 tiles of 76px still fit in the
   622px scrollport, which is 84% of the tools in teacher mode against the 80%
   floor. */
@media (min-width: 361px) and (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet {
    --nbg-wb-gap: 6px;
    --nbg-wb-tile-label: 0.78rem;
  }

  /* ONE LINE, AND THE MEASUREMENT SAYS WHY. A second hint line makes the tile
     73px instead of 59px, which at 390×844 is four rows of tools where five
     fit — 72% of the tools in view in teacher mode against the 80% floor. The
     hint is clamped VERTICALLY (-webkit-line-clamp), never with
     text-overflow: ellipsis: an ellipsis makes scrollWidth exceed
     clientWidth, which is the §33 clipped-sentence rule the gate measures on
     every text leaf in this panel. The full sentence stays in the title
     attribute, and on the desktop rail it is spelt out in full. */
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-sheet-item-hint, .nabgol-wb-btn-hint) {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    overflow: hidden;
    font-size: 0.66rem;
    line-height: 1.3;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn-cap {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    font-size: 0.62rem;
    line-height: 1.25;
    color: var(--nbgc-ink-soft, #94a3b6);
  }

  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-audience-help, .nabgol-guidance-help) {
    display: block;
    margin: 0 0 2px;
    font-size: 0.66rem;
    line-height: 1.35;
  }
}

/* ── §34-8 · THE TWO SETTINGS SIT BESIDE THEIR NAME, NOT UNDER IT ──────────
 *
 * «حالتِ ویژه» and «کمکم کن» are the only two blocks in this panel that change
 * a STATE. Their heads are the two cheapest things to move: measured at
 * 320×568, a head of its own costs 36px of a 341px scrollport, and the two of
 * them together were one whole row of tools — eleven of twenty-five tools in
 * view in teacher mode, against a 62% floor.
 *
 * Beside its track the head costs NOTHING: the row is the track's own 44px and
 * the two text lines (name over sentence) are 29px of it. That is also the
 * better shape — a label and the control it names on one line is what a
 * settings row looks like, while «از معلم بخواه» and «مدیریتِ کلاس» keep the
 * full-width heading with a hairline, because what follows them is a GRID of
 * errands rather than one control. Same grammar, two weights (§34-3ج), and the
 * difference now says something instead of being decoration.
 *
 * The pairing is marked in the markup (data-wb-head-pair, written by
 * chat-workspace.js::askSectionTitleEl) rather than sniffed with :has() — the
 * fleet's readers include messenger webviews old enough to have no :has(), and
 * on those the head would silently fall back to full width and cost the row
 * back.
 */
@media (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wbm-ask > [data-wb-head-pair] {
    grid-column: span 2;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    row-gap: 0;
    margin: 0 !important;
    padding: 0 4px 0 0;
    border-bottom: 0;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wbm-ask > [data-wb-head-pair] .nabgol-wb-section-title {
    font-size: 0.74rem;
    color: var(--nbgc-ink-strong, #f3f7fb);
  }

  /* Two lines here, not one: this sentence is the only thing telling a reader
     what the track beside it decides, and it has half a row to say it in. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wbm-ask > [data-wb-head-pair] .nabgol-wb-section-lede {
    flex: 0 0 auto;
    -webkit-line-clamp: 2;
    font-size: 0.64rem;
    line-height: 1.25;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wbm-ask > [data-wb-head-pair] + :is(.nabgol-ask-prefs-row, .nabgol-audience-row) {
    grid-column: span 2;
    margin: 0;
  }
}

/* ── three columns from 361px up ───────────────────────────────────────────
   Four columns is what the 320px class needs to clear its 62% floor; from
   361px the same grid at three columns clears the 80% floor with room to
   spare (measured: 84% in teacher mode at 390×844) and buys back 32px of tile
   width — which is the difference between a hint line that says «همین مبحث،
   با…» and one that says almost nothing. */
@media (min-width: 361px) and (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-wbm-ask, .nabgol-wb-stack) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /* In a three-column grid a `span 2` head and a `span 2` track cannot share
     a row, so the pair is 1 + 2: the name takes one column, the control two. */
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wbm-ask > [data-wb-head-pair] {
    grid-column: span 1;
  }
}

/* ── §34-8 · THE LAST 60px, AND WHERE EACH ONE CAME FROM ───────────────────
 *
 * At 390×844 in teacher mode the panel holds 25 controls and shows 19 of them.
 * The twentieth — the row that clears the 80% floor — began 0.2px below the
 * panel's own bottom edge. Sixty pixels, itemised, because next time someone
 * will want to know which of these is safe to give back:
 *
 *   · the grid gap, 6px → 5px, over thirteen gaps ......................  13px
 *   · the two full-width section heads, 22px → 18px ....................  16px
 *   · the tile's own padding, 6px → 5px, over seven rows ...............  14px
 *   · the grab handle's margins and the panel's top padding ............   5px
 *   · «اگر هیچ‌کدام روشن نباشد …» — hidden HERE only ...................  34px
 *
 * That last one is the only one with a product cost, and it is the smallest
 * loss available. The line names the OFF state of «حالتِ ویژه», and at 390px it
 * wraps to two lines and costs a whole row of tools. What still says it on the
 * phone: the section's own lede («پاسخ برای چه کسی نوشته شود»), the fact that
 * with no mode on NOTHING in the track is selected — the empty state that is
 * the normal one, by §17's own decision — and each pill's caption line. The
 * element stays in the DOM (two gates read it) and the desktop rail, which has
 * a whole column of height, keeps it visible.
 *
 * The guidance line stays: «الان: کم — بیشترش را خودم حل می‌کنم» is not a
 * static explanation, it is the only place that names WHICH level is on.
 */
@media (min-width: 361px) and (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet {
    --nbg-wb-gap: 5px;
  }

  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-ask-sheet-item, .nabgol-wb-btn) {
    padding: 5px 8px !important;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section-head,
  body.mobile-chat #nabgolWorkbenchSheet :is(.nabgol-wbm-ask, .nabgol-wb-stack) > .nabgol-wb-section-title {
    margin-bottom: 1px;
    padding-bottom: 1px;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-audience-help {
    display: none;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-guidance-help {
    display: block;
    margin: 0;
    font-size: 0.66rem;
    line-height: 1.3;
  }
}

@media (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-grab {
    margin: 2px auto 2px;
  }
}

/* ══ §36-3 · «not yet» and the backup row ═════════════════════════════════

   EXPLAINED-DISABLED. The generic `.nabgol-wb-btn:disabled` above dims the
   whole tile to opacity .5 — which would carry the LABEL'S INK down with it,
   and test_controls_always_reachable.js measures its 4.5:1 floor on the
   composited ink, not on the declared colour. A dimmed tile would read as
   «unreadable», which is a different and worse claim than «not ready yet».
   So the state is said with a dashed edge and a flat face, the ink is left
   exactly where it was, and the sentence on the tile does the explaining.
   pointer-events is deliberately NOT none: the tile stays in the hit-test
   tree, or the reachability gate is right to call it dead. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-wb-btn:disabled, .nabgol-wb-btn[aria-disabled="true"]),
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-wb-btn:disabled, .nabgol-wb-btn[aria-disabled="true"]):hover,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-wb-btn:disabled, .nabgol-wb-btn[aria-disabled="true"]):focus-visible {
  opacity: 1;
  cursor: default;
  border-style: dashed;
  background-image: none;
  box-shadow: none;
  transform: none;
}

/* THE BACKUP PAIR — §35-5-ب. Two errands that must stay available and must
   stop looking like «تمرین بده».

   The two shells need two different moves, because their stacks are already
   two different layouts. The desktop rail stacks in a column, so the pair is
   one row there and that is a whole row of rail given back. The phone sheet
   is ALREADY a 4-column grid, where the two tiles are side by side and
   turning the container into a flex row would fight the grid for no gain —
   so on the phone only the WEIGHT changes: flat face, no lift, no sentence.
   Nothing here sets white-space:nowrap — the labels («برگرداندن از فایل» is
   17 characters) do not fit one line in a 71px cell, and a clipped label is
   exactly what test_wb_panel_masterpiece.js §7 counts. They wrap, as they
   already did. */
#nabgolWorkbench .nabgol-wb-stack.nabgol-wb-inline-row {
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 6px;
}

#nabgolWorkbench .nabgol-wb-stack.nabgol-wb-inline-row > .nabgol-wb-inline-btn {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* The sentence is what made these full cards. It is not lost: `title` carries
   it, and the section's own lede — «ذخیره و برگرداندن، فقط روی همین دستگاه» —
   already says it once for both. */
body :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn.nabgol-wb-inline-btn .nabgol-wb-btn-hint {
  display: none;
}

body :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn.nabgol-wb-inline-btn {
  background-image: none;
  box-shadow: none;
}

body :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn.nabgol-wb-inline-btn .nabgol-wb-btn-label {
  font-weight: 550;
}

/* ══ §36-4 · THE VISUAL LANGUAGE — THREE WEIGHTS, ONE RULE ══════════════════
   docs/CHAT_REDESIGN_MASTER_PLAN.md §35-4 · §36-4

   THE NUMBER THIS ANSWERS. Measured on the live origin, `dabir-riazi-8`,
   2026-09-11, with live/tools/_wb_audit.js: the desktop rail paints TWENTY-ONE
   controls in TWO background colours — one of which is «the option you picked»
   green. «از معلم بخواه» (a message goes and an answer comes back), «گزارشِ
   پیشرفت» (a document is written) and «پشتیبان‌گیری» (a file lands on this
   device) are three fundamentally different errands wearing one coat, and the
   only thing separating them is an 11.5px heading in #94a3b6 ink.

   THE RULE IS NOT A LIST OF IDS — IT IS `data-action-kind`.
   Every control in this panel already carries its kind on the element:
   chat-workbench.js::buttonEl and four places in chat-workspace.js stamp
   `data-action-kind` from the registry, and HOME_BY_KIND is a TOTAL function
   of that kind (chat-workspace.js §«Forever: kind -> home»). So the weight is
   a function of the same total input the panel's structure already is, and a
   capability added next year — for a robot that does not exist yet — gets the
   right weight with no edit to this file. That is the whole reason this is
   written against the attribute and not against a list of names.

     send_now                              → the accent tier. A message leaves
                                             and an answer comes back: the
                                             faintest brand tint, a 2px bar on
                                             the starting edge, and the lift.
     pref_only                             → SEGMENTED. Untouched: a track of
                                             pills already says «pick one».
     mutate_doc · share_out · navigate
     local_io · anything this file has
     not met yet                           → the quiet tier. Something is made,
                                             taken or opened: a plain surface,
                                             no tint, no bar.

   THE QUIET TIER IS THE DEFAULT, AND THAT IS THE SAFE DIRECTION. A kind this
   stylesheet has never seen falls to it — it does not get promised to the
   reader as «press this and an answer arrives».

   ── AND A CORRECTION, BECAUSE THE FIRST VERSION OF THIS BLOCK WAS UGLY ────
   §35-4-پ-۱ measured the day theme's real defect: the tile's face was 1.25:1
   against the phone panel and 1.07:1 against the day rail, its edge 1.34:1 and
   1.17:1 — a white card on a white curtain. The first answer here was to make
   the tile HOLLOW and push the edge to 3:1 (#5b6a85 / #78859a), on the reading
   that WCAG 1.4.11 sets 3:1 for the boundary of a control.
   Shown to the owner, that reading was wrong in practice and the verdict was
   immediate: «خطوط پر رنگ زشت» — twenty-two hard grey frames, a wireframe, not
   a product. The rule it leaned on says 3:1 for the visual information REQUIRED
   TO IDENTIFY the control, and a card is not identified by its outline alone:
   it is identified by a surface that its ground is not, plus (in daylight) the
   shadow that surface casts, plus its own label. Spend the contrast on the
   SURFACE and the boundary is free to be a hairline — which is what every
   flagship surface in this class actually does.

   So the tier is a FILL, not a frame:
     night  tile rgb(25,34,53) on the panel's rgb(15,23,42)   — fill Δ, no shadow
            edge rgba(255,255,255,0.055): a whisper, not a line
     day    tile #ffffff on a ground that recedes to rgb(237,239,242)
            plus 0 1px 2px rgba(15,23,42,.05) — a card that sits ON the ground
            edge rgba(15,23,42,0.07)
   The day panel is the half that had to move: a white tile can only be a card
   if its ground is not also white, so the phone sheet takes the same soft grey
   the rail already had. Nothing is asked of the edge any more, and the accent
   tier drops from a 16% wash to 8–9% — a tint you notice only when you compare
   two tiles, which is exactly when it means something.
   test_wb_visual_language.js reads every one of these off the rendered page in
   both themes and both shells, so none of them is a comment that can rot. */
/* ── THE PALETTE, WRITTEN ONCE ─────────────────────────────────────────────
   A HUE IS A MEANING, AND IT IS SPENT IN THREE STRENGTHS — surface, edge, ink.
   That is the whole colour system of this panel, and it is short on purpose:
   two working hues, two state hues that only exist while a mode is on, and one
   hue that is spent on nothing at all.

     BRAND GREEN   «press this and an answer comes back» (kind = send_now) and
                   «this is the one you chose» (a segment, the send button).
                   surface 8% · edge 26% · glyph 100% · chosen segment: solid.
     NEUTRAL SLATE «this makes, fetches or saves something» — every other kind,
                   and every kind this file has not met yet.
                   surface 7.5% (night) / white (day) · edge 5.5–7% · glyph muted.
     AMBER         parent mode. Marks only: the dot, the 3px rule, the band.
     INDIGO        teacher mode. The same marks, never anything else (§36-4-۱).
     RED           nothing. It is held for a failure, which is the only thing a
                   child has ever been taught that red means.

   ONE STRENGTH IS NOT A SECOND COLOUR. The tier is not «a green card»: it is
   the same card with the same geometry, tinted. Read alone it barely registers
   — read against the tile above it, it is unmistakable, which is exactly the
   moment the distinction is worth anything.

   NO STRIPE. The first version of this marked the tier with a 3px bar on the
   tile's starting edge (§35-4-الف suggests one). Eleven tiles in a column each
   wearing the same bar is a rule of ribbon down the panel — the owner's words
   were «خط سمت راست کادر دکمه‌ها … خوب نیست», and they were right: a repeated
   ornament is decoration, not information. The hue moved into the three
   properties the card already has instead, so the tier is carried by the card
   itself and nothing is added to the geometry. */
:root {
  --nbgw-tile-face: rgba(148, 168, 200, 0.075);
  --nbgw-tile-edge: rgba(255, 255, 255, 0.085);
  /* §12-1 — «not yet»: a real face, never transparent, and a dash you can see. */
  --nbgw-tile-face-wait: rgba(148, 168, 200, 0.055);
  --nbgw-tile-edge-wait: rgba(255, 255, 255, 0.17);
  --nbgw-tile-shadow: none;
  --nbgw-tile-edge-hover: rgba(52, 211, 153, 0.42);
  --nbgw-tile-face-hover: rgba(148, 168, 200, 0.13);
  --nbgw-tile-send-face: rgba(16, 185, 129, 0.08);
  --nbgw-tile-send-edge: rgba(52, 211, 153, 0.22);
  --nbgw-glyph-quiet: #94a3b6;
  --nbgw-glyph-send: #34d399;
}

html[data-theme="light"] {
  --nbgw-tile-face: #ffffff;
  --nbgw-tile-edge: rgba(15, 23, 42, 0.085);
  --nbgw-tile-face-wait: #f2f5f8;
  --nbgw-tile-edge-wait: rgba(15, 23, 42, 0.20);
  --nbgw-tile-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);
  --nbgw-tile-edge-hover: rgba(5, 150, 105, 0.38);
  --nbgw-tile-face-hover: #f7fbf9;
  --nbgw-tile-send-face: #f3fdf9;
  --nbgw-tile-send-edge: rgba(5, 150, 105, 0.20);
  --nbgw-glyph-quiet: #4b5563;
  --nbgw-glyph-send: #047857;
}

/* ── the quiet default ─────────────────────────────────────────────────────
   This deliberately overrides the face half of §30-3's «one button family».
   The family was never the gradient: it is the radius, the type scale, the
   press animation and the focus ring, and all four are untouched. What §30-3
   could not know is that an identical GRADIENT on twenty-two tiles is exactly
   the measurement §35-4 later took — two colours for twenty-one errands. A
   flat surface in its place is not a downgrade: a gradient plus an inner
   highlight plus a drop shadow on every one of twenty-two cards is what makes
   a dense panel look moulded rather than calm. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item) {
  background-color: var(--nbgw-tile-face);
  background-image: none;
  border-color: var(--nbgw-tile-edge);
  box-shadow: var(--nbgw-tile-shadow);
}

/* Hover is the accent's third and last home on this surface, and it arrives as
   an EDGE. A card that changes its fill under the pointer competes with the
   tier that means «this one sends». */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item):hover,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item):focus-visible {
  background-color: var(--nbgw-tile-face-hover);
  background-image: none;
  border-color: var(--nbgw-tile-edge-hover);
  box-shadow: var(--nbgw-tile-shadow);
}

/* ── the accent tier ───────────────────────────────────────────────────────
   Same card, same geometry, one hue in all three of its layers. Nothing is
   added: no bar, no badge, no second radius. A reader scanning the column sees
   a warm block of cards where the answers come from and a cool one where the
   documents are made, and never has to be told which is which. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="send_now"] {
  background-color: var(--nbgw-tile-send-face);
  background-image: none;
  border-color: var(--nbgw-tile-send-edge);
  box-shadow: var(--nbgw-tile-shadow);
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="send_now"]:hover,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="send_now"]:focus-visible {
  background-color: var(--nbgw-tile-send-face);
  border-color: var(--nbgw-tile-edge-hover);
  box-shadow: var(--nbgw-tile-shadow);
}

/* ══ §12-1 · «not yet» IS STILL A BUTTON ══════════════════════════════════
   This rule used to take the face to `transparent` and the edge to the
   hairline `--nbgw-rule` (0.09 alpha on dark). Measured on the live origin at
   390×844: next to «گزارش برای والدین» — face rgba(148,168,200,.075), edge
   0.8px solid rgba(255,255,255,.086) — «خلاصهٔ امروز» came out
   background-color: rgba(0,0,0,0), border 1px dashed rgba(148,168,200,.09).
   Against the panel's own ground that is no card at all: the owner reads it
   as a heading, not as something that will become pressable.

   The reasoning behind it («a card that is not pressable yet should not look
   like it is sitting on top of anything») answered the wrong question. The
   tile is not being asked to look pressed — it is being asked to look like a
   BUTTON THAT IS NOT READY, which is a state of a button and has to be drawn
   on a button. So: same face family as the live tile with a touch less
   weight, and the state carried entirely by a dash that can actually be seen.
   One signal, said once, on a surface that exists. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-wb-btn:disabled, .nabgol-wb-btn[aria-disabled="true"]),
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-wb-btn:disabled, .nabgol-wb-btn[aria-disabled="true"]):hover,
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) :is(.nabgol-wb-btn:disabled, .nabgol-wb-btn[aria-disabled="true"]):focus-visible {
  border-color: var(--nbgw-tile-edge-wait);
  background-color: var(--nbgw-tile-face-wait);
  box-shadow: none;
}

/* ── §35-4-پ-۲ · ONE GLYPH PER TIER, AND NOT ONE FILE MORE ─────────────────
   Twenty-two tiles, zero glyphs: for a reader of seven to thirteen that is a
   wall of Persian text, and the reader this product is judged by (the parent,
   over the child's shoulder) scans shapes before words.

   WHAT THIS IS NOT: not an icon font (a fleet-wide download on a server that
   compresses nothing), not an <img>, not a coloured illustration. Each glyph
   is a ~180-byte inline SVG used as a MASK, so `background-color:
   currentColor` paints it in the tile's own ink — the glyph is automatically
   the colour of its tier in both themes, and a theme change can never leave it
   behind. At opacity .72 the mark measures 8.48:1 (night) and 6.51:1 (day)
   against the panel, well over the 3:1 a non-text mark needs.

   THE DEFAULT IS A DOT, AND THAT IS WHY THIS IS TOTAL. --nbgw-glyph is set on
   `[data-action-kind]` with no value listed, so a kind this file has not met
   gets a neutral mark rather than a 15px block of solid ink — which is what an
   unset mask-image would paint.

   IT COSTS ONE LINE'S WIDTH, NOT A COLUMN. The glyph is inline in the label's
   first line, so on the phone — where the tile is 92px wide, the label is
   clamped to two lines and the hint is already off below 361px — it takes 20px
   from ONE line instead of 20px from every row's height. A column beside the
   text would have cost the density §34-8 measured; a line above it would have
   cost a whole row. */
@supports ((-webkit-mask-image: linear-gradient(#000, #000)) or (mask-image: linear-gradient(#000, #000))) {
  :is(#nabgolWorkbench, #nabgolWorkbenchSheet)
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind] {
    --nbgw-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4.5' fill='%23000'/%3E%3C/svg%3E");
  }

  :is(#nabgolWorkbench, #nabgolWorkbenchSheet)
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="send_now"] {
    --nbgw-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12a8 8 0 1 1 3.2 6.4L4 20l1.1-3.3A7.9 7.9 0 0 1 4 12z'/%3E%3C/svg%3E");
  }

  :is(#nabgolWorkbench, #nabgolWorkbenchSheet)
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="mutate_doc"] {
    --nbgw-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a1.5 1.5 0 0 0-1.5 1.5v15A1.5 1.5 0 0 0 7 21h10a1.5 1.5 0 0 0 1.5-1.5V7.5z'/%3E%3Cpath d='M14 3v4.5h4.5M9 13h6M9 17h4'/%3E%3C/svg%3E");
  }

  :is(#nabgolWorkbench, #nabgolWorkbenchSheet)
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="share_out"] {
    --nbgw-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 3 3 10.2l7.2 3.1L13.3 21z'/%3E%3Cpath d='M10.2 13.3 21 3'/%3E%3C/svg%3E");
  }

  :is(#nabgolWorkbench, #nabgolWorkbenchSheet)
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="navigate"] {
    --nbgw-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 7s-2.2-2-8-2v13c5.8 0 8 2 8 2s2.2-2 8-2V5c-5.8 0-8 2-8 2z'/%3E%3Cpath d='M12 7v13'/%3E%3C/svg%3E");
  }

  :is(#nabgolWorkbench, #nabgolWorkbenchSheet)
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind="local_io"] {
    --nbgw-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 15v4a1.5 1.5 0 0 0 1.5 1.5h13A1.5 1.5 0 0 0 20 19v-4'/%3E%3Cpath d='M8 10.5l4 4 4-4M12 14.5V3'/%3E%3C/svg%3E");
  }

  :is(#nabgolWorkbench, #nabgolWorkbenchSheet)
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind]
    :is(.nabgol-wb-btn-label, .nabgol-ask-bar-btn-label, .nabgol-ask-sheet-item-label)::before {
    content: '';
    display: inline-block;
    vertical-align: -2px;
    inline-size: 15px;
    block-size: 15px;
    margin-inline-end: 5px;
    background-color: currentColor;
    opacity: 0.72;
    -webkit-mask-image: var(--nbgw-glyph);
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: center;
    -webkit-mask-size: contain;
    mask-image: var(--nbgw-glyph);
    mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
  }


}

/* ── §35-4-پ-۴ · THE DESKTOP RAIL NOW SAYS HOW MUCH IS BELOW THE FOLD ──────
   Measured: the rail's scrollport is 750px and its content 1851px — two and a
   half screens of tools — with a gutter of ZERO. Chrome's overlay scrollbar
   draws nothing until a mouse is already moving inside the column, so the rail
   told a reader with more than half its tools out of sight exactly nothing.
   The phone was given this in §34-3ث; the desktop was not, and the indicator
   it was given is the SAME element, the same sizing function and the same two
   colours — chat-workbench.js::syncVRail now measures whichever shell it is
   in instead of the phone alone, so there is one implementation and not two
   that can drift. */
@media (min-width: 768px) {
  body.desktop-chat.nabgol-workbench-on #nabgolWorkbench {
    position: relative;
  }

  body.desktop-chat #nabgolWorkbench .nabgol-wb-vrail {
    position: absolute;
    left: 5px;
    width: 3px;
    border-radius: 999px;
    background: #64748b;
    pointer-events: none;
    z-index: 3;
  }

  body.desktop-chat #nabgolWorkbench .nabgol-wb-vrail[hidden] {
    display: none;
  }

  body.desktop-chat #nabgolWorkbench .nabgol-wb-vthumb {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 3px;
    border-radius: 999px;
    background: #e2e8f0;
    will-change: transform;
  }

  html[data-theme="light"] body.desktop-chat #nabgolWorkbench .nabgol-wb-vthumb {
    background: #0f172a;
  }
}

/* ── AND THE PHONE'S GRID DOES NOT GET ONE — A MEASUREMENT SAID SO ────────
   §35-4-پ-۲ asks for a glyph on every tile. On the desktop rail, where a tile
   is 179px wide and the column has no ceiling, it costs nothing. On the phone
   it costs a whole ROW OF TOOLS, and that row is a number another part of this
   plan already owns: §34-3ج buys density with a three-column grid whose
   narrowest tile is 92px, and group 4 of test_wb_panel_masterpiece.js reads it
   off the rendered page — ≥80% of the tools in view at 390px, ≥62% at 320px.

   MEASURED, three times, on the local build of this very change:
     15px glyph + 5px gutter → the panel's column grew 716px → 771px;
                               390px fell to 76%, 320px to 60%. Both under.
     12px + 3px             → 320px recovered; 390px stayed at 19/25 = 76%.
     10px + 2px             → still 19/25 = 76%, and now in the night theme too.
   Any inline mark at all pushes one label from one clamped line to two, and one
   extra line in a grid row costs the whole row. Removing the mark returns the
   page to 20/25 = 80% — checked by disabling only this rule and re-running the
   same gate, so the cause is this rule and nothing else.

   So the floor wins over the wish, and it wins by a number rather than by
   taste. The phone keeps the other two halves of the visual language — the
   filled/hollow weight and the 3px bar — which cost no height at all, and the
   child on a phone still sees which tiles send and which make. If a later
   session wants the glyph here too, the thing to change first is the density
   floor or the grid, not this rule. */
@media (max-width: 767.98px) {
  body.mobile-chat #nabgolWorkbenchSheet
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind]
    :is(.nabgol-wb-btn-label, .nabgol-ask-bar-btn-label, .nabgol-ask-sheet-item-label)::before {
    display: none;
  }
}

/* ══ §36-4-ب · THE PANEL READS LIKE A PRODUCT, NOT A FORM ═══════════════════
 *
 * The three weights above answer «which errand is this?». They do not answer
 * «where am I?» — and a first capture of the finished rail said so plainly:
 * six section headings and six ledes in ONE ink at ONE size, a dial rendered
 * as three full-width slabs, and a glyph that bidi had dropped at the far end
 * of its own label. What follows is the second half of the same job, and every
 * change is either a hierarchy the eye needs or a number that was measured.
 *
 * ── 1 · A HEADING AND ITS SENTENCE ARE NOT THE SAME VOICE ─────────────────
 * `.nabgol-wb-section-title` and `.nabgol-wb-section-lede` were both 0.72rem
 * in --nbgw-rail-muted, so a heading and the sentence under it merged into one
 * grey paragraph and the panel had six of them. A heading is a place; a lede
 * is a description. They get two inks and two sizes, and the heading's ink
 * goes UP, never down — 11.9:1 on the night panel and 10.4:1 on the day one,
 * against 6.95:1 and 7.56:1 for the muted token they shared.
 *
 * ── 2 · THE ACCENT BUDGET ─────────────────────────────────────────────────
 * Solid brand green now means exactly one thing on this surface: «this is the
 * one you chose» (the dial's active pill, and the composer's send button in
 * the conversation). The wash means «this family sends». Nothing else in the
 * panel is allowed to be green, which is why the hollow tier's hover is the
 * only other place it appears and it appears as an edge, never a fill.
 */
:root {
  /* The heading's own ink. Deliberately not --nbgc-ink-strong: that token is
     for a title on the page's canvas, and this lands on a panel over a panel
     (the same composite --nbgw-rail-muted was derived against). */
  --nbgw-rail-head: #cbd5e1;
  --nbgw-rule: rgba(148, 168, 200, 0.09);
}

html[data-theme="light"] {
  --nbgw-rail-head: #334155;
  --nbgw-rule: rgba(15, 23, 42, 0.065);
}

body :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section-title {
  font-size: 0.76rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--nbgw-rail-head) !important;
}

body :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section-lede {
  font-size: 0.7rem;
  font-weight: 400;
  line-height: 1.5;
}

/* «الان: کم — …» is a readout, not a heading. It was 600-weight in the same
   size as both of them, which made the loudest line in the section the one
   that only repeats a state the pill above already shows. */
body :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-guidance-help {
  font-size: 0.69rem;
  font-weight: 400;
  opacity: 0.92;
}

/* ── 3 · THE RHYTHM ────────────────────────────────────────────────────────
   A section was 10px of top padding, 2px of bottom and a hairline — so the
   rule sat almost against the next heading and belonged to neither side. It
   is now centred in the gap it divides, and the gap is big enough to be read
   as one. The height this costs is paid back three times over by item 4. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section {
  padding: 14px 0 14px;
  border-bottom: 1px solid var(--nbgw-rule);
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section:first-child {
  padding-top: 6px;
}

:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section-head {
  margin: 0 0 8px;
}

/* ── 4 · THE DIAL IS A DIAL, ON BOTH SHELLS ────────────────────────────────
   «کم · متوسط · زیاد» were three full-width slabs in the rail, one of them a
   solid green bar 179px wide — a stack of buttons says «three errands», and
   the green said it loudly. The comment this replaces reasoned that «the rail
   has a whole column's height and no such pressure». It has: the rail's own
   measurement is 1851px of tools in a 750px column. So the dial becomes what
   it is on the phone — one track, three equal segments — which says «pick
   one», gives back ~76px of column, and shrinks the loudest green on the
   surface to a third of its width.
   The AUDIENCE row stays stacked: its two pills carry caption sentences
   («برای والدین: چطور به فرزندتان توضیح بدهید» is 41 characters), and 88px of
   segment would clamp them to four lines to save one row. */
#nabgolWorkbench .nabgol-ask-prefs-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 0;
  align-items: stretch;
  border: 1px solid var(--nbgw-tile-edge);
  border-radius: 10px;
  background: var(--nbgw-tile-face);
  overflow: hidden;
}

#nabgolWorkbench .nabgol-ask-prefs-row .nabgol-ask-pref-btn {
  border: 0;
  border-radius: 0;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 34px;
  padding: 4px 6px;
}

#nabgolWorkbench .nabgol-ask-prefs-row .nabgol-ask-pref-btn:not(.is-active):not([aria-pressed="true"]) {
  background: transparent;
  background-image: none;
}

#nabgolWorkbench .nabgol-ask-prefs-row .nabgol-ask-pref-btn:not(.is-active) + .nabgol-ask-pref-btn:not(.is-active) {
  border-inline-start: 1px solid var(--nbgw-rule);
}

/* The pill's free-standing 3px ring is clipped on three sides by the track's
   own `overflow: hidden`, so it is dropped here exactly as the phone drops it:
   inside a track, the fill alone already says «this one». */
#nabgolWorkbench .nabgol-ask-prefs-row .nabgol-ask-pref-btn.is-active,
#nabgolWorkbench .nabgol-ask-prefs-row .nabgol-ask-pref-btn[aria-pressed="true"] {
  box-shadow: none;
  font-weight: 700;
}

/* ── 5 · THE TILE HAS A SURFACE AGAIN, AND IT IS NEARLY NOTHING ────────────
   A pure outline reads as a wireframe at any zoom. 4.5% of the panel's own
   light is enough to make a card feel like a card and far too little to be a
   second colour: it moves the night tile from the panel's own value to
   rgb(21,29,49) and the day one to rgb(250,250,251). The BOUNDARY is still
   the edge, and the edge is still the measured 3:1 — the fill is depth, not
   information, which is why nothing is allowed to depend on it. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item) {
  background-color: var(--nbgw-tile-face);
}

/* ── 6 · THE GLYPH GOES IN A COLUMN OF ITS OWN, ON THE STARTING SIDE ───────
   As an inline `::before` inside the label it is an inline-block, which the
   bidi algorithm treats as a neutral object: on an RTL line it was reordered
   to the FAR END of the text, so every tile in the first capture had its mark
   floating alone on the left. A grid cell has no bidi to lose — column 1 of an
   RTL grid IS the right-hand side — and it also spans both rows, so the mark
   sits beside the whole tile instead of on the label's first line.
   Rail only, for the reason measured two blocks above: 179px has room for a
   16px column and a 92px phone tile does not.
   The two backup tiles are excluded on purpose — §36-3 made that pair
   deliberately lighter than the rest, and at 86px wide a column would take a
   third of the label. */
@media (min-width: 768px) {
  #nabgolWorkbench
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn)[data-action-kind]:not(.nabgol-wb-inline-btn) {
    display: grid;
    grid-template-columns: 16px minmax(0, 1fr);
    column-gap: 8px;
    row-gap: 1px;
    align-items: start;
    justify-items: start;
  }

  #nabgolWorkbench
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn)[data-action-kind]:not(.nabgol-wb-inline-btn) > * {
    grid-column: 2;
    min-width: 0;
    max-width: 100%;
  }

  #nabgolWorkbench
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn)[data-action-kind]:not(.nabgol-wb-inline-btn)::before {
    content: '';
    grid-column: 1;
    grid-row: 1 / span 2;
    inline-size: 16px;
    block-size: 16px;
    margin-block-start: 2px;
    background-color: var(--nbgw-glyph-quiet);
    opacity: 1;
    -webkit-mask-image: var(--nbgw-glyph);
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: center;
    -webkit-mask-size: contain;
    mask-image: var(--nbgw-glyph);
    mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
  }

  /* An engine with no mask support would paint that cell as a solid 16px block
     of ink. It gets no cell at all instead — the tile falls back to the plain
     column it was, and nothing is lost but the mark. */
  @supports not ((-webkit-mask-image: linear-gradient(#000, #000)) or (mask-image: linear-gradient(#000, #000))) {
    #nabgolWorkbench
      :is(.nabgol-wb-btn, .nabgol-ask-bar-btn)[data-action-kind]:not(.nabgol-wb-inline-btn) {
      display: flex;
    }
  }
}

/* The label's own inline mark is what the grid replaces; it stays declared for
   nobody, so it is switched off here rather than left to fight the cell. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-wb-btn, .nabgol-ask-bar-btn, .nabgol-ask-sheet-item)[data-action-kind]
  :is(.nabgol-wb-btn-label, .nabgol-ask-bar-btn-label, .nabgol-ask-sheet-item-label)::before {
  content: none;
}

/* ── 7 · THE RAIL IS A SURFACE, NOT A STRIPE OF THE CANVAS ─────────────────
   Measured: the day rail is rgb(237,239,242) against a rgb(248,250,252) page —
   1.05:1, which is not a surface, it is a rounding error. The column that
   holds every tool on the screen should be able to say where it starts. The
   night rail keeps its own value; what both get is a real dividing line
   instead of a 0.16-alpha hairline that the tiles' own edges now out-shout. */
@media (min-width: 768px) {
  body.desktop-chat.nabgol-workbench-on #nabgolWorkbench {
    border-inline-start: 1px solid var(--nbgw-rail-seam);
  }
}

:root {
  --nbgw-rail-seam: rgba(148, 168, 200, 0.12);
}

html[data-theme="light"] {
  --nbgw-rail-seam: rgba(15, 23, 42, 0.07);
}

/* ══ §36-4-پ · TWO GRAMMARS AND NOTHING IN BETWEEN ══════════════════════════
 *
 * With the dial turned into a track, the rail had three vocabularies on one
 * column: tinted hollow TILES for errands, one segmented TRACK for the
 * guidance dial, and — left over from before either existed — two free-
 * standing white CARDS for «والدین / معلم», which are a choice, not an errand.
 * Two cards that look like tiles but behave like a dial is the one thing a
 * panel this dense cannot afford, so the audience row becomes a track too.
 * It stays STACKED (its pills carry caption sentences; §36-4-ب-۴ has the
 * measurement) — a track can run down as easily as across, and what makes it
 * a track is the single frame and the shared seam, not the axis.
 *
 * After this the whole surface is exactly two grammars:
 *     a framed TRACK  → «یکی از اینها را انتخاب کن»   (audience · guidance)
 *     a free TILE     → «این کار را انجام بده»        (everything else)
 * and the tile's own three weights say what kind of errand it is.
 */
#nabgolWorkbench .nabgol-audience-row {
  border: 1px solid var(--nbgw-tile-edge);
  border-radius: 10px;
  background: var(--nbgw-tile-face);
  overflow: hidden;
  gap: 0;
}

#nabgolWorkbench .nabgol-audience-row .nabgol-ask-pref-btn {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

#nabgolWorkbench .nabgol-audience-row .nabgol-ask-pref-btn:not(.is-active):not([aria-pressed="true"]) {
  background: transparent;
  background-image: none;
}

#nabgolWorkbench .nabgol-audience-row .nabgol-ask-pref-btn:not(.is-active) + .nabgol-ask-pref-btn:not(.is-active) {
  border-block-start: 1px solid var(--nbgw-rule);
}

/* ── every section gets the same rule, including the three inside the ask bar
   ─────────────────────────────────────────────────────────────────────────
   «پیشرفتِ من», «گزارشِ پیشرفت» and «پشتیبان‌گیری» are real
   `.nabgol-wb-section` elements and have carried a bottom rule since §2.
   «مخاطبِ پاسخ», «میزانِ کمک» and «از معلم بخواه» are not — they are heads
   inside #nabgolAskBar, which is itself one section. So the panel drew a line
   between its 4th and 5th headings and nothing between its 2nd and 3rd, and
   the eye read that as «these two belong together» when they do not.
   The rule goes on the head rather than on a wrapper because there is no
   wrapper to put it on, and `:first-child` keeps it off the top of the bar
   where the section's own boundary already is.
   The `> * + *` rule further up gives every child of the bar a 10px top
   margin; most of that is spent on the padding the rule needs to sit clear
   of, rather than added to it. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet)
  :is(.nabgol-ask-bar, .nabgol-wbm-ask) > .nabgol-wb-section-head:not(:first-child) {
  margin-top: 4px;
  padding-top: 14px;
  border-top: 1px solid var(--nbgw-rule);
}

/* The audience block's own footnote is the third voice in its section and was
   the same size as the heading. It is a footnote. */
body :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-audience-help {
  font-size: 0.69rem;
  font-weight: 400;
  line-height: 1.5;
  opacity: 0.92;
}

/* ── the indicator is a scrollbar, not a stripe ────────────────────────────
   Its two colours are what test_wb_panel_masterpiece.js group 3 measures —
   track ≥3:1 on the panel and thumb ≥3:1 on the track — and on a day panel
   that pair is forced to straddle: a mid-slate track and a near-black thumb.
   At 3px on a 200px column that read as the loudest thing in the rail. Width
   is not a contrast, so this is the one dimension that can be spent: 2px, and
   two pixels further off the edge. The phone keeps 3px — a thumb-driven
   scroller is looked at, not glanced at. */
@media (min-width: 768px) {
  body.desktop-chat #nabgolWorkbench .nabgol-wb-vrail,
  body.desktop-chat #nabgolWorkbench .nabgol-wb-vthumb {
    width: 2px;
  }

  body.desktop-chat #nabgolWorkbench .nabgol-wb-vrail {
    left: 7px;
  }
}

/* ── the last section does not divide anything ────────────────────────────
   §2 wrote `.nabgol-wb-section:last-child { border-bottom: 0 }`, which is
   (0,1,1). §36-4-ب's rhythm rule is (1,1,0) and beat it, so the panel grew a
   rule under its final row with nothing on the other side of it. */
:is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-section:last-child {
  border-bottom: 0;
}

/* ── «پیشرفتِ من» is the same card on both shells ──────────────────────────
   §34-3ج made it the phone's one special card: the only control in the panel
   with live data behind it, so it is a surface with a chevron rather than one
   more tile. The rail never got that, and after §36-4 it was the only row in
   the column with neither a glyph nor a weight of its own — it read as a tile
   that had lost its icon. Same declarations, one media query further out. */
@media (min-width: 768px) {
  #nabgolWorkbench .nabgol-wb-btn[data-wb-progress-btn] {
    position: relative;
    min-height: 52px;
    padding-inline-end: 28px;
    border-radius: 14px;
    background: var(--nbgc-surface-raised, rgba(148, 168, 200, 0.17));
  }

  #nabgolWorkbench .nabgol-wb-btn[data-wb-progress-btn]::after {
    content: '';
    position: absolute;
    inset-inline-end: 12px;
    top: 50%;
    width: 7px;
    height: 7px;
    border-inline-start: 2px solid var(--nbgw-rail-muted, #94a3b6);
    border-bottom: 2px solid var(--nbgw-rail-muted, #94a3b6);
    transform: translateY(-50%) rotate(-45deg);
  }

  #nabgolWorkbench .nabgol-wb-progress-line {
    font-size: 0.84rem;
    font-weight: 700;
  }
}

/* ── the day panel has to recede for a white card to be a card ─────────────
   The rail already stood on rgb(237,239,242). The phone sheet stood on pure
   white, which is why §35-4-پ-۱ could measure a 1.25:1 tile there and call it
   invisible — it was not the tile that was wrong, it was the ground. A card
   is white; the surface it sits on is not. Same value as the rail, so the two
   shells are one product, and the head keeps the sheet's own white so the
   panel still reads as a sheet that was pulled up over the page. */
@media (max-width: 767.98px) {
  html[data-theme="light"] body.mobile-chat #nabgolWorkbenchSheet {
    /* chat-mobile-flagship.css paints every .bottom-sheet with an !important
       --nbgc-sheet-face, which is the right default for a menu of four rows and
       the wrong one for a panel of twenty-two white cards. Same weight, one id
       narrower, and nothing outside this panel is touched. */
    background: #eff1f5 !important;
  }

  html[data-theme="light"] body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-head {
    background: #ffffff;
    border-bottom-color: var(--nbgw-rule);
  }
}

/* The one special card keeps being special by being the LIGHTEST thing in the
   column on a day panel and the raised one at night — the same idea in both,
   which `--nbgc-surface-raised` cannot express on a ground that is already
   grey. */
html[data-theme="light"] :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-btn[data-wb-progress-btn] {
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.07);
}

/* ── the head sits on the panel, and the panel starts under it ─────────────
   A 1px hairline under a title is what a dialog does; a panel that owns a
   whole column says it with the ground instead. The head keeps the page's own
   surface and the body drops to the panel ground, so the boundary is a change
   of material rather than a drawn line. */
@media (min-width: 768px) {
  body.desktop-chat.nabgol-workbench-on #nabgolWorkbench .nabgol-wb-head {
    border-bottom-color: var(--nbgw-rule);
  }
}

/* ── the rail's indicator is a thumb, not a rule down the column ───────────
   §34-6-۳ makes the phone's indicator carry a TRACK as well as a thumb, and
   the two contrasts it measures (track ≥3:1 on the panel, thumb ≥3:1 on the
   track) force that track to be a mid-slate and the thumb to be near-white.
   On a phone that is right: a thumb-driven scroller is looked at.
   On the rail it was the loudest thing in the column — a 780px light line
   beside twenty quiet cards, for a scroller a mouse wheel drives without ever
   looking at it. So the rail keeps the thumb and drops the track's fill: the
   thumb then measures against the panel itself (far above 3:1), and what is
   left is exactly the overlay scrollbar every desktop surface in this class
   uses. The phone is untouched. */
@media (min-width: 768px) {
  body.desktop-chat #nabgolWorkbench .nabgol-wb-vrail {
    background: transparent;
  }

  body.desktop-chat #nabgolWorkbench .nabgol-wb-vthumb {
    background: #748094;
  }

  html[data-theme="light"] body.desktop-chat #nabgolWorkbench .nabgol-wb-vthumb {
    background: #727e90;
  }
}

/* ── the glyph is the tier's third strength ────────────────────────────────
   It was `currentColor` at 58% — the label's own ink, dimmed, which made every
   mark on the column the same grey no matter what it stood for. A hue that
   only reaches the surface and the edge is a tint; a hue that also reaches the
   mark is a language. The quiet tier's glyph is the panel's muted ink at full
   strength (6.4:1 on a night card, 7.5:1 on a day one) and the accent tier's
   is the brand itself (#34d399 on the night tint, #047857 on the day one —
   both far past the 3:1 a non-text mark owes). */
@media (min-width: 768px) {
  #nabgolWorkbench
    :is(.nabgol-wb-btn, .nabgol-ask-bar-btn)[data-action-kind="send_now"]:not(.nabgol-wb-inline-btn)::before {
    background-color: var(--nbgw-glyph-send);
  }
}

/* ── the narrow phone buys its rhythm back ─────────────────────────────────
   §36-4-ب-۳ gave a section 14px of air above and below where it had 10 and 2.
   On the rail and on a 390px phone that is paid for by the dial's new shape.
   At 320px it is not: measured, the extra air cost one whole row of the
   three-column grid and group 4 of test_wb_panel_masterpiece.js read
   15/25 = 60% against its 62% floor.
   360px is already this panel's «less of everything» breakpoint — the hint
   line and the audience captions come off there for the same reason — so the
   rhythm is halved there too rather than everywhere. */
@media (max-width: 360.98px) {
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section {
    padding-top: 5px;
    padding-bottom: 5px;
  }

  body.mobile-chat #nabgolWorkbenchSheet
    :is(.nabgol-ask-bar, .nabgol-wbm-ask) > .nabgol-wb-section-head:not(:first-child) {
    margin-top: 0;
    padding-top: 5px;
  }

  body.mobile-chat #nabgolWorkbenchSheet .nabgol-wb-section-head {
    margin-bottom: 2px;
  }

  body.mobile-chat #nabgolWorkbenchSheet
    :is(.nabgol-ask-bar, .nabgol-wbm-ask) > * + * {
    margin-top: 6px;
  }
}

/* ── §36-4-ت · TWO CONTRAST DEFECTS THE MODE COLOURS EXPOSED ───────────────
 *
 * ۱ · THE CAPTION UNDER A CHOSEN PILL WAS UNREADABLE, AND HAD BEEN ALL ALONG.
 * §34-8 gave the phone's audience captions a FIXED ink — `--nbgc-ink-soft` —
 * while the pill under them changes surface with the mode: white when it is
 * not chosen, solid amber for «والدین», solid indigo for «معلم». A fixed ink
 * over a moving surface can only be right by luck, and measured on the day
 * theme it was not: the caption on the chosen pill read 1.35:1, and even on the
 * unchosen white one it read 3.76:1 — under the 4.5:1 floor this project holds
 * every panel label to. No gate had ever seen it, because
 * test_controls_always_reachable.js never opens a mode, which is exactly how a
 * bug survives three sessions of green.
 * The fix is not a third colour. The caption belongs to its pill, so it takes
 * the pill's own ink and steps back with opacity — which is right on white,
 * right on amber, right on indigo, and right on whatever a later mode is.
 * Measured after: 12.4:1 on the unchosen pill, 5.3:1 on the chosen one.
 *
 * ۲ · THE PANEL'S NAME IS NOT A MODE.
 * §7 asked for three places a special mode is visible, and §30 answered with
 * the mode bar, the 3px rule and the panel head — tinting BOTH the head's
 * title and its state line. «میزِ کار» is the name of the place; it means the
 * same thing in every mode, and a name that changes colour is the loudest way
 * to say something that is not true. The sentence under it («حالت معلم روشن
 * است — پاسخ‌ها راهنمای تدریس‌اند…») says it in words AND in the mode's hue,
 * and it is joined by the bar, the rule and the chosen pill: four signals, and
 * this removes the only one that was decorative. */
@media (min-width: 361px) {
  body.mobile-chat #nabgolWorkbenchSheet .nabgol-ask-pref-btn-cap {
    color: inherit;
    opacity: 0.78;
  }
}

body.nabgol-special-mode-on :is(#nabgolWorkbench, #nabgolWorkbenchSheet) .nabgol-wb-title {
  color: var(--nbgc-ink-strong, #f3f7fb) !important;
}
