@nadicodeai/design-system 12.1.111 → 12.1.113
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/AGENTS.md +8 -6
- package/DESIGN.md +163 -1785
- package/README.md +7 -6
- package/dist/tokens/nadicode.dtcg-resolved.json +1 -1
- package/dist/tokens/nadicode.dtcg.json +1 -1
- package/package.json +2 -1
- package/src/tokens/extension.tokens.json +1383 -0
package/DESIGN.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
version: alpha
|
|
3
3
|
name: nadicode Design System
|
|
4
4
|
description: >-
|
|
5
|
-
nadicode's design system and its
|
|
6
|
-
rules every component
|
|
7
|
-
|
|
5
|
+
nadicode's design system and its design authority for tokens, visual
|
|
6
|
+
direction and the rules every component and page shares: every component,
|
|
7
|
+
website section, and product screen in the website, the Portal, the Nadia
|
|
8
|
+
desktop app, and the Alveare desktop app builds on it. A component's own
|
|
9
|
+
contract is the usage page in its source in @nadicodeai/ui.
|
|
8
10
|
|
|
9
11
|
colors:
|
|
10
12
|
action: "#111111"
|
|
@@ -522,7 +524,7 @@ spacing:
|
|
|
522
524
|
|
|
523
525
|
## Overview
|
|
524
526
|
|
|
525
|
-
This file is nadicode's design system and its
|
|
527
|
+
This file is nadicode's design system and its design authority for tokens, visual direction and the rules every component and page shares; a component's own contract is the usage page in its source in `@nadicodeai/ui`. The tokens above are the values; the sections below are the rules for applying them. Every component in `@nadicodeai/ui`, every website section, and every screen in the Portal, Nadia and Alveare builds on it. Another document may say how one product applies a rule, and links here for the rule; it never restates one. A shared rule that is missing here is added here first; a rule of one component is added to its usage page.
|
|
526
528
|
|
|
527
529
|
nadicode puts AI Agents to work inside small and mid-sized companies. Its sites and products read as a technology company with a real product: the interface is neutral and exact, the product is shown working, and colour and depth give the page its energy. Three ideas carry every screen:
|
|
528
530
|
|
|
@@ -614,7 +616,7 @@ Every chart and KPI card is a stock shadcn registry component owned by `@nadicod
|
|
|
614
616
|
- A multi-series chart has a legend below the plot, left-aligned and wrapping: a round dot and the entity name, in series order.
|
|
615
617
|
- A signed comparison keeps a visible zero line so losses and gains share one baseline, and colours each bar by its consequence: `success` where the value is favourable, `destructive` where it is not.
|
|
616
618
|
- A chart is a named section: its card title is the heading that names the plot.
|
|
617
|
-
- Every chart card has one header, the same on every page
|
|
619
|
+
- Every chart card has one header and footer, the same on every page: `ChartCard`, whose usage page holds them. The period's choice sits on the page's title row where the page has one. A daily axis labels every second day from the first, fewer in a half-width card. A ranked list beside a chart is one line per entity (place, colour, name, share, figure), so it never stands taller than the chart; a category axis is as wide as its longest name up to 128 px, a longer name wrapping to a second line; a short window's activity calendar draws larger cells and shares its row with a sibling card, never a lone narrow card.
|
|
618
620
|
|
|
619
621
|
No pie, donut, radar or dual-axis chart, and no mark or logo inside a legend. The one ring is `Gauge`, a control for a single ratio out of 100 against a fixed maximum, not a chart.
|
|
620
622
|
|
|
@@ -634,8 +636,7 @@ A hue follows its entity, never its rank or position: one assignment per surface
|
|
|
634
636
|
|
|
635
637
|
### Meters, deltas and labels
|
|
636
638
|
|
|
637
|
-
- **Meter
|
|
638
|
-
- **Gauge**: a ring for one ratio out of 100 where the comparison is the point (a hit rate, an uptime), in one product-chosen tone from the same set, with an adjacent label that names the measure and carries the unit. Its figure is the bare number, never a percent sign. It has no indeterminate form: an unknown wait is the waiting line.
|
|
639
|
+
- **Meter** and **Gauge**: `Progress` for consumption against a cap and `Gauge` for one ratio out of 100 where the comparison is the point; their usage pages hold their tones, stops, overage and figure. Neither has an indeterminate form: an unknown wait is the waiting line.
|
|
639
640
|
- **Delta**: an outline Badge with a trend icon (`TrendingUp`, `TrendingDown`, `Minus`) and the signed value, followed by a muted "vs {period}". Direction crossed with whether up is good sets the tone; a neutral direction stays neutral. Never bare signed text, colour alone, or a ▲▼ glyph. A figure with no comparison shows no badge.
|
|
640
641
|
- **Labels**: legend, axis and label text are ink roles and never wear the series colour. A single series is titled, not legended. Tooltips enhance a chart and never hold the only copy of a value; where a page needs the numbers as text, it shows a real table built from the same data.
|
|
641
642
|
|
|
@@ -735,7 +736,7 @@ Control geometry is the same in every product:
|
|
|
735
736
|
| `{spacing.icon-stroke}`, `{spacing.icon-stroke-sm}` | The icon line ("Iconography") |
|
|
736
737
|
| `{spacing.focus-outline-width}`, `{spacing.focus-outline-offset}` | The focus outline |
|
|
737
738
|
|
|
738
|
-
Product chrome uses the 36 px control
|
|
739
|
+
Product chrome uses the 36 px control: a page header, a toolbar, a card's header and footer, a filter row, a collection row's actions and the three-dot trigger take `{spacing.control-height}` with a `{typography.button}` label. Compact controls use 32 px and prominent controls 40 px; a button's `sm` and `xs` sizes are for a control nested inside dense content, such as a notice's or a banner's one action, a descriptive item's trailing controls, a composer or an input group, and never for chrome. A control nested in a field, and `SegmentedControl`'s options, keep the same outer heights; their usage pages hold how.
|
|
739
740
|
|
|
740
741
|
### The website column
|
|
741
742
|
|
|
@@ -757,25 +758,14 @@ The Portal, Nadia and Alveare are product shells: persistent navigation on the l
|
|
|
757
758
|
| Getting the app | Above the account | Downloads, an outlined row | The update card, only when there is one | The update card |
|
|
758
759
|
| The page's actions | The page's title row | Secondary, primary, the three dots | The window header's trailing edge: the Agent's three dots, after the chat switcher | The channel header's trailing edge |
|
|
759
760
|
|
|
760
|
-
- **The sidebar swaps, and is never joined by a second.** Inside an object, the same column shows a back link, what you are in (its identity mark at 24 px and its name) and its sections, and the top bar keeps the path (`SidebarSections`). No rail, second column or tab row of an object's sections appears beside it. In the Portal an Agent is the exception, because she is a deployment: the sidebar stays on the places, and her sections stand as the `TabsNav` band under the top bar, as Vercel draws a deployment's tabs, at most six (Overview, Scheduled tasks, Usage, Capabilities, Messaging, Settings); a tab that holds several sections opens on the first and shows them as line tabs at the top of its content.
|
|
761
|
+
- **The sidebar swaps, and is never joined by a second.** Inside an object, the same column shows a back link, what you are in (its identity mark at 24 px and its name) and its sections, and the top bar keeps the path (`SidebarSections`). No rail, second column or tab row of an object's sections appears beside it. In the Portal an Agent is the exception, because she is a deployment: the sidebar stays on the places, and her sections stand as the `TabsNav` band under the top bar, as Vercel draws a deployment's tabs, at most six (Overview, Scheduled tasks, Usage, Capabilities, Messaging, Settings); a tab that holds several sections opens on the first and shows them as line tabs at the top of its content.
|
|
761
762
|
- **An area whose pages are siblings opens as a sub-menu, as Vercel's sidebar does.** Vercel marks such a row with a › at its end ("Logs", "Observability", "Firewall", "Settings"), and its press replaces the places with one row, a ‹ at its start and the area's name centred, above the area's pages as words alone, the open one filled like a selected row; a row that only opens a page has no ›. In the Portal these areas are Settings (nadicode), Company (whoever manages a company) and Library (everyone who sees it: Agent templates, Skills, Plugins), each with its › row, and Account, opened from the account menu; their pages are never tabs (`SidebarSections` without an identity, its row ending in `SidebarMenuChevron`). “Tabs imply the views share scope, URL parent, and data model” (https://vercel.com/geist/tabs): Library's pages hold different objects with different lists and different ways to add, so they are a sub-menu, as Vercel's AI Gateway is. A destination whose pages are views of one reading, Analytics, keeps its tabs, as Vercel's Analytics and OpenRouter's Activity do. The ‹ returns to where the person opened the area from.
|
|
762
763
|
- **The top bar holds only the path, never an action.** It names where the open page sits, ending at the place or the object, and never the page's own title; an object's own status sits beside its name in the path and nowhere else on the page. A top bar that only says where you are cannot be mistaken for a toolbar.
|
|
763
764
|
- **Find goes to places.** It opens from the outlined field at the top of the sidebar and on ⌘K, and names every sidebar place, chat and settings page; it never runs a command. Its field names what it searches, never a bare "Search"; ⌘K or Ctrl+K opens it and no other field takes that binding; a shortcut on a row is a `CommandShortcut`; and a polite live region reads how many results remain as the person types.
|
|
764
765
|
- **The account lives at the sidebar's foot.** `AccountMenu` names who is signed in and for whom, opens the account's settings from its gear, and holds Theme, Language and Sign out; the offer to get or update the app stands just above it.
|
|
765
766
|
- **Navigation names stable destinations.** An object opened from search or a link still shows its parent in the path; a return link remembers a visit and never replaces the parent. A scope selector keeps the current section when the next object has it, and otherwise opens its overview.
|
|
766
767
|
- **Compact screens keep the same relationships.** Tabs scroll horizontally, primary content stacks before supporting facts, and no second sidebar appears.
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
**Nadia's window** sorts every thing by what it belongs to, in four scopes: the company (what every Agent here shares), one Agent (her work and her setup), one chat (what is happening now) and the person on this computer (how the app behaves). The company's pages of work, Wiki and Skills, sit in the list; what it sets once, its Memory, Mail and Alveare, sits in Settings beside this computer's settings.
|
|
770
|
-
|
|
771
|
-
- **The list at rest** holds, top to bottom: Find; Scheduled tasks; the company's Wiki and Skills; the group "Agents", Nadia first, then by name ("Agent orbs"); then the update card and the account. Nothing else, and no chats under an Agent: her chats are in the switcher by her name.
|
|
772
|
-
- **The company's pages**, Wiki and Skills, are rows under Scheduled tasks at the top of the list, each its own page with its own title and its actions on that title's row, never tabs under the company's name.
|
|
773
|
-
- **Scheduled tasks** is a place: one page of every Agent's scheduled work, each row with its Agent's orb, its schedule and its last or next run, failures first, filtered by Agent, with New task on the title row; a task opens for editing in its row. The row carries a red count of the tasks that failed (`SidebarMenuBadge tone="attention"`), so the person sees a failure before looking for it.
|
|
774
|
-
- **⋯ → Edit** stays as it is: it swaps the list to the Agent's Profile, Skills, Apps, MCP, Messaging, Plugins and Passwords. The chat switcher by her name stays as it is.
|
|
775
|
-
- **Settings** is what is set once rather than worked in: how the app behaves on this computer (its language, look, notifications, services and updates) and the company's Memory, Mail and Alveare. It opens from the account menu's gear and swaps the list to a back link to the Agents and its sections, each its own page: General, Appearance, Notifications, and the company's Memory, Mail and Alveare, then Updates; the account menu holds the gear in its header, then Usage (only once billing has answered with its page), Theme, Language and Sign out, and never a second Settings row.
|
|
776
|
-
- **The window header** is the Agent's title row: her orb and name, the chat switcher, then, on a chat, the side panel's toggle, and her three dots last (New chat, Edit, Open in Portal, Delete).
|
|
777
|
-
- **The side panel is opened, never pushed.** On a chat, the header's toggle opens the window's right side on the panel the person last chose: the Browser, or Artifacts, the images, documents and links in the Agent's chats, as Hermes names them, newest first, one opening large in their place. Its 44 px band names the panel, then the switch between the two, then ×; while she browses behind Artifacts or with the panel closed, the toggle and the switch's Browser carry a dot, and nothing moves by itself. × or Esc closes it and gives focus back to the toggle, while a page she is browsing keeps loading behind. Opened, it takes 44% of the window, held between 28rem and 48rem, and yields first: by its drag edge it narrows to 352 px and widens only as far as leaves the Agents list and 360 px of chat; under 1024 px it lies over the chat at the same width, without a drag edge. It is not a `Sheet`: it never blocks the chat, takes focus or dims the page.
|
|
778
|
-
- **The list narrows.** From 640 to 899 px it becomes a column of 48 px squares: Find, Scheduled tasks, Wiki and Skills, then the orbs, each named with its state line in a tooltip; under 640 px it leaves for a sheet the header's sidebar button opens.
|
|
768
|
+
Nadia's window, its list, its Settings and its side panel are Nadia's register ([Nadia's design doctrine](../../apps/nadia/docs/design-doctrine.md#the-window)).
|
|
779
769
|
|
|
780
770
|
**Alveare** keeps the same arrangement in Buzz's components: places in the sidebar, Inbox first; the channel header names the channel and holds only the channel's own controls; the update card and the package's `AccountMenu` stand at the sidebar's foot; the top band keeps only the sidebar toggle.
|
|
781
771
|
|
|
@@ -785,17 +775,19 @@ A product page is one of five page compositions, each answering one question fir
|
|
|
785
775
|
|
|
786
776
|
| Composition | Owner | First answer | Structure |
|
|
787
777
|
| --- | --- | --- | --- |
|
|
788
|
-
| Overview | `OverviewPage` | What needs attention? | The period
|
|
789
|
-
| Collection | `CollectionPage` | Which record? | The title
|
|
790
|
-
| Object | `ObjectPage` | What is this, what can I do? | The parent in the path and its sections in the sidebar
|
|
791
|
-
| Settings | `SettingsPage` | What can I change? |
|
|
792
|
-
| Library | `LibraryShelf` for Agent templates; `CollectionPage` for Skills and Plugins | What reusable thing can I use? | Agent templates as Vercel's Templates gallery
|
|
778
|
+
| Overview | `OverviewPage` | What needs attention? | The period, the figures, the chart cards, then the exceptions that need a person. Never a stack of previews of every section. |
|
|
779
|
+
| Collection | `CollectionPage` | Which record? | The title and the page's actions, the sibling collections as line tabs, one toolbar, then one line per record ("Tables and missing values"); one row is one hover and one open target. A collection whose reader must also see what waits on them across its records takes a `rail`. The Portal's Agents are its exception, a `DataTable` of entity rows, as Vercel's Deployments list. |
|
|
780
|
+
| Object | `ObjectPage` | What is this, what can I do? | The parent in the path and its sections in the sidebar, then the object card, then its sections, each a card only where it owns a decision. An Agent's first section, Profile, opens with her `AgentProfileCard`, the same in every product. |
|
|
781
|
+
| Settings | `SettingsPage` | What can I change? | Section cards, each saving its own fields; the danger zone closes the page. |
|
|
782
|
+
| Library | `LibraryShelf` for Agent templates; `CollectionPage` for Skills and Plugins | What reusable thing can I use? | Agent templates as Vercel's Templates gallery; Skills and Plugins as an entity collection, with staff's hub as its rail. |
|
|
783
|
+
|
|
784
|
+
Each composition's usage page holds its slots, geometry and states.
|
|
793
785
|
|
|
794
786
|
The pages share the parts below them, each with one owner: one line per record is `RecordList`, which `CollectionPage`, an overview's exceptions and an object's "Needs attention" section draw; an absence is `EmptyState` ("Elevation & Depth"); an overlay is the owner its job names ("Menus and commands"); what happened is `ActivityFeed` ("Activity"); a record's mark is `IdentityMark` ("Identity marks").
|
|
795
787
|
|
|
796
|
-
Every setting is that Settings composition, whether it belongs to the person, to the platform or to one record's Settings tab, so the column keeps its width and its field layout from one entry of a settings menu to the next, and each section saves its own fields from its own footer ("Cards and sections").
|
|
788
|
+
Every setting is that Settings composition, whether it belongs to the person, to the platform or to one record's Settings tab, so the column keeps its width and its field layout from one entry of a settings menu to the next, and each section saves its own fields from its own footer ("Cards and sections"). A card's header and fields share one uninterrupted body, and only its save footer has a divider. `SettingsPage`'s, `SettingsSection`'s and `SettingsField`'s usage pages hold the column, the cards and the fields; Nadia keeps its settings column at most 42rem. A structured table keeps visible column names while its container can hold the data, and a matrix whose every column must stay, such as notification audiences by group, keeps them all and lets its names wrap.
|
|
797
789
|
|
|
798
|
-
Collections and working pages open with the same header
|
|
790
|
+
Collections and working pages open with the same header, `PageHeader`, with the page's actions on the title's row through `PageActions`, whose usage pages hold their order, variants and wrapping. Settings pages open directly with their section cards and keep a screen-reader h1 for the destination; an extra visible title would duplicate the navigation and delay the first setting. An action always sits on the title of the thing it acts on, never on a tab's, and one command is a button, never a menu of one. Navigation remains a visible link or part of the navigation, never an overflow command. Under the title sits at most the one muted line saying what the page's records are for; nothing introduces, explains or counts the page. Inside an object worked from a section sidebar, the title is the section's name ("Apps"); a page that opens with the object's own header or card, such as an Agent's Profile, has it as its title and no title row above it.
|
|
799
791
|
|
|
800
792
|
A collection is named once, by the page's title, and the collection's card never adds a header that only describes it. A populated collection carries no picture; its first use shows one, in every product ("Elevation & Depth"). The table's footer holds only a count or the paging, never a help sentence: guidance a step needs lives in that step.
|
|
801
793
|
|
|
@@ -834,18 +826,9 @@ The owner approved the materials on 18 October 2026: Vercel's surfaces with a li
|
|
|
834
826
|
|
|
835
827
|
**Product views on the website** preserve the real interface. Nadia uses captures of the running application, with the unchanged full-size image linked and capture provenance recorded in the repository, following the founder's 12 October correction of invented UI. Portal and Alveare may use inert scenes built from real components with fictional example data recorded in the repository. Never invent interface controls or frame a view in a device mockup. A product window takes the raised height on its ground; a card that overlaps it floats. Live components use dark mode in a black section; captures preserve the application's captured theme.
|
|
836
828
|
|
|
837
|
-
Absence follows its container, and only a first use has a picture. In every product, the Portal included, a collection's first use shows its section's picture, and every other kind of absence goes without one. A picture sits on a working screen only there: never in a populated collection, a row or any other card; whole-page moments keep theirs ("Entry screens"). A page or region absence is a resting card with its own edge, never a dashed boundary; an absence inside a card is unframed, because the card already owns the edge, and `CollectionPage` puts every absence it draws in its card. `EmptyState`
|
|
829
|
+
Absence follows its container, and only a first use has a picture. In every product, the Portal included, a collection's first use shows its section's picture, and every other kind of absence goes without one. A picture sits on a working screen only there: never in a populated collection, a row or any other card; whole-page moments keep theirs ("Entry screens"). A page or region absence is a resting card with its own edge, never a dashed boundary; an absence inside a card is unframed, because the card already owns the edge, and `CollectionPage` puts every absence it draws in its card. `EmptyState` is the only owner of an absence: nothing else draws one (`empty-state-owner`), its `scope` (`page`, `region` or `card`) sets that frame, and it has no presentation option, so every product draws each kind the same way. A composition takes its absences as props (`empty`, `noMatch`, `failed`), as a `DataTable` takes `empty`. Its kind names the cause, and `EmptyState`'s usage page holds what each kind draws: `firstUse` (a collection with no records yet: its section's picture from the approved set in `@nadicodeai/design-system/assets/empty`, which [the art direction](../../skills/design/art-direction/references/surfaces.md#the-empty-state-set) keeps, and the one action that adds the first record, which the page's title row also keeps as its filled primary; a create action carries the leading +), `nothingYet`, `noResults`, `cleared`, `denied` and `failed`; a card-sized failure is `failed` with `scope="card"`, and there is no `ErrorCard`.
|
|
838
830
|
|
|
839
|
-
|
|
840
|
-
- `nothingYet`: a list that is empty now and fills by itself. One line, no picture, nothing to press.
|
|
841
|
-
- `noResults`: a search or filter that matches nothing. One line and Clear filters (or Clear search), no picture. A single typed query is quoted in curly quotes.
|
|
842
|
-
- `cleared`: work that is finished. The success mark and one line.
|
|
843
|
-
- `denied`: this viewer's role or plan does not open the page or region. The lock mark, a title (a heading), one line naming the feature and, when the plan gates it, the plan, and the one way out. One gated tile inside an open page is a `MessageNotice`, never a `denied`.
|
|
844
|
-
- `failed`: a read that failed where content would be. The warning mark, the message's title and body, at most two controls with Retry first, and, for a failure on our side, its identifier in a collapsed disclosure, in monospace, with a copy button. A failure that fills a page moves focus to its first control. A card-sized failure is `failed` with `scope="card"`; there is no `ErrorCard`.
|
|
845
|
-
|
|
846
|
-
The quiet lines (`nothingYet`, `noResults`, `cleared`) carry no live role of their own: the wrapper that stays mounted while rows and absence swap announces them, once.
|
|
847
|
-
|
|
848
|
-
A persistent notice sits in the section it concerns, action feedback is a toast, and field validation stays with its field. A notice carries one action, a 32 px outline button, and at most a second one after it, such as Nadia's Ask Nadia after Try again, and has no close button: it stays until the state changes, and one note stands for one concept. A section notice is always the framed note, with or without its action; the page or the account gets a `NoticeBanner`, which carries its one fix as a command (never a ready-made button), reads at 16 px and draws its button as a pill. A toast leaves after 6 s, which is also the Undo window; a failure the person must handle is never a toast alone but a very short toast beside a persistent notice. A notice, a failed read, a confirmation's error and a toast each show a message its product's catalogue worded, never a sentence written where it shows: `MessageNotice` under the control whose write failed (`action`) or atop the section it concerns (`section`), `EmptyState` `failed`, `ConfirmDialog`'s error and the toast. Each wraps a long word, never truncates, closes its title with a full stop before a body that follows on the same line, and shows a body only when it says more than the title ([the decision](../../docs/adr/2026-10-08-every-message-a-customer-reads-is-a-code-its-products-catalogue-words.md)).
|
|
831
|
+
A persistent notice sits in the section it concerns, action feedback is a toast, and field validation stays with its field. A notice has no close button: it stays until the state changes, and one note stands for one concept. A section notice is `MessageNotice`; the page or the account gets a `NoticeBanner`; a failure the person must handle is never a toast alone but a very short toast beside a persistent notice. A notice, a failed read, a confirmation's error and a toast each show a message its product's catalogue worded, never a sentence written where it shows ([the decision](../../docs/adr/2026-10-08-every-message-a-customer-reads-is-a-code-its-products-catalogue-words.md)). Each wraps a long word, never truncates, closes its title with a full stop before a body that follows on the same line, and shows a body only when it says more than the title; their usage pages hold how each draws it.
|
|
849
832
|
|
|
850
833
|
Dialogs, sheets, drawers and the command palette sit over the scrim ("Colors"); popovers, selects and toasts float without one. Focus is not elevation: it is always the focus outline.
|
|
851
834
|
|
|
@@ -890,16 +873,16 @@ answer keeps its component, density, value format and action placement.
|
|
|
890
873
|
|
|
891
874
|
| Information | Component and context |
|
|
892
875
|
| --- | --- |
|
|
893
|
-
| Records a person finds one of and acts on | `RecordList
|
|
894
|
-
| Records with the same comparable facts | `DataTable
|
|
895
|
-
| A descriptive item with supporting prose | `ItemGroup` and `Item
|
|
896
|
-
| What happened, in order | `ActivityFeed
|
|
897
|
-
| The identity of a record in a collection | `RecordIdentity
|
|
898
|
-
| Facts about one object | `ObjectPage`'s facts, `ObjectFacts` or `SettingsFactsSection
|
|
899
|
-
| A coherent set of changes | `SettingsSection` with its `save` and `SettingsField
|
|
900
|
-
| A classification, lifecycle or operation | `Badge`, `StatusBadge` or `ActionStatus
|
|
876
|
+
| Records a person finds one of and acts on | `RecordList` inside `CollectionPage`, on a page of its own. |
|
|
877
|
+
| Records with the same comparable facts | `DataTable`. |
|
|
878
|
+
| A descriptive item with supporting prose | `ItemGroup` and `Item`, rather than invented table columns. |
|
|
879
|
+
| What happened, in order | `ActivityFeed` ("Activity"). |
|
|
880
|
+
| The identity of a record in a collection | `RecordIdentity`; the containing list owns navigation. |
|
|
881
|
+
| Facts about one object | `ObjectPage`'s facts, `ObjectFacts` or `SettingsFactsSection`, in one coherent section. A relation uses its same identity or `Tag`; it does not become a separate card. |
|
|
882
|
+
| A coherent set of changes | `SettingsSection` with its `save` and `SettingsField`. |
|
|
883
|
+
| A classification, lifecycle or operation | `Badge`, `StatusBadge` or `ActionStatus`. A missing value, an empty list and a failed read remain distinct. |
|
|
901
884
|
| Another view or sibling collection of the current scope | `TabsNav` or line `Tabs` ("Controls"). A tab never introduces a new scope or a second collection owner. |
|
|
902
|
-
| A measurement over time or across objects | The
|
|
885
|
+
| A measurement over time or across objects | The KPI or chart composition for the reading ("Data Visualization"); a named comparison is a `DataTable` with units and visible headings. |
|
|
903
886
|
|
|
904
887
|
One section holds one complete task or answer. A status, explanatory sentence
|
|
905
888
|
or Change button belongs beside the facts or fields it qualifies; it does not
|
|
@@ -917,7 +900,7 @@ Every component has a usage page, as Geist documents each of its own: what it is
|
|
|
917
900
|
| Words | Which strings the product words, and how. |
|
|
918
901
|
| Access | Its role, its name, its keyboard path and its focus. |
|
|
919
902
|
|
|
920
|
-
The page is written in the component's own source, as the TSDoc of its main export (`@family`, `@when`, `@instead`, `@behaviour`, `@words`, `@access`), so an editor shows it on hover in every product; `@nadicodeai/ui`'s showcase renders every page, family by family, with the component drawn in its states. A component without its usage page, or a page without its specimen, fails the package's checks. A usage page applies the rules in this file and never restates one.
|
|
903
|
+
The page is written in the component's own source, as the TSDoc of its main export (`@family`, `@when`, `@instead`, `@behaviour`, `@words`, `@access`), so an editor shows it on hover in every product; `@nadicodeai/ui`'s showcase renders every page, family by family, with the component drawn in its states. A component without its usage page, or a page without its specimen, fails the package's checks. A usage page holds its component's own rules, applies the shared rules in this file and never restates one.
|
|
921
904
|
|
|
922
905
|
The table below maps all 73 entries in the [Geist component reference](https://vercel.com/geist/introduction) to our shared owners; how each owner is used is on its usage page. **Component** means a public owner exists for the job; it does not promise every Geist prop. **Composition** means existing parts provide the presentation together. An **enhanced capability gap** names specific behavior, not the absence of a matching component name. Use our exported APIs and names, not Geist's prop names: for example, our Button appearance is `variant`, while HTML submission behavior is `type`. A dedicated name in Geist does not require another primitive in our library; prefer existing compositions before adding another registry or dependency.
|
|
923
906
|
|
|
@@ -927,79 +910,79 @@ Every example and consuming surface covers its reachable populated, empty, loadi
|
|
|
927
910
|
|
|
928
911
|
| Geist reference | Shared owner |
|
|
929
912
|
| --- | --- |
|
|
930
|
-
| [Address Input](https://vercel.com/geist/address-input) |
|
|
931
|
-
| [Avatar](https://vercel.com/geist/avatar) |
|
|
932
|
-
| [Badge](https://vercel.com/geist/badge) |
|
|
933
|
-
| [Banner](https://vercel.com/geist/banner) |
|
|
934
|
-
| [Book](https://vercel.com/geist/book) |
|
|
935
|
-
| [Breadcrumbs](https://vercel.com/geist/breadcrumbs) |
|
|
936
|
-
| [Browser](https://vercel.com/geist/browser) |
|
|
937
|
-
| [Button](https://vercel.com/geist/button) |
|
|
938
|
-
| [Calendar](https://vercel.com/geist/calendar) |
|
|
939
|
-
| [Checkbox](https://vercel.com/geist/checkbox) |
|
|
940
|
-
| [Choicebox](https://vercel.com/geist/choicebox) |
|
|
941
|
-
| [Clearable Input](https://vercel.com/geist/clearable-input) |
|
|
942
|
-
| [Code](https://vercel.com/geist/code) |
|
|
943
|
-
| [Code Block](https://vercel.com/geist/code-block) | `CodeBlock
|
|
944
|
-
| [Collapse](https://vercel.com/geist/collapse) |
|
|
945
|
-
| [Combobox](https://vercel.com/geist/combobox) |
|
|
946
|
-
| [Command Menu](https://vercel.com/geist/command-menu) |
|
|
947
|
-
| [Context Card](https://vercel.com/geist/context-card) |
|
|
948
|
-
| [Context Menu](https://vercel.com/geist/context-menu) |
|
|
949
|
-
| [Copy Button](https://vercel.com/geist/copy-button) | `CopyButton
|
|
950
|
-
| [Description](https://vercel.com/geist/description) |
|
|
951
|
-
| [Destructive Action Modal](https://vercel.com/geist/destructive-action-modal) |
|
|
952
|
-
| [Dots Menu](https://vercel.com/geist/dots-menu) |
|
|
953
|
-
| [Drawer](https://vercel.com/geist/drawer) |
|
|
954
|
-
| [Empty State](https://vercel.com/geist/empty-state) |
|
|
955
|
-
| [Entity](https://vercel.com/geist/entity) |
|
|
956
|
-
| [Error](https://vercel.com/geist/error) |
|
|
957
|
-
| [Error Card](https://vercel.com/geist/error-card) | `EmptyState kind="failed" scope="card"`; no ErrorCard export
|
|
958
|
-
| [Feedback](https://vercel.com/geist/feedback) |
|
|
959
|
-
| [Fieldset](https://vercel.com/geist/fieldset) |
|
|
960
|
-
| [File Tree](https://vercel.com/geist/file-tree) |
|
|
961
|
-
| [Gauge](https://vercel.com/geist/gauge) |
|
|
962
|
-
| [Grid](https://vercel.com/geist/grid) |
|
|
963
|
-
| [Input](https://vercel.com/geist/input) |
|
|
964
|
-
| [JSON View](https://vercel.com/geist/json-view) | Composition for static JSON: code display with exact serialized text
|
|
965
|
-
| [Keyboard Input](https://vercel.com/geist/keyboard-input) |
|
|
966
|
-
| [Label](https://vercel.com/geist/label) |
|
|
967
|
-
| [Load More Button](https://vercel.com/geist/load-more-button) |
|
|
968
|
-
| [Loading Dots](https://vercel.com/geist/loading-dots) |
|
|
969
|
-
| [Menu](https://vercel.com/geist/menu) |
|
|
970
|
-
| [MiddleTruncate](https://vercel.com/geist/middle-truncate) | `MiddleTruncate
|
|
971
|
-
| [Modal](https://vercel.com/geist/modal) |
|
|
972
|
-
| [Multi Select](https://vercel.com/geist/multi-select) |
|
|
973
|
-
| [Note](https://vercel.com/geist/note) |
|
|
974
|
-
| [Pagination](https://vercel.com/geist/pagination) | Not built until a page needs it: the pages of a table of records are `DataTable`'s own Previous and Next under its card, and `RecordList`'s footer paging
|
|
975
|
-
| [Phone](https://vercel.com/geist/phone) |
|
|
976
|
-
| [Pill](https://vercel.com/geist/badge#pill) | `Badge
|
|
977
|
-
| [Progress](https://vercel.com/geist/progress) |
|
|
978
|
-
| [Project Banner](https://vercel.com/geist/project-banner) |
|
|
979
|
-
| [Radio](https://vercel.com/geist/radio) |
|
|
980
|
-
| [Relative Time Card](https://vercel.com/geist/relative-time-card) |
|
|
981
|
-
| [Scroller](https://vercel.com/geist/scroller) |
|
|
982
|
-
| [Search Input](https://vercel.com/geist/search-input) |
|
|
983
|
-
| [Select](https://vercel.com/geist/select) |
|
|
984
|
-
| [Separator](https://vercel.com/geist/separator) |
|
|
985
|
-
| [Sheet](https://vercel.com/geist/sheet) |
|
|
986
|
-
| [Show more](https://vercel.com/geist/show-more) | Not built until a page needs it: a list that grows from the server takes `LoadMoreButton
|
|
987
|
-
| [Skeleton](https://vercel.com/geist/skeleton) |
|
|
988
|
-
| [Slider](https://vercel.com/geist/slider) |
|
|
989
|
-
| [Snippet](https://vercel.com/geist/snippet) | `Snippet
|
|
990
|
-
| [Spinner](https://vercel.com/geist/spinner) |
|
|
991
|
-
| [Split Button](https://vercel.com/geist/split-button) | Not built until a page needs it
|
|
992
|
-
| [Status Dot](https://vercel.com/geist/status-dot) |
|
|
993
|
-
| [Switch](https://vercel.com/geist/switch) |
|
|
994
|
-
| [Table](https://vercel.com/geist/table) |
|
|
995
|
-
| [Tabs](https://vercel.com/geist/tabs) |
|
|
996
|
-
| [Text With Copy Button](https://vercel.com/geist/text-with-copy-button) | `TextWithCopyButton
|
|
997
|
-
| [Textarea](https://vercel.com/geist/textarea) |
|
|
998
|
-
| [Theme Switcher](https://vercel.com/geist/theme-switcher) |
|
|
999
|
-
| [Toast](https://vercel.com/geist/toast) |
|
|
1000
|
-
| [Toggle](https://vercel.com/geist/toggle) |
|
|
1001
|
-
| [Tooltip](https://vercel.com/geist/tooltip) |
|
|
1002
|
-
| [Video](https://vercel.com/geist/video) |
|
|
913
|
+
| [Address Input](https://vercel.com/geist/address-input) | `Field` parts in a `FieldGroup` 16 px apart: a `NativeSelect` country first, a street `Combobox` (or `Input` when there is no lookup), Address line 2 with (optional) written in its label, then pairs such as State and ZIP or Postal code and City two-up; a failed lookup ends in the manual fields. No dedicated export: it needs a provider only a product has |
|
|
914
|
+
| [Avatar](https://vercel.com/geist/avatar) | The `Avatar` family; a record's mark is `IdentityMark`, and an Agent is her `AgentOrb` |
|
|
915
|
+
| [Badge](https://vercel.com/geist/badge) | `Badge`; `StatusBadge` for state, `Tag` for a categorical fact |
|
|
916
|
+
| [Banner](https://vercel.com/geist/banner) | `NoticeBanner` |
|
|
917
|
+
| [Book](https://vercel.com/geist/book) | `Card` / `PictureLabel` + `AspectRatio` and cover artwork; no book-frame export |
|
|
918
|
+
| [Breadcrumbs](https://vercel.com/geist/breadcrumbs) | The `Breadcrumb` family |
|
|
919
|
+
| [Browser](https://vercel.com/geist/browser) | `Card` + `AspectRatio` and decorative browser chrome; `DesktopShell` stays real product chrome |
|
|
920
|
+
| [Button](https://vercel.com/geist/button) | `Button`, `ButtonLink` and `buttonVariants` |
|
|
921
|
+
| [Calendar](https://vercel.com/geist/calendar) | `Calendar`; `DateRangeControl` for a metric's window |
|
|
922
|
+
| [Checkbox](https://vercel.com/geist/checkbox) | `Checkbox` with the Field parts |
|
|
923
|
+
| [Choicebox](https://vercel.com/geist/choicebox) | `ChoiceboxGroup` |
|
|
924
|
+
| [Clearable Input](https://vercel.com/geist/clearable-input) | `ClearableInput` |
|
|
925
|
+
| [Code](https://vercel.com/geist/code) | Semantic `code` with the shared mono typography roles |
|
|
926
|
+
| [Code Block](https://vercel.com/geist/code-block) | `CodeBlock` |
|
|
927
|
+
| [Collapse](https://vercel.com/geist/collapse) | `Accordion`, `Collapsible` and the complete `Disclosure`; a collapse never nests in another |
|
|
928
|
+
| [Combobox](https://vercel.com/geist/combobox) | `Combobox` |
|
|
929
|
+
| [Command Menu](https://vercel.com/geist/command-menu) | `CommandDialog` |
|
|
930
|
+
| [Context Card](https://vercel.com/geist/context-card) | `HoverCard` with `HoverCardSummary` |
|
|
931
|
+
| [Context Menu](https://vercel.com/geist/context-menu) | `ActionContextMenu` |
|
|
932
|
+
| [Copy Button](https://vercel.com/geist/copy-button) | `CopyButton`; `TextWithCopyButton` binds a shown value to it |
|
|
933
|
+
| [Description](https://vercel.com/geist/description) | `ObjectPage`'s `facts`, `ObjectFacts`, `SettingsFactsSection`, `TableValue` |
|
|
934
|
+
| [Destructive Action Modal](https://vercel.com/geist/destructive-action-modal) | `ConfirmDialog` |
|
|
935
|
+
| [Dots Menu](https://vercel.com/geist/dots-menu) | `ActionMenu` for a record, `PageActions`' `menu` for a page |
|
|
936
|
+
| [Drawer](https://vercel.com/geist/drawer) | `Drawer`, the phone's bottom sheet for a short job |
|
|
937
|
+
| [Empty State](https://vercel.com/geist/empty-state) | `EmptyState`, following the [absence contract](#elevation--depth) |
|
|
938
|
+
| [Entity](https://vercel.com/geist/entity) | `RecordList` for records; `Item`, `ItemGroup` and `ItemSelect` for a descriptive list; `CatalogEntry` in `LibraryShelf` and `CatalogDrawer`; `AgentListRow` |
|
|
939
|
+
| [Error](https://vercel.com/geist/error) | `FieldError` (a field), `MessageNotice` (a control or section), `EmptyState kind="failed"` with its reference (a block) |
|
|
940
|
+
| [Error Card](https://vercel.com/geist/error-card) | `EmptyState kind="failed" scope="card"`; no ErrorCard export |
|
|
941
|
+
| [Feedback](https://vercel.com/geist/feedback) | `Popover`, `Field`, `Textarea`, `RadioGroup`, optional `Select`, and `Button` |
|
|
942
|
+
| [Fieldset](https://vercel.com/geist/fieldset) | `SettingsSection` with `SettingsField`; `FieldSet` and `FieldLegend` for semantic subgroups |
|
|
943
|
+
| [File Tree](https://vercel.com/geist/file-tree) | `SidebarMenu` + `Collapsible` + `FileTypeIcon` can follow sidebar-11 for nested files |
|
|
944
|
+
| [Gauge](https://vercel.com/geist/gauge) | `Gauge` |
|
|
945
|
+
| [Grid](https://vercel.com/geist/grid) | Layout grid, `CardRow`, website `nc-page`; no ruled `Grid` API |
|
|
946
|
+
| [Input](https://vercel.com/geist/input) | `Input`; `InputGroup` for parts inside the box; `Field` or `SettingsField` for the card around it |
|
|
947
|
+
| [JSON View](https://vercel.com/geist/json-view) | Composition for static JSON: code display with exact serialized text |
|
|
948
|
+
| [Keyboard Input](https://vercel.com/geist/keyboard-input) | `Kbd` |
|
|
949
|
+
| [Label](https://vercel.com/geist/label) | `Label`, `FieldLabel` and `FieldLegend` |
|
|
950
|
+
| [Load More Button](https://vercel.com/geist/load-more-button) | `LoadMoreButton` |
|
|
951
|
+
| [Loading Dots](https://vercel.com/geist/loading-dots) | `Button`'s `loading` and `WaitingLine`; no LoadingDots |
|
|
952
|
+
| [Menu](https://vercel.com/geist/menu) | `ActionMenu`, `ActionContextMenu`, `PageActions`' `menu` and `AccountMenu`; the `DropdownMenu` family directly only for a choice menu such as a sort |
|
|
953
|
+
| [MiddleTruncate](https://vercel.com/geist/middle-truncate) | `MiddleTruncate` |
|
|
954
|
+
| [Modal](https://vercel.com/geist/modal) | The `Dialog` family, `FormDialog` for a short form and `ConfirmDialog` for a consequence |
|
|
955
|
+
| [Multi Select](https://vercel.com/geist/multi-select) | `MultiSelect`; `Combobox multiple` when typing to find matters more; `CollectionFilters` for query facets |
|
|
956
|
+
| [Note](https://vercel.com/geist/note) | `MessageNotice placement="section"` |
|
|
957
|
+
| [Pagination](https://vercel.com/geist/pagination) | Not built until a page needs it: the pages of a table of records are `DataTable`'s own Previous and Next under its card, and `RecordList`'s footer paging |
|
|
958
|
+
| [Phone](https://vercel.com/geist/phone) | `AspectRatio` + decorative frame and captured content; no device-frame export |
|
|
959
|
+
| [Pill](https://vercel.com/geist/badge#pill) | `Badge` through `render` for a link-like badge; `Tag` for a static category; `CollectionFilters` for filters |
|
|
960
|
+
| [Progress](https://vercel.com/geist/progress) | The `Progress` family; `UsageMeter` |
|
|
961
|
+
| [Project Banner](https://vercel.com/geist/project-banner) | `NoticeBanner` |
|
|
962
|
+
| [Radio](https://vercel.com/geist/radio) | `RadioGroup` |
|
|
963
|
+
| [Relative Time Card](https://vercel.com/geist/relative-time-card) | `RecordTime` |
|
|
964
|
+
| [Scroller](https://vercel.com/geist/scroller) | `ScrollArea` and `ScrollBar` |
|
|
965
|
+
| [Search Input](https://vercel.com/geist/search-input) | `CollectionSearch` in `CollectionToolbar` |
|
|
966
|
+
| [Select](https://vercel.com/geist/select) | The `Select` and `NativeSelect` families |
|
|
967
|
+
| [Separator](https://vercel.com/geist/separator) | `Separator` |
|
|
968
|
+
| [Sheet](https://vercel.com/geist/sheet) | `Sheet`; `RecordSheet` for one record looked at from a list; `FormDrawer` and `CatalogDrawer` for its steps and catalogue forms |
|
|
969
|
+
| [Show more](https://vercel.com/geist/show-more) | Not built until a page needs it: a list that grows from the server takes `LoadMoreButton` |
|
|
970
|
+
| [Skeleton](https://vercel.com/geist/skeleton) | `Skeleton` and `SkeletonRegion` |
|
|
971
|
+
| [Slider](https://vercel.com/geist/slider) | `Slider` |
|
|
972
|
+
| [Snippet](https://vercel.com/geist/snippet) | `Snippet` |
|
|
973
|
+
| [Spinner](https://vercel.com/geist/spinner) | `Button`'s `loading` and `WaitingLine`, no Spinner export |
|
|
974
|
+
| [Split Button](https://vercel.com/geist/split-button) | Not built until a page needs it |
|
|
975
|
+
| [Status Dot](https://vercel.com/geist/status-dot) | `StatusDot` and `StatusBadge` |
|
|
976
|
+
| [Switch](https://vercel.com/geist/switch) | `SegmentedControl` for two or three exclusive views of one surface; `Tabs` for panels; `ToggleGroup` for pressed buttons; `ThemeModeSwitcher` for the theme |
|
|
977
|
+
| [Table](https://vercel.com/geist/table) | `Table`; `DataTable` for records; `RecordList` for rows that name themselves; `TableCard` and `TableValue` |
|
|
978
|
+
| [Tabs](https://vercel.com/geist/tabs) | `Tabs`, and `TabsNav` with `TabsLink` for URL views |
|
|
979
|
+
| [Text With Copy Button](https://vercel.com/geist/text-with-copy-button) | `TextWithCopyButton` |
|
|
980
|
+
| [Textarea](https://vercel.com/geist/textarea) | `Textarea` with `Field` or `SettingsField` |
|
|
981
|
+
| [Theme Switcher](https://vercel.com/geist/theme-switcher) | `ThemeModeSwitcher`, `ThemeModeMenu` and `ThemeModeSegments` |
|
|
982
|
+
| [Toast](https://vercel.com/geist/toast) | `Toaster` and `showMessageToast` |
|
|
983
|
+
| [Toggle](https://vercel.com/geist/toggle) | `Switch` for a boolean setting; our `Toggle` is a pressed button |
|
|
984
|
+
| [Tooltip](https://vercel.com/geist/tooltip) | The `Tooltip` family |
|
|
985
|
+
| [Video](https://vercel.com/geist/video) | `AspectRatio` + native video, controls, poster and caption tracks |
|
|
1003
986
|
|
|
1004
987
|
### Additional shared building blocks
|
|
1005
988
|
|
|
@@ -1008,47 +991,40 @@ These shared components also follow the same foundations, although Geist does no
|
|
|
1008
991
|
| Owner | Use and composition contract |
|
|
1009
992
|
| --- | --- |
|
|
1010
993
|
| `Sidebar`, `SidebarSections`, `UpdateCard`, `AccountMenu`, `DesktopShell`; the Portal's `PortalShellFrame` | Persistent product navigation and workspace chrome ("Product shells"). The product owns destinations and active state; the shell owns compact behavior, landmarks and layout. `SidebarSections` is the sidebar's swap into an object's sections or an area's sub-menu, `UpdateCard` the offer to update above the account. Never add a competing sidebar to a page. |
|
|
1011
|
-
| `Popover` | A bounded contextual control such as filters or a scope chooser. Name its trigger, keep essential meaning visible outside hover, and restore focus when it closes. Which form surface a job takes is decided in [Menus and commands](#menus-and-commands). |
|
|
1012
|
-
| `InputOTP` and its group/slot parts | A fixed-length verification code. Keep one logical input with paste and keyboard behavior, a visible label, invalid/retry state and a real resend policy. The product owns length, expiry and submission. |
|
|
1013
|
-
| `Carousel` | A finite horizontal rail where adjacent media or items have a meaningful sequence. Give previous/next controls clear names and boundaries; preserve keyboard access and reduced motion. A sortable record collection uses a table or entity list. |
|
|
1014
|
-
| `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle` | A workspace with genuinely adjustable panes. Keep keyboard resizing, meaningful minimum sizes, readable content and a compact alternative. The product owns persistence of pane sizes. |
|
|
1015
|
-
| `AspectRatio` | Stable layout for real media while it loads. Supply a meaningful ratio and correct media alternative; the wrapper creates neither playback controls nor a device-frame component. |
|
|
1016
|
-
| Field parts and form adapters | Connect actual validation to controls, help and errors. Use the field owner that matches the product's form engine; preserve values through recoverable failure. Do not change the form engine during visual styling. |
|
|
1017
|
-
| `PairingCode` | A short code two screens show at once so a person can tell they are talking to each other, such as the four digits Nadia and Alveare Server both show while a Nadia asks to join. Each digit stands in its own cell at `{typography.heading-lg}` with tabular figures, large enough to compare from across a desk, and assistive technology reads the label, then the digits one by one. It only shows a code: a code a person types is `InputOTP`. |
|
|
1018
|
-
| `QrCode` | A real scannable value with a readable fallback and an alternative action when scanning is unavailable. Keep secrets out of accessible labels and show expiry or invalidity from actual state. |
|
|
1019
|
-
| `FileDiff` | Existing code-change comparison, with file identity and additions/removals explained. A diff is not a general code editor or JSON viewer. Preserve exact source and the established conversation/tool owner. |
|
|
1020
994
|
| Chart kit and `KpiCard` | Choose the reading through [Data Visualization](#data-visualization), then use its shared chart owner with units, period, legend and accessible data. Geometry never decides business thresholds. |
|
|
1021
995
|
|
|
996
|
+
`Popover`, `InputOTP`, `Carousel`, the resizable panels, `AspectRatio`, the Field parts, `PairingCode`, `QrCode` and `FileDiff` each hold their contract on their usage page. Which form surface a job takes is decided in [Menus and commands](#menus-and-commands).
|
|
997
|
+
|
|
1022
998
|
### Complete compositions
|
|
1023
999
|
|
|
1024
1000
|
Choose the owner for the whole task. Keep its slots and state handling together so pages supply content without recreating card zones, toolbar geometry or overlay behavior.
|
|
1025
1001
|
|
|
1026
|
-
| Task | Shared composition |
|
|
1027
|
-
| --- | --- |
|
|
1028
|
-
| Settings | `SettingsPage` → `SettingsSection` with its `save` → `SettingsField`. |
|
|
1029
|
-
| Read-only facts | `ObjectPage`'s `facts`, `SettingsFactsSection` or `ObjectFacts`, with `TableValue` for missing facts. |
|
|
1030
|
-
| Entity collection | `CollectionPage` on `RecordList
|
|
1031
|
-
| A list inside another page | `RecordList` with its `heading`: an overview's exceptions, an object's "Needs attention". |
|
|
1032
|
-
| Comparable collection | `DataTable` within `TableCard`, under `PageActions` and `CollectionToolbar`. |
|
|
1033
|
-
| Overview | `OverviewPage` with its `KpiCard` figures, its `ChartCard`s and its exceptions
|
|
1034
|
-
| Object | `ObjectPage` with `ObjectSection`, `ObjectFacts`, a `RecordList` with its heading, a `SettingsSection` or an `ActivityFeed` as its sections. |
|
|
1035
|
-
| A reusable thing to add | `LibraryShelf` with `AgentCard`s for a gallery of templates; `CollectionPage` for a catalog a person finds, opens and adds from (the Portal's Skills and Plugins); `CatalogDrawer` with `CatalogEntry`s where the choice opens from a page. |
|
|
1036
|
-
| What happened | `ActivityFeed`; one run's steps are `RunTimeline` ("Activity"). |
|
|
1037
|
-
| Getting something set up | `NumberedSteps` for the steps on a page; `FormDrawer job="steps"` for a setup with a wait. |
|
|
1038
|
-
| Short form: a new record, or one or two values from a command | `FormDialog` with Field parts; Portal binds it through `ActionDialogForm`. A record in a list edits inside its row (Entity collection); a catalog uses `CatalogDrawer` and a setup in steps `FormDrawer` ([Menus and commands](#menus-and-commands)). |
|
|
1039
|
-
| One record looked at from a list | `RecordSheet`. |
|
|
1040
|
-
| Destructive confirmation | `ConfirmDialog`; the app's confirm-action adapter. |
|
|
1041
|
-
| Global commands or record actions | `CommandDialog` for Find; `ActionMenu` and `ActionContextMenu` for one record; `PageActions` for a page. |
|
|
1042
|
-
| Absence or failed read | `EmptyState`, through the composition's `empty`, `noMatch` and `failed` or `DataTable.empty`; `MessageNotice` for persistent conditions. |
|
|
1043
|
-
| Rich choices | `ChoiceboxGroup` with `ChoiceboxGroupItem`, in the group's own `FieldSet` and legend. |
|
|
1044
|
-
| Copyable identifier or command | `TextWithCopyButton` for a value, `Snippet` for a command; the prompt is the component's and is never copied. |
|
|
1045
|
-
| Plain code or static JSON | `CodeBlock`. |
|
|
1046
|
-
| A record's time | `RecordTime`: the time in its verb's sentence, or the clock time in a feed, with UTC and the local zone in its hover card
|
|
1047
|
-
| Expandable file navigation | `SidebarMenu` and `Collapsible`, following shadcn sidebar-11, with file icons and real file links or commands.
|
|
1048
|
-
| Feedback collection | `Popover` with Field, Textarea, optional RadioGroup/Select and Button; inline rendering uses the same form parts.
|
|
1049
|
-
| Native media playback | `AspectRatio` around a native video with its controls, poster and caption tracks.
|
|
1050
|
-
|
|
1051
|
-
Use `CopyButton`, `TextWithCopyButton`, `Snippet` and `CodeBlock` for their complete compositions. Feedback and expandable file navigation combine existing parts with product adapters. Syntax colour
|
|
1002
|
+
| Task | Shared composition |
|
|
1003
|
+
| --- | --- |
|
|
1004
|
+
| Settings | `SettingsPage` → `SettingsSection` with its `save` → `SettingsField`. |
|
|
1005
|
+
| Read-only facts | `ObjectPage`'s `facts`, `SettingsFactsSection` or `ObjectFacts`, with `TableValue` for missing facts. |
|
|
1006
|
+
| Entity collection | `CollectionPage` on `RecordList`, with `RowEditForm` for the edit inside a row. The page supplies its records and their commands as data, never its own toolbar, table, rows or menus. |
|
|
1007
|
+
| A list inside another page | `RecordList` with its `heading`: an overview's exceptions, an object's "Needs attention". |
|
|
1008
|
+
| Comparable collection | `DataTable` within `TableCard`, under `PageActions` and `CollectionToolbar`. |
|
|
1009
|
+
| Overview | `OverviewPage` with its `KpiCard` figures, its `ChartCard`s and its exceptions; the product supplies the reading time and the way to each figure's owner. |
|
|
1010
|
+
| Object | `ObjectPage` with `ObjectSection`, `ObjectFacts`, a `RecordList` with its heading, a `SettingsSection` or an `ActivityFeed` as its sections. |
|
|
1011
|
+
| A reusable thing to add | `LibraryShelf` with `AgentCard`s for a gallery of templates; `CollectionPage` for a catalog a person finds, opens and adds from (the Portal's Skills and Plugins); `CatalogDrawer` with `CatalogEntry`s where the choice opens from a page. |
|
|
1012
|
+
| What happened | `ActivityFeed`; one run's steps are `RunTimeline` ("Activity"). |
|
|
1013
|
+
| Getting something set up | `NumberedSteps` for the steps on a page; `FormDrawer job="steps"` for a setup with a wait. |
|
|
1014
|
+
| Short form: a new record, or one or two values from a command | `FormDialog` with Field parts; Portal binds it through `ActionDialogForm`. A record in a list edits inside its row (Entity collection); a catalog uses `CatalogDrawer` and a setup in steps `FormDrawer` ([Menus and commands](#menus-and-commands)). |
|
|
1015
|
+
| One record looked at from a list | `RecordSheet`. |
|
|
1016
|
+
| Destructive confirmation | `ConfirmDialog`; the app's confirm-action adapter. |
|
|
1017
|
+
| Global commands or record actions | `CommandDialog` for Find; `ActionMenu` and `ActionContextMenu` for one record; `PageActions` for a page. |
|
|
1018
|
+
| Absence or failed read | `EmptyState`, through the composition's `empty`, `noMatch` and `failed` or `DataTable.empty`; `MessageNotice` for persistent conditions. |
|
|
1019
|
+
| Rich choices | `ChoiceboxGroup` with `ChoiceboxGroupItem`, in the group's own `FieldSet` and legend. |
|
|
1020
|
+
| Copyable identifier or command | `TextWithCopyButton` for a value, `Snippet` for a command; the prompt is the component's and is never copied. |
|
|
1021
|
+
| Plain code or static JSON | `CodeBlock`. |
|
|
1022
|
+
| A record's time | `RecordTime`: the time in its verb's sentence, or the clock time in a feed, with UTC and the local zone in its hover card; the product supplies its refresh policy. |
|
|
1023
|
+
| Expandable file navigation | `SidebarMenu` and `Collapsible`, following shadcn sidebar-11, with file icons and real file links or commands. Keep the nested lists semantic; selection and roving arrow-key navigation, a full tree widget, need a separately verified keyboard contract. |
|
|
1024
|
+
| Feedback collection | `Popover` with Field, Textarea, optional RadioGroup/Select and Button; inline rendering uses the same form parts. The product supplies the prompt, the topic choices, the permitted context and the destination; no collection backend is implied. |
|
|
1025
|
+
| Native media playback | `AspectRatio` around a native video with its controls, poster and caption tracks. The product supplies the source, the captions, a transcript where needed, the playback policy and the recovery when the media is unavailable; a richer player needs a concrete media requirement. |
|
|
1026
|
+
|
|
1027
|
+
Use `CopyButton`, `TextWithCopyButton`, `Snippet` and `CodeBlock` for their complete compositions. Feedback and expandable file navigation combine existing parts with product adapters. Syntax colour, full JSON or tree-widget navigation, and a JSON view's search highlighting and depth controls remain behaviour gaps: do not invent undocumented props or copy a local implementation into every caller.
|
|
1052
1028
|
|
|
1053
1029
|
### Personalization boundaries
|
|
1054
1030
|
|
|
@@ -1061,95 +1037,65 @@ The owner's decisions where Geist and ours differ:
|
|
|
1061
1037
|
- A settings toggle, the theme included, is a draft that its section's Save applies, where Geist applies a toggle on change. The exception is a switch in a card's header: it applies at once, and that card has no Save, only its footer line.
|
|
1062
1038
|
- Find goes to places only: it runs no command and has no page stack.
|
|
1063
1039
|
- A wait stays still, with no spinner, loading dots or shimmer; a `Button` takes Geist's `loading` behaviour with its pending word in place of the spinner.
|
|
1064
|
-
- `Gauge` is a control for one ratio, never a chart.
|
|
1065
1040
|
- `ChoiceboxGroup`, `ClearableInput`, `Snippet` and `LoadMoreButton` are components, never recipes a page assembles.
|
|
1066
1041
|
- The three-dot trigger stays 36 px, ruled by the owner on 14 October 2026.
|
|
1067
1042
|
|
|
1068
1043
|
### Controls
|
|
1069
1044
|
|
|
1070
|
-
|
|
1045
|
+
`Button`'s usage page holds its sizes, variants and loading; `textLinkVariants`' holds the link treatments; `Checkbox`'s and `RadioGroup`'s hold their checked marks.
|
|
1046
|
+
|
|
1071
1047
|
- **Dialog footers.** A dialog's Cancel sits at the footer's leading edge and its primary at the trailing edge; a dialog with one button fills the footer with it. A step back (Previous) is grouped with Cancel in one wrapper at the leading edge, so the footer keeps two ends. A choice to stop being asked is a checkbox at the end of the body, remembered by whichever action is taken, never a third button. On a phone the dialog and the confirmation are bottom sheets whose footer keeps its one row, Cancel leading and the primary trailing.
|
|
1072
|
-
- **Tabs** switch between sibling collections or views of one scope, such as a company's Members, Invitations and Teams, or Billing's Subscriptions, Approvals and Stripe events. One shows at a time; the choice lives in the URL, as a route or `?tab=` with the first tab left out, so it survives a reload, Back and a shared link; and switching never changes whose things you are looking at. A tab never introduces a new scope: another company or Agent is another place, reached from the sidebar or a scope selector, and a choice of whose things are listed is a filter in the toolbar. A
|
|
1073
|
-
- **
|
|
1074
|
-
- **Fields** draw their edge as a 1 px ring outside the box in `{colors.input}`, darker on hover and full strength with a 4 px halo on focus, `{rounded.sm}` (`{rounded.md}` at 40 px; `rounded` makes a pill), in three heights that Input, Textarea, Select, NativeSelect, Combobox, MultiSelect and InputGroup share: `{spacing.control-height-sm}`, `{spacing.control-height}` and `{spacing.control-height-lg}`. Inline padding is `{spacing.control-padding-inline}`. A prefix or suffix is a filled cell with a divider, or `plain` on the box fill, with a 14 px mark; an icon button inside a field fills the row flush to its edge, is muted until hovered and never fills. Every field has a name: a visible label of 13 px in the secondary text colour, 8 px above the box, tied by id (or `aria-label` where the name is drawn elsewhere). Colour sits in one place: an error turns the ring red, fills the halo (also while the box has focus) and colours the 13 px message under it (8 px below, with an alert mark; 16 px beside a 40 px field), and a Combobox colours its typed text; the label, fill, text, placeholder and marks stay neutral. A disabled box, and the label of a disabled control, step down in fill and text, never in opacity, and ignore hover. A field fills its container. Help is the one-line description of the card that holds the field, one setting to a card, never a line under each field; the error takes its place while it shows. A field that may stay empty says so in its label, never in its placeholder. A field validates when it loses focus, stays focusable while it saves, and the save of a `FormDialog`, `FormDrawer`, `RowEditForm` or `SettingsSection` trims the ends of its text.
|
|
1048
|
+
- **Tabs** switch between sibling collections or views of one scope, such as a company's Members, Invitations and Teams, or Billing's Subscriptions, Approvals and Stripe events. One shows at a time; the choice lives in the URL, as a route or `?tab=` with the first tab left out, so it survives a reload, Back and a shared link; and switching never changes whose things you are looking at. A tab never introduces a new scope: another company or Agent is another place, reached from the sidebar or a scope selector, and a choice of whose things are listed is a filter in the toolbar. A page's collections take the line tabs (`Tabs` with `TabsList variant="line"`), under the title row and above the toolbar. The page's actions stay on its title row whichever tab is shown, the toolbar belongs to the tab shown and switching clears its search and page, and two lists are never stacked with a tab row between them. A set of different things, such as Nadia's company sections, is pages in the sidebar, never tabs. A choice that changes a value rather than a view uses radio or toggle semantics instead. `Tabs`' usage page holds the tabs' geometry and words.
|
|
1049
|
+
- **Fields.** Input, Textarea, Select, NativeSelect, Combobox, MultiSelect and InputGroup share one box in three heights, `Input`'s, and `Field`'s label and message: their usage pages hold the geometry, the states and the validation. Help is the one-line description of the card that holds the field, one setting to a card, never a line under each field; a field that may stay empty says so in its label, never in its placeholder.
|
|
1075
1050
|
- **Focus** is drawn once, by the base layer, on every `:focus-visible` element. A component never repaints it; it may move it to a proxy that stands for the focused element, as a field group does for its input.
|
|
1076
|
-
- Enabled buttons show a pointer; a disabled control advertises nothing. On coarse or non-hover input every target is at least `{spacing.touch-target}`, while a checkbox or radio mark stays compact and its label supplies the target. An unchecked checkbox or radio mark is its `{colors.input}` edge with no fill of its own, so it shows the surface it sits on, and greys on hover unless disabled.
|
|
1051
|
+
- Enabled buttons show a pointer; a disabled control advertises nothing. On coarse or non-hover input every target is at least `{spacing.touch-target}`, while a checkbox or radio mark stays compact and its label supplies the target. An unchecked checkbox or radio mark is its `{colors.input}` edge with no fill of its own, so it shows the surface it sits on, and greys on hover unless disabled.
|
|
1077
1052
|
|
|
1078
1053
|
### Cards and sections
|
|
1079
1054
|
|
|
1080
|
-
|
|
1055
|
+
A card or settings section is composed around a real task, collection or form; its header names the content and may explain scope or consequence, and it is never a card holding only an introduction. A card's or a section's title carries no icon, unless the card stands for one external system, whose mark it then carries. On a settings page the shape follows the data, and when it saves follows whether a half-done edit makes sense. A reversible choice (a switch, a theme, a language, a pick from a short list) applies at once, with no Save, and the product's toast confirms it; a change that fails says so in the toast and the control shows the stored value again. A collection is a table whose Add opens a form and whose every row carries **⋯**, and a destructive action there confirms first. A status is a read-only card with the one action that fixes it. A row of five figures sits in one row from 1280 px, three over two below that, two by two with the fifth across on a tablet, and one column on a phone; it never leaves one figure alone beside a hole.
|
|
1056
|
+
|
|
1057
|
+
`Card`, `CardRow`, `SettingsSection`, `SettingsFactsSection` and `KpiCard` hold their own shapes on their usage pages.
|
|
1081
1058
|
|
|
1082
1059
|
### Menus and commands
|
|
1083
1060
|
|
|
1084
|
-
A record's primary destination is its visible name or a labelled link. Navigation is never hidden in its action menu. Keep the main task visible: Edit opens the record inside its row, as in Vercel Domains; Connect belongs beside an available connection. Additional mutations use an end-aligned `ActionMenu`, the same commands on a right-click through `ActionContextMenu`; a menu is not required when the row has no secondary mutations. Commands reach a person only through `PageActions` (a page), `ActionMenu` and `ActionContextMenu` (a record) and `AccountMenu` (the account), each taking its commands as data (`menu-owner`).
|
|
1061
|
+
A record's primary destination is its visible name or a labelled link. Navigation is never hidden in its action menu. Keep the main task visible: Edit opens the record inside its row, as in Vercel Domains; Connect belongs beside an available connection. Additional mutations use an end-aligned `ActionMenu`, the same commands on a right-click through `ActionContextMenu`; a menu is not required when the row has no secondary mutations. Commands reach a person only through `PageActions` (a page), `ActionMenu` and `ActionContextMenu` (a record) and `AccountMenu` (the account), each taking its commands as data (`menu-owner`). A menu names the record it acts on, keeps a command that cannot run in place with its reason, and puts the destructive command last after a divider; `ActionMenu`'s usage page holds how it draws them, and `AccountMenu`'s the account menu's one exception. A destructive command never becomes the loudest repeated action: it is never a button on every row.
|
|
1085
1062
|
|
|
1086
1063
|
Choose the surface by where the thing being changed is shown and how big the job is, never by the page that happens to need it: the same job takes the same surface in every product. Adding a skill is the catalogue drawer in the Portal and in Nadia, and editing a task or an MCP server opens its row in both. Each surface has one owner:
|
|
1087
1064
|
|
|
1088
1065
|
| The person wants to | Surface | Owner | Example |
|
|
1089
1066
|
| --- | --- | --- | --- |
|
|
1090
|
-
| Change a record shown in a list | Its row opens into the form
|
|
1067
|
+
| Change a record shown in a list | Its row opens into the form | `RowEditForm` in `CollectionPage`'s `editor` | Vercel Domains › Edit; a task, a mailbox, an MCP server, a channel |
|
|
1091
1068
|
| Change a fact on a record's own page or card | In place: a pencil turns the fact into its field, saved by the card's Save | `AgentProfileCard`; an `ObjectSection` that swaps to its `SettingsSection` | An Agent's name and description |
|
|
1092
1069
|
| Add a record through a few fields, or change one or two values from a command | A centred dialog | `FormDialog`; the Portal's `ActionDialogForm` | New task, add a mailbox, add an MCP server |
|
|
1093
|
-
| Choose from a catalogue | A modal sheet at the right edge
|
|
1094
|
-
| Set up in several steps with a wait | The same sheet, its progress
|
|
1095
|
-
| Look at one record from a list, then go back to the list | A sheet from the right that leaves the page usable
|
|
1070
|
+
| Choose from a catalogue | A modal sheet at the right edge | `CatalogDrawer` | Add a skill, in both products; Vercel Domains › Add |
|
|
1071
|
+
| Set up in several steps with a wait | The same sheet, with its progress | `FormDrawer job="steps"` | Connect a messaging channel; Telegram's QR setup |
|
|
1072
|
+
| Look at one record from a list, then go back to the list | A sheet from the right that leaves the page usable | `RecordSheet` | One Stripe event in Billing |
|
|
1096
1073
|
| Do a workflow a person could link to | Its own page | The page's composition | Vercel Add New › Project; New Agent |
|
|
1097
1074
|
| Confirm a consequence | A confirmation | `ConfirmDialog` | Remove, Disconnect |
|
|
1098
1075
|
|
|
1099
|
-
A record already on screen is never edited in a dialog or a sheet, and a sheet is never chosen because an action takes input: a catalogue is `CatalogDrawer
|
|
1100
|
-
|
|
1101
|
-
Collection search and filters stay immediately above their rows. The title row holds the collection's primary action, unless an inline form already exposes that task. Scope selectors preserve the authorized organization or account. Filters do not compete with primary actions. The account menu identifies the signed-in person and exposes their account settings, theme and language, drawn as Vercel's: 288 px wide, opening 6 px above its trigger; a header of the name and the lines under it with the gear at its end, and no picture; then one divider and the rows, 36 px high, each its label leading and its icon or its control trailing in muted ink, Theme and Language as a small round pill of choices, a product's own reading before its icon, and Sign out last in the body colour, since signing out destroys nothing. Ruled by the owner on 16 October 2026.
|
|
1076
|
+
A record already on screen is never edited in a dialog or a sheet, and a sheet is never chosen because an action takes input: a catalogue is `CatalogDrawer` and a setup in steps is `FormDrawer` with `job="steps"`. A `Drawer` is only the phone's bottom sheet for a short job, never a desktop surface and never a confirmation. A settings page is the Settings composition. These choices follow the live Vercel Domains, Projects and settings pages and the [Geist Modal](https://vercel.com/geist/modal), [Sheet](https://vercel.com/geist/sheet) and [Fieldset](https://vercel.com/geist/fieldset) patterns.
|
|
1102
1077
|
|
|
1078
|
+
Collection search and filters stay immediately above their rows. The title row holds the collection's primary action, unless an inline form already exposes that task. Scope selectors preserve the authorized organization or account. Filters do not compete with primary actions.
|
|
1103
1079
|
|
|
1104
1080
|
### Tables and missing values
|
|
1105
1081
|
|
|
1106
|
-
|
|
1082
|
+
`Table`, `DataTable`, `TableCard`, `RecordList`, `Item` and `Tag` hold their geometry, columns and rows on their usage pages; `page-composition` refuses a `DataTable` without column headings. No heading sorts the rows, so no heading is a button: the page holds the order, through a `CollectionSort` above the list, and `aria-sort` marks the column the rows follow.
|
|
1107
1083
|
|
|
1108
|
-
A
|
|
1109
|
-
|
|
1110
|
-
| Slot | Width | Holds |
|
|
1111
|
-
| --- | --- | --- |
|
|
1112
|
-
| Selection | 40 px, only when the list is picked from | A box named "Select {name}" |
|
|
1113
|
-
| Identity | The rest: the one column without a size | The record's 32 px identity mark ("Identity marks"), then its name (600) over one muted 14 px line saying what it is or where it comes from, each on one line ending in an ellipsis (`RecordIdentity`'s `detail`: "Company skill · every Agent has it") |
|
|
1114
|
-
| Facts | Each fact's `size` | A few facts on one line, ending in an ellipsis |
|
|
1115
|
-
| Status | `status.size` | Only the exception, the status that tells this row apart from the others; empty for the usual record |
|
|
1116
|
-
| Time | `time.size`, tabular | The time in its verb's sentence (`RecordTime`: "Updated 3 hours ago", the date after a week, the exact moment on hover) |
|
|
1117
|
-
| Checklist | 52 px, only when the record has steps to be ready | Its `ProgressChecklist` ring ("Status") |
|
|
1118
|
-
| The row's command and the three dots | `commandsSize`; left out, 64 px for the three dots alone, or as wide as the widest lone menu command drawn as a button, never cutting its label | One command that is not destructive, as an `outline` button, then the row's `ActionMenu`; or a muted chevron when the row only opens |
|
|
1119
|
-
|
|
1120
|
-
A status column stands only while a record in the list shows its exception, the commands column only while a record has a command, a menu or a message or the rows open, and the commands column widens for a failed action's next steps only while a row shows one, so the name and its line keep the room the row leaves. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row. An action that failed or was refused shows as its catalogue message inside its own row, with its next step, never a notice under the row, and an edit opens inside its row. A screen gives `RecordList` the records and what each one says, never its own toolbar, table, rows or menus, and anything more than a few facts lives on the record's page. A descriptive list uses `ItemGroup` and `Item` instead of table semantics: 16 px padding, a 600 title over one 20 px description with no gap, a row of 72 px, and at most two trailing controls (`size="sm"`, 32 px), the rest in the three dots. A list a person picks from starts each row with `ItemSelect`, whose box is named "Select {name}". The table inherits its enclosing surface, whose Card owns the outer edge; a visible header and every record except the last end with a quiet 1 px `border` divider. An interactive body row takes the full `accent` fill on hover, on keyboard focus within it and while its menu is open; a passive table does not imply an action on hover; a selected row takes `muted`; headers and footers never highlight. A collection fits its container without sideways scrolling: each column is as wide as its definition's `size` in pixels, the one column without a size takes what is left, and a card narrower than the sized columns plus 160 px for the unsized one keeps the identity and the actions in their columns and takes every other column out of the row, as Vercel's lists read on a phone: each joins one muted line under the name, joined by a middle dot and ending in an ellipsis, with no labels on screen, or is dropped when its column says `compact: "dropped"`, for a fact the record's page holds and the phone can spare; a status keeps its own mark. A row on a phone is the name over that one line, never a stack of labelled values: in a record row the facts join the identity's own line after a middle dot, so the record stays one 72 px row, the name over one line. A table whose every column must stay, a settings matrix, names them all in `primaryColumns` and lays out by its content on a narrow card, so its names wrap beside the columns. A titled table card carries its toolbar on the title's row, title left and controls right, as Vercel heads a card's list; under 576 px the toolbar takes its own line under the title. A value too long for its column holds one line and ends in an ellipsis, whole in its title, as a long name does. A document's table, such as a legal page's, is read whole instead: its columns take the `wraps` option, so their words wrap and the row grows, and it shows its header row. In the compact layout every cell but the identity wraps between words. Text anywhere in the product breaks between words, and inside a word only when that word alone cannot fit a line; a machine string such as a hash or a key breaks at any character in a row of wrapped text, or is cut in the middle with `MiddleTruncate` on one line. One categorical fact in a row, such as an installation or a partner, is a `Tag`: a 24 px pill with its mark, dashed when the fact states an absence. An app in a row is its brand mark, its identity mark at 32 px.
|
|
1084
|
+
A collection fits its container without sideways scrolling, and on a phone a row is the name over one line, never a stack of labelled values, where a status keeps its own mark; `DataTable`'s and `RecordList`'s usage pages hold how their columns give way. Text anywhere in the product breaks between words, and inside a word only when that word alone cannot fit a line; a machine string such as a hash or a key breaks at any character in wrapped text, or is cut in the middle with `MiddleTruncate` on one line.
|
|
1121
1085
|
|
|
1122
1086
|
An unknown or not-applicable value in a table, a comparison list or a set of facts is a muted `—` with screen-reader text, in the same slot as a present value; zero stays zero. An absent report is not `None`: `None` is only for a complete report that found nothing. A stale value keeps its last reading with a short `Stale` qualifier. Loading, failure, missing permission and actionable setup each keep their own visible state and never turn into a dash. Essential reasons and actions never live only in a hover tooltip.
|
|
1123
1087
|
|
|
1124
1088
|
### Status
|
|
1125
1089
|
|
|
1126
|
-
A status is one `StatusBadge`: a mark and a word in one of five tones, so it reads without colour.
|
|
1127
|
-
|
|
1128
|
-
| Tone | Means | Pair |
|
|
1129
|
-
| --- | --- | --- |
|
|
1130
|
-
| Gray | Default, and every terminal state that needs no action | `{colors.canvas-soft-2}` / `{colors.body}` |
|
|
1131
|
-
| Green | Healthy, complete | `{colors.success-soft}` / `{colors.success-deep}` |
|
|
1132
|
-
| Red | Unusable, failed | `{colors.error-soft}` / `{colors.error-deep}` |
|
|
1133
|
-
| Amber | Waiting on a person's decision | `{colors.warning-soft}` / `{colors.warning-deep}` |
|
|
1134
|
-
| Blue | A step in motion | `{colors.info-soft}` / `{colors.info-deep}` |
|
|
1090
|
+
A status is one `StatusBadge`: a mark and a word in one of five tones, so it reads without colour. `StatusBadge`'s usage page holds the tones; `ProgressChecklist`'s holds how far a record is through the steps that make it ready.
|
|
1135
1091
|
|
|
1136
1092
|
The Portal, Nadia and Alveare draw every status with the one `StatusBadge` in `@nadicodeai/ui`, which owns the tones and their marks; each app keeps only its value-to-tone map in one module, and nothing else chooses a status colour. A status never moves.
|
|
1137
1093
|
|
|
1138
|
-
How far a record is through the steps that make it ready is a `ProgressChecklist`, as Vercel ends a project's row with its Production Checklist: a 24 px blue `Gauge`, its track and its arc the share of steps done, a whole ring when all are, with the double check inside in ink, on a 36 px ghost button before the row's commands whose tooltip names the checklist and how far it is ("Customer setup 3/4"), that opens the steps in a sheet at the right: the ring, the title, one line, then a card per step with its icon on a tile of its hue, its title, one line and the outline button that leads where it is done; every step is the same hairline card, and a done step differs only by the blue Done chip after its title and by having no button, so the steps still to do lead the eye. A step is done because the thing it asks for exists, so the checklist remembers nothing and has no Skip. The step's hue says which kind of step it is, never whether it is done.
|
|
1139
|
-
|
|
1140
1094
|
In a list or a feed a status shows only for the exception: the record or the event that differs from the others, such as a failure, a revocation or a wait for a person's decision. The usual state shows nothing, so a status never stands on every row. An object's own status sits beside its name in the path ("Product shells").
|
|
1141
1095
|
|
|
1142
1096
|
### Activity
|
|
1143
1097
|
|
|
1144
|
-
What happened has one shape in every product, `ActivityFeed`,
|
|
1145
|
-
|
|
1146
|
-
- **Time.** The time of day in the viewer's own zone, tabular (`RecordTime`); UTC and the local zone in its hover card. One rule for every feed, never a time printed in UTC.
|
|
1147
|
-
- **Actor.** The actor's identity mark at 24 px: a person's initials, an Agent's real orb, an Installation's tile. The system's own work has no mark, and never takes an orb.
|
|
1148
|
-
- **Sentence.** The actor's name, the action, then the object as a link that keeps the text's colour; a status after it only for the exception.
|
|
1149
|
-
- **Order.** Rows group under their day, its name over its date, newest first, then "Show older events", never a page count. The search and filters stand right above the rows and live in the URL.
|
|
1150
|
-
- **Frame.** The tab is the feed's title: the feed adds no card header of its own. It loads as still skeleton rows in the row's shape; an empty feed is one quiet line, never a picture; a failed read is the warning mark and Retry, never "no events".
|
|
1151
|
-
|
|
1152
|
-
One run's steps are its run timeline (`RunTimeline`): a neutral rail whose nodes mark done, current and to come and never grade a step; the outcome that needs a person is the `StatusBadge` inside its step, "Needs your decision", and each step's time stands in the feed's column.
|
|
1098
|
+
What happened has one shape in every product, `ActivityFeed`, whose usage page holds its row and frame; one run's steps are `RunTimeline`'s.
|
|
1153
1099
|
|
|
1154
1100
|
### System activity
|
|
1155
1101
|
|
|
@@ -1162,11 +1108,11 @@ Who does the work decides how it looks. An Agent's work is that Agent's orb in i
|
|
|
1162
1108
|
| Measurable | A progress line with a written count, "Step 2 of 3" or "12 of 40 MB". Never a percentage. A ratio of a fixed maximum is a `Gauge`, which prints the bare number and leaves the unit to its label. |
|
|
1163
1109
|
| A page load | Still skeleton placeholders in the shape of the content, inside one `SkeletonRegion`, never pulsing and never paired with a waiting line. |
|
|
1164
1110
|
|
|
1165
|
-
One wait gets one indicator. A request waiting for a person is not a wait: queued, paused, blocked, failed and done take the status or feedback treatment. A wait is ink; info blue never marks one.
|
|
1111
|
+
One wait gets one indicator. A request waiting for a person is not a wait: queued, paused, blocked, failed and done take the status or feedback treatment. A wait is ink; info blue never marks one.
|
|
1166
1112
|
|
|
1167
1113
|
### Failure surfaces
|
|
1168
1114
|
|
|
1169
|
-
A page that cannot show what was asked for opens with a picture, the way a Portal email does: one whole cut-out in art direction's editorial register, centred above the words, whose idea says what happened. The picture carries
|
|
1115
|
+
A page that cannot show what was asked for opens with a picture, the way a Portal email does: one whole cut-out in art direction's editorial register, centred above the words, whose idea says what happened. The picture carries its label (`LabelledPicture`). Below the label, on the same centre line, stand a mono eyebrow naming the situation, the page's one heading, one plain sentence, and the recovery action, which leads. The cut-out's transparent ground takes the page's own, so one file serves light and dark, and it stays whole at every width: it scales down with the column and is never cropped by the viewport. No orb turns on a failure page.
|
|
1170
1116
|
|
|
1171
1117
|
A Portal email, whether the Portal or Knock sends it, follows the same order under its picture, in one structure: the picture, the eyebrow and a short heading keep the centre line; one sentence of consequence, a list between hairlines when the email is about several things (each a semibold heading over its one sentence), a table of its facts between hairlines when it has facts, one to-do sentence, the fallback link and the footer stand flush left; the button stays centred.
|
|
1172
1118
|
|
|
@@ -1179,39 +1125,21 @@ An absence inside a product's own chrome, such as an address or a record the Por
|
|
|
1179
1125
|
|
|
1180
1126
|
### Agent orbs
|
|
1181
1127
|
|
|
1182
|
-
An Agent is its orb, in every product; there is no other Agent picture.
|
|
1128
|
+
An Agent is its orb, in every product; there is no other Agent picture. `AgentOrb`'s usage page holds its forms, colours, sizes, states and reduced motion, and `AgentListRow`'s holds an Agent's row in Nadia's list. A surface that only knows a machine checked in draws idle.
|
|
1183
1129
|
|
|
1184
|
-
- **Stored look.** An Agent's form is stored as `orb:<form>` and its colour as the identity hex or nothing; a template declares its starting look the same way. The root Agent always draws as Nadia. An unknown form draws `orbit`, an unknown colour the text colour, and a stored rosso draws arancio. The look is a person's choice and is never derived from a name, id or role.
|
|
1185
|
-
- **Sizes** are 20, 24, 32, 40, 64, 96 and 160 px. On a photograph an orb takes the stronger `over-picture` weight; everywhere else it is `plain`.
|
|
1186
|
-
- **States.** Idle turns at its form's own pace and breathes. Working and thinking move with their cue, the ribbon around working and three dots above thinking, waiting holds, blocked makes one interrupted effort and stops, and done celebrates once and settles back into idle. A surface that only knows a machine checked in draws idle. No state draws a circle around the orb, and a label names the state wherever the exact state matters.
|
|
1187
|
-
- **In Nadia's list.** Each Agent's row (`AgentListRow`) is 52 px high: her orb at 32 px in her real state, her name, and one state line in words, "Working", "Idle" or "Needs you". Only "Needs you" takes a 6 px status dot before its words; the orb shows working by itself. In the list's narrow column (from 640 to 899 px) each orb stands at 40 px in a 48 px square, named with its state line in a tooltip. Only an orb moves in the list.
|
|
1188
|
-
- **Status and ambient.** An orb that stands for an Agent shows its real state. An orb in decorative artwork, such as a sign-in picture, takes ambient motion: its form moves at its own pace with no state pose or cue, and it claims no activity.
|
|
1189
|
-
- **Reduced motion.** Movement stops; a thinking or working orb breathes between full ink and 0.45 opacity so busy still reads as busy, and an ambient orb holds still.
|
|
1190
1130
|
- **In a conversation.** Her states are the conversation's own: the orb in its header follows them, and every mark of her activity in the thread is her own orb in her real state, never another Agent's figure, a spinner, a ticker or a pulse. Her steps and tool calls hold still and say in words what they do or did, with a tool's kind as a decorative icon beside the words and no state of its own; the outcome of a step or a request is the `StatusBadge`, and a failed turn is the `MessageNotice`. A conversation has two actors, her and the person, and every wait in it belongs to one of them. Everything she does, including what follows the person's approval or answer, is her orb in its state: working once Run is pressed, thinking once a question is answered, waiting while an approval or a question waits for the person, blocked when a turn fails, done once when she finishes. The person's own action in progress shows on what they made: a file stays veiled on its own chip until it is uploaded, and fills only where its upload reports progress; the microphone shows it records. A pressed control keeps its place and changes only its word, a button through its `loading`. The waiting line is for the window's own loading, outside the conversation. Ruled by the owner on 11 October 2026: the Agent's states are the chat's default states, not random icons; and on 13 October 2026: the person never meets "the app" in a conversation, only the Agent.
|
|
1191
1131
|
|
|
1192
|
-
Text sits beside an orb, never on it.
|
|
1193
|
-
|
|
1194
1132
|
### Agent card
|
|
1195
1133
|
|
|
1196
|
-
An Agent
|
|
1134
|
+
An Agent shown as an object, in the Portal's Library and Nadia's gallery alike, is one `AgentCard`, whose usage page holds its shape.
|
|
1197
1135
|
|
|
1198
1136
|
### Company card
|
|
1199
1137
|
|
|
1200
|
-
The
|
|
1138
|
+
The company's card is `CompanyCard`, whose usage page holds where it appears (sign-up, the account's Profile, the Partner invitation), its face, foil and motion.
|
|
1201
1139
|
|
|
1202
1140
|
### Identity marks
|
|
1203
1141
|
|
|
1204
|
-
An identity mark says which thing a record is, and `IdentityMark` is its one owner: a row's, an object's, a feed's and a sidebar's mark is one of its kinds, never a decorative icon. A list gets its richness from real identity marks, never from decoration.
|
|
1205
|
-
|
|
1206
|
-
| Kind | The mark |
|
|
1207
|
-
| --- | --- |
|
|
1208
|
-
| An Agent | Her real orb from the orb engine, at its largest size not above the mark's, with no tile and no ring; never a painted circle ("Agent orbs") |
|
|
1209
|
-
| An app | Its own logo in the tile |
|
|
1210
|
-
| A company | Its logo: the one white ink Sofia keeps from its site, on a black tile (`{colors.identity-ink}`) in both themes, as its card stamps it, or a square SVG icon in its own colours filling the tile, as Vercel shows a project's favicon; its two initials in a ringed tile on the card ground until a logo is found |
|
|
1211
|
-
| A person | Their picture, or their initials, round |
|
|
1212
|
-
| A record of a kind | The kind's own icon in a ringed tile on the card ground, the same icon its section has in the navigation: Mail for a mailbox, a server for an MCP server, a key for a password. A Library skill takes the purple category ground with the Skills icon and a plugin the `info-soft` ground with the Plugins icon, both without a ring, so the ground says which kind it is; an entry that has its own object picture draws it on that ground in the icon's place |
|
|
1213
|
-
|
|
1214
|
-
Initials stand only for a company or a person. The mark is 32 px in a record's row, 64 px at the head of an object's page, 40 px on a Library entry, 24 px in a feed and on a sidebar's identity line, and 28 px for the company at the top of Nadia's list; a tile takes 6 px corners, 8 px at 40 and 64.
|
|
1142
|
+
An identity mark says which thing a record is, and `IdentityMark` is its one owner: a row's, an object's, a feed's and a sidebar's mark is one of its kinds, never a decorative icon. A list gets its richness from real identity marks, never from decoration. `IdentityMark`'s usage page holds its kinds and sizes.
|
|
1215
1143
|
|
|
1216
1144
|
A recognised app, platform or model maker is drawn with its genuine mark beside its readable name; an unknown one keeps its name and a text monogram, never a guessed logo. A model's maker is 24 px, in a model list, a routing table or a setting, and on the website's lists of apps and makers. A mark grows only where it stands for the object itself, as on its card or at the head of its page, and there every surface of that object draws it at one size. A mark identifies and never replaces the label, and its colour identifies the maker, never a connection's health. Marks are used nominatively, to name a platform, an integration or a provider, never next to wording that implies endorsement. A brand mark never stands in for a UI icon, and a UI icon never stands in for a brand; a catalogue icon is one of the catalogue's fixed set, never a brand mark, and an app keeps its brand mark. In a chart, a model is named by its label, and marks stay out of legends.
|
|
1217
1145
|
|
|
@@ -1225,9 +1153,9 @@ These three ship as framework-neutral CSS; `@nadicodeai/ui` wraps the last two f
|
|
|
1225
1153
|
|
|
1226
1154
|
**`dotted-field`** — the ground of a canvas where a person or an Agent places and arranges objects: a diagram of an Agent's work, a board of its outputs. The dots say that things here can be moved, so the field never sits behind a dashboard, a list, settings or a website section, and it never stands in for elevation.
|
|
1227
1155
|
|
|
1228
|
-
**`usage-meter`** — consumption
|
|
1156
|
+
**`usage-meter`** — consumption against its allowance; `UsageMeter`'s usage page holds the rest.
|
|
1229
1157
|
|
|
1230
|
-
**`run-timeline`** — the
|
|
1158
|
+
**`run-timeline`** — the thread of an Agent's run, one step per row; `RunTimeline`'s usage page holds the rest.
|
|
1231
1159
|
|
|
1232
1160
|
## Iconography
|
|
1233
1161
|
|
|
@@ -1293,1560 +1221,10 @@ The clear space is one stroke width of the rendered logo on every side. The mini
|
|
|
1293
1221
|
- Do say a status with a `StatusBadge` tone, a mark and a word. Don't use colour alone or a bare dot.
|
|
1294
1222
|
- Do open a failure page with one whole cut-out whose idea says what happened, labelled like a work in a museum, above the words on one centre line, with the recovery action leading and the diagnostic code only for a request that stopped. Don't apologise, don't crop the picture, don't joke about lost work, and don't put an orb on a failure page.
|
|
1295
1223
|
- Do use the dotted field only on a canvas where things are arranged. Don't put it behind lists, dashboards, settings or website sections.
|
|
1296
|
-
- Do build a page from its composition
|
|
1297
|
-
- Do name a tab with a noun, and keep a list's count in its footer. Don't put a count in a tab, or switch whose things are shown with a tab.
|
|
1224
|
+
- Do build a page from its composition. Don't assemble a page's header, toolbar, rows or menus by hand.
|
|
1298
1225
|
- Do put the path alone in the top bar and the page's actions on its title row. Don't put an action in the top bar or a second sidebar beside the first.
|
|
1299
|
-
- Do add a rule here before a product needs it. Don't restate a rule in another document; link to it.
|
|
1226
|
+
- Do add a shared rule here, and a component's own rule to its usage page, before a product needs it. Don't restate a rule in another document; link to it.
|
|
1300
1227
|
|
|
1301
1228
|
## Token extension
|
|
1302
1229
|
|
|
1303
|
-
The YAML front matter holds the four groups the DESIGN.md format defines: colors, typography, rounded and spacing.
|
|
1304
|
-
|
|
1305
|
-
```json design-tokens
|
|
1306
|
-
{
|
|
1307
|
-
"core": {
|
|
1308
|
-
"material": {
|
|
1309
|
-
"$type": "number",
|
|
1310
|
-
"scrim-opacity": {
|
|
1311
|
-
"$value": 0.8
|
|
1312
|
-
},
|
|
1313
|
-
"dark-scrim-opacity": {
|
|
1314
|
-
"$value": 0.6
|
|
1315
|
-
},
|
|
1316
|
-
"glass-opacity": {
|
|
1317
|
-
"$value": 0.72
|
|
1318
|
-
},
|
|
1319
|
-
"glass-saturation": {
|
|
1320
|
-
"$value": 1.8
|
|
1321
|
-
},
|
|
1322
|
-
"glass-blur": {
|
|
1323
|
-
"$type": "dimension",
|
|
1324
|
-
"$value": {
|
|
1325
|
-
"value": 20,
|
|
1326
|
-
"unit": "px"
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
},
|
|
1330
|
-
"elevation": {
|
|
1331
|
-
"$type": "shadow",
|
|
1332
|
-
"light": {
|
|
1333
|
-
"resting": {
|
|
1334
|
-
"$value": [
|
|
1335
|
-
{
|
|
1336
|
-
"offsetX": {
|
|
1337
|
-
"value": 0,
|
|
1338
|
-
"unit": "px"
|
|
1339
|
-
},
|
|
1340
|
-
"offsetY": {
|
|
1341
|
-
"value": 0,
|
|
1342
|
-
"unit": "px"
|
|
1343
|
-
},
|
|
1344
|
-
"blur": {
|
|
1345
|
-
"value": 0,
|
|
1346
|
-
"unit": "px"
|
|
1347
|
-
},
|
|
1348
|
-
"spread": {
|
|
1349
|
-
"value": 1,
|
|
1350
|
-
"unit": "px"
|
|
1351
|
-
},
|
|
1352
|
-
"color": {
|
|
1353
|
-
"colorSpace": "srgb",
|
|
1354
|
-
"components": [
|
|
1355
|
-
0,
|
|
1356
|
-
0,
|
|
1357
|
-
0
|
|
1358
|
-
],
|
|
1359
|
-
"alpha": 0.08
|
|
1360
|
-
}
|
|
1361
|
-
},
|
|
1362
|
-
{
|
|
1363
|
-
"offsetX": {
|
|
1364
|
-
"value": 0,
|
|
1365
|
-
"unit": "px"
|
|
1366
|
-
},
|
|
1367
|
-
"offsetY": {
|
|
1368
|
-
"value": 2,
|
|
1369
|
-
"unit": "px"
|
|
1370
|
-
},
|
|
1371
|
-
"blur": {
|
|
1372
|
-
"value": 2,
|
|
1373
|
-
"unit": "px"
|
|
1374
|
-
},
|
|
1375
|
-
"spread": {
|
|
1376
|
-
"value": 0,
|
|
1377
|
-
"unit": "px"
|
|
1378
|
-
},
|
|
1379
|
-
"color": {
|
|
1380
|
-
"colorSpace": "srgb",
|
|
1381
|
-
"components": [
|
|
1382
|
-
0,
|
|
1383
|
-
0,
|
|
1384
|
-
0
|
|
1385
|
-
],
|
|
1386
|
-
"alpha": 0.04
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
]
|
|
1390
|
-
},
|
|
1391
|
-
"raised": {
|
|
1392
|
-
"$value": [
|
|
1393
|
-
{
|
|
1394
|
-
"offsetX": {
|
|
1395
|
-
"value": 0,
|
|
1396
|
-
"unit": "px"
|
|
1397
|
-
},
|
|
1398
|
-
"offsetY": {
|
|
1399
|
-
"value": 0,
|
|
1400
|
-
"unit": "px"
|
|
1401
|
-
},
|
|
1402
|
-
"blur": {
|
|
1403
|
-
"value": 0,
|
|
1404
|
-
"unit": "px"
|
|
1405
|
-
},
|
|
1406
|
-
"spread": {
|
|
1407
|
-
"value": 1,
|
|
1408
|
-
"unit": "px"
|
|
1409
|
-
},
|
|
1410
|
-
"color": {
|
|
1411
|
-
"colorSpace": "srgb",
|
|
1412
|
-
"components": [
|
|
1413
|
-
0,
|
|
1414
|
-
0,
|
|
1415
|
-
0
|
|
1416
|
-
],
|
|
1417
|
-
"alpha": 0.08
|
|
1418
|
-
}
|
|
1419
|
-
},
|
|
1420
|
-
{
|
|
1421
|
-
"offsetX": {
|
|
1422
|
-
"value": 0,
|
|
1423
|
-
"unit": "px"
|
|
1424
|
-
},
|
|
1425
|
-
"offsetY": {
|
|
1426
|
-
"value": 2,
|
|
1427
|
-
"unit": "px"
|
|
1428
|
-
},
|
|
1429
|
-
"blur": {
|
|
1430
|
-
"value": 2,
|
|
1431
|
-
"unit": "px"
|
|
1432
|
-
},
|
|
1433
|
-
"spread": {
|
|
1434
|
-
"value": 0,
|
|
1435
|
-
"unit": "px"
|
|
1436
|
-
},
|
|
1437
|
-
"color": {
|
|
1438
|
-
"colorSpace": "srgb",
|
|
1439
|
-
"components": [
|
|
1440
|
-
0,
|
|
1441
|
-
0,
|
|
1442
|
-
0
|
|
1443
|
-
],
|
|
1444
|
-
"alpha": 0.04
|
|
1445
|
-
}
|
|
1446
|
-
},
|
|
1447
|
-
{
|
|
1448
|
-
"offsetX": {
|
|
1449
|
-
"value": 0,
|
|
1450
|
-
"unit": "px"
|
|
1451
|
-
},
|
|
1452
|
-
"offsetY": {
|
|
1453
|
-
"value": 8,
|
|
1454
|
-
"unit": "px"
|
|
1455
|
-
},
|
|
1456
|
-
"blur": {
|
|
1457
|
-
"value": 16,
|
|
1458
|
-
"unit": "px"
|
|
1459
|
-
},
|
|
1460
|
-
"spread": {
|
|
1461
|
-
"value": -4,
|
|
1462
|
-
"unit": "px"
|
|
1463
|
-
},
|
|
1464
|
-
"color": {
|
|
1465
|
-
"colorSpace": "srgb",
|
|
1466
|
-
"components": [
|
|
1467
|
-
0,
|
|
1468
|
-
0,
|
|
1469
|
-
0
|
|
1470
|
-
],
|
|
1471
|
-
"alpha": 0.08
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
]
|
|
1475
|
-
},
|
|
1476
|
-
"floating": {
|
|
1477
|
-
"$value": [
|
|
1478
|
-
{
|
|
1479
|
-
"offsetX": {
|
|
1480
|
-
"value": 0,
|
|
1481
|
-
"unit": "px"
|
|
1482
|
-
},
|
|
1483
|
-
"offsetY": {
|
|
1484
|
-
"value": 0,
|
|
1485
|
-
"unit": "px"
|
|
1486
|
-
},
|
|
1487
|
-
"blur": {
|
|
1488
|
-
"value": 0,
|
|
1489
|
-
"unit": "px"
|
|
1490
|
-
},
|
|
1491
|
-
"spread": {
|
|
1492
|
-
"value": 1,
|
|
1493
|
-
"unit": "px"
|
|
1494
|
-
},
|
|
1495
|
-
"color": {
|
|
1496
|
-
"colorSpace": "srgb",
|
|
1497
|
-
"components": [
|
|
1498
|
-
0,
|
|
1499
|
-
0,
|
|
1500
|
-
0
|
|
1501
|
-
],
|
|
1502
|
-
"alpha": 0.08
|
|
1503
|
-
}
|
|
1504
|
-
},
|
|
1505
|
-
{
|
|
1506
|
-
"offsetX": {
|
|
1507
|
-
"value": 0,
|
|
1508
|
-
"unit": "px"
|
|
1509
|
-
},
|
|
1510
|
-
"offsetY": {
|
|
1511
|
-
"value": 1,
|
|
1512
|
-
"unit": "px"
|
|
1513
|
-
},
|
|
1514
|
-
"blur": {
|
|
1515
|
-
"value": 1,
|
|
1516
|
-
"unit": "px"
|
|
1517
|
-
},
|
|
1518
|
-
"spread": {
|
|
1519
|
-
"value": 0,
|
|
1520
|
-
"unit": "px"
|
|
1521
|
-
},
|
|
1522
|
-
"color": {
|
|
1523
|
-
"colorSpace": "srgb",
|
|
1524
|
-
"components": [
|
|
1525
|
-
0,
|
|
1526
|
-
0,
|
|
1527
|
-
0
|
|
1528
|
-
],
|
|
1529
|
-
"alpha": 0.02
|
|
1530
|
-
}
|
|
1531
|
-
},
|
|
1532
|
-
{
|
|
1533
|
-
"offsetX": {
|
|
1534
|
-
"value": 0,
|
|
1535
|
-
"unit": "px"
|
|
1536
|
-
},
|
|
1537
|
-
"offsetY": {
|
|
1538
|
-
"value": 4,
|
|
1539
|
-
"unit": "px"
|
|
1540
|
-
},
|
|
1541
|
-
"blur": {
|
|
1542
|
-
"value": 8,
|
|
1543
|
-
"unit": "px"
|
|
1544
|
-
},
|
|
1545
|
-
"spread": {
|
|
1546
|
-
"value": -4,
|
|
1547
|
-
"unit": "px"
|
|
1548
|
-
},
|
|
1549
|
-
"color": {
|
|
1550
|
-
"colorSpace": "srgb",
|
|
1551
|
-
"components": [
|
|
1552
|
-
0,
|
|
1553
|
-
0,
|
|
1554
|
-
0
|
|
1555
|
-
],
|
|
1556
|
-
"alpha": 0.06
|
|
1557
|
-
}
|
|
1558
|
-
},
|
|
1559
|
-
{
|
|
1560
|
-
"offsetX": {
|
|
1561
|
-
"value": 0,
|
|
1562
|
-
"unit": "px"
|
|
1563
|
-
},
|
|
1564
|
-
"offsetY": {
|
|
1565
|
-
"value": 16,
|
|
1566
|
-
"unit": "px"
|
|
1567
|
-
},
|
|
1568
|
-
"blur": {
|
|
1569
|
-
"value": 32,
|
|
1570
|
-
"unit": "px"
|
|
1571
|
-
},
|
|
1572
|
-
"spread": {
|
|
1573
|
-
"value": -8,
|
|
1574
|
-
"unit": "px"
|
|
1575
|
-
},
|
|
1576
|
-
"color": {
|
|
1577
|
-
"colorSpace": "srgb",
|
|
1578
|
-
"components": [
|
|
1579
|
-
0,
|
|
1580
|
-
0,
|
|
1581
|
-
0
|
|
1582
|
-
],
|
|
1583
|
-
"alpha": 0.1
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
]
|
|
1587
|
-
},
|
|
1588
|
-
"modal": {
|
|
1589
|
-
"$value": [
|
|
1590
|
-
{
|
|
1591
|
-
"offsetX": {
|
|
1592
|
-
"value": 0,
|
|
1593
|
-
"unit": "px"
|
|
1594
|
-
},
|
|
1595
|
-
"offsetY": {
|
|
1596
|
-
"value": 0,
|
|
1597
|
-
"unit": "px"
|
|
1598
|
-
},
|
|
1599
|
-
"blur": {
|
|
1600
|
-
"value": 0,
|
|
1601
|
-
"unit": "px"
|
|
1602
|
-
},
|
|
1603
|
-
"spread": {
|
|
1604
|
-
"value": 1,
|
|
1605
|
-
"unit": "px"
|
|
1606
|
-
},
|
|
1607
|
-
"color": {
|
|
1608
|
-
"colorSpace": "srgb",
|
|
1609
|
-
"components": [
|
|
1610
|
-
0,
|
|
1611
|
-
0,
|
|
1612
|
-
0
|
|
1613
|
-
],
|
|
1614
|
-
"alpha": 0.08
|
|
1615
|
-
}
|
|
1616
|
-
},
|
|
1617
|
-
{
|
|
1618
|
-
"offsetX": {
|
|
1619
|
-
"value": 0,
|
|
1620
|
-
"unit": "px"
|
|
1621
|
-
},
|
|
1622
|
-
"offsetY": {
|
|
1623
|
-
"value": 8,
|
|
1624
|
-
"unit": "px"
|
|
1625
|
-
},
|
|
1626
|
-
"blur": {
|
|
1627
|
-
"value": 24,
|
|
1628
|
-
"unit": "px"
|
|
1629
|
-
},
|
|
1630
|
-
"spread": {
|
|
1631
|
-
"value": -12,
|
|
1632
|
-
"unit": "px"
|
|
1633
|
-
},
|
|
1634
|
-
"color": {
|
|
1635
|
-
"colorSpace": "srgb",
|
|
1636
|
-
"components": [
|
|
1637
|
-
0,
|
|
1638
|
-
0,
|
|
1639
|
-
0
|
|
1640
|
-
],
|
|
1641
|
-
"alpha": 0.12
|
|
1642
|
-
}
|
|
1643
|
-
},
|
|
1644
|
-
{
|
|
1645
|
-
"offsetX": {
|
|
1646
|
-
"value": 0,
|
|
1647
|
-
"unit": "px"
|
|
1648
|
-
},
|
|
1649
|
-
"offsetY": {
|
|
1650
|
-
"value": 32,
|
|
1651
|
-
"unit": "px"
|
|
1652
|
-
},
|
|
1653
|
-
"blur": {
|
|
1654
|
-
"value": 72,
|
|
1655
|
-
"unit": "px"
|
|
1656
|
-
},
|
|
1657
|
-
"spread": {
|
|
1658
|
-
"value": -12,
|
|
1659
|
-
"unit": "px"
|
|
1660
|
-
},
|
|
1661
|
-
"color": {
|
|
1662
|
-
"colorSpace": "srgb",
|
|
1663
|
-
"components": [
|
|
1664
|
-
0,
|
|
1665
|
-
0,
|
|
1666
|
-
0
|
|
1667
|
-
],
|
|
1668
|
-
"alpha": 0.12
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
]
|
|
1672
|
-
},
|
|
1673
|
-
"glass": {
|
|
1674
|
-
"$value": [
|
|
1675
|
-
{
|
|
1676
|
-
"offsetX": {
|
|
1677
|
-
"value": 0,
|
|
1678
|
-
"unit": "px"
|
|
1679
|
-
},
|
|
1680
|
-
"offsetY": {
|
|
1681
|
-
"value": 1,
|
|
1682
|
-
"unit": "px"
|
|
1683
|
-
},
|
|
1684
|
-
"blur": {
|
|
1685
|
-
"value": 0,
|
|
1686
|
-
"unit": "px"
|
|
1687
|
-
},
|
|
1688
|
-
"spread": {
|
|
1689
|
-
"value": 0,
|
|
1690
|
-
"unit": "px"
|
|
1691
|
-
},
|
|
1692
|
-
"color": {
|
|
1693
|
-
"colorSpace": "srgb",
|
|
1694
|
-
"components": [
|
|
1695
|
-
1,
|
|
1696
|
-
1,
|
|
1697
|
-
1
|
|
1698
|
-
],
|
|
1699
|
-
"alpha": 0.75
|
|
1700
|
-
},
|
|
1701
|
-
"inset": true
|
|
1702
|
-
},
|
|
1703
|
-
{
|
|
1704
|
-
"offsetX": {
|
|
1705
|
-
"value": 0,
|
|
1706
|
-
"unit": "px"
|
|
1707
|
-
},
|
|
1708
|
-
"offsetY": {
|
|
1709
|
-
"value": 0,
|
|
1710
|
-
"unit": "px"
|
|
1711
|
-
},
|
|
1712
|
-
"blur": {
|
|
1713
|
-
"value": 0,
|
|
1714
|
-
"unit": "px"
|
|
1715
|
-
},
|
|
1716
|
-
"spread": {
|
|
1717
|
-
"value": 1,
|
|
1718
|
-
"unit": "px"
|
|
1719
|
-
},
|
|
1720
|
-
"color": {
|
|
1721
|
-
"colorSpace": "srgb",
|
|
1722
|
-
"components": [
|
|
1723
|
-
1,
|
|
1724
|
-
1,
|
|
1725
|
-
1
|
|
1726
|
-
],
|
|
1727
|
-
"alpha": 0.35
|
|
1728
|
-
},
|
|
1729
|
-
"inset": true
|
|
1730
|
-
},
|
|
1731
|
-
{
|
|
1732
|
-
"offsetX": {
|
|
1733
|
-
"value": 0,
|
|
1734
|
-
"unit": "px"
|
|
1735
|
-
},
|
|
1736
|
-
"offsetY": {
|
|
1737
|
-
"value": 0,
|
|
1738
|
-
"unit": "px"
|
|
1739
|
-
},
|
|
1740
|
-
"blur": {
|
|
1741
|
-
"value": 0,
|
|
1742
|
-
"unit": "px"
|
|
1743
|
-
},
|
|
1744
|
-
"spread": {
|
|
1745
|
-
"value": 1,
|
|
1746
|
-
"unit": "px"
|
|
1747
|
-
},
|
|
1748
|
-
"color": {
|
|
1749
|
-
"colorSpace": "srgb",
|
|
1750
|
-
"components": [
|
|
1751
|
-
0,
|
|
1752
|
-
0,
|
|
1753
|
-
0
|
|
1754
|
-
],
|
|
1755
|
-
"alpha": 0.08
|
|
1756
|
-
}
|
|
1757
|
-
},
|
|
1758
|
-
{
|
|
1759
|
-
"offsetX": {
|
|
1760
|
-
"value": 0,
|
|
1761
|
-
"unit": "px"
|
|
1762
|
-
},
|
|
1763
|
-
"offsetY": {
|
|
1764
|
-
"value": 4,
|
|
1765
|
-
"unit": "px"
|
|
1766
|
-
},
|
|
1767
|
-
"blur": {
|
|
1768
|
-
"value": 8,
|
|
1769
|
-
"unit": "px"
|
|
1770
|
-
},
|
|
1771
|
-
"spread": {
|
|
1772
|
-
"value": -4,
|
|
1773
|
-
"unit": "px"
|
|
1774
|
-
},
|
|
1775
|
-
"color": {
|
|
1776
|
-
"colorSpace": "srgb",
|
|
1777
|
-
"components": [
|
|
1778
|
-
0,
|
|
1779
|
-
0,
|
|
1780
|
-
0
|
|
1781
|
-
],
|
|
1782
|
-
"alpha": 0.06
|
|
1783
|
-
}
|
|
1784
|
-
},
|
|
1785
|
-
{
|
|
1786
|
-
"offsetX": {
|
|
1787
|
-
"value": 0,
|
|
1788
|
-
"unit": "px"
|
|
1789
|
-
},
|
|
1790
|
-
"offsetY": {
|
|
1791
|
-
"value": 16,
|
|
1792
|
-
"unit": "px"
|
|
1793
|
-
},
|
|
1794
|
-
"blur": {
|
|
1795
|
-
"value": 32,
|
|
1796
|
-
"unit": "px"
|
|
1797
|
-
},
|
|
1798
|
-
"spread": {
|
|
1799
|
-
"value": -8,
|
|
1800
|
-
"unit": "px"
|
|
1801
|
-
},
|
|
1802
|
-
"color": {
|
|
1803
|
-
"colorSpace": "srgb",
|
|
1804
|
-
"components": [
|
|
1805
|
-
0,
|
|
1806
|
-
0,
|
|
1807
|
-
0
|
|
1808
|
-
],
|
|
1809
|
-
"alpha": 0.08
|
|
1810
|
-
}
|
|
1811
|
-
}
|
|
1812
|
-
]
|
|
1813
|
-
}
|
|
1814
|
-
},
|
|
1815
|
-
"dark": {
|
|
1816
|
-
"resting": {
|
|
1817
|
-
"$value": [
|
|
1818
|
-
{
|
|
1819
|
-
"offsetX": {
|
|
1820
|
-
"value": 0,
|
|
1821
|
-
"unit": "px"
|
|
1822
|
-
},
|
|
1823
|
-
"offsetY": {
|
|
1824
|
-
"value": 0,
|
|
1825
|
-
"unit": "px"
|
|
1826
|
-
},
|
|
1827
|
-
"blur": {
|
|
1828
|
-
"value": 0,
|
|
1829
|
-
"unit": "px"
|
|
1830
|
-
},
|
|
1831
|
-
"spread": {
|
|
1832
|
-
"value": 1,
|
|
1833
|
-
"unit": "px"
|
|
1834
|
-
},
|
|
1835
|
-
"color": {
|
|
1836
|
-
"colorSpace": "srgb",
|
|
1837
|
-
"components": [
|
|
1838
|
-
1,
|
|
1839
|
-
1,
|
|
1840
|
-
1
|
|
1841
|
-
],
|
|
1842
|
-
"alpha": 0.145
|
|
1843
|
-
}
|
|
1844
|
-
},
|
|
1845
|
-
{
|
|
1846
|
-
"offsetX": {
|
|
1847
|
-
"value": 0,
|
|
1848
|
-
"unit": "px"
|
|
1849
|
-
},
|
|
1850
|
-
"offsetY": {
|
|
1851
|
-
"value": 0,
|
|
1852
|
-
"unit": "px"
|
|
1853
|
-
},
|
|
1854
|
-
"blur": {
|
|
1855
|
-
"value": 0,
|
|
1856
|
-
"unit": "px"
|
|
1857
|
-
},
|
|
1858
|
-
"spread": {
|
|
1859
|
-
"value": 2,
|
|
1860
|
-
"unit": "px"
|
|
1861
|
-
},
|
|
1862
|
-
"color": {
|
|
1863
|
-
"colorSpace": "srgb",
|
|
1864
|
-
"components": [
|
|
1865
|
-
0,
|
|
1866
|
-
0,
|
|
1867
|
-
0
|
|
1868
|
-
],
|
|
1869
|
-
"alpha": 1
|
|
1870
|
-
}
|
|
1871
|
-
},
|
|
1872
|
-
{
|
|
1873
|
-
"offsetX": {
|
|
1874
|
-
"value": 0,
|
|
1875
|
-
"unit": "px"
|
|
1876
|
-
},
|
|
1877
|
-
"offsetY": {
|
|
1878
|
-
"value": 1,
|
|
1879
|
-
"unit": "px"
|
|
1880
|
-
},
|
|
1881
|
-
"blur": {
|
|
1882
|
-
"value": 2,
|
|
1883
|
-
"unit": "px"
|
|
1884
|
-
},
|
|
1885
|
-
"spread": {
|
|
1886
|
-
"value": 0,
|
|
1887
|
-
"unit": "px"
|
|
1888
|
-
},
|
|
1889
|
-
"color": {
|
|
1890
|
-
"colorSpace": "srgb",
|
|
1891
|
-
"components": [
|
|
1892
|
-
0,
|
|
1893
|
-
0,
|
|
1894
|
-
0
|
|
1895
|
-
],
|
|
1896
|
-
"alpha": 0.5
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
]
|
|
1900
|
-
},
|
|
1901
|
-
"raised": {
|
|
1902
|
-
"$value": [
|
|
1903
|
-
{
|
|
1904
|
-
"offsetX": {
|
|
1905
|
-
"value": 0,
|
|
1906
|
-
"unit": "px"
|
|
1907
|
-
},
|
|
1908
|
-
"offsetY": {
|
|
1909
|
-
"value": 1,
|
|
1910
|
-
"unit": "px"
|
|
1911
|
-
},
|
|
1912
|
-
"blur": {
|
|
1913
|
-
"value": 0,
|
|
1914
|
-
"unit": "px"
|
|
1915
|
-
},
|
|
1916
|
-
"spread": {
|
|
1917
|
-
"value": 0,
|
|
1918
|
-
"unit": "px"
|
|
1919
|
-
},
|
|
1920
|
-
"color": {
|
|
1921
|
-
"colorSpace": "srgb",
|
|
1922
|
-
"components": [
|
|
1923
|
-
1,
|
|
1924
|
-
1,
|
|
1925
|
-
1
|
|
1926
|
-
],
|
|
1927
|
-
"alpha": 0.06
|
|
1928
|
-
},
|
|
1929
|
-
"inset": true
|
|
1930
|
-
},
|
|
1931
|
-
{
|
|
1932
|
-
"offsetX": {
|
|
1933
|
-
"value": 0,
|
|
1934
|
-
"unit": "px"
|
|
1935
|
-
},
|
|
1936
|
-
"offsetY": {
|
|
1937
|
-
"value": 0,
|
|
1938
|
-
"unit": "px"
|
|
1939
|
-
},
|
|
1940
|
-
"blur": {
|
|
1941
|
-
"value": 0,
|
|
1942
|
-
"unit": "px"
|
|
1943
|
-
},
|
|
1944
|
-
"spread": {
|
|
1945
|
-
"value": 1,
|
|
1946
|
-
"unit": "px"
|
|
1947
|
-
},
|
|
1948
|
-
"color": {
|
|
1949
|
-
"colorSpace": "srgb",
|
|
1950
|
-
"components": [
|
|
1951
|
-
1,
|
|
1952
|
-
1,
|
|
1953
|
-
1
|
|
1954
|
-
],
|
|
1955
|
-
"alpha": 0.16
|
|
1956
|
-
}
|
|
1957
|
-
},
|
|
1958
|
-
{
|
|
1959
|
-
"offsetX": {
|
|
1960
|
-
"value": 0,
|
|
1961
|
-
"unit": "px"
|
|
1962
|
-
},
|
|
1963
|
-
"offsetY": {
|
|
1964
|
-
"value": 0,
|
|
1965
|
-
"unit": "px"
|
|
1966
|
-
},
|
|
1967
|
-
"blur": {
|
|
1968
|
-
"value": 0,
|
|
1969
|
-
"unit": "px"
|
|
1970
|
-
},
|
|
1971
|
-
"spread": {
|
|
1972
|
-
"value": 2,
|
|
1973
|
-
"unit": "px"
|
|
1974
|
-
},
|
|
1975
|
-
"color": {
|
|
1976
|
-
"colorSpace": "srgb",
|
|
1977
|
-
"components": [
|
|
1978
|
-
0,
|
|
1979
|
-
0,
|
|
1980
|
-
0
|
|
1981
|
-
],
|
|
1982
|
-
"alpha": 1
|
|
1983
|
-
}
|
|
1984
|
-
},
|
|
1985
|
-
{
|
|
1986
|
-
"offsetX": {
|
|
1987
|
-
"value": 0,
|
|
1988
|
-
"unit": "px"
|
|
1989
|
-
},
|
|
1990
|
-
"offsetY": {
|
|
1991
|
-
"value": 12,
|
|
1992
|
-
"unit": "px"
|
|
1993
|
-
},
|
|
1994
|
-
"blur": {
|
|
1995
|
-
"value": 24,
|
|
1996
|
-
"unit": "px"
|
|
1997
|
-
},
|
|
1998
|
-
"spread": {
|
|
1999
|
-
"value": -8,
|
|
2000
|
-
"unit": "px"
|
|
2001
|
-
},
|
|
2002
|
-
"color": {
|
|
2003
|
-
"colorSpace": "srgb",
|
|
2004
|
-
"components": [
|
|
2005
|
-
0,
|
|
2006
|
-
0,
|
|
2007
|
-
0
|
|
2008
|
-
],
|
|
2009
|
-
"alpha": 0.8
|
|
2010
|
-
}
|
|
2011
|
-
}
|
|
2012
|
-
]
|
|
2013
|
-
},
|
|
2014
|
-
"floating": {
|
|
2015
|
-
"$value": [
|
|
2016
|
-
{
|
|
2017
|
-
"offsetX": {
|
|
2018
|
-
"value": 0,
|
|
2019
|
-
"unit": "px"
|
|
2020
|
-
},
|
|
2021
|
-
"offsetY": {
|
|
2022
|
-
"value": 1,
|
|
2023
|
-
"unit": "px"
|
|
2024
|
-
},
|
|
2025
|
-
"blur": {
|
|
2026
|
-
"value": 0,
|
|
2027
|
-
"unit": "px"
|
|
2028
|
-
},
|
|
2029
|
-
"spread": {
|
|
2030
|
-
"value": 0,
|
|
2031
|
-
"unit": "px"
|
|
2032
|
-
},
|
|
2033
|
-
"color": {
|
|
2034
|
-
"colorSpace": "srgb",
|
|
2035
|
-
"components": [
|
|
2036
|
-
1,
|
|
2037
|
-
1,
|
|
2038
|
-
1
|
|
2039
|
-
],
|
|
2040
|
-
"alpha": 0.08
|
|
2041
|
-
},
|
|
2042
|
-
"inset": true
|
|
2043
|
-
},
|
|
2044
|
-
{
|
|
2045
|
-
"offsetX": {
|
|
2046
|
-
"value": 0,
|
|
2047
|
-
"unit": "px"
|
|
2048
|
-
},
|
|
2049
|
-
"offsetY": {
|
|
2050
|
-
"value": 0,
|
|
2051
|
-
"unit": "px"
|
|
2052
|
-
},
|
|
2053
|
-
"blur": {
|
|
2054
|
-
"value": 0,
|
|
2055
|
-
"unit": "px"
|
|
2056
|
-
},
|
|
2057
|
-
"spread": {
|
|
2058
|
-
"value": 1,
|
|
2059
|
-
"unit": "px"
|
|
2060
|
-
},
|
|
2061
|
-
"color": {
|
|
2062
|
-
"colorSpace": "srgb",
|
|
2063
|
-
"components": [
|
|
2064
|
-
1,
|
|
2065
|
-
1,
|
|
2066
|
-
1
|
|
2067
|
-
],
|
|
2068
|
-
"alpha": 0.16
|
|
2069
|
-
}
|
|
2070
|
-
},
|
|
2071
|
-
{
|
|
2072
|
-
"offsetX": {
|
|
2073
|
-
"value": 0,
|
|
2074
|
-
"unit": "px"
|
|
2075
|
-
},
|
|
2076
|
-
"offsetY": {
|
|
2077
|
-
"value": 0,
|
|
2078
|
-
"unit": "px"
|
|
2079
|
-
},
|
|
2080
|
-
"blur": {
|
|
2081
|
-
"value": 0,
|
|
2082
|
-
"unit": "px"
|
|
2083
|
-
},
|
|
2084
|
-
"spread": {
|
|
2085
|
-
"value": 2,
|
|
2086
|
-
"unit": "px"
|
|
2087
|
-
},
|
|
2088
|
-
"color": {
|
|
2089
|
-
"colorSpace": "srgb",
|
|
2090
|
-
"components": [
|
|
2091
|
-
0,
|
|
2092
|
-
0,
|
|
2093
|
-
0
|
|
2094
|
-
],
|
|
2095
|
-
"alpha": 1
|
|
2096
|
-
}
|
|
2097
|
-
},
|
|
2098
|
-
{
|
|
2099
|
-
"offsetX": {
|
|
2100
|
-
"value": 0,
|
|
2101
|
-
"unit": "px"
|
|
2102
|
-
},
|
|
2103
|
-
"offsetY": {
|
|
2104
|
-
"value": 24,
|
|
2105
|
-
"unit": "px"
|
|
2106
|
-
},
|
|
2107
|
-
"blur": {
|
|
2108
|
-
"value": 48,
|
|
2109
|
-
"unit": "px"
|
|
2110
|
-
},
|
|
2111
|
-
"spread": {
|
|
2112
|
-
"value": -12,
|
|
2113
|
-
"unit": "px"
|
|
2114
|
-
},
|
|
2115
|
-
"color": {
|
|
2116
|
-
"colorSpace": "srgb",
|
|
2117
|
-
"components": [
|
|
2118
|
-
0,
|
|
2119
|
-
0,
|
|
2120
|
-
0
|
|
2121
|
-
],
|
|
2122
|
-
"alpha": 0.9
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
]
|
|
2126
|
-
},
|
|
2127
|
-
"modal": {
|
|
2128
|
-
"$value": [
|
|
2129
|
-
{
|
|
2130
|
-
"offsetX": {
|
|
2131
|
-
"value": 0,
|
|
2132
|
-
"unit": "px"
|
|
2133
|
-
},
|
|
2134
|
-
"offsetY": {
|
|
2135
|
-
"value": 1,
|
|
2136
|
-
"unit": "px"
|
|
2137
|
-
},
|
|
2138
|
-
"blur": {
|
|
2139
|
-
"value": 0,
|
|
2140
|
-
"unit": "px"
|
|
2141
|
-
},
|
|
2142
|
-
"spread": {
|
|
2143
|
-
"value": 0,
|
|
2144
|
-
"unit": "px"
|
|
2145
|
-
},
|
|
2146
|
-
"color": {
|
|
2147
|
-
"colorSpace": "srgb",
|
|
2148
|
-
"components": [
|
|
2149
|
-
1,
|
|
2150
|
-
1,
|
|
2151
|
-
1
|
|
2152
|
-
],
|
|
2153
|
-
"alpha": 0.1
|
|
2154
|
-
},
|
|
2155
|
-
"inset": true
|
|
2156
|
-
},
|
|
2157
|
-
{
|
|
2158
|
-
"offsetX": {
|
|
2159
|
-
"value": 0,
|
|
2160
|
-
"unit": "px"
|
|
2161
|
-
},
|
|
2162
|
-
"offsetY": {
|
|
2163
|
-
"value": 0,
|
|
2164
|
-
"unit": "px"
|
|
2165
|
-
},
|
|
2166
|
-
"blur": {
|
|
2167
|
-
"value": 0,
|
|
2168
|
-
"unit": "px"
|
|
2169
|
-
},
|
|
2170
|
-
"spread": {
|
|
2171
|
-
"value": 1,
|
|
2172
|
-
"unit": "px"
|
|
2173
|
-
},
|
|
2174
|
-
"color": {
|
|
2175
|
-
"colorSpace": "srgb",
|
|
2176
|
-
"components": [
|
|
2177
|
-
1,
|
|
2178
|
-
1,
|
|
2179
|
-
1
|
|
2180
|
-
],
|
|
2181
|
-
"alpha": 0.18
|
|
2182
|
-
}
|
|
2183
|
-
},
|
|
2184
|
-
{
|
|
2185
|
-
"offsetX": {
|
|
2186
|
-
"value": 0,
|
|
2187
|
-
"unit": "px"
|
|
2188
|
-
},
|
|
2189
|
-
"offsetY": {
|
|
2190
|
-
"value": 0,
|
|
2191
|
-
"unit": "px"
|
|
2192
|
-
},
|
|
2193
|
-
"blur": {
|
|
2194
|
-
"value": 0,
|
|
2195
|
-
"unit": "px"
|
|
2196
|
-
},
|
|
2197
|
-
"spread": {
|
|
2198
|
-
"value": 2,
|
|
2199
|
-
"unit": "px"
|
|
2200
|
-
},
|
|
2201
|
-
"color": {
|
|
2202
|
-
"colorSpace": "srgb",
|
|
2203
|
-
"components": [
|
|
2204
|
-
0,
|
|
2205
|
-
0,
|
|
2206
|
-
0
|
|
2207
|
-
],
|
|
2208
|
-
"alpha": 1
|
|
2209
|
-
}
|
|
2210
|
-
},
|
|
2211
|
-
{
|
|
2212
|
-
"offsetX": {
|
|
2213
|
-
"value": 0,
|
|
2214
|
-
"unit": "px"
|
|
2215
|
-
},
|
|
2216
|
-
"offsetY": {
|
|
2217
|
-
"value": 48,
|
|
2218
|
-
"unit": "px"
|
|
2219
|
-
},
|
|
2220
|
-
"blur": {
|
|
2221
|
-
"value": 96,
|
|
2222
|
-
"unit": "px"
|
|
2223
|
-
},
|
|
2224
|
-
"spread": {
|
|
2225
|
-
"value": -24,
|
|
2226
|
-
"unit": "px"
|
|
2227
|
-
},
|
|
2228
|
-
"color": {
|
|
2229
|
-
"colorSpace": "srgb",
|
|
2230
|
-
"components": [
|
|
2231
|
-
0,
|
|
2232
|
-
0,
|
|
2233
|
-
0
|
|
2234
|
-
],
|
|
2235
|
-
"alpha": 1
|
|
2236
|
-
}
|
|
2237
|
-
}
|
|
2238
|
-
]
|
|
2239
|
-
},
|
|
2240
|
-
"glass": {
|
|
2241
|
-
"$value": [
|
|
2242
|
-
{
|
|
2243
|
-
"offsetX": {
|
|
2244
|
-
"value": 0,
|
|
2245
|
-
"unit": "px"
|
|
2246
|
-
},
|
|
2247
|
-
"offsetY": {
|
|
2248
|
-
"value": 1,
|
|
2249
|
-
"unit": "px"
|
|
2250
|
-
},
|
|
2251
|
-
"blur": {
|
|
2252
|
-
"value": 0,
|
|
2253
|
-
"unit": "px"
|
|
2254
|
-
},
|
|
2255
|
-
"spread": {
|
|
2256
|
-
"value": 0,
|
|
2257
|
-
"unit": "px"
|
|
2258
|
-
},
|
|
2259
|
-
"color": {
|
|
2260
|
-
"colorSpace": "srgb",
|
|
2261
|
-
"components": [
|
|
2262
|
-
1,
|
|
2263
|
-
1,
|
|
2264
|
-
1
|
|
2265
|
-
],
|
|
2266
|
-
"alpha": 0.1
|
|
2267
|
-
},
|
|
2268
|
-
"inset": true
|
|
2269
|
-
},
|
|
2270
|
-
{
|
|
2271
|
-
"offsetX": {
|
|
2272
|
-
"value": 0,
|
|
2273
|
-
"unit": "px"
|
|
2274
|
-
},
|
|
2275
|
-
"offsetY": {
|
|
2276
|
-
"value": 0,
|
|
2277
|
-
"unit": "px"
|
|
2278
|
-
},
|
|
2279
|
-
"blur": {
|
|
2280
|
-
"value": 0,
|
|
2281
|
-
"unit": "px"
|
|
2282
|
-
},
|
|
2283
|
-
"spread": {
|
|
2284
|
-
"value": 1,
|
|
2285
|
-
"unit": "px"
|
|
2286
|
-
},
|
|
2287
|
-
"color": {
|
|
2288
|
-
"colorSpace": "srgb",
|
|
2289
|
-
"components": [
|
|
2290
|
-
1,
|
|
2291
|
-
1,
|
|
2292
|
-
1
|
|
2293
|
-
],
|
|
2294
|
-
"alpha": 0.14
|
|
2295
|
-
}
|
|
2296
|
-
},
|
|
2297
|
-
{
|
|
2298
|
-
"offsetX": {
|
|
2299
|
-
"value": 0,
|
|
2300
|
-
"unit": "px"
|
|
2301
|
-
},
|
|
2302
|
-
"offsetY": {
|
|
2303
|
-
"value": 16,
|
|
2304
|
-
"unit": "px"
|
|
2305
|
-
},
|
|
2306
|
-
"blur": {
|
|
2307
|
-
"value": 32,
|
|
2308
|
-
"unit": "px"
|
|
2309
|
-
},
|
|
2310
|
-
"spread": {
|
|
2311
|
-
"value": -12,
|
|
2312
|
-
"unit": "px"
|
|
2313
|
-
},
|
|
2314
|
-
"color": {
|
|
2315
|
-
"colorSpace": "srgb",
|
|
2316
|
-
"components": [
|
|
2317
|
-
0,
|
|
2318
|
-
0,
|
|
2319
|
-
0
|
|
2320
|
-
],
|
|
2321
|
-
"alpha": 0.8
|
|
2322
|
-
}
|
|
2323
|
-
}
|
|
2324
|
-
]
|
|
2325
|
-
}
|
|
2326
|
-
}
|
|
2327
|
-
},
|
|
2328
|
-
"motion": {
|
|
2329
|
-
"duration": {
|
|
2330
|
-
"$type": "duration",
|
|
2331
|
-
"control": {
|
|
2332
|
-
"$value": {
|
|
2333
|
-
"value": 100,
|
|
2334
|
-
"unit": "ms"
|
|
2335
|
-
}
|
|
2336
|
-
},
|
|
2337
|
-
"close": {
|
|
2338
|
-
"$value": {
|
|
2339
|
-
"value": 140,
|
|
2340
|
-
"unit": "ms"
|
|
2341
|
-
}
|
|
2342
|
-
},
|
|
2343
|
-
"confirm": {
|
|
2344
|
-
"$value": {
|
|
2345
|
-
"value": 180,
|
|
2346
|
-
"unit": "ms"
|
|
2347
|
-
}
|
|
2348
|
-
},
|
|
2349
|
-
"open": {
|
|
2350
|
-
"$value": {
|
|
2351
|
-
"value": 220,
|
|
2352
|
-
"unit": "ms"
|
|
2353
|
-
}
|
|
2354
|
-
},
|
|
2355
|
-
"msg-in": {
|
|
2356
|
-
"$value": {
|
|
2357
|
-
"value": 240,
|
|
2358
|
-
"unit": "ms"
|
|
2359
|
-
}
|
|
2360
|
-
},
|
|
2361
|
-
"transition": {
|
|
2362
|
-
"$value": {
|
|
2363
|
-
"value": 240,
|
|
2364
|
-
"unit": "ms"
|
|
2365
|
-
}
|
|
2366
|
-
},
|
|
2367
|
-
"arrive": {
|
|
2368
|
-
"$value": {
|
|
2369
|
-
"value": 300,
|
|
2370
|
-
"unit": "ms"
|
|
2371
|
-
}
|
|
2372
|
-
},
|
|
2373
|
-
"drawer-swipe": {
|
|
2374
|
-
"$value": {
|
|
2375
|
-
"value": 400,
|
|
2376
|
-
"unit": "ms"
|
|
2377
|
-
}
|
|
2378
|
-
},
|
|
2379
|
-
"drawer": {
|
|
2380
|
-
"$value": {
|
|
2381
|
-
"value": 450,
|
|
2382
|
-
"unit": "ms"
|
|
2383
|
-
}
|
|
2384
|
-
},
|
|
2385
|
-
"wait": {
|
|
2386
|
-
"$value": {
|
|
2387
|
-
"value": 1.6,
|
|
2388
|
-
"unit": "s"
|
|
2389
|
-
}
|
|
2390
|
-
}
|
|
2391
|
-
},
|
|
2392
|
-
"ease": {
|
|
2393
|
-
"$type": "cubicBezier",
|
|
2394
|
-
"emphasized": {
|
|
2395
|
-
"$value": [
|
|
2396
|
-
0.3,
|
|
2397
|
-
0.7,
|
|
2398
|
-
0.2,
|
|
2399
|
-
1
|
|
2400
|
-
]
|
|
2401
|
-
},
|
|
2402
|
-
"out-strong": {
|
|
2403
|
-
"$value": [
|
|
2404
|
-
0.23,
|
|
2405
|
-
1,
|
|
2406
|
-
0.32,
|
|
2407
|
-
1
|
|
2408
|
-
]
|
|
2409
|
-
},
|
|
2410
|
-
"in-out-strong": {
|
|
2411
|
-
"$value": [
|
|
2412
|
-
0.77,
|
|
2413
|
-
0,
|
|
2414
|
-
0.175,
|
|
2415
|
-
1
|
|
2416
|
-
]
|
|
2417
|
-
},
|
|
2418
|
-
"drawer": {
|
|
2419
|
-
"$value": [
|
|
2420
|
-
0.32,
|
|
2421
|
-
0.72,
|
|
2422
|
-
0,
|
|
2423
|
-
1
|
|
2424
|
-
]
|
|
2425
|
-
}
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
},
|
|
2429
|
-
"semantic": {
|
|
2430
|
-
"radius": {
|
|
2431
|
-
"$type": "dimension",
|
|
2432
|
-
"$value": "{core.rounded.md}"
|
|
2433
|
-
},
|
|
2434
|
-
"color": {
|
|
2435
|
-
"$type": "color",
|
|
2436
|
-
"light": {
|
|
2437
|
-
"background": {
|
|
2438
|
-
"$value": "{core.color.canvas}"
|
|
2439
|
-
},
|
|
2440
|
-
"foreground": {
|
|
2441
|
-
"$value": "{core.color.ink}"
|
|
2442
|
-
},
|
|
2443
|
-
"card": {
|
|
2444
|
-
"$value": "{core.color.material-solid}"
|
|
2445
|
-
},
|
|
2446
|
-
"card-foreground": {
|
|
2447
|
-
"$value": "{core.color.ink}"
|
|
2448
|
-
},
|
|
2449
|
-
"popover": {
|
|
2450
|
-
"$value": "{core.color.material-solid}"
|
|
2451
|
-
},
|
|
2452
|
-
"popover-foreground": {
|
|
2453
|
-
"$value": "{core.color.ink}"
|
|
2454
|
-
},
|
|
2455
|
-
"primary": {
|
|
2456
|
-
"$value": "{core.color.action}"
|
|
2457
|
-
},
|
|
2458
|
-
"primary-foreground": {
|
|
2459
|
-
"$value": "{core.color.action-foreground}"
|
|
2460
|
-
},
|
|
2461
|
-
"primary-hover": {
|
|
2462
|
-
"$value": "{core.color.action-hover}"
|
|
2463
|
-
},
|
|
2464
|
-
"primary-active": {
|
|
2465
|
-
"$value": "{core.color.action-active}"
|
|
2466
|
-
},
|
|
2467
|
-
"secondary": {
|
|
2468
|
-
"$value": "{core.color.canvas-soft}"
|
|
2469
|
-
},
|
|
2470
|
-
"secondary-foreground": {
|
|
2471
|
-
"$value": "{core.color.ink}"
|
|
2472
|
-
},
|
|
2473
|
-
"muted": {
|
|
2474
|
-
"$value": "{core.color.canvas-soft}"
|
|
2475
|
-
},
|
|
2476
|
-
"muted-foreground": {
|
|
2477
|
-
"$value": "{core.color.body}"
|
|
2478
|
-
},
|
|
2479
|
-
"placeholder": {
|
|
2480
|
-
"$value": "{core.color.muted}"
|
|
2481
|
-
},
|
|
2482
|
-
"accent": {
|
|
2483
|
-
"$value": "{core.color.canvas-soft-2}"
|
|
2484
|
-
},
|
|
2485
|
-
"accent-foreground": {
|
|
2486
|
-
"$value": "{core.color.ink}"
|
|
2487
|
-
},
|
|
2488
|
-
"destructive": {
|
|
2489
|
-
"$value": "{core.color.error}"
|
|
2490
|
-
},
|
|
2491
|
-
"destructive-foreground": {
|
|
2492
|
-
"$value": "{core.color.identity-white}"
|
|
2493
|
-
},
|
|
2494
|
-
"warning": {
|
|
2495
|
-
"$value": "{core.color.warning}"
|
|
2496
|
-
},
|
|
2497
|
-
"warning-foreground": {
|
|
2498
|
-
"$value": "{core.color.ink}"
|
|
2499
|
-
},
|
|
2500
|
-
"success": {
|
|
2501
|
-
"$value": "{core.color.success}"
|
|
2502
|
-
},
|
|
2503
|
-
"success-foreground": {
|
|
2504
|
-
"$value": "{core.color.ink}"
|
|
2505
|
-
},
|
|
2506
|
-
"info": {
|
|
2507
|
-
"$value": "{core.color.info}"
|
|
2508
|
-
},
|
|
2509
|
-
"info-foreground": {
|
|
2510
|
-
"$value": "{core.color.identity-white}"
|
|
2511
|
-
},
|
|
2512
|
-
"destructive-soft": {
|
|
2513
|
-
"$value": "{core.color.error-soft}"
|
|
2514
|
-
},
|
|
2515
|
-
"destructive-soft-foreground": {
|
|
2516
|
-
"$value": "{core.color.error-deep}"
|
|
2517
|
-
},
|
|
2518
|
-
"warning-soft": {
|
|
2519
|
-
"$value": "{core.color.warning-soft}"
|
|
2520
|
-
},
|
|
2521
|
-
"warning-soft-foreground": {
|
|
2522
|
-
"$value": "{core.color.warning-deep}"
|
|
2523
|
-
},
|
|
2524
|
-
"success-soft": {
|
|
2525
|
-
"$value": "{core.color.success-soft}"
|
|
2526
|
-
},
|
|
2527
|
-
"success-soft-foreground": {
|
|
2528
|
-
"$value": "{core.color.success-deep}"
|
|
2529
|
-
},
|
|
2530
|
-
"info-soft": {
|
|
2531
|
-
"$value": "{core.color.info-soft}"
|
|
2532
|
-
},
|
|
2533
|
-
"info-soft-foreground": {
|
|
2534
|
-
"$value": "{core.color.info-deep}"
|
|
2535
|
-
},
|
|
2536
|
-
"border": {
|
|
2537
|
-
"$value": "{core.color.line}"
|
|
2538
|
-
},
|
|
2539
|
-
"input": {
|
|
2540
|
-
"$value": "{core.color.input}"
|
|
2541
|
-
},
|
|
2542
|
-
"ring": {
|
|
2543
|
-
"$value": "{core.color.focus-ring}"
|
|
2544
|
-
},
|
|
2545
|
-
"scrim": {
|
|
2546
|
-
"$value": "{core.color.scrim}"
|
|
2547
|
-
},
|
|
2548
|
-
"chart-1": {
|
|
2549
|
-
"$value": "{core.color.chart-1}"
|
|
2550
|
-
},
|
|
2551
|
-
"chart-2": {
|
|
2552
|
-
"$value": "{core.color.chart-2}"
|
|
2553
|
-
},
|
|
2554
|
-
"chart-3": {
|
|
2555
|
-
"$value": "{core.color.chart-3}"
|
|
2556
|
-
},
|
|
2557
|
-
"chart-4": {
|
|
2558
|
-
"$value": "{core.color.chart-4}"
|
|
2559
|
-
},
|
|
2560
|
-
"chart-5": {
|
|
2561
|
-
"$value": "{core.color.chart-5}"
|
|
2562
|
-
},
|
|
2563
|
-
"selection": {
|
|
2564
|
-
"$value": "{core.color.navigation-selection-bg}"
|
|
2565
|
-
},
|
|
2566
|
-
"selection-foreground": {
|
|
2567
|
-
"$value": "{core.color.navigation-selection-fg}"
|
|
2568
|
-
},
|
|
2569
|
-
"recessed": {
|
|
2570
|
-
"$value": "{core.color.canvas-soft}"
|
|
2571
|
-
},
|
|
2572
|
-
"sidebar": {
|
|
2573
|
-
"$value": "{core.color.canvas-soft}"
|
|
2574
|
-
},
|
|
2575
|
-
"sidebar-foreground": {
|
|
2576
|
-
"$value": "{core.color.ink}"
|
|
2577
|
-
},
|
|
2578
|
-
"sidebar-primary": {
|
|
2579
|
-
"$value": "{core.color.navigation-selection-bg}"
|
|
2580
|
-
},
|
|
2581
|
-
"sidebar-primary-foreground": {
|
|
2582
|
-
"$value": "{core.color.navigation-selection-fg}"
|
|
2583
|
-
},
|
|
2584
|
-
"sidebar-primary-hover": {
|
|
2585
|
-
"$value": "{core.color.navigation-selection-hover}"
|
|
2586
|
-
},
|
|
2587
|
-
"sidebar-accent": {
|
|
2588
|
-
"$value": "{core.color.canvas-soft-2}"
|
|
2589
|
-
},
|
|
2590
|
-
"sidebar-accent-foreground": {
|
|
2591
|
-
"$value": "{core.color.ink}"
|
|
2592
|
-
},
|
|
2593
|
-
"sidebar-border": {
|
|
2594
|
-
"$value": "{core.color.line}"
|
|
2595
|
-
},
|
|
2596
|
-
"sidebar-ring": {
|
|
2597
|
-
"$value": "{core.color.focus-ring}"
|
|
2598
|
-
},
|
|
2599
|
-
"category-teal": {
|
|
2600
|
-
"$value": "{core.color.category-teal-soft}"
|
|
2601
|
-
},
|
|
2602
|
-
"category-teal-foreground": {
|
|
2603
|
-
"$value": "{core.color.category-teal-deep}"
|
|
2604
|
-
},
|
|
2605
|
-
"category-purple": {
|
|
2606
|
-
"$value": "{core.color.category-purple-soft}"
|
|
2607
|
-
},
|
|
2608
|
-
"category-purple-foreground": {
|
|
2609
|
-
"$value": "{core.color.category-purple-deep}"
|
|
2610
|
-
},
|
|
2611
|
-
"category-pink": {
|
|
2612
|
-
"$value": "{core.color.category-pink-soft}"
|
|
2613
|
-
},
|
|
2614
|
-
"category-pink-foreground": {
|
|
2615
|
-
"$value": "{core.color.category-pink-deep}"
|
|
2616
|
-
}
|
|
2617
|
-
},
|
|
2618
|
-
"dark": {
|
|
2619
|
-
"background": {
|
|
2620
|
-
"$value": "{core.color.dark-canvas}"
|
|
2621
|
-
},
|
|
2622
|
-
"foreground": {
|
|
2623
|
-
"$value": "{core.color.dark-ink}"
|
|
2624
|
-
},
|
|
2625
|
-
"card": {
|
|
2626
|
-
"$value": "{core.color.dark-material-solid}"
|
|
2627
|
-
},
|
|
2628
|
-
"card-foreground": {
|
|
2629
|
-
"$value": "{core.color.dark-ink}"
|
|
2630
|
-
},
|
|
2631
|
-
"popover": {
|
|
2632
|
-
"$value": "{core.color.dark-material-solid}"
|
|
2633
|
-
},
|
|
2634
|
-
"popover-foreground": {
|
|
2635
|
-
"$value": "{core.color.dark-ink}"
|
|
2636
|
-
},
|
|
2637
|
-
"primary": {
|
|
2638
|
-
"$value": "{core.color.dark-action}"
|
|
2639
|
-
},
|
|
2640
|
-
"primary-foreground": {
|
|
2641
|
-
"$value": "{core.color.dark-action-foreground}"
|
|
2642
|
-
},
|
|
2643
|
-
"primary-hover": {
|
|
2644
|
-
"$value": "{core.color.dark-action-hover}"
|
|
2645
|
-
},
|
|
2646
|
-
"primary-active": {
|
|
2647
|
-
"$value": "{core.color.dark-action-active}"
|
|
2648
|
-
},
|
|
2649
|
-
"secondary": {
|
|
2650
|
-
"$value": "{core.color.dark-canvas-soft}"
|
|
2651
|
-
},
|
|
2652
|
-
"secondary-foreground": {
|
|
2653
|
-
"$value": "{core.color.dark-ink}"
|
|
2654
|
-
},
|
|
2655
|
-
"muted": {
|
|
2656
|
-
"$value": "{core.color.dark-canvas-soft}"
|
|
2657
|
-
},
|
|
2658
|
-
"muted-foreground": {
|
|
2659
|
-
"$value": "{core.color.dark-body}"
|
|
2660
|
-
},
|
|
2661
|
-
"placeholder": {
|
|
2662
|
-
"$value": "{core.color.dark-muted}"
|
|
2663
|
-
},
|
|
2664
|
-
"accent": {
|
|
2665
|
-
"$value": "{core.color.dark-canvas-soft-2}"
|
|
2666
|
-
},
|
|
2667
|
-
"accent-foreground": {
|
|
2668
|
-
"$value": "{core.color.dark-ink}"
|
|
2669
|
-
},
|
|
2670
|
-
"destructive": {
|
|
2671
|
-
"$value": "{core.color.dark-error}"
|
|
2672
|
-
},
|
|
2673
|
-
"destructive-foreground": {
|
|
2674
|
-
"$value": "{core.color.dark-on-primary}"
|
|
2675
|
-
},
|
|
2676
|
-
"warning": {
|
|
2677
|
-
"$value": "{core.color.dark-warning}"
|
|
2678
|
-
},
|
|
2679
|
-
"warning-foreground": {
|
|
2680
|
-
"$value": "{core.color.dark-on-primary}"
|
|
2681
|
-
},
|
|
2682
|
-
"success": {
|
|
2683
|
-
"$value": "{core.color.dark-success}"
|
|
2684
|
-
},
|
|
2685
|
-
"success-foreground": {
|
|
2686
|
-
"$value": "{core.color.dark-on-primary}"
|
|
2687
|
-
},
|
|
2688
|
-
"info": {
|
|
2689
|
-
"$value": "{core.color.dark-info}"
|
|
2690
|
-
},
|
|
2691
|
-
"info-foreground": {
|
|
2692
|
-
"$value": "{core.color.dark-on-primary}"
|
|
2693
|
-
},
|
|
2694
|
-
"destructive-soft": {
|
|
2695
|
-
"$value": "{core.color.dark-error-soft}"
|
|
2696
|
-
},
|
|
2697
|
-
"destructive-soft-foreground": {
|
|
2698
|
-
"$value": "{core.color.dark-error-deep}"
|
|
2699
|
-
},
|
|
2700
|
-
"warning-soft": {
|
|
2701
|
-
"$value": "{core.color.dark-warning-soft}"
|
|
2702
|
-
},
|
|
2703
|
-
"warning-soft-foreground": {
|
|
2704
|
-
"$value": "{core.color.dark-warning-deep}"
|
|
2705
|
-
},
|
|
2706
|
-
"success-soft": {
|
|
2707
|
-
"$value": "{core.color.dark-success-soft}"
|
|
2708
|
-
},
|
|
2709
|
-
"success-soft-foreground": {
|
|
2710
|
-
"$value": "{core.color.dark-success-deep}"
|
|
2711
|
-
},
|
|
2712
|
-
"info-soft": {
|
|
2713
|
-
"$value": "{core.color.dark-info-soft}"
|
|
2714
|
-
},
|
|
2715
|
-
"info-soft-foreground": {
|
|
2716
|
-
"$value": "{core.color.dark-info-deep}"
|
|
2717
|
-
},
|
|
2718
|
-
"border": {
|
|
2719
|
-
"$value": "{core.color.dark-line}"
|
|
2720
|
-
},
|
|
2721
|
-
"input": {
|
|
2722
|
-
"$value": "{core.color.dark-input}"
|
|
2723
|
-
},
|
|
2724
|
-
"ring": {
|
|
2725
|
-
"$value": "{core.color.dark-focus-ring}"
|
|
2726
|
-
},
|
|
2727
|
-
"scrim": {
|
|
2728
|
-
"$value": "{core.color.dark-scrim}"
|
|
2729
|
-
},
|
|
2730
|
-
"chart-1": {
|
|
2731
|
-
"$value": "{core.color.dark-chart-1}"
|
|
2732
|
-
},
|
|
2733
|
-
"chart-2": {
|
|
2734
|
-
"$value": "{core.color.dark-chart-2}"
|
|
2735
|
-
},
|
|
2736
|
-
"chart-3": {
|
|
2737
|
-
"$value": "{core.color.dark-chart-3}"
|
|
2738
|
-
},
|
|
2739
|
-
"chart-4": {
|
|
2740
|
-
"$value": "{core.color.dark-chart-4}"
|
|
2741
|
-
},
|
|
2742
|
-
"chart-5": {
|
|
2743
|
-
"$value": "{core.color.dark-chart-5}"
|
|
2744
|
-
},
|
|
2745
|
-
"selection": {
|
|
2746
|
-
"$value": "{core.color.dark-navigation-selection-bg}"
|
|
2747
|
-
},
|
|
2748
|
-
"selection-foreground": {
|
|
2749
|
-
"$value": "{core.color.dark-navigation-selection-fg}"
|
|
2750
|
-
},
|
|
2751
|
-
"recessed": {
|
|
2752
|
-
"$value": "{core.color.dark-canvas}"
|
|
2753
|
-
},
|
|
2754
|
-
"sidebar": {
|
|
2755
|
-
"$value": "{core.color.dark-canvas}"
|
|
2756
|
-
},
|
|
2757
|
-
"sidebar-foreground": {
|
|
2758
|
-
"$value": "{core.color.dark-ink}"
|
|
2759
|
-
},
|
|
2760
|
-
"sidebar-primary": {
|
|
2761
|
-
"$value": "{core.color.dark-navigation-selection-bg}"
|
|
2762
|
-
},
|
|
2763
|
-
"sidebar-primary-foreground": {
|
|
2764
|
-
"$value": "{core.color.dark-navigation-selection-fg}"
|
|
2765
|
-
},
|
|
2766
|
-
"sidebar-primary-hover": {
|
|
2767
|
-
"$value": "{core.color.dark-navigation-selection-hover}"
|
|
2768
|
-
},
|
|
2769
|
-
"sidebar-accent": {
|
|
2770
|
-
"$value": "{core.color.dark-canvas-soft-2}"
|
|
2771
|
-
},
|
|
2772
|
-
"sidebar-accent-foreground": {
|
|
2773
|
-
"$value": "{core.color.dark-ink}"
|
|
2774
|
-
},
|
|
2775
|
-
"sidebar-border": {
|
|
2776
|
-
"$value": "{core.color.dark-line}"
|
|
2777
|
-
},
|
|
2778
|
-
"sidebar-ring": {
|
|
2779
|
-
"$value": "{core.color.dark-focus-ring}"
|
|
2780
|
-
},
|
|
2781
|
-
"category-teal": {
|
|
2782
|
-
"$value": "{core.color.dark-category-teal-soft}"
|
|
2783
|
-
},
|
|
2784
|
-
"category-teal-foreground": {
|
|
2785
|
-
"$value": "{core.color.dark-category-teal-deep}"
|
|
2786
|
-
},
|
|
2787
|
-
"category-purple": {
|
|
2788
|
-
"$value": "{core.color.dark-category-purple-soft}"
|
|
2789
|
-
},
|
|
2790
|
-
"category-purple-foreground": {
|
|
2791
|
-
"$value": "{core.color.dark-category-purple-deep}"
|
|
2792
|
-
},
|
|
2793
|
-
"category-pink": {
|
|
2794
|
-
"$value": "{core.color.dark-category-pink-soft}"
|
|
2795
|
-
},
|
|
2796
|
-
"category-pink-foreground": {
|
|
2797
|
-
"$value": "{core.color.dark-category-pink-deep}"
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2800
|
-
}
|
|
2801
|
-
},
|
|
2802
|
-
"register": {
|
|
2803
|
-
"website": {
|
|
2804
|
-
"$extensions": {
|
|
2805
|
-
"ai.nadicode.targets": [
|
|
2806
|
-
"css",
|
|
2807
|
-
"data"
|
|
2808
|
-
]
|
|
2809
|
-
},
|
|
2810
|
-
"layout": {
|
|
2811
|
-
"$type": "dimension",
|
|
2812
|
-
"content-max": {
|
|
2813
|
-
"$value": {
|
|
2814
|
-
"value": 1200,
|
|
2815
|
-
"unit": "px"
|
|
2816
|
-
}
|
|
2817
|
-
},
|
|
2818
|
-
"gutter-mobile": {
|
|
2819
|
-
"$value": {
|
|
2820
|
-
"value": 20,
|
|
2821
|
-
"unit": "px"
|
|
2822
|
-
}
|
|
2823
|
-
},
|
|
2824
|
-
"gutter-tablet": {
|
|
2825
|
-
"$value": {
|
|
2826
|
-
"value": 40,
|
|
2827
|
-
"unit": "px"
|
|
2828
|
-
}
|
|
2829
|
-
},
|
|
2830
|
-
"gutter-desktop": {
|
|
2831
|
-
"$value": {
|
|
2832
|
-
"value": 64,
|
|
2833
|
-
"unit": "px"
|
|
2834
|
-
}
|
|
2835
|
-
},
|
|
2836
|
-
"section-step-mobile": {
|
|
2837
|
-
"$value": {
|
|
2838
|
-
"value": 64,
|
|
2839
|
-
"unit": "px"
|
|
2840
|
-
}
|
|
2841
|
-
},
|
|
2842
|
-
"section-step-desktop": {
|
|
2843
|
-
"$value": {
|
|
2844
|
-
"value": 96,
|
|
2845
|
-
"unit": "px"
|
|
2846
|
-
}
|
|
2847
|
-
}
|
|
2848
|
-
}
|
|
2849
|
-
}
|
|
2850
|
-
}
|
|
2851
|
-
}
|
|
2852
|
-
```
|
|
1230
|
+
The YAML front matter holds the four groups the DESIGN.md format defines: colors, typography, rounded and spacing. Every other value is authored in `src/tokens/extension.tokens.json`, in the W3C design-tokens format: `core.material` (the scrim and glass values, a `dark-` value beside one that differs in dark), `core.elevation` (the four heights and the glass edge, per mode), `core.motion` (durations and easings), `semantic` (the shared colour roles and radius) and `register.website` (the website column). An alias is written `{core.color.canvas}`. In CSS a token is `--nc-<name>`, an elevation is reached only through `nc-elevation-<height>`, and Tailwind names the values through the `nc-` and `nadicode-` namespaces. The build composes the two into the package's token files and CSS, as the package README describes.
|