/* Phase 4 Slice 1: Transcript layout, cardless prose, code blocks, user bubbles
   planopus.md §§8.2, 8.3, 8.4, 8.7
   This sheet is active only with ?phase4=1 (media=not all otherwise). */

html.phase4 {
  --gutter: 16px;
  --turn-gap: 20px;
  --item-gap: 10px;
}

/* --------------------------------------------------------------------------
   1. Assistant Message: Cardless Prose (planopus.md §8.4)
   No card. Prose sits directly on page background.
   -------------------------------------------------------------------------- */
html.phase4 .assistant,
html.phase4 .assistant.cardless {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  animation: none !important;
  align-self: stretch;
  color: var(--ink);
  font-size: 16px;
  line-height: 24px;
}

/* Very faint paper behind assistant prose only (owner's word: keep the airy
   cardless feel). The outer .assistant stays transparent, so work cards /
   footers remain visually separate. Code blocks keep their own breakout by
   matching the padding with a negative margin. */
/* Text size (System > Settings > Text size): --text-scale on html, default 1. */
html { --text-scale: 1; }
html.phase4 .assistant .md {
  font-size: calc(16px * var(--text-scale));
  background: color-mix(in srgb, var(--surface) 45%, transparent);
  border-radius: 13px;
  padding: 8px 10px;
  box-sizing: border-box;
}

/* No content -> no paper. The live bubble and think box are created empty
   before their first delta; without this they painted a bare rounded rectangle
   above the "Thinking…" card. Probe: the empty markup has zero child nodes
   (whitespace-only deltas normalize to empty through mdToHtml), so :empty is
   the precise match. A .md holding real text — even a bare text node — keeps
   its tint. */
html.phase4 .assistant .md:empty {
  background: none !important;
  padding: 0 !important;
  border-radius: 0 !important;
}

html.phase4 .assistant .md > pre,
html.phase4 .assistant .md .codeblock {
  margin-left: -10px !important;
  margin-right: -10px !important;
}

/* Thinking card inside assistant keeps its own surface styling */
html.phase4 .assistant details.thinking {
  margin: 8px 0;
}

/* Hide legacy overlapping time pill on cardless prose */
html.phase4 .assistant .msg-speed {
  display: none !important;
}

/* Prose Typography (§8.4) */
html.phase4 .assistant .md h1,
html.phase4 .assistant.cardless h1 {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 20px;
  line-height: 26px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin-top: 16px;
  margin-bottom: 8px;
}

html.phase4 .assistant .md h2,
html.phase4 .assistant.cardless h2 {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 18px;
  line-height: 24px;
  font-weight: 600;
  color: var(--ink);
  margin-top: 14px;
  margin-bottom: 8px;
}

html.phase4 .assistant .md h3,
html.phase4 .assistant.cardless h3 {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 22px;
  font-weight: 600;
  color: var(--ink);
  margin-top: 12px;
  margin-bottom: 6px;
}

html.phase4 .assistant .md p,
html.phase4 .assistant.cardless p {
  text-wrap: pretty;
  margin-bottom: 12px;
}

html.phase4 .assistant .md p:last-child,
html.phase4 .assistant.cardless p:last-child {
  margin-bottom: 0;
}

html.phase4 .assistant .md ul,
html.phase4 .assistant .md ol {
  padding-left: 20px;
  margin-bottom: 12px;
}

html.phase4 .assistant .md li::marker {
  color: var(--accent-ink);
}

html.phase4 .assistant .md blockquote.md-quote {
  border-left: 3px solid var(--accent-soft);
  color: var(--ink-2);
  padding: 4px 0 4px 12px;
  margin: 10px 0;
  background: transparent;
  border-radius: 0;
}

html.phase4 .assistant .md a {
  color: var(--accent-ink);
  text-decoration: none;
}

html.phase4 .assistant .md a.link-open {
  cursor: default;
}

html.phase4 .assistant .md a:hover {
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   2. User Message Bubble (planopus.md §8.3)
   Right-aligned, max-width 84%, radius 20/6px, --bubble-user token.
   Collapse >12 lines with bottom fade + "Show more".
   -------------------------------------------------------------------------- */
html.phase4 .msg-user {
  align-self: flex-end;
  margin-left: auto;
  max-width: 84% !important;
  border-radius: 20px 20px 6px 20px !important;
  background: var(--bubble-user) !important;
  color: var(--on-bubble-user) !important;
  font-size: calc(16px * var(--text-scale)) !important;
  line-height: 22px !important;
  padding: 10px 14px !important;
  border: 1px solid transparent;
  word-break: break-word;
  position: relative;
  box-sizing: border-box;
}

/* Note strip inside user bubble */
html.phase4 .msg-user.msg-with-note {
  display: flex;
  flex-direction: column;
}

/* Collapsible user bubble (>12 lines) */
html.phase4 .msg-user.user-collapsible:not(.user-expanded) .user-bubble-content {
  max-height: calc(12 * 22px);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, black calc(100% - 32px), transparent 100%);
  mask-image: linear-gradient(to bottom, black calc(100% - 32px), transparent 100%);
}

html.phase4 .msg-user.user-collapsible.user-expanded .user-bubble-content {
  max-height: none;
  overflow: visible;
  -webkit-mask-image: none;
  mask-image: none;
}

html.phase4 .user-expander {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 8px;
  padding: 6px 14px;
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 13px;
  line-height: 18px;
  font-weight: 600;
  color: var(--on-bubble-user);
  background: rgb(255 255 255 / 0.16);
  border: none;
  border-radius: 999px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  min-height: 36px;
  user-select: none;
}

html.phase4 .user-expander:active {
  background: rgb(255 255 255 / 0.28);
}

/* --------------------------------------------------------------------------
   3. Code Blocks (planopus.md §8.7)
   8px side breakout, 32px header bar (lang, wrap, 44px copy),
   horizontal swipe contained (no pager slide), collapse >24 lines at 360px.
   -------------------------------------------------------------------------- */
