/* =========================================================
   GEXI — public/shell/gx-rail.css   (SU3 Step 2 — the Work Rail · STRUCTURE PASS 2026-07-22)

   FUNCTIONAL layout + the LIVE status pips for the Work Rail island (workRail.js) that owns #gx-drawer. Token-driven
   (var(--*) only, no off-brand literals) so SU2's gx-skin.css layers the premium glow/gradient on top without rework.
   The Conversations group reuses chat.css's cv-* sidebar styles (chat.css is loaded in app-shell.html) — no fork; the
   .gx-rail-convos-scoped overrides below retune ONLY spacing/structure, so /chat's own sidebar stays byte-identical.

   STRUCTURE (owner 2026-07-22: "structured like ChatGPT and Claude"): ONE vertical rhythm — every row is a
   --rail-row-h (36px, 44px on touch/mobile) box with ZERO margins and the SAME --rail-x inline padding, so the whole
   rail shares one left edge (icon'd rows share one 18px icon column too). Sections read as quiet dim labels, not
   chrome; the ONLY divider is the Tools hairline; hover reveals the secondary actions (chat.css's delete affordance).
   ========================================================= */

/* SU3 — the Work Rail is a WIDE list (not the legacy 72px icon stack); override the shell's desktop rail-width token
   (last-load, so the shipped appShell.css is untouched). Mobile uses its own slide-over width, unaffected. */
#gx-shell { --gx-rail-w: 280px; }

.gx-rail {
  display: flex; flex-direction: column; height: 100%; min-height: 0;
  background: var(--void, var(--bg)); color: var(--text);
  /* the ONE rhythm every row obeys (rows = min-height + inline padding, never ad-hoc margins) */
  --rail-row-h: 36px;      /* the row height (ChatGPT/Claude-tight; bumped to 44px on touch/mobile below) */
  --rail-x: 10px;          /* the ONE inline row padding — every row + label shares this left edge (12px on mobile) */
}

/* ---- section 1 · primary actions (fixed): ＋New chat + the PINNED search (ChatGPT parity — search sits under New
   chat, above the list, and never scrolls away). The input drives the SAME sessionQuery signal the shared SessionList
   filters by; the SessionList's own inline input is hidden below (rail-scope only). ---- */
