/* Non-critical styles for new.nexius.pro SPA — extracted from inline <style>
 * in index.html. Theme variables, body baseline, and the pre-React skeleton-
 * shell stay inline so the initial HTML paint stays styled even if this file
 * is still in flight. Everything here is either UI polish, mobile utilities,
 * or layout/markdown styles that only render inside the React tree (i.e. after
 * the JS bundle has parsed and React has mounted, by which time the stylesheet
 * has long since loaded). Cache-bust via ?v=<hash> in index.html. */

::-webkit-scrollbar { width: 8px; height: 8px; }
/* Auto-hide: the thumb is invisible at rest and only fades in while the pointer
   is over the scrollable area, so a resting scrollbar never sits on an
   overflowing panel (chat / menus / lists). The gutter stays reserved
   (scrollbar-gutter: stable below) → revealing the thumb never shifts layout. */
::-webkit-scrollbar-thumb { background: transparent; transition: background 0.18s ease; }
:hover::-webkit-scrollbar-thumb { background: var(--scroll-thumb); }
::-webkit-scrollbar-track { background: transparent; }
html, body, #root { max-width: 100%; overflow-x: hidden; }
/* Reserve scrollbar space даже когда контента мало (workspace overflow:hidden,
   marketplace overflow:auto) — иначе при переключении табов viewport ширина
   прыгает на ~15px и логотип/центрированный nav в TopBar сдвигается. */
html { scrollbar-gutter: stable; }

/* Plain background — раньше тут была dotted-grid SVG-картинка (32x32 paddle
   из circle r=1), но юзер попросил убрать точки. Оставлен только
   background-color, !important чтобы перебить inline body shorthand из
   index.html. --canvas — отдельный токен страницы: в light это мягкий
   серый, чтобы белые поверхности (--bg) читались как карточки; в тёмных
   темах --canvas == --bg, разницы нет. */
body {
  background-color: var(--canvas) !important;
  background-image: none !important;
}
/* Strip the opaque var(--bg) backgrounds React views set on their roots
   so the body bg bleeds through (legacy от dotted-grid; теперь просто
   keep transparent чтобы цвет body был один источник истины). */
[data-screen-label] { background: transparent !important; }
input::placeholder { color: var(--placeholder); }
button:focus-visible, input:focus-visible, select:focus-visible { outline: 1px solid var(--fg); outline-offset: 1px; }
select { color-scheme: light; }
[data-theme="dark"] select,
[data-theme="dark-blue"] select,
[data-theme="dark-gray"] select { color-scheme: dark; }
.wireframe-stamp {
  position: fixed; top: 12px; right: 16px; z-index: 100;
  font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-watermark);
  letter-spacing: 0.18em; text-transform: uppercase; pointer-events: none;
}

/* ── Right-side drawer animations ── */
@keyframes drawer-slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes drawer-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes drawer-slide-in-left { from { transform: translateX(-100%); } to { transform: translateX(0); } }

/* ── Worker Setup sidebar cards (create.jsx WorkerExtrasAside) ──
   Hover lift + border accent that's hard to express purely as inline
   styles on a static React element. Pairs with `createStyles.setupCard`
   and the `.nx-setup-card` className applied to each section. The card
   body never gets the hover treatment — only the header is interactive,
   so we restrict the cursor pointer there. */
.nx-setup-card { will-change: transform; }
.nx-setup-card:hover {
  border-color: var(--border-mid, var(--border));
  box-shadow: 0 6px 24px -18px rgba(0, 0, 0, 0.45);
}
[data-theme="dark"] .nx-setup-card:hover,
[data-theme="dark-blue"] .nx-setup-card:hover,
[data-theme="dark-gray"] .nx-setup-card:hover {
  background-color: color-mix(in oklab, var(--bg) 92%, white 8%);
  box-shadow: 0 6px 24px -16px rgba(0, 0, 0, 0.7);
}

/* One-click example briefs under the centered Create composer. */
.nx-example-pill {
  transition: border-color 140ms ease, color 140ms ease, background-color 140ms ease;
}
.nx-example-pill:hover {
  border-color: var(--border-strong);
  color: var(--fg-strong);
  background: var(--bg);
}

/* Voice-dictation mic button — pulsing ring while listening. */
@keyframes nx-mic-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 255, 136, 0.35); }
  50% { box-shadow: 0 0 0 5px rgba(0, 255, 136, 0); }
}
.nx-mic-listening { animation: nx-mic-pulse 1.4s ease-out infinite; }

/* ── Build-pipeline indicators (BuildingPreview in /create) ── */
@keyframes pulse  { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
@keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(280%); } }
/* progressShimmer — overlay sweep on BuildingProgress when the LLM
   takes longer than estimated. Pure visual cue that the request is
   still alive while pct is pinned at 99%. */
@keyframes progressShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
/* indeterminateSlide — travelling slice for indeterminate progress
   (BuildingProgress when the backend doesn't stream % data). The slice
   is 35% wide; it enters from -35% and exits at 100%, so the bar is
   never fully empty mid-animation. */
@keyframes indeterminateSlide { 0% { left: -35%; } 100% { left: 100%; } }

/* ── Chat-list "working now" process animations ───────────────────
   Each run path (workspace.jsx renderAgentItem / renderTeamItem) gets a
   distinct micro-animation so the user can tell WHAT a worker/team is doing
   at a glance: chat → pulsing dots, playbook → marching equalizer bars,
   scheduled → rotating ring, team → a dot handing off across a track. The
   accent green (#00FF88) reads as "alive". prefers-reduced-motion freezes
   them (see the media block near the spinner). */
@keyframes nx-proc-bar    { 0%, 100% { transform: scaleY(0.35); opacity: 0.45; } 50% { transform: scaleY(1); opacity: 1; } }
@keyframes nx-proc-travel { 0% { left: 0; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { left: 100%; opacity: 0; } }
@keyframes nx-proc-ring   { 0% { box-shadow: 0 0 0 0 rgba(0, 255, 136, 0.45); } 70%, 100% { box-shadow: 0 0 0 5px rgba(0, 255, 136, 0); } }

/* Avatar gets a single expanding green ring while any process runs. */
.nx-proc-avatar-ring { animation: nx-proc-ring 1.8s cubic-bezier(0.4, 0, 0.6, 1) infinite; }

@media (prefers-reduced-motion: reduce) {
  .nx-proc-avatar-ring { animation: none; }
}

/* ── Workspace Office ─────────────────────────────────────────────
   The office is a real viewport-filling product surface, not a card preview.
   Mobile keeps the actual floor visible inside a horizontal scroller so the
   pixel workers do not collapse into unreadable dots. */
.nx-office-panel {
  flex: 1;
  min-width: 0;
  height: calc(100vh - 56px);
  padding: 4px 6px 6px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}
.nx-office-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  gap: 16px;
  flex-wrap: wrap;
}
.nx-office-intro {
  max-width: 760px;
}
.nx-office-intro h1 {
  font-size: 20px !important;
  margin: 0 !important;
}
.nx-office-intro > div:first-child {
  margin-bottom: 2px !important;
}
.nx-office-intro p {
  display: none;
}
.nx-office-stats {
  margin-bottom: 6px !important;
  flex: 0 0 auto;
}
.nx-office-stats > div {
  padding: 6px 12px !important;
}
.nx-office-stats > div > div:first-child {
  font-size: 8.5px !important;
}
.nx-office-stats > div > div:last-child {
  font-size: 16px !important;
}
.nx-office-floor {
  border: none;
  background: var(--bg-soft);
  position: relative;
  overflow: hidden;
  flex: 1 1 auto;
  min-height: 0;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02);
}
.nx-office-floor svg {
  width: 100%;
  height: 100%;
  display: block;
  shape-rendering: crispEdges;
}
.nx-office-mobile-list {
  display: none !important;
}

/* ── Hero (HomeHero) decorative animations ── */
@keyframes nx-glow-breathe {
  0%, 100% { opacity: 0.55; transform: translate(-50%, -50%) scale(1); }
  50%      { opacity: 0.85; transform: translate(-50%, -50%) scale(1.06); }
}

/* Gradient-shimmer green accent — replaces the flat #00FF88 fill on the
   "AI workers" headline word. Slow horizontal sweep gives the hero motion
   without distracting from copy; reduced-motion users get a static fill. */
@keyframes nx-hero-shimmer {
  0%   { background-position:   0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position:   0% 50%; }
}
.nx-hero-accent {
  background-image: linear-gradient(110deg,
    #00FF88 0%, #6CFFB6 28%, #C8FFE0 50%, #6CFFB6 72%, #00FF88 100%);
  background-size: 240% 100%;
  background-position: 0% 50%;
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: nx-hero-shimmer 9s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
  filter: drop-shadow(0 0 28px rgba(0, 255, 136, 0.18));
}
@media (prefers-reduced-motion: reduce) {
  .nx-hero-accent { animation: none; background-position: 0% 50%; }
}

/* Status pulse dot for the "live now" pill — radial ring expands then fades. */
@keyframes nx-hero-pulse-dot {
  0%   { box-shadow: 0 0 0 0   rgba(0, 255, 136, 0.55); }
  70%  { box-shadow: 0 0 0 9px rgba(0, 255, 136, 0);    }
  100% { box-shadow: 0 0 0 0   rgba(0, 255, 136, 0);    }
}
.nx-hero-pulse-dot {
  display: inline-block;
  width: 6px; height: 6px; border-radius: 50%;
  background: #00FF88;
  animation: nx-hero-pulse-dot 2.4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Live-status pill that sits between title and lede. Tight mono, faint green
   border, glassy fill — anchors the hero with a real "this is alive" signal. */
.nx-hero-live-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px 6px 12px;
  margin-bottom: 22px;
  border: 1px solid rgba(0, 255, 136, 0.22);
  border-radius: 999px;
  background: rgba(0, 255, 136, 0.04);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-strong);
  font-weight: 400;
}
.nx-hero-live-pill .nx-hero-live-sep {
  color: var(--fg-faintest);
  margin: 0 2px;
}

