@nadicodeai/design-system 12.1.117 → 12.1.119

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.
Files changed (2) hide show
  1. package/DESIGN.md +11 -11
  2. package/package.json +9 -3
package/DESIGN.md CHANGED
@@ -560,7 +560,7 @@ The neutral spine carries grounds, chrome, text and every control: `{colors.ink}
560
560
 
561
561
  The identity palette is the brand's colour: cobalto `{colors.identity-cobalto}`, verde `{colors.identity-verde}`, arancio `{colors.identity-arancio}`, giallo `{colors.identity-giallo}` and rosso `{colors.identity-rosso}`, with `{colors.identity-ink}` and `{colors.identity-white}` as the poles type sits on. Azzurro `{colors.identity-azzurro}` has two jobs: the first stripe of Nadia's ribbon, and a band of a company's card foil ("Company card").
562
562
 
563
- The hues appear at full strength and flat, with no tints, steps, gradients or hover variants, in these places. The one exception is the website's shader objects, each the material of one object and never a section's ground: the threads she holds, a fan of lines in her stripes from her orb to her colleagues, on black; Alveare's hive, cells that light in its hues as the work passes; and the company card's holographic foil ("Company card"). Stripes and cells stay pure bands of their hues, never a colour between two of them. Ruled by the founder on 27 September 2026: "shaders are not backgrounds all over the place".
563
+ The hues appear at full strength and flat, with no tints, steps, gradients or hover variants, in these places. The one exception is the website's shader objects, each the material of one object and never a section's ground: the threads she holds, a fan of lines in her stripes from her orb to her colleagues, on black; Alveare's hive, cells that light in its hues as the work passes; and the company card's holographic foil ("Company card"). Stripes and cells stay pure bands of their hues, never a colour between two of them. Ruled by the founder: "shaders are not backgrounds all over the place".
564
564
 
565
565
  - **Section grounds on the website.** A section's ground is white, soft or black, and two neighbouring sections never share one; colour lives in the pictures, the objects, the Agents and the shader objects, never as a section's ground.
566
566
  - **Glass.** The colour a glass surface shows through ("Elevation & Depth").
@@ -752,15 +752,15 @@ The Portal, Nadia and Alveare are product shells: persistent navigation on the l
752
752
  | --- | --- | --- | --- | --- |
753
753
  | Where I can go | The sidebar | Groups by viewer, one selected row | Find, Scheduled tasks, the company's Wiki and Skills, then the Agents | Inbox, Channels, Direct messages |
754
754
  | An object's sections | The sidebar, swapped | Back link, the object, its sections | Two swaps only: ⋯ → Edit and Settings | The channel's own panels |
755
- | The path | The top bar | Centred: the group or the parents, then the place | The window header: the Agent's orb and name, then the chat switcher | The channel header names the channel |
755
+ | The path | The top bar | Customer or Partner switcher on the left and the current section centred; other paths centred | The window header: the Agent's orb and name, then the chat switcher | The channel header names the channel |
756
756
  | Find, ⌘K | The top of the sidebar | An outlined field | At the top of the list | Buzz's search, in its sidebar |
757
757
  | The account | The sidebar's foot | With the bell | Under the update card | The package's `AccountMenu` |
758
758
  | Getting the app | Above the account | Downloads, an outlined row | The update card, only when there is one | The update card |
759
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 |
760
760
 
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
+ - **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 navigation (`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.
762
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.
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
+ - **The top bar holds navigation, never the page's actions.** Customer and Partner collections and their object sections use `ScopeSwitcher`'s navigation variant on the left: the company's mark and name, a searchable list with the current company checked, and a close link back to the originating collection. The current section is centred, below the switcher on phones so the company name and status remain visible. Other pages keep the centred path, ending at the place or the object. An object's own status sits beside its name in the path and nowhere else on the page.
764
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.
765
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.
766
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.
@@ -797,7 +797,7 @@ A section earns a card when it owns a decision, not for every label and value. A
797
797
 
798
798
  Product UI sits on one continuous workspace ground, `{colors.material-workspace}` (true black in dark), and solid objects rise above it at four heights: `nc-elevation-resting` for resting content, then `nc-elevation-raised`, `nc-elevation-floating` and `nc-elevation-modal` when an object is physically raised, floating or modal. Physical role chooses the height, never the importance of the content. Each recipe carries its own edge, so an elevated surface never adds a border, a ring or a second shadow.
799
799
 
800
- The owner approved the materials on 18 October 2026: Vercel's surfaces with a little more depth on what floats, and glass only where it is useful. [The materials reference](../../docs/adr/2026-09-23-the-nadicode-design-system/depth-and-glass.html) shows each height and the glass in both modes. Four rules decide them.
800
+ The owner approved the materials: Vercel's surfaces with a little more depth on what floats, and glass only where it is useful. [The materials reference](../../docs/adr/2026-09-23-the-nadicode-design-system/depth-and-glass.html) shows each height and the glass in both modes. Four rules decide them.
801
801
 