html.phase4 .codeblock {
  position: relative;
  margin-top: 10px;
  margin-bottom: 10px;
  margin-left: -10px !important;
  margin-right: -10px !important;
  border-radius: 12px;
  background: var(--code-bg);
  color: var(--code-fg);
  border: 1px solid var(--line);
  overflow: hidden;
  overscroll-behavior-x: contain;
}

/* 44px Header Bar: holds the 44px copy button so it never overlaps line one */
html.phase4 .codeblock .code-head {
  height: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 4px 0 12px;
  background: rgb(255 255 255 / 0.04);
  border-bottom: 1px solid rgb(255 255 255 / 0.08);
  user-select: none;
}

/* Language label: mono 11 uppercase --ink-3 */
html.phase4 .codeblock .code-lang {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  line-height: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  user-select: none;
}

html.phase4 .codeblock .code-head-actions {
  display: flex;
  align-items: center;
  gap: 2px;
}

/* Wrap toggle button */
html.phase4 .codeblock .code-wrap-toggle {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-3);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 3px 8px;
  cursor: pointer;
  text-transform: lowercase;
  min-height: 28px;
  display: inline-flex;
  align-items: center;
}

html.phase4 .codeblock .code-wrap-toggle:active {
  background: rgb(255 255 255 / 0.08);
}

html.phase4 .codeblock .code-wrap-toggle.active {
  color: var(--accent);
  background: rgb(255 255 255 / 0.08);
  border-color: rgb(255 255 255 / 0.12);
}

/* 44px Copy button in header row. `relative`, not `static`: the legacy
   .code-copy::after tap-target (style.css, inset:-4px) is absolutely
   positioned, so with a *static* button its containing block became the
   .codeblock itself — an invisible 44px target stretched over the whole code
   block and swallowed every touch there, which is why a wide `pre` could not
   be swipe-scrolled sideways in the promoted app. Relative keeps the button in
   the header flow and pins the tap target back onto the button; the offsets of
   the legacy absolute rule are neutralised. */
html.phase4 .codeblock .code-copy {
  position: relative !important;
  top: auto !important;
  right: auto !important;
  width: 44px !important;
  height: 44px !important;
  min-width: 44px !important;
  min-height: 44px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: transparent !important;
  border: none !important;
  border-radius: 6px !important;
  color: var(--ink-3) !important;
  padding: 0 !important;
  margin: 0 !important;
  cursor: pointer !important;
  box-shadow: none !important;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .codeblock .code-copy:active {
  color: var(--accent) !important;
  background: rgb(255 255 255 / 0.08) !important;
}

html.phase4 .codeblock .code-copy.ok {
  color: var(--ok) !important;
}

html.phase4 .codeblock .code-copy svg {
  width: 16px;
  height: 16px;
  display: block;
}

/* Code block pre & code body */
html.phase4 .codeblock pre {
  margin: 0;
  padding: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  line-height: 20px;
  background: transparent !important;
  border: none !important;
  border-radius: 0 !important;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x pan-y;
}

html.phase4 .codeblock pre code {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  background: transparent;
  color: inherit;
  padding: 0;
  border-radius: 0;
}

html.phase4 .codeblock pre.wrapped,
html.phase4 .codeblock pre.wrapped code {
  white-space: pre-wrap !important;
  word-break: break-all;
}

/* Collapsible code blocks (>24 lines) */
html.phase4 .codeblock.code-collapsed pre {
  max-height: 360px;
  overflow-y: hidden;
  -webkit-mask-image: linear-gradient(to bottom, black calc(100% - 48px), transparent 100%);
  mask-image: linear-gradient(to bottom, black calc(100% - 48px), transparent 100%);
}

html.phase4 .codeblock.code-expanded pre {
  max-height: none;
  overflow-y: visible;
  -webkit-mask-image: none;
  mask-image: none;
}

html.phase4 .code-expander {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 36px;
  min-height: 36px;
  padding: 0 16px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  background: rgb(255 255 255 / 0.04);
  border: none;
  border-top: 1px solid rgb(255 255 255 / 0.08);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .code-expander:active {
  background: rgb(255 255 255 / 0.08);
}

/* --------------------------------------------------------------------------
   4. LiveRenderer Engine (planopus.md §10.2)
   Bottom padding synced to --composer-h, open code fence styling
   -------------------------------------------------------------------------- */
html.phase4 #feed {
  /* #composer is a flex sibling below #transcript (which already ends with its
     own 16px bottom padding in style.css), so the old --composer-h spacer left
     a full blank composer-height between the last message and the box. Keep one
     intentional gap only. */
  padding-bottom: 0;
}

html.phase4 .codeblock.code-open {
  border-color: var(--line);
}

html.phase4 .codeblock.code-open pre {
  padding: 12px;
}

/* --------------------------------------------------------------------------
   5. Turn Work Card (planopus.md §8.5)
   Container: --surface, hairline, --radius-md (14px), padding 10/12.
   Header row: 44px, orb/tool/check glyph, summary label, chevron.
   Collapsed: shows 1 live line while running; expanded: vertical timeline.
   -------------------------------------------------------------------------- */
html.phase4 #feed .work-card,
html.phase4 #feed > .work-card,
html.phase4 .work-card {
  background: var(--surface) !important;
  border: 1px solid var(--line) !important;
  border-radius: 12px !important;
  padding: 6px 10px !important;
  margin: 6px 0 !important;
  box-sizing: border-box !important;
  display: flex !important;
  flex-direction: column !important;
  user-select: none;
}

/* Compact header (owner, 2026-10-10): the whole card is the tap target, so
   the header row itself can be 32px; the collapsed trail below carries the
   three latest steps. */
html.phase4 .work-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 32px;
  height: 32px;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--ink);
  text-align: left;
  font-family: inherit;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .work-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  color: var(--ink-2);
}