/* Faint dotted grid behind the hero — only the top-left quadrant via mask,
   so it suggests a coordinate plane without competing with the headline. */
.nx-hero-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.045) 1px, transparent 0);
  background-size: 28px 28px;
  background-position: -1px -1px;
  -webkit-mask-image:
    radial-gradient(ellipse 60% 60% at 22% 38%, rgba(0, 0, 0, 0.9), transparent 75%);
          mask-image:
    radial-gradient(ellipse 60% 60% at 22% 38%, rgba(0, 0, 0, 0.9), transparent 75%);
  opacity: 0.55;
}

/* Hairline rule that extends from the eyebrow text toward the viewport edge —
   adds editorial discipline without weight. Drawn inside .nx-home-eyebrow as
   a flex item; flex:1 lets it fill remaining space up to a reasonable cap. */
.nx-hero-eyebrow-rule {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--border-mid), transparent);
  max-width: 140px;
  margin-left: 4px;
  opacity: 0.7;
}
@media (max-width: 768px) {
  .nx-hero-eyebrow-rule { display: none; }
}
/* Composer input wrapper — invisible on desktop (textarea + actions row
   stack vertically inside .nx-composer as before). Flipped to flex-row on
   mobile fullscreen — see body.nx-chat-fullscreen rules below. */
.nx-composer-input { display: contents; }

/* Chat-pane wrapper must be able to shrink below its content so the message
   list scrolls and the composer stays pinned at the bottom. The flex wrapper
   around LiveChatPanel / TeamOrchestratorPanel sets min-width:0 but not
   min-height, so its default min-height:auto let it grow to full content
   height (tens of thousands of px) and push the input field off-screen
   ("окно ввода пропало"). Force min-height:0 here — defensive, covers every
   chat pane regardless of the inline style on the wrapper. */
.mob-pane-chat > div { min-height: 0; }

.nx-hero-glow { animation: nx-glow-breathe 7s ease-in-out infinite; }

@keyframes nx-fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.nx-hero-fade { animation: nx-fade-up 0.7s cubic-bezier(0.22, 1, 0.36, 1) both; }

/* ── Sprout (HomeHeroSprout) ── fully grown, gentle sway + glow + sparks.
   Each leaf wraps in a sway group; the rotation pivots around the leaf
   base (50% 100% of fill-box). Left and right swing in counter-phase. */
@keyframes nx-sprout-sway-l {
  0%, 100% { transform: rotate(-1.4deg); }
  50%      { transform: rotate(2.2deg); }
}
@keyframes nx-sprout-sway-r {
  0%, 100% { transform: rotate(1.4deg); }
  50%      { transform: rotate(-2.2deg); }
}
.nx-sprout-sway-l, .nx-sprout-sway-r {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}
.nx-sprout-sway-l { animation: nx-sprout-sway-l 5.5s ease-in-out infinite; }
.nx-sprout-sway-r { animation: nx-sprout-sway-r 5.5s ease-in-out 0.25s infinite; }

@keyframes nx-sprout-glow-pulse {
  0%, 100% { opacity: 0.65; }
  50%      { opacity: 1; }
}
.nx-sprout-glow { animation: nx-sprout-glow-pulse 5s ease-in-out infinite; }

/* tiny rising particles around the sprout */
@keyframes nx-sprout-spark {
  0%   { opacity: 0; transform: translateY(0); }
  20%  { opacity: 0.9; }
  100% { opacity: 0; transform: translateY(-60px); }
}
.nx-sprout-spark { animation: nx-sprout-spark 4.5s ease-out infinite; }

/* Soil horizon — gentle breath: scaleX in from center + opacity pulse
   so the ground line feels alive without competing with the leaf sway. */
@keyframes nx-sprout-ground-pulse {
  0%, 100% { opacity: 0.7; transform: scaleX(0.92); }
  50%      { opacity: 1;   transform: scaleX(1); }
}
.nx-sprout-ground {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: nx-sprout-ground-pulse 5.5s ease-in-out 0.4s infinite;
}

/* ── Worker card grid — desktop default = 4 columns, fall back as
     viewport narrows so cards never get crushed below ~240 px. ────── */
@media (max-width: 1280px) { .mb-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; } }
@media (max-width: 960px)  { .mb-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; } }
@media (max-width: 640px)  { .mb-card-grid { grid-template-columns: 1fr !important; } }

/* ── TopBar responsive — laptops & narrow windows ────────────────────
   The desktop TopBar packs logo + 5-item nav (incl. the long "Create AI
   worker") + a centered decorative tagline + theme toggle + account
   cluster onto one flex row. The full row only fits cleanly at ≥1680px
   (verified with screenshots); below that the flex:1 tagline
   (whiteSpace:nowrap, can't shrink past its text) squeezes the row —
   nav labels wrap to 2–3 lines and the account cluster clips off the
   right edge (the "overlap / unreadable" reported on 13" screens).
   Fix: drop the decorative tagline ≤1680px (purely a slogan,
   pointer-events:none, already hidden ≤768px via mb-hide);
   margin-left:auto on the theme cluster replaces it as the spacer that
   right-anchors theme + account — same trick the ≤768px block uses on
   .nx-topbar-right. Queries start at min-width:769px so they never
   collide with the existing ≤768px mobile rules. */
.nx-topbar-nav button { white-space: nowrap; }
@media (min-width: 769px) and (max-width: 1680px) {
  .nx-topbar-tagline { display: none !important; }
  .nx-topbar-row .nx-topbar-right { margin-left: auto !important; }
}
/* Narrow windows 769–1100px: tighten the row so logo + nav + theme +
   account never overflow before the burger menu takes over at ≤768px. */
@media (min-width: 769px) and (max-width: 1100px) {
  .nx-topbar-row { gap: 12px !important; }
  .nx-topbar-nav { margin-left: 4px !important; }
  .nx-topbar-nav button { padding: 6px 8px !important; letter-spacing: 0.05em !important; }
  .nx-topbar-logo-text { font-size: 23px !important; }
}

/* Collapsible top bar. Default desktop padding; collapsed shrinks to a
   compact strip (~40px) by hiding non-essential text and reducing padding,
   actually freeing vertical space. On mobile the button is hidden, so keep
   full padding to avoid a stranded collapsed state. */
.nx-topbar-root { padding: 11px 28px; transition: padding 180ms ease; }
.nx-topbar-root.nx-topbar-collapsed { padding: 6px 28px; }
.nx-topbar-root.nx-topbar-collapsed .nx-topbar-row { gap: 12px !important; }
/* Keep the wallet balance visible next to the avatar even when collapsed —
   only the wordmark + sign-up CTA fold away. */
.nx-topbar-root.nx-topbar-collapsed .nx-topbar-logo-text,
.nx-topbar-root.nx-topbar-collapsed .nx-topbar-signup { display: none !important; }
.nx-topbar-root.nx-topbar-collapsed .nx-topbar-avatar {
  width: 30px !important; height: 30px !important;
  min-width: 30px !important; min-height: 30px !important;
}
@media (max-width: 768px) {
  .nx-topbar-root.nx-topbar-collapsed { padding: 20px 28px; }
}

/* ── Mobile responsive (≤768px) ──────────────────────────────── */
/* Default desktop state for mobile-only utility classes.
   `mb-only` is for inline-level chips (display:inline-flex on mobile).
   `mb-flex` is for block-level panels (display:flex on mobile).
   Both default to `display:none !important` so they beat any inline
   `style={{ display: "flex" }}` left in JSX from earlier code. */
.mb-only { display: none !important; }
.mb-flex { display: none !important; }
.mb-backdrop { display: none; }
.nx-title-tail { display: inline; }
.nx-mobile-copy,
.nx-mobile-flow { display: none; }

/* ── Fleet status filter — minimal underline tabs ─────────────────────
   ACTIVE / STOPPED / ARCHIVED. No container, no elevation, no halo:
   three text buttons in a row sharing a thin baseline; the active one
   carries a 1px underline + brighter text. Dot fills from --dot-color
   inlined on the button. */
.nx-fleet-status-tabs {
  display: inline-flex;
  align-items: stretch;
  gap: 24px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--border-soft);
}
.nx-fleet-status-tab {
  position: relative;
  border: none;
  background: transparent;
  color: var(--fg-faint);
  padding: 8px 2px;
  margin-bottom: -1px;
  border-bottom: 1px solid transparent;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  transition: color 140ms ease, border-color 140ms ease;
}
.nx-fleet-status-tab:hover { color: var(--fg-muted); }
.nx-fleet-status-tab:focus-visible { outline: none; color: var(--fg-strong); }
.nx-fleet-status-tab.is-active {
  color: var(--fg-strong);
  border-bottom-color: var(--fg-strong);
}
.nx-fleet-status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--dot-color, var(--fg-faint));
  flex-shrink: 0;
}
.nx-fleet-status-count {
  font-size: 10.5px;
  color: var(--fg-faint);
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-variant-numeric: tabular-nums;
  transition: color 140ms ease;
}
.nx-fleet-status-tab.is-active .nx-fleet-status-count { color: var(--fg-muted); }

