@robr0/design-system 0.5.0 → 0.6.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/README.md +19 -8
- package/components/ChatMessage/ChatMessage.css +6 -0
- package/components/ChatMessage/ChatMessage.d.ts +7 -1
- package/components/ChatMessage/ChatMessage.js +2 -0
- package/components/Composer/Composer.css +5 -6
- package/components/Timeline/Timeline.css +9 -1
- package/package.json +1 -1
- package/tokens/registry.json +1 -0
- package/tokens/registry.json.d.ts +1 -0
- package/tokens/registry.json.js +1 -1
- package/tokens/tokens-light.css +1 -0
- package/tokens/tokens-primitives.css +5 -0
package/README.md
CHANGED
|
@@ -5,20 +5,21 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/@robr0/design-system)
|
|
6
6
|
<!-- npm-badge:end -->
|
|
7
7
|
|
|
8
|
-
A personal portfolio site
|
|
8
|
+
A personal portfolio site, the AI-ready React design system behind it, and the AI layer that lets the site answer questions about itself. Claude Code builds all of it from the written specs in this repo (`CLAUDE.md` for the rules, `design.md` for the design language, `content-design.md` for how every word reads, and `porting-guide.md` for rebuilding the site chat inside another design system), and generated registries keep this README and the docs site from drifting. The design system is the backbone every portfolio page is built on, so the work is presented consistently and to the same craft standards throughout.
|
|
9
9
|
|
|
10
10
|
**[→ Live site](https://robertritacca.com/)** · **[→ Storybook](https://design-system-iota-one.vercel.app/?path=/docs/robr0-ds--docs)**
|
|
11
11
|
|
|
12
|
-
The **live site** is the portfolio built on the design system. **Storybook** is the interactive component explorer for the design system itself. They
|
|
12
|
+
The **live site** is the portfolio built on the design system. **Storybook** is the interactive component explorer for the design system itself. They deploy separately: two Vercel projects from one repo.
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Three parts, one repo
|
|
17
17
|
|
|
18
18
|
| Part | Description |
|
|
19
19
|
|---|---|
|
|
20
20
|
| **Portfolio website** (`/website`) | Next.js app with case studies, work history, writing, and about pages, all built exclusively with the design system components below. **[Live site →](https://robertritacca.com/)** |
|
|
21
21
|
| **Design system** (`/src`) | <!-- component-count -->78<!-- /component-count --> React components, a three-tier token architecture, dark mode, and a full documentation site. Built to production standards. **[Storybook →](https://design-system-iota-one.vercel.app/?path=/docs/robr0-ds--docs)** |
|
|
22
|
+
| **AI layer** (`ai` components in `/src`, chat in `/website`, `/evals`) | A site-wide chat that answers questions about the work: built from the library's own `ai` components, grounded in a corpus generated from the site's published content, and scored by a golden-set eval. |
|
|
22
23
|
|
|
23
24
|
---
|
|
24
25
|
|
|
@@ -32,7 +33,7 @@ Accordion · Agent status · AI button · Alert · Alert dialog · App layout ·
|
|
|
32
33
|
|
|
33
34
|
### Using the package
|
|
34
35
|
|
|
35
|
-
The design system is published as [`@robr0/design-system`](https://www.npmjs.com/package/@robr0/design-system) (React 19+ is a peer dependency). The **[full setup guide](https://robertritacca.com/docs/get-started)**
|
|
36
|
+
The design system is published as [`@robr0/design-system`](https://www.npmjs.com/package/@robr0/design-system) (React 19+ is a peer dependency). The **[full setup guide](https://robertritacca.com/docs/get-started)** expands on everything in this section:
|
|
36
37
|
|
|
37
38
|
```bash
|
|
38
39
|
npm install @robr0/design-system
|
|
@@ -86,19 +87,29 @@ Dark mode is driven by `data-theme="dark"` on the root element, with no `prefers
|
|
|
86
87
|
|
|
87
88
|
### Design principles
|
|
88
89
|
|
|
89
|
-
Stated as token roles on purpose
|
|
90
|
+
Stated as token roles on purpose. What each role resolves to is the theme, and yours to override:
|
|
90
91
|
|
|
91
|
-
- **Style with semantic tokens, never raw values
|
|
92
|
+
- **Style with semantic tokens, never raw values**: that is what makes one primitive override cascade through everything
|
|
92
93
|
- **One typeface**, hierarchy carried by weight contrast
|
|
93
94
|
- **The primary-action token means "click here"**: CTAs and focus only, never decoration
|
|
94
95
|
- **Shape is a per-element-type token**, not a per-instance choice
|
|
95
96
|
- **Five status roles** (info, positive, warning, error, neutral) shared by every status-bearing component
|
|
96
|
-
- **Depth is token-owned**: the container ramp plus the system's elevation tokens
|
|
97
|
+
- **Depth is token-owned**: the container ramp plus the system's elevation tokens, and components don't bring their own shadows
|
|
97
98
|
|
|
98
99
|
The defaults behind each role, and every component spec, live in [`design.md`](design.md).
|
|
99
100
|
|
|
100
101
|
---
|
|
101
102
|
|
|
103
|
+
## AI layer
|
|
104
|
+
|
|
105
|
+
The library's `ai` category is the interface half: chat primitives (Chat thread, Chat message, Composer) and agent-state components (Tool call, Reasoning, Agent status). Those components ship in the npm package; the rest of the chat does not. The conversation state hook, the streaming transport, the backend route, and the corpus are this site's own code under `website/`, and a consumer builds their own equivalents, with their LLM API key held server-side, never in the client. The site's own chat, robr0 GPT, is built from the shipped primitives, so it doubles as a live demo of the components it is made of.
|
|
106
|
+
|
|
107
|
+
The answering half is a Claude-backed route (`website/src/app/api/chat/route.ts`) with a persona and guardrails. There is no retrieval step: `scripts/generate-site-corpus.mjs` compiles every published page's prose, the data registries, and the root specs into one corpus at build time, and the model reads it whole. The corpus is public-only, and a validator enforces that boundary. Nothing reaches the model that is not already on the site, so a prompt injection has nothing private to leak. The route also deploys ahead of its keys, so an unconfigured deploy answers with a polite notice rather than throwing.
|
|
108
|
+
|
|
109
|
+
Answers are measured, not assumed. `evals/chat` holds a golden set that runs through the real route (persona, corpus, guardrails, all of it) with `npm run eval:chat`; it costs real API calls, so it runs on demand and never in CI. A second validator fails the build when a golden-set fact is missing from the corpus, which keeps the eval and the site describing the same system.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
102
113
|
## Tech
|
|
103
114
|
|
|
104
115
|
- **React 19 + TypeScript**: component library
|
|
@@ -118,7 +129,7 @@ Every push and pull request runs a GitHub Actions pipeline ([`ci.yml`](.github/w
|
|
|
118
129
|
npm run verify # lint + library type-check + package build + story tests + Storybook build + website lint + build
|
|
119
130
|
```
|
|
120
131
|
|
|
121
|
-
CI also guards against documentation drift: generated surfaces (this README's component count and list, the website's skills pages, the published
|
|
132
|
+
CI also guards against documentation drift: generated surfaces (this README's component count and list, the website's skills pages, the published blueprint copies of the root markdown specs) are rebuilt from their source registries on every build, and CI fails if the committed copies are stale. The numbers on the site are never hand-written.
|
|
122
133
|
|
|
123
134
|
---
|
|
124
135
|
|
|
@@ -253,6 +253,12 @@
|
|
|
253
253
|
opacity: 1;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
/* showActions pins the row on: the actions are part of the response, not a
|
|
257
|
+
secondary affordance to discover. */
|
|
258
|
+
.ds-chat-message--show-actions .ds-chat-message__actions {
|
|
259
|
+
opacity: 1;
|
|
260
|
+
}
|
|
261
|
+
|
|
256
262
|
@media (hover: none) {
|
|
257
263
|
.ds-chat-message__actions {
|
|
258
264
|
opacity: 1;
|
|
@@ -41,8 +41,14 @@ type ChatMessageOwnProps = {
|
|
|
41
41
|
pending?: boolean;
|
|
42
42
|
/** Accessible text announced for the pending state. */
|
|
43
43
|
pendingLabel?: string;
|
|
44
|
-
/** Action row under the content, revealed on hover and keyboard focus (always visible on touch). */
|
|
44
|
+
/** Action row under the content, revealed on hover and keyboard focus (always visible on touch) — `showActions` pins it on. */
|
|
45
45
|
actions?: React.ReactNode;
|
|
46
|
+
/**
|
|
47
|
+
* Always show the action row instead of revealing it on hover and focus.
|
|
48
|
+
* For surfaces where the actions are part of the response — a copy or
|
|
49
|
+
* feedback row — rather than a secondary affordance.
|
|
50
|
+
*/
|
|
51
|
+
showActions?: boolean;
|
|
46
52
|
/** Footer slot under the content — a sources row, an edited note. */
|
|
47
53
|
footer?: React.ReactNode;
|
|
48
54
|
/** Additional CSS classes */
|
|
@@ -15,6 +15,7 @@ const ChatMessage = React.forwardRef(
|
|
|
15
15
|
pending = false,
|
|
16
16
|
pendingLabel = "Waiting for a reply",
|
|
17
17
|
actions,
|
|
18
|
+
showActions = false,
|
|
18
19
|
footer,
|
|
19
20
|
className = "",
|
|
20
21
|
children,
|
|
@@ -31,6 +32,7 @@ const ChatMessage = React.forwardRef(
|
|
|
31
32
|
grouped ? `${baseClass}--grouped` : "",
|
|
32
33
|
size === "compact" ? `${baseClass}--compact` : "",
|
|
33
34
|
pending ? `${baseClass}--pending` : "",
|
|
35
|
+
showActions ? `${baseClass}--show-actions` : "",
|
|
34
36
|
className
|
|
35
37
|
].filter(Boolean).join(" ");
|
|
36
38
|
return /* @__PURE__ */ jsxs("div", { ...rest, ref, className: classes, children: [
|
|
@@ -13,12 +13,11 @@
|
|
|
13
13
|
--ds-composer-send-size: 40px;
|
|
14
14
|
background-color: var(--color-input-bg-primary);
|
|
15
15
|
border: var(--border-xs) solid var(--color-input-border-primary);
|
|
16
|
-
/*
|
|
17
|
-
plus the action bar's padding-sm ring, plus the border width
|
|
18
|
-
(border-radius applies to the border's outer edge).
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
);
|
|
16
|
+
/* The token's default is concentric with the send button: half the
|
|
17
|
+
button, plus the action bar's padding-sm ring, plus the border width
|
|
18
|
+
(border-radius applies to the border's outer edge). A token rather
|
|
19
|
+
than the calc so radius re-theming reaches this corner too. */
|
|
20
|
+
border-radius: var(--radius-composer);
|
|
22
21
|
box-shadow: var(--shadow-floating);
|
|
23
22
|
transition: border-color var(--motion-duration-fast) var(--motion-ease-standard);
|
|
24
23
|
/* The whole shell is the input affordance — clicking anywhere that is
|
|
@@ -332,8 +332,16 @@
|
|
|
332
332
|
bottom: calc(8px - var(--gap-lg)); /* stop 8px above the next logo */
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
-
/* Last entry has no following logo —
|
|
335
|
+
/* Last entry has no following logo — the bar runs to its own content's end
|
|
336
|
+
and fades out: the hairline treatment (1px, dissolving to the transparent
|
|
337
|
+
container colour) that marks the end of the timeline. */
|
|
336
338
|
.ds-timeline--company .ds-timeline__item:last-child::before {
|
|
337
339
|
display: block;
|
|
338
340
|
bottom: 0;
|
|
341
|
+
width: var(--border-xs);
|
|
342
|
+
background: linear-gradient(
|
|
343
|
+
to bottom,
|
|
344
|
+
var(--color-divider),
|
|
345
|
+
var(--color-bg-container-primary-transparent)
|
|
346
|
+
);
|
|
339
347
|
}
|
package/package.json
CHANGED
package/tokens/registry.json
CHANGED
package/tokens/registry.json.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const categories = { "colour": ["--color-action-icon-active", "--color-action-icon-default", "--color-action-passive-bg", "--color-action-passive-bg-active", "--color-action-passive-bg-hover", "--color-action-passive-text", "--color-action-primary-bg", "--color-action-primary-bg-active", "--color-action-primary-bg-hover", "--color-action-primary-border", "--color-action-primary-border-secondary", "--color-action-primary-border-tertiary", "--color-action-primary-text", "--color-action-primary-text-active", "--color-action-primary-text-secondary", "--color-action-primary-text-tertiary", "--color-ai-gradient-end", "--color-ai-gradient-mid", "--color-ai-gradient-start", "--color-bg-container-border", "--color-bg-container-inverse", "--color-bg-container-primary", "--color-bg-container-primary-semi", "--color-bg-container-primary-transparent", "--color-bg-container-secondary", "--color-bg-container-tertiary", "--color-bg-page-inverse", "--color-bg-page-primary", "--color-chart-contribution-0", "--color-chart-contribution-1", "--color-chart-contribution-2", "--color-chart-contribution-3", "--color-chart-contribution-4", "--color-chat-bubble-received-bg", "--color-chat-bubble-received-text", "--color-chat-bubble-sent-bg", "--color-chat-bubble-sent-text", "--color-control-thumb", "--color-core-accent-amber", "--color-core-accent-cobalt", "--color-core-accent-coral", "--color-core-accent-gold", "--color-core-accent-mint", "--color-core-accent-violet", "--color-core-ui-primary", "--color-core-ui-secondary", "--color-divider", "--color-icon-primary", "--color-icon-secondary", "--color-input-bg-disabled", "--color-input-bg-primary", "--color-input-border-disabled", "--color-input-border-hover", "--color-input-border-primary", "--color-input-border-selected", "--color-input-text-disabled", "--color-input-text-inverse", "--color-input-text-placeholder", "--color-input-text-primary", "--color-scrim", "--color-status-error-bg", "--color-status-error-border", "--color-status-error-text", "--color-status-info-bg", "--color-status-info-border", "--color-status-info-text", "--color-status-neutral-bg", "--color-status-neutral-border", "--color-status-neutral-text", "--color-status-positive-bg", "--color-status-positive-border", "--color-status-positive-text", "--color-status-warning-bg", "--color-status-warning-border", "--color-status-warning-text", "--color-text-inverse", "--color-text-on-inverse", "--color-text-primary", "--color-text-secondary", "--color-text-tertiary"], "typography": ["--font-display-1-family", "--font-display-1-letter-spacing", "--font-display-1-line-height", "--font-display-1-size", "--font-display-1-weight", "--font-display-2-family", "--font-display-2-letter-spacing", "--font-display-2-line-height", "--font-display-2-size", "--font-display-2-weight", "--font-family-code", "--font-family-primary", "--font-heading-1-family", "--font-heading-1-letter-spacing", "--font-heading-1-line-height", "--font-heading-1-size", "--font-heading-1-weight", "--font-heading-2-family", "--font-heading-2-letter-spacing", "--font-heading-2-line-height", "--font-heading-2-size", "--font-heading-2-weight", "--font-heading-3-family", "--font-heading-3-letter-spacing", "--font-heading-3-line-height", "--font-heading-3-size", "--font-heading-3-weight", "--font-mega-1-family", "--font-mega-1-letter-spacing", "--font-mega-1-line-height", "--font-mega-1-size", "--font-mega-1-weight", "--font-mega-2-family", "--font-mega-2-letter-spacing", "--font-mega-2-line-height", "--font-mega-2-size", "--font-mega-2-weight", "--font-paragraph-em-family", "--font-paragraph-em-letter-spacing", "--font-paragraph-em-line-height", "--font-paragraph-em-size", "--font-paragraph-em-weight", "--font-paragraph-family", "--font-paragraph-letter-spacing", "--font-paragraph-line-height", "--font-paragraph-size", "--font-paragraph-sm-em-family", "--font-paragraph-sm-em-letter-spacing", "--font-paragraph-sm-em-line-height", "--font-paragraph-sm-em-size", "--font-paragraph-sm-em-weight", "--font-paragraph-sm-family", "--font-paragraph-sm-letter-spacing", "--font-paragraph-sm-line-height", "--font-paragraph-sm-size", "--font-paragraph-sm-weight", "--font-paragraph-weight", "--font-sub-display-family", "--font-sub-display-letter-spacing", "--font-sub-display-line-height", "--font-sub-display-size", "--font-sub-display-weight", "--font-title-body-family", "--font-title-body-letter-spacing", "--font-title-body-line-height", "--font-title-body-size", "--font-title-body-weight"], "spacing": ["--gap-lg", "--gap-md", "--gap-sm", "--gap-sm-md", "--gap-xl", "--gap-xs", "--gap-xxl", "--gap-xxs", "--gap-xxxl", "--gap-xxxxl", "--padding-lg", "--padding-md", "--padding-sm", "--padding-sm-md", "--padding-xl", "--padding-xs", "--padding-xxl", "--padding-xxs", "--padding-xxxs"], "radius": ["--radius-full", "--radius-lg", "--radius-md", "--radius-sm", "--radius-xl", "--radius-xs", "--radius-xxl", "--radius-xxs"], "border": ["--border-md", "--border-xs"], "shadow": ["--shadow-floating", "--shadow-modal"], "icons": ["--icon-size-lg", "--icon-size-md", "--icon-size-sm", "--icon-size-xl"], "motion": ["--motion-duration-base", "--motion-duration-deliberate", "--motion-duration-fast", "--motion-duration-loop-matrix", "--motion-duration-loop-shimmer", "--motion-duration-loop-spin", "--motion-duration-slow", "--motion-duration-slower", "--motion-ease-emphasized", "--motion-ease-entrance", "--motion-ease-linear", "--motion-ease-spring", "--motion-ease-standard"] };
|
|
1
|
+
const categories = { "colour": ["--color-action-icon-active", "--color-action-icon-default", "--color-action-passive-bg", "--color-action-passive-bg-active", "--color-action-passive-bg-hover", "--color-action-passive-text", "--color-action-primary-bg", "--color-action-primary-bg-active", "--color-action-primary-bg-hover", "--color-action-primary-border", "--color-action-primary-border-secondary", "--color-action-primary-border-tertiary", "--color-action-primary-text", "--color-action-primary-text-active", "--color-action-primary-text-secondary", "--color-action-primary-text-tertiary", "--color-ai-gradient-end", "--color-ai-gradient-mid", "--color-ai-gradient-start", "--color-bg-container-border", "--color-bg-container-inverse", "--color-bg-container-primary", "--color-bg-container-primary-semi", "--color-bg-container-primary-transparent", "--color-bg-container-secondary", "--color-bg-container-tertiary", "--color-bg-page-inverse", "--color-bg-page-primary", "--color-chart-contribution-0", "--color-chart-contribution-1", "--color-chart-contribution-2", "--color-chart-contribution-3", "--color-chart-contribution-4", "--color-chat-bubble-received-bg", "--color-chat-bubble-received-text", "--color-chat-bubble-sent-bg", "--color-chat-bubble-sent-text", "--color-control-thumb", "--color-core-accent-amber", "--color-core-accent-cobalt", "--color-core-accent-coral", "--color-core-accent-gold", "--color-core-accent-mint", "--color-core-accent-violet", "--color-core-ui-primary", "--color-core-ui-secondary", "--color-divider", "--color-icon-primary", "--color-icon-secondary", "--color-input-bg-disabled", "--color-input-bg-primary", "--color-input-border-disabled", "--color-input-border-hover", "--color-input-border-primary", "--color-input-border-selected", "--color-input-text-disabled", "--color-input-text-inverse", "--color-input-text-placeholder", "--color-input-text-primary", "--color-scrim", "--color-status-error-bg", "--color-status-error-border", "--color-status-error-text", "--color-status-info-bg", "--color-status-info-border", "--color-status-info-text", "--color-status-neutral-bg", "--color-status-neutral-border", "--color-status-neutral-text", "--color-status-positive-bg", "--color-status-positive-border", "--color-status-positive-text", "--color-status-warning-bg", "--color-status-warning-border", "--color-status-warning-text", "--color-text-inverse", "--color-text-on-inverse", "--color-text-primary", "--color-text-secondary", "--color-text-tertiary"], "typography": ["--font-display-1-family", "--font-display-1-letter-spacing", "--font-display-1-line-height", "--font-display-1-size", "--font-display-1-weight", "--font-display-2-family", "--font-display-2-letter-spacing", "--font-display-2-line-height", "--font-display-2-size", "--font-display-2-weight", "--font-family-code", "--font-family-primary", "--font-heading-1-family", "--font-heading-1-letter-spacing", "--font-heading-1-line-height", "--font-heading-1-size", "--font-heading-1-weight", "--font-heading-2-family", "--font-heading-2-letter-spacing", "--font-heading-2-line-height", "--font-heading-2-size", "--font-heading-2-weight", "--font-heading-3-family", "--font-heading-3-letter-spacing", "--font-heading-3-line-height", "--font-heading-3-size", "--font-heading-3-weight", "--font-mega-1-family", "--font-mega-1-letter-spacing", "--font-mega-1-line-height", "--font-mega-1-size", "--font-mega-1-weight", "--font-mega-2-family", "--font-mega-2-letter-spacing", "--font-mega-2-line-height", "--font-mega-2-size", "--font-mega-2-weight", "--font-paragraph-em-family", "--font-paragraph-em-letter-spacing", "--font-paragraph-em-line-height", "--font-paragraph-em-size", "--font-paragraph-em-weight", "--font-paragraph-family", "--font-paragraph-letter-spacing", "--font-paragraph-line-height", "--font-paragraph-size", "--font-paragraph-sm-em-family", "--font-paragraph-sm-em-letter-spacing", "--font-paragraph-sm-em-line-height", "--font-paragraph-sm-em-size", "--font-paragraph-sm-em-weight", "--font-paragraph-sm-family", "--font-paragraph-sm-letter-spacing", "--font-paragraph-sm-line-height", "--font-paragraph-sm-size", "--font-paragraph-sm-weight", "--font-paragraph-weight", "--font-sub-display-family", "--font-sub-display-letter-spacing", "--font-sub-display-line-height", "--font-sub-display-size", "--font-sub-display-weight", "--font-title-body-family", "--font-title-body-letter-spacing", "--font-title-body-line-height", "--font-title-body-size", "--font-title-body-weight"], "spacing": ["--gap-lg", "--gap-md", "--gap-sm", "--gap-sm-md", "--gap-xl", "--gap-xs", "--gap-xxl", "--gap-xxs", "--gap-xxxl", "--gap-xxxxl", "--padding-lg", "--padding-md", "--padding-sm", "--padding-sm-md", "--padding-xl", "--padding-xs", "--padding-xxl", "--padding-xxs", "--padding-xxxs"], "radius": ["--radius-composer", "--radius-full", "--radius-lg", "--radius-md", "--radius-sm", "--radius-xl", "--radius-xs", "--radius-xxl", "--radius-xxs"], "border": ["--border-md", "--border-xs"], "shadow": ["--shadow-floating", "--shadow-modal"], "icons": ["--icon-size-lg", "--icon-size-md", "--icon-size-sm", "--icon-size-xl"], "motion": ["--motion-duration-base", "--motion-duration-deliberate", "--motion-duration-fast", "--motion-duration-loop-matrix", "--motion-duration-loop-shimmer", "--motion-duration-loop-spin", "--motion-duration-slow", "--motion-duration-slower", "--motion-ease-emphasized", "--motion-ease-entrance", "--motion-ease-linear", "--motion-ease-spring", "--motion-ease-standard"] };
|
|
2
2
|
const registry = {
|
|
3
3
|
categories
|
|
4
4
|
};
|
package/tokens/tokens-light.css
CHANGED
|
@@ -144,6 +144,7 @@
|
|
|
144
144
|
--radius-xl: var(--primitive-radius-xl);
|
|
145
145
|
--radius-xxl: var(--primitive-radius-xxl);
|
|
146
146
|
--radius-full: var(--primitive-radius-full);
|
|
147
|
+
--radius-composer: var(--primitive-radius-composer);
|
|
147
148
|
|
|
148
149
|
--padding-xxxs: var(--primitive-padding-xxxs);
|
|
149
150
|
--padding-xxs: var(--primitive-padding-xxs);
|
|
@@ -136,6 +136,11 @@
|
|
|
136
136
|
--primitive-radius-xl: 24px;
|
|
137
137
|
--primitive-radius-xxl: 48px;
|
|
138
138
|
--primitive-radius-full: 999px;
|
|
139
|
+
/* The composer shell's corner: concentric with the 40px send button it
|
|
140
|
+
wraps (half the button + the padding-sm ring + the border width).
|
|
141
|
+
Held as a resolved constant so consumers re-theme it like any other
|
|
142
|
+
radius step. */
|
|
143
|
+
--primitive-radius-composer: 29px;
|
|
139
144
|
|
|
140
145
|
/* Padding */
|
|
141
146
|
--primitive-padding-xxxs: 2px;
|