/* Conversation column skeleton: header (breadcrumb row only for subagents not fork + tabs) over the view
   area, composer InputBar at the bottom. Column width/squeeze is layout's;
   this fills its cell. Figma: Header 39:27730 (83px two-row), tabs 13px with
   a 2px active bar. */

.root {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-width: 0;
  background: var(--dsw-alias-bg-base);

  /* Shared width axis for the whole column: one content width W
     (--dsh-chat-content-width) for the transcript, the dock cards
     (todo/goal/queue: card minus four insets, 4 x 8 = 32), and the takeover
     cards (question/approval/plan review); the input card alone is W + 32px.
     The relation also holds when a narrow viewport shrinks everything: the
     chat scroller and the takeover frames pad clearance + 16px per side while
     the input card clears the bare clearance, so the input card stays exactly
     content + 32px at every width. Declared on the root because the
     transcript and the composer seat are sibling subtrees. */
  --dsh-chat-content-width: 748px;
  --dsh-composer-card-max-width: calc(var(--dsh-chat-content-width) + 32px);
  --dsh-composer-side-clearance: 16px;
  --dsh-composer-dock-inset: 8px;
}

.header {
  position: relative;
  flex: none;
  padding: 12px 28px 0 20px;
  border-bottom: 1px solid transparent;
}

.header::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: 1px;
  left: 0;
  z-index: 0;
  height: 1px;
  background: var(--dsw-alias-border-l2);
  pointer-events: none;
}

/* Blank hero/settling: keep the strict Session header mounted without taking
   column space; the root-owned scrollport and composer remain below it. */
.headerHidden {
  display: none;
}

.titleRow {
  display: flex;
  align-items: center;
  gap: 0;
  min-height: 32px;
}

.titleCluster {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.crumbs {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}

.crumbSeg {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.crumbSep {
  /* figma: "/" separators are 14px caption gray (75:7903), one tint lighter than crumb text. */
  color: var(--dsw-alias-label-caption);
  font-size: 14px;
  line-height: 20px;
}

.crumb {
  max-width: 220px;
  overflow: hidden;
  padding: 4px 8px;
  border: none;
  border-radius: 12px;
  background: transparent;
  font-size: 14px;
  line-height: 20px;
  color: var(--dsw-alias-label-tertiary);
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.crumb:hover:not(:disabled) {
  background: var(--dsw-alias-interactive-bg-hover);
}

.crumbCurrent {
  font-weight: 500;
  color: var(--dsw-alias-label-primary);
  cursor: default;
}

.headerActions {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
}

.headerUtilities {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
  margin-left: 20px;
}

.headerUtilities:empty {
  display: none;
}

/* figma Tab_Group 34:11441: 35px strip, gap 36, pad-left 8, tabs bottom-aligned. */
.tabs {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 36px;
  margin-top: 4px;
  padding-left: 8px;
}

/* figma .Tab 34:11442: 13/16 text (figma wt510, rendered 500), gap 8 to the 2px bar. */
.tab {
  position: relative;
  padding: 0 0 11px;
  border: none;
  background: transparent;
  font-size: 13px;
  line-height: 16px;
  font-weight: 500;
  color: var(--dsw-alias-label-tertiary);
  cursor: pointer;
}

.tab::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: 1px;
  left: 0;
  height: 2px;
  border-radius: 2px;
  background: transparent;
}

/* Selected tab is blue, not ink: brand-primary resolves to neutral black in
   this token sheet, so the selected state rides the business blue — the
   nearest semantic token that stays blue in both themes. */
.tabActive {
  color: var(--dsw-alias-state-business-primary);
}

.tabActive::after {
  background: var(--dsw-alias-state-business-primary);
}

.viewArea {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

/* Composer context stack (Figma 9:937): standalone dock cards share one
   rhythm above the input card. */
.composerStack {
  /* Horizontal geometry (card width, clearance, dock inset) rides the shared
     .root variables above so takeover siblings match the stack. */
  --dsh-composer-stack-gap: 6px;

  display: flex;
  flex-direction: column;
  gap: var(--dsh-composer-stack-gap);
}

/* Common seat for the composer chain (fallback + elected overlay siblings). */
.composerSeat {
  display: flex;
  flex: none;
  flex-direction: column;
  /* One cap for every scrolling text region a composer seat can hold: the
     InputBar draft (figma Input 75:8208 max 14 lines × 24px line) and the
     takeover panels' bodies top out at the same height, so electing a
     takeover never grows the footer past the card it replaces. Declared on
     the seat because it is the chain's only shared ancestor — fallback and
     elected overlay are siblings — and custom properties inherit down to
     whichever entry is mounted. */
  --dsh-composer-text-max-height: 336px;
}

/* Active phase: header is ordinary column chrome above the scrollport (not
   sticky). The scroll body holds the transcript and the sticky composer seat
   so wheel over the footer moves the flow. */
.root[data-phase='active'] {
  overflow: hidden;
}

.root[data-phase='active'] .header {
  flex: none;
}

.scrollBody {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  /* The column scrolls on ONE axis. Stating `hidden` rather than leaving the
     initial `visible` is what removes the horizontal bar: a box that scrolls in
     one axis computes `visible` to `auto` in the other, so any bleed becomes
     user-scrollable. `.heroGlow` bleeds by construction (1051/776 of the hero
     box), which put a horizontal scrollbar under every center column narrower
     than the glow. Clipping is unchanged — `overflow-y: auto` already made this
     a scroll container that clips both axes, so this only takes away the bar. */
  overflow-x: hidden;
  /* Reserved unconditionally: the composer seat rides this box's content box in
     Chat and its padding box under a view's composer overlay, so an `auto`
     gutter moves the input card sideways by the bar's width whenever the two
     differ ([decision](../../../../../../.agents/notes/implemented/bug-fix/2026-08-04-composer-tab-gutter-reservation.md)). */
  scrollbar-gutter: stable;
}

.root[data-phase='active'] .viewArea {
  flex: 1 0 auto;
  min-height: auto;
}

.root[data-phase='active'] .composerSeat {
  position: sticky;
  bottom: 0;
  /* Above markdown CodeBlock sticky banners (z-index 6) so the footer never
     paints under a sticking code header while scrolling. */
  z-index: 7;
  /* Input mask (figma 1205:27463): transcript fades out under a FIXED 36px
     band at the seat's top (the figma 24% of the resting ~150px composer),
     solid below — px stops, not %, so a growing draft only widens the solid
     region and the fade band never stretches. The 0px stop is bg-base at
     zero alpha (not white, which the figma export hardcodes) so both themes
     fade from their own base. */
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--dsw-alias-bg-base) 0%, transparent) 0px,
    var(--dsw-alias-bg-base) 36px
  );
}