.gx-rail-top { flex: none; display: flex; flex-direction: column; gap: 2px; padding: 0 0 var(--space-2); }
.gx-rail-new {
  flex: none; margin: 0; min-height: var(--rail-row-h); padding: 0 var(--rail-x); box-sizing: border-box;
  display: flex; align-items: center; justify-content: flex-start; gap: var(--space-2);
  font: inherit; font-weight: 600; font-size: var(--text-sm); color: var(--text);
  background: none; border: 0; border-radius: var(--radius, 10px); cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.gx-rail-new:hover { background: var(--card-alt); }
.gx-rail-new:focus-visible { outline: var(--focus-ring); outline-offset: -2px; }
.gx-rail-new-ic { flex: 0 0 18px; width: 18px; text-align: center; font-size: var(--text-base); line-height: 1; color: var(--brand-500); }   /* the one green accent — a tinted glyph in the shared 18px icon column */
/* ⭐ WAVE 0.5 C8 — THE PLACES (Chats · Projects). Two rows, deliberately NOT a segmented control: a segment
   would invent a second geometry inside a rail whose whole point is ONE rhythm. These reuse it verbatim —
   the same --rail-row-h box, the same --rail-x left edge, the same shared 18px icon column, zero margins —
   so the switch reads as part of the list rather than as chrome bolted above it. Tokens only, no new colours.
   Retires with GEXI_PROJECT_MODE. */
/* SIDE BY SIDE (owner, 2026-07-28: "make project and chat side by side like how claude has chat and code
   side by side"). The two places share ONE row and split it evenly, so the switch reads as a single control
   with two halves rather than as two list items that happen to be about places. The rail's rhythm is still
   honoured where it matters — the SAME --rail-row-h height and the SAME --rail-x outer edge (moved to the
   container, so the pair lines up with every row below it) — the halves just centre their own labels. */
.gx-rail-places {
  display: flex; flex-direction: row; gap: 4px;
  margin: 0 0 var(--space-1); padding: 0 var(--rail-x); box-sizing: border-box;
}
.gx-rail-place {
  flex: 1 1 0; min-width: 0; margin: 0; min-height: var(--rail-row-h); padding: 0 var(--space-2); box-sizing: border-box;
  display: flex; align-items: center; justify-content: center; gap: var(--space-2);
  font: inherit; font-weight: 600; font-size: var(--text-sm); color: var(--muted);
  background: none; border: 0; border-radius: var(--radius, 10px); cursor: pointer; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.gx-rail-place:hover { background: var(--card-alt); color: var(--text); }
.gx-rail-place:focus-visible { outline: var(--focus-ring); outline-offset: -2px; }
.gx-rail-place.is-active { background: var(--card-alt); color: var(--text); }
.gx-rail-place-ic { flex: 0 0 18px; width: 18px; text-align: center; font-size: var(--text-base); line-height: 1; }
.gx-rail-place.is-active .gx-rail-place-ic { color: var(--brand-500); }

.gx-rail-search {
  flex: none; width: 100%; box-sizing: border-box; margin: 0; min-height: 32px; padding: 0 var(--rail-x);
  font: inherit; font-size: var(--text-sm); color: var(--text);
  background: var(--void, var(--bg)); border: 1px solid var(--line); border-radius: var(--radius, 10px);
}
.gx-rail-search::placeholder { color: var(--faint, var(--muted)); }
.gx-rail-search:focus { outline: none; border-color: var(--muted); }

/* the visually-hidden aria-live announcer (status flips read by screen-readers; never silent). */
.gx-rail-announce { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

.gx-rail-error { margin: 0 0 var(--space-2); padding: var(--space-2) var(--rail-x); font-size: var(--text-xs); color: var(--muted); background: var(--card-alt); border-radius: var(--radius-sm, 8px); }
.gx-rail-retry { margin-left: var(--space-1); font: inherit; font-size: var(--text-xs); color: var(--brand-500); background: none; border: 0; text-decoration: underline; cursor: pointer; }

/* ---- section 2 · the scrolling groups (Projects → Conversations) — ONE scroll (the group lists inside are inert) ---- */
.gx-rail-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }

/* collapsible groups (<details>/<summary> — keyboard-accessible by default). ChatGPT/Claude-feel: NO hairline between
   groups (spacing carries the separation; the single divider lives above the Tools footer). */
.gx-rail-group { border: 0; margin: 0; padding: 0; }
/* the section label — QUIET and dim (11px, sentence-case), the ChatGPT "Today" / Claude "Recents" register; it sits on
   the same left edge as every row. */
.gx-rail-grouphd {
  min-height: 26px; box-sizing: border-box; padding: var(--space-2) var(--rail-x) 2px;
  display: flex; align-items: center; gap: var(--space-1);
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.02em; text-transform: none;
  color: var(--faint, var(--muted)); cursor: pointer; list-style: none;
}
.gx-rail-grouphd::-webkit-details-marker { display: none; }
.gx-rail-grouphd:focus-visible { outline: var(--focus-ring); outline-offset: -2px; }
/* C10 — .gx-rail-count DELETED with the two <details> groups it labelled: one place at a time means the
   list IS the count, so there is no badge left to style. */

/* the shared SessionList, rail-scoped SPACING-ONLY retune (chat.css owns the base styles; /chat is untouched):
   the rail's pinned top search owns the query, so the inline input hides; the static "Recent" sub-label is redundant
   under the "Conversations N" summary; the inner list joins the rail's ONE scroll + row rhythm. */
.gx-rail-convos .cv-session-search { display: none; }
.gx-rail-convos .cv-side-label { display: none; }
.gx-rail-convos .cv-sessions { flex: none; overflow: visible; margin: 0; padding: 0 0 var(--space-1); gap: 1px; }
.gx-rail-convos .cv-session { min-height: var(--rail-row-h); box-sizing: border-box; margin: 0; padding: 0 var(--rail-x); gap: var(--space-2); border-radius: var(--radius, 10px); font-size: var(--text-sm); }
.gx-rail-convos .cv-side-empty { padding: var(--space-1) var(--rail-x) var(--space-2); font-size: var(--text-sm); }

/* a Projects/Deliverables row — the LIVE task line (Interaction LAW: it RADIATES the producer working). */
.gx-rail-works { display: flex; flex-direction: column; gap: 1px; padding: 0 0 var(--space-1); }
.gx-rail-work {
  width: 100%; min-width: 0; box-sizing: border-box; display: flex; align-items: center; gap: var(--space-2);
  min-height: var(--rail-row-h); padding: 2px var(--rail-x); margin: 0; font: inherit; text-align: left; color: inherit;
  background: none; border: 0; border-radius: var(--radius, 10px); cursor: pointer; contain: layout paint;
}
.gx-rail-work:hover { background: var(--card-alt); }
.gx-rail-work.is-active { background: var(--card-alt); box-shadow: inset 2px 0 0 var(--brand-500); }
.gx-rail-work:focus-visible { outline: var(--focus-ring); outline-offset: -2px; }
.gx-rail-work-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.gx-rail-work-title { font-size: var(--text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gx-rail-live { font-size: var(--text-xs); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gx-rail-cost { flex: none; font-size: var(--text-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.gx-rail-chips { flex: none; display: flex; gap: 2px; }
.gx-rail-chip { font-size: 10px; padding: 1px var(--space-1); border-radius: 4px; background: var(--card-alt); color: var(--muted); }

/* the LIVE status pip — a shape+text-labelled dot (never colour-only). Step-2 colours via the --glyph-* dark-canvas
   tokens with a safe brand fallback; SU2's gx-glyphs grammar can refine. .gx-glyph--making pulses ONLY opacity. */
.gx-pip { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--pip, var(--muted)); }
.gx-rail-work > .gx-pip { margin: 0 5px; }   /* the 8px dot sits centred in the SAME 18px icon column as .gx-rail-icon — one label edge across icon'd rows */
.gx-glyph--making { --pip: var(--glyph-making, var(--brand-500)); }
.gx-glyph--ready  { --pip: var(--glyph-ready,  var(--cost-free, var(--brand-400, var(--brand-500)))); }
.gx-glyph--failed { --pip: var(--glyph-failed, var(--red)); }
.gx-glyph--review { --pip: var(--glyph-review, var(--amber, var(--brand-500))); }
.gx-glyph--pending { --pip: var(--glyph-pending, var(--faint, var(--muted))); }
.gx-rail-work .gx-glyph--making { animation: gxRailPulse 1.4s ease-in-out infinite; }
@keyframes gxRailPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
@media (prefers-reduced-motion: reduce) { .gx-rail-work .gx-glyph--making { animation: none; } }

/* ---- section 3 · the Tools footer — the old rooms, demoted (the shellRouter still handles these clicks by delegation
   on #gx-drawer). Tools carries the SINGLE divider in the rail. ---- */
.gx-rail-tools { margin-top: var(--space-1); padding-top: var(--space-1); border-top: 0.5px solid var(--line); border-bottom: 0; }
.gx-rail-roomlist { display: flex; flex-direction: column; gap: 1px; padding: 0 0 var(--space-1); }
.gx-rail-item {
  display: flex; flex-direction: row; align-items: center; gap: var(--space-2);
  min-height: var(--rail-row-h); box-sizing: border-box; padding: 0 var(--rail-x); border-radius: var(--radius, 10px);
  color: var(--muted); text-decoration: none; font-size: var(--text-sm);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}   /* flex-direction:row + min-height override the legacy appShell.css icon-stack for the wide rail */
.gx-rail-item:hover { background: var(--card-alt); color: var(--text); }
.gx-rail-item.active { color: var(--text); }
.gx-rail-icon { flex: 0 0 18px; width: 18px; text-align: center; font-size: var(--text-base); line-height: 1; }   /* the ONE 18px icon column — labels align across every icon'd row */
.gx-rail-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* first-load skeleton (SU2 adds the .gx-shimmer sweep) — rows at the SAME rhythm as the real rows. */
.gx-rail-skel { padding: var(--space-2) 0; display: flex; flex-direction: column; gap: 2px; }
.gx-rail-skelrow { height: var(--rail-row-h); border-radius: var(--radius, 10px); background: var(--card-alt); opacity: 0.6; }

/* the inviting EMPTY state (never three blank groups). */
.gx-rail-empty { padding: var(--space-4); text-align: center; }
.gx-rail-empty-h { margin: 0 0 var(--space-1); font-weight: 640; font-size: var(--text-sm); }
.gx-rail-empty-sub { margin: 0; font-size: var(--text-xs); color: var(--muted); line-height: 1.5; }

/* tap-taming for the rail's primary touch targets (no 300ms delay, no blue flash) — mobile audit. */
.gx-rail-new, .gx-rail-item, .gx-rail-work { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }

/* ---- touch/mobile: the SAME structure at a 44px row floor (owner law: 44px touch targets) + the drawer's 12px inline
   padding (gx-skin's mobile pass) — the rows follow via the one --rail-x token, so the single left edge holds. ---- */
@media (max-width: 959px), (hover: none) {
  .gx-rail { --rail-row-h: 44px; --rail-x: 12px; }
}