/* Marketplace card grid: 5-up base (set inline in marketplace.jsx) steps down
   by viewport width so cards never get too narrow. Ranges are non-overlapping
   with the ≤768px → 1fr rule below, so cascade order is irrelevant. */
@media (max-width: 1500px) and (min-width: 1201px) {
  .mb-cards-auto { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
}
@media (max-width: 1200px) and (min-width: 1025px) {
  .mb-cards-auto { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
}
@media (max-width: 1024px) and (min-width: 769px) {
  .mb-cards-auto { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

@media (max-width: 768px) {
  .mb-pad { padding-left: 16px !important; padding-right: 16px !important; }
  .mb-pad-y { padding-top: 14px !important; padding-bottom: 14px !important; }
  .mb-pad-tight { padding: 16px !important; }
  .mb-hide { display: none !important; }
  .mb-only { display: inline-flex !important; }
  /* My fleet — status filter on mobile renders as a single compact <select>
     instead of a 3-segment row. The segmented control is hidden via .mb-hide
     in JSX. We strip the OS chrome and paint our own decorations:
       ::before — 5px colored dot reflecting current status (CSS var
                  --status-color set inline on the wrap by JSX),
       ::after  — chevron on the right.
     Native picker on iOS/Android still pops on tap; only the trigger is
     restyled to match the rest of the workspace chrome. */
  .nx-fleet-status-select-wrap {
    position: relative;
    width: fit-content;
    max-width: 100%;
  }
  .nx-fleet-status-select-wrap::before {
    content: "";
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--status-color, var(--fg-faint));
    pointer-events: none;
  }
  .nx-fleet-status-select-wrap::after {
    content: "▾";
    position: absolute;
    right: 9px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 9px;
    color: var(--fg-faint);
    pointer-events: none;
  }
  .nx-fleet-status-select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background: var(--bg);
    color: var(--fg-strong);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: 5px 22px 5px 22px;
    font-size: 10.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
    font-weight: 500;
    cursor: pointer;
    outline: none;
    line-height: 1.3;
    min-width: 0;
  }
  .nx-fleet-status-select:focus-visible {
    border-color: var(--fg-strong);
  }
  /* FleetPanel (unauthed wireframe) stats strip: 4 stats in one row at
     ~95px each clips "$324.18" and the success-rate %. Collapse to 2x2
     and rewire the border recipe so the cross-seam (between row 1 and
     row 2) reads with a top-border on items 3-4 instead of stale
     right-borders on items 1 and 3. */
  .nx-fleet-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  .nx-fleet-stats > div {
    border-right: none !important;
  }
  .nx-fleet-stats > div:nth-child(2n+1) {
    border-right: 1px solid var(--border-soft) !important;
  }
  .nx-fleet-stats > div:nth-child(n+3) {
    border-top: 1px solid var(--border-soft);
  }
  /* Create — team review stats footer (4 metrics: Orchestrator / Workers /
     Avg runtime / Tools). Same 4-col → 2x2 collapse + border rewire as
     FleetPanel above. */
  .nx-team-review-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
  .nx-team-review-stats > div {
    border-right: none !important;
  }
  .nx-team-review-stats > div:nth-child(2n+1) {
    border-right: 1px solid var(--border-soft) !important;
  }
  .nx-team-review-stats > div:nth-child(n+3) {
    border-top: 1px solid var(--border-soft);
  }
  /* Create — team review member cards. Inline grid is N × minmax(180px),
     so 3+ workers overflow a 480px viewport. On mobile drop to a single
     column and unclamp maxWidth (inline `memberCount * 220` becomes 660+
     for a 3-worker team and stretches the visible bus arrow off-screen). */
  .nx-team-review-members {
    grid-template-columns: 1fr !important;
    max-width: 100% !important;
  }
  /* Balance — transaction row. Desktop is a flat 5-col table (date | type |
     desc | amount | balance) plus an .mb-hide header row above. On mobile
     we rewire the same 5 cells into a 2-row receipt:
       row 1:  [date]  [type-pill]                       [amount]
       row 2:  [description spans 2 cols]                [balance]
     so the operator reads "what / how much" first, then the trailing
     balance + description below. No JSX duplication — cells are addressed
     by data-tx-cell attributes set in BalanceTxRow. */
  .nx-bal-tx-row {
    grid-template-columns: auto 1fr auto !important;
    grid-template-areas:
      "date   type    amount"
      "desc   desc    balance" !important;
    gap: 6px 12px !important;
    padding: 12px 16px !important;
    align-items: center !important;
  }
  .nx-bal-tx-row > [data-tx-cell="date"]    { grid-area: date; }
  .nx-bal-tx-row > [data-tx-cell="type"]    { grid-area: type; justify-self: start; }
  .nx-bal-tx-row > [data-tx-cell="desc"]    { grid-area: desc; font-size: 12px; color: var(--fg-soft) !important; }
  .nx-bal-tx-row > [data-tx-cell="amount"]  { grid-area: amount; }
  .nx-bal-tx-row > [data-tx-cell="balance"] { grid-area: balance; font-size: 10.5px; }
  /* Detail (worker page) — team orchestration SVG diagram. Desktop fixes
     minWidth: 700 + overflowX: auto on the parent, so on a 480px viewport
     the user has to swipe to see the hub. Drop the floor on mobile and
     let SVG re-scale naturally (it has explicit viewBox, so geometry stays
     proportional, just visually smaller). */
  .nx-team-svg {
    min-width: 0 !important;
  }
  /* Detail (team page) — TeamCostBreakdown row. Desktop is "label | bar
     200px | price 80px", which pushes past 360px viewport on mobile.
     Collapse to "label | price" and hide the decorative bar — numeric
     price is the actionable data. */
  .nx-cost-breakdown-row {
    grid-template-columns: 1fr auto !important;
    gap: 10px !important;
  }
  .nx-cost-breakdown-row > *:nth-child(2) {
    display: none !important;
  }
  /* Worker card actions row. Corner icons (Edit + Delete) live INLINE in
     this row now (anchored right via margin-left:auto in JSX), not pinned
     absolutely to the corner — so the row is a single naturally-wrapping
     flex strip and there's no right-padding reservation to keep in sync.
     Mobile-only refinements:
       - tighter horizontal padding + gap,
       - chip padding/tracking shrunk so the primary chips fit on phones,
       - secondary meta chips (v{N} / published / from-marketplace) hidden
         since Edit listing + Unpublish already signal published state. */
  .nx-fleet-card-actions {
    padding-left: 14px !important;
    padding-right: 14px !important;
    padding-top: 12px !important;
    gap: 5px !important;
    row-gap: 6px !important;
  }
  .nx-fleet-card-actions > button {
    padding-left: 6px !important;
    padding-right: 6px !important;
    margin-left: 0 !important;
    letter-spacing: 0.1em !important;
  }
  .nx-fleet-card-actions > span {
    margin-left: 0 !important;
  }
  .nx-fleet-card-actions .nx-fleet-meta-chip {
    display: none !important;
  }
  /* TopBar mobile layout: collapse the 32px desktop gap and right-anchor
     the theme+avatar cluster so [hamburger][logo] hug the left while
     [theme][avatar] hug the right. Also normalize the hamburger button
     to a 32×32 square so it matches the 32px avatar circle visually. */
  .nx-topbar-row { gap: 10px !important; }
  .nx-topbar-row .nx-topbar-spacer { display: none !important; }
  .nx-topbar-row .nx-topbar-right { margin-left: auto !important; }
  .nx-topbar-row .nx-topbar-burger {
    width: 32px !important; height: 32px !important;
    padding: 0 !important; display: inline-flex !important;
    align-items: center !important; justify-content: center !important;
    margin-right: 0 !important;
  }
  .mb-flex { display: flex !important; }
  .nx-office-panel {
    height: auto !important;
    min-height: calc(100svh - 75px) !important;
    padding: 14px !important;
    overflow: auto !important;
  }
  .nx-office-header {
    align-items: flex-start !important;
    margin-bottom: 12px !important;
  }
  .nx-office-intro h1 {
    font-size: 26px !important;
  }
  .nx-office-intro p {
    font-size: 12px !important;
    line-height: 1.45 !important;
  }
  .nx-office-actions {
    width: 100% !important;
    justify-content: flex-start !important;
    overflow-x: auto !important;
    padding-bottom: 2px !important;
  }
  .nx-office-stats {
    display: none !important;
  }
  .nx-office-floor {
    flex: 0 0 auto !important;
    min-height: 520px !important;
    height: 520px !important;
    overflow: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  .nx-office-floor svg {
    width: 980px !important;
    min-width: 980px !important;
    height: 520px !important;
  }
  .nx-office-mobile-list {
    display: none !important;
  }
  .mb-stack { grid-template-columns: 1fr !important; gap: 16px !important; }
  .mb-col-stack { flex-direction: column !important; height: auto !important; }
  .mb-fullw { width: 100% !important; flex: 1 0 auto !important; }
  .mb-no-side-border { border-right: none !important; border-left: none !important; border-bottom: 1px solid var(--border) !important; }
  /* Two-pane mobile: only one of list/chat is visible at a time. */
  .mob-pane-list, .mob-pane-chat { width: 100% !important; flex: 1 !important; min-width: 0 !important; border-right: none !important; }
  .mob-pane-list.mob-hidden, .mob-pane-chat.mob-hidden { display: none !important; }
  .mb-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .mb-table-scroll > * { min-width: 720px; }
  /* Cap для sidebar'ов которые на мобиле стекаются над main контентом
     (Tables / Notes list). Иначе list забирает весь viewport и main не виден. */
  .mb-aside-cap {
    max-height: 45vh !important;
    flex: 0 0 auto !important;
    width: 100% !important;
  }
  /* Auto-высота для shell'ов которые на десктопе калиброваны как
     100vh - 75px, но на мобиле после mb-col-stack дают 2x viewport. */
  .mb-shell-auto-h {
    height: auto !important;
    min-height: calc(100vh - 75px) !important;
  }
  .mb-sidebar { display: none !important; }
  .mb-sidebar.open {
    display: flex !important;
    position: fixed; top: 0; left: 0; bottom: 0;
    width: min(86vw, 320px) !important;
    z-index: 50;
    animation: drawer-slide-in-left 200ms ease-out;
    box-shadow: 4px 0 24px rgba(0,0,0,0.3);
  }
  .mb-backdrop {
    display: block;
    position: fixed; inset: 0; z-index: 49;
    background: rgba(0,0,0,0.45);
    animation: drawer-fade-in 200ms ease-out;
  }
  /* ── Mobile UX pass: extra utilities (Phase 6 of plan) ──
     New names so we don't change the meaning of existing classes. */

  /* Generic N-col grid collapsers.
     mb-stack collapses to 1fr unconditionally; -3/-4/-6 are softer:
     N-col → 2-col on tablets and 1-col on phones. Use them on grids
     where collapsing fully to one column wastes too much horizontal
     space at 600-768px. */
  .mb-stack-3 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 12px !important; }
  .mb-stack-4 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 12px !important; }
  .mb-stack-6 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: 10px !important; }

  /* Era / money-flow arrows turn from horizontal → vertical so the
     sequence still reads top-to-bottom on stacked layouts. Apply on
     the arrow glyph itself, not its parent grid. display: inline-block
     so rotate works on naturally-inline <span> arrows; align: center
     so the arrow sits in the middle of the stacked flow. */
  .mb-arrow-rotate {
    transform: rotate(90deg) !important;
    display: inline-block !important;
    text-align: center !important;
  }

  /* Settings-style form rows: "label  |  control" → label on top, control below. */
  .mb-form-row-stack { grid-template-columns: 1fr !important; gap: 6px !important; }

  /* ── Settings shell mobile polish ────────────────────────────────
     Targets the entire Settings surface ([data-screen-label="04 Settings"]
     wrapping <SettingsView>). Inline styles on settingsStyles.page / .h1 /
     .sectionHeader can't be tweaked per-viewport in JSX without plumbing
     className everywhere, so we override here with !important. */
  /* Lock the outer settings surface to viewport width so no inner element
     can push horizontal scroll. Inline `flex: 1; minWidth: 0` on the main
     column already allows shrinking, but some catalog rows with long URLs
     occasionally measure wider — clip them at the shell. */
  [data-screen-label="04 Settings"] {
    max-width: 100vw !important;
    overflow-x: hidden !important;
  }
  /* The main flex:1 column has inline `overflowY: auto`. Per CSS spec,
     when one axis is non-visible, the other auto-promotes from visible
     to auto — so the column ends up scrollable horizontally too. Force
     overflow-x: hidden so only vertical scroll remains. */
  [data-screen-label="04 Settings"] > div:not(.mb-sidebar) {
    overflow-x: hidden !important;
    max-width: 100% !important;
    min-width: 0 !important;
  }
  [data-screen-label="04 Settings"] header > h1 {
    font-size: 24px !important;
    letter-spacing: 0 !important;
  }
  /* Catch settingsStyles.sectionHeader (display:flex; justifyContent:
     space-between; border-bottom). On mobile allow wrap so [title] +
     [Catalog/Custom toggle / +Add key / etc] stack instead of forcing the
     right cluster off-screen. */
  [data-screen-label="04 Settings"] div[style*="justify-content: space-between"][style*="border-bottom"] {
    flex-wrap: wrap !important;
    row-gap: 8px !important;
  }
  /* External / Proxy keys catalog expanded row — desktop pads 52px on the
     left to align the inline form under the 28px icon + 10px gap. On
     mobile that wastes ~14% of a 360px viewport; align flush with the row. */
  [data-screen-label="04 Settings"] div[style*="padding: 12px 14px 14px 52px"] {
    padding: 12px 14px 14px 16px !important;
  }
  /* Outer page container — drop the 32px/48px vertical padding so section
     headers sit closer to the breadcrumb. Horizontal padding already
     handled by .mb-pad (16/16). */
  [data-screen-label="04 Settings"] .mb-pad {
    padding-top: 18px !important;
    padding-bottom: 28px !important;
  }
  /* External / Proxy / Residential / Browser keys catalog list:
     overflowY:auto + maxHeight:520 puts a vertical scrollbar over the
     right edge — chevron and url ellipsis end up clipped. Reserve the
     gutter and bump row padding so content breathes. */
  [data-screen-label="04 Settings"] div[style*="max-height: 520"][style*="overflow-y: auto"] {
    scrollbar-gutter: stable !important;
  }
  [data-screen-label="04 Settings"] div[style*="max-height: 520"][style*="overflow-y: auto"] button {
    padding-right: 18px !important;
  }

  /* Tighter button padding for cramped clusters in TopBar. */
  .mb-tight { padding: 5px 8px !important; font-size: 11px !important; }

  /* Marketplace LiveFilterBar collapse. Default mobile state hides the
     chip row entirely — the mb-only "Filters · N ▾" toggle in the JSX
     reveals it via .nx-fbar-row-expanded. Chips themselves get tighter
     padding + smaller font when expanded so 6 dropdowns fit on ~2 rows
     instead of 4. */
  .nx-fbar-row { display: none !important; }
  .nx-fbar-row-expanded { display: flex !important; margin-top: 10px; gap: 6px !important; }
  .nx-fbar-row-expanded > button { padding: 5px 9px !important; font-size: 11px !important; }
  .nx-fbar-row-expanded > button > span:last-child { font-size: 8px !important; }

  /* Touch-target floor — every interactive element gets at least 36×36
     on mobile (iOS HIG suggests 44, but many of our action pills are
     deliberately compact; 36 is a safe minimum that doesn't break
     existing UI). Add :where() so specificity stays low — inline
     styles still win. Opt out with .mb-no-min on the element. */
  button:not(.mb-no-min):not([disabled]),
  a[role="button"]:not(.mb-no-min),
  [role="button"]:not(.mb-no-min) {
    min-height: 36px;
  }

  .nx-home-title {
    font-size: clamp(28px, 7.6vw, 34px) !important;
    line-height: 1.08 !important;
    max-width: min(360px, calc(100vw - 32px)) !important;
    margin: 0 auto 14px !important;
    letter-spacing: -0.005em !important;
    text-align: center !important;
    text-wrap: balance;
  }
  /* Override the desktop inline clamp() on the two H1 lines so the title
     fits the viewport. Defeat whiteSpace: nowrap as well — at phone width
     "for personal & business tasks" exceeds even max-content, so we let
     it wrap naturally as a soft 2-line subtitle below the headline. */
  .nx-home-title > span:nth-of-type(1) {
    font-size: clamp(30px, 9vw, 44px) !important;
    white-space: normal !important;
    display: block !important;
  }
  .nx-home-title > span:nth-of-type(2) {
    font-size: clamp(17px, 5.4vw, 24px) !important;
    white-space: normal !important;
    display: block !important;
    margin-top: 6px !important;
    color: var(--fg-strong) !important;
  }
  /* Legacy hooks for the older <br>+tail markup — kept harmless. */
  .nx-home-title .nx-title-br { display: none !important; }
  .nx-title-tail { display: block !important; }
  /* Mobile: drop the desktop one-screen lock — hero content (title +
     mobile copy + flow + CTA + 8-row stack strip) totals ~700px, which
     exceeded `100svh - 77px` on iPhone SE / short-viewport phones and
     was clipped under `overflow: hidden`. On mobile let the shell scroll
     naturally; sticky TopBar keeps the chrome on top. */
  .nx-vision-shell {
    height: auto !important;
    min-height: 100svh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  [data-screen-label="00 Vision"] {
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
  }
  .nx-home-hero {
    height: auto !important;
    min-height: 0 !important;
    padding-top: 18px !important;
    padding-bottom: 28px !important;
    align-items: flex-start !important;
    overflow: visible !important;
  }
  .nx-home-copy {
    display: block !important;
    width: 100% !important;
    max-width: min(360px, calc(100vw - 32px)) !important;
    margin: 0 auto !important;
    text-align: center !important;
  }
  .nx-home-eyebrow {
    justify-content: center !important;
    margin-bottom: 12px !important;
  }
  .nx-home-lede,
  .nx-home-detail {
    display: none !important;
  }
  .nx-mobile-copy {
    display: block !important;
    max-width: min(360px, calc(100vw - 32px)) !important;
    margin: 0 auto 16px !important;
  }
  .nx-mobile-copy p {
    margin: 0 !important;
    color: var(--fg-strong) !important;
    font-size: 13.5px !important;
    line-height: 1.5 !important;
    font-weight: 300 !important;
    text-align: center !important;
  }
  .nx-mobile-flow {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: 8px !important;
    width: 100% !important;
    max-width: min(360px, calc(100vw - 32px)) !important;
    margin: 0 auto 14px !important;
  }
  .nx-mobile-flow span {
    display: grid !important;
    align-content: center !important;
    justify-items: center !important;
    min-height: 68px !important;
    border: 1px solid var(--border) !important;
    background: rgba(0, 255, 136, 0.025) !important;
    padding: 10px 6px !important;
    color: var(--fg-strong) !important;
    font-size: 12px !important;
    line-height: 1.25 !important;
    font-weight: 350 !important;
    letter-spacing: -0.005em !important;
    text-align: center !important;
  }
  .nx-mobile-flow strong {
    display: block !important;
    margin-bottom: 7px !important;
    color: #00FF88 !important;
    font-family: "JetBrains Mono", ui-monospace, Menlo, monospace !important;
    font-size: 11px !important;
    font-weight: 500 !important;
    letter-spacing: 0.08em !important;
  }
  .nx-home-cta-row {
    display: grid !important;
    grid-template-columns: 1fr !important;
    gap: 8px !important;
    max-width: min(360px, calc(100vw - 32px)) !important;
    margin: 0 auto !important;
  }
  .nx-home-button {
    width: 100% !important;
    justify-content: center !important;
    min-height: 44px !important;
    padding: 12px 14px !important;
    font-size: 12.5px !important;
  }
  .nx-home-section {
    padding-top: 58px !important;
    padding-bottom: 32px !important;
  }
  .nx-future-hero {
    padding-top: 24px !important;
    padding-bottom: 14px !important;
  }
  .nx-future-title {
    font-size: clamp(31px, 9.1vw, 38px) !important;
    line-height: 1.02 !important;
    max-width: 330px !important;
  }
  .nx-future-console {
    min-height: 0 !important;
  }
  .nx-future-section {
    padding-top: 58px !important;
    padding-bottom: 34px !important;
  }
  .nx-step-card {
    min-height: 0 !important;
    padding: 18px !important;
  }
  .nx-step-card-head {
    margin-bottom: 14px !important;
  }
  /* Two-pane layouts that hardcode "320px 1fr" — collapse to single column. */
  .mb-twopane { grid-template-columns: 1fr !important; }

  /* ── Mobile master/detail (.nx-md-master / .nx-md-detail) ──────
     Used together with `useIsMobile()` + URL state to swap between a
     full-width list (master) and a full-width detail panel on phones.
     Add .is-hidden-mobile to whichever pane should not be visible.
     Desktop ≥769px ignores these classes — the parent two-pane grid
     keeps both columns side-by-side. */
  .nx-md-master, .nx-md-detail {
    width: 100% !important;
    min-width: 0 !important;
    grid-column: 1 / -1 !important;
  }
  .nx-md-master.is-hidden-mobile,
  .nx-md-detail.is-hidden-mobile,
  .is-hidden-mobile {
    display: none !important;
  }
  /* Sticky back-bar above mobile detail (overrides .mb-only's default
     inline-flex to flex so the title can ellipsis-truncate). */
  .nx-md-back { display: flex !important; }

  /* Drawer panel becomes full-screen on phones — it's the only thing on the
     surface and the floating "✕ close" already serves as a back affordance. */
  .nx-drawer-panel {
    width: 100vw !important;
    border-left: none !important;
    box-shadow: none !important;
  }
  /* Auto-fill card grids that hardcode minmax(>=320px) — drop the minmax floor
     so cards never push horizontal scroll on narrow viewports. */
  .mb-cards-auto { grid-template-columns: minmax(0, 1fr) !important; }
  /* Compact composer / chat-surface padding override. */
  .mb-pad-compact { padding-left: 14px !important; padding-right: 14px !important; }
  /* Composer base + responsive padding. Base lives outside @media so desktop
     keeps the original 16/28 padding via inline style; mobile shrinks. */
  .nx-composer { padding: 14px 16px !important; }

  /* Stack strip on mobile — collapse the 4-col desktop bento to a single
     column. Cells use inline `gridColumn: span N` (anchor=2, chip=1) which
     would otherwise leave anchors trying to span phantom columns; force
     every cell to full row so the list reads top-to-bottom. */
  .nx-home-stack {
    display: block !important;
    max-width: min(360px, calc(100vw - 32px)) !important;
    margin: 14px auto 0 !important;
    padding-top: 14px !important;
  }
  .nx-home-stack-grid {
    grid-template-columns: 1fr !important;
    grid-auto-rows: auto !important;
    gap: 8px !important;
  }
  .nx-home-stack-grid > div {
    grid-column: 1 / -1 !important;
    min-height: 56px !important;
    padding: 12px 14px !important;
    gap: 4px !important;
  }
  /* Anchors keep their green sheen via the inline gradient — no need to
     change background here. Inner name + role/metric row stay as-is. */

  /* ── Worker card compact mode (≤768px) ─────────────────────────────
     Desktop card carries minHeight:480 + padding "12px 18px" per row for
     grid density. On phones (1-col grid) that leaves huge empty space
     under the BRAIN line for a never-run worker. Shrink:
       - drop the 480px floor so the card stretches to actual content;
       - tighten horizontal padding 18 → 12 on every direct child row;
       - tighter footer padding so the Chat/Run row sits flush. */
  .nx-worker-card {
    min-height: 0 !important;
  }
  .nx-worker-card > div {
    padding-left: 12px !important;
    padding-right: 12px !important;
  }
  /* Last row (footer with Chat / Run) gets a tighter vertical padding too —
     desktop uses 12px which feels loose under the now-collapsed card. */
  .nx-worker-card > div:last-child {
    padding-top: 9px !important;
    padding-bottom: 9px !important;
  }

  /* ── LiveChatPanel header on mobile ────────────────────────────────
     The header packs avatar + name + model-picker + Stop + Test/Live +
     Run on one wrapping flex row. On a narrow viewport that produces a
     cramped mess (10.5px caps text squeezed between 5+ chips). Mobile
     overrides:
       - shrink horizontal padding so the row gets ~10px more breathing
         room left and right;
       - keep `flex-wrap: wrap` (already inline) but force each chip to
         a 36px touch-floor with bumped font/padding so taps land cleanly;
       - smaller avatar (40 → 32) and tighter gap so first row stays
         on a single line: [back] [CR] [name + model] [Stop] [Run];
       - Test/Live toggle gets `mb-hide` in JSX so it's gone here. */
  .nx-chat-header {
    padding: 10px 14px !important;
    gap: 8px !important;
  }
  /* Avatar — shrink so the row doesn't wrap on iPhone SE. Target by class,
     NOT `> div:nth-of-type(1)`: for custom workers the avatar is a <button>,
     so the nth-of-type(1) div was actually the title block, which got crushed
     to 32px and forced its ⚙ Settings chip to spill over the Call button. */
  .nx-chat-header .nx-chat-avatar {
    width: 32px !important;
    height: 32px !important;
    min-height: 0 !important;
    padding: 0 !important;
    font-size: 11px !important;
  }
  .nx-chat-header > button,
  .nx-chat-header > a {
    min-height: 36px !important;
    padding: 8px 12px !important;
    font-size: 11px !important;
    letter-spacing: 0.12em !important;
  }
  /* The back-arrow chip keeps its glyph-height instead of getting
     fattened by the generic button rule above. */
  .nx-chat-header > button.mb-only {
    min-height: 32px !important;
    width: 32px !important;
    padding: 4px 8px !important;
    font-size: 16px !important;
  }
  /* Action chips (+ Telegram, ■ Stop, ▶ Start, ▶ Run, Telegram-connected
     pill). The generic `> button` rule above bumps them to 36px tall to
     hit a comfortable touch target — but that fattens the whole row and
     forces it to wrap on tablet-narrow widths, leaving the LLM picker
     visually colliding with the wrapped buttons. Bring action chips back
     to compact sizing (still 30px min-height = WCAG-friendly) so the
     strip stays single-row on most mobile viewports. */
  .nx-chat-header .nx-chat-act {
    min-height: 30px !important;
    padding: 5px 10px !important;
    font-size: 10px !important;
    letter-spacing: 0.08em !important;
  }
  /* In mobile full-screen chat the chat-header keeps its full toolbar
     (avatar, name, ⚙ Settings, ▶ Run, ■ Stop) — only the global TopBar
     gets hidden (see the body.nx-chat-fullscreen .nx-topbar-root rule
     outside this media query). Compact ergonomics for the toolbar live
     in the .nx-chat-header block above. */
  /* Composer in mobile chat — extra-compact so the keyboard + the
     "Message …" input + the action row fit without scrolling on small
     screens. Reduces padding, removes the inter-element gap, and caps
     the textarea auto-grow at ~3 lines so a long draft doesn't push
     the send row off-screen. */
  body.nx-chat-fullscreen .nx-composer {
    padding: 8px 10px !important;
    gap: 0 !important;
  }
  /* Mobile chat: collapse composer into a single inline row — textarea on
     the left, mic + Send pinned right. LIVE chip, char counter and 📎 are
     hidden so the row stays uncluttered and the messages pane gets the
     freed vertical space. */
  body.nx-chat-fullscreen .nx-composer-input {
    display: flex !important;
    flex-direction: row !important;
    align-items: flex-end !important;
    gap: 8px !important;
    width: 100% !important;
  }
  body.nx-chat-fullscreen .nx-composer textarea {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    max-height: 96px !important;
    min-height: 36px !important;
    /* 16px floor: iOS Safari auto-zooms the page when a focused field's
       font-size is < 16px. Anything smaller here re-triggers the zoom on tap. */
    font-size: 16px !important;
    padding: 8px 10px !important;
    background: var(--bg-soft) !important;
    border: 1px solid var(--border-soft) !important;
    border-radius: var(--radius-md) !important;
    line-height: 1.4 !important;
  }
  body.nx-chat-fullscreen .nx-composer .nx-composer-row {
    flex: 0 0 auto !important;
    gap: 6px !important;
    justify-content: flex-end !important;
    align-items: center !important;
    margin-top: 0 !important;
  }
  body.nx-chat-fullscreen .nx-composer-chip-mode,
  body.nx-chat-fullscreen .nx-composer-charcount,
  body.nx-chat-fullscreen .nx-composer-attach,
  body.nx-chat-fullscreen .nx-composer .nx-composer-row .mb-hide {
    display: none !important;
  }
  /* Tighten Send button on mobile so it doesn't push the textarea too far.
     Height matches the mic chip (38px inline) so the composer action row is a
     single even-height line on mobile, mirroring desktop. */
  body.nx-chat-fullscreen .nx-composer .nx-composer-row > button:last-child {
    padding: 0 14px !important;
    height: 38px !important;
    font-size: 11px !important;
    letter-spacing: 0.1em !important;
  }
}

/* Fullscreen worker chat (LiveChatExperience.mobView === "chat"): kill the
   global TopBar at every width so the screen is just the conversation + the
   ‹ back chip. Body class is set only while mobView === "chat" in
   workspace.jsx, so desktop layouts are unaffected in practice. */
body.nx-chat-fullscreen .nx-topbar-root { display: none !important; }
/* WorkspaceView root locks `height: calc(100vh - 75px)` to reserve space for
   the global TopBar. In mobile fullscreen-chat the TopBar is hidden — but the
   subtracted 75 px stayed, leaving a dead strip below the composer. Reclaim
   the full viewport so the chat history + composer stretch to the bottom.

   Pinned to the *visual* viewport, not the layout viewport: on iOS the soft
   keyboard and the collapsing URL-bar don't resize 100vh/svh. The fix has
   three parts, all driven from window.visualViewport in LiveChatExperience:
     1. Lock the body (position:fixed + inset:0) so the *page* can't scroll.
     2. Size the chat shell to the live visualViewport HEIGHT (--nx-chat-vh)
        so when the keyboard slides up the shell shrinks and the composer (the
        bottom flex child) rides just above it instead of being covered.
     3. Compensate for the visualViewport OFFSET (--nx-chat-top) with a GPU
        transform. When iOS pans the visual viewport up to reveal the focused
        input, the fixed shell would otherwise stay glued to the layout-top
        and the composer would "slide to the top" of the screen. Translating
        the shell down by offsetTop re-glues it to the visible region. Using
        transform (not top) keeps it on the compositor — no layout jitter.
   Falls back to 100svh / 0 offset before the first measurement. */
body.nx-chat-fullscreen {
  position: fixed !important;
  inset: 0 !important;
  overflow: hidden !important;
}
body.nx-chat-fullscreen [data-screen-label="03 Workspace"] {
  position: fixed !important;
  left: 0 !important;
  right: 0 !important;
  top: 0 !important;
  height: var(--nx-chat-vh, 100svh) !important;
  transform: translateY(var(--nx-chat-top, 0px)) !important;
}

/* ── Master/detail at the wider mobile breakpoint (≤960px) ──────────
   The main mobile utility block above gates on 768px to avoid disturbing
   desktop/tablet typography. The chat-style list→detail toggle should
   apply on a wider band so that iPhone landscape (≤932) and small
   tablets in portrait (810–960) also get a single-pane swap instead of
   stacking the list above the detail. Only the strict master/detail
   rules are duplicated here; everything else (mb-pad, mb-only, drawer,
   …) keeps the 768 cap. JS useIsMobile() also uses 960 so the
   `is-hidden-mobile` class is added at the same threshold. */
@media (max-width: 960px) {
  .mb-twopane { grid-template-columns: 1fr !important; }
  .nx-md-master, .nx-md-detail {
    width: 100% !important;
    min-width: 0 !important;
    grid-column: 1 / -1 !important;
  }
  .nx-md-master.is-hidden-mobile,
  .nx-md-detail.is-hidden-mobile,
  .is-hidden-mobile {
    display: none !important;
  }
  .nx-md-back { display: flex !important; }
}

/* On the narrowest viewports (phones in portrait), tighten the chat
   header further and drop the "+ Telegram" word — the ✈ glyph alone is
   enough to convey the affordance and saves precious horizontal space. */
@media (max-width: 480px) {
  .nx-chat-header {
    padding: 8px 10px !important;
    gap: 6px !important;
  }
  .nx-chat-header .nx-chat-act {
    padding: 4px 8px !important;
    font-size: 9.5px !important;
    letter-spacing: 0.06em !important;
  }
  .nx-chat-header .nx-chat-act .nx-chat-act-label { display: none !important; }
}

@media (min-width: 481px) and (max-width: 768px) {
  .nx-home-title {
    max-width: min(560px, calc(100vw - 56px)) !important;
    margin-bottom: 16px !important;
  }
  /* Tablet bumps the headline + subtitle a notch above the phone scale. */
  .nx-home-title > span:nth-of-type(1) {
    font-size: clamp(38px, 6.8vw, 56px) !important;
  }
  .nx-home-title > span:nth-of-type(2) {
    font-size: clamp(22px, 4.2vw, 32px) !important;
  }
  .nx-home-copy,
  .nx-mobile-copy,
  .nx-mobile-flow,
  .nx-home-cta-row,
  .nx-home-stack {
    max-width: min(560px, calc(100vw - 56px)) !important;
  }
  .nx-mobile-copy {
    margin-bottom: 16px !important;
  }
  .nx-mobile-flow span {
    min-height: 54px !important;
    font-size: 11.5px !important;
  }
  /* Tablet: stay on 1-col like phones. A 2-col tablet bento sounds nice
     but the HOME_STACK order has chips interleaved with anchors (chip,
     chip, chip, anchor, chip, anchor, anchor, …), and CSS grid auto-flow
     leaves orphan half-slots before every span-2 anchor. The 1-col list
     reads cleanly top-to-bottom; cells just get slightly more padding
     for the wider viewport. */
  .nx-home-stack-grid > div {
    min-height: 64px !important;
    padding: 13px 18px !important;
  }
}

@media (max-width: 768px) and (max-height: 620px) {
  .nx-home-hero {
    padding-top: 4px !important;
    padding-bottom: 6px !important;
  }
  .nx-home-eyebrow {
    margin-bottom: 6px !important;
    font-size: 10px !important;
    letter-spacing: 0.14em !important;
  }
  .nx-home-title {
    font-size: clamp(25px, 7.6vw, 31px) !important;
    max-width: 300px !important;
    margin-bottom: 8px !important;
  }
  .nx-mobile-copy {
    max-width: 300px !important;
    margin-bottom: 8px !important;
  }
  .nx-mobile-copy p {
    font-size: 12px !important;
    line-height: 1.38 !important;
  }
  .nx-mobile-copy p:first-child {
    font-size: 13px !important;
    margin-bottom: 5px !important;
  }
  .nx-mobile-flow {
    gap: 6px !important;
    margin-bottom: 8px !important;
  }
  .nx-mobile-flow span {
    min-height: 42px !important;
    padding: 5px !important;
    font-size: 10px !important;
    line-height: 1.16 !important;
  }
  .nx-mobile-flow strong {
    margin-bottom: 3px !important;
    font-size: 9.5px !important;
  }
  .nx-home-cta-row {
    gap: 6px !important;
  }
  .nx-home-button {
    min-height: 36px !important;
    padding: 7px 10px !important;
  }
}

/* ── Marketing home (/) mobile layout ─────────────────────────────── */
@media (max-width: 768px) {
  .nx-mhome-header { padding: 0 16px !important; }
  .nx-mhome-nav { gap: 12px !important; padding: 14px 0 !important; }
  .nx-mhome-theme { margin-left: auto !important; }
  .nx-mhome-mobmenu { padding: 18px 16px 28px !important; }
  .nx-mhome-body { padding: 8px 16px 48px !important; }
  .nx-mhome-section { margin-top: 64px !important; padding-top: 4px !important; }
  .nx-mhome-hero { grid-template-columns: 1fr !important; gap: 24px !important; padding: 36px 0 56px !important; }
  .nx-mhome-hero h1 { font-size: clamp(32px, 9vw, 46px) !important; letter-spacing: -1px !important; line-height: 1.05 !important; }
  .nx-mhome-hero p { font-size: 15px !important; max-width: none !important; line-height: 1.55 !important; }
  .nx-mhome-bento { grid-template-columns: 1fr !important; gap: 12px !important; }
  .nx-mhome-section-head { padding: 4px 0 20px !important; text-align: left !important; margin: 0 !important; }
  .nx-mhome-section-head h2 { font-size: clamp(26px, 7vw, 34px) !important; letter-spacing: -0.6px !important; }
  .nx-mhome-two-col { grid-template-columns: 1fr !important; gap: 12px !important; }
  .nx-mhome-stats { grid-template-columns: 1fr !important; }
  .nx-mhome-cards { grid-template-columns: 1fr !important; }
  .nx-mhome-sync { flex-direction: column !important; align-items: stretch !important; gap: 10px !important; }
  .nx-mhome-process { flex-direction: column !important; align-items: center !important; margin-top: 16px !important; gap: 8px !important; }
  .nx-mhome-step { display: flex !important; flex-direction: row !important; align-items: center !important; justify-content: center !important; gap: 16px !important; padding: 12px 16px !important; width: 100% !important; flex: 0 0 auto !important; text-align: left !important; }
  .nx-mhome-step > span { margin-top: 0 !important; display: inline-flex !important; }
  .nx-mhome-arrow { display: flex !important; justify-content: center !important; transform: rotate(90deg) !important; margin: 2px 0 !important; }
  .nx-mhome-signup-grid { grid-template-columns: 1fr !important; }
  .nx-mhome-signup-grid > div:first-child { padding: 28px 22px !important; }
  .nx-mhome-signup-grid > div:last-child { margin: 10px !important; padding: 28px 22px !important; }
}

/* ── ≤480px overrides — drop one more level on already-mobile layouts ── */
@media (max-width: 480px) {
  .mb-stack-3, .mb-stack-4 { grid-template-columns: 1fr !important; }
  .mb-stack-6 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  /* Body padding on already-padded surfaces — avoid cards bumping the edge. */
  .mb-pad { padding-left: 12px !important; padding-right: 12px !important; }
  .nx-home-title {
    font-size: clamp(27px, 7.4vw, 32px) !important;
    max-width: min(360px, calc(100vw - 32px)) !important;
  }
  .nx-home-section {
    padding-top: 50px !important;
    padding-bottom: 28px !important;
  }
  .nx-future-title {
    font-size: clamp(30px, 8.9vw, 36px) !important;
    max-width: 320px !important;
  }
  .nx-future-section {
    padding-top: 50px !important;
    padding-bottom: 28px !important;
  }
  .nx-home-section h2 {
    font-size: 28px !important;
    line-height: 1.08 !important;
  }
  .nx-future-section h2 {
    font-size: 28px !important;
    line-height: 1.08 !important;
  }
  /* Search/sort row — stack input over sort control on narrow phones. */
  .mb-row-stack { display: grid !important; grid-template-columns: 1fr !important; gap: 8px !important; align-items: stretch !important; }
  .nx-mhome-hero h1 { font-size: clamp(28px, 9.5vw, 38px) !important; }
  .nx-mhome-section-head h2 { font-size: clamp(24px, 7.5vw, 30px) !important; }
  .nx-mhome-signup-grid > div:first-child,
  .nx-mhome-signup-grid > div:last-child { padding: 22px 16px !important; }
}

@media (max-width: 768px) and (max-height: 620px) {
  .nx-home-title {
    font-size: clamp(25px, 7.6vw, 31px) !important;
    max-width: 300px !important;
    margin-bottom: 8px !important;
  }
}

/* ── ≤380px overrides — iPhone SE / older Android phones ────────── */
@media (max-width: 380px) {
  .mb-pad { padding-left: 10px !important; padding-right: 10px !important; }
  .mb-stack-6 { grid-template-columns: 1fr !important; }
  /* Chat header: hide secondary controls (Edit, Clear, mode label) — Run/Stop stay. */
  .mb-chat-secondary { display: none !important; }
  .nx-composer { padding: 12px 12px !important; }
}

/* Layout-specific skeleton bodies (rendered inside React tree, after mount). */
.sk-page { padding: 32px 40px; max-width: 1600px; margin: 0 auto; }
.sk-h1 { width: 280px; max-width: 60vw; height: 28px; margin: 8px 0 12px; }
.sk-eyebrow { width: 140px; height: 11px; margin-bottom: 8px; }
.sk-lede { width: 460px; max-width: 80vw; height: 14px; margin-bottom: 28px; }
.sk-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.sk-card { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 18px; min-height: 168px; display: flex; flex-direction: column; gap: 12px; }
.sk-card-row { height: 14px; }
.sk-card-row.sm { width: 60%; height: 11px; }
.sk-card-row.lg { width: 90%; }

/* Dimensions match the real SettingsView/WorkspaceView shell so the swap
   from RouteSkeleton → real route doesn't shift the layout (used to flash
   ~11 px of vertical jump + sidebar padding change on every cold load). */
.sk-with-sidebar { display: flex; height: calc(100vh - 75px); overflow: hidden; }
.sk-sidebar { width: 260px; border-right: 1px solid var(--border); padding: 20px 0; display: flex; flex-direction: column; gap: 6px; flex-shrink: 0; background: var(--bg-soft); }
.sk-sidebar-row { height: 24px; margin: 0 14px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); }
.sk-sidebar-head { height: 18px; width: 60%; margin: 0 16px 16px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); }
.sk-content { flex: 1; padding: 32px 40px 48px; max-width: 1280px; }
@media (max-width: 768px) {
  .sk-sidebar { display: none; }
  .sk-content { padding: 24px 16px 40px !important; }
}
@media (max-width: 480px) {
  .sk-content { padding: 20px 12px 36px !important; }
}

