/* Pod chat · states the d215 frame does not draw (S3d, D223 lift). Every rule here moved out of v2.css unchanged: empty and starter states, catch-up, delivery hints, cards and other chat-only surfaces the frame has not drawn yet. Redraw them here when a frame lands. Imported by V2App.tsx after chat-inspector.css. */ /* Catch-up strip — the constant agents-TL;DR pinned above the transcript /* Catch-up strip — the constant agents-TL;DR pinned above the transcript (2026-09-01). One thin row; the expanded body is bounded so a long summary scrolls inside the strip, never the pane. */ .v2-catchup { border-bottom: 1px solid var(--v2-border); background: var(--v2-surface); padding: 6px 20px; font-size: 13px; } .v2-catchup__row { display: flex; align-items: center; gap: 10px; min-width: 0; } .v2-root button.v2-catchup__toggle { background: transparent; border: none; padding: 0; font-size: 13px; font-weight: 650; color: var(--v2-text-secondary); cursor: pointer; white-space: nowrap; } .v2-root button.v2-catchup__toggle:hover:not(:disabled) { color: var(--v2-text-primary); } .v2-root button.v2-catchup__toggle:disabled { cursor: default; } .v2-catchup__chevron { display: inline-block; margin-right: 4px; transition: transform 0.08s ease; } .v2-catchup__chevron--open { transform: rotate(90deg); } .v2-catchup__time { font-weight: 400; color: var(--v2-text-tertiary); } .v2-catchup__snippet { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--v2-text-tertiary); } .v2-root button.v2-catchup__refresh { background: transparent; border: none; padding: 0; font-size: 12px; color: var(--v2-accent); cursor: pointer; white-space: nowrap; } .v2-root button.v2-catchup__refresh:hover:not(:disabled) { text-decoration: underline; } .v2-root button.v2-catchup__refresh:disabled { color: var(--v2-text-tertiary); cursor: default; } .v2-root button.v2-catchup__dismiss { background: transparent; border: none; padding: 0 2px; font-size: 14px; line-height: 1; color: var(--v2-text-tertiary); cursor: pointer; } .v2-root button.v2-catchup__dismiss:hover { color: var(--v2-text-primary); } .v2-catchup__body { margin-top: 6px; max-height: 220px; overflow-y: auto; white-space: pre-wrap; color: var(--v2-text-secondary); line-height: 1.5; } /* Sender-only teaching cue shown once per pod/session when a message reaches a pod with agents but addresses none of them. Aligns with message text, stays quiet/secondary, and disappears naturally with transcript scroll. Box geometry is NOT here: it belongs to the side-row slot rule below, which this row shares with the no-agent row. */ .v2-chat__delivery-hint { color: var(--v2-text-tertiary); font-size: 12px; line-height: 1.4; } .v2-chat__delivery-hint strong { color: var(--v2-ink); font-weight: 600; } /* The transcript's two side-rows — the sender-only delivery cue above and the no-agent row below — occupy ONE slot, and that slot IS the message text column of the transcript they sit in. Both are siblings of `.v2-msg` inside `.v2-chat__messages`, so the indent is the avatar track plus the gap of the rule that governs those rows HERE, which is the thread override `.v2-thread .v2-msg { grid-template-columns: 28px minmax(0, 1fr); gap: 8px }` — 28 + 8 = 36, NOT the base `.v2-msg` grid (38 + 12 = 50), which that override replaces (0,3,0 beats 0,1,0). The first cut of this rule derived from the base grid and was 14px out; ux-lead's #1860 gate measured it at 390, 720 and 1440 — 50px put both rows 14px right of `.v2-msg__content`, 36px put them on it (injection on their fixture, right edge and scrollWidth unchanged). Both placements of these rows share their message's container (transcript level, or inside a `.v2-thread-block` for a thread root), so the same relative indent holds in both. The width subtracts the same indent: `.v2-chat__messages > *` sets width: 100%, so an indent without its complement overruns the pane by exactly the indent. That was the #1846 defect — at 390 the full-width act ran 64→426 and the body line was cut (ux-lead's shot, 2026-09-23) — and the same class one indent over on `.v2-thread-block` (2026-08-24): indent + width must sum to 100%. One rule for both rows, so they cannot drift apart again: this is the only place either row's box is declared, and v2-layout-invariants.test.ts derives the expected indent from `.v2-thread .v2-msg`'s own grid, so moving that column fails the suite instead of silently misaligning these rows. */ .v2-chat__delivery-hint, .v2-chat__no-agents, .v2-chat__starts { width: calc(100% - 48px); margin: -4px 0 8px 48px; } /* The delivery hint above requires an agent to name (`agentsInPod > 0`), which leaves out the pod where nothing can answer at all — a team pod with no agent installed. This row sits in the same slot under the sent message, says why the send went quiet, and carries the one step that changes it. Ink and tint only: nothing here succeeded, and no accent or toast should say otherwise. */ .v2-chat__no-agents { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; /* Box geometry lives in the shared side-row slot rule above, next to the delivery cue it shares the slot with. */ } .v2-chat__no-agents-kicker { color: var(--v2-text-tertiary); font-family: var(--v2-font-mono); font-size: 11px; font-weight: 500; line-height: 16px; text-transform: lowercase; } .v2-chat__no-agents-body { color: var(--v2-text-secondary); font-size: 12px; line-height: 1.4; } .v2-root button.v2-chat__no-agents-action { min-height: 32px; padding: 0 12px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius); background: var(--v2-surface); color: var(--v2-text-primary); font-size: 12px; font-weight: 600; transition: background 80ms ease, border-color 80ms ease; } .v2-root button.v2-chat__no-agents-action:hover { background: var(--v2-surface-hover); } /* Scout's starts (first session, direction B, ruled 2026-10-15): the welcome's offers, one bordered button per start, in one column at one width so they read as a set. A click sends the start as the person's own message. Box geometry lives in the shared side-row slot rule above. */ .v2-chat__starts { display: grid; grid-template-columns: minmax(0, max-content); gap: 6px; } .v2-root button.v2-chat__start { min-height: 32px; padding: 6px 12px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius); background: var(--v2-surface); color: var(--v2-text-primary); font-size: 13px; font-weight: 500; line-height: 1.35; text-align: left; white-space: normal; transition: background 80ms ease, border-color 80ms ease; } .v2-root button.v2-chat__start:hover:not(:disabled) { background: var(--v2-surface-hover); border-color: var(--v2-border-strong); } .v2-root button.v2-chat__start:disabled { opacity: 0.6; cursor: default; } /* TASK-647 item 4: the run-hosted start is the screen's one filled action. Keyed on the action in the component, not on its position. */ .v2-root button.v2-chat__start.v2-chat__start--primary { background: var(--v2-ink); border-color: var(--v2-ink); color: var(--v2-on-ink); font-weight: 600; } .v2-root button.v2-chat__start.v2-chat__start--primary:hover:not(:disabled) { background: var(--v2-ink-hover); border-color: var(--v2-ink-hover); } /* A line that belongs to the start above it: the hosted start's beta limits, or why it could not start. Same slot and size as the delivery hint. */ .v2-chat__start-note { margin: -2px 0 2px; color: var(--v2-text-tertiary); font-size: 12px; line-height: 1.4; } .v2-chat__start-note--error { color: var(--v2-danger); } @media (max-width: 760px) { /* The row's single act is a touch target on a phone: full width of the row, 44 tall. This must override the MINIMUM, not a height — a `height` here would lose to the base rule's own min-height and render 32 (TASK-140). */ .v2-root button.v2-chat__no-agents-action { width: 100%; min-height: 44px; } /* Scout's starts are touch targets too: 44 tall on a phone, as drawn. */ .v2-root button.v2-chat__start { min-height: 44px; } } .v2-chat__error { padding: 9px 12px; border-radius: 8px; background: rgba(239, 68, 68, 0.08); color: var(--v2-danger); font-size: 12px; border: 1px solid rgba(239, 68, 68, 0.16); } /* A 1:1 agent room must not make a successful POST look like an active agent. The liveness row is deliberately adjacent to, but outside, the composer: it remains visible while someone writes and never becomes part of the scrollable transcript. */ .v2-chat__agent-room-status { margin: 8px 24px 0; padding: 8px 10px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius-sm); background: var(--v2-bg-subtle); color: var(--v2-text-secondary); font-size: 12px; line-height: 1.4; } .v2-chat__agent-room-command { display: block; margin-top: 4px; font-family: var(--v2-font-mono, ui-monospace, monospace); overflow-wrap: anywhere; user-select: all; } .v2-chat__agent-room-status--wait { border-color: var(--v2-border); background: var(--v2-surface-hover); color: var(--v2-text-secondary); font-family: var(--v2-font-mono); font-weight: 500; } .v2-chat__agent-room-status-dot { width: 6px; height: 6px; flex: 0 0 auto; border-radius: 50%; background: var(--v2-success); } .v2-chat__agent-room-status--timeout { border-color: var(--v2-border-strong); background: var(--v2-bg-subtle); color: var(--v2-text-secondary); font-weight: 500; } .v2-chat__starter-prompts { display: flex; flex-wrap: wrap; gap: 8px; /* Part of the conversation column: siblings of the messages list share its full pane width and left edge (rule 2 v5, full-width) — a second edge here recreates the v1 island. max-width keeps the mobile-shrink property the 390px pane needs. */ width: 100%; max-width: 100%; margin-inline: 0; padding: 10px 24px 0; background: var(--v2-surface); flex-shrink: 0; } .v2-chat__new-pod { align-self: center; width: min(760px, 100%); margin: auto; padding: 24px; border: 1px solid var(--v2-border-strong); border-radius: var(--v2-radius-lg); background: var(--v2-bg-subtle); } .v2-chat__new-pod-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; } .v2-chat__new-pod-title { color: var(--v2-text-primary); font-size: 20px; font-weight: 700; letter-spacing: -0.02em; } .v2-root button.v2-chat__new-pod-dismiss { display: grid; flex: 0 0 auto; width: 28px; height: 28px; place-items: center; border-radius: var(--v2-radius-sm); color: var(--v2-text-tertiary); } .v2-root button.v2-chat__new-pod-dismiss:hover { background: var(--v2-surface-hover); color: var(--v2-text-primary); } .v2-chat__new-pod-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; } .v2-root button.v2-chat__new-pod-action, .v2-chat__new-pod-action { display: flex; min-width: 0; min-height: 88px; flex-direction: column; align-items: flex-start; gap: 5px; padding: 12px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius); background: var(--v2-surface); color: var(--v2-text-primary); text-align: left; } .v2-root button.v2-chat__new-pod-action { transition: background 80ms ease, border-color 80ms ease; } .v2-root button.v2-chat__new-pod-action:hover { background: var(--v2-surface-hover); } .v2-root button.v2-chat__new-pod-action--hosted { background: var(--v2-ink); color: var(--v2-on-ink); font-weight: 600; } .v2-root button.v2-chat__new-pod-action--hosted:hover { background: var(--v2-ink-hover); } .v2-root button.v2-chat__new-pod-action--hosted:disabled { opacity: 0.7; } .v2-chat__new-pod-action-title { color: var(--v2-text-primary); font-size: 13px; font-weight: 700; } .v2-chat__new-pod-status { color: var(--v2-text-secondary); font-size: 11px; line-height: 1.4; } .v2-chat__new-pod-action--invite .v2-invite-link-row { width: 100%; margin-top: auto; } .v2-root button.v2-chat__new-pod-copy { flex: 0 0 auto; padding: 0 10px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius-sm); background: var(--v2-surface); color: var(--v2-accent-text); font-size: 11px; font-weight: 700; } .v2-chat__new-pod-action--invite > .v2-chat__new-pod-copy { min-height: 32px; margin-top: auto; } @media (max-width: 760px) { .v2-chat__new-pod-action--invite > .v2-chat__new-pod-copy { min-height: 44px; } } .v2-root button.v2-chat__new-pod-copy:hover { background: var(--v2-surface-hover); } .v2-chat__new-pod-error { display: flex; align-items: center; gap: 8px; margin-top: auto; color: var(--v2-danger); font-size: 11px; } .v2-root .v2-chat__new-pod-error button { flex: 0 0 auto; color: var(--v2-accent-text); font-size: 11px; font-weight: 700; } .v2-root button.v2-chat__starter-prompt { min-width: 0; max-width: 100%; padding: 7px 11px; border: 1px solid var(--v2-border); border-radius: var(--v2-radius-pill); background: var(--v2-surface); color: var(--v2-text-secondary); font-size: 12px; font-weight: 600; line-height: 1.35; text-align: left; white-space: normal; transition: background 80ms ease, border-color 80ms ease, color 80ms ease; } .v2-root button.v2-chat__starter-prompt:hover { background: var(--v2-surface-hover); } @media (max-width: 700px) { .v2-chat__new-pod { padding: 16px; } .v2-chat__new-pod-actions { grid-template-columns: minmax(0, 1fr); } .v2-root button.v2-chat__new-pod-action, .v2-chat__new-pod-action { min-height: 0; } } /* Read-only banner shown in place of the composer when the viewer can read an agent-dm pod (§3.7) but isn't a formal member. Styled as a soft note, not an error — being a read-only observer is the intended state. */ .v2-chat__readonly { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; margin: 12px 16px 16px; background: var(--v2-bg-subtle); border: 1px solid var(--v2-border-soft); border-radius: var(--v2-radius); } .v2-chat__readonly-icon { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--v2-radius-pill); background: var(--v2-surface-hover); color: var(--v2-ink); } .v2-chat__readonly-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; } .v2-chat__readonly-title { font-size: 13px; font-weight: 600; color: var(--v2-text-primary); } .v2-chat__readonly-text { font-size: 12.5px; line-height: 1.45; color: var(--v2-text-secondary); } /* GitHub PR preview card. Rendered below a message body when the content contains a `https://github.com///pull/` URL. Card fetches from GitHub REST API on mount; failure mode is silent (parent's clickable URL stays). Visual: borders not shadows, one accent color, no gradients — matches the v2 design system. */ .v2-prcard { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; padding: 10px 12px; background: var(--v2-surface); border: 1px solid var(--v2-border-soft); border-radius: var(--v2-radius); text-decoration: none; color: var(--v2-text-primary); transition: border-color 120ms ease, background 120ms ease; } .v2-prcard:hover { border-color: var(--v2-border); background: var(--v2-surface-hover); } .v2-prcard--loading { flex-direction: row; align-items: center; justify-content: space-between; gap: 8px; color: var(--v2-text-secondary); font-size: 12.5px; } .v2-prcard__chip { font-family: var(--v2-font-mono, ui-monospace, SFMono-Regular, monospace); font-size: 12px; padding: 2px 8px; border-radius: var(--v2-radius-pill); background: var(--v2-accent-soft); color: var(--v2-accent-text); } .v2-prcard__loading-text { font-style: italic; } .v2-prcard__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--v2-text-secondary); } .v2-prcard__repo { font-family: var(--v2-font-mono, ui-monospace, SFMono-Regular, monospace); letter-spacing: 0.01em; } .v2-prcard__state { display: inline-flex; align-items: center; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; padding: 2px 8px; border-radius: var(--v2-radius-pill); border: 1px solid transparent; } .v2-prcard__state--open { color: #16a34a; background: rgba(22, 163, 74, 0.10); border-color: rgba(22, 163, 74, 0.20); } .v2-prcard__state--merged { color: #6f42c1; background: rgba(111, 66, 193, 0.10); border-color: rgba(111, 66, 193, 0.20); } .v2-prcard__state--closed { color: #ef4444; background: rgba(239, 68, 68, 0.10); border-color: rgba(239, 68, 68, 0.20); } .v2-prcard__title { font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--v2-text-primary); } .v2-prcard__num { font-family: var(--v2-font-mono, ui-monospace, SFMono-Regular, monospace); color: var(--v2-text-secondary); font-weight: 500; margin-right: 4px; } .v2-prcard__meta { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; font-size: 12px; color: var(--v2-text-secondary); } .v2-prcard__metric { font-family: var(--v2-font-mono, ui-monospace, SFMono-Regular, monospace); font-size: 11.5px; } .v2-prcard__metric--add { color: #16a34a; } .v2-prcard__metric--del { color: #ef4444; } .v2-prcard__contributors { display: inline-flex; align-items: center; margin-left: auto; } .v2-prcard__avatar { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; margin-left: -6px; border-radius: 50%; background-size: cover; background-position: center; background-color: var(--v2-accent-soft); border: 2px solid var(--v2-surface); font-size: 10px; font-weight: 600; color: var(--v2-accent-text); } .v2-prcard__avatar:first-child { margin-left: 0; } .v2-prcard__avatar--overflow { background-color: var(--v2-border-soft); color: var(--v2-text-secondary); font-size: 10px; } .v2-gig { min-width: 0; max-width: 600px; padding: 12px 16px; border: 1px solid var(--v2-border-soft); border-radius: var(--v2-radius); background: var(--v2-surface); color: var(--v2-text-primary); overflow-wrap: anywhere; } .v2-gig__head, .v2-gig__stack { display: flex; gap: 8px; align-items: baseline; } .v2-gig__head { justify-content: space-between; font: 500 11px var(--v2-font-mono); color: var(--v2-text-muted); margin-bottom: 8px; } .v2-gig__stack { flex-wrap: wrap; align-items: center; margin-bottom: 8px; } .v2-approval { border: 1px solid var(--v2-border-soft); border-radius: var(--v2-radius); background: var(--v2-surface); box-shadow: 0 0 0 2px var(--v2-accent); padding: 12px 16px; max-width: none; display: flex; flex-direction: column; gap: 8px; } .v2-approval__head { display: flex; align-items: center; gap: 8px; } .v2-approval__badge { font-size: 10.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--v2-ink); font-family: var(--v2-font-mono); } .v2-approval__agent { font-size: 12.5px; font-weight: 600; color: var(--v2-text-secondary); } .v2-approval__time { font-size: 11.5px; color: var(--v2-text-muted); margin-left: auto; } .v2-approval__summary { font-size: 14px; color: var(--v2-text-primary); line-height: 1.45; } /* The consent line — server-derived from actionType + params. It outranks the agent's prose deliberately: the prose is unvalidated and the human is consenting to what executes, not to what was pitched. */ .v2-approval__action { font-size: 14.5px; font-weight: 600; color: var(--v2-text-primary); line-height: 1.4; overflow-wrap: anywhere; } /* Owner-only canonical tool arguments. Keep the exact JSON readable without letting a long comment body widen the message column on mobile. */ .v2-approval__tool-call { margin: 0; padding: 8px 10px; border: 1px solid var(--v2-border-soft); border-radius: var(--v2-radius-sm); background: var(--v2-bg); color: var(--v2-text-primary); font: 12px/1.45 var(--v2-font-mono); white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: auto; } /* The agent's reason for asking, demoted below the action it belongs to. */ .v2-approval__pitch { font-size: 13px; color: var(--v2-text-secondary); line-height: 1.45; padding-left: 10px; border-left: 2px solid var(--v2-border-soft); overflow-wrap: anywhere; } .v2-approval__actions { display: flex; gap: 8px; margin-top: 2px; } .v2-root button.v2-approval__btn { border-radius: var(--v2-radius-sm); font-size: 13px; font-weight: 600; padding: 7px 16px; cursor: pointer; border: 1px solid var(--v2-border); } .v2-root button.v2-approval__btn--approve { background: var(--v2-ink); border-color: var(--v2-ink); color: var(--v2-on-ink); } .v2-root button.v2-approval__btn--approve:not(:disabled):hover { background: var(--v2-ink-hover); } .v2-root button.v2-approval__btn--decline { background: var(--v2-bg); color: var(--v2-text-secondary); } .v2-root button.v2-approval__btn--decline:not(:disabled):hover { background: var(--v2-surface-hover); color: var(--v2-text-primary); } .v2-root button.v2-approval__btn:disabled { opacity: 0.55; cursor: default; } .v2-approval__state { font-size: 13px; color: var(--v2-text-secondary); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .v2-approval__state--approved { color: #047857; font-weight: 600; } .v2-approval__state--declined { color: var(--v2-text-tertiary); font-weight: 600; } .v2-approval__state--attention { color: #b45309; font-weight: 600; } .v2-approval__state--expired { color: var(--v2-text-muted); font-style: italic; } .v2-root button.v2-approval__result-link { border: none; background: none; color: var(--v2-accent-text); font-size: 13px; font-weight: 600; cursor: pointer; padding: 0; text-decoration: underline; } .v2-approval__error { font-size: 12.5px; color: #b91c1c; } /* Hosted-to-BYO handoff: the command is server-composed and the card copies the selected string verbatim. Keep it visually distinct from approval cards without making the shell instructions look like ordinary agent prose. */ .v2-byo-handoff { border: 1px solid var(--v2-border-soft); border-radius: var(--v2-radius); background: var(--v2-surface); box-shadow: 0 0 0 2px var(--v2-accent); padding: 12px 16px; display: flex; flex-direction: column; gap: 8px; } .v2-byo-handoff__head { display: flex; align-items: center; gap: 8px; } .v2-byo-handoff__badge { font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--v2-ink); font-family: var(--v2-font-mono); } .v2-byo-handoff__agent, .v2-byo-handoff__time { font-size: 12.5px; color: var(--v2-text-secondary); } .v2-byo-handoff__time { margin-left: auto; font-size: 12px; color: var(--v2-text-muted); } .v2-byo-handoff__title { font-size: 15px; font-weight: 650; color: var(--v2-text-primary); } .v2-byo-handoff__body, .v2-byo-handoff__note { font-size: 13px; color: var(--v2-text-secondary); line-height: 1.45; } .v2-byo-handoff__os { display: flex; gap: 6px; flex-wrap: wrap; } .v2-root button.v2-byo-handoff__os-btn, .v2-root button.v2-byo-handoff__copy { border: 1px solid var(--v2-border); border-radius: var(--v2-radius-sm); font-size: 13px; font-weight: 600; cursor: pointer; } .v2-root button.v2-byo-handoff__os-btn { padding: 6px 10px; background: var(--v2-bg); color: var(--v2-text-secondary); } .v2-root button.v2-byo-handoff__os-btn--selected { background: var(--v2-ink); border-color: var(--v2-ink); color: var(--v2-on-ink); } .v2-byo-handoff__command { margin: 0; padding: 10px 12px; border: 1px solid var(--v2-border-soft); border-radius: var(--v2-radius-sm); background: var(--v2-bg); color: var(--v2-text-primary); font: 12px/1.5 var(--v2-font-mono); white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: auto; } .v2-root button.v2-byo-handoff__copy { align-self: flex-start; padding: 7px 14px; background: var(--v2-ink); border-color: var(--v2-ink); color: var(--v2-on-ink); } .v2-root button.v2-byo-handoff__copy:hover:not(:disabled) { background: var(--v2-ink-hover); } .v2-root button.v2-byo-handoff__copy:disabled { opacity: 0.55; cursor: default; } .v2-root:lang(zh) .v2-chat__new-pod-title { letter-spacing: 0; } .v2-root:lang(zh) .v2-chat__delivery-hint, .v2-root:lang(zh) .v2-chat__readonly-text, .v2-root:lang(zh) .v2-approval__summary, .v2-root:lang(zh) .v2-approval__action { line-height: 1.6; } /* A square ghost icon button; the word lives in aria-label and title. */ .v2-root button.v2-icon-button { display: inline-grid; width: 28px; height: 28px; flex: none; place-items: center; padding: 0; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--v2-text-secondary); cursor: pointer; } .v2-root button.v2-icon-button:hover:not(:disabled) { background: var(--v2-surface-hover); color: var(--v2-text-primary); } .v2-root button.v2-icon-button:focus-visible { outline: none; box-shadow: var(--v2-focus-ring); }