/* ============================================================================
 * Zexir — Profit Mode design system
 *
 * WHY THIS FILE EXISTS
 * Four stylesheets (foundation, index-polish, premium-pass, index-fast, plus
 * profit-mode) each defined their own value for the same token names. The result
 * was three different sidebar widths, four different sidebar backgrounds, and a
 * purple/blue tint leaking through every neutral surface.
 *
 * Rather than add a fifth layer of per-selector overrides, this file resolves the
 * conflict at the token level. It loads LAST and gives every shared variable a
 * single authoritative value, so the ~2000 existing rules downstream inherit one
 * coherent palette and geometry without any of them being rewritten.
 *
 * RULES FOR EDITING
 *   - Change appearance by editing a token here, not by adding a selector.
 *   - Only add a selector below when a rule hardcodes a literal colour that no
 *     token controls. Those are grouped in the "Literal-colour corrections"
 *     section and each one says what it is correcting.
 *   - Greyscale only. Rose gold is reserved for generation progress (§1).
 * ========================================================================== */

/* ---------------------------------------------------------------------------
 * 1. Neutral scale
 * A single perceptually even grey ramp. No hue: every step has R=G=B, which is
 * what removes the lilac cast the old #f8f7fa / #eeebf4 / #e6e3eb values had.
 * ------------------------------------------------------------------------- */
:root {
  --zx-white: #ffffff;
  --zx-50: #fbfbfb;
  --zx-100: #f7f7f7;
  --zx-150: #f2f2f2;
  --zx-200: #ebebeb;
  --zx-300: #e0e0e0;
  --zx-400: #c7c7c7;
  --zx-500: #9a9a9a;
  --zx-600: #767676;
  --zx-700: #565656;
  --zx-800: #3a3a3a;
  --zx-900: #1f1f1f;
  --zx-950: #141414;
  --zx-black: #0a0a0a;

  /* Alpha neutrals. Used for hover/press so surfaces tint consistently
   * regardless of what sits underneath them. */
  --zx-alpha-04: rgba(0, 0, 0, 0.04);
  --zx-alpha-06: rgba(0, 0, 0, 0.06);
  --zx-alpha-08: rgba(0, 0, 0, 0.08);
  --zx-alpha-12: rgba(0, 0, 0, 0.12);

  /* The one permitted accent, per §1: generation progress only. */
  --zx-rose: #b98a86;
  --zx-rose-deep: #a4736f;
}

/* ---------------------------------------------------------------------------
 * 2. Semantic tokens
 * Every name below is already consumed by one of the existing stylesheets.
 * Re-pointing them here is what unifies the product.
 * ------------------------------------------------------------------------- */
:root {
  /* Surfaces. Sidebar is pure white to match ChatGPT; separation comes from the hairline
   * border, not from a fill. */
  --bg-page: var(--zx-white);
  --bg-sidebar: var(--zx-white);
  --bg-surface: var(--zx-white);
  --bg-input: var(--zx-white);
  --bg-glass: rgba(255, 255, 255, 0.86);

  /* Text. Slightly darker mid/low tones than before so secondary labels read as
   * deliberate rather than washed out. */
  --text-high: var(--zx-900);
  --text-med: var(--zx-700);
  --text-low: var(--zx-600);
  --text-on-brand: var(--zx-white);

  /* Brand is now literally black — §1 removes accent colour from the system. */
  --brand-primary: var(--zx-black);
  --brand-primary-hover: var(--zx-900);
  --brand-primary-soft: var(--zx-alpha-06);

  --border-subtle: var(--zx-alpha-08);
  --border-strong: var(--zx-alpha-12);

  /* Geometry — one value each, replacing the 245/252/256/280px disagreement. */
  --sidebar-w: 268px;
  --sidebar-mini: 62px;
  --header-h: 54px;
  --input-max-w: 780px;

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 18px;
  --radius-pill: 999px;

  /* Shadows kept deliberately shallow. §22 forbids giant shadows and heavy blur
   * because they are the most expensive thing a compositor can be asked to do. */
  --shadow-subtle: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-elevated: 0 6px 20px rgba(0, 0, 0, 0.08);
  --shadow-modal: 0 16px 48px rgba(0, 0, 0, 0.14);
}