html.phase4 .work-card[data-live="true"] .work-glyph {
  color: var(--accent);
}

html.phase4 .work-card:not([data-live="true"]) .work-glyph {
  color: var(--ok);
}

html.phase4 .work-summary {
  flex: 1;
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

html.phase4 .work-chev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--ink-3);
  transition: transform 0.2s cubic-bezier(0.2, 0, 0, 1);
}

html.phase4 .work-card:not(.collapsed) .work-chev {
  transform: rotate(180deg);
}

/* Collapsed live line under header */
html.phase4 .work-card.collapsed:not([data-live="true"]) .work-live-line,
html.phase4 .work-card:not(.collapsed) .work-live-line {
  display: none;
}

html.phase4 .work-card.collapsed[data-live="true"] .work-live-line {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  line-height: 18px;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Collapsed trail: latest three steps, newest first, one mono line each. */
html.phase4 .work-trail { display: none; }
html.phase4 .work-card.collapsed .work-trail:not(:empty) {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 2px 0 1px 2px;
  border-top: 1px solid var(--line);
  cursor: pointer;
}
html.phase4 .work-trail-row {
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 18px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  min-width: 0;
}
html.phase4 .trail-dot {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-3);
}
html.phase4 .work-trail-row[data-st="running"] .trail-dot { background: var(--accent); animation: trail-dot-pulse 1.2s ease-in-out infinite; }
html.phase4 .work-trail-row[data-st="ok"] .trail-dot { background: var(--ok); }
html.phase4 .work-trail-row[data-st="fail"] .trail-dot { background: var(--danger); }
@keyframes trail-dot-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { html.phase4 .work-trail-row[data-st="running"] .trail-dot { animation: none; } }
html.phase4 .trail-name { flex: none; font-weight: 600; color: var(--ink); }
html.phase4 .trail-arg { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
html.phase4 .work-trail-more {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 11.5px;
  line-height: 16px;
  color: var(--ink-3);
  padding-left: 13px;
}

/* Expanded body */
html.phase4 .work-card.collapsed .work-body {
  display: none;
}

html.phase4 .work-card:not(.collapsed) .work-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

/* Timeline */
html.phase4 .work-timeline {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

html.phase4 .work-step {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 6px 8px;
  border-radius: 8px;
  cursor: pointer;
  background: transparent;
  transition: background 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .work-step:hover,
html.phase4 .work-step:active {
  background: var(--surface-2);
}

html.phase4 .work-step.failed {
  background: rgba(180, 35, 24, 0.08) !important;
}

html.phase4 .work-step.failed:hover,
html.phase4 .work-step.failed:active {
  background: rgba(180, 35, 24, 0.14) !important;
}

html.phase4 .step-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--ink-2);
}

html.phase4 .work-step.failed .step-icon {
  color: var(--danger);
}

html.phase4 .step-main {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

html.phase4 .step-name {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 18px;
  font-weight: 600;
  color: var(--ink);
  flex-shrink: 0;
}

html.phase4 .step-arg {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  line-height: 18px;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

/* Phone widths: long step arguments and the live line wrap to two lines. */
@media (max-width: 600px) {
  html.phase4 .step-arg {
    white-space: normal;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    word-break: break-word;
  }
  html.phase4 .work-card.collapsed[data-live="true"] .work-live-line {
    white-space: normal;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    word-break: break-word;
  }
}

html.phase4 .step-dur {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-3);
  flex-shrink: 0;
}

html.phase4 .step-ts {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

html.phase4 .step-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

html.phase4 .step-status[data-st="ok"],
html.phase4 .work-step[data-st="ok"] .step-status {
  color: var(--ok);
}

html.phase4 .step-status[data-st="fail"],
html.phase4 .work-step[data-st="fail"] .step-status {
  color: var(--danger);
}

html.phase4 .step-status[data-st="running"],
html.phase4 .work-step[data-st="running"] .step-status {
  color: var(--accent);
}

/* Diff chip: +N -M */
html.phase4 .diff-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 6px;
  border-radius: 999px;
  background: var(--surface-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  font-weight: 600;
  line-height: 14px;
  color: var(--ink-2);
  flex-shrink: 0;
}

html.phase4 .diff-chip .diff-add-count {
  color: var(--ok);
}

html.phase4 .diff-chip .diff-del-count {
  color: var(--danger);
}

/* Step expander (last 6 steps shown by default) */
html.phase4 .work-card:not(.show-all-steps) .work-step.older-step {
  display: none !important;
}

html.phase4 .work-expander {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 12px;
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-ink);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  align-self: center;
  margin-top: 4px;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .work-expander:active {
  background: var(--surface-2);
}

/* --------------------------------------------------------------------------
   6. Tool Detail Sheet (planopus.md §8.6)
   -------------------------------------------------------------------------- */
html.phase4 #picker .sheet.tool-detail-sheet {
  display: flex !important;
  flex-direction: column !important;
  padding: 16px 16px calc(16px + var(--safe-bottom, 0px)) !important;
  overflow-y: auto !important;
  -webkit-overflow-scrolling: touch;
  box-sizing: border-box !important;
}

html.phase4 .tool-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  background: var(--surface);
  z-index: 2;
}

html.phase4 .tool-sheet-head-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

html.phase4 .tool-sheet-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--ink);
  flex-shrink: 0;
}

html.phase4 .tool-sheet-title-group {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

html.phase4 .tool-sheet-name {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 17px;
  line-height: 22px;
  font-weight: 600;
  color: var(--ink);
}

html.phase4 .tool-sheet-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-3);
}

html.phase4 .tool-sheet-badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
}

html.phase4 .tool-sheet-badge.ok {
  background: rgba(46, 111, 64, 0.12);
  color: var(--ok);
}

