@materialwebunofficial/antigravity-themes 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,115 @@
1
+ // Turn tokens: under every finished agent turn, beside the turn's time in
2
+ // its toolbar, one plain line of what the turn's model calls used:
3
+ // "2.5k in · 358 out · 142k cache"
4
+ // Each model call stores its usage on the step it produced
5
+ // (CortexStepMetadata.modelUsage); the line sums them over the turn, the same
6
+ // totals the app's own flag-gated cost summary lists as Input, Cache, Output.
7
+ // in input + cache-write tokens (prompt the provider had to process)
8
+ // out output tokens (thinking included)
9
+ // cache cache-read tokens (left out when 0)
10
+ // Read-only: the turn's steps come from the toolbar's React props. The span
11
+ // carries the time label's own classes, so each theme styles it as the time.
12
+ function agyTurnTokens() {
13
+ const TOOLBAR = '[data-testid="cascade-system-message-toolbar"]';
14
+ const CLASSES = 'agy-turn-tokens text-xs text-muted-foreground px-1 whitespace-nowrap tabular-nums';
15
+
16
+ const num = (v) => Number(v ?? 0) || 0;
17
+ const fmt = (n) => (n >= 999500 ? `${+(n / 1e6).toFixed(1)}M`
18
+ : n >= 9950 ? `${Math.round(n / 1e3)}k`
19
+ : n >= 1000 ? `${+(n / 1e3).toFixed(1)}k`
20
+ : String(n));
21
+ const fiberOf = (el) => el && el[Object.keys(el).find((k) => k.startsWith('__reactFiber$'))];
22
+
23
+ // The toolbar's component gets the turn's steps (and showThumbsUpDown)
24
+ function stepsOf(toolbar) {
25
+ let f = fiberOf(toolbar);
26
+ for (let i = 0; f && i < 8; i++, f = f.return) {
27
+ const p = f.memoizedProps;
28
+ if (Array.isArray(p?.steps) && 'showThumbsUpDown' in p) return p.steps;
29
+ }
30
+ return null;
31
+ }
32
+ function lineFor(steps) {
33
+ let input = 0, output = 0, cache = 0;
34
+ for (const s of steps) {
35
+ const u = s?.metadata?.modelUsage;
36
+ if (!u) continue;
37
+ input += num(u.inputTokens) + num(u.cacheWriteTokens);
38
+ output += num(u.outputTokens);
39
+ cache += num(u.cacheReadTokens);
40
+ }
41
+ if (!input && !output) return '';
42
+ return [`${fmt(input)} in`, `${fmt(output)} out`, cache ? `${fmt(cache)} cache` : ''].filter(Boolean).join(' · ');
43
+ }
44
+
45
+ // toolbar -> { steps, el } it was labelled for: a labelled toolbar costs a
46
+ // few property reads, no DOM queries
47
+ const labelled = new WeakMap();
48
+ function label(toolbar) {
49
+ const steps = stepsOf(toolbar);
50
+ const prev = labelled.get(toolbar);
51
+ if (prev && prev.steps === steps && (!prev.el || prev.el.isConnected)) return;
52
+ const group = toolbar.querySelector(':scope > div > div.ml-auto'); // time, copy, thumbs
53
+ if (!group) return;
54
+ const text = steps ? lineFor(steps) : '';
55
+ let el = group.querySelector(':scope > .agy-turn-tokens');
56
+ if (!text) {
57
+ el?.remove();
58
+ labelled.set(toolbar, { steps, el: null });
59
+ return;
60
+ }
61
+ if (!el) {
62
+ el = document.createElement('span');
63
+ el.className = CLASSES;
64
+ group.prepend(el);
65
+ }
66
+ if (el.textContent !== text) el.textContent = text;
67
+ labelled.set(toolbar, { steps, el });
68
+ }
69
+
70
+ // A toolbar mounts when its turn finishes: look inside what the transcript
71
+ // adds (small subtrees while a reply streams), and rescan it every 2s for
72
+ // the rest (a new viewport after navigation, steps that changed in place)
73
+ let viewport = null, observer = null;
74
+ function onMutations(records) {
75
+ try {
76
+ for (const r of records) {
77
+ for (const n of r.addedNodes) {
78
+ if (n.nodeType !== 1 || n.classList.contains('agy-turn-tokens')) continue;
79
+ if (n.matches(TOOLBAR)) label(n);
80
+ else n.querySelectorAll(TOOLBAR).forEach(label);
81
+ }
82
+ }
83
+ } catch {
84
+ // app internals changed: leave the toolbars as they are
85
+ }
86
+ }
87
+ function scan() {
88
+ if (document.hidden) return;
89
+ const vp = document.querySelector('[data-testid="autoscroll-viewport"]');
90
+ if (vp !== viewport) {
91
+ observer?.disconnect();
92
+ viewport = vp;
93
+ if (vp) {
94
+ observer = new MutationObserver(onMutations);
95
+ observer.observe(vp, { childList: true, subtree: true });
96
+ }
97
+ }
98
+ try {
99
+ viewport?.querySelectorAll(TOOLBAR).forEach(label);
100
+ } catch {
101
+ // as above
102
+ }
103
+ }
104
+
105
+ const timer = setInterval(scan, 2000);
106
+ scan();
107
+
108
+ return {
109
+ dispose() {
110
+ clearInterval(timer);
111
+ observer?.disconnect();
112
+ document.querySelectorAll('.agy-turn-tokens').forEach((el) => el.remove());
113
+ },
114
+ };
115
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "default": "matte",
3
+ "themes": {
4
+ "matte": ["matte.css"],
5
+ "md3e": ["md3e-tokens.css", "md3e.css", "md3e-icons.css"]
6
+ },
7
+ "fonts": {
8
+ "md3e": [
9
+ { "family": "Roboto", "file": "../vendor/md3e/roboto-variable.woff2", "weight": "100 900", "stretch": "75% 100%" }
10
+ ]
11
+ },
12
+ "ripple": ["md3e"],
13
+ "options": [
14
+ { "key": "matte", "name": "Matte", "theme": "matte", "swatch": "#ededee" },
15
+ { "key": "md3e-teal", "name": "Material 3 · Teal", "theme": "md3e", "swatch": "#a5faf9" },
16
+ { "key": "md3e-ocean", "name": "Material 3 · Ocean", "theme": "md3e", "seed": "ocean", "swatch": "#9ecefe" },
17
+ { "key": "md3e-forest", "name": "Material 3 · Forest", "theme": "md3e", "seed": "forest", "swatch": "#c8f2ae" },
18
+ { "key": "md3e-amber", "name": "Material 3 · Amber", "theme": "md3e", "seed": "amber", "swatch": "#fecd79" },
19
+ { "key": "md3e-coral", "name": "Material 3 · Coral", "theme": "md3e", "seed": "coral", "swatch": "#ffa6a8" }
20
+ ]
21
+ }
@@ -0,0 +1,390 @@
1
+ /* ==========================================================================
2
+ "Matte": a theme for Antigravity Desktop (tested with 2.28)
3
+
4
+ Idea: matte, quiet, fast. A near-black window holds one rounded panel;
5
+ surfaces step up in small neutral increments, 1px hairlines carry the
6
+ structure, and the only bright thing is the send button. No gradients,
7
+ blur, grain, glow, masks or looping animation. Light mode is the same
8
+ structure inverted, from the token block after 00.
9
+
10
+ Built for speed (a full style recalc costs about what the stock app's
11
+ does):
12
+ - Almost everything is done through the app's own tokens; the app's
13
+ Tailwind classes then paint the components. Few rules = cheap recalc.
14
+ - The handful of rules end in an id, class or single attribute: no
15
+ :has(), no :is()/:where() lists on the right, no universal
16
+ pseudo-elements (scrollbars, *::before).
17
+ - --background is the panel color inside the panel and the window color
18
+ outside it, so the app's own opaque layers (pinned user message band,
19
+ transcript fade, sticky sidebar titles) match their surface with no
20
+ workarounds.
21
+
22
+ Cascade: unlayered rules beat Tailwind v4's @layer utilities; the app
23
+ writes its tokens and the VS Code theme inline on <html>, so sections 01
24
+ and 02 use !important. Never wrap this file in @layer.
25
+
26
+ Scope: :root[data-agy-theme="matte"]; loaded by src/theme-host.js.
27
+ ========================================================================== */
28
+
29
+
30
+ /* 00 — Tokens -------------------------------------------------------------- */
31
+ :root[data-agy-theme="matte"] {
32
+ /* Surfaces, back to front (neutral, no blue cast) */
33
+ --m-window: #0e0e10; /* window frame, title bar, sidebar */
34
+ --m-panel: #151517; /* the conversation panel */
35
+ --m-raised: #1c1c1f; /* composer, user message, cards, menus */
36
+ --m-high: #26262a; /* highlight inside raised things, tooltips */
37
+ --m-inset: #111113; /* code */
38
+
39
+ /* Hairlines and states (alpha white, reads the same on every surface) */
40
+ --m-line: rgb(255 255 255 / 0.075);
41
+ --m-line-2: rgb(255 255 255 / 0.11);
42
+ --m-line-3: rgb(255 255 255 / 0.18);
43
+ --m-hover: rgb(255 255 255 / 0.045);
44
+ --m-select: rgb(255 255 255 / 0.08);
45
+
46
+ /* Text — contrast on --m-panel */
47
+ --m-text-max: #f2f2f3;
48
+ --m-text: #dcdcde; /* 13.4:1 */
49
+ --m-text-2: #a3a3a8; /* 7.0:1 */
50
+ --m-text-3: #86868c; /* 4.9:1 */
51
+
52
+ /* The one bright thing */
53
+ --m-primary: #ededee;
54
+ --m-primary-ink: #111113;
55
+ --m-strong: #ffffff; /* one step past --m-primary (button hover) */
56
+
57
+ /* Status, the Context card's segments, and the remaining literals */
58
+ --m-success: #6fbf8b;
59
+ --m-warning: #d9a35b;
60
+ --m-error: #e06c6c;
61
+ --m-blue: #7aa2f7;
62
+ --m-amber: #e5a84b;
63
+ --m-teal: #73daca;
64
+ --m-selection: rgb(255 255 255 / 0.16);
65
+ --m-lineno: #5c5c60;
66
+ --m-scroll: rgb(255 255 255 / 0.10);
67
+ --m-scroll-2: rgb(255 255 255 / 0.18);
68
+ --m-scroll-3: rgb(255 255 255 / 0.24);
69
+ --m-find: rgb(217 163 91 / 0.24);
70
+ --m-find-current: rgb(217 163 91 / 0.55);
71
+ --m-find-border: rgb(217 163 91 / 0.85);
72
+ --m-shadow: rgb(0 0 0 / 0.7);
73
+ --m-shadow-menu: rgb(0 0 0 / 0.75);
74
+
75
+ --m-font-ui: "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
76
+ --m-font-display: "Segoe UI Variable Display", "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
77
+ --m-font-mono: "Cascadia Mono", "Cascadia Code", Consolas, monospace;
78
+ }
79
+
80
+ /* Light mode: the app's own setting (System / Light / Dark, marked on
81
+ <body>), mirrored by theme-host.js as data-agy-mode. Same structure,
82
+ inverted: a light gray window holds a near-white panel, raised things are
83
+ white and carry the hairline, lines and states are alpha black, and the
84
+ one strong thing is the near-black send button. Every rule reads these
85
+ tokens, so nothing else changes. Contrast on --m-panel. */
86
+ :root[data-agy-theme="matte"][data-agy-mode="light"] {
87
+ --m-window: #ebebed;
88
+ --m-panel: #f8f8f9;
89
+ --m-raised: #ffffff;
90
+ --m-high: #e7e7ea;
91
+ --m-inset: #f1f1f3;
92
+
93
+ --m-line: rgb(0 0 0 / 0.08);
94
+ --m-line-2: rgb(0 0 0 / 0.12);
95
+ --m-line-3: rgb(0 0 0 / 0.22);
96
+ --m-hover: rgb(0 0 0 / 0.04);
97
+ --m-select: rgb(0 0 0 / 0.07);
98
+
99
+ --m-text-max: #0b0b0d;
100
+ --m-text: #1d1d20; /* 15.8:1 */
101
+ --m-text-2: #4b4b51; /* 8.2:1 */
102
+ --m-text-3: #626268; /* 5.7:1, 5.1:1 on the window */
103
+
104
+ --m-primary: #18181b;
105
+ --m-primary-ink: #f6f6f7;
106
+ --m-strong: #000000;
107
+
108
+ --m-success: #277045;
109
+ --m-warning: #94560a;
110
+ --m-error: #b3373a;
111
+ --m-blue: #3a63c4;
112
+ --m-amber: #a86a12;
113
+ --m-teal: #1f7f71;
114
+ --m-selection: rgb(0 0 0 / 0.12);
115
+ --m-lineno: #8e8e94;
116
+ --m-scroll: rgb(0 0 0 / 0.14);
117
+ --m-scroll-2: rgb(0 0 0 / 0.24);
118
+ --m-scroll-3: rgb(0 0 0 / 0.32);
119
+ --m-find: rgb(168 106 18 / 0.18);
120
+ --m-find-current: rgb(168 106 18 / 0.40);
121
+ --m-find-border: rgb(168 106 18 / 0.8);
122
+ --m-shadow: rgb(0 0 0 / 0.16);
123
+ --m-shadow-menu: rgb(0 0 0 / 0.18);
124
+ }
125
+
126
+
127
+ /* 01 — Bridge: app tokens (inline on <html>, hence !important) ------------ */
128
+ :root[data-agy-theme="matte"] {
129
+ --background: var(--m-window) !important; /* re-pointed to --m-panel inside the panel (10) */
130
+ --content: var(--m-panel) !important;
131
+ --foreground: var(--m-text) !important;
132
+ --primary: var(--m-primary) !important;
133
+ --primary-foreground: var(--m-primary-ink) !important;
134
+ --secondary: var(--m-high) !important;
135
+ --secondary-foreground: var(--m-text-2) !important;
136
+ --muted: var(--m-raised) !important;
137
+ --muted-foreground: var(--m-text-3) !important;
138
+ --placeholder: var(--m-text-3) !important;
139
+ --border: var(--m-line) !important;
140
+ --card: var(--m-raised) !important;
141
+ --card-border: var(--m-line-2) !important;
142
+ --sidebar: var(--m-window) !important;
143
+ --sidebar-secondary: var(--m-select) !important;
144
+ --sidebar-muted: var(--m-raised) !important;
145
+ --link: var(--m-text-max) !important;
146
+ --code-foreground: var(--m-text) !important;
147
+ --success: var(--m-success) !important;
148
+ --warning: var(--m-warning) !important;
149
+ --error: var(--m-error) !important;
150
+ /* find in conversation / code */
151
+ --editor-find-match-background: var(--m-find) !important;
152
+ --editor-find-current-background: var(--m-find-current) !important;
153
+ --editor-find-current-border: var(--m-find-border) !important;
154
+ }
155
+
156
+ :root[data-agy-theme="matte"] {
157
+ --font-sans: var(--m-font-ui);
158
+ --font-mono: var(--m-font-mono);
159
+ --ring: var(--m-line-3);
160
+ --rt-color-dark: var(--m-high);
161
+ --rt-color-white: var(--m-text);
162
+ --rt-opacity: 1;
163
+ }
164
+
165
+ :root[data-agy-theme="matte"] body {
166
+ --focus-ring-color: var(--m-line-3);
167
+ }
168
+
169
+ /* Code colors: the app writes its code-color setting inline on <body>
170
+ (hence !important); while a theme is on, the theme owns them */
171
+ :root[data-agy-theme="matte"] .theme-dark {
172
+ --syntax-default-fg: #d4d4d4 !important;
173
+ --syntax-comment: #6e6e6e !important;
174
+ --syntax-punctuation: #d4d4d4 !important;
175
+ --syntax-operator: #d4d4d4 !important;
176
+ --syntax-variable: #d4d4d4 !important;
177
+ --syntax-keyword: #d19a66 !important;
178
+ --syntax-string: #a5c995 !important;
179
+ --syntax-attr-value: #a5c995 !important;
180
+ --syntax-inserted: #a5c995 !important;
181
+ --syntax-attr-name: #e3c98a !important;
182
+ --syntax-builtin: #e3c98a !important;
183
+ --syntax-function: #e3c98a !important;
184
+ --syntax-class-name: #e3c98a !important;
185
+ --syntax-number: #dca8a0 !important;
186
+ --syntax-constant: #dca8a0 !important;
187
+ --syntax-property: #e08b8b !important;
188
+ --syntax-tag: #e08b8b !important;
189
+ --syntax-deleted: #e08b8b !important;
190
+ --syntax-regex: #d9a066 !important;
191
+ --bg-selection: var(--m-selection) !important;
192
+ --bg-selection-overlay: var(--m-selection) !important;
193
+ --bg-cursor-line: var(--m-hover) !important;
194
+ }
195
+ /* The same quiet palette, dark enough for --m-inset (all 4.2:1 or more) */
196
+ :root[data-agy-theme="matte"] .theme-light {
197
+ --syntax-default-fg: #24242a !important;
198
+ --syntax-comment: #727279 !important;
199
+ --syntax-punctuation: #24242a !important;
200
+ --syntax-operator: #24242a !important;
201
+ --syntax-variable: #24242a !important;
202
+ --syntax-keyword: #984a14 !important;
203
+ --syntax-string: #3d6b29 !important;
204
+ --syntax-attr-value: #3d6b29 !important;
205
+ --syntax-inserted: #3d6b29 !important;
206
+ --syntax-attr-name: #755600 !important;
207
+ --syntax-builtin: #755600 !important;
208
+ --syntax-function: #755600 !important;
209
+ --syntax-class-name: #755600 !important;
210
+ --syntax-number: #9c3d34 !important;
211
+ --syntax-constant: #9c3d34 !important;
212
+ --syntax-property: #a1393b !important;
213
+ --syntax-tag: #a1393b !important;
214
+ --syntax-deleted: #a1393b !important;
215
+ --syntax-regex: #86500a !important;
216
+ --bg-selection: var(--m-selection) !important;
217
+ --bg-selection-overlay: var(--m-selection) !important;
218
+ --bg-cursor-line: var(--m-hover) !important;
219
+ }
220
+
221
+
222
+ /* 02 — Bridge: VS Code vars (inline on <html>; One Dark = the blue cast) -- */
223
+ :root[data-agy-theme="matte"] {
224
+ --vscode-foreground: var(--m-text) !important;
225
+ --vscode-focusBorder: var(--m-line-3) !important;
226
+ --vscode-textLink-foreground: var(--m-text-max) !important;
227
+ --vscode-textCodeBlock-background: var(--m-inset) !important;
228
+ --vscode-sideBar-background: var(--m-window) !important;
229
+ --vscode-editor-background: var(--m-inset) !important;
230
+ --vscode-editor-foreground: var(--m-text) !important;
231
+ --vscode-editor-lineHighlightBackground: var(--m-hover) !important;
232
+ --vscode-editor-selectionBackground: var(--m-selection) !important;
233
+ --vscode-editorCursor-foreground: var(--m-text-max) !important;
234
+ --vscode-editorLineNumber-foreground: var(--m-lineno) !important;
235
+ --vscode-editorLineNumber-activeForeground: var(--m-text-2) !important;
236
+ --vscode-editor-findMatchBackground: rgb(217 163 91 / 0.40) !important;
237
+ --vscode-editor-findMatchHighlightBackground: rgb(217 163 91 / 0.20) !important;
238
+ --vscode-editorWidget-background: var(--m-raised) !important;
239
+ --vscode-editorWidget-border: var(--m-line-2) !important;
240
+ --vscode-editorHoverWidget-background: var(--m-raised) !important;
241
+ --vscode-editorHoverWidget-border: var(--m-line-2) !important;
242
+ --vscode-input-background: var(--m-raised) !important;
243
+ --vscode-input-border: var(--m-line-2) !important;
244
+ --vscode-dropdown-background: var(--m-raised) !important;
245
+ --vscode-dropdown-border: var(--m-line-2) !important;
246
+ --vscode-button-background: var(--m-primary) !important;
247
+ --vscode-button-foreground: var(--m-primary-ink) !important;
248
+ --vscode-button-hoverBackground: var(--m-strong) !important;
249
+ --vscode-badge-background: var(--m-high) !important;
250
+ --vscode-badge-foreground: var(--m-text) !important;
251
+ --vscode-list-hoverBackground: var(--m-hover) !important;
252
+ --vscode-list-focusBackground: var(--m-select) !important;
253
+ --vscode-list-activeSelectionBackground: var(--m-select) !important;
254
+ --vscode-list-inactiveSelectionBackground: var(--m-hover) !important;
255
+ --vscode-scrollbarSlider-background: var(--m-scroll) !important;
256
+ --vscode-scrollbarSlider-hoverBackground: var(--m-scroll-2) !important;
257
+ --vscode-scrollbarSlider-activeBackground: var(--m-scroll-3) !important;
258
+ --vscode-diffEditor-insertedLineBackground: rgb(111 191 139 / 0.10) !important;
259
+ --vscode-diffEditor-insertedTextBackground: rgb(111 191 139 / 0.22) !important;
260
+ --vscode-diffEditor-removedLineBackground: rgb(224 108 108 / 0.10) !important;
261
+ --vscode-diffEditor-removedTextBackground: rgb(224 108 108 / 0.22) !important;
262
+ }
263
+
264
+
265
+ /* 03 — Base ---------------------------------------------------------------- */
266
+ :root[data-agy-theme="matte"] body {
267
+ -webkit-font-smoothing: antialiased;
268
+ }
269
+ ::selection {
270
+ background: var(--m-selection);
271
+ }
272
+ /* The app's ::highlight rules read the find colors crosswise (every match
273
+ in the "current" color): restated the right way round */
274
+ :root[data-agy-theme="matte"] ::highlight(find-match-highlight) {
275
+ background-color: var(--editor-find-match-background);
276
+ }
277
+ :root[data-agy-theme="matte"] ::highlight(find-match-current) {
278
+ background-color: var(--editor-find-current-background);
279
+ }
280
+
281
+
282
+ /* 10 — Frame: one rounded panel in a darker window ------------------------- */
283
+ /* The content pane (Tailwind class group/pane, one per pane) becomes the
284
+ panel. Re-pointing --background (and Tailwind's resolved
285
+ --color-background) here makes every bg-background / var(--background)
286
+ layer inside the panel match it: the pinned user-message band, the fade
287
+ above the composer, sticky headers. */
288
+ :root[data-agy-theme="matte"] .group\/pane {
289
+ --background: var(--m-panel);
290
+ --color-background: var(--m-panel);
291
+ width: auto;
292
+ height: calc(100% - 8px);
293
+ /* No outline: flush against the sidebar a 1px ring reads as a divider.
294
+ Tone alone (#151517 on #0e0e10) marks the panel; a 6px gap lets its
295
+ corners read as a card. */
296
+ margin: 0 8px 8px 6px;
297
+ border-radius: 14px;
298
+ background: var(--m-panel);
299
+ overflow: hidden;
300
+ }
301
+
302
+ /* Full-height 1px divider between sidebar and panel (holds the resize sash,
303
+ so it keeps its box; only the line goes). Tailwind class hook. */
304
+ :root[data-agy-theme="matte"] .bg-border.flex-shrink-0.z-30.h-full {
305
+ background: transparent;
306
+ }
307
+
308
+ /* The right-hand pane (terminal, task output, files): its tab strip stays
309
+ on the window like the conversation's title row, and the content below
310
+ it becomes the same rounded panel. Markup (2.26):
311
+ flex-col > [data-active-tab-id] (tab strip, border-b) + .flex-grow */
312
+ :root[data-agy-theme="matte"] [data-active-tab-id] {
313
+ border-bottom-color: transparent;
314
+ }
315
+ :root[data-agy-theme="matte"] [data-active-tab-id] + .flex-grow {
316
+ --background: var(--m-panel);
317
+ --color-background: var(--m-panel);
318
+ margin: 0 8px 8px 0;
319
+ border-radius: 14px;
320
+ background: var(--m-panel);
321
+ }
322
+
323
+
324
+ /* 20 — Sidebar ------------------------------------------------------------- */
325
+ /* Row hover is the app's own hover:bg-sidebar-muted: it also sets --row-bg,
326
+ which the action buttons' fade gradient uses, so the two always match.
327
+ (A separate hover color here left a lighter block behind the buttons.)
328
+ The action group sat 4px past the row's end; keep it inside the corners.
329
+ Tailwind class hook. */
330
+ :root[data-agy-theme="matte"] [data-testid="conversation-row-sidebar"] .pl-6.justify-end {
331
+ right: 0;
332
+ border-radius: 0 8px 8px 0;
333
+ }
334
+ :root[data-agy-theme="matte"] [data-testid="conversation-row-sidebar"][data-selected="true"] span {
335
+ color: var(--m-text-max);
336
+ }
337
+
338
+
339
+ /* 30 — Conversation -------------------------------------------------------- */
340
+ :root[data-agy-theme="matte"] [role="article"] h1,
341
+ :root[data-agy-theme="matte"] [role="article"] h2,
342
+ :root[data-agy-theme="matte"] [role="article"] h3 {
343
+ font-family: var(--m-font-display);
344
+ font-weight: 600;
345
+ letter-spacing: -0.01em;
346
+ color: var(--m-text-max);
347
+ }
348
+ :root[data-agy-theme="matte"] [role="article"] a {
349
+ text-decoration: underline;
350
+ text-decoration-color: var(--m-line-3);
351
+ text-underline-offset: 3px;
352
+ }
353
+ :root[data-agy-theme="matte"] [role="article"] a:hover {
354
+ text-decoration-color: var(--m-text-2);
355
+ }
356
+ /* Fenced code: the card inside <pre> (bg-muted) sits darker than the panel */
357
+ :root[data-agy-theme="matte"] [role="article"] pre > div {
358
+ border-radius: 12px;
359
+ background: var(--m-inset);
360
+ --agy-lineno: var(--m-lineno); /* code-tools.js line numbers */
361
+ }
362
+
363
+
364
+ /* 40 — Composer ------------------------------------------------------------ */
365
+ /* The shell's 1px ring is its padded background (p-px bg-card-border).
366
+ Focus only brightens that ring: no movement, no glow. The app's own
367
+ click-anywhere-to-focus is opted out for the transcript in
368
+ src/theme-host.js. */
369
+ :root[data-agy-theme="matte"] [id="antigravity.agentSidePanelInputBox"] {
370
+ box-shadow: 0 10px 28px -14px var(--m-shadow);
371
+ }
372
+ :root[data-agy-theme="matte"] [id="antigravity.agentSidePanelInputBox"]:focus-within {
373
+ background: var(--m-line-3);
374
+ }
375
+
376
+
377
+ /* 50 — Menus & tooltips ---------------------------------------------------- */
378
+ :root[data-agy-theme="matte"] [role="menu"] {
379
+ border-color: var(--m-line-2);
380
+ border-radius: 12px;
381
+ box-shadow: 0 16px 40px -12px var(--m-shadow-menu);
382
+ }
383
+ /* App tooltips are bg-card, the composer's color: give them their own
384
+ surface so "Select Model Ctrl+/" never reads as text over the input. */
385
+ :root[data-agy-theme="matte"] .compact-tooltip {
386
+ border-color: var(--m-line-2);
387
+ background: var(--m-high);
388
+ color: var(--m-text-max);
389
+ box-shadow: 0 8px 20px -8px var(--m-shadow);
390
+ }