/* ---------------------------------------------------------------------------
 * 3. Motion system (§21)
 * One vocabulary of durations and curves. Features reference these instead of
 * inventing their own timing, which is what makes unrelated transitions feel
 * like the same product.
 * ------------------------------------------------------------------------- */
:root {
  /* Standard: the default for almost everything. */
  --zx-ease: cubic-bezier(0.2, 0, 0, 1);
  /* Emphasised: entrances that should feel like they settle into place. */
  --zx-ease-emphasis: cubic-bezier(0.16, 1, 0.3, 1);
  /* Exits: start fast, no overshoot. Leaving should never feel slow. */
  --zx-ease-exit: cubic-bezier(0.4, 0, 1, 1);

  --zx-fast: 120ms;   /* hover, press, colour changes */
  --zx-base: 200ms;   /* menus, tooltips, reveals */
  --zx-slow: 320ms;   /* sidebar, overlays, layout shifts */

  /* Legacy aliases so existing rules pick up the new curve automatically. */
  --ease: var(--zx-ease);
  --transition: all var(--zx-base) var(--zx-ease);
}

/* ---------------------------------------------------------------------------
 * 4. Namespace reconciliation
 * index-fast and profit-mode use private token namespaces. Point them at the
 * shared scale so all three agree.
 * ------------------------------------------------------------------------- */
:root {
  /* index-fast */
  --index-sidebar-width: var(--sidebar-w);
  --index-sidebar-rail: var(--sidebar-mini);
  --index-header-height: var(--header-h);
  --index-content-width: var(--input-max-w);
  --index-sidebar-bg: var(--bg-sidebar);
  --index-hover-bg: var(--zx-200);
  --index-text: var(--text-high);
  --index-secondary: var(--text-low);
  --index-hairline: var(--border-subtle);

  /* profit-mode */
  --profit-black: var(--zx-black);
  --profit-ink: var(--text-high);
  --profit-muted: var(--text-low);
  --profit-line: var(--border-subtle);
  --profit-sidebar: var(--bg-sidebar);
  --profit-hover: var(--zx-200);

  /* The violet/blue accents are collapsed onto the neutral ramp. They are kept
   * defined rather than deleted because ~6 downstream rules still reference
   * them; pointing them at greys neutralises those rules in place. */
  --profit-violet: var(--text-high);
  --profit-blue: var(--zx-800);
  --profit-rose: var(--zx-rose);

  /* Primary actions become solid near-black instead of a three-stop gradient. */
  --profit-action: var(--zx-black);
  --profit-action-hover: var(--zx-900);
  --profit-action-shadow: 0 2px 8px rgba(0, 0, 0, 0.16);
}

/* ---------------------------------------------------------------------------
 * 5. Typography (§1: "slightly increase font weight ... more substantial
 *    without becoming heavy")
 * Nudged one step, not two: 500 for controls, 600 for section headers.
 * ------------------------------------------------------------------------- */
body.index-workspace {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--text-high);
}

body.index-workspace .nav-link,
body.index-workspace .nav-text,
body.index-workspace .model-picker-btn,
body.index-workspace .composer-add-menu-item,
body.index-workspace button {
  font-weight: 500;
}

/* Section headers ("Pinned", "Chats") — .sidebar-section-label is the row the
 * profit-mode script builds; .history-label is the original Chats label it
 * reuses in place. */
body.index-workspace .sidebar-section-label,
body.index-workspace .sidebar-history-section .history-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 10px 14px 4px 18px;
  font-weight: 600;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-low);
}

/* ---------------------------------------------------------------------------
 * 6. Literal-colour corrections
 * Each rule here overrides a hardcoded tinted literal that no token reaches.
 * ------------------------------------------------------------------------- */

/* profit-mode:1192 — lilac hover wash on composer utility buttons. */
body.index-workspace .mic-btn:hover,
body.index-workspace .model-picker-btn:hover {
  background: var(--zx-alpha-06) !important;
}

/* profit-mode:1226 — user bubble was #f3f1f6 (violet-tinted). */
body.index-workspace .user-bubble {
  background: var(--zx-150) !important;
}

/* profit-mode:1213 — purple glow under the streaming send button. */
body.index-workspace #sendBtn.streaming {
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.14) !important;
}