html.phase4 .tool-sheet-badge.fail {
  background: rgba(180, 35, 24, 0.12);
  color: var(--danger);
}

html.phase4 .tool-sheet-badge.running {
  background: rgba(180, 83, 9, 0.12);
  color: var(--accent);
}

html.phase4 .tool-sheet-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-2);
  border: none;
  color: var(--ink-2);
  cursor: pointer;
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .tool-sheet-close:active {
  background: var(--line-strong);
}

/* Sections */
html.phase4 .tool-sheet-section {
  margin-bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

html.phase4 .tool-sheet-sec-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

html.phase4 .tool-sheet-sec-title {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  line-height: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
}

html.phase4 .tool-sheet-copy-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 8px;
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 12px;
  color: var(--ink-2);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .tool-sheet-copy-btn:active {
  background: var(--surface-2);
}

html.phase4 .tool-sheet-pre {
  background: var(--code-bg);
  color: var(--code-fg);
  border-radius: 10px;
  padding: 10px 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  line-height: 18px;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 240px;
  overflow-y: auto;
  margin: 0;
}

/* Diff View */
html.phase4 .diff-view {
  background: var(--code-bg);
  border-radius: 10px;
  overflow: hidden;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 18px;
  max-height: 360px;
  overflow-y: auto;
}

html.phase4 .diff-line {
  display: flex;
  align-items: flex-start;
  padding: 1px 8px;
  color: var(--code-fg);
  white-space: pre-wrap;
  word-break: break-all;
}

html.phase4 .diff-line.diff-add {
  background: rgba(46, 111, 64, 0.18) !important;
  color: #a8cf94 !important;
}

html.phase4 .diff-line.diff-del {
  background: rgba(180, 35, 24, 0.18) !important;
  color: #f08a7e !important;
}

html.phase4 .diff-line.diff-same {
  background: transparent;
  color: var(--ink-3);
}

html.phase4 .diff-marker {
  display: inline-block;
  width: 14px;
  flex-shrink: 0;
  user-select: none;
  font-weight: 600;
}

html.phase4 .diff-line.diff-add .diff-marker {
  color: var(--ok);
}

html.phase4 .diff-line.diff-del .diff-marker {
  color: var(--danger);
}

html.phase4 .diff-code {
  flex: 1;
}

html.phase4 .diff-capped-notice {
  padding: 8px 12px;
  font-size: 12px;
  color: var(--warn);
  background: rgba(138, 90, 0, 0.1);
  text-align: center;
  font-weight: 500;
}

/* --------------------------------------------------------------------------
   4. Phase 4 Slice 4: Native Composer + Steer/Queue (planopus.md §8.13)
   -------------------------------------------------------------------------- */
html.phase4 #composer {
  position: relative;
  flex: none;
  background: var(--surface);
  border: 1px solid var(--line);
  overflow: visible !important;
  box-sizing: border-box;
  /* Composer bottom offset. An installed shell grows by --sb-fill below 100dvh
     (style.css html.pwa) so the status band can fill the glass strip. Phase 4
     hides #band, so #composer is the bottom-most element and its own bottom
     margin must carry that same fill — otherwise the box lands
     fill − 10px BELOW the visible bottom edge (owner: "composer sometimes hides
     below the screen bottom edge"). The device lift (home indicator, less the
     10px the pill keeps) is measured on the inset alone: --safe-bottom already
     includes --sb-fill once the strip beats env(), so it cannot be used for the
     lift. Keyboard open pins the shell to --vvh/--vv-top, so the fill does not
     apply there. */
  --p4-device-inset: max(env(safe-area-inset-bottom, 0px), var(--test-safe-bottom, 0px), var(--sb-sim, 0px));
  --p4-composer-lift: max(8px, calc(var(--p4-device-inset) - 10px));
  --p4-composer-gap: calc(var(--sb-fill, 0px) + var(--p4-composer-lift));
}
html.phase4.kb-open #composer {
  --p4-composer-gap: var(--p4-composer-lift);
}

/* The mic moved out of #tools-rail (whose column layout parked its decorative
   <small> caption under the glyph). In the row toolbar the caption would sit
   beside the SVG and read as the word "mic", so hide the caption only — the
   SVG icon, aria-label and tap target are unchanged. */
html.phase4 #composer #p4-toolbar small {
  display: none;
}

/* The default composer's radial ::before whisper behind ＋ and Send is retired
   in the modern composer. The button color itself keeps the pressed-state and
   Send-contrast signal. */
html.phase4 #composer :is(#btn-plus, #btn-send)::before {
  content: none;
}

/* Hide legacy tools rail and status band in phase4 */
html.phase4 #tools-rail,
html.phase4 #band,
html.phase4 #status {
  display: none !important;
}

/* COLLAPSED mode: 48px capsule row [+] [1-line field] [mic] */
html.phase4 #composer.collapsed {
  height: 48px;
  min-height: 48px;
  border-radius: 24px;
  margin: 0 12px var(--p4-composer-gap);
  padding: 0 6px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
}

html.phase4 #composer.collapsed .crow {
  display: flex !important;
  flex-direction: row !important;
  align-items: center !important;
  width: 100% !important;
  height: 48px !important;
  gap: 4px !important;
}

html.phase4 #composer.collapsed #p4-toolbar {
  display: contents !important;
}

html.phase4 #composer #agent-run {
  order: 0 !important;
  width: 32px !important;
  height: 32px !important;
  min-height: 32px !important;
  border-radius: 50% !important;
  flex-shrink: 0 !important;
}
html.phase4 #composer.collapsed #btn-plus {
  order: 1 !important;
  /* style.css leaves #btn-plus at align-self: flex-start (the v1 resting pill
     wants that). In the phase 4 row it parked ＋ 6px above the pill centreline
     while mic/input/agent chip stayed centred. */
  align-self: center !important;
  width: 36px !important;
  height: 36px !important;
  min-height: 36px !important;
  border-radius: 50% !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--ink-2) !important;
  background: transparent !important;
  border: none !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  font-size: 20px !important;
  padding: 0 !important;
}

