/* customer-grid/gridChat.css — the docked chat panel (W37-T40, contract C8). * * ⛔ MODULE-LOCAL BY CONTRACT, not by preference. C8 hands `index.css` (12k+ lines) to lane A * alone this wave, and every other lane adds styles in its own per-surface sheet imported by its * own component. The precedent already exists next door in `scriptView.css` and `navExtras.css`. * ⚠ Colours come from the design tokens (navy #1F4E78 + gold #C8A24B, DESIGN.md), never from fresh * hexes: a surface that invents its own palette is the thing the constitution exists to prevent. * Only the tokens this file actually uses are named. * ⛔⛔ NO FALLBACK LITERAL INSIDE A `font:` SHORTHAND, and this sheet shipped ten of them before * `web_ui` said so (lane A, mailbox A-47). A fallback there is a SECOND SOURCE OF TRUTH for a size * that silently becomes THE size the day the token is renamed, and `index.css` always loads, so it * can never actually fire. Sizes are therefore `var(--lp-fs-xs)` bare; colours keep their fallback * because a missing colour is a legibility failure rather than a silent wrong number. * ⚠ NO EMOJIS AND NO ALL-CAPS CHROME (DESIGN.md). */ .cg-chat { display: flex; flex-direction: column; height: 100%; min-height: 0; /* ⚠ A FLOOR AND A CEILING, NOT A FIXED WIDTH. The host docks this beside a grid whose columns are the reason the person is here; a panel that cannot give width back squeezes the thing it is talking about. Below the floor the transcript stops being readable, so the floor is real. */ min-width: 280px; max-width: 420px; flex: 0 0 340px; background: var(--lp-surface, #ffffff); border-left: 1px solid var(--lp-border, #e4e7ec); } /* Below 1024px a docked panel and a grid cannot both be usable, so the panel takes the surface. ⚠ It does NOT hide itself: hiding would leave the host's toggle saying "open" with nothing on screen, which is a worse failure than a full-width panel the person can close. */ @media (max-width: 1024px) { .cg-chat { flex: 1 1 auto; max-width: none; border-left: 0; } } .cg-chat-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--lp-border, #e4e7ec); background: var(--lp-surface, #ffffff); } .cg-chat-title { font: 600 var(--lp-fs-xs)/1.4 Inter, system-ui, sans-serif; color: var(--lp-text, #1d2939); /* The database name can be long and the header is narrow. Truncating beats wrapping into a two-line header that shifts the whole panel down. */ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 0; } .cg-chat-close { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: 0; border-radius: 6px; background: transparent; color: var(--lp-text-muted, #667085); cursor: pointer; } .cg-chat-close:hover { background: var(--lp-surface-sunken, #f2f4f7); color: var(--lp-text, #1d2939); } /* ── the transcript ─────────────────────────────────────────────────────── */ .cg-chat-log { display: flex; flex-direction: column; gap: 10px; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 14px 12px; } .cg-chat-turn { display: flex; flex-direction: column; gap: 6px; } .cg-chat-msg { max-width: 92%; padding: 8px 10px; border-radius: 10px; font: 400 var(--lp-fs-xs)/1.55 Inter, system-ui, sans-serif; white-space: pre-wrap; /* ⚠ A pasted column name or an id has no spaces to break on and would otherwise push the panel wider than its own max-width. */ overflow-wrap: anywhere; } .cg-chat-msg.is-you { align-self: flex-end; background: var(--lp-navy, #1f4e78); color: #ffffff; } .cg-chat-msg.is-assistant { align-self: flex-start; background: var(--lp-surface-sunken, #f2f4f7); color: var(--lp-text, #1d2939); } /* ⚠ The panel talking about ITSELF (a write landed, a proposal was declined) is neither side of the conversation, so it is centred and quiet rather than dressed as an answer. */ .cg-chat-msg.is-note { align-self: center; max-width: 100%; background: transparent; color: var(--lp-text-muted, #667085); font-size: var(--lp-fs-2xs, 11px); text-align: center; padding: 2px 4px; } /* ⛔ An error is a KIND OF TURN, in the transcript where it can be re-read while the person rephrases. Not a toast that has already faded by then. */ .cg-chat-msg.is-error { align-self: flex-start; background: #fef3f2; color: #b42318; border: 1px solid #fecdca; } .cg-chat-pending { display: flex; align-items: center; gap: 8px; padding: 2px 2px 4px; font: 400 var(--lp-fs-2xs)/1.4 Inter, system-ui, sans-serif; color: var(--lp-text-muted, #667085); } /* ── the write confirm (R10) ────────────────────────────────────────────── */ .cg-chat-edits { border: 1px solid var(--lp-border, #e4e7ec); border-radius: 10px; background: var(--lp-surface, #ffffff); padding: 10px; } .cg-chat-edits-head { margin: 0 0 8px; font: 600 var(--lp-fs-2xs)/1.4 Inter, system-ui, sans-serif; color: var(--lp-text, #1d2939); } .cg-chat-edits-table { width: 100%; border-collapse: collapse; font: 400 var(--lp-fs-3xs)/1.45 Inter, system-ui, sans-serif; /* A proposal can name more cells than fit; it scrolls rather than being clipped, because a confirm the person cannot fully read is not a confirm. */ display: block; max-height: 220px; overflow: auto; } .cg-chat-edits-table th { text-align: left; font-weight: 600; color: var(--lp-text-muted, #667085); padding: 0 8px 4px 0; position: sticky; top: 0; background: var(--lp-surface, #ffffff); } .cg-chat-edits-table td { padding: 3px 8px 3px 0; color: var(--lp-text, #1d2939); border-top: 1px solid var(--lp-border, #e4e7ec); vertical-align: top; overflow-wrap: anywhere; } /* ⚠ The two values are told apart by WEIGHT and colour, never by colour alone: a red/green pair is unreadable to a substantial minority of people, and this is a confirm before a write. */ .cg-chat-before { color: var(--lp-text-muted, #667085); text-decoration: line-through; } .cg-chat-after { color: var(--lp-navy, #1f4e78); font-weight: 600; } /* ⚠ Centred under the note it belongs to, and quiet: an undo control that shouted would read as a warning that something went wrong, when what happened is exactly what the person confirmed. */ .cg-chat-undo { display: flex; justify-content: center; margin-top: 2px; } .cg-chat-edits-act { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; } .cg-chat-ghost, .cg-chat-go { border-radius: 7px; padding: 5px 12px; font: 500 var(--lp-fs-2xs)/1.2 Inter, system-ui, sans-serif; cursor: pointer; } .cg-chat-ghost { border: 1px solid var(--lp-border, #e4e7ec); background: var(--lp-surface, #ffffff); color: var(--lp-text, #1d2939); } .cg-chat-go { border: 1px solid var(--lp-navy, #1f4e78); background: var(--lp-navy, #1f4e78); color: #ffffff; } .cg-chat-ghost:disabled, .cg-chat-go:disabled { opacity: 0.55; cursor: default; } /* ── the opening and the composer ───────────────────────────────────────── */ .cg-chat-opening { display: flex; flex-direction: column; justify-content: center; flex: 1 1 auto; min-height: 0; gap: 10px; padding: 16px 12px; text-align: center; } .cg-chat-opening-h { margin: 0; font: 600 var(--lp-fs-lg)/1.3 Inter, system-ui, sans-serif; color: var(--lp-text, #1d2939); } .cg-chat-opening-p { margin: 0 0 6px; font: 400 var(--lp-fs-2xs)/1.55 Inter, system-ui, sans-serif; color: var(--lp-text-muted, #667085); } .cg-chat-foot { padding: 10px 12px 12px; border-top: 1px solid var(--lp-border, #e4e7ec); } .cg-chat-composer { border: 1px solid var(--lp-border, #e4e7ec); border-radius: 12px; background: var(--lp-surface, #ffffff); padding: 8px; text-align: left; } .cg-chat-composer:focus-within { border-color: var(--lp-navy, #1f4e78); } .cg-chat-input { width: 100%; border: 0; outline: 0; resize: none; background: transparent; color: var(--lp-text, #1d2939); font: 400 var(--lp-fs-xs)/1.5 Inter, system-ui, sans-serif; } .cg-chat-input::placeholder { color: var(--lp-text-muted, #667085); } .cg-chat-input:disabled { color: var(--lp-text-muted, #667085); } /* ⚠ The foot row sits INSIDE the composer's border, which is the shape `cg-agent-composer-foot` already established. A second card outline under the input would read as two controls. */ .cg-chat-composer-foot { display: flex; align-items: center; gap: 8px; margin-top: 6px; } .cg-chat-scope { font: 400 var(--lp-fs-3xs)/1.3 Inter, system-ui, sans-serif; color: var(--lp-text-muted, #667085); } .cg-chat-spacer { flex: 1 1 auto; } .cg-chat-send { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: 0; border-radius: 50%; background: var(--lp-navy, #1f4e78); color: #ffffff; cursor: pointer; } .cg-chat-send:disabled { background: var(--lp-surface-sunken, #f2f4f7); color: var(--lp-text-muted, #667085); cursor: default; }