/* profit-mode:265 — muted grey for the empty pinned hint. */
body.index-workspace .sidebar-pinned-empty {
  color: var(--text-low);
}

/* profit-mode:863-886 — the right-side navigator hardcodes #c6c7c9 / #111 / #dedede /
 * #6c6f74. Geometry there already matches §18 (3.5px lines, 5.5px hover extend), so only
 * the colours are re-pointed at the ramp. */
body.index-workspace .conversation-map-line {
  background: var(--zx-400) !important;
  transition: width var(--zx-fast) var(--zx-ease),
    background-color var(--zx-fast) var(--zx-ease),
    transform var(--zx-fast) var(--zx-ease) !important;
}

body.index-workspace .conversation-map-line:hover,
body.index-workspace .conversation-map-line.active {
  background: var(--zx-black) !important;
}

body.index-workspace .conversation-map-preview {
  border: 1px solid var(--border-subtle) !important;
  background: var(--bg-surface) !important;
  box-shadow: var(--shadow-elevated) !important;
  animation: zx-tooltip-in var(--zx-fast) var(--zx-ease);
}

body.index-workspace .conversation-map-preview strong {
  color: var(--text-high);
  font-weight: 600;
}

body.index-workspace .conversation-map-preview span {
  color: var(--text-low) !important;
}

/* Inline <style> in index.html hardcodes #2b2b2b / #303030 for incognito and
 * #fefefe / #e3e3e3 for the composer menus. Normalise onto the ramp. */
body.index-workspace.temporary-chat-mode .input-region .composer {
  background: var(--zx-950) !important;
  border-color: var(--zx-800) !important;
}

body.index-workspace #composerAddMenu,
body.index-workspace #composerRecentMenu,
body.index-workspace #composerPersonalitiesMenu {
  border: 1px solid var(--border-subtle) !important;
  background: var(--bg-surface) !important;
  box-shadow: var(--shadow-elevated) !important;
}

/* ---------------------------------------------------------------------------
 * 7. Generation progress — the one place rose gold is allowed (§4)
 * Rose fills the completed portion; the remainder stays near-black.
 * ------------------------------------------------------------------------- */
body.index-workspace #sendBtn.streaming {
  background: linear-gradient(
    90deg,
    var(--zx-rose) 0 calc(var(--stream-progress, 0) * 1%),
    var(--zx-black) calc(var(--stream-progress, 0) * 1%) 100%
  ) !important;
}

/* ---------------------------------------------------------------------------
 * 8. Sidebar and chat list (§6, §7)
 * The structural pass: consistent row geometry, calm hover, and controls that
 * only appear on hover so a resting list is just titles.
 * ------------------------------------------------------------------------- */
body.index-workspace #sidebar {
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border-subtle);
}

/* Header row: brand on the left, then Search immediately left of the
 * close-sidebar button — the script reorders the DOM to achieve that, this
 * gives the row its geometry (§6). */
body.index-workspace #sidebar .sidebar-header {
  display: flex;
  align-items: center;
  gap: 2px;
  min-height: var(--header-h);
  padding: 0 8px 0 12px;
}

body.index-workspace .sidebar-brand-btn {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  border: 0;
  background: none;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color var(--zx-fast) var(--zx-ease);
}

body.index-workspace .sidebar-brand-btn:hover {
  background: var(--zx-alpha-04);
}

body.index-workspace .sidebar-full-brand {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}

body.index-workspace .sidebar-full-favicon {
  width: 18px;
  height: 18px;
  align-self: center;
  border-radius: 5px;
}

/* "Zexir" is the wordmark, so it gets real size. The plan matches it exactly in size and
 * weight and separates only by colour, so the two read as one lockup. */
body.index-workspace .sidebar-brand-name,
body.index-workspace .sidebar-brand-plan {
  font-size: 21px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.1;
  white-space: nowrap;
}

body.index-workspace .sidebar-brand-name {
  color: var(--text-high);
}

body.index-workspace .sidebar-brand-plan {
  color: var(--zx-500);
}

/* Taller header to give the wordmark room to breathe. */
body.index-workspace #sidebar .sidebar-header {
  min-height: 64px;
}