html.phase4 #composer.collapsed #input {
  order: 2 !important;
  flex: 1 1 auto !important;
  height: 32px !important;
  min-height: 32px !important;
  max-height: 32px !important;
  line-height: 20px !important;
  padding: 6px 8px !important;
  font-size: 15px !important;
  border: none !important;
  outline: none !important;
  box-shadow: none !important;
  resize: none !important;
  overflow: hidden !important;
  white-space: nowrap !important;
  text-overflow: ellipsis !important;
  background: transparent !important;
  color: var(--ink) !important;
  box-sizing: border-box !important;
}

html.phase4 #composer.collapsed #btn-mic {
  order: 3 !important;
  width: 36px !important;
  height: 36px !important;
  min-height: 36px !important;
  border-radius: 50% !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--ink-2) !important;
  background: transparent !important;
  border: none !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  padding: 0 !important;
}

html.phase4 #composer.collapsed #btn-stop {
  order: 3 !important;
  width: 36px !important;
  height: 36px !important;
  min-height: 36px !important;
  border-radius: 50% !important;
  display: none;
  align-items: center !important;
  justify-content: center !important;
  color: var(--danger) !important;
  background: var(--surface-2) !important;
  border: none !important;
  cursor: pointer !important;
  position: relative !important;
  flex-shrink: 0 !important;
  padding: 0 !important;
}

html.phase4 #composer.collapsed.running-empty #btn-mic {
  display: none !important;
}

html.phase4 #composer.collapsed.running-empty #btn-stop {
  display: inline-flex !important;
}

/* Collapsed row keeps the model chip (empty field = room between the input and
   the mic) so model/effort is visible without focusing the field. */
html.phase4 #composer.collapsed .p4-meta-group {
  order: 3 !important;
  display: inline-flex !important;
  align-items: center !important;
  flex: 0 1 auto !important;
  min-width: 0 !important;
  overflow: hidden !important;
}
html.phase4 #composer.collapsed .p4-model-chip {
  max-width: 112px !important;
  height: 26px !important;
  font-size: 11.5px !important;
}
/* The label span must ellipsize itself; otherwise its box runs past the
   chip (clipped, but still "overflowing" to layout checks). */
/* Small chevron (replaces the old ▾ glyph in the label) */
html.phase4 .p4-model-chip::after {
  content: '';
  flex: 0 0 auto;
  width: 5px;
  height: 5px;
  margin: -2px 0 0 1px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.65;
}
html.phase4 .p4-model-chip #p4-model-name {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Hide other toolbar items in collapsed */
html.phase4 #composer.collapsed .p4-ctx-ring,
html.phase4 #composer.collapsed .p4-spacer,
html.phase4 #composer.collapsed #char-count,
html.phase4 #composer.collapsed #btn-queue,
html.phase4 #composer.collapsed #btn-send,
html.phase4 #composer.collapsed #btn-steer {
  display: none !important;
}

/* EXPANDED mode: radius 22, field-sizing: content, 1-8 lines, 40px toolbar */
html.phase4 #composer.expanded {
  height: auto !important;
  min-height: auto !important;
  max-height: none !important;
  border-radius: 22px !important;
  margin: 0 12px var(--p4-composer-gap) !important;
  padding: 8px 12px 6px !important;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
  display: flex !important;
  flex-direction: column !important;
}

html.phase4 #composer.expanded .crow {
  display: flex !important;
  flex-direction: column !important;
  width: 100% !important;
  gap: 4px !important;
}

html.phase4 #composer.expanded #input {
  order: 1 !important;
  width: 100% !important;
  field-sizing: content;
  min-height: 28px !important;
  max-height: 176px !important; /* 8 lines @ 22px */
  line-height: 22px !important;
  font-size: 16px !important;
  padding: 4px 4px !important;
  border: none !important;
  outline: none !important;
  box-shadow: none !important;
  resize: none !important;
  overflow-y: auto !important;
  white-space: pre-wrap !important;
  background: transparent !important;
  color: var(--ink) !important;
  box-sizing: border-box !important;
}

/* 40px toolbar row. min-width: 0 lets the row shrink with the box instead of
   keeping its content width — without it the row stayed wider than the composer
   at 390px (owner bug: Queue/Steer painted outside the rounded box). */
html.phase4 #composer.expanded #p4-toolbar {
  order: 2 !important;
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
  height: 40px !important;
  min-height: 40px !important;
  max-height: 40px !important;
  width: 100% !important;
  min-width: 0 !important;
  gap: 6px !important;
}

/* Entry fade runs on the collapsed -> expanded transition only (JS adds
   .p4-toolbar-in once and drops it on animationend). Re-running it on every
   live repaint read as a flicker. */
html.phase4 #composer.expanded #p4-toolbar.p4-toolbar-in {
  animation: p4-toolbar-fade 0.15s ease-out;
}

/* Keyboard up while typing: drop the model/ctx meta group so ＋, mic, Queue and
   Steer stay reachable in one compact row above the keyboard. */
html.phase4.kb-open #composer.expanded .p4-meta-group {
  display: none !important;
}

/* Row fit (owner bug: keyboard up but html.kb-open not set — an installed iOS
   shell shrinks window.innerHeight together with the visual viewport, so the
   old detector could not see the keyboard — left the model/ctx meta group in the
   row, the row grew wider than the box and #composer { overflow: visible }
   painted Queue and Steer OUTSIDE the rounded background). The row must fit at
   any width without help from the kb-open class:
     1. the meta group is the only shrinkable group, so it yields before any
        control can leave the box,
     2. when even its natural width does not fit, JS marks the composer
        .p4-tight  -> ctx ring hidden, model chip capped,
        .p4-tighter -> the whole meta group drops,
        .p4-tightest -> the Queue pill drops to its icon (small phones).
   .p4-natural is the JS measuring state (meta at its natural width). */
