From 097fe9c4cf7e474941565d97b77915a9224de38b Mon Sep 17 00:00:00 2001 From: Carlos Escalante Date: Wed, 29 Apr 2026 22:02:58 -0600 Subject: [PATCH] Point sync-db at old-vps and add A2UI theming notes The production SSH alias is old-vps; the placeholder "production" alias does not exist. Also captures research findings on theming the A2UI basic catalog without overriding component internals, for later reference. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/a2ui-theming-findings.md | 53 +++++++++++++++++++++++++++++++++++ scripts/sync-db.sh | 2 +- 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 docs/a2ui-theming-findings.md diff --git a/docs/a2ui-theming-findings.md b/docs/a2ui-theming-findings.md new file mode 100644 index 0000000..ee3bc6a --- /dev/null +++ b/docs/a2ui-theming-findings.md @@ -0,0 +1,53 @@ +# A2UI Theming Findings + +Captured 2026-04-28 while researching how to beautify the table the agent renders via `render_a2ui` without overriding component internals. + +## TL;DR + +- A2UI v0.9 docs prescribe theming through a small set of **documented top-level CSS variables** declared on `:where(:root)` (zero specificity, so host CSS wins without `!important`). +- Default theme uses `light-dark()` so tokens self-toggle. Recommended dark-mode coupling: add the documented `a2ui-dark` class on `` whenever Tailwind's `.dark` is on; that flips `color-scheme: dark` and resolves every `light-dark()` to its dark branch. +- **In our app, this approach has near-zero visible effect.** We render through `@copilotkit/a2ui-renderer` (React variant), not `@a2ui/lit`. Inspecting the compiled React renderer (`node_modules/.pnpm/@copilotkit+a2ui-renderer@1.56.4/.../catalog/basic/components/*.mjs`), every component uses **hardcoded inline styles**; the only CSS variable consumed across the whole basic catalog is `--a2ui-primary-color`. +- This matches open issues `google/A2UI#977` and `#1285` ("React renderer parity is incomplete"). + +## Documented token surface (Lit / Angular) + +From `tech_docs/A2UI/renderers/web_core/src/v0_9/basic_catalog/styles/default.ts`: + +- Color palette: `--a2ui-color-background`, `--a2ui-color-on-background`, `--a2ui-color-surface`, `--a2ui-color-on-surface`, `--a2ui-color-primary`, `--a2ui-color-primary-light/-dark/-hover`, `--a2ui-color-on-primary`, `--a2ui-color-secondary`, `--a2ui-color-secondary-light/-dark/-hover`, `--a2ui-color-on-secondary`, `--a2ui-color-input`, `--a2ui-color-on-input`, `--a2ui-color-border`. +- Borders: `--a2ui-border`, `--a2ui-border-width`, `--a2ui-border-radius`. +- Typography: `--a2ui-font-family-title`, `--a2ui-font-family-monospace`, `--a2ui-font-size`, `--a2ui-font-scale`, `--a2ui-font-size-xs..2xl`, `--a2ui-line-height-headings`, `--a2ui-line-height-body`. +- Spacing: `--a2ui-grid-base`, `--a2ui-spacing-xs..xl`. + +Per-component tokens like `--a2ui-card-background` exist but the renderer README and the official theming guide explicitly frame them as catalog-internal, not stable spec. Avoid relying on them. + +## Dark-mode coupling + +A2UI default uses `light-dark(...)` and supports forced modes via `a2ui-light` / `a2ui-dark` classes (see the `:where(.a2ui-dark)` block in `default.ts`). Best practice for a host that uses Tailwind `.dark` on ``: toggle the matching `a2ui-dark` class in lockstep — one effect-driven `useEffect`, or add it directly to the root if the app is dark-only. No need to redeclare every token under `.dark`; the default rules already pick up the right branch through `light-dark()`. + +## Footguns in v0.9 + +- The agent-supplied `theme` payload (e.g. `createSurface.theme.primaryColor`) is **not yet wired** in the basic catalog. Tracked in `google/A2UI#979` (Lit) and `#977` (React). Don't expect agent-side theming to recolor anything in v0.9; only the host CSS does. +- `hintedStyles` (h1–h6 mappings) require all keys when overridden — see `google/A2UI#602`. +- Tracking issues for the broader theming surface: `google/A2UI#1083`, `#1118`. + +## Why this won't move the table in our app + +`@copilotkit/a2ui-renderer@1.56.4` (React) is what `` plugs in. Its components apply colors and borders as inline `style` props (`backgroundColor: "#fff"`, `border: "1px solid #ccc"`, etc.). Inline styles can only be overridden with `!important` in author CSS, which contradicts the "don't take its freedom" goal. So the documented `--a2ui-*` token contract is currently a **Lit-only surface** for this catalog. + +## Practical options for this codebase + +1. **Quick win**: set `--a2ui-primary-color: var(--primary)` on `:root`. Real but small effect (primary buttons, links). +2. **Prompt-side polish**: instruct the agent to compose richer A2UI structures — wrap the table in a `Card`, use `usageHint: "h3"` for the section title, insert a `Divider`, group columns with `Row` + `Column` weights — so the renderer's existing inline styles produce a cleaner result. No code change. +3. **Switch renderer**: replace `@copilotkit/a2ui-renderer` with `@a2ui/lit` (or wait for `@a2ui/react` parity). Then every documented `--a2ui-*` token actually applies. Non-trivial migration. +4. **Custom catalog overrides**: register replacement React components for `Row`/`List`/`Card` via `createA2UICatalog`; full control, most invasive, accepts ownership of those components forever. + +## Source links + +- `tech_docs/A2UI/docs/guides/theming.md` +- `tech_docs/A2UI/renderers/web_core/src/v0_9/basic_catalog/styles/default.ts` +- `tech_docs/A2UI/renderers/lit/README.md` §"CSS-based Basic Catalog Theming" +- `https://github.com/google/A2UI/issues/977` (React renderer theming gap) +- `https://github.com/google/A2UI/issues/1285` (React renderer parity) +- `https://github.com/google/A2UI/issues/1118` (theming surface roadmap) +- `https://github.com/google/A2UI/issues/979` (Lit `theme` payload not wired) +- `https://github.com/google/A2UI/pull/1079` (v0.9 CSS-variable rollout) diff --git a/scripts/sync-db.sh b/scripts/sync-db.sh index a467b64..c386b8d 100755 --- a/scripts/sync-db.sh +++ b/scripts/sync-db.sh @@ -2,7 +2,7 @@ set -euo pipefail # ── Configuration ──────────────────────────────────────────────── -PROD_SSH_ALIAS="production" +PROD_SSH_ALIAS="old-vps" PROD_CONTAINER="wealthysmart-db-prod" PROD_DB="wealthysmart" PROD_USER="wealthy_user"