/* Hovering the sidebar swaps the favicon for the collapse icon, like ChatGPT. Both glyphs are
 * stacked in the same 22px box and cross-faded, so nothing reflows on hover. */
body.index-workspace .sidebar-brand-btn {
  position: relative;
}

body.index-workspace .sidebar-full-favicon {
  width: 22px;
  height: 22px;
  transition: opacity var(--zx-fast) var(--zx-ease);
}

body.index-workspace .sidebar-brand-collapse-icon {
  position: absolute;
  left: 6px;
  top: 50%;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-top: -11px;
  font-size: 21px;
  color: var(--text-med);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--zx-fast) var(--zx-ease);
}

body.index-workspace #sidebar:hover .sidebar-full-favicon {
  opacity: 0;
}

body.index-workspace #sidebar:hover .sidebar-brand-collapse-icon {
  opacity: 1;
}

/* Search + close share one icon-button treatment. */
body.index-workspace .sidebar-header-search,
body.index-workspace #sidebar .sidebar-header #menuBtn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-med);
  cursor: pointer;
  transition: background-color var(--zx-fast) var(--zx-ease),
    color var(--zx-fast) var(--zx-ease);
}

body.index-workspace .sidebar-header-search:hover,
body.index-workspace #sidebar .sidebar-header #menuBtn:hover {
  background: var(--zx-alpha-06);
  color: var(--text-high);
}

/* Account row at the foot of the sidebar shows the workspace type (§6). */
body.index-workspace .sidebar-account-plan {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-low);
}

/* --- Guest sign-in footer ------------------------------------------------- */
body.index-workspace .sidebar-bottom {
  flex: 0 0 auto;
  padding: 0;
  background: transparent;
  border-top: 1px solid var(--border-subtle);
}

body.index-workspace .sidebar-bottom.sidebar-bottom-guest {
  border-top: 1px solid var(--border-subtle);
}

/* Flat block, no card. The bordered card read as a floating panel wedged into the sidebar;
 * a hairline above it and plain copy sits quietly at the foot instead. */
body.index-workspace .sidebar-login-box {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin: 0;
  padding: 12px 14px 14px;
  border: 0;
  background: transparent;
}

body.index-workspace .sidebar-login-copy .line {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--text-low);
}

body.index-workspace .sidebar-login-btn {
  width: 100%;
  min-height: 34px;
  padding: 0 12px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color var(--zx-fast) var(--zx-ease),
    border-color var(--zx-fast) var(--zx-ease), color var(--zx-fast) var(--zx-ease);
}

body.index-workspace .sidebar-login-btn--primary {
  background: var(--zx-black);
  color: var(--zx-white);
}

body.index-workspace .sidebar-login-btn--primary:hover {
  background: var(--zx-900);
}

body.index-workspace .sidebar-login-btn--ghost {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--text-high);
}

body.index-workspace .sidebar-login-btn--ghost:hover {
  background: var(--zx-alpha-04);
}

/* Collapsed rail: the card would overflow a 62px sidebar, so it is replaced by
 * nothing rather than being allowed to clip. */
body.index-workspace #sidebar.collapsed .sidebar-login-box,
body.index-workspace #sidebar.sidebar-collapsed .sidebar-login-box {
  display: none;
}

/* Rows: one height, one radius, one inset. */
body.index-workspace #sidebar-history .history-chat-btn,
body.index-workspace .sidebar-pinned-list .history-chat-btn {
  min-height: 34px !important;
  padding: 0 8px 0 10px !important;
  margin: 1px 8px !important;
  border-radius: var(--radius-sm) !important;
  font-size: 13.5px !important;
  font-weight: 500 !important;
  color: var(--text-med) !important;
  /* Colour-only transition: no layout property animates on hover. */
  transition: background-color var(--zx-fast) var(--zx-ease),
    color var(--zx-fast) var(--zx-ease) !important;
}

body.index-workspace #sidebar-history .history-chat-btn:hover,
body.index-workspace .sidebar-pinned-list .history-chat-btn:hover {
  background: var(--zx-alpha-04) !important;
  color: var(--text-high) !important;
}

/* Active row reads as selected via weight + ink, not a coloured fill. */
body.index-workspace #sidebar .history-chat-btn.active {
  background: var(--zx-alpha-08) !important;
  color: var(--text-high) !important;
  font-weight: 600 !important;
}

