@artooi/ag-ui-web-component 0.44.0 → 0.46.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.
- package/CHANGELOG.md +182 -1
- package/README.md +245 -32
- package/dist/ag-ui-web-component.bundle.js +3696 -2798
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +4 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +28 -8
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/read_flag.d.ts +11 -0
- package/dist/core/read_flag.d.ts.map +1 -0
- package/dist/core/read_json_attribute.d.ts +15 -0
- package/dist/core/read_json_attribute.d.ts.map +1 -0
- package/dist/index.js +5084 -3481
- package/dist/index.js.map +4 -4
- package/dist/tools/tool_catalog.d.ts +5 -0
- package/dist/tools/tool_catalog.d.ts.map +1 -1
- package/dist/tools/tool_dispatch.d.ts.map +1 -1
- package/dist/ui/charts/chart_styles.d.ts +2 -0
- package/dist/ui/charts/chart_styles.d.ts.map +1 -0
- package/dist/ui/composer/attachment_styles.d.ts +2 -0
- package/dist/ui/composer/attachment_styles.d.ts.map +1 -0
- package/dist/ui/composer/build_composer.d.ts +30 -0
- package/dist/ui/composer/build_composer.d.ts.map +1 -0
- package/dist/ui/composer/composer_styles.d.ts +2 -0
- package/dist/ui/composer/composer_styles.d.ts.map +1 -0
- package/dist/ui/composer/skill_styles.d.ts +2 -0
- package/dist/ui/composer/skill_styles.d.ts.map +1 -0
- package/dist/ui/history/history_styles.d.ts +2 -0
- package/dist/ui/history/history_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/approval_styles.d.ts +2 -0
- package/dist/ui/interrupts/approval_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/confirmation_styles.d.ts +2 -0
- package/dist/ui/interrupts/confirmation_styles.d.ts.map +1 -0
- package/dist/ui/interrupts/question_styles.d.ts +2 -0
- package/dist/ui/interrupts/question_styles.d.ts.map +1 -0
- package/dist/ui/placement/collapse_styles.d.ts +2 -0
- package/dist/ui/placement/collapse_styles.d.ts.map +1 -0
- package/dist/ui/placement/embedded_styles.d.ts +2 -0
- package/dist/ui/placement/embedded_styles.d.ts.map +1 -0
- package/dist/ui/placement/launcher_styles.d.ts +2 -0
- package/dist/ui/placement/launcher_styles.d.ts.map +1 -0
- package/dist/ui/placement/page_styles.d.ts +2 -0
- package/dist/ui/placement/page_styles.d.ts.map +1 -0
- package/dist/ui/placement/panel_placement.d.ts.map +1 -1
- package/dist/ui/placement/preset_styles.d.ts +2 -0
- package/dist/ui/placement/preset_styles.d.ts.map +1 -0
- package/dist/ui/placement/resize_styles.d.ts +2 -0
- package/dist/ui/placement/resize_styles.d.ts.map +1 -0
- package/dist/ui/placement/sidebar_styles.d.ts +2 -0
- package/dist/ui/placement/sidebar_styles.d.ts.map +1 -0
- package/dist/ui/placement/small_viewport_styles.d.ts +2 -0
- package/dist/ui/placement/small_viewport_styles.d.ts.map +1 -0
- package/dist/ui/placement/surface_for.d.ts +74 -0
- package/dist/ui/placement/surface_for.d.ts.map +1 -0
- package/dist/ui/progress/run_notice_styles.d.ts +2 -0
- package/dist/ui/progress/run_notice_styles.d.ts.map +1 -0
- package/dist/ui/progress/thoughts_styles.d.ts +2 -0
- package/dist/ui/progress/thoughts_styles.d.ts.map +1 -0
- package/dist/ui/progress/tool_call_card.d.ts +8 -0
- package/dist/ui/progress/tool_call_card.d.ts.map +1 -1
- package/dist/ui/progress/tool_group_styles.d.ts +2 -0
- package/dist/ui/progress/tool_group_styles.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_group.d.ts +47 -0
- package/dist/ui/progress/tool_step_group.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_styles.d.ts +2 -0
- package/dist/ui/progress/tool_step_styles.d.ts.map +1 -0
- package/dist/ui/shell/adopt_styles.d.ts +9 -4
- package/dist/ui/shell/adopt_styles.d.ts.map +1 -1
- package/dist/ui/shell/build_header.d.ts +40 -0
- package/dist/ui/shell/build_header.d.ts.map +1 -0
- package/dist/ui/shell/build_launcher.d.ts +20 -0
- package/dist/ui/shell/build_launcher.d.ts.map +1 -0
- package/dist/ui/shell/frame_styles.d.ts +2 -0
- package/dist/ui/shell/frame_styles.d.ts.map +1 -0
- package/dist/ui/shell/theme_styles.d.ts +2 -0
- package/dist/ui/shell/theme_styles.d.ts.map +1 -0
- package/dist/ui/shell/token_styles.d.ts +2 -0
- package/dist/ui/shell/token_styles.d.ts.map +1 -0
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/themes/classic_styles.d.ts +2 -0
- package/dist/ui/themes/classic_styles.d.ts.map +1 -0
- package/dist/ui/themes/classic_tokens.d.ts +2 -0
- package/dist/ui/themes/classic_tokens.d.ts.map +1 -0
- package/dist/ui/themes/code_tokens.d.ts +2 -0
- package/dist/ui/themes/code_tokens.d.ts.map +1 -0
- package/dist/ui/themes/ledger_styles.d.ts +2 -0
- package/dist/ui/themes/ledger_styles.d.ts.map +1 -0
- package/dist/ui/themes/ledger_tokens.d.ts +2 -0
- package/dist/ui/themes/ledger_tokens.d.ts.map +1 -0
- package/dist/ui/themes/modern_styles.d.ts +2 -0
- package/dist/ui/themes/modern_styles.d.ts.map +1 -0
- package/dist/ui/themes/quiet_styles.d.ts +2 -0
- package/dist/ui/themes/quiet_styles.d.ts.map +1 -0
- package/dist/ui/themes/scheme_styles.d.ts +2 -0
- package/dist/ui/themes/scheme_styles.d.ts.map +1 -0
- package/dist/ui/themes/soft_styles.d.ts +2 -0
- package/dist/ui/themes/soft_styles.d.ts.map +1 -0
- package/dist/ui/themes/soft_tokens.d.ts +2 -0
- package/dist/ui/themes/soft_tokens.d.ts.map +1 -0
- package/dist/ui/themes/theme_hosts.d.ts +15 -0
- package/dist/ui/themes/theme_hosts.d.ts.map +1 -0
- package/dist/ui/transcript/attachment_chip_styles.d.ts +2 -0
- package/dist/ui/transcript/attachment_chip_styles.d.ts.map +1 -0
- package/dist/ui/transcript/build_transcript.d.ts +21 -0
- package/dist/ui/transcript/build_transcript.d.ts.map +1 -0
- package/dist/ui/transcript/greeting_styles.d.ts +2 -0
- package/dist/ui/transcript/greeting_styles.d.ts.map +1 -0
- package/dist/ui/transcript/groups_tool_steps.d.ts +13 -0
- package/dist/ui/transcript/groups_tool_steps.d.ts.map +1 -0
- package/dist/ui/transcript/message_action_styles.d.ts +2 -0
- package/dist/ui/transcript/message_action_styles.d.ts.map +1 -0
- package/dist/ui/transcript/message_styles.d.ts +2 -0
- package/dist/ui/transcript/message_styles.d.ts.map +1 -0
- package/dist/ui/transcript/transcript.d.ts +16 -1
- package/dist/ui/transcript/transcript.d.ts.map +1 -1
- package/dist/ui/transcript/transcript_styles.d.ts +2 -0
- package/dist/ui/transcript/transcript_styles.d.ts.map +1 -0
- package/dist/ui/ui_strings.d.ts +18 -0
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/constants.ts +4 -1
- package/src/core/ag_ui_chat.ts +164 -299
- package/src/core/read_flag.ts +13 -0
- package/src/core/read_json_attribute.ts +30 -0
- package/src/tools/tool_catalog.ts +23 -10
- package/src/tools/tool_dispatch.ts +26 -11
- package/src/ui/charts/chart_block.ts +9 -9
- package/src/ui/charts/chart_styles.ts +63 -0
- package/src/ui/composer/attachment_styles.ts +71 -0
- package/src/ui/composer/build_composer.ts +112 -0
- package/src/ui/composer/composer_styles.ts +174 -0
- package/src/ui/composer/skill_styles.ts +120 -0
- package/src/ui/history/history_styles.ts +484 -0
- package/src/ui/interrupts/approval_styles.ts +52 -0
- package/src/ui/interrupts/confirmation_styles.ts +114 -0
- package/src/ui/interrupts/question_styles.ts +73 -0
- package/src/ui/placement/collapse_styles.ts +137 -0
- package/src/ui/placement/embedded_styles.ts +14 -0
- package/src/ui/placement/launcher_styles.ts +189 -0
- package/src/ui/placement/page_styles.ts +47 -0
- package/src/ui/placement/panel_placement.ts +3 -12
- package/src/ui/placement/preset_styles.ts +33 -0
- package/src/ui/placement/resize_styles.ts +186 -0
- package/src/ui/placement/sidebar_styles.ts +88 -0
- package/src/ui/placement/small_viewport_styles.ts +56 -0
- package/src/ui/placement/surface_for.ts +135 -0
- package/src/ui/progress/run_notice_styles.ts +52 -0
- package/src/ui/progress/thoughts_styles.ts +65 -0
- package/src/ui/progress/tool_call_card.ts +11 -0
- package/src/ui/progress/tool_group_styles.ts +232 -0
- package/src/ui/progress/tool_step_group.ts +269 -0
- package/src/ui/progress/tool_step_styles.ts +472 -0
- package/src/ui/shell/adopt_styles.ts +11 -5
- package/src/ui/shell/build_header.ts +108 -0
- package/src/ui/shell/build_launcher.ts +50 -0
- package/src/ui/shell/frame_styles.ts +119 -0
- package/src/ui/shell/theme_styles.ts +11 -0
- package/src/ui/shell/token_styles.ts +406 -0
- package/src/ui/styles.ts +104 -3774
- package/src/ui/themes/classic_styles.ts +32 -0
- package/src/ui/themes/classic_tokens.ts +50 -0
- package/src/ui/themes/code_tokens.ts +21 -0
- package/src/ui/themes/ledger_styles.ts +168 -0
- package/src/ui/themes/ledger_tokens.ts +32 -0
- package/src/ui/themes/modern_styles.ts +80 -0
- package/src/ui/themes/quiet_styles.ts +115 -0
- package/src/ui/themes/scheme_styles.ts +17 -0
- package/src/ui/themes/soft_styles.ts +148 -0
- package/src/ui/themes/soft_tokens.ts +28 -0
- package/src/ui/themes/theme_hosts.ts +14 -0
- package/src/ui/transcript/attachment_chip_styles.ts +116 -0
- package/src/ui/transcript/build_transcript.ts +67 -0
- package/src/ui/transcript/greeting_styles.ts +171 -0
- package/src/ui/transcript/groups_tool_steps.ts +16 -0
- package/src/ui/transcript/message_action_styles.ts +155 -0
- package/src/ui/transcript/message_styles.ts +262 -0
- package/src/ui/transcript/transcript.ts +109 -3
- package/src/ui/transcript/transcript_styles.ts +140 -0
- package/src/ui/ui_strings.ts +31 -0
- package/src/version.ts +1 -1
- package/dist/ui/placement/is_collapsible_placement.d.ts +0 -18
- package/dist/ui/placement/is_collapsible_placement.d.ts.map +0 -1
- package/dist/ui/placement/is_draggable_placement.d.ts +0 -9
- package/dist/ui/placement/is_draggable_placement.d.ts.map +0 -1
- package/src/ui/placement/is_collapsible_placement.ts +0 -19
- package/src/ui/placement/is_draggable_placement.ts +0 -23
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// The panel itself and its header: title, icon holder and header controls.
|
|
2
|
+
export const FRAME_STYLES: string = `
|
|
3
|
+
.chat {
|
|
4
|
+
position: relative;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
flex: 1;
|
|
8
|
+
min-height: 0;
|
|
9
|
+
background: var(--_bg);
|
|
10
|
+
border: 1px solid var(--_border);
|
|
11
|
+
border-radius: var(--_panel-radius);
|
|
12
|
+
box-shadow: var(--_shadow);
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.header {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: space-between;
|
|
20
|
+
gap: 8px;
|
|
21
|
+
padding: 10px 14px;
|
|
22
|
+
border-bottom: 1px solid var(--_border);
|
|
23
|
+
background: var(--_header-bg);
|
|
24
|
+
color: var(--_header-fg);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* The header is the panel's title bar: on the placements that let the widget
|
|
28
|
+
be moved it drags the whole thing, matching the launcher's own drag. The
|
|
29
|
+
selector lists those placements rather than asking JS to stamp an attribute,
|
|
30
|
+
because a cursor that appears one frame late reads as a control that only
|
|
31
|
+
sometimes exists. touch-action keeps a finger drag here moving the panel
|
|
32
|
+
instead of scrolling the page behind it. */
|
|
33
|
+
:host(:not([placement])) .header,
|
|
34
|
+
:host([placement=""]) .header,
|
|
35
|
+
:host([placement="floating"]) .header,
|
|
36
|
+
:host([placement="bottom-left"]) .header {
|
|
37
|
+
cursor: move;
|
|
38
|
+
touch-action: none;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* A host that turned the drag off keeps a header that says so. */
|
|
42
|
+
:host([data-launcher-drag="false"]) .header {
|
|
43
|
+
cursor: auto;
|
|
44
|
+
touch-action: auto;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* :host is carried for the specificity, not the scope: the placement rules
|
|
48
|
+
above are a host selector plus a class plus an attribute, and a bare
|
|
49
|
+
.header[data-dragging] loses to them -- silently, because the drag still
|
|
50
|
+
works and only the cursor is wrong. */
|
|
51
|
+
:host .header[data-dragging] {
|
|
52
|
+
cursor: grabbing;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* The cursor inherits, so a control a host slots into the header would show
|
|
56
|
+
the drag cursor over something the drag deliberately ignores. Named to
|
|
57
|
+
match the controls panel_drag steps aside for. */
|
|
58
|
+
.header ::slotted(:is(button, a, input, select, textarea)) {
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.header-title {
|
|
63
|
+
flex: 1;
|
|
64
|
+
min-width: 0;
|
|
65
|
+
font-weight: 600;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
text-overflow: ellipsis;
|
|
68
|
+
white-space: nowrap;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Header / launcher icon holder: a slot, with a data-icon-url <img>
|
|
72
|
+
fallback, sized via --ag-ui-icon-size. */
|
|
73
|
+
.icon-holder {
|
|
74
|
+
display: inline-flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
flex: none;
|
|
78
|
+
width: var(--_icon-size);
|
|
79
|
+
height: var(--_icon-size);
|
|
80
|
+
line-height: 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.icon-img {
|
|
84
|
+
width: 100%;
|
|
85
|
+
height: 100%;
|
|
86
|
+
object-fit: contain;
|
|
87
|
+
border-radius: var(--_icon-radius);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.header-controls {
|
|
91
|
+
display: flex;
|
|
92
|
+
gap: var(--_header-gap);
|
|
93
|
+
flex: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.header-btn {
|
|
97
|
+
display: inline-flex;
|
|
98
|
+
flex: 0 0 auto;
|
|
99
|
+
align-items: center;
|
|
100
|
+
justify-content: center;
|
|
101
|
+
box-sizing: border-box;
|
|
102
|
+
width: var(--_header-btn-size);
|
|
103
|
+
height: var(--_header-btn-size);
|
|
104
|
+
border: none;
|
|
105
|
+
background: transparent;
|
|
106
|
+
color: inherit;
|
|
107
|
+
font: inherit;
|
|
108
|
+
line-height: 1;
|
|
109
|
+
padding: 0;
|
|
110
|
+
border-radius: 6px;
|
|
111
|
+
cursor: pointer;
|
|
112
|
+
opacity: 0.85;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.header-btn:hover {
|
|
116
|
+
opacity: 1;
|
|
117
|
+
background: rgba(255, 255, 255, 0.18);
|
|
118
|
+
}
|
|
119
|
+
`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// The density presets: token overrides only. The themes live in ui/themes.
|
|
2
|
+
export const THEME_STYLES: string = `
|
|
3
|
+
/* ── Density ────────────────────────────────────────────────────────────── */
|
|
4
|
+
:host([density="compact"]) {
|
|
5
|
+
--_font-size: var(--ag-ui-font-size, 13px);
|
|
6
|
+
--_space: var(--ag-ui-space, 6px);
|
|
7
|
+
--_pad: var(--ag-ui-pad, 10px);
|
|
8
|
+
--_msg-pad: var(--ag-ui-msg-pad, 5px 9px);
|
|
9
|
+
--_msg-radius: var(--ag-ui-msg-radius, 10px);
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
// Every public --ag-ui-* token read into its private --_* alias on :host.
|
|
2
|
+
// This is where the token defaults are declared; see the block comment below.
|
|
3
|
+
export const TOKEN_STYLES: string = `
|
|
4
|
+
/* ── Token defaults ─────────────────────────────────────────────────────────
|
|
5
|
+
Every public --ag-ui-* token is read here into a private --_* alias, and
|
|
6
|
+
only the alias is used by the rules below.
|
|
7
|
+
|
|
8
|
+
The indirection is what makes ancestor theming work. Declaring the public
|
|
9
|
+
name on :host would set it on the host element, and a value on an element
|
|
10
|
+
always beats one inherited from an ancestor, so tokens put on a wrapper
|
|
11
|
+
would have no effect. Reading the public name with the default as a var()
|
|
12
|
+
fallback leaves it undeclared on the element, so an ancestor's value
|
|
13
|
+
inherits normally while one aimed at the element still wins.
|
|
14
|
+
|
|
15
|
+
Two invariants hold this together:
|
|
16
|
+
1. No rule outside a :host block may reference a public name
|
|
17
|
+
directly. A public name read outside these blocks resolves to nothing and
|
|
18
|
+
silently drops its declaration rather than erroring, so the miss shows up
|
|
19
|
+
as a missing colour, not a failure.
|
|
20
|
+
2. Every --_* alias in use is declared here. Aliases inherit like any custom
|
|
21
|
+
property, so an undeclared one would pick up a same-named property from
|
|
22
|
+
the host page; declaring it on :host shields the shadow tree from that. */
|
|
23
|
+
:host {
|
|
24
|
+
/* Colors. The default theme, Quiet: three seeds, and every other shade
|
|
25
|
+
mixed from them in oklch, so a host that sets only --ag-ui-accent (or
|
|
26
|
+
only the background and text) gets a whole widget rethemed. The seeds use
|
|
27
|
+
light-dark, so the scheme word on the theme attribute picks the half;
|
|
28
|
+
see scheme_styles in the themes directory. Every derived shade still
|
|
29
|
+
reads its own public token first, so each stays an override point. */
|
|
30
|
+
color-scheme: light;
|
|
31
|
+
--_bg: var(--ag-ui-bg, light-dark(#ffffff, #161618));
|
|
32
|
+
--_fg: var(--ag-ui-fg, light-dark(#1b1b1d, #ececee));
|
|
33
|
+
--_accent: var(--ag-ui-accent, light-dark(#232326, #f0f0f2));
|
|
34
|
+
--_ink-2: var(--ag-ui-ink-2, color-mix(in oklch, var(--_fg) 78%, var(--_bg)));
|
|
35
|
+
--_ink-3: var(--ag-ui-ink-3, color-mix(in oklch, var(--_fg) 64%, var(--_bg)));
|
|
36
|
+
--_line: var(--ag-ui-line, color-mix(in oklch, var(--_fg) 11%, var(--_bg)));
|
|
37
|
+
--_line-strong: var(--ag-ui-line-strong, color-mix(in oklch, var(--_fg) 20%, var(--_bg)));
|
|
38
|
+
--_wash: var(--ag-ui-wash, color-mix(in oklch, var(--_fg) 4.5%, var(--_bg)));
|
|
39
|
+
--_accent-ink: var(--ag-ui-accent-ink, color-mix(in oklch, var(--_accent) 82%, var(--_fg)));
|
|
40
|
+
--_ring: var(--ag-ui-ring, color-mix(in oklch, var(--_accent) 55%, transparent));
|
|
41
|
+
/* The user's turn is the accent at a whisper. With Quiet's graphite accent
|
|
42
|
+
that is a neutral wash; once a host sets a brand accent it becomes a tint
|
|
43
|
+
of the brand, which is the one thing Soft does that Quiet keeps. */
|
|
44
|
+
--_user-bg: var(--ag-ui-user-bg, color-mix(in oklch, var(--_accent) 12%, var(--_bg)));
|
|
45
|
+
--_user-fg: var(--ag-ui-user-fg, var(--_fg));
|
|
46
|
+
--_assistant-bg: var(--ag-ui-assistant-bg, transparent);
|
|
47
|
+
--_hover: var(--ag-ui-hover, color-mix(in oklch, var(--_fg) 6%, var(--_bg)));
|
|
48
|
+
--_input-bg: var(--ag-ui-input-bg, var(--_bg));
|
|
49
|
+
--_tool-bg: var(--ag-ui-tool-bg, transparent);
|
|
50
|
+
--_tool-fg: var(--ag-ui-tool-fg, var(--_ink-2));
|
|
51
|
+
--_header-bg: var(--ag-ui-header-bg, var(--_bg));
|
|
52
|
+
--_header-fg: var(--ag-ui-header-fg, var(--_fg));
|
|
53
|
+
--_border: var(--ag-ui-border, var(--_line));
|
|
54
|
+
--_radius: var(--ag-ui-radius, 12px);
|
|
55
|
+
/* The panel's own frame, which is the one corner a placement can put against
|
|
56
|
+
the edge of the viewport. The placements that do (page, sidebar, side, full,
|
|
57
|
+
and all but embedded on a small viewport) square this and leave --_radius alone, so
|
|
58
|
+
the answer well and the controls inside the panel stay as round as the
|
|
59
|
+
theme says: none of them meets that edge. */
|
|
60
|
+
/* What a theme sets for the frame; the effective value below is what a
|
|
61
|
+
placement squares, so the two never fight over one property. A host's
|
|
62
|
+
--ag-ui-radius still rounds the frame, as it did before themes gave the
|
|
63
|
+
frame a radius of its own; only the theme's own default differs. */
|
|
64
|
+
--_frame-radius: var(--ag-ui-frame-radius, var(--ag-ui-radius, 14px));
|
|
65
|
+
--_panel-radius: var(--ag-ui-panel-radius, var(--_frame-radius));
|
|
66
|
+
|
|
67
|
+
/* Body text and raised chrome, read only by the code-block copy button.
|
|
68
|
+
The defaults restate what it inherits, so a host that sets neither sees
|
|
69
|
+
no repaint — see the note on .code-copy. */
|
|
70
|
+
--_text: var(--ag-ui-text, var(--_fg));
|
|
71
|
+
--_surface: var(--ag-ui-surface, transparent);
|
|
72
|
+
|
|
73
|
+
/* Message action row: the control box and the mark inside it. The box has a
|
|
74
|
+
floor of 24px so it stays a reliable target at every density. */
|
|
75
|
+
--_action-size: var(--ag-ui-action-size, 28px);
|
|
76
|
+
/* The header's own controls. Sized rather than left to their contents: a row
|
|
77
|
+
of buttons each as wide as the glyph inside it comes out uneven, and uneven
|
|
78
|
+
buttons two pixels apart read as one smudge rather than five controls. */
|
|
79
|
+
--_header-btn-size: var(--ag-ui-header-btn-size, 30px);
|
|
80
|
+
--_header-gap: var(--ag-ui-header-gap, 4px);
|
|
81
|
+
--_action-icon-size: var(--ag-ui-action-icon-size, 15px);
|
|
82
|
+
--_tooltip-bg: var(--ag-ui-tooltip-bg, var(--_fg));
|
|
83
|
+
--_tooltip-fg: var(--ag-ui-tooltip-fg, var(--_bg));
|
|
84
|
+
|
|
85
|
+
/* Text and marks drawn on top of the accent and danger fills. Separate
|
|
86
|
+
tokens because they are not free: a host that themes the accent to a pale
|
|
87
|
+
colour has white-on-pale with no way to correct it, which is the one
|
|
88
|
+
theming change that makes a control unreadable rather than merely off. */
|
|
89
|
+
/* Picked from the accent's own luminance where relative colour syntax is
|
|
90
|
+
supported (the first block after this rule). Without it, this value: the
|
|
91
|
+
scheme's colour, which is the right side for each newer theme's own
|
|
92
|
+
accent in both schemes. Classic and code take white instead, in the
|
|
93
|
+
second block. */
|
|
94
|
+
--_on-accent: var(--ag-ui-on-accent, light-dark(#ffffff, #111111));
|
|
95
|
+
--_on-danger: var(--ag-ui-on-danger, #ffffff);
|
|
96
|
+
|
|
97
|
+
/* Resize grips: the corner squares and the edge strips between them. Wide
|
|
98
|
+
enough to hit without being wide enough to swallow a click on the content
|
|
99
|
+
underneath, and adjustable for a host with a coarser pointer. */
|
|
100
|
+
--_grip-corner: var(--ag-ui-grip-corner, 14px);
|
|
101
|
+
--_grip-edge: var(--ag-ui-grip-edge, 6px);
|
|
102
|
+
--_grip-edge-docked: var(--ag-ui-grip-edge-docked, 8px);
|
|
103
|
+
/* The mark drawn inside a grip, as opposed to the area it answers to. */
|
|
104
|
+
--_grip-mark-length: var(--ag-ui-grip-mark-length, 28px);
|
|
105
|
+
--_grip-mark-thickness: var(--ag-ui-grip-mark-thickness, 3px);
|
|
106
|
+
|
|
107
|
+
/* Status accents for tool-call cards. */
|
|
108
|
+
--_success: var(--ag-ui-success, light-dark(#15803d, #4ade80));
|
|
109
|
+
--_danger: var(--ag-ui-danger, light-dark(#b91c1c, #f87171));
|
|
110
|
+
--_muted: var(--ag-ui-muted, var(--_ink-3));
|
|
111
|
+
|
|
112
|
+
/* Tool-call status icon glyphs (override to re-theme) + spinner speed.
|
|
113
|
+
The pending state is the animated ring; the settled states use these. */
|
|
114
|
+
--_tool-icon-done: var(--ag-ui-tool-icon-done, "✓");
|
|
115
|
+
--_tool-icon-error: var(--ag-ui-tool-icon-error, "✕");
|
|
116
|
+
--_tool-icon-declined: var(--ag-ui-tool-icon-declined, "⊘");
|
|
117
|
+
--_tool-icon-interrupted: var(--ag-ui-tool-icon-interrupted, "◌");
|
|
118
|
+
|
|
119
|
+
/* Disclosure marks on every expandable row. Tokenised for the same reason
|
|
120
|
+
the status icons above are: a host re-theming one set and not the other
|
|
121
|
+
ends up with two vocabularies in one transcript. */
|
|
122
|
+
--_disclosure-collapsed: var(--ag-ui-disclosure-collapsed, "▸");
|
|
123
|
+
--_disclosure-expanded: var(--ag-ui-disclosure-expanded, "▾");
|
|
124
|
+
--_tool-spin-duration: var(--ag-ui-tool-spin-duration, 0.7s);
|
|
125
|
+
|
|
126
|
+
/* Answer well (opt-in via data-answer-well) — boxes a whole assistant turn. */
|
|
127
|
+
--_well-bg: var(--ag-ui-well-bg, transparent);
|
|
128
|
+
--_well-border: var(--ag-ui-well-border, var(--_border));
|
|
129
|
+
--_well-radius: var(--ag-ui-well-radius, var(--_radius));
|
|
130
|
+
|
|
131
|
+
/* Surface — set --ag-ui-shadow: none for a flush, embedded panel. */
|
|
132
|
+
--_frame-shadow: var(--ag-ui-frame-shadow, 0 1px 2px light-dark(rgb(0 0 0 / 0.05), rgb(255 255 255 / 0.04)), 0 12px 32px -16px light-dark(rgb(0 0 0 / 0.22), rgb(0 0 0 / 0.7)));
|
|
133
|
+
--_shadow: var(--ag-ui-shadow, var(--_frame-shadow));
|
|
134
|
+
--_font: var(--ag-ui-font, Inter, ui-sans-serif, system-ui, sans-serif);
|
|
135
|
+
--_serif: var(--ag-ui-serif, Charter, "Bitstream Charter", "Iowan Old Style", Georgia, serif);
|
|
136
|
+
--_font-size: var(--ag-ui-font-size, var(--_text-md));
|
|
137
|
+
/* The type scale. */
|
|
138
|
+
--_text-xs: var(--ag-ui-text-xs, 11.5px);
|
|
139
|
+
--_text-sm: var(--ag-ui-text-sm, 12.5px);
|
|
140
|
+
--_text-md: var(--ag-ui-text-md, 14px);
|
|
141
|
+
--_text-lg: var(--ag-ui-text-lg, 16px);
|
|
142
|
+
--_leading: var(--ag-ui-leading, 1.55);
|
|
143
|
+
--_code-font: var(--ag-ui-code-font, ui-monospace, "SF Mono", Menlo, monospace);
|
|
144
|
+
|
|
145
|
+
/* Header / launcher icon box. */
|
|
146
|
+
--_icon-size: var(--ag-ui-icon-size, 22px);
|
|
147
|
+
--_icon-radius: var(--ag-ui-icon-radius, 4px);
|
|
148
|
+
|
|
149
|
+
/* Composer — one bordered surface holding the field and its tool row. */
|
|
150
|
+
--_composer-radius: var(--ag-ui-composer-radius, 12px);
|
|
151
|
+
--_composer-max-height: var(--ag-ui-composer-max-height, 40vh);
|
|
152
|
+
--_tool-btn-size: var(--ag-ui-tool-btn-size, 30px);
|
|
153
|
+
--_send-size: var(--ag-ui-send-size, 30px);
|
|
154
|
+
--_glyph-size: var(--ag-ui-glyph-size, 18px);
|
|
155
|
+
--_glyph-stroke: var(--ag-ui-glyph-stroke, 1.75);
|
|
156
|
+
|
|
157
|
+
/* How wide a chart is allowed to get. A cap rather than a width: below it
|
|
158
|
+
the chart fills its column, and above it a wider panel is just a wider
|
|
159
|
+
panel. */
|
|
160
|
+
--_chart-max-width: var(--ag-ui-chart-max-width, 480px);
|
|
161
|
+
/* Chart series. Quiet draws in ink and keeps hues for the series past two. */
|
|
162
|
+
--_chart-1: var(--ag-ui-chart-1, var(--_fg));
|
|
163
|
+
--_chart-2: var(--ag-ui-chart-2, color-mix(in oklch, var(--_fg) 32%, var(--_bg)));
|
|
164
|
+
--_chart-3: var(--ag-ui-chart-3, #e0803c);
|
|
165
|
+
--_chart-4: var(--ag-ui-chart-4, #b563d8);
|
|
166
|
+
--_chart-5: var(--ag-ui-chart-5, #d84f6e);
|
|
167
|
+
--_chart-6: var(--ag-ui-chart-6, #3ba7c4);
|
|
168
|
+
|
|
169
|
+
/* Unread badge on the launcher. */
|
|
170
|
+
--_badge-bg: var(--ag-ui-badge-bg, var(--_danger));
|
|
171
|
+
--_badge-fg: var(--ag-ui-badge-fg, #ffffff);
|
|
172
|
+
--_badge-size: var(--ag-ui-badge-size, 18px);
|
|
173
|
+
--_badge-font-size: var(--ag-ui-badge-font-size, 11px);
|
|
174
|
+
|
|
175
|
+
/* The floating launcher a collapsed widget shrinks to. */
|
|
176
|
+
--_launcher-size: var(--ag-ui-launcher-size, 48px);
|
|
177
|
+
--_launcher-bg: var(--ag-ui-launcher-bg, var(--_bg));
|
|
178
|
+
--_launcher-fg: var(--ag-ui-launcher-fg, var(--_fg));
|
|
179
|
+
--_launcher-radius: var(--ag-ui-launcher-radius, 14px);
|
|
180
|
+
--_launcher-icon-size: var(--ag-ui-launcher-icon-size, 22px);
|
|
181
|
+
--_launcher-inset: var(--ag-ui-launcher-inset, auto 0 0 auto);
|
|
182
|
+
|
|
183
|
+
/* Motion. One duration and two curves drive every collapse, expand and
|
|
184
|
+
slide-over, so the widget accelerates and settles as one thing. The
|
|
185
|
+
default curve decelerates into place; the pop curve overshoots slightly,
|
|
186
|
+
for something arriving. */
|
|
187
|
+
--_motion: var(--ag-ui-motion, 0.28s);
|
|
188
|
+
--_ease: var(--ag-ui-ease, cubic-bezier(0.32, 0.72, 0, 1));
|
|
189
|
+
--_ease-pop: var(--ag-ui-ease-pop, cubic-bezier(0.34, 1.36, 0.64, 1));
|
|
190
|
+
|
|
191
|
+
/* Spacing — the density preset overrides these. */
|
|
192
|
+
--_space: var(--ag-ui-space, 10px);
|
|
193
|
+
--_pad: var(--ag-ui-pad, 16px);
|
|
194
|
+
--_msg-pad: var(--ag-ui-msg-pad, 8px 12px);
|
|
195
|
+
--_msg-radius: var(--ag-ui-msg-radius, 12px);
|
|
196
|
+
|
|
197
|
+
/* Edges of the viewport the host has already spent, and that a fixed
|
|
198
|
+
placement must therefore stay out of: a sticky nav bar, a docked toolbar,
|
|
199
|
+
a device's safe area. Four longhands rather than one shorthand because a
|
|
200
|
+
custom property is a token stream and CSS cannot index one -- the height
|
|
201
|
+
arithmetic below needs the vertical pair on its own.
|
|
202
|
+
|
|
203
|
+
Every fixed placement derives from these, and the heights subtract them in
|
|
204
|
+
one place. A host that reserved its chrome by restating --ag-ui-inset per
|
|
205
|
+
placement had to keep --ag-ui-height in step by hand, and forgetting it
|
|
206
|
+
overflowed the panel past the bottom of the screen with nothing to say so.
|
|
207
|
+
|
|
208
|
+
These take env(safe-area-inset-*) verbatim, which is what a full-bleed
|
|
209
|
+
placement wants on a device with a notch. */
|
|
210
|
+
--_viewport-inset-top: var(--ag-ui-viewport-inset-top, 0px);
|
|
211
|
+
--_viewport-inset-right: var(--ag-ui-viewport-inset-right, 0px);
|
|
212
|
+
--_viewport-inset-bottom: var(--ag-ui-viewport-inset-bottom, 0px);
|
|
213
|
+
--_viewport-inset-left: var(--ag-ui-viewport-inset-left, 0px);
|
|
214
|
+
/* What is left of the viewport once the host's chrome is taken out, on both
|
|
215
|
+
axes, so a placement never composes this itself and no host can subtract
|
|
216
|
+
an edge from the position and forget it in the height.
|
|
217
|
+
|
|
218
|
+
Settable in their own right, and that is not only convention: an on-screen
|
|
219
|
+
keyboard changes no viewport-percentage length -- not vh, not dvh, not svh
|
|
220
|
+
-- so a full-bleed panel on a phone has to be told the height rather than
|
|
221
|
+
deriving it. The value to publish there is the visual viewport's. */
|
|
222
|
+
--_viewport-height: var(
|
|
223
|
+
--ag-ui-viewport-height,
|
|
224
|
+
calc(
|
|
225
|
+
min(var(--_visual-viewport-inset-top) + var(--_visual-viewport-height), 100dvh - var(--_viewport-inset-bottom)) -
|
|
226
|
+
var(--_viewport-inset-top) - var(--_keyboard-inset-top)
|
|
227
|
+
)
|
|
228
|
+
);
|
|
229
|
+
/* That default is the host's box cut to the part of the screen the user can
|
|
230
|
+
see: from the top the panel starts at, the host's reserved top moved down
|
|
231
|
+
by the keyboard inset below, to whichever is further up, the bottom of the
|
|
232
|
+
visible area or the host's reserved bottom. Where nothing has measured, the
|
|
233
|
+
visible area is the layout viewport with no pan, and this is the host's
|
|
234
|
+
box exactly.
|
|
235
|
+
|
|
236
|
+
Cut rather than replaced. A measured height used as the whole answer kept
|
|
237
|
+
a bar the host reserved at the top in the position and out of the height,
|
|
238
|
+
so the panel ran that far past the bottom of the visible area, with its
|
|
239
|
+
composer behind the keyboard. */
|
|
240
|
+
/* The measured height of the part of the screen the user can actually see,
|
|
241
|
+
written by the element from the visual viewport and falling back to the
|
|
242
|
+
layout viewport where nothing has measured yet.
|
|
243
|
+
|
|
244
|
+
This is the on-screen keyboard, and it needs measuring because no CSS
|
|
245
|
+
length describes it: an on-screen keyboard has no effect on any
|
|
246
|
+
viewport-percentage unit, so 100vh, 100dvh and 100svh are all the same
|
|
247
|
+
number with the keyboard up as without it. A full-bleed panel sized from
|
|
248
|
+
any of them puts its composer behind the keyboard the user is typing into.
|
|
249
|
+
|
|
250
|
+
Separate from the token above so a host that states the usable height
|
|
251
|
+
outright still wins: the element writes this one inline, and an inline
|
|
252
|
+
value would otherwise outrank the host's own rule.
|
|
253
|
+
|
|
254
|
+
The fallback is dvh rather than vh because the browser's own bars do move
|
|
255
|
+
it, where a keyboard does not. iOS Safari resolves vh to the viewport with
|
|
256
|
+
its bars collapsed, so on a page that does not scroll them away a panel
|
|
257
|
+
sized from it ran under the address bar by the bars' height -- 40px on
|
|
258
|
+
the phone measured -- with a docked composer underneath. dvh is the
|
|
259
|
+
viewport with the bars as they are. */
|
|
260
|
+
--_visual-viewport-height: var(--ag-ui-visual-viewport-height, 100dvh);
|
|
261
|
+
/* How much of the layout viewport is hidden below the visible one, measured
|
|
262
|
+
and written by the element alongside the height above.
|
|
263
|
+
|
|
264
|
+
A shorter panel is not enough on its own for anything anchored to the
|
|
265
|
+
bottom. A floating widget is positioned against the layout viewport, so
|
|
266
|
+
with a keyboard up its bottom edge -- and the launcher that lives at that
|
|
267
|
+
corner -- sits behind the keyboard however tall the panel is. This is what
|
|
268
|
+
lifts it clear. */
|
|
269
|
+
/* Two tokens, for the same reason the height above has two: the element
|
|
270
|
+
writes the measurement inline, and a host that states its own value needs
|
|
271
|
+
a knob that outranks that write rather than one the next write replaces.
|
|
272
|
+
A host wanting no keyboard lift at all sets --ag-ui-keyboard-inset: 0px. */
|
|
273
|
+
--_keyboard-inset: var(--ag-ui-keyboard-inset, var(--_visual-viewport-inset-bottom));
|
|
274
|
+
--_visual-viewport-inset-bottom: var(--ag-ui-visual-viewport-inset-bottom, 0px);
|
|
275
|
+
/* How far a panel anchored at the top moves down for a keyboard, below the
|
|
276
|
+
top the host reserved. With the same two-token shape as the lift above;
|
|
277
|
+
0px keeps the panel at the host's top.
|
|
278
|
+
|
|
279
|
+
To show the field being typed into, a browser pans the visible area down
|
|
280
|
+
the layout viewport, and a fixed element stays against the layout top, so
|
|
281
|
+
a panel that did not move showed only its lower part, from the pan down,
|
|
282
|
+
with its header off the screen and an empty band under it. It moves by
|
|
283
|
+
what the pan goes past the host's reserved top, not by the whole pan: the
|
|
284
|
+
pan scrolls a bar reserved there away with the rest of the page rather
|
|
285
|
+
than pushing it down, and adding the two put the panel a whole bar below
|
|
286
|
+
the visible area. A corner panel anchored at the bottom does not use this,
|
|
287
|
+
because the band below already accounts for the pan. */
|
|
288
|
+
--_keyboard-inset-top: var(--ag-ui-keyboard-inset-top, max(0px, var(--_visual-viewport-inset-top) - var(--_viewport-inset-top)));
|
|
289
|
+
/* How much of the layout viewport is hidden above the visible one: how far
|
|
290
|
+
the browser panned. Measured and written by the element with the two
|
|
291
|
+
above. */
|
|
292
|
+
--_visual-viewport-inset-top: var(--ag-ui-visual-viewport-inset-top, 0px);
|
|
293
|
+
--_viewport-width: var(
|
|
294
|
+
--ag-ui-viewport-width,
|
|
295
|
+
calc(100vw - var(--_viewport-inset-left) - var(--_viewport-inset-right))
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
/* Layout — override from outside to dock the widget anywhere.
|
|
299
|
+
Set --ag-ui-position: static (and place this element in your own
|
|
300
|
+
grid/flex layout) to embed it in the page flow instead of floating. */
|
|
301
|
+
--_position: var(--ag-ui-position, fixed);
|
|
302
|
+
--_z-index: var(--ag-ui-z-index, 2147483000);
|
|
303
|
+
--_width: var(--ag-ui-width, 380px);
|
|
304
|
+
--_height: var(--ag-ui-height, 560px);
|
|
305
|
+
/* The gutter a resting floating panel keeps between itself and the edge of
|
|
306
|
+
the box the host left free. One number, because the inset below spends it
|
|
307
|
+
and the cap beneath has to know it was spent. */
|
|
308
|
+
--_edge-gutter: var(--ag-ui-edge-gutter, 24px);
|
|
309
|
+
--_inset: var(
|
|
310
|
+
--ag-ui-inset,
|
|
311
|
+
auto calc(var(--_edge-gutter) + var(--_viewport-inset-right))
|
|
312
|
+
calc(var(--_edge-gutter) + var(--_viewport-inset-bottom) + var(--_keyboard-inset)) auto
|
|
313
|
+
);
|
|
314
|
+
/* The cap is what the host left free, less the *one* gutter the inset above
|
|
315
|
+
spends on the anchored edge -- not two, and not none.
|
|
316
|
+
|
|
317
|
+
Two was the first answer and it was felt on one axis only. The arithmetic
|
|
318
|
+
says why: the default panel is 560 tall against a cap of the viewport
|
|
319
|
+
minus 48, which on an 800px screen with a header reserved is 72px of
|
|
320
|
+
headroom, so the height reaches its cap almost immediately; the default
|
|
321
|
+
width is 380 against a cap near 1230, which is 850px nothing ever reaches.
|
|
322
|
+
Once the size is capped a grip cannot grow the panel, so a pull on the
|
|
323
|
+
anchored edge is written as position instead and the panel travels, and a
|
|
324
|
+
pull on the free edge stops a whole gutter short of an edge a drag can
|
|
325
|
+
reach.
|
|
326
|
+
|
|
327
|
+
None was the correction, and it overshot: the panel is anchored bottom-
|
|
328
|
+
right with a gutter already spent there, so a cap of the full usable
|
|
329
|
+
height puts the far edge exactly one gutter outside it. On an 800px screen
|
|
330
|
+
with nothing reserved that is a top of -24 -- the header, and every
|
|
331
|
+
control in it, off the top of the window. Reserve a 120px header and it
|
|
332
|
+
sits inside that instead, which is the one thing the reservation exists to
|
|
333
|
+
prevent.
|
|
334
|
+
|
|
335
|
+
One is the fixed point of both complaints. A resting panel grown to the
|
|
336
|
+
cap runs from the usable near edge to its gutter on the far one, so the
|
|
337
|
+
near edge is reachable by a resize exactly as it is by a drag, and neither
|
|
338
|
+
can put any part of the panel outside the box. */
|
|
339
|
+
--_max-width: var(--ag-ui-max-width, calc(var(--_viewport-width) - var(--_edge-gutter)));
|
|
340
|
+
--_max-height: var(--ag-ui-max-height, calc(var(--_viewport-height) - var(--_edge-gutter)));
|
|
341
|
+
/* Reading-column width for placement="page" (full-bleed, centred content). */
|
|
342
|
+
--_content-max-width: var(--ag-ui-content-max-width, 820px);
|
|
343
|
+
/* The greeting over an empty full-page conversation. The size scales with
|
|
344
|
+
the viewport between a phone and a desktop rather than stepping at a
|
|
345
|
+
breakpoint. */
|
|
346
|
+
--_greeting-font: var(--ag-ui-greeting-font, var(--_font));
|
|
347
|
+
--_greeting-size: var(--ag-ui-greeting-size, clamp(1.5rem, 4vw, 2.25rem));
|
|
348
|
+
/* Slim rail the sidebar placement collapses to. Only that placement reads
|
|
349
|
+
it, but it is declared here so every alias has a default in one place. */
|
|
350
|
+
--_rail-width: var(--ag-ui-rail-width, 52px);
|
|
351
|
+
|
|
352
|
+
position: var(--_position);
|
|
353
|
+
inset: var(--_inset);
|
|
354
|
+
z-index: var(--_z-index);
|
|
355
|
+
width: var(--_width);
|
|
356
|
+
max-width: var(--_max-width);
|
|
357
|
+
height: var(--_height);
|
|
358
|
+
max-height: var(--_max-height);
|
|
359
|
+
display: flex;
|
|
360
|
+
font-family: var(--_font);
|
|
361
|
+
font-size: var(--_font-size);
|
|
362
|
+
color: var(--_fg);
|
|
363
|
+
|
|
364
|
+
/* Surfaces a theme can tint; Quiet leaves them neutral. */
|
|
365
|
+
--_tint: var(--ag-ui-tint, var(--_wash));
|
|
366
|
+
--_tint-2: var(--ag-ui-tint-2, var(--_user-bg));
|
|
367
|
+
|
|
368
|
+
/* Status marks drawn as masks, so they take the colour of their state. */
|
|
369
|
+
--_ico-check: var(--ag-ui-ico-check, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E"));
|
|
370
|
+
--_ico-error: var(--ag-ui-ico-error, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6.2'/%3E%3Cpath d='M8 4.9v3.7M8 11.1v.1'/%3E%3C/svg%3E"));
|
|
371
|
+
--_ico-declined: var(--ag-ui-ico-declined, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6.2'/%3E%3Cpath d='M3.8 12.2l8.4-8.4'/%3E%3C/svg%3E"));
|
|
372
|
+
--_ico-chevron: var(--ag-ui-ico-chevron, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 3.5l4.5 4.5L6 12.5'/%3E%3C/svg%3E"));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/* The colour drawn on the accent, from the accent's own luminance: white on
|
|
376
|
+
an accent darker than WCAG relative luminance 0.179, black on a lighter
|
|
377
|
+
one. That is the crossover where the two give the same contrast, so the
|
|
378
|
+
pick is always the better of the two and never under 4.58:1. A threshold on
|
|
379
|
+
oklch lightness was tried first and missed: indigo 500 sits under the
|
|
380
|
+
threshold that works for greys and took white at 4.47:1. Each channel is
|
|
381
|
+
the same expression over the linear channels, so the result is pure black
|
|
382
|
+
or pure white. A host that sets a mid-tone brand accent in the dark scheme
|
|
383
|
+
would otherwise get the scheme's near-black on it. Relative colour syntax
|
|
384
|
+
with channel arithmetic is Chrome 119, Firefox 128 and Safari 18. Of the
|
|
385
|
+
browsers at or above this package's floor (Chrome 123, Firefox 120, Safari
|
|
386
|
+
17.5), Firefox 120 to 127 lack it, and Safari 17.5 and 17.6 parse an older
|
|
387
|
+
draft that rejects this expression, so the test below asks for the exact
|
|
388
|
+
expression and those engines keep the fallback above. light-dark needs no
|
|
389
|
+
such test: the floor is set where every engine has it. */
|
|
390
|
+
@supports (color: color(from red srgb-linear clamp(0, (0.179 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1) 0 0)) {
|
|
391
|
+
:host {
|
|
392
|
+
--_on-accent: var(--ag-ui-on-accent, color(from var(--_accent) srgb-linear clamp(0, (0.179 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1) clamp(0, (0.179 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1) clamp(0, (0.179 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1)));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/* Without relative colour syntax, classic and code keep the white they drew
|
|
397
|
+
before the theme set, not the scheme's colour: their accents are dark in
|
|
398
|
+
both schemes. Only on that path, so where the pick can be computed it is.
|
|
399
|
+
The condition is the one above, negated, and must stay its exact twin. */
|
|
400
|
+
@supports not (color: color(from red srgb-linear clamp(0, (0.179 - (0.2126 * r + 0.7152 * g + 0.0722 * b)) * 100000, 1) 0 0)) {
|
|
401
|
+
:host([theme~="classic"]),
|
|
402
|
+
:host([theme~="code"]) {
|
|
403
|
+
--_on-accent: var(--ag-ui-on-accent, #ffffff);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
`;
|