html.phase4 #composer.expanded.p4-natural .p4-meta-group {
  flex: 0 0 auto !important;
}
html.phase4 #composer.expanded.p4-tight .p4-ctx-ring {
  display: none !important;
}
html.phase4 #composer.expanded.p4-tight .p4-model-chip {
  max-width: 92px !important;
}
html.phase4 #composer.expanded.p4-tighter .p4-meta-group {
  display: none !important;
}
html.phase4 #composer.expanded.p4-tightest #btn-queue {
  width: 32px !important;
  padding: 0 !important;
  justify-content: center !important;
}
html.phase4 #composer.expanded.p4-tightest #btn-queue span {
  display: none !important;
}

/* Docked actions tray (owner change, §8.13). In-flow row at the top of the
   composer: the composer grows by exactly this row, so --composer-h and the
   last-message padding stay correct. No scrim, no modal sheet. Horizontal
   scroll at 390px, never wraps to two rows. */
html.phase4 #composer .p4-action-tray {
  order: 0 !important;
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
  gap: 6px !important;
  width: 100% !important;
  padding: 4px 0 8px !important;
  margin: 0 !important;
  overflow-x: auto !important;
  overflow-y: hidden !important;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
html.phase4 #composer .p4-action-tray::-webkit-scrollbar {
  display: none;
}
html.phase4 #composer .p4-action-tray[hidden] {
  display: none !important;
}
html.phase4 #composer .p4-tray-btn {
  display: inline-flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 3px !important;
  flex: 0 0 auto !important;
  min-width: 64px !important;
  min-height: 52px !important;
  padding: 6px 8px !important;
  border: 1px solid var(--line) !important;
  border-radius: 14px !important;
  background: var(--surface-2) !important;
  color: var(--ink-2) !important;
  font-size: 11px !important;
  font-weight: 600 !important;
  line-height: 1.1 !important;
  cursor: pointer !important;
  -webkit-tap-highlight-color: transparent;
}
html.phase4 #composer .p4-tray-btn .ico {
  width: 20px !important;
  height: 20px !important;
}
html.phase4 #composer .p4-tray-btn:active {
  background: var(--line) !important;
}
html.phase4 #composer #btn-plus.on {
  color: var(--accent) !important;
}

@keyframes p4-toolbar-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

html.phase4 #composer.expanded #btn-plus {
  order: 1 !important;
  /* Same flex-start reset as the collapsed pill; without it ＋ sat 2px above
     the Send/mic centreline in the 40px toolbar row. */
  align-self: center !important;
  width: 36px !important;
  height: 36px !important;
  min-height: 36px !important;
  border-radius: 50% !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  position: relative !important;
  color: var(--ink-2) !important;
  background: var(--surface-2) !important;
  border: none !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  font-size: 20px !important;
  line-height: 1 !important;
  padding: 0 !important;
}

/* ＋ matches Send's 36px box; the ::after gives a 44px hit target without
   growing the 40px toolbar row. */
html.phase4 #composer.expanded #btn-plus::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
}

html.phase4 #composer.expanded .p4-meta-group {
  order: 2 !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  /* The yield valve of the row: shrinkable (never flex-shrink: 0) and clipped,
     so a tight box ellipsizes the model chip instead of pushing a control out. */
  flex: 0 1 auto !important;
  min-width: 0 !important;
  overflow: hidden !important;
}

html.phase4 .p4-model-chip {
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
  height: 26px !important;
  padding: 0 7px 0 8px !important;
  border-radius: 13px !important;
  background: var(--surface-2) !important;
  border: 1px solid var(--line) !important;
  color: var(--ink-2) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  cursor: pointer !important;
  max-width: 140px !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  /* min-width: 0 lets the chip ellipsize inside the shrinking meta group. */
  flex: 0 1 auto !important;
  min-width: 0 !important;
}

html.phase4 .p4-ctx-ring {
  display: inline-flex !important;
  align-items: center !important;
  flex: 0 0 auto !important;
  gap: 3px !important;
  height: 28px !important;
  padding: 0 6px !important;
  border-radius: 14px !important;
  background: var(--surface-2) !important;
  color: var(--ink-3) !important;
  font-size: 11px !important;
  font-family: var(--mono) !important;
  font-weight: 600 !important;
  cursor: pointer !important;
}

html.phase4 #composer.expanded .p4-spacer {
  order: 3 !important;
  flex: 1 1 auto !important;
  min-width: 0 !important;
}

html.phase4 #composer.expanded #char-count {
  order: 4 !important;
  /* Never shrinks: the >2,000 warning is a nowrap number and must not be
     squeezed under a control. The meta group yields first. */
  flex: 0 0 auto !important;
  font-size: 11px !important;
  font-family: var(--mono) !important;
  color: var(--ink-3) !important;
  white-space: nowrap !important;
  padding: 0 4px !important;
  display: inline-block !important;
}

html.phase4 #composer.expanded #btn-mic {
  order: 5 !important;
  width: 32px !important;
  height: 32px !important;
  min-height: 32px !important;
  border-radius: 50% !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: var(--ink-2) !important;
  background: transparent !important;
  border: none !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  padding: 0 !important;
}

html.phase4 #composer.expanded #btn-queue {
  order: 6 !important;
  height: 32px !important;
  padding: 0 10px !important;
  border-radius: 16px !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 4px !important;
  background: var(--surface-2) !important;
  border: 1px solid var(--line) !important;
  color: var(--ink) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
}

html.phase4 #composer.expanded #btn-send {
  order: 7 !important;
  width: 36px !important;
  height: 36px !important;
  min-height: 36px !important;
  border-radius: 50% !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: var(--accent) !important;
  color: #fff !important;
  border: none !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  padding: 0 !important;
}