/* Row layout. Actual markup is:
 *   [.chat-pin-indicator?] [.nav-text] [.chat-share-btn] [.chat-more-btn]
 * The title needs `min-width: 0` for ellipsis to work inside a flex row —
 * without it the text forces the row wider and pushes the controls out, which
 * is most of why the list looked ragged. */
body.index-workspace #sidebar-history .history-chat-btn,
body.index-workspace .sidebar-pinned-list .history-chat-btn {
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
}

body.index-workspace .history-chat-btn .nav-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.35;
}

body.index-workspace .history-chat-btn .chat-pin-indicator {
  flex: 0 0 auto;
  font-size: 14px !important;
  color: var(--text-low);
}

body.index-workspace .history-chat-btn .chat-share-btn,
body.index-workspace .history-chat-btn .chat-more-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-low);
  cursor: pointer;
}

body.index-workspace .history-chat-btn .chat-share-btn .material-symbols-rounded,
body.index-workspace .history-chat-btn .chat-more-btn .material-symbols-rounded {
  font-size: 17px;
}

/* Hover-only row controls (§7). Opacity only, so revealing them never reflows
 * the row — the buttons keep their box at all times.
 *
 * .chat-pin-indicator is deliberately excluded: it is a status marker rendered
 * only on pinned rows, not a control, so hiding it would remove the only signal
 * that a row is pinned. §7 refers to the pin *button*, which this is not. */
body.index-workspace .history-chat-btn .chat-share-btn,
body.index-workspace .history-chat-btn .chat-more-btn {
  opacity: 0 !important;
  pointer-events: none !important;
  transition: opacity var(--zx-fast) var(--zx-ease) !important;
}

body.index-workspace .history-chat-btn:hover .chat-share-btn,
body.index-workspace .history-chat-btn:hover .chat-more-btn,
body.index-workspace .history-chat-btn:focus-within .chat-share-btn,
body.index-workspace .history-chat-btn:focus-within .chat-more-btn {
  opacity: 1 !important;
  pointer-events: auto !important;
}

body.index-workspace .history-chat-btn .chat-pin-indicator {
  opacity: 0.55 !important;
  pointer-events: none !important;
}

body.index-workspace .history-chat-btn .chat-share-btn:hover,
body.index-workspace .history-chat-btn .chat-more-btn:hover {
  background: var(--zx-alpha-08) !important;
  border-radius: 6px !important;
}

/* Section headers: New Chat + three-dot hidden until the header is hovered (§7).
 * Reserve the row height so revealing them cannot shift the label. */
body.index-workspace .sidebar-section-actions {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-height: 22px;
}

body.index-workspace .sidebar-section-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--text-low);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--zx-fast) var(--zx-ease),
    background-color var(--zx-fast) var(--zx-ease);
}

body.index-workspace .sidebar-section-action .material-symbols-rounded {
  font-size: 17px;
}

body.index-workspace .sidebar-section-label:hover .sidebar-section-action,
body.index-workspace .sidebar-section-label:focus-within .sidebar-section-action,
body.index-workspace .history-label:hover .sidebar-section-action,
body.index-workspace .history-label:focus-within .sidebar-section-action {
  opacity: 1;
  pointer-events: auto;
}

body.index-workspace .sidebar-section-action:hover {
  background: var(--zx-alpha-08);
  color: var(--text-high);
}

/* Section dropdown + right-rail request menu share one surface treatment. */
body.index-workspace .sidebar-section-menu {
  position: fixed;
  z-index: 2147483646;
  min-width: 190px;
  padding: 5px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  box-shadow: var(--shadow-elevated);
}

body.index-workspace .sidebar-section-menu button {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 9px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-high);
  font-size: 13.5px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--zx-fast) var(--zx-ease);
}

body.index-workspace .sidebar-section-menu button:hover {
  background: var(--zx-alpha-06);
}

body.index-workspace .sidebar-section-menu button .material-symbols-rounded {
  font-size: 18px;
  color: var(--text-low);
}

/* Collapsed section: hide the body without animating height. */
body.index-workspace .sidebar-history-section.section-collapsed .sidebar-section-body,
body.index-workspace .sidebar-history-section.section-collapsed .sidebar-history-scroll {
  display: none;
}