.sk-split { display: grid; grid-template-columns: 380px 1fr; gap: 18px; padding: 32px 40px; }
.sk-split-pane { border: 1px solid var(--border); border-radius: var(--radius-md); min-height: 320px; padding: 18px; display: flex; flex-direction: column; gap: 10px; }

/* Loading spinner — used wherever a panel is awaiting first data */
@keyframes nx-spin { to { transform: rotate(360deg); } }
.nx-spinner {
  width: 22px;
  height: 22px;
  border: 2px solid var(--border-mid, #2a2a3a);
  border-top-color: var(--fg, #fff);
  border-radius: 50%;
  animation: nx-spin 0.7s linear infinite;
  flex-shrink: 0;
}
.nx-spinner-inline {
  width: 12px;
  height: 12px;
  border: 1.5px solid var(--border-mid, #2a2a3a);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: nx-spin 0.7s linear infinite;
  display: inline-block;
  vertical-align: -2px;
}
.nx-loading-pane {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
  color: var(--fg-muted, #888);
  gap: 10px;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-family: inherit;
}
.nx-loading-pane.compact { min-height: 96px; }
@media (prefers-reduced-motion: reduce) {
  .nx-spinner, .nx-spinner-inline { animation: none; }
}
/* Chat-bubble markdown render. Inherits color/size from parent bubble. */
.nx-md p { margin: 0 0 8px; line-height: 1.65; }
.nx-md p:last-child { margin-bottom: 0; }
.nx-md h3, .nx-md h4, .nx-md h5, .nx-md h6 {
  margin: 12px 0 6px; font-weight: 600; line-height: 1.3; letter-spacing: -0.005em;
}
.nx-md h3 { font-size: 1.15em; }
.nx-md h4 { font-size: 1.08em; }
.nx-md h5, .nx-md h6 { font-size: 0.95em; opacity: 0.9; }
.nx-md h3:first-child, .nx-md h4:first-child, .nx-md h5:first-child, .nx-md h6:first-child { margin-top: 0; }
.nx-md ul, .nx-md ol {
  margin: 4px 0 8px;
  padding-left: 1.55em;
  list-style-position: outside;
  overflow-wrap: anywhere;
}
.nx-md ol { padding-left: 1.85em; }
.nx-md ul ul, .nx-md ul ol, .nx-md ol ul, .nx-md ol ol {
  margin-top: 3px;
  margin-bottom: 3px;
}
.nx-md li { margin-bottom: 3px; line-height: 1.6; padding-left: 0.2em; overflow-wrap: anywhere; }
.nx-md li:last-child { margin-bottom: 0; }
.nx-md strong { font-weight: 600; }
.nx-md em { font-style: italic; }
.nx-md code {
  font-family: "JetBrains Mono", ui-monospace, Menlo, monospace;
  font-size: 0.88em; padding: 1px 5px; border-radius: var(--radius-sm);
  background: rgba(127,127,127,0.18);
}
.nx-md a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.nx-md a:hover { opacity: 0.85; }
.nx-md hr { margin: 12px 0; border: 0; border-top: 1px solid var(--border-soft); }
.nx-md blockquote {
  margin: 8px 0; padding: 4px 12px;
  border-left: 3px solid var(--border-mid);
  color: var(--fg-muted); font-style: italic;
}
.nx-md blockquote p { margin: 0; }
/* Tables wider than the bubble must not stretch the bubble (which would
   defeat the chat panel's flex:1 + overflow-y on the message list and
   kill vertical scrolling). The wrapper trick: render the <table> as
   block, cap it at 100% of its container, and scroll horizontally
   when needed. The .nx-md container itself is min-width: 0 so flex
   ancestors can shrink it. */
.nx-md { min-width: 0; max-width: 100%; }
.nx-md table {
  border-collapse: collapse; margin: 8px 0; font-size: 0.92em;
  display: block; max-width: 100%; width: max-content;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.nx-md th, .nx-md td {
  border: 1px solid var(--border-soft);
  padding: 5px 9px; text-align: left; vertical-align: top;
  white-space: nowrap;
}
.nx-md th { background: rgba(127,127,127,0.08); font-weight: 600; }
.nx-md tr:nth-child(even) td { background: rgba(127,127,127,0.04); }

/* ── /create page adaptive fixes (2026-06-16) ───────────────────────
   The .nx-create-* classNames are emitted by infra/static/spa/create.jsx
   (PromptForm + CreateView + ConnectorsAutoflowModal). Inline style objects on
   those elements still drive desktop sizing; these rules only override below
   the listed breakpoints to keep /create single-viewport on phones (iPhone SE
   320px, Galaxy S8 360px, modern phones 380-430px).

   Why CSS-only: create.jsx has 0 matchMedia/useMediaQuery usage, and shipping a
   JS-side breakpoint hook here would force every other React render to round-
   trip a state value. CSS handles the 5 known pain points cleanly:
     1. h1 34px → fluid clamp so "Automate a process / or create a digital
        employee?" stops becoming 5 lines on 320px
     2. idleShell 24px padding eats 17% of 280px viewports
     3. idleCenter maxWidth 640 needs to drop on phones
     4. builder picker dropdown (position: absolute, left: 0) overflows
        the centered composer on phones
     5. ConnectorsAutoflowModal has maxWidth 560 with no fluid width, the
        draft-restored toast pins to top:78 right:20 and overlaps TopBar */

.nx-create-h1 {
  font-size: clamp(22px, 8vw, 34px) !important;
  line-height: 1.12 !important;
  word-wrap: break-word;
  overflow-wrap: anywhere;
  hyphens: auto;
}

/* Replace the JSX inline `height: calc(100vh - 75px) + overflowY: auto` with
   `min-height + overflow: visible` so the body scrolls normally. Inline
   `overflowY: auto` was clipping the example pills on tall desktop viewports
   (~970px) — the inner scrollbar is invisible (macOS overlay scrollbar) so
   users saw the content as "cut off" without realising they could scroll.
   The `min-height` keeps the empty-screen vertical centering working when
   the composer is shorter than the viewport. */
.nx-create-idle-shell {
  height: auto !important;
  min-height: calc(100vh - 75px) !important;
  overflow: visible !important;
  overflow-y: visible !important;
}
/* Same fix, but for the two-pane build/review shell (clarify / building /
   ready / testing). The inline `createStyles.shell` is `height: calc(100vh
   - 75px) + overflow: hidden` with each pane `overflowY: auto`, so the LEFT
   WORKER SETUP column (now 8 cards: …Real world, Browser & Proxy) clips its
   bottom card on shorter desktop viewports. The macOS overlay scrollbar is
   invisible at rest, so that clipped card reads as a stray "strip" at the
   bottom rather than scrollable content. Let the body scroll instead and
   stop the panes from clipping — the shell stretches both columns to its
   (content-driven) height, so the left sidebar background/border still fill
   the full column. */
.nx-create-shell {
  height: auto !important;
  min-height: calc(100vh - 75px) !important;
  overflow: visible !important;
  overflow-y: visible !important;
}
.nx-create-shell > div {
  overflow: visible !important;
}
/* Push the example pills DOWN on tall screens (more separation from the
   composer), but COLLAPSE the gap on short ones so the whole composer +
   examples still fit in one viewport without scrolling. The gap grows with
   viewport height up to a 200px cap, then floors at 16px. 800px is the
   no-scroll threshold for the TALLEST mode — Team: nav (70) + shell padding
   (48) + composer (~447) + examples block (~185, 16 pills) + the "or start
   from an example" header (~30) ≈ 780, plus safety. Worker/Employee blocks
   are shorter, so they get even more headroom. The header is hidden ≤760px
   and the textarea is tightened ≤820px so everything still fits a small
   laptop in one viewport (see max-height ladder below). */
.nx-create-idle-center .nx-create-examples { margin-top: clamp(16px, calc(100vh - 800px), 200px) !important; }

@media (max-width: 768px) {
  .nx-create-idle-shell { padding: 16px !important; }
  .nx-create-idle-center { max-width: 100% !important; }
  .nx-create-textarea-centered { min-height: 132px !important; padding: 14px !important; }
  /* "or start from an example" — 96px top margin is fine on desktop, but on
     a single-viewport phone it disconnects the pills from the textarea. */
  .nx-create-idle-center .nx-create-examples { margin-top: 28px !important; }
  /* Auto-build row: let the description wrap so it doesn't push the toggle
     off the edge of a centered composer. */
  .nx-create-auto-row { flex-wrap: wrap !important; justify-content: center !important; }
  .nx-create-auto-row > span { max-width: 100% !important; }
  /* Mode toggle: tighten on phones, allow wrap if the 3 buttons don't fit. */
  .nx-create-mode-toggle { flex-wrap: wrap !important; }
  .nx-create-mode-toggle > button { padding: 8px 10px !important; }
  /* Builder picker dropdown: anchor to right edge so the 460px menu doesn't
     overflow the centered column. */
  .nx-create-builder-picker-menu { left: auto !important; right: 0 !important; }
  /* ConnectorsAutoflowModal: cap width to viewport-24 on phones. */
  .nx-create-modal-card { width: calc(100vw - 24px) !important; max-width: 560px !important; padding: 20px 18px !important; }
  /* Draft-restored toast: span the row instead of pinning to the corner. */
  .nx-create-toast { right: 12px !important; left: 12px !important; max-width: calc(100vw - 24px) !important; text-align: center !important; }
}

@media (max-width: 480px) {
  .nx-create-idle-shell { padding: 12px !important; }
  .nx-create-textarea-centered { min-height: 108px !important; font-size: 15px !important; padding: 12px !important; }
  .nx-create-h1 { font-size: clamp(20px, 7vw, 26px) !important; }
  .nx-create-idle-center .nx-create-examples { margin-top: 18px !important; }
}

@media (max-width: 380px) {
  .nx-create-textarea-centered { min-height: 92px !important; }
  .nx-create-h1 { font-size: 20px !important; }
  .nx-create-mode-toggle > button { padding: 7px 8px !important; font-size: 10px !important; }
}

/* ── Short-viewport (landscape phones, split-screen, browser-chrome laptops).
   Width-based rules above keep /create readable on tall phones; this branch
   keeps it single-viewport on short panels. Targets the same .nx-create-*
   classNames, plus .nx-create-recent-list (added 2026-06-16) so the RecentList
   underneath the composer can be hidden without removing it from the
   desktop flow. Combined tall+short at ≤380×420 collapses everything to a
   minimal form (header + textarea + CTA). */

/* ~760–820px tall: room for the examples header gets tight once the pills
   wrap to several rows (Team/Employee). Gently shorten the textarea so the
   header + pills still fit without scrolling — much less aggressive than the
   ≤760 block below, which kicks in for genuinely short panels. */
@media (max-height: 820px) {
  .nx-create-textarea-centered { min-height: 150px !important; }
}

/* ~660–760px tall (small laptops, browser-chrome 768p, half-height windows):
   the composer + example pills are taller than the viewport, so the
   clamp() gap above already floors at 16px — but that alone isn't enough.
   Gently compact the composer (shorter textarea, tighter header margin,
   smaller stack gap, minimal example gap) and DROP the decorative examples
   header so the whole thing still fits on one screen without scrolling. The
   ≤600px block below takes over for shorter panels. */
@media (max-height: 760px) {
  .nx-create-textarea-centered { min-height: 120px !important; }
  .nx-create-h1 { margin: 8px 0 8px !important; }
  .nx-create-idle-center { gap: 10px !important; }
  .nx-create-idle-center .nx-create-examples { margin-top: 12px !important; }
  .nx-create-idle-center .nx-create-examples > div:first-child { display: none !important; }
}

@media (max-height: 600px) {
  .nx-create-idle-shell { padding: 10px 12px !important; }
  .nx-create-idle-center { gap: 8px !important; }
  .nx-create-h1 { font-size: 18px !important; line-height: 1.05 !important; margin: 2px 0 4px !important; }
  .nx-create-mode-toggle { margin: 8px auto 6px !important; }
  .nx-create-textarea-centered { min-height: 72px !important; padding: 10px !important; font-size: 14px !important; }
  .nx-create-auto-row { margin: 6px auto 0 !important; }
  .nx-create-idle-center .nx-create-examples { margin-top: 8px !important; }
  /* Hide the "or start from an example" eyebrow — keep the pills but tighten
     the row so the whole composer fits. */
  .nx-create-idle-center .nx-create-examples > div:first-child { display: none !important; }
}

@media (max-height: 480px) {
  /* RecentList is a "nice to have" on a fresh visit, but on landscape phones
     (568×320) it pushes the CTA off-screen. Hide it. */
  .nx-create-recent-list { display: none !important; }
  .nx-create-textarea-centered { min-height: 60px !important; padding: 8px !important; }
  .nx-create-h1 { font-size: 16px !important; line-height: 1.05 !important; }
  /* Compact the example pills to a single tight row. */
  .nx-create-idle-center .nx-create-examples { margin-top: 4px !important; }
  .nx-create-idle-center .nx-create-examples > div:last-child > button { padding: 5px 10px !important; font-size: 11px !important; }
}

@media (max-height: 380px) {
  /* Very short (split-screen, browser devtools open, very small landscape
     panels) — drop the examples entirely, leave just the input + CTA. */
  .nx-create-idle-center .nx-create-examples { display: none !important; }
  .nx-create-textarea-centered { min-height: 48px !important; }
  .nx-create-h1 { font-size: 15px !important; }
  /* Auto-build row becomes a single line. */
  .nx-create-auto-row > span { display: none !important; }
}