802
802
  **Content lies on the page.** Cards, KPIs, tables, lists and settings take the resting height: white in light and `{colors.dark-material-resting}` in dark, on the black page. Their edge is a 1 px line, black at 8% in light; in dark white at 14.5%, with a 1 px black ring outside it, so the edge stays sharp where one surface overlaps another. They have no grey fill, as Vercel's cards have none.
803
803
 
@@ -840,11 +840,11 @@ A corner follows what the thing is, on one scale: buttons, inputs, badges, tabs
840
840
 
841
841
  UI text stays static: no shimmer, typing, scrambling, pulsing or animated dots. Status labels use sentence case without trailing ellipses; complete instructional sentences keep their punctuation.
842
842
 
843
- Only Agents move on their own. The interface answers a person's action, briefly, and stops: motion follows the action, grows from the element that was pressed, and settles, within 300 ms; sheets and drawers that follow the pointer take their own durations. Keyboard actions and anything used a hundred times a day are instant. While a person waits for something they asked for, one waiting line moves and nothing else ("System activity"). On the website three things move: Agents, the product at work, and the shader objects. A product scene runs the real components through their states in beats while it is half in view, rests on the finished work, loops, stops off-screen, and holds the finished work under reduced motion; a part of a scene arrives with `.nc-arrive`: it holds its place from the start and comes into focus there on the message-arrival timing, so a playing scene never shifts the page. The threads, the hive and the card's foil move at their own slow pace; each stops off-screen and holds one frame under reduced motion. Words never move, and there is no parallax, scroll reveal of text, marquee or shimmer. Ruled by the founder on 26 September 2026: a Stripe-grade product site, with shaders adjusted to the art direction and the products shown working.
843
+ Only Agents move on their own. The interface answers a person's action, briefly, and stops: motion follows the action, grows from the element that was pressed, and settles, within 300 ms; sheets and drawers that follow the pointer take their own durations. Keyboard actions and anything used a hundred times a day are instant. While a person waits for something they asked for, one waiting line moves and nothing else ("System activity"). On the website three things move: Agents, the product at work, and the shader objects. A product scene runs the real components through their states in beats while it is half in view, rests on the finished work, loops, stops off-screen, and holds the finished work under reduced motion; a part of a scene arrives with `.nc-arrive`: it holds its place from the start and comes into focus there on the message-arrival timing, so a playing scene never shifts the page. The threads, the hive and the card's foil move at their own slow pace; each stops off-screen and holds one frame under reduced motion. Words never move, and there is no parallax, scroll reveal of text, marquee or shimmer. Ruled by the founder: a Stripe-grade product site, with shaders adjusted to the art direction and the products shown working.
844
844
 
845
845
  The homepage figures have one owner-requested exception: a slight lean in response to a fine pointer, with no autonomous loop and no movement under reduced motion. Architecture and words stay still.
846
846
 
847
- In the products a picture stands only on a collection's first use and on a whole-page moment: the entry screens, the failure pages, the Downloads page and a product's first run ("Entry screens"). Every picture stays still, with one exception: a first use's picture arrives once, after it loads. It holds its place and comes into focus there, from transparent and an 8 px blur to sharp, over `arrive` on `emphasized`, and never moves again; it never loops, and under reduced motion it does not animate at all and simply appears. Ruled by the owner on 14 October 2026.
847
+ In the products a picture stands only on a collection's first use and on a whole-page moment: the entry screens, the failure pages, the Downloads page and a product's first run ("Entry screens"). Every picture stays still, with one exception: a first use's picture arrives once, after it loads. It holds its place and comes into focus there, from transparent and an 8 px blur to sharp, over `arrive` on `emphasized`, and never moves again; it never loops, and under reduced motion it does not animate at all and simply appears. Ruled by the owner.
848
848
 
849
849
  The default transition in every product is `confirm`, 180 ms, `out-strong`. Under reduced motion, movement stops and paint continues: transforms and keyframed movement go to their end state, and opacity and colour transitions stay, because a fade or a colour change is the state change itself. A component never answers reduced motion by turning every transition off.
850
850
 
@@ -1038,7 +1038,7 @@ The owner's decisions where Geist and ours differ:
1038
1038
  - Find goes to places only: it runs no command and has no page stack.
1039
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.
1040
1040
  - `ChoiceboxGroup`, `ClearableInput`, `Snippet` and `LoadMoreButton` are components, never recipes a page assembles.
1041
- - The three-dot trigger stays 36 px, ruled by the owner on 14 October 2026.
1041
+ - The three-dot trigger stays 36 px, ruled by the owner.
1042
1042
 
1043
1043
  ### Controls
1044
1044
 
@@ -1127,7 +1127,7 @@ An absence inside a product's own chrome, such as an address or a record the Por
1127
1127
 
1128
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.
1129
1129
 
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.
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: the Agent's states are the chat's default states, not random icons, and the person never meets "the app" in a conversation, only the Agent.
1131
1131
 
1132
1132
  ### Agent card
1133
1133
 
@@ -1207,7 +1207,7 @@ The clear space is one stroke width of the rendered logo on every side. The mini
1207
1207
  - **Portal.** A product shell on the workspace ground, built from the page compositions and the package components, with `globals.css` giving every elevated surface its tone.