/* --- Incognito exit rail -------------------------------------------------- */
/*
 * profit-mode anchors this on `left`, so widening when armed pushed it off the right edge of the
 * screen. The JS now sets `right`; this clears the stale `left` so the two cannot fight, and pins
 * the label to the right so its text grows leftward as the rail widens.
 */
body.index-workspace .incognito-exit-rail {
  left: auto !important;
  align-items: flex-end;
  justify-content: flex-end;
  padding-right: 7px;
  border-color: var(--border-subtle) !important;
  background: var(--bg-surface) !important;
  box-shadow: var(--shadow-elevated) !important;
  transition: width var(--zx-base) var(--zx-ease-emphasis),
    opacity var(--zx-fast) var(--zx-ease), transform var(--zx-base) var(--zx-ease);
}

body.index-workspace .incognito-exit-label {
  background: var(--zx-150) !important;
  color: var(--text-high) !important;
  white-space: nowrap;
  transition: width var(--zx-base) var(--zx-ease-emphasis),
    border-radius var(--zx-base) var(--zx-ease);
}

body.index-workspace .incognito-exit-rail.armed .incognito-exit-label {
  background: var(--zx-black) !important;
  color: var(--zx-white) !important;
}

/* --- Collapsed rail ------------------------------------------------------- */
/*
 * When collapsed, every rail button becomes a centred icon square. Previously the buttons kept
 * their expanded left-aligned padding, so the icons sat off-centre in a 62px rail.
 * `justify-content: center` plus symmetric padding is what actually centres them; the labels are
 * removed from flow with `display: none` so they cannot pull the icon left.
 */
body.index-workspace #sidebar.collapsed .nav-link,
body.index-workspace #sidebar.sidebar-collapsed .nav-link,
body.index-workspace #sidebar.collapsed .sidebar-utility-link,
body.index-workspace #sidebar.sidebar-collapsed .sidebar-utility-link {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 40px !important;
  height: 40px !important;
  margin: 2px auto !important;
  padding: 0 !important;
  border-radius: var(--radius-sm) !important;
}

body.index-workspace #sidebar.collapsed .nav-link .nav-text,
body.index-workspace #sidebar.sidebar-collapsed .nav-link .nav-text,
body.index-workspace #sidebar.collapsed .sidebar-section-label,
body.index-workspace #sidebar.sidebar-collapsed .sidebar-section-label,
body.index-workspace #sidebar.collapsed .history-label,
body.index-workspace #sidebar.sidebar-collapsed .history-label {
  display: none !important;
}

body.index-workspace #sidebar.collapsed #sidebar-top-nav,
body.index-workspace #sidebar.sidebar-collapsed #sidebar-top-nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 4px 0;
}

/* The rail search button only exists for the collapsed state. */
body.index-workspace .sidebar-rail-search {
  display: none;
}

body.index-workspace #sidebar.collapsed .sidebar-rail-search,
body.index-workspace #sidebar.sidebar-collapsed .sidebar-rail-search {
  display: flex !important;
}

/* --- New Chat hit area ---------------------------------------------------- */
/*
 * The New Chat row stretched the full sidebar width, so the hover target ran far past the label.
 * Sizing it to its content keeps the activation box where the button visually appears.
 */
body.index-workspace #newChatBtn {
  align-self: flex-start;
  width: auto;
  max-width: calc(100% - 16px);
  margin: 2px 8px;
  padding: 0 10px;
  min-height: 36px;
  border-radius: var(--radius-sm);
}

body.index-workspace #sidebar.collapsed #newChatBtn,
body.index-workspace #sidebar.sidebar-collapsed #newChatBtn {
  align-self: center;
  max-width: none;
}

/* --- Chat surface (width + centring) -------------------------------------- */
/*
 * Messages were both too narrow and not centred: the column had a max-width but no auto margins,
 * so it hugged the left edge of the scroller.
 */
body.index-workspace #chat-container {
  width: 100%;
  max-width: var(--input-max-w);
  margin-inline: auto;
  padding-inline: 20px;
}

body.index-workspace .message {
  font-size: 15.5px;
  line-height: 1.68;
}