/* Views may opt into a composer overlay while ConversationRoot retains
   ownership of the seat geometry and its active-phase precedence. */
.scrollBody:has([data-conversation-composer-overlay]) {
  position: relative;
  /* A clipping box nothing scrolls out of, stated as a scroll container on both
     axes rather than `overflow: hidden`: a single-axis scroller computes the
     other axis to `auto`, and the seat's absolute positioning below needs the
     box to stay a containing block in every engine. */
  overflow-x: hidden;
  overflow-y: auto;
  /* The view owns its own scrollers (the trajectory ledger scrolls inside the
     view), so this box never scrolls here; reserving a gutter would only
     narrow the view's content by the bar's width. Chat keeps the reservation
     on the same element, so the seat below compensates with the bar's width
     ([decision](../../../../../../.agents/notes/implemented/bug-fix/2026-08-04-composer-tab-gutter-reservation.md)). */
  scrollbar-gutter: auto;
}

.scrollBody:has([data-conversation-composer-overlay]) > :global([data-slot='conversation.session']) > .viewArea {
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
}

.scrollBody:has([data-conversation-composer-overlay]) > .composerSeat {
  position: absolute;
  /* Chat's seat rides this box's content box, which its own scrolling shortens
     by the bar's width; the overlay seat is against the padding box, so it
     must give back the same width to keep the input card in place across
     tabs. Reads ui-theme's --dsh-scrollbar-width, which mirrors the WebKit
     bar's layout width. Chat reserves the engine-resolved width, so on an
     engine where the resolved width differs from this fixed 8px the card
     drifts by half the difference — accepted residual risk, recorded in
     ([decision](../../../../../../.agents/notes/implemented/bug-fix/2026-08-12-composer-overlay-seat-width-compensation.md)). */
  right: var(--dsh-scrollbar-width);
  bottom: 0;
  left: 0;
}

/* Hero phase: the composer stack (hero chrome + workspace row + card) is
   flex-centered in the column; composer phase docks it at the bottom. Flex,
   NOT absolute+transform: a transform would make this box the containing
   block for position:fixed descendants (pickers/modals), shrinking them. */
.composerHero {
  position: relative; /* .heroGlow positioning context */
  align-self: center;
  /* figma 75:8208 drew 12 between all three rows; the workspace row now sits
     8 above the card (its margin-top restores 12 under the hero chrome). */
  gap: 8px;
  /* Foot inside the centered box floats the stack a bit above true center. */
  padding-bottom: 32px;
  /* Card cap + both clearances: the hero input card lands at exactly the same
     width as the docked composer at every viewport. */
  width: min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance)), 100%);
  z-index: 1;
}

/* Blue backdrop ellipse (figma 313:14109), centered on the input card: the
   card's resting center sits ~92px above the stack bottom (32 foot pad +
   half of the ~120px two-row card); width tracks the card (glow asset 1051
   vs design card 776) so blur scales in userSpace with it. z-index -1 keeps
   it behind the in-flow hero content inside this stacking context. */
.heroGlow {
  position: absolute;
  left: 50%;
  bottom: 92px;
  z-index: -1;
  width: calc(100% * 1051 / 776);
  aspect-ratio: 1051 / 468;
  transform: translate(-50%, 50%);
  pointer-events: none;
}

.heroWorkspaceRow {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  margin-top: 4px;
  /* figma drew px 8; nudged +12 so the chip's folder glyph lines up closer to
     the card's inner controls below. */
  padding-left: 20px;
}

/* Hero: the composer sits inside the session scroll body; center there so
   the tree seat matches active (sticky footer) without a Root remount. */
.root[data-phase='hero'] .scrollBody {
  justify-content: center;
  overflow-y: auto;
}

/* Settling (session replaying, hero/docked unknown): keep the composer seat
   mounted but invisible so no wrong layout flashes before the phase lands. */
.root[data-phase='settling'] .composerSeat {
  visibility: hidden;
}