/* Mode toggles set the hidden attribute. Author !important display above must not paint a hidden button. */
html.phase4 #composer.expanded #btn-send[hidden],
html.phase4 #composer.expanded #btn-stop[hidden],
html.phase4 #composer.expanded #btn-queue[hidden] {
  display: none !important;
}

html.phase4 #composer.expanded #btn-send.steer {
  background: var(--accent) !important;
  color: #fff !important;
}

html.phase4 #composer.expanded #btn-send:disabled {
  background: var(--surface-2) !important;
  color: var(--ink-3) !important;
  opacity: 0.5 !important;
  cursor: default !important;
}

html.phase4 #composer.expanded #btn-stop {
  order: 7 !important;
  width: 36px !important;
  height: 36px !important;
  min-height: 36px !important;
  border-radius: 50% !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: var(--surface-2) !important;
  color: var(--danger) !important;
  border: none !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  padding: 0 !important;
  position: relative !important;
}

/* One 44px hit target for every composer button (same idiom as #btn-plus):
   the ::after grows the tap area without growing the 40px toolbar row. */
html.phase4 #composer #btn-mic,
html.phase4 #composer #btn-send,
html.phase4 #composer #btn-stop,
html.phase4 #composer #btn-queue { position: relative; }
html.phase4 #composer #btn-mic::after,
html.phase4 #composer #btn-send::after,
html.phase4 #composer #btn-stop::after,
html.phase4 #composer #btn-queue::after {
  content: '';
  position: absolute;
  /* Not past the right edge: an abs box that pokes out there counts toward the
     toolbar's scrollWidth and makes the row-fit tiers think the row overflows
     (meta group would be dropped). Left/top/bottom still grow the target. */
  inset: -4px 0 -4px -4px;
  border-radius: 50%;
}

/* Action Sheet styles */
html.phase4 .p4-action-sheet .m-title {
  font-size: 17px !important;
  font-weight: 600 !important;
  margin-bottom: 12px !important;
}

html.phase4 .p4-action-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px 8px;
  padding: 8px 0 16px;
}

html.phase4 .p4-action-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px 4px 10px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .p4-action-tile:active {
  transform: scale(0.95);
  background: var(--line-strong);
}

html.phase4 .p4-action-tile svg {
  width: 24px;
  height: 24px;
  color: var(--accent);
}

html.phase4 .p4-action-tile span {
  font-size: 11px;
  font-weight: 500;
  color: var(--ink);
  text-align: center;
  line-height: 1.2;
}

html.phase4 .p4-team-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  background: var(--surface-2);
  border-radius: 12px;
  margin: 4px 0 16px;
}

html.phase4 .p4-team-label {
  display: flex;
  flex-direction: column;
}

html.phase4 .p4-team-label strong {
  font-size: 14px;
  color: var(--ink);
}

html.phase4 .p4-team-label small {
  font-size: 12px;
  color: var(--ink-2);
}

html.phase4 .p4-switch {
  width: 44px;
  height: 26px;
  accent-color: var(--accent);
}

/* Slash Popover styles */
html.phase4 .p4-slash-popover {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 12px;
  right: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);
  max-height: 240px;
  overflow-y: auto;
  z-index: 100;
  display: flex;
  flex-direction: column;
  padding: 6px;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

html.phase4 .p4-slash-popover[hidden] {
  display: none !important;
}

html.phase4 .p4-slash-head {
  padding: 4px 8px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--ink-3);
  letter-spacing: 0.05em;
}

html.phase4 .p4-slash-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 6px 10px;
  border-radius: 8px;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  width: 100%;
  -webkit-tap-highlight-color: transparent;
}

html.phase4 .p4-slash-item:hover,
html.phase4 .p4-slash-item:active {
  background: var(--surface-2);
}

html.phase4 .p4-slash-name {
  font-size: 13px;
  color: var(--ink);
  font-family: var(--mono);
}

html.phase4 .p4-slash-desc {
  font-size: 11px;
  color: var(--ink-2);
}

/* --------------------------------------------------------------------------
   Live Subtitle (planopus.md §7.6)
   12/16 system-ui, --ink-2, state dot/needs-input styling.
   -------------------------------------------------------------------------- */
html.phase4 .sess-sub-cwd {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

html.phase4 .sess-sub-cwd.needs-input {
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   Jump Pill Capsule (planopus.md §8.12)
   Surface, hairline, shadow, 44px hit target, centered floating above composer.
   -------------------------------------------------------------------------- */
html.phase4 #btn-scroll-bot {
  position: absolute;
  bottom: calc(var(--bot-h, 60px) + 12px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 35;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  height: 44px;
  padding: 0 16px;
  border-radius: 22px;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  color: var(--ink);
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  box-sizing: border-box;
}

html.phase4 #btn-scroll-bot[hidden] {
  display: none !important;
}

html.phase4 #btn-scroll-bot:active {
  background: var(--surface-2);
}

html.phase4 #btn-scroll-bot.live {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

html.phase4 #btn-scroll-bot.has-new {
  color: var(--ink);
  border-color: var(--accent);
}

/* --------------------------------------------------------------------------
   Slim Todo Strip (planopus.md §8.11)
   Slim strip above the composer: 3/7 · <current item> + 2px progress fill.
   -------------------------------------------------------------------------- */
html.phase4 #todo-strip {
  display: flex;
  align-items: center;
  position: relative;
  overflow: hidden;
  height: 28px;
  min-height: 28px;
  margin: 0 12px 6px;
  padding: 0 12px;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  flex: none;
  box-sizing: border-box;
}

html.phase4 #todo-strip[hidden] {
  display: none !important;
}

html.phase4 .todo-strip-text {
  font-family: system-ui, -apple-system, sans-serif;
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1 1 auto;
  text-align: left;
}

html.phase4 .todo-strip-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--line);
}