body.index-workspace .ai-bubble,
body.index-workspace .user-bubble {
  font-size: 15.5px;
  line-height: 1.68;
}

body.index-workspace .user-bubble {
  border-radius: var(--radius-lg) !important;
  padding: 10px 15px !important;
}

/* Composer column must share the message column's width and centring, or the two disagree. */
body.index-workspace .input-region,
body.index-workspace .input-region .composer {
  width: 100%;
  max-width: var(--input-max-w);
  margin-inline: auto;
}

/* --- Header auth buttons (pill) ------------------------------------------- */
body.index-workspace #auth-section {
  display: flex;
  align-items: center;
  gap: 8px;
}

body.index-workspace #auth-section .btn {
  min-height: 36px;
  padding: 0 16px;
  border-radius: var(--radius-pill) !important;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  transition: background-color var(--zx-fast) var(--zx-ease),
    border-color var(--zx-fast) var(--zx-ease), color var(--zx-fast) var(--zx-ease);
}

body.index-workspace #auth-section .btn-primary {
  border: 1px solid transparent !important;
  background: var(--zx-black) !important;
  color: var(--zx-white) !important;
  box-shadow: none !important;
}

body.index-workspace #auth-section .btn-primary:hover {
  background: var(--zx-900) !important;
}

body.index-workspace #auth-section .btn-outline {
  border: 1px solid var(--border-strong) !important;
  background: transparent !important;
  color: var(--text-high) !important;
}

body.index-workspace #auth-section .btn-outline:hover {
  background: var(--zx-alpha-04) !important;
}

/* --- Per-chat context menu ------------------------------------------------ */
/*
 * The menu used to open directly over the three-dot button that spawned it, hiding its own
 * trigger. Anchoring it to the right edge and shifting it left keeps the trigger visible.
 */
body.index-workspace #chatContextMenu {
  min-width: 208px;
  padding: 5px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  box-shadow: var(--shadow-elevated);
  transform-origin: top right;
}

body.index-workspace #chatContextMenu button,
body.index-workspace #chatContextMenu .chat-context-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-high);
  font-size: 13.5px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--zx-fast) var(--zx-ease);
}

body.index-workspace #chatContextMenu button:hover,
body.index-workspace #chatContextMenu .chat-context-item:hover {
  background: var(--zx-alpha-06);
}

body.index-workspace #chatContextMenu .material-symbols-rounded {
  font-size: 19px;
  color: var(--text-low);
}

/* Delete is last and is the only red thing in the product — destructive actions should not
 * look like their neighbours. */
body.index-workspace #chatContextMenu button.danger,
body.index-workspace #chatContextMenu button[data-action="delete"] {
  order: 99;
  margin-top: 4px;
  border-top: 1px solid var(--border-subtle);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  padding-top: 9px;
  color: #c0342b;
}

body.index-workspace #chatContextMenu button.danger .material-symbols-rounded,
body.index-workspace #chatContextMenu button[data-action="delete"] .material-symbols-rounded {
  color: #c0342b;
}

body.index-workspace #chatContextMenu button.danger:hover,
body.index-workspace #chatContextMenu button[data-action="delete"]:hover {
  background: rgba(192, 52, 43, 0.08);
}

/* ---------------------------------------------------------------------------
 * 9. Composer (§2)
 * Pill shape, substantial but not heavy.
 * ------------------------------------------------------------------------- */
body.index-workspace .input-region .composer {
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  background: var(--bg-input);
  box-shadow: var(--shadow-subtle);
  transition: border-color var(--zx-base) var(--zx-ease),
    box-shadow var(--zx-base) var(--zx-ease);
}

body.index-workspace .input-region .composer:focus-within {
  border-color: var(--zx-400);
  box-shadow: var(--shadow-elevated);
}

/* The model selector is always present (§2) — never gated behind the + menu. */
body.index-workspace .model-picker-btn {
  display: inline-flex !important;
  align-items: center;
  gap: 6px;
  border-radius: var(--radius-pill);
  color: var(--text-med);
  transition: background-color var(--zx-fast) var(--zx-ease);
}

/* The + menu matches composer width instead of floating narrow (§2). */
body.index-workspace #composerAddMenu {
  width: min(var(--input-max-w), calc(100vw - 32px)) !important;
  min-width: 0 !important;
  max-width: calc(100vw - 32px) !important;
  border-radius: var(--radius-lg) !important;
}