1208
1208
  - **Nadia.** Nadia draws her own window through Hermes's `window.shell` area, inside Hermes's app, which owns Tailwind and its own surface layering. Nadia's theme paints Hermes's roles with the shared `semantic` roles and core radii, and imports `@nadicodeai/ui/components.css` with the design system's host stylesheet, so the package components render with the same recipes and glass. The window follows the operating system's material where the system composites it. Hermes answers reduced motion by cutting every transition and animation; Nadia's stylesheet gives her own parts, the package overlays, the entry screen and the waiting line, the reduced-motion policy in "Motion" back.
1209
1209
  Her conversation is one centred column of `56rem` holding her replies, the person's messages and the chat bar: her reply is plain text across the column, only the person's message is a bubble, grey (`{colors.canvas-soft-2}`) at the `raised` height in both modes, at the column's trailing edge, and the chat bar floats over the messages in glass ("Elevation & Depth"). The selected Agent row carries the sidebar's selected fill, as the Agents list draws it.
1210
- - **Alveare.** The desktop keeps Buzz's components and layout, styled through an adapter as Nadia styles Hermes: Buzz's colour roles read the shared `semantic` roles, tokens only and never a copied value, every text takes a type role, and Buzz's shared components take the package's geometry, states, focus and motion, over the design system's host stylesheet and `@nadicodeai/ui/components.css`. For the four jobs the products share, Alveare mounts the package's own component in place of Buzz's: every empty state is `EmptyState`, the account menu is `AccountMenu`, a status is `StatusBadge`, and the three dots are `ActionMenu`. Agents appear as their orbs, and a person never reads "Buzz". Ruled by the owner on 14 October 2026.
1210
+ - **Alveare.** The desktop keeps Buzz's components and layout, styled through an adapter as Nadia styles Hermes: Buzz's colour roles read the shared `semantic` roles, tokens only and never a copied value, every text takes a type role, and Buzz's shared components take the package's geometry, states, focus and motion, over the design system's host stylesheet and `@nadicodeai/ui/components.css`. For the four jobs the products share, Alveare mounts the package's own component in place of Buzz's: every empty state is `EmptyState`, the account menu is `AccountMenu`, a status is `StatusBadge`, and the three dots are `ActionMenu`. Agents appear as their orbs, and a person never reads "Buzz". Ruled by the owner.
1211
1211
 
1212
1212
  ## Do's and Don'ts
1213
1213
 
@@ -1222,7 +1222,7 @@ The clear space is one stroke width of the rendered logo on every side. The mini
1222
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.
1223
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.
1224
1224
  - Do build a page from its composition. Don't assemble a page's header, toolbar, rows or menus by hand.
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.
1225
+ - Do put navigation 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.
1226
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.
1227
1227
 
1228
1228
  ## Token extension
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nadicodeai/design-system",
3
- "version": "12.1.117",
3
+ "version": "12.1.119",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -186,7 +186,8 @@
186
186
  "generate:icons": "tsx scripts/generate-icons.ts",
187
187
  "generate:favicons": "tsx scripts/generate-favicons.ts",
188
188
  "lint:design": "design.md lint DESIGN.md",
189
- "lint": "node ../../tools/workspace/heavy-slots.mjs -- eslint --max-warnings=0",
189
+ "lint": "npm run lint:oxlint && node ../../tools/workspace/heavy-slots.mjs -- eslint --max-warnings=0",
190
+ "lint:oxlint": "node ../../tools/workspace/heavy-slots.mjs -- oxlint",
190
191
  "typecheck": "node ../../tools/workspace/heavy-slots.mjs -- node ../../node_modules/typescript-native/bin/tsc --checkers 2 -p tsconfig.json",
191
192
  "check": "npm run lint:design && npm run lint && npm run typecheck",
192
193
  "check:static": "npm run check",
@@ -197,7 +198,11 @@
197
198
  },
198
199
  "devDependencies": {
199
200
  "@google/design.md": "0.4.0",
201
+ "@nadicodeai/eslint-config": "*",
200
202
  "@nadicodeai/eslint-plugin": "*",
203
+ "@nadicodeai/oxlint-config": "*",
204
+ "@nadicodeai/static-design-server": "*",
205
+ "@nadicodeai/test-support": "*",
201
206
  "@playwright/test": "^1.64.1",
202
207
  "@types/node": "^24",
203
208
  "ajv": "8.20.0",
@@ -205,6 +210,7 @@
205
210
  "esbuild": "^0.28.2",
206
211
  "eslint": "^9.39.4",
207
212
  "lucide-static": "1.57.0",
213
+ "oxlint": "1.88.0",
208
214
  "parse5": "^8.0.1",
209
215
  "postcss": "^8.5.30",
210
216
  "postcss-value-parser": "^4.2.0",
@@ -213,6 +219,6 @@
213
219
  "tsx": "^4.23.15",
214
220
  "typescript": "^6",
215
221
  "typescript-native": "npm:typescript@7.0.2",
216
- "vitest": "^5.0.0"
222
+ "vitest": "^5.0.5"
217
223
  }
218
224
  }