html.phase4 .todo-strip-fill {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 0 1px 1px 0;
  transition: width 0.2s ease;
}

/* Phase 4 Transcript: Date separators, Unread divider, Assistant footer, User bubble actions */
html.phase4 .p4-date-sep {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 16px auto;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-3);
  text-align: center;
  user-select: none;
}

html.phase4 .p4-unread-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 20px 0;
  color: var(--accent-ink);
  font-size: 12px;
  font-weight: 500;
  text-align: center;
  user-select: none;
}
html.phase4 .p4-unread-divider::before,
html.phase4 .p4-unread-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
}

html.phase4 .assistant .p4-asst-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
  padding: 4px 0;
  border-top: 1px solid var(--line);
}
html.phase4 .assistant:not(:last-of-type):not(.p4-footer-open) .p4-asst-footer {
  display: none !important;
}
html.phase4 .assistant:last-of-type .p4-asst-footer,
html.phase4 .assistant.p4-footer-open .p4-asst-footer {
  display: flex !important;
}
html.phase4 .p4-asst-metrics {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 16px;
  color: var(--ink-3);
}
html.phase4 .p4-asst-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}
html.phase4 .p4-footer-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  border-radius: 8px;
}
html.phase4 .p4-footer-btn:active {
  background: var(--surface2, rgba(0, 0, 0, 0.06));
}

html.phase4 .turn-meta {
  display: none !important;
}
html.phase4 .msg-user .p4-user-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 6px;
  padding-top: 4px;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  user-select: none;
}
html.phase4 .msg-user .p4-user-actions[hidden] {
  display: none !important;
}
html.phase4 .p4-user-time {
  font-family: var(--mono);
  font-size: 11px;
  opacity: 0.75;
  margin-right: auto;
}
html.phase4 .p4-user-act-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: none;
  background: transparent;
  color: inherit;
  opacity: 0.85;
  cursor: pointer;
  border-radius: 8px;
}
html.phase4 .p4-user-act-btn:active {
  opacity: 1;
  background: rgba(255, 255, 255, 0.12);
}

/* stream.js reuses the legacy .code-copy class on the reply footer and the user
   bubble action buttons. style.css:1985 pins .code-copy absolute top/right,
   which floated Copy over every assistant reply (and reserved its space as
   fake right padding). These are row buttons, not overlays — pin them static
   and drop the code-copy border. The code-block copy button
   (.codeblock .code-copy) is intentionally left where it is. */
html.phase4 :is(.p4-footer-btn, .p4-user-act-btn) {
  position: relative !important;
  top: auto !important;
  right: auto !important;
  border: none !important;
}

/* The legacy 4px tap-target growth (style.css .code-copy::after, inset:-4px)
   existed to lift a 36px box to 44px. The phase-4 copy/footer buttons are
   already 44px boxes, and `position: relative` above is what bounds the
   pseudo to them at all — an expanding inset would then just overlap the
   neighbouring control (the wrap toggle in the code header, the next action in
   a footer row), so there is nothing left to grow. */
html.phase4 :is(.codeblock .code-copy, .p4-footer-btn, .p4-user-act-btn)::after {
  inset: 0;
}





/* --------------------------------------------------------------------------
   Nested horizontal scrollers own the sideways swipe (owner bug, planopus
   §8.8). A wide table or a wide code block is its own horizontal scroller, but
   the pager is a native horizontal scroll-snap container, so a sideways drag
   that starts inside one of them used to escape to the pager and flip the page
   to Sessions — on iPhone most of all, and only while the answer was still
   arriving.

   Three layers, deliberately overlapping:

   1. containment on the nested scroller: overscroll-behavior-x: contain stops
      the browser from chaining the drag to the pager once the table/code has
      reached its own left or right edge, and touch-action keeps both axes
      alive inside it (a vertical drag still scrolls the transcript);
   2. the arrival fade is neutralised for a tail block that IS the scroller
      (see stream.js triggerInkFlash): `.p4-tail.p4-arrive` animates
      `transform`, and an animated transform on the parent of a nested scroller
      makes iOS Safari stop treating the pane as scrollable by touch. That is
      the live-paint-only difference — a reopened session has no tail and
      therefore no transform;
   3. `html #pager.pager-hscroll` is the gesture-window lock pager.js adds on
      touchstart inside an overflowing scroller and removes on
      touchend/touchcancel, because iOS does not always honour
      overscroll-behavior on a nested scroller of a scroll-snap parent.
   -------------------------------------------------------------------------- */
html.phase3 :is(.md-table-wrap, #transcript .codeblock pre),
html.phase4 :is(.md-table-wrap, #transcript .codeblock pre) {
  overflow-x: auto;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  touch-action: pan-x pan-y;
}

/* pager.js adds this class for the length of one gesture that began inside an
   overflowing table / code block. `overflow-x: hidden` (also set inline) makes
   the pager itself unscrollable sideways for that gesture, so a drag that runs
   past the inner scroller's edge has nowhere to chain to. Vertical panning is
   untouched, and scrollLeft — and so the current snap page — is preserved. */
html.phase3 #pager.pager-hscroll,
html.phase4 #pager.pager-hscroll,
html.phase5 #pager.pager-hscroll {
  overflow-x: hidden;
}

/* Layer 2 as pure CSS (higher specificity than `.p4-tail.p4-arrive` in
   phase4-motion.css, so it wins wherever it is loaded). Prose tails keep the
   fade; a table / code fence tail keeps its touch scrolling. */
html.phase4 :is(.p4-tail.p4-arrive, .p4-tail):is(.md-table-wrap, .tbl-wrap, .codeblock) {
  animation: none;
  transform: none;
}

/* A reply with no measured duration keeps its footer (time, Copy, Copy with
   session details) folded until the reply is tapped. */
html.phase4 .assistant:not(.p4-footer-open) .p4-asst-footer.p4-footer-bare {
  display: none !important;
}