/* ---------------------------------------------------------------------------
 * 10. Menus, tooltips, overlays (§21)
 * Transform + opacity only — both compositor-only properties, per §22.
 * ------------------------------------------------------------------------- */
body.index-workspace .model-picker-menu,
body.index-workspace #composerAddMenu,
body.index-workspace #composerRecentMenu,
body.index-workspace #composerPersonalitiesMenu,
body.index-workspace .sidebar-section-menu {
  transform-origin: top center;
  animation: zx-menu-in var(--zx-base) var(--zx-ease-emphasis);
  will-change: transform, opacity;
}

@keyframes zx-menu-in {
  from {
    opacity: 0;
    transform: translateY(-4px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

body.index-workspace .profit-tooltip {
  animation: zx-tooltip-in var(--zx-fast) var(--zx-ease);
}

@keyframes zx-tooltip-in {
  from {
    opacity: 0;
    transform: translateY(2px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/*
 * Sidebar open/close animation.
 *
 * Width is a layout property, so this is the one place it is animated — confined to a single
 * element with a short duration. `!important` is needed because index-fast and profit-mode both
 * set `transition: none` on the sidebar, which is what removed the animation in the first place.
 * The main region animates its margin in step so the two never tear apart mid-transition.
 */
body.index-workspace #sidebar {
  transition: width var(--zx-slow) var(--zx-ease-emphasis),
    transform var(--zx-slow) var(--zx-ease-emphasis) !important;
  will-change: width;
}

body.index-workspace .viewport,
body.index-workspace .main-region,
body.index-workspace #main-content {
  transition: margin-left var(--zx-slow) var(--zx-ease-emphasis),
    padding-left var(--zx-slow) var(--zx-ease-emphasis) !important;
}

/* Labels fade slightly ahead of the width so text does not appear to stretch. */
body.index-workspace #sidebar .nav-text,
body.index-workspace #sidebar .sidebar-full-brand {
  transition: opacity var(--zx-base) var(--zx-ease) !important;
}

/* List expansion (§21). */
body.index-workspace .sidebar-pinned-list,
body.index-workspace #sidebar-history {
  transition: opacity var(--zx-base) var(--zx-ease);
}

/* ---------------------------------------------------------------------------
 * 11. Focus visibility
 * A single visible focus ring. Keyboard shortcuts are a headline feature (§8),
 * so keyboard users must be able to see where they are.
 * ------------------------------------------------------------------------- */
body.index-workspace :focus-visible {
  outline: 2px solid var(--zx-black);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

body.index-workspace :focus:not(:focus-visible) {
  outline: none;
}

/* ---------------------------------------------------------------------------
 * 12. Reduced motion (§21, §23)
 * Honour the OS setting. Animations are removed rather than shortened, but
 * opacity is forced to its end state so nothing is left invisible.
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  body.index-workspace *,
  body.index-workspace *::before,
  body.index-workspace *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  body.index-workspace .model-picker-menu,
  body.index-workspace #composerAddMenu,
  body.index-workspace #composerRecentMenu,
  body.index-workspace #composerPersonalitiesMenu,
  body.index-workspace .profit-tooltip,
  body.index-workspace .sidebar-section-menu,
  body.index-workspace .conversation-map-preview {
    opacity: 1;
    transform: none;
  }
}

/* The Settings "Interface motion" switch sets body.motion-off. Honouring it here is what
 * makes that control real rather than decorative (§11). Same treatment as the OS setting,
 * so there is one code path for "no motion" instead of two that can drift. */
body.index-workspace.motion-off *,
body.index-workspace.motion-off *::before,
body.index-workspace.motion-off *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

body.index-workspace.motion-off .model-picker-menu,
body.index-workspace.motion-off #composerAddMenu,
body.index-workspace.motion-off #composerRecentMenu,
body.index-workspace.motion-off #composerPersonalitiesMenu,
body.index-workspace.motion-off .profit-tooltip,
body.index-workspace.motion-off .sidebar-section-menu,
body.index-workspace.motion-off .conversation-map-preview {
  opacity: 1;
  transform: none;
}
