@verdify/ui 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/LICENSE +12 -0
  2. package/dist/components/accordion/accordion.variants.d.ts.map +1 -1
  3. package/dist/components/accordion/accordion.variants.js +2 -1
  4. package/dist/components/accordion/accordion.variants.js.map +1 -1
  5. package/dist/components/agent-badge/agent-badge.variants.d.ts.map +1 -1
  6. package/dist/components/agent-badge/agent-badge.variants.js.map +1 -1
  7. package/dist/components/alert/alert.variants.d.ts.map +1 -1
  8. package/dist/components/alert/alert.variants.js +3 -2
  9. package/dist/components/alert/alert.variants.js.map +1 -1
  10. package/dist/components/breadcrumb/breadcrumb.variants.d.ts.map +1 -1
  11. package/dist/components/breadcrumb/breadcrumb.variants.js +2 -1
  12. package/dist/components/breadcrumb/breadcrumb.variants.js.map +1 -1
  13. package/dist/components/button/button.variants.d.ts.map +1 -1
  14. package/dist/components/button/button.variants.js +2 -1
  15. package/dist/components/button/button.variants.js.map +1 -1
  16. package/dist/components/card/card.variants.d.ts.map +1 -1
  17. package/dist/components/card/card.variants.js +2 -1
  18. package/dist/components/card/card.variants.js.map +1 -1
  19. package/dist/components/checkbox/checkbox.js +1 -1
  20. package/dist/components/checkbox/checkbox.js.map +1 -1
  21. package/dist/components/checkbox/checkbox.variants.d.ts.map +1 -1
  22. package/dist/components/checkbox/checkbox.variants.js +2 -1
  23. package/dist/components/checkbox/checkbox.variants.js.map +1 -1
  24. package/dist/components/command-palette/command-palette.variants.d.ts +1 -1
  25. package/dist/components/command-palette/command-palette.variants.d.ts.map +1 -1
  26. package/dist/components/command-palette/command-palette.variants.js +5 -3
  27. package/dist/components/command-palette/command-palette.variants.js.map +1 -1
  28. package/dist/components/consent-toggle/consent-toggle.variants.d.ts +1 -1
  29. package/dist/components/consent-toggle/consent-toggle.variants.d.ts.map +1 -1
  30. package/dist/components/consent-toggle/consent-toggle.variants.js +1 -1
  31. package/dist/components/consent-toggle/consent-toggle.variants.js.map +1 -1
  32. package/dist/components/credential-card/credential-card.variants.d.ts +3 -3
  33. package/dist/components/credential-card/credential-card.variants.d.ts.map +1 -1
  34. package/dist/components/credential-card/credential-card.variants.js +3 -3
  35. package/dist/components/credential-card/credential-card.variants.js.map +1 -1
  36. package/dist/components/data-grid/data-grid.variants.d.ts +1 -1
  37. package/dist/components/data-grid/data-grid.variants.d.ts.map +1 -1
  38. package/dist/components/data-grid/data-grid.variants.js +11 -10
  39. package/dist/components/data-grid/data-grid.variants.js.map +1 -1
  40. package/dist/components/dialog/dialog.variants.d.ts.map +1 -1
  41. package/dist/components/dialog/dialog.variants.js +3 -2
  42. package/dist/components/dialog/dialog.variants.js.map +1 -1
  43. package/dist/components/identity-chip/identity-chip.variants.d.ts.map +1 -1
  44. package/dist/components/identity-chip/identity-chip.variants.js +3 -2
  45. package/dist/components/identity-chip/identity-chip.variants.js.map +1 -1
  46. package/dist/components/input/input.variants.d.ts.map +1 -1
  47. package/dist/components/input/input.variants.js +3 -2
  48. package/dist/components/input/input.variants.js.map +1 -1
  49. package/dist/components/label/label.variants.js +1 -1
  50. package/dist/components/label/label.variants.js.map +1 -1
  51. package/dist/components/menu/menu.d.ts.map +1 -1
  52. package/dist/components/menu/menu.js +1 -1
  53. package/dist/components/menu/menu.js.map +1 -1
  54. package/dist/components/menu/menu.variants.d.ts +1 -1
  55. package/dist/components/menu/menu.variants.d.ts.map +1 -1
  56. package/dist/components/menu/menu.variants.js +3 -2
  57. package/dist/components/menu/menu.variants.js.map +1 -1
  58. package/dist/components/pagination/pagination.variants.d.ts.map +1 -1
  59. package/dist/components/pagination/pagination.variants.js +2 -1
  60. package/dist/components/pagination/pagination.variants.js.map +1 -1
  61. package/dist/components/popover/popover.variants.d.ts.map +1 -1
  62. package/dist/components/popover/popover.variants.js +4 -3
  63. package/dist/components/popover/popover.variants.js.map +1 -1
  64. package/dist/components/progress/progress.variants.d.ts +1 -1
  65. package/dist/components/progress/progress.variants.d.ts.map +1 -1
  66. package/dist/components/progress/progress.variants.js +1 -1
  67. package/dist/components/progress/progress.variants.js.map +1 -1
  68. package/dist/components/radio/radio.d.ts.map +1 -1
  69. package/dist/components/radio/radio.js +2 -1
  70. package/dist/components/radio/radio.js.map +1 -1
  71. package/dist/components/select/select.variants.d.ts +3 -3
  72. package/dist/components/select/select.variants.d.ts.map +1 -1
  73. package/dist/components/select/select.variants.js +5 -4
  74. package/dist/components/select/select.variants.js.map +1 -1
  75. package/dist/components/sheet/sheet.variants.d.ts.map +1 -1
  76. package/dist/components/sheet/sheet.variants.js +3 -2
  77. package/dist/components/sheet/sheet.variants.js.map +1 -1
  78. package/dist/components/sidebar/sidebar.variants.d.ts +1 -1
  79. package/dist/components/sidebar/sidebar.variants.d.ts.map +1 -1
  80. package/dist/components/sidebar/sidebar.variants.js +4 -3
  81. package/dist/components/sidebar/sidebar.variants.js.map +1 -1
  82. package/dist/components/switch/switch.variants.d.ts.map +1 -1
  83. package/dist/components/switch/switch.variants.js +2 -1
  84. package/dist/components/switch/switch.variants.js.map +1 -1
  85. package/dist/components/table/table.d.ts.map +1 -1
  86. package/dist/components/table/table.js +1 -1
  87. package/dist/components/table/table.js.map +1 -1
  88. package/dist/components/table/table.variants.d.ts.map +1 -1
  89. package/dist/components/table/table.variants.js +9 -7
  90. package/dist/components/table/table.variants.js.map +1 -1
  91. package/dist/components/tabs/tabs.variants.d.ts.map +1 -1
  92. package/dist/components/tabs/tabs.variants.js +3 -2
  93. package/dist/components/tabs/tabs.variants.js.map +1 -1
  94. package/dist/components/textarea/textarea.js +2 -2
  95. package/dist/components/textarea/textarea.js.map +1 -1
  96. package/dist/components/textarea/textarea.variants.d.ts.map +1 -1
  97. package/dist/components/textarea/textarea.variants.js +2 -1
  98. package/dist/components/textarea/textarea.variants.js.map +1 -1
  99. package/dist/components/toast/toast.variants.d.ts.map +1 -1
  100. package/dist/components/toast/toast.variants.js +3 -2
  101. package/dist/components/toast/toast.variants.js.map +1 -1
  102. package/dist/components/trust-score/trust-score.variants.d.ts +1 -1
  103. package/dist/components/trust-score/trust-score.variants.d.ts.map +1 -1
  104. package/dist/components/trust-score/trust-score.variants.js +1 -1
  105. package/dist/components/trust-score/trust-score.variants.js.map +1 -1
  106. package/dist/index.d.ts +1 -0
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +3 -1
  109. package/dist/index.js.map +1 -1
  110. package/dist/lib/focus-ring.d.ts +2 -0
  111. package/dist/lib/focus-ring.d.ts.map +1 -0
  112. package/dist/lib/focus-ring.js +5 -0
  113. package/dist/lib/focus-ring.js.map +1 -0
  114. package/package.json +18 -19
  115. package/registry/accordion.json +3 -2
  116. package/registry/agent-badge.json +1 -1
  117. package/registry/alert.json +3 -2
  118. package/registry/breadcrumb.json +3 -2
  119. package/registry/button.json +3 -2
  120. package/registry/card.json +3 -2
  121. package/registry/checkbox.json +4 -3
  122. package/registry/command-palette.json +3 -2
  123. package/registry/consent-toggle.json +1 -1
  124. package/registry/credential-card.json +1 -1
  125. package/registry/data-grid.json +2 -1
  126. package/registry/dialog.json +3 -2
  127. package/registry/focus-ring.json +16 -0
  128. package/registry/identity-chip.json +2 -1
  129. package/registry/init.json +1 -1
  130. package/registry/input.json +3 -2
  131. package/registry/label.json +1 -1
  132. package/registry/menu.json +4 -3
  133. package/registry/pagination.json +3 -2
  134. package/registry/popover.json +3 -2
  135. package/registry/progress.json +1 -1
  136. package/registry/radio.json +3 -2
  137. package/registry/select.json +3 -2
  138. package/registry/sheet.json +3 -2
  139. package/registry/sidebar.json +3 -2
  140. package/registry/switch.json +3 -2
  141. package/registry/table.json +3 -2
  142. package/registry/tabs.json +3 -2
  143. package/registry/textarea.json +3 -2
  144. package/registry/toast.json +3 -2
  145. package/registry/trust-score.json +1 -1
  146. package/registry.json +4 -0
@@ -18,7 +18,7 @@ const consentToggleVariants = cva("flex flex-col gap-(--space-2)", {
18
18
  const consentToggleRecipientClass = "text-body text-text-secondary";
19
19
  const consentToggleDetailClass = "text-body text-text-secondary";
20
20
  const consentToggleEvidenceClass = "flex items-center text-body";
21
- const consentToggleFailureClass = "text-body text-status-critical-fg";
21
+ const consentToggleFailureClass = "text-body text-status-critical-on-surface";
22
22
  export {
23
23
  consentToggleDetailClass,
24
24
  consentToggleEvidenceClass,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/consent-toggle/consent-toggle.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// ConsentToggle is the explicit, revocable affordance by which an actor grants or\n// withdraws permission for one specific use of their data or identity (spec §1). It\n// COMPOSES the committed Switch as its control — the granted axis maps to the Switch's\n// `on` — and adds the scope, the named recipient, the optional detail, the optional\n// evidence affordance, and the failure message AROUND it. So the track / thumb / focus\n// ring / target-size floor / slide-and-tint motion are bound ONCE in switch.variants.ts\n// and are NOT re-bound here; this file binds only the surrounding text + layout roles.\n//\n// brand != state (spec §4/§5/§8). The granted track takes the primary ACTION accent\n// (the Switch's `aria-checked:bg-action-primary-bg`), NEVER --color-status-verified-*:\n// verified green is the in-product verified status, never a consent affordance, and a\n// grant reports permission, not a verification result. ConsentToggle therefore binds\n// NOTHING from the status tier on its granted state — the one status color it ever\n// reaches for is --color-status-critical-fg, and ONLY on the failure message (a stated\n// failed grant/withdrawal), never on the granted/checked state. This component-scoped\n// invariant (no status color on the grant; verified green never a consent affordance) is\n// pinned as a test in consent-toggle.test.tsx — the action accent IS legitimate here, so\n// the negative forbids only the STATUS tier, per the build-on-brand skill's scoping note.\n//\n// The motion is the Switch's FAST functional slide/tint on verdify easing, collapsing to\n// the instant endpoint under reduced motion — never the 350ms VerifiedBadge-only theatre\n// duration: a consent grant is not a verification (G-U3).\n\n// The root layout (spec §2): a column stacking the control row, the optional evidence\n// affordance, and the optional failure message at the --space-2 gap. The `variant` axis\n// (spec §3) is a form of how the consent is PRESENTED — a plain grant, a grant with the\n// evidence affordance, or a grant scoped to an AI agent — never a level of color or alarm,\n// so NONE of the variants recolors anything: the granted accent and every text role are\n// identical across all three. Non-interactive container: the focus ring, the keyboard\n// model, and the target-size floor all live on the composed Switch control, not here.\nexport const consentToggleVariants = cva(\"flex flex-col gap-(--space-2)\", {\n variants: {\n // STRUCTURAL axis = spec §3. Display/composition forms, never alarm levels.\n variant: {\n // grant (default): a single permission the actor turns on to allow, off to withhold.\n grant: \"\",\n // with-evidence: adds the evidence affordance so the actor can review the recorded\n // grant — what, to whom, when. Use wherever the grant is consequential.\n \"with-evidence\": \"\",\n // agent-scoped: the recipient is an AI-agent actor, named AS an agent (AgentBadge),\n // so the actor knows they are granting to an agent, not a human.\n \"agent-scoped\": \"\",\n },\n },\n defaultVariants: { variant: \"grant\" },\n});\n\n// The recipient + detail block (spec §2/§5): who receives the data and the optional bound\n// of the grant, in the SECONDARY text color at the --text-body type role. It is composed\n// into the control's accessible description (aria-describedby), so a screen reader\n// announces \"to whom\" alongside the scope — never a bare on/off with the meaning missing.\nexport const consentToggleRecipientClass = \"text-body text-text-secondary\";\n\n// The optional detail line (spec §2/§5): one statement clarifying the bound or duration of\n// the grant (for example, what stops when consent is withdrawn), under the recipient, in\n// the secondary text color at the body role.\nexport const consentToggleDetailClass = \"text-body text-text-secondary\";\n\n// The optional evidence affordance row (spec §2/§3): a slot holding the caller's link or\n// Button to the PROOF of the grant — what was consented to, to whom, and when — so the act\n// is reviewable later. It is the caller's own focus stop with its own keyboard model and\n// focus ring (the evidence control is not folded into the busy switch); this row only\n// positions it. Surfaces a proof of the consent event, not a stored document.\nexport const consentToggleEvidenceClass = \"flex items-center text-body\";\n\n// The failure message (spec §4/§5/§7): shown next to the control on a FAILED grant or\n// withdrawal, naming what failed and what to do next without blaming the reader, in the\n// CRITICAL status foreground at the --text-body role. It is the ONLY status color the\n// component binds, and only here — never on the granted state (brand != state). It is\n// announced through an assertive live region (role=alert), set in the tsx, per 4.1.3.\nexport const consentToggleFailureClass = \"text-body text-status-critical-fg\";\n\nexport type ConsentToggleVariantProps = VariantProps<typeof consentToggleVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAgChC,MAAM,wBAAwB,IAAI,iCAAiC;AAAA,EACxE,UAAU;AAAA;AAAA,IAER,SAAS;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAAA,MAGP,iBAAiB;AAAA;AAAA;AAAA,MAGjB,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,SAAS,QAAQ;AACtC,CAAC;AAMM,MAAM,8BAA8B;AAKpC,MAAM,2BAA2B;AAOjC,MAAM,6BAA6B;AAOnC,MAAM,4BAA4B;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/consent-toggle/consent-toggle.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// ConsentToggle is the explicit, revocable affordance by which an actor grants or\n// withdraws permission for one specific use of their data or identity (spec §1). It\n// COMPOSES the committed Switch as its control — the granted axis maps to the Switch's\n// `on` — and adds the scope, the named recipient, the optional detail, the optional\n// evidence affordance, and the failure message AROUND it. So the track / thumb / focus\n// ring / target-size floor / slide-and-tint motion are bound ONCE in switch.variants.ts\n// and are NOT re-bound here; this file binds only the surrounding text + layout roles.\n//\n// brand != state (spec §4/§5/§8). The granted track takes the primary ACTION accent\n// (the Switch's `aria-checked:bg-action-primary-bg`), NEVER --color-status-verified-*:\n// verified green is the in-product verified status, never a consent affordance, and a\n// grant reports permission, not a verification result. ConsentToggle therefore binds\n// NOTHING from the status tier on its granted state — the one status color it ever\n// reaches for is --color-status-critical-fg, and ONLY on the failure message (a stated\n// failed grant/withdrawal), never on the granted/checked state. This component-scoped\n// invariant (no status color on the grant; verified green never a consent affordance) is\n// pinned as a test in consent-toggle.test.tsx — the action accent IS legitimate here, so\n// the negative forbids only the STATUS tier, per the build-on-brand skill's scoping note.\n//\n// The motion is the Switch's FAST functional slide/tint on verdify easing, collapsing to\n// the instant endpoint under reduced motion — never the 350ms VerifiedBadge-only theatre\n// duration: a consent grant is not a verification (G-U3).\n\n// The root layout (spec §2): a column stacking the control row, the optional evidence\n// affordance, and the optional failure message at the --space-2 gap. The `variant` axis\n// (spec §3) is a form of how the consent is PRESENTED — a plain grant, a grant with the\n// evidence affordance, or a grant scoped to an AI agent — never a level of color or alarm,\n// so NONE of the variants recolors anything: the granted accent and every text role are\n// identical across all three. Non-interactive container: the focus ring, the keyboard\n// model, and the target-size floor all live on the composed Switch control, not here.\nexport const consentToggleVariants = cva(\"flex flex-col gap-(--space-2)\", {\n variants: {\n // STRUCTURAL axis = spec §3. Display/composition forms, never alarm levels.\n variant: {\n // grant (default): a single permission the actor turns on to allow, off to withhold.\n grant: \"\",\n // with-evidence: adds the evidence affordance so the actor can review the recorded\n // grant — what, to whom, when. Use wherever the grant is consequential.\n \"with-evidence\": \"\",\n // agent-scoped: the recipient is an AI-agent actor, named AS an agent (AgentBadge),\n // so the actor knows they are granting to an agent, not a human.\n \"agent-scoped\": \"\",\n },\n },\n defaultVariants: { variant: \"grant\" },\n});\n\n// The recipient + detail block (spec §2/§5): who receives the data and the optional bound\n// of the grant, in the SECONDARY text color at the --text-body type role. It is composed\n// into the control's accessible description (aria-describedby), so a screen reader\n// announces \"to whom\" alongside the scope — never a bare on/off with the meaning missing.\nexport const consentToggleRecipientClass = \"text-body text-text-secondary\";\n\n// The optional detail line (spec §2/§5): one statement clarifying the bound or duration of\n// the grant (for example, what stops when consent is withdrawn), under the recipient, in\n// the secondary text color at the body role.\nexport const consentToggleDetailClass = \"text-body text-text-secondary\";\n\n// The optional evidence affordance row (spec §2/§3): a slot holding the caller's link or\n// Button to the PROOF of the grant — what was consented to, to whom, and when — so the act\n// is reviewable later. It is the caller's own focus stop with its own keyboard model and\n// focus ring (the evidence control is not folded into the busy switch); this row only\n// positions it. Surfaces a proof of the consent event, not a stored document.\nexport const consentToggleEvidenceClass = \"flex items-center text-body\";\n\n// The failure message (spec §4/§5/§7): shown next to the control on a FAILED grant or\n// withdrawal, naming what failed and what to do next without blaming the reader, in the\n// CRITICAL status foreground at the --text-body role. It is the ONLY status color the\n// component binds, and only here — never on the granted state (brand != state). It is\n// announced through an assertive live region (role=alert), set in the tsx, per 4.1.3.\nexport const consentToggleFailureClass = \"text-body text-status-critical-on-surface\";\n\nexport type ConsentToggleVariantProps = VariantProps<typeof consentToggleVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAgChC,MAAM,wBAAwB,IAAI,iCAAiC;AAAA,EACxE,UAAU;AAAA;AAAA,IAER,SAAS;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAAA,MAGP,iBAAiB;AAAA;AAAA;AAAA,MAGjB,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,SAAS,QAAQ;AACtC,CAAC;AAMM,MAAM,8BAA8B;AAKpC,MAAM,2BAA2B;AAOjC,MAAM,6BAA6B;AAOnC,MAAM,4BAA4B;","names":[]}
@@ -7,9 +7,9 @@ export declare const credentialCardBodyClass = "flex min-w-0 flex-1 flex-col gap
7
7
  export declare const credentialCardLabelClass = "text-label text-text-primary";
8
8
  export declare const credentialCardIdentifierClass = "text-mono text-text-secondary [direction:ltr] truncate";
9
9
  export declare const credentialCardStatusClass = "flex shrink-0 flex-wrap items-center gap-(--space-1)";
10
- export declare const credentialCardMetaClass = "text-caption text-text-muted";
10
+ export declare const credentialCardMetaClass = "text-caption text-text-secondary";
11
11
  export declare const credentialCardControlsClass = "flex shrink-0 items-center gap-(--space-2)";
12
- export declare const credentialCardReasonClass = "text-caption text-text-muted";
13
- export declare const credentialCardErrorClass = "text-caption text-status-critical-fg";
12
+ export declare const credentialCardReasonClass = "text-caption text-text-secondary";
13
+ export declare const credentialCardErrorClass = "text-caption text-status-critical-on-surface";
14
14
  export type CredentialCardVariantProps = VariantProps<typeof credentialCardVariants>;
15
15
  //# sourceMappingURL=credential-card.variants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credential-card.variants.d.ts","sourceRoot":"","sources":["../../../src/components/credential-card/credential-card.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAsClE,eAAO,MAAM,sBAAsB;;8EAwBlC,CAAC;AAOF,eAAO,MAAM,uBAAuB,+GAC0E,CAAC;AAK/G,eAAO,MAAM,uBAAuB,iDAAiD,CAAC;AAKtF,eAAO,MAAM,wBAAwB,iCAAiC,CAAC;AAOvE,eAAO,MAAM,6BAA6B,2DACgB,CAAC;AAO3D,eAAO,MAAM,yBAAyB,yDAAyD,CAAC;AAIhG,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AAOtE,eAAO,MAAM,2BAA2B,+CAA+C,CAAC;AAMxF,eAAO,MAAM,yBAAyB,iCAAiC,CAAC;AAQxE,eAAO,MAAM,wBAAwB,yCAAyC,CAAC;AAE/E,MAAM,MAAM,0BAA0B,GAAG,YAAY,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"credential-card.variants.d.ts","sourceRoot":"","sources":["../../../src/components/credential-card/credential-card.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAsClE,eAAO,MAAM,sBAAsB;;8EAwBlC,CAAC;AAOF,eAAO,MAAM,uBAAuB,+GAC0E,CAAC;AAK/G,eAAO,MAAM,uBAAuB,iDAAiD,CAAC;AAKtF,eAAO,MAAM,wBAAwB,iCAAiC,CAAC;AAOvE,eAAO,MAAM,6BAA6B,2DACgB,CAAC;AAO3D,eAAO,MAAM,yBAAyB,yDAAyD,CAAC;AAKhG,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAO1E,eAAO,MAAM,2BAA2B,+CAA+C,CAAC;AAOxF,eAAO,MAAM,yBAAyB,qCAAqC,CAAC;AAQ5E,eAAO,MAAM,wBAAwB,iDAAiD,CAAC;AAEvF,MAAM,MAAM,0BAA0B,GAAG,YAAY,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -29,10 +29,10 @@ const credentialCardBodyClass = "flex min-w-0 flex-1 flex-col gap-(--space-1)";
29
29
  const credentialCardLabelClass = "text-label text-text-primary";
30
30
  const credentialCardIdentifierClass = "text-mono text-text-secondary [direction:ltr] truncate";
31
31
  const credentialCardStatusClass = "flex shrink-0 flex-wrap items-center gap-(--space-1)";
32
- const credentialCardMetaClass = "text-caption text-text-muted";
32
+ const credentialCardMetaClass = "text-caption text-text-secondary";
33
33
  const credentialCardControlsClass = "flex shrink-0 items-center gap-(--space-2)";
34
- const credentialCardReasonClass = "text-caption text-text-muted";
35
- const credentialCardErrorClass = "text-caption text-status-critical-fg";
34
+ const credentialCardReasonClass = "text-caption text-text-secondary";
35
+ const credentialCardErrorClass = "text-caption text-status-critical-on-surface";
36
36
  export {
37
37
  credentialCardBodyClass,
38
38
  credentialCardControlsClass,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/credential-card/credential-card.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// CredentialCard is one ROW in the list of credentials ATTACHED to an identity — a single way\n// to reach that identity (an email, phone, passkey, wallet, or enterprise SSO connection). It\n// encodes the platform's first invariant — identity is not credentials — in its UI contract: a\n// card is a LINK to an identity, never the identity itself, so it never reads as \"you\" and never\n// stands in for the account (spec §1/§8).\n//\n// It COMPOSES the committed primitives rather than reinventing them — a Card-like neutral surface\n// (the surface-* roles, bound here), the destructive Button for `remove`, the secondary Button\n// for an optional `action`, the Badge for a `status`, the Checkbox for `selectable`, and the\n// Button's in-place loading spinner for a resolving removal. So the focus ring, the target-size\n// floor, the keyboard model, and the control motion all come from those proven primitives; this\n// file binds ONLY the surrounding neutral surface + text-role + layout classes.\n//\n// brand != state (spec §3/§5/§8). The card SURFACE consumes NO action or status token of its own\n// — neutrals carry the card. The brand violet (Sovereign Violet, the action accent) is never a\n// card fill, never the icon, never the identifier, and never marks a credential as special. The\n// verified-status green is reserved for the `verified` status Badge and is never spent on the\n// card surface, the icon, or the identifier — coloring the card green would imply the IDENTITY is\n// verified, which is the one misreport this molecule forbids. The card therefore binds nothing\n// from the action tier and nothing from the status tier; those colors live on the controls and\n// Badges it holds (asserted positively in their own primitives' tests), never on this surface.\n//\n// The motion the card adds is none of its own: control hover/press uses the composed primitive's\n// fast functional transition on verdify easing, collapsing to the instant endpoint under reduced\n// motion. A resolving removal is a plain wait on the Button's ambient spinner — never the 350ms\n// VerifiedBadge-only theatre duration: a removal is not a verification (G-U3).\n\n// The card container (spec §2/§4/§5): a NEUTRAL raised surface, the same Card-static surface the\n// committed Card binds, but it is a LIST ROW (`<li role=\"listitem\">`, set in the tsx) so it sits\n// in the credential list's `<ul role=\"list\">` (spec §7). It is a static container, NOT a single\n// clickable control — the whole row does not map to one action — so it carries no focus ring and\n// no target-size floor of its own (those live on its controls, spec §4/§5). The `kind` axis is\n// which credential the card represents; it is carried by the `icon` + `label` TEXT, never by\n// color, so NONE of the kinds recolors the surface — every kind is the identical neutral surface\n// (spec §3). `selectable` composes with any kind and changes layout (a leading Checkbox), not\n// color, so it is not a color variant here.\nexport const credentialCardVariants = cva(\n [\n // raised neutral surface, rounded container, resting elevation, internal padding from --space-4\n \"relative flex items-start gap-(--space-2) rounded-lg border bg-surface-raised shadow-sm p-(--space-4)\",\n // the default container hairline (spec §5)\n \"border-surface-border\",\n // logical-property text alignment so the row mirrors under dir=rtl (G-U6); list rows carry\n // no bullet marker\n \"text-start text-text-primary list-none\",\n ],\n {\n variants: {\n // STRUCTURAL axis = spec §3 (the credential KIND the card represents). The kind is carried\n // by the icon + label text, never color, so every kind is the SAME neutral surface.\n kind: {\n email: \"\",\n phone: \"\",\n passkey: \"\",\n wallet: \"\",\n \"enterprise-sso\": \"\",\n },\n },\n defaultVariants: { kind: \"email\" },\n },\n);\n\n// The kind icon (spec §2/§5/§7): one small glyph for the credential kind at the md icon role. It\n// reinforces the kind shown in the label and is decorative (aria-hidden, set in the tsx) — the\n// label text still carries the kind if the icon is dropped, so the kind never rests on the icon\n// or color alone. Its fill is the SECONDARY text role (a neutral role), never a status color and\n// never the brand (spec §2/§3).\nexport const credentialCardIconClass =\n \"inline-flex h-(--size-icon-md) w-(--size-icon-md) shrink-0 items-center justify-center text-text-secondary\";\n\n// The label + identifier block (spec §2): the human-readable kind name above the value that\n// identifies this specific credential. Takes the remaining inline space between the icon and the\n// trailing status/controls; stacks the two lines at the --space-1 gap.\nexport const credentialCardBodyClass = \"flex min-w-0 flex-1 flex-col gap-(--space-1)\";\n\n// The label (spec §2/§5): the human-readable name of the credential KIND, a statement in\n// sentence case (for example \"Email\", \"Passkey\", \"Wallet\"), in the label type role + the PRIMARY\n// text color. The label says what kind of link this is, not who the identity is.\nexport const credentialCardLabelClass = \"text-label text-text-primary\";\n\n// The identifier (spec §2/§5/G-U6): the value that identifies this specific credential — the\n// email, the masked phone, the passkey device name, the truncated wallet address, or the SSO\n// provider + domain. It renders in the MONOSPACE type role (never the UI font for credential\n// strings) in the SECONDARY text color, isolated left-to-right so addresses, hashes, and wallet\n// strings stay readable even inside RTL text, and truncates rather than wrapping.\nexport const credentialCardIdentifierClass =\n \"text-mono text-text-secondary [direction:ltr] truncate\";\n\n// The status row (spec §2): at most one or two small Badges stating a fact about the credential —\n// `verified` (the green status, on the composed Badge's verified variant) or `primary` (the\n// credential you currently sign in with, a NEUTRAL Badge — \"primary\" is which credential is used,\n// a fact, not a status color and never the brand). The status describes the credential, not the\n// identity. This row only positions the composed Badges; their color lives in badge.variants.ts.\nexport const credentialCardStatusClass = \"flex shrink-0 flex-wrap items-center gap-(--space-1)\";\n\n// The meta line (spec §2/§5): quiet secondary text such as when the credential was added or last\n// used, in the MUTED text color at the caption role. De-emphasized; never an alarm color.\nexport const credentialCardMetaClass = \"text-caption text-text-muted\";\n\n// The trailing controls cluster (spec §2): the optional `action` beside the required `remove`,\n// aligned to the inline-end edge at the --space-2 gap. Keep the card to one primary action\n// (`remove`) plus at most one further low-emphasis control (restraint over volume). It only lays\n// the controls out; each control's treatment + focus ring + target-size floor live on the\n// composed Button.\nexport const credentialCardControlsClass = \"flex shrink-0 items-center gap-(--space-2)\";\n\n// The disabled-reason note (spec §4/§5/§7): when a control is disabled (for example `remove` on\n// the last sign-in credential), the reason is given as adjacent text in the MUTED text color at\n// the caption role — wired to the control as its accessible description (so the reason is heard,\n// not just seen), never communicated by graying alone.\nexport const credentialCardReasonClass = \"text-caption text-text-muted\";\n\n// The removal-failure message (spec §4/§7): on a FAILED removal the credential stays in the list\n// and the failure is stated plainly where it happened, in the CRITICAL status foreground at the\n// caption role — naming what failed and what to do next, never blaming the reader and never an\n// exclamation mark. It is the ONLY status color this component binds, and only here (never on the\n// card surface, brand != state). It is announced through an assertive live region (role=alert,\n// set in the tsx) per 4.1.3.\nexport const credentialCardErrorClass = \"text-caption text-status-critical-fg\";\n\nexport type CredentialCardVariantProps = VariantProps<typeof credentialCardVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAsChC,MAAM,yBAAyB;AAAA,EACpC;AAAA;AAAA,IAEE;AAAA;AAAA,IAEA;AAAA;AAAA;AAAA,IAGA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA;AAAA,MAGR,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,MAAM,QAAQ;AAAA,EACnC;AACF;AAOO,MAAM,0BACX;AAKK,MAAM,0BAA0B;AAKhC,MAAM,2BAA2B;AAOjC,MAAM,gCACX;AAOK,MAAM,4BAA4B;AAIlC,MAAM,0BAA0B;AAOhC,MAAM,8BAA8B;AAMpC,MAAM,4BAA4B;AAQlC,MAAM,2BAA2B;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/credential-card/credential-card.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// CredentialCard is one ROW in the list of credentials ATTACHED to an identity — a single way\n// to reach that identity (an email, phone, passkey, wallet, or enterprise SSO connection). It\n// encodes the platform's first invariant — identity is not credentials — in its UI contract: a\n// card is a LINK to an identity, never the identity itself, so it never reads as \"you\" and never\n// stands in for the account (spec §1/§8).\n//\n// It COMPOSES the committed primitives rather than reinventing them — a Card-like neutral surface\n// (the surface-* roles, bound here), the destructive Button for `remove`, the secondary Button\n// for an optional `action`, the Badge for a `status`, the Checkbox for `selectable`, and the\n// Button's in-place loading spinner for a resolving removal. So the focus ring, the target-size\n// floor, the keyboard model, and the control motion all come from those proven primitives; this\n// file binds ONLY the surrounding neutral surface + text-role + layout classes.\n//\n// brand != state (spec §3/§5/§8). The card SURFACE consumes NO action or status token of its own\n// — neutrals carry the card. The brand violet (Sovereign Violet, the action accent) is never a\n// card fill, never the icon, never the identifier, and never marks a credential as special. The\n// verified-status green is reserved for the `verified` status Badge and is never spent on the\n// card surface, the icon, or the identifier — coloring the card green would imply the IDENTITY is\n// verified, which is the one misreport this molecule forbids. The card therefore binds nothing\n// from the action tier and nothing from the status tier; those colors live on the controls and\n// Badges it holds (asserted positively in their own primitives' tests), never on this surface.\n//\n// The motion the card adds is none of its own: control hover/press uses the composed primitive's\n// fast functional transition on verdify easing, collapsing to the instant endpoint under reduced\n// motion. A resolving removal is a plain wait on the Button's ambient spinner — never the 350ms\n// VerifiedBadge-only theatre duration: a removal is not a verification (G-U3).\n\n// The card container (spec §2/§4/§5): a NEUTRAL raised surface, the same Card-static surface the\n// committed Card binds, but it is a LIST ROW (`<li role=\"listitem\">`, set in the tsx) so it sits\n// in the credential list's `<ul role=\"list\">` (spec §7). It is a static container, NOT a single\n// clickable control — the whole row does not map to one action — so it carries no focus ring and\n// no target-size floor of its own (those live on its controls, spec §4/§5). The `kind` axis is\n// which credential the card represents; it is carried by the `icon` + `label` TEXT, never by\n// color, so NONE of the kinds recolors the surface — every kind is the identical neutral surface\n// (spec §3). `selectable` composes with any kind and changes layout (a leading Checkbox), not\n// color, so it is not a color variant here.\nexport const credentialCardVariants = cva(\n [\n // raised neutral surface, rounded container, resting elevation, internal padding from --space-4\n \"relative flex items-start gap-(--space-2) rounded-lg border bg-surface-raised shadow-sm p-(--space-4)\",\n // the default container hairline (spec §5)\n \"border-surface-border\",\n // logical-property text alignment so the row mirrors under dir=rtl (G-U6); list rows carry\n // no bullet marker\n \"text-start text-text-primary list-none\",\n ],\n {\n variants: {\n // STRUCTURAL axis = spec §3 (the credential KIND the card represents). The kind is carried\n // by the icon + label text, never color, so every kind is the SAME neutral surface.\n kind: {\n email: \"\",\n phone: \"\",\n passkey: \"\",\n wallet: \"\",\n \"enterprise-sso\": \"\",\n },\n },\n defaultVariants: { kind: \"email\" },\n },\n);\n\n// The kind icon (spec §2/§5/§7): one small glyph for the credential kind at the md icon role. It\n// reinforces the kind shown in the label and is decorative (aria-hidden, set in the tsx) — the\n// label text still carries the kind if the icon is dropped, so the kind never rests on the icon\n// or color alone. Its fill is the SECONDARY text role (a neutral role), never a status color and\n// never the brand (spec §2/§3).\nexport const credentialCardIconClass =\n \"inline-flex h-(--size-icon-md) w-(--size-icon-md) shrink-0 items-center justify-center text-text-secondary\";\n\n// The label + identifier block (spec §2): the human-readable kind name above the value that\n// identifies this specific credential. Takes the remaining inline space between the icon and the\n// trailing status/controls; stacks the two lines at the --space-1 gap.\nexport const credentialCardBodyClass = \"flex min-w-0 flex-1 flex-col gap-(--space-1)\";\n\n// The label (spec §2/§5): the human-readable name of the credential KIND, a statement in\n// sentence case (for example \"Email\", \"Passkey\", \"Wallet\"), in the label type role + the PRIMARY\n// text color. The label says what kind of link this is, not who the identity is.\nexport const credentialCardLabelClass = \"text-label text-text-primary\";\n\n// The identifier (spec §2/§5/G-U6): the value that identifies this specific credential — the\n// email, the masked phone, the passkey device name, the truncated wallet address, or the SSO\n// provider + domain. It renders in the MONOSPACE type role (never the UI font for credential\n// strings) in the SECONDARY text color, isolated left-to-right so addresses, hashes, and wallet\n// strings stay readable even inside RTL text, and truncates rather than wrapping.\nexport const credentialCardIdentifierClass =\n \"text-mono text-text-secondary [direction:ltr] truncate\";\n\n// The status row (spec §2): at most one or two small Badges stating a fact about the credential —\n// `verified` (the green status, on the composed Badge's verified variant) or `primary` (the\n// credential you currently sign in with, a NEUTRAL Badge — \"primary\" is which credential is used,\n// a fact, not a status color and never the brand). The status describes the credential, not the\n// identity. This row only positions the composed Badges; their color lives in badge.variants.ts.\nexport const credentialCardStatusClass = \"flex shrink-0 flex-wrap items-center gap-(--space-1)\";\n\n// The meta line (spec §2/§5): quiet secondary text such as when the credential was added or last\n// used, at the caption role. Essential de-emphasized text (it conveys when), so it uses the SECONDARY\n// text color (AA), not the decorative-only muted role (accessibility.md). Never an alarm color.\nexport const credentialCardMetaClass = \"text-caption text-text-secondary\";\n\n// The trailing controls cluster (spec §2): the optional `action` beside the required `remove`,\n// aligned to the inline-end edge at the --space-2 gap. Keep the card to one primary action\n// (`remove`) plus at most one further low-emphasis control (restraint over volume). It only lays\n// the controls out; each control's treatment + focus ring + target-size floor live on the\n// composed Button.\nexport const credentialCardControlsClass = \"flex shrink-0 items-center gap-(--space-2)\";\n\n// The disabled-reason note (spec §4/§5/§7): when a control is disabled (for example `remove` on\n// the last sign-in credential), the reason is given as adjacent text at the caption role — wired to\n// the control as its accessible description (so the reason is heard, not just seen). It is essential\n// text, so it uses the SECONDARY text color (AA), not the decorative-only muted role\n// (accessibility.md), and is never communicated by graying alone.\nexport const credentialCardReasonClass = \"text-caption text-text-secondary\";\n\n// The removal-failure message (spec §4/§7): on a FAILED removal the credential stays in the list\n// and the failure is stated plainly where it happened, in the CRITICAL status foreground at the\n// caption role — naming what failed and what to do next, never blaming the reader and never an\n// exclamation mark. It is the ONLY status color this component binds, and only here (never on the\n// card surface, brand != state). It is announced through an assertive live region (role=alert,\n// set in the tsx) per 4.1.3.\nexport const credentialCardErrorClass = \"text-caption text-status-critical-on-surface\";\n\nexport type CredentialCardVariantProps = VariantProps<typeof credentialCardVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAsChC,MAAM,yBAAyB;AAAA,EACpC;AAAA;AAAA,IAEE;AAAA;AAAA,IAEA;AAAA;AAAA;AAAA,IAGA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA;AAAA,MAGR,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,QACP,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,MAAM,QAAQ;AAAA,EACnC;AACF;AAOO,MAAM,0BACX;AAKK,MAAM,0BAA0B;AAKhC,MAAM,2BAA2B;AAOjC,MAAM,gCACX;AAOK,MAAM,4BAA4B;AAKlC,MAAM,0BAA0B;AAOhC,MAAM,8BAA8B;AAOpC,MAAM,4BAA4B;AAQlC,MAAM,2BAA2B;","names":[]}
@@ -24,6 +24,6 @@ export declare const dataGridBulkActionVariants: (props?: ({
24
24
  destructive?: boolean | null | undefined;
25
25
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
26
26
  export type DataGridBulkActionVariantProps = VariantProps<typeof dataGridBulkActionVariants>;
27
- export declare const dataGridEmptyClass = "px-(--space-3) py-(--space-6) text-center text-body text-text-muted";
27
+ export declare const dataGridEmptyClass = "px-(--space-3) py-(--space-6) text-center text-body text-text-secondary";
28
28
  export declare const dataGridStatusRegionClass = "sr-only";
29
29
  //# sourceMappingURL=data-grid.variants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-grid.variants.d.ts","sourceRoot":"","sources":["../../../src/components/data-grid/data-grid.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAkBlE,eAAO,MAAM,gBAAgB,oFAI3B,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAKzE,eAAO,MAAM,kBAAkB,sCAAsC,CAAC;AAOtE,eAAO,MAAM,sBAAsB,QAED,CAAC;AAqBnC,eAAO,MAAM,gBAAgB,QAKyB,CAAC;AAavD,eAAO,MAAM,oBAAoB;;;;;8EAsChC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMjF,eAAO,MAAM,4BAA4B;;8EAUxC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,YAAY,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAUjG,eAAO,MAAM,uBAAuB,QAO6D,CAAC;AAKlG,eAAO,MAAM,sBAAsB,2FACuD,CAAC;AAQ3F,eAAO,MAAM,0BAA0B,QAGU,CAAC;AAOlD,eAAO,MAAM,oBAAoB,QAIqB,CAAC;AAIvD,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAMvE,eAAO,MAAM,0BAA0B;;8EAoBtC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,YAAY,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAK7F,eAAO,MAAM,kBAAkB,wEACwC,CAAC;AAMxE,eAAO,MAAM,yBAAyB,YAAY,CAAC"}
1
+ {"version":3,"file":"data-grid.variants.d.ts","sourceRoot":"","sources":["../../../src/components/data-grid/data-grid.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAmBlE,eAAO,MAAM,gBAAgB,oFAI3B,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAKzE,eAAO,MAAM,kBAAkB,sCAAsC,CAAC;AAOtE,eAAO,MAAM,sBAAsB,QAED,CAAC;AAqBnC,eAAO,MAAM,gBAAgB,QAKyB,CAAC;AAavD,eAAO,MAAM,oBAAoB;;;;;8EAsChC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMjF,eAAO,MAAM,4BAA4B;;8EAUxC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,YAAY,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAUjG,eAAO,MAAM,uBAAuB,QAOzB,CAAC;AAKZ,eAAO,MAAM,sBAAsB,2FACuD,CAAC;AAQ3F,eAAO,MAAM,0BAA0B,QAGU,CAAC;AAOlD,eAAO,MAAM,oBAAoB,QAIqB,CAAC;AAIvD,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAMvE,eAAO,MAAM,0BAA0B;;8EAoBtC,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,YAAY,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAM7F,eAAO,MAAM,kBAAkB,4EAC4C,CAAC;AAM5E,eAAO,MAAM,yBAAyB,YAAY,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { cva } from "class-variance-authority";
2
+ import { focusRing } from "../../lib/focus-ring";
2
3
  const dataGridVariants = cva([
3
4
  "relative w-full overflow-auto",
4
5
  "bg-surface-canvas text-body text-text-primary",
@@ -17,7 +18,7 @@ const dataGridCellVariants = cva(
17
18
  [
18
19
  "px-(--space-3) align-middle text-start text-body text-text-primary",
19
20
  // the roving active cell's focus ring — always visible, never removed (2.4.7)
20
- "outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2",
21
+ focusRing,
21
22
  // keep the active cell clear of the sticky header + a pinned column before it takes focus (2.4.11)
22
23
  "scroll-mt-(--space-12) scroll-ms-(--space-12)"
23
24
  ],
@@ -38,10 +39,10 @@ const dataGridCellVariants = cva(
38
39
  none: "",
39
40
  // each status is the fg only, paired with the cell's text — the words carry the meaning,
40
41
  // the fg reinforces it (spec §3/§5); never a saturated -bg fill, never the brand
41
- verified: "text-status-verified-fg",
42
- signal: "text-status-signal-fg",
43
- caution: "text-status-caution-fg",
44
- critical: "text-status-critical-fg"
42
+ verified: "text-status-verified-on-surface",
43
+ signal: "text-status-signal-on-surface",
44
+ caution: "text-status-caution-on-surface",
45
+ critical: "text-status-critical-on-surface"
45
46
  }
46
47
  },
47
48
  defaultVariants: {
@@ -55,7 +56,7 @@ const dataGridCellVariants = cva(
55
56
  const dataGridColumnHeaderVariants = cva(
56
57
  [
57
58
  "px-(--space-3) align-middle text-start text-label text-text-secondary",
58
- "outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2",
59
+ focusRing,
59
60
  "scroll-mt-(--space-12) scroll-ms-(--space-12)"
60
61
  ],
61
62
  {
@@ -63,9 +64,9 @@ const dataGridColumnHeaderVariants = cva(
63
64
  defaultVariants: { density: "comfortable" }
64
65
  }
65
66
  );
66
- const dataGridSortButtonClass = "inline-flex items-center gap-(--space-1) -mx-(--space-1) px-(--space-1) rounded-(--radius-sm) text-label text-action-ghost-fg cursor-pointer select-none hover:bg-action-ghost-bg-hover transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) motion-reduce:duration-(--motion-duration-instant) min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop) outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2";
67
+ const dataGridSortButtonClass = "inline-flex items-center gap-(--space-1) -mx-(--space-1) px-(--space-1) rounded-(--radius-sm) text-label text-action-ghost-fg cursor-pointer select-none hover:bg-action-ghost-bg-hover transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) motion-reduce:duration-(--motion-duration-instant) min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop) " + focusRing;
67
68
  const dataGridSortCaretClass = "inline-flex h-(--size-icon-sm) w-(--size-icon-sm) shrink-0 items-center justify-center";
68
- const dataGridSelectionCellClass = "px-(--space-3) align-middle text-start outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 scroll-mt-(--space-12) scroll-ms-(--space-12)";
69
+ const dataGridSelectionCellClass = "px-(--space-3) align-middle text-start " + focusRing + " scroll-mt-(--space-12) scroll-ms-(--space-12)";
69
70
  const dataGridBulkBarClass = "flex items-center gap-(--space-3) px-(--space-3) py-(--space-2) bg-surface-raised border-t border-border-default transition-opacity duration-(--motion-duration-fast) ease-(--motion-easing-verdify) motion-reduce:duration-(--motion-duration-instant)";
70
71
  const dataGridBulkCountClass = "text-label text-text-secondary";
71
72
  const dataGridBulkActionVariants = cva(
@@ -75,7 +76,7 @@ const dataGridBulkActionVariants = cva(
75
76
  "min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop)",
76
77
  "transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)",
77
78
  "motion-reduce:duration-(--motion-duration-instant)",
78
- "outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2"
79
+ focusRing
79
80
  ],
80
81
  {
81
82
  variants: {
@@ -89,7 +90,7 @@ const dataGridBulkActionVariants = cva(
89
90
  defaultVariants: { destructive: false }
90
91
  }
91
92
  );
92
- const dataGridEmptyClass = "px-(--space-3) py-(--space-6) text-center text-body text-text-muted";
93
+ const dataGridEmptyClass = "px-(--space-3) py-(--space-6) text-center text-body text-text-secondary";
93
94
  const dataGridStatusRegionClass = "sr-only";
94
95
  export {
95
96
  dataGridBulkActionVariants,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/data-grid/data-grid.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// A DataGrid shows many rows of structured records in a scrollable, operable, two-dimensional grid\n// you navigate one cell at a time (spec §1). It is a NEUTRAL data surface (spec §1/§3): neutrals\n// carry roughly 90% of it, and a dense grid earns its legibility from restraint. It paints from the\n// surface, text, and border roles; it reaches the --color-action-* tier only for the controls it\n// hosts (the sortable-header ghost accent, the row-hover affordance, the bulk-bar actions, and the\n// NEUTRAL selection accent) and the --color-status-* tier ONLY inside a cell that reports a real\n// state, paired with text — never as a row tint, a header fill, or the selection accent, and NEVER\n// a brand token as a status (brand != state, G-U2). Selection and the active cell are NEUTRAL action\n// states; a verified/trust state is a status cell (spec §3/§4/§8).\n\n// The scroll container <div role=\"grid\"> (spec §2 grid / §5). The neutral canvas surface and the\n// default cell text role, framed by the outer surface border at the md radius, with a fixed-height\n// scroll viewport (the caller sizes it via className — the token set has no grid-height scale, the\n// caller-owned-dimension precedent J). It NEVER wears the brand violet or a status fill (spec §3/§8)\n// — those belong to the controls and the status cells inside it. The active cell is kept scrolled\n// clear of the sticky header and pinned columns by scroll-margin (2.4.11 Focus Not Obscured).\nexport const dataGridVariants = cva([\n \"relative w-full overflow-auto\",\n \"bg-surface-canvas text-body text-text-primary\",\n \"border border-surface-border rounded-(--radius-md)\",\n]);\n\nexport type DataGridVariantProps = VariantProps<typeof dataGridVariants>;\n\n// The inner table element. The grid is a real <table> for the row/column relationship (1.3.1),\n// border-collapsed so the gridlines read as single hairlines, and start-aligned so it mirrors under\n// dir=\"rtl\" (G-U6).\nexport const dataGridTableClass = \"w-full border-collapse text-start\";\n\n// The column-header row <tr> (spec §2 column-header-row / §4 Default / §5). It is STICKY — it stays\n// pinned to the top of the scroll viewport while rows scroll under it — on the raised neutral surface\n// with the sm elevation so it reads ABOVE the scrolling rows (spec §4/§5). z on the sticky layer so a\n// scrolled cell never paints over the pinned header. A header row NEVER wears a status or brand tint\n// (spec §3/§8).\nexport const dataGridHeaderRowClass =\n \"sticky top-0 z-(--z-index-sticky) bg-surface-raised shadow-sm \" +\n \"border-b border-border-default\";\n\n// The shared cell padding by density (spec §3 density / §5 --space-*). Density tightens the VERTICAL\n// padding only, ABOVE the a11y floor — any in-cell control keeps its own --size-target-* floor\n// (DEC-B: never a fixed height below the floor). Horizontal inline padding is constant.\nconst cellPaddingVariants = {\n density: {\n comfortable: \"py-(--space-3)\",\n compact: \"py-(--space-1)\",\n },\n} as const;\n\n// A data row <tr> (spec §4 Default/Hover/Selected). RESTING: no fill, on the canvas. HOVER: a\n// restrained GHOST fill to track the eye across a wide row — an AFFORDANCE, never the sole carrier of\n// meaning, and never a selection (nothing is selected until you act, spec §4 Hover). SELECTED\n// (aria-selected): the NEUTRAL secondary-action selection accent — selection is a neutral action\n// state, NOT verified green and NOT the brand violet (selecting a row never implies it is verified;\n// brand != state, G-U2, spec §4/§8). Selection is encoded by the row checkbox + aria-selected, so a\n// grayscale reader reads it from the checkbox, not the fill (1.4.1). Motion is the fast token\n// transition on the verdify easing, instant under reduced motion — never the 350ms VerifiedBadge-only\n// theatre (a row hover/select is a plain transition, G-U3).\nexport const dataGridRowClass =\n \"border-b border-border-default \" +\n \"hover:bg-action-ghost-bg-hover \" +\n \"aria-selected:bg-action-secondary-bg-hover \" +\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant)\";\n\n// A data cell <td role=\"gridcell\"> (spec §2 cell, §4/§5). It is ONE focusable unit in the roving\n// grid: exactly one cell is the active cell (tabindex=0) and shows the visible 2px focus ring; every\n// other cell is tabindex=-1. The ring is part of the base and is NEVER removed (spec §4 Focus /\n// 2.4.7). scroll-margin keeps the active cell clear of the sticky header + pinned columns before it\n// takes focus (spec §7, 2.4.11 Focus Not Obscured). Default: the primary text color at the body type\n// role. A `mono` cell takes the monospace role and is isolated LTR so an identifier/key/timestamp\n// stays readable inside an RTL layout (spec §3/§5, G-U6). A `secondary` cell is de-emphasized\n// auxiliary text. A `status` cell carries the status fg paired with the cell's words — the status\n// color lives in the CELL only, never the row or header (spec §3), and NEVER a brand token (brand !=\n// state, G-U2); status-*-bg is the one neutral raised surface, so meaning is carried by the fg + the\n// text, not a saturated fill.\nexport const dataGridCellVariants = cva(\n [\n \"px-(--space-3) align-middle text-start text-body text-text-primary\",\n // the roving active cell's focus ring — always visible, never removed (2.4.7)\n \"outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\",\n // keep the active cell clear of the sticky header + a pinned column before it takes focus (2.4.11)\n \"scroll-mt-(--space-12) scroll-ms-(--space-12)\",\n ],\n {\n variants: {\n ...cellPaddingVariants,\n mono: {\n // identifier/key/timestamp: the monospace role, isolated LTR inside RTL text (G-U6)\n true: \"text-mono [direction:ltr]\",\n false: \"\",\n },\n secondary: {\n // de-emphasized secondary cell text (spec §5 --color-text-secondary)\n true: \"text-text-secondary\",\n false: \"\",\n },\n status: {\n none: \"\",\n // each status is the fg only, paired with the cell's text — the words carry the meaning,\n // the fg reinforces it (spec §3/§5); never a saturated -bg fill, never the brand\n verified: \"text-status-verified-fg\",\n signal: \"text-status-signal-fg\",\n caution: \"text-status-caution-fg\",\n critical: \"text-status-critical-fg\",\n },\n },\n defaultVariants: {\n density: \"comfortable\",\n mono: false,\n secondary: false,\n status: \"none\",\n },\n },\n);\n\nexport type DataGridCellVariantProps = VariantProps<typeof dataGridCellVariants>;\n\n// A column-header cell <th role=\"columnheader\"> (spec §2 column-header / §4/§5). The header LABEL is\n// the SECONDARY text color at the label type role (the quiet, tracked column label) on the raised\n// header surface — a header NEVER wears a status or brand tint (spec §3/§8). It is also a roving\n// active-cell target, so it carries the same focus ring + scroll-margin as a data cell.\nexport const dataGridColumnHeaderVariants = cva(\n [\n \"px-(--space-3) align-middle text-start text-label text-text-secondary\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\",\n \"scroll-mt-(--space-12) scroll-ms-(--space-12)\",\n ],\n {\n variants: { ...cellPaddingVariants },\n defaultVariants: { density: \"comfortable\" },\n },\n);\n\nexport type DataGridColumnHeaderVariantProps = VariantProps<typeof dataGridColumnHeaderVariants>;\n\n// The SORTABLE-header control (spec §2/§4 Sorted/§6/§7): a real <button> inside the columnheader, so\n// it reads as the control it is and toggles the sort on Enter. It is the GHOST action accent — the\n// label + caret in the ghost fg with the restrained ghost hover fill (spec §4 sortable-header hover /\n// §5) — the action tier is legitimate here because it is a control the grid HOSTS, not a header tint.\n// It carries the target-size floor (40px desktop / 44px touch, spec §7) and inherits the active\n// cell's focus ring from the columnheader. Motion is the fast token transition, never the deliberate\n// verified-check theatre (G-U3). aria-sort lives on the parent th, and the caret encodes direction\n// alongside it so it never rests on color alone (spec §4 Sorted / 1.4.1).\nexport const dataGridSortButtonClass =\n \"inline-flex items-center gap-(--space-1) -mx-(--space-1) px-(--space-1) rounded-(--radius-sm) \" +\n \"text-label text-action-ghost-fg cursor-pointer select-none \" +\n \"hover:bg-action-ghost-bg-hover \" +\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant) \" +\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop) \" +\n \"outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\";\n\n// The sort-direction caret (spec §4 Sorted / §5): the sm icon role, decorative (the direction is also\n// encoded by aria-sort on the th + the glyph's shape via data-direction, so it never rests on color\n// alone — 1.4.1). It inherits the ghost accent color from the button.\nexport const dataGridSortCaretClass =\n \"inline-flex h-(--size-icon-sm) w-(--size-icon-sm) shrink-0 items-center justify-center\";\n\n// The selection cell <td role=\"gridcell\"> and the select-all header cell (spec §2 selection-cell /\n// §5): the leading cell that holds the row's Checkbox, carrying the active-cell focus ring +\n// scroll-margin like any other cell. The checkbox is the committed Checkbox component (reused, not\n// re-rolled), which already binds the control surface + border tokens (spec §5) and the brand action\n// accent on the CHECKED box — a checked checkbox is the brand accent, never status-verified (G-U2):\n// selection is a neutral action state. This wrapper is just the cell padding + the roving focus ring.\nexport const dataGridSelectionCellClass =\n \"px-(--space-3) align-middle text-start \" +\n \"outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 \" +\n \"scroll-mt-(--space-12) scroll-ms-(--space-12)\";\n\n// The bulk-action bar (spec §2 bulk-action-bar / §4/§5): a toolbar that appears when rows are\n// selected, on the raised neutral surface with the sm elevation and a hairline top border, holding\n// the selection actions + a clear-selection control. It is a NEUTRAL surface — the COLOR lives on the\n// action buttons it holds, never on the bar (spec §3/§8). Motion is the fast token transition (the\n// bar's appear/transition), never the deliberate verified-check theatre (G-U3).\nexport const dataGridBulkBarClass =\n \"flex items-center gap-(--space-3) px-(--space-3) py-(--space-2) \" +\n \"bg-surface-raised border-t border-border-default \" +\n \"transition-opacity duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant)\";\n\n// The selected-count label in the bulk-action bar (spec §2): the secondary text at the label role —\n// the count of selected rows, in words, so selection is announced, never color alone (1.4.1 / 4.1.3).\nexport const dataGridBulkCountClass = \"text-label text-text-secondary\";\n\n// A bulk-action button (spec §2/§5): the PRIMARY selection action is the primary ACTION accent; a\n// `destructive` action (for example, revoke a key) is the destructive ACTION accent — a risk signal\n// named in TEXT, never a status color (spec §5/§8). Both carry the visible focus ring + target-size\n// floor. Motion is the fast token transition, never the deliberate verified-check theatre (G-U3).\nexport const dataGridBulkActionVariants = cva(\n [\n \"inline-flex items-center justify-center gap-(--space-1) rounded-(--radius-md) px-(--space-3)\",\n \"text-label font-medium cursor-pointer\",\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop)\",\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\",\n ],\n {\n variants: {\n destructive: {\n // a destructive bulk action — a risk signal in the ACTION tier, NEVER a status token\n true: \"bg-action-destructive-bg text-action-destructive-fg border border-action-destructive-border\",\n // the default bulk action — the primary action accent\n false: \"bg-action-primary-bg text-action-primary-fg border border-action-primary-border hover:bg-action-primary-bg-hover\",\n },\n },\n defaultVariants: { destructive: false },\n },\n);\n\nexport type DataGridBulkActionVariantProps = VariantProps<typeof dataGridBulkActionVariants>;\n\n// The empty-state cell (spec §2/§4 Empty): a plain line spanning the full grid width, in the muted\n// text color — an empty grid is NOT an error and never reads as one (no status color). Its copy says\n// why it is empty and what to do next, in plain words ending in a period (spec §4 Empty / voice).\nexport const dataGridEmptyClass =\n \"px-(--space-3) py-(--space-6) text-center text-body text-text-muted\";\n\n// The off-screen-capable live region (spec §2 status-region / §7 4.1.3): announces the resolved row\n// count, sort + filter changes, and the selection count politely; a blocking row-load error\n// assertively. Always sr-only (it never paints — the visual state carries the same information for\n// sighted users), so it reaches assistive tech as TEXT, never color alone (1.4.1 / 4.1.3).\nexport const dataGridStatusRegionClass = \"sr-only\";\n"],"mappings":"AAAA,SAAS,WAA8B;AAkBhC,MAAM,mBAAmB,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOM,MAAM,qBAAqB;AAO3B,MAAM,yBACX;AAMF,MAAM,sBAAsB;AAAA,EAC1B,SAAS;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAWO,MAAM,mBACX;AAiBK,MAAM,uBAAuB;AAAA,EAClC;AAAA,IACE;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,GAAG;AAAA,MACH,MAAM;AAAA;AAAA,QAEJ,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,WAAW;AAAA;AAAA,QAET,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA;AAAA;AAAA,QAGN,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAQO,MAAM,+BAA+B;AAAA,EAC1C;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU,EAAE,GAAG,oBAAoB;AAAA,IACnC,iBAAiB,EAAE,SAAS,cAAc;AAAA,EAC5C;AACF;AAYO,MAAM,0BACX;AAWK,MAAM,yBACX;AAQK,MAAM,6BACX;AASK,MAAM,uBACX;AAOK,MAAM,yBAAyB;AAM/B,MAAM,6BAA6B;AAAA,EACxC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,aAAa;AAAA;AAAA,QAEX,MAAM;AAAA;AAAA,QAEN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,aAAa,MAAM;AAAA,EACxC;AACF;AAOO,MAAM,qBACX;AAMK,MAAM,4BAA4B;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/data-grid/data-grid.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport { focusRing } from \"../../lib/focus-ring\";\n\n// A DataGrid shows many rows of structured records in a scrollable, operable, two-dimensional grid\n// you navigate one cell at a time (spec §1). It is a NEUTRAL data surface (spec §1/§3): neutrals\n// carry roughly 90% of it, and a dense grid earns its legibility from restraint. It paints from the\n// surface, text, and border roles; it reaches the --color-action-* tier only for the controls it\n// hosts (the sortable-header ghost accent, the row-hover affordance, the bulk-bar actions, and the\n// NEUTRAL selection accent) and the --color-status-* tier ONLY inside a cell that reports a real\n// state, paired with text — never as a row tint, a header fill, or the selection accent, and NEVER\n// a brand token as a status (brand != state, G-U2). Selection and the active cell are NEUTRAL action\n// states; a verified/trust state is a status cell (spec §3/§4/§8).\n\n// The scroll container <div role=\"grid\"> (spec §2 grid / §5). The neutral canvas surface and the\n// default cell text role, framed by the outer surface border at the md radius, with a fixed-height\n// scroll viewport (the caller sizes it via className — the token set has no grid-height scale, the\n// caller-owned-dimension precedent J). It NEVER wears the brand violet or a status fill (spec §3/§8)\n// — those belong to the controls and the status cells inside it. The active cell is kept scrolled\n// clear of the sticky header and pinned columns by scroll-margin (2.4.11 Focus Not Obscured).\nexport const dataGridVariants = cva([\n \"relative w-full overflow-auto\",\n \"bg-surface-canvas text-body text-text-primary\",\n \"border border-surface-border rounded-(--radius-md)\",\n]);\n\nexport type DataGridVariantProps = VariantProps<typeof dataGridVariants>;\n\n// The inner table element. The grid is a real <table> for the row/column relationship (1.3.1),\n// border-collapsed so the gridlines read as single hairlines, and start-aligned so it mirrors under\n// dir=\"rtl\" (G-U6).\nexport const dataGridTableClass = \"w-full border-collapse text-start\";\n\n// The column-header row <tr> (spec §2 column-header-row / §4 Default / §5). It is STICKY — it stays\n// pinned to the top of the scroll viewport while rows scroll under it — on the raised neutral surface\n// with the sm elevation so it reads ABOVE the scrolling rows (spec §4/§5). z on the sticky layer so a\n// scrolled cell never paints over the pinned header. A header row NEVER wears a status or brand tint\n// (spec §3/§8).\nexport const dataGridHeaderRowClass =\n \"sticky top-0 z-(--z-index-sticky) bg-surface-raised shadow-sm \" +\n \"border-b border-border-default\";\n\n// The shared cell padding by density (spec §3 density / §5 --space-*). Density tightens the VERTICAL\n// padding only, ABOVE the a11y floor — any in-cell control keeps its own --size-target-* floor\n// (DEC-B: never a fixed height below the floor). Horizontal inline padding is constant.\nconst cellPaddingVariants = {\n density: {\n comfortable: \"py-(--space-3)\",\n compact: \"py-(--space-1)\",\n },\n} as const;\n\n// A data row <tr> (spec §4 Default/Hover/Selected). RESTING: no fill, on the canvas. HOVER: a\n// restrained GHOST fill to track the eye across a wide row — an AFFORDANCE, never the sole carrier of\n// meaning, and never a selection (nothing is selected until you act, spec §4 Hover). SELECTED\n// (aria-selected): the NEUTRAL secondary-action selection accent — selection is a neutral action\n// state, NOT verified green and NOT the brand violet (selecting a row never implies it is verified;\n// brand != state, G-U2, spec §4/§8). Selection is encoded by the row checkbox + aria-selected, so a\n// grayscale reader reads it from the checkbox, not the fill (1.4.1). Motion is the fast token\n// transition on the verdify easing, instant under reduced motion — never the 350ms VerifiedBadge-only\n// theatre (a row hover/select is a plain transition, G-U3).\nexport const dataGridRowClass =\n \"border-b border-border-default \" +\n \"hover:bg-action-ghost-bg-hover \" +\n \"aria-selected:bg-action-secondary-bg-hover \" +\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant)\";\n\n// A data cell <td role=\"gridcell\"> (spec §2 cell, §4/§5). It is ONE focusable unit in the roving\n// grid: exactly one cell is the active cell (tabindex=0) and shows the visible 2px focus ring; every\n// other cell is tabindex=-1. The ring is part of the base and is NEVER removed (spec §4 Focus /\n// 2.4.7). scroll-margin keeps the active cell clear of the sticky header + pinned columns before it\n// takes focus (spec §7, 2.4.11 Focus Not Obscured). Default: the primary text color at the body type\n// role. A `mono` cell takes the monospace role and is isolated LTR so an identifier/key/timestamp\n// stays readable inside an RTL layout (spec §3/§5, G-U6). A `secondary` cell is de-emphasized\n// auxiliary text. A `status` cell carries the status fg paired with the cell's words — the status\n// color lives in the CELL only, never the row or header (spec §3), and NEVER a brand token (brand !=\n// state, G-U2); status-*-bg is the one neutral raised surface, so meaning is carried by the fg + the\n// text, not a saturated fill.\nexport const dataGridCellVariants = cva(\n [\n \"px-(--space-3) align-middle text-start text-body text-text-primary\",\n // the roving active cell's focus ring — always visible, never removed (2.4.7)\n focusRing,\n // keep the active cell clear of the sticky header + a pinned column before it takes focus (2.4.11)\n \"scroll-mt-(--space-12) scroll-ms-(--space-12)\",\n ],\n {\n variants: {\n ...cellPaddingVariants,\n mono: {\n // identifier/key/timestamp: the monospace role, isolated LTR inside RTL text (G-U6)\n true: \"text-mono [direction:ltr]\",\n false: \"\",\n },\n secondary: {\n // de-emphasized secondary cell text (spec §5 --color-text-secondary)\n true: \"text-text-secondary\",\n false: \"\",\n },\n status: {\n none: \"\",\n // each status is the fg only, paired with the cell's text — the words carry the meaning,\n // the fg reinforces it (spec §3/§5); never a saturated -bg fill, never the brand\n verified: \"text-status-verified-on-surface\",\n signal: \"text-status-signal-on-surface\",\n caution: \"text-status-caution-on-surface\",\n critical: \"text-status-critical-on-surface\",\n },\n },\n defaultVariants: {\n density: \"comfortable\",\n mono: false,\n secondary: false,\n status: \"none\",\n },\n },\n);\n\nexport type DataGridCellVariantProps = VariantProps<typeof dataGridCellVariants>;\n\n// A column-header cell <th role=\"columnheader\"> (spec §2 column-header / §4/§5). The header LABEL is\n// the SECONDARY text color at the label type role (the quiet, tracked column label) on the raised\n// header surface — a header NEVER wears a status or brand tint (spec §3/§8). It is also a roving\n// active-cell target, so it carries the same focus ring + scroll-margin as a data cell.\nexport const dataGridColumnHeaderVariants = cva(\n [\n \"px-(--space-3) align-middle text-start text-label text-text-secondary\",\n focusRing,\n \"scroll-mt-(--space-12) scroll-ms-(--space-12)\",\n ],\n {\n variants: { ...cellPaddingVariants },\n defaultVariants: { density: \"comfortable\" },\n },\n);\n\nexport type DataGridColumnHeaderVariantProps = VariantProps<typeof dataGridColumnHeaderVariants>;\n\n// The SORTABLE-header control (spec §2/§4 Sorted/§6/§7): a real <button> inside the columnheader, so\n// it reads as the control it is and toggles the sort on Enter. It is the GHOST action accent — the\n// label + caret in the ghost fg with the restrained ghost hover fill (spec §4 sortable-header hover /\n// §5) — the action tier is legitimate here because it is a control the grid HOSTS, not a header tint.\n// It carries the target-size floor (40px desktop / 44px touch, spec §7) and inherits the active\n// cell's focus ring from the columnheader. Motion is the fast token transition, never the deliberate\n// verified-check theatre (G-U3). aria-sort lives on the parent th, and the caret encodes direction\n// alongside it so it never rests on color alone (spec §4 Sorted / 1.4.1).\nexport const dataGridSortButtonClass =\n \"inline-flex items-center gap-(--space-1) -mx-(--space-1) px-(--space-1) rounded-(--radius-sm) \" +\n \"text-label text-action-ghost-fg cursor-pointer select-none \" +\n \"hover:bg-action-ghost-bg-hover \" +\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant) \" +\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop) \" +\n focusRing;\n\n// The sort-direction caret (spec §4 Sorted / §5): the sm icon role, decorative (the direction is also\n// encoded by aria-sort on the th + the glyph's shape via data-direction, so it never rests on color\n// alone — 1.4.1). It inherits the ghost accent color from the button.\nexport const dataGridSortCaretClass =\n \"inline-flex h-(--size-icon-sm) w-(--size-icon-sm) shrink-0 items-center justify-center\";\n\n// The selection cell <td role=\"gridcell\"> and the select-all header cell (spec §2 selection-cell /\n// §5): the leading cell that holds the row's Checkbox, carrying the active-cell focus ring +\n// scroll-margin like any other cell. The checkbox is the committed Checkbox component (reused, not\n// re-rolled), which already binds the control surface + border tokens (spec §5) and the brand action\n// accent on the CHECKED box — a checked checkbox is the brand accent, never status-verified (G-U2):\n// selection is a neutral action state. This wrapper is just the cell padding + the roving focus ring.\nexport const dataGridSelectionCellClass =\n \"px-(--space-3) align-middle text-start \" +\n focusRing + \" \" +\n \"scroll-mt-(--space-12) scroll-ms-(--space-12)\";\n\n// The bulk-action bar (spec §2 bulk-action-bar / §4/§5): a toolbar that appears when rows are\n// selected, on the raised neutral surface with the sm elevation and a hairline top border, holding\n// the selection actions + a clear-selection control. It is a NEUTRAL surface — the COLOR lives on the\n// action buttons it holds, never on the bar (spec §3/§8). Motion is the fast token transition (the\n// bar's appear/transition), never the deliberate verified-check theatre (G-U3).\nexport const dataGridBulkBarClass =\n \"flex items-center gap-(--space-3) px-(--space-3) py-(--space-2) \" +\n \"bg-surface-raised border-t border-border-default \" +\n \"transition-opacity duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant)\";\n\n// The selected-count label in the bulk-action bar (spec §2): the secondary text at the label role —\n// the count of selected rows, in words, so selection is announced, never color alone (1.4.1 / 4.1.3).\nexport const dataGridBulkCountClass = \"text-label text-text-secondary\";\n\n// A bulk-action button (spec §2/§5): the PRIMARY selection action is the primary ACTION accent; a\n// `destructive` action (for example, revoke a key) is the destructive ACTION accent — a risk signal\n// named in TEXT, never a status color (spec §5/§8). Both carry the visible focus ring + target-size\n// floor. Motion is the fast token transition, never the deliberate verified-check theatre (G-U3).\nexport const dataGridBulkActionVariants = cva(\n [\n \"inline-flex items-center justify-center gap-(--space-1) rounded-(--radius-md) px-(--space-3)\",\n \"text-label font-medium cursor-pointer\",\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop)\",\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n focusRing,\n ],\n {\n variants: {\n destructive: {\n // a destructive bulk action — a risk signal in the ACTION tier, NEVER a status token\n true: \"bg-action-destructive-bg text-action-destructive-fg border border-action-destructive-border\",\n // the default bulk action — the primary action accent\n false: \"bg-action-primary-bg text-action-primary-fg border border-action-primary-border hover:bg-action-primary-bg-hover\",\n },\n },\n defaultVariants: { destructive: false },\n },\n);\n\nexport type DataGridBulkActionVariantProps = VariantProps<typeof dataGridBulkActionVariants>;\n\n// The empty-state cell (spec §2/§4 Empty): a plain line spanning the full grid width — an empty grid\n// is NOT an error and never reads as one (no status color). Its copy says why it is empty and what to\n// do next (spec §4 Empty / voice). Essential text, so it uses the SECONDARY text color (AA), not the\n// decorative-only muted role (accessibility.md).\nexport const dataGridEmptyClass =\n \"px-(--space-3) py-(--space-6) text-center text-body text-text-secondary\";\n\n// The off-screen-capable live region (spec §2 status-region / §7 4.1.3): announces the resolved row\n// count, sort + filter changes, and the selection count politely; a blocking row-load error\n// assertively. Always sr-only (it never paints — the visual state carries the same information for\n// sighted users), so it reaches assistive tech as TEXT, never color alone (1.4.1 / 4.1.3).\nexport const dataGridStatusRegionClass = \"sr-only\";\n"],"mappings":"AAAA,SAAS,WAA8B;AACvC,SAAS,iBAAiB;AAkBnB,MAAM,mBAAmB,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOM,MAAM,qBAAqB;AAO3B,MAAM,yBACX;AAMF,MAAM,sBAAsB;AAAA,EAC1B,SAAS;AAAA,IACP,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAWO,MAAM,mBACX;AAiBK,MAAM,uBAAuB;AAAA,EAClC;AAAA,IACE;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,GAAG;AAAA,MACH,MAAM;AAAA;AAAA,QAEJ,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,WAAW;AAAA;AAAA,QAET,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA;AAAA;AAAA,QAGN,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAQO,MAAM,+BAA+B;AAAA,EAC1C;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU,EAAE,GAAG,oBAAoB;AAAA,IACnC,iBAAiB,EAAE,SAAS,cAAc;AAAA,EAC5C;AACF;AAYO,MAAM,0BACX,iYAMA;AAKK,MAAM,yBACX;AAQK,MAAM,6BACX,4CACA,YAAY;AAQP,MAAM,uBACX;AAOK,MAAM,yBAAyB;AAM/B,MAAM,6BAA6B;AAAA,EACxC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,aAAa;AAAA;AAAA,QAEX,MAAM;AAAA;AAAA,QAEN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,aAAa,MAAM;AAAA,EACxC;AACF;AAQO,MAAM,qBACX;AAMK,MAAM,4BAA4B;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.variants.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/dialog.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAgBlE,eAAO,MAAM,mBAAmB,oFAK9B,CAAC;AAcH,eAAO,MAAM,mBAAmB;;8EA+B/B,CAAC;AAIF,eAAO,MAAM,iBAAiB,mGACoE,CAAC;AAInG,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAI5D,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAKtE,eAAO,MAAM,eAAe,iEACoC,CAAC;AAMjE,eAAO,MAAM,iBAAiB,gGACiE,CAAC;AAOhG,eAAO,MAAM,mBAAmB,oFAa9B,CAAC;AAIH,eAAO,MAAM,qBAAqB,0CAA0C,CAAC;AAE7E,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"dialog.variants.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/dialog.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAiBlE,eAAO,MAAM,mBAAmB,oFAK9B,CAAC;AAcH,eAAO,MAAM,mBAAmB;;8EA+B/B,CAAC;AAIF,eAAO,MAAM,iBAAiB,mGACoE,CAAC;AAInG,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAI5D,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAKtE,eAAO,MAAM,eAAe,iEACoC,CAAC;AAMjE,eAAO,MAAM,iBAAiB,gGACiE,CAAC;AAOhG,eAAO,MAAM,mBAAmB,oFAa9B,CAAC;AAIH,eAAO,MAAM,qBAAqB,0CAA0C,CAAC;AAE7E,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { cva } from "class-variance-authority";
2
+ import { focusRing } from "../../lib/focus-ring";
2
3
  const dialogScrimVariants = cva([
3
4
  "fixed inset-0 z-(--z-index-modal) bg-scrim-dark",
4
5
  "transition-opacity duration-(--motion-duration-base) ease-(--motion-easing-verdify)",
@@ -23,7 +24,7 @@ const dialogPanelVariants = cva(
23
24
  "data-[state=open]:scale-100 data-[state=closed]:scale-95",
24
25
  // the panel takes focus when there is no obvious first control; its ring is never removed
25
26
  "outline-none",
26
- "focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2"
27
+ focusRing
27
28
  ],
28
29
  {
29
30
  variants: {
@@ -54,7 +55,7 @@ const dialogCloseVariants = cva([
54
55
  "sm:min-h-(--size-target-desktop) sm:min-w-(--size-target-desktop)",
55
56
  // visible 2px focus ring at 2px offset; never removed
56
57
  "outline-none",
57
- "focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2"
58
+ focusRing
58
59
  ]);
59
60
  const dialogCloseGlyphClass = "h-(--size-icon-md) w-(--size-icon-md)";
60
61
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/dialog/dialog.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// Dialog is a NEUTRAL overlay surface (spec §1/§3/§5/§8): brand violet and Verified Green are\n// accents, neutrals carry the surface. The PANEL and the SCRIM are neutral; Sovereign Violet\n// appears only on a footer PRIMARY action — through Button, not here — and Verified Green never\n// appears on the dialog as decoration. A destructive confirm uses the destructive ACTION\n// treatment on its confirm button (Button), never a red panel. So NOTHING in this file binds an\n// --color-action-primary-* or --color-status-* fill (brand != state, G-U2). This is the ONLY\n// token-binding site (skill §5 hard rule).\n\n// The scrim: the dimming layer behind the panel that separates the dialog from the page and\n// absorbs outside clicks (spec §2 scrim, §5 --color-scrim-*). It is a neutral dim on the modal\n// z-layer, decorative (no role). The fade is a PLAIN base transition + verdify easing, instant\n// under reduced motion — never the 350ms VerifiedBadge-only theatre (G-U3 motion-theatre gate).\n// Enter/exit ride Radix's data-state on the overlay (attribute-selector variants, not arbitrary\n// values). On a light surface the dark scrim token applies (spec §5: scrim-dark on light).\nexport const dialogScrimVariants = cva([\n \"fixed inset-0 z-(--z-index-modal) bg-scrim-dark\",\n \"transition-opacity duration-(--motion-duration-base) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n \"data-[state=open]:opacity-100 data-[state=closed]:opacity-0\",\n]);\n\n// The panel: the raised container holding the dialog content; it takes role=dialog + the focus\n// trap (Radix). A NEUTRAL raised surface (--color-surface-raised) with the outer surface border,\n// the lg corner radius, the lg elevation shadow above the scrim, centered on the modal z-layer.\n// It never exceeds the viewport and scrolls its BODY when content overflows (spec §3) — the\n// panel caps its own height to the viewport less the gutter; the DialogBody owns the scroll. The\n// open/close transition is the BASE duration + verdify easing, instant under reduced motion, and\n// rides Radix's data-state (attribute-selector enter/exit, not arbitrary values). NEVER the\n// deliberate verified-check theatre (G-U3). Panel padding/gaps come from --space-*.\n//\n// size = the panel's MAX WIDTH only (spec §3 sm/md/lg, md default), bound to the --container-*\n// scale; the panel is full-width up to that cap and centered. There is no fixed height — the\n// height emerges from the content up to the viewport cap.\nexport const dialogPanelVariants = cva(\n [\n // centered on the modal layer; full available width up to the size cap, with side gutters\n \"fixed left-1/2 top-1/2 z-(--z-index-modal) -translate-x-1/2 -translate-y-1/2\",\n \"flex w-[calc(100%-var(--space-8))] flex-col gap-(--space-4)\",\n // never taller than the viewport less the gutter; the body scrolls within (spec §3)\n \"max-h-[calc(100dvh-var(--space-8))]\",\n // neutral raised surface + outer border + lg radius + lg elevation; panel inset padding\n \"bg-surface-raised border border-surface-border rounded-(--radius-lg) shadow-(--shadow-lg)\",\n \"p-(--space-6)\",\n // base open/close transition + verdify easing, instant under reduced motion (NEVER deliberate)\n \"transition-[opacity,transform] duration-(--motion-duration-base) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n // enter/exit ride Radix data-state — attribute-selector variants, not arbitrary values\n \"data-[state=open]:opacity-100 data-[state=closed]:opacity-0\",\n \"data-[state=open]:scale-100 data-[state=closed]:scale-95\",\n // the panel takes focus when there is no obvious first control; its ring is never removed\n \"outline-none\",\n \"focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\",\n ],\n {\n variants: {\n // size = max width only (spec §3). md is the default. Bound to the --container-* scale.\n size: {\n sm: \"max-w-(--container-sm)\",\n md: \"max-w-(--container-md)\",\n lg: \"max-w-(--container-lg)\",\n },\n },\n defaultVariants: { size: \"md\" },\n },\n);\n\n// The header: the top region holding the title and the optional close button on the inline-end.\n// Logical-property layout (G-U6); a neutral hairline divider under it continues the surface.\nexport const dialogHeaderClass =\n \"flex items-start justify-between gap-(--space-4) border-b border-border-default pb-(--space-4)\";\n\n// The title: names the dialog in one short statement; it is the accessible name (Radix wires\n// aria-labelledby). The h2 type role in primary text (spec §5 --text-h2 / --color-text-primary).\nexport const dialogTitleClass = \"text-h2 text-text-primary\";\n\n// The description: optional supporting text under the title, associated with the panel for\n// screen readers (Radix wires aria-describedby). Body type role in secondary text (spec §5).\nexport const dialogDescriptionClass = \"text-body text-text-secondary\";\n\n// The body: the scrollable content region between header and footer. The panel caps its height\n// to the viewport; the body takes the remaining space and scrolls when content overflows (spec\n// §3). Body text is the body type role in secondary text (spec §5 --text-body / text-secondary).\nexport const dialogBodyClass =\n \"min-h-0 flex-1 overflow-y-auto text-body text-text-secondary\";\n\n// The footer: the action region holding the primary and any secondary/cancel action, aligned to\n// the inline-end with a neutral hairline divider above it. The actions themselves are Buttons —\n// the dialog spec does not restate their --color-action-* bindings (spec §5 note). Logical-\n// property layout (G-U6): actions flow inline-end with a gap.\nexport const dialogFooterClass =\n \"flex items-center justify-end gap-(--space-2) border-t border-border-default pt-(--space-4)\";\n\n// The close button: the dismiss control in the header. A NEUTRAL ghost surface — the glyph in\n// --color-action-ghost-fg at rest, the restrained ghost hover fill (spec §5 ghost-fg /\n// ghost-bg-hover), the md radius, the persistent focus ring, the target-size floor (44px touch /\n// 40px pointer, spec §7 2.5.8 / DEC-B) with the height EMERGING from the floor, never fixed\n// below it. fast functional hover motion + verdify easing, instant under reduced motion (G-U3).\nexport const dialogCloseVariants = cva([\n \"inline-flex items-center justify-center rounded-(--radius-md)\",\n // neutral ghost surface: glyph color at rest + restrained hover fill (no bg/border at rest)\n \"text-action-ghost-fg hover:bg-action-ghost-bg-hover\",\n // fast functional hover transition + verdify easing, instant under reduced motion (NEVER deliberate)\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n // target-size floor: 44px touch / 40px pointer; the close button is square at the floor (DEC-B)\n \"min-h-(--size-target-mobile) min-w-(--size-target-mobile)\",\n \"sm:min-h-(--size-target-desktop) sm:min-w-(--size-target-desktop)\",\n // visible 2px focus ring at 2px offset; never removed\n \"outline-none\",\n \"focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\",\n]);\n\n// The close glyph: a neutral X, --size-icon-md, drawn with currentColor so it inherits the\n// button's ghost-fg. Decorative (aria-hidden) — the button carries the accessible name (spec §7).\nexport const dialogCloseGlyphClass = \"h-(--size-icon-md) w-(--size-icon-md)\";\n\nexport type DialogPanelVariantProps = VariantProps<typeof dialogPanelVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAgBhC,MAAM,sBAAsB,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAcM,MAAM,sBAAsB;AAAA,EACjC;AAAA;AAAA,IAEE;AAAA,IACA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA,MAER,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,MAAM,KAAK;AAAA,EAChC;AACF;AAIO,MAAM,oBACX;AAIK,MAAM,mBAAmB;AAIzB,MAAM,yBAAyB;AAK/B,MAAM,kBACX;AAMK,MAAM,oBACX;AAOK,MAAM,sBAAsB,IAAI;AAAA,EACrC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AACF,CAAC;AAIM,MAAM,wBAAwB;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/dialog/dialog.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport { focusRing } from \"../../lib/focus-ring\";\n\n// Dialog is a NEUTRAL overlay surface (spec §1/§3/§5/§8): brand violet and Verified Green are\n// accents, neutrals carry the surface. The PANEL and the SCRIM are neutral; Sovereign Violet\n// appears only on a footer PRIMARY action — through Button, not here — and Verified Green never\n// appears on the dialog as decoration. A destructive confirm uses the destructive ACTION\n// treatment on its confirm button (Button), never a red panel. So NOTHING in this file binds an\n// --color-action-primary-* or --color-status-* fill (brand != state, G-U2). This is the ONLY\n// token-binding site (skill §5 hard rule).\n\n// The scrim: the dimming layer behind the panel that separates the dialog from the page and\n// absorbs outside clicks (spec §2 scrim, §5 --color-scrim-*). It is a neutral dim on the modal\n// z-layer, decorative (no role). The fade is a PLAIN base transition + verdify easing, instant\n// under reduced motion — never the 350ms VerifiedBadge-only theatre (G-U3 motion-theatre gate).\n// Enter/exit ride Radix's data-state on the overlay (attribute-selector variants, not arbitrary\n// values). On a light surface the dark scrim token applies (spec §5: scrim-dark on light).\nexport const dialogScrimVariants = cva([\n \"fixed inset-0 z-(--z-index-modal) bg-scrim-dark\",\n \"transition-opacity duration-(--motion-duration-base) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n \"data-[state=open]:opacity-100 data-[state=closed]:opacity-0\",\n]);\n\n// The panel: the raised container holding the dialog content; it takes role=dialog + the focus\n// trap (Radix). A NEUTRAL raised surface (--color-surface-raised) with the outer surface border,\n// the lg corner radius, the lg elevation shadow above the scrim, centered on the modal z-layer.\n// It never exceeds the viewport and scrolls its BODY when content overflows (spec §3) — the\n// panel caps its own height to the viewport less the gutter; the DialogBody owns the scroll. The\n// open/close transition is the BASE duration + verdify easing, instant under reduced motion, and\n// rides Radix's data-state (attribute-selector enter/exit, not arbitrary values). NEVER the\n// deliberate verified-check theatre (G-U3). Panel padding/gaps come from --space-*.\n//\n// size = the panel's MAX WIDTH only (spec §3 sm/md/lg, md default), bound to the --container-*\n// scale; the panel is full-width up to that cap and centered. There is no fixed height — the\n// height emerges from the content up to the viewport cap.\nexport const dialogPanelVariants = cva(\n [\n // centered on the modal layer; full available width up to the size cap, with side gutters\n \"fixed left-1/2 top-1/2 z-(--z-index-modal) -translate-x-1/2 -translate-y-1/2\",\n \"flex w-[calc(100%-var(--space-8))] flex-col gap-(--space-4)\",\n // never taller than the viewport less the gutter; the body scrolls within (spec §3)\n \"max-h-[calc(100dvh-var(--space-8))]\",\n // neutral raised surface + outer border + lg radius + lg elevation; panel inset padding\n \"bg-surface-raised border border-surface-border rounded-(--radius-lg) shadow-(--shadow-lg)\",\n \"p-(--space-6)\",\n // base open/close transition + verdify easing, instant under reduced motion (NEVER deliberate)\n \"transition-[opacity,transform] duration-(--motion-duration-base) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n // enter/exit ride Radix data-state — attribute-selector variants, not arbitrary values\n \"data-[state=open]:opacity-100 data-[state=closed]:opacity-0\",\n \"data-[state=open]:scale-100 data-[state=closed]:scale-95\",\n // the panel takes focus when there is no obvious first control; its ring is never removed\n \"outline-none\",\n focusRing,\n ],\n {\n variants: {\n // size = max width only (spec §3). md is the default. Bound to the --container-* scale.\n size: {\n sm: \"max-w-(--container-sm)\",\n md: \"max-w-(--container-md)\",\n lg: \"max-w-(--container-lg)\",\n },\n },\n defaultVariants: { size: \"md\" },\n },\n);\n\n// The header: the top region holding the title and the optional close button on the inline-end.\n// Logical-property layout (G-U6); a neutral hairline divider under it continues the surface.\nexport const dialogHeaderClass =\n \"flex items-start justify-between gap-(--space-4) border-b border-border-default pb-(--space-4)\";\n\n// The title: names the dialog in one short statement; it is the accessible name (Radix wires\n// aria-labelledby). The h2 type role in primary text (spec §5 --text-h2 / --color-text-primary).\nexport const dialogTitleClass = \"text-h2 text-text-primary\";\n\n// The description: optional supporting text under the title, associated with the panel for\n// screen readers (Radix wires aria-describedby). Body type role in secondary text (spec §5).\nexport const dialogDescriptionClass = \"text-body text-text-secondary\";\n\n// The body: the scrollable content region between header and footer. The panel caps its height\n// to the viewport; the body takes the remaining space and scrolls when content overflows (spec\n// §3). Body text is the body type role in secondary text (spec §5 --text-body / text-secondary).\nexport const dialogBodyClass =\n \"min-h-0 flex-1 overflow-y-auto text-body text-text-secondary\";\n\n// The footer: the action region holding the primary and any secondary/cancel action, aligned to\n// the inline-end with a neutral hairline divider above it. The actions themselves are Buttons —\n// the dialog spec does not restate their --color-action-* bindings (spec §5 note). Logical-\n// property layout (G-U6): actions flow inline-end with a gap.\nexport const dialogFooterClass =\n \"flex items-center justify-end gap-(--space-2) border-t border-border-default pt-(--space-4)\";\n\n// The close button: the dismiss control in the header. A NEUTRAL ghost surface — the glyph in\n// --color-action-ghost-fg at rest, the restrained ghost hover fill (spec §5 ghost-fg /\n// ghost-bg-hover), the md radius, the persistent focus ring, the target-size floor (44px touch /\n// 40px pointer, spec §7 2.5.8 / DEC-B) with the height EMERGING from the floor, never fixed\n// below it. fast functional hover motion + verdify easing, instant under reduced motion (G-U3).\nexport const dialogCloseVariants = cva([\n \"inline-flex items-center justify-center rounded-(--radius-md)\",\n // neutral ghost surface: glyph color at rest + restrained hover fill (no bg/border at rest)\n \"text-action-ghost-fg hover:bg-action-ghost-bg-hover\",\n // fast functional hover transition + verdify easing, instant under reduced motion (NEVER deliberate)\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n // target-size floor: 44px touch / 40px pointer; the close button is square at the floor (DEC-B)\n \"min-h-(--size-target-mobile) min-w-(--size-target-mobile)\",\n \"sm:min-h-(--size-target-desktop) sm:min-w-(--size-target-desktop)\",\n // visible 2px focus ring at 2px offset; never removed\n \"outline-none\",\n focusRing,\n]);\n\n// The close glyph: a neutral X, --size-icon-md, drawn with currentColor so it inherits the\n// button's ghost-fg. Decorative (aria-hidden) — the button carries the accessible name (spec §7).\nexport const dialogCloseGlyphClass = \"h-(--size-icon-md) w-(--size-icon-md)\";\n\nexport type DialogPanelVariantProps = VariantProps<typeof dialogPanelVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AACvC,SAAS,iBAAiB;AAgBnB,MAAM,sBAAsB,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAcM,MAAM,sBAAsB;AAAA,EACjC;AAAA;AAAA,IAEE;AAAA,IACA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA,MAER,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,MAAM,KAAK;AAAA,EAChC;AACF;AAIO,MAAM,oBACX;AAIK,MAAM,mBAAmB;AAIzB,MAAM,yBAAyB;AAK/B,MAAM,kBACX;AAMK,MAAM,oBACX;AAOK,MAAM,sBAAsB,IAAI;AAAA,EACrC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AACF,CAAC;AAIM,MAAM,wBAAwB;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"identity-chip.variants.d.ts","sourceRoot":"","sources":["../../../src/components/identity-chip/identity-chip.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAqClE,eAAO,MAAM,oBAAoB;;8EA6ChC,CAAC;AAKF,eAAO,MAAM,qBAAqB,kDAAkD,CAAC;AAKrF,eAAO,MAAM,0BAA0B,sDAAsD,CAAC;AAK9F,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAQ7D,eAAO,MAAM,8BAA8B,QASiB,CAAC;AAI7D,eAAO,MAAM,4BAA4B,0CAA0C,CAAC;AAEpF,MAAM,MAAM,wBAAwB,GAAG,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"identity-chip.variants.d.ts","sourceRoot":"","sources":["../../../src/components/identity-chip/identity-chip.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAsClE,eAAO,MAAM,oBAAoB;;8EA6ChC,CAAC;AAKF,eAAO,MAAM,qBAAqB,kDAAkD,CAAC;AAKrF,eAAO,MAAM,0BAA0B,sDAAsD,CAAC;AAK9F,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAQ7D,eAAO,MAAM,8BAA8B,QASiB,CAAC;AAI7D,eAAO,MAAM,4BAA4B,0CAA0C,CAAC;AAEpF,MAAM,MAAM,wBAAwB,GAAG,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { cva } from "class-variance-authority";
2
+ import { focusRing } from "../../lib/focus-ring";
2
3
  const identityChipVariants = cva(
3
4
  [
4
5
  // shape / layout: a single inline row, never shrinking in a flex line, names truncatable
@@ -31,7 +32,7 @@ const identityChipVariants = cva(
31
32
  // restrained ghost hover/press fill — quiet neutral, never a status or brand color (spec §4)
32
33
  "hover:bg-action-ghost-bg-hover active:bg-action-ghost-bg-hover",
33
34
  // focus ring — always visible, never removed (spec §4/§7)
34
- "outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2",
35
+ focusRing,
35
36
  // disabled — DEC-C: dim the label via the disabled TOKEN, inert, never opacity-60 (spec §4)
36
37
  "aria-disabled:pointer-events-none aria-disabled:text-text-disabled"
37
38
  ],
@@ -48,7 +49,7 @@ const identityChipVariants = cva(
48
49
  const identityChipNameClass = "min-w-0 truncate text-label text-text-primary";
49
50
  const identityChipSecondaryClass = "min-w-0 truncate text-caption text-text-secondary";
50
51
  const identityChipTextClass = "flex min-w-0 flex-col";
51
- const identityChipRemoveControlClass = "inline-flex shrink-0 items-center justify-center rounded-(--radius-full) min-h-(--size-target-mobile) min-w-(--size-target-mobile) sm:min-h-(--size-target-desktop) sm:min-w-(--size-target-desktop) text-action-ghost-fg cursor-pointer transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) motion-reduce:duration-(--motion-duration-instant) hover:bg-action-ghost-bg-hover active:bg-action-ghost-bg-hover outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 disabled:pointer-events-none disabled:text-text-disabled";
52
+ const identityChipRemoveControlClass = "inline-flex shrink-0 items-center justify-center rounded-(--radius-full) min-h-(--size-target-mobile) min-w-(--size-target-mobile) sm:min-h-(--size-target-desktop) sm:min-w-(--size-target-desktop) text-action-ghost-fg cursor-pointer transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) motion-reduce:duration-(--motion-duration-instant) hover:bg-action-ghost-bg-hover active:bg-action-ghost-bg-hover " + focusRing + " disabled:pointer-events-none disabled:text-text-disabled";
52
53
  const identityChipRemoveGlyphClass = "h-(--size-icon-sm) w-(--size-icon-sm)";
53
54
  export {
54
55
  identityChipNameClass,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/identity-chip/identity-chip.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// An IdentityChip is a compact inline reference to a single identity — a person or an AI agent\n// (spec §1). It COMPOSES the committed primitives — the Avatar for the picture, the optional\n// AgentBadge for the actor kind, the optional VerifiedBadge for a surfaced verification, and a\n// Skeleton in the chip's shape while the identity is still resolving — rather than reinventing\n// any of them. This file binds ONLY the chip body's neutral surface + text-role + layout classes\n// and (for the interactive variants) the ghost hover/press fill, the focus ring, the target-size\n// floor, and the fast functional transition; every composed primitive owns its own tokens.\n//\n// brand != state (spec §3/§5/§8). A chip carries NO status of its own — it reports who, never a\n// result — so the chip body consumes NOTHING from the status tier: no --color-status-* token is\n// bound here, and the verified-status green lives entirely inside the composed VerifiedBadge,\n// never painted on the chip. The brand violet (Sovereign Violet, the action accent) is never a\n// chip FILL either: the brand is not a status and a chip is not an action, so the body paints\n// from neutral surface / text / border roles. The interactive variants are real controls, so\n// they legitimately bind the ACTION-GHOST hover/press fill and the focus ring — the restrained\n// neutral control treatment, never a brand-colored or status-colored chip.\n//\n// The motion is the functional fast transition on verdify easing, collapsing to the instant\n// endpoint under reduced motion — never the 350ms VerifiedBadge-only theatre duration: a chip\n// is not a verification (G-U3).\n\n// The chip container (spec §2/§3/§4/§5). A self-contained rounded unit that holds the avatar,\n// the name, and the reserved badge positions in a single inline row at the --space-1 gap with\n// --space-2 inline padding, on the NEUTRAL raised surface with the muted hairline that separates\n// it from a same-colored surface. `relative` so a loading-state Skeleton placed inside can sit\n// `absolute inset-0` (the committed Avatar/Skeleton pattern). `min-w-0` so the name can truncate\n// rather than overflow when the chip is width-constrained (spec §2 — the name is never dropped).\n//\n// The `variant` axis is about HOW the chip is used (spec §3), never status and never a brand\n// fill — so NONE of the variants recolors the body. `static` (default) is a passive frame: no\n// focus, no hit target, no hover (spec §3/§4/§6). `interactive` and `removable` are real controls\n// and add the ghost hover/press fill, the focus ring, the target-size floor, and the fast\n// functional transition — the difference is the keyboard model and which element takes focus\n// (the body for `interactive`, the trailing remove-control for `removable`), carried by the tsx,\n// not by recoloring here.\nexport const identityChipVariants = cva(\n [\n // shape / layout: a single inline row, never shrinking in a flex line, names truncatable\n \"inline-flex min-w-0 shrink-0 items-center gap-(--space-1) px-(--space-2)\",\n // full radius + the neutral raised surface + the muted separating hairline (spec §5)\n \"rounded-(--radius-full) bg-surface-raised border border-surface-border-muted\",\n // relative so a loading Skeleton can be positioned absolute inset-0 inside (Avatar pattern)\n \"relative\",\n // global-first: never wrap the row; logical alignment so it mirrors under dir=rtl (G-U6)\n \"whitespace-nowrap text-start\",\n ],\n {\n variants: {\n // STRUCTURAL axis = spec §3 (how the chip is USED, never status, never a brand fill).\n variant: {\n // static (default): a read-only inline reference — non-interactive, no focus, no hit\n // target, no hover. The common case (spec §3).\n static: \"\",\n // interactive: the chip body is itself a control (an account-switcher trigger, a chip\n // that opens the profile). It takes the focus ring, the target-size floor, the restrained\n // ghost hover/press fill, and the fast functional transition (spec §3/§4). DEC-C: a\n // disabled control dims the label/name via the disabled TOKEN, never a blanket opacity.\n interactive: [\n \"cursor-pointer\",\n // fast functional motion on verdify easing; instant under reduced motion (NEVER deliberate)\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n // target-size floor — 44px touch / 40px pointer (spec §5/§7, WCAG 2.5.8)\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop)\",\n // restrained ghost hover/press fill — quiet neutral, never a status or brand color (spec §4)\n \"hover:bg-action-ghost-bg-hover active:bg-action-ghost-bg-hover\",\n // focus ring — always visible, never removed (spec §4/§7)\n \"outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\",\n // disabled — DEC-C: dim the label via the disabled TOKEN, inert, never opacity-60 (spec §4)\n \"aria-disabled:pointer-events-none aria-disabled:text-text-disabled\",\n ],\n // removable: a token in an editable field. The chip BODY stays presentational (no focus\n // ring / target floor of its own) — the trailing remove-control is the focusable part and\n // owns the target size + focus ring (set on removeControlClass). The body keeps the static\n // surface (spec §3/§4).\n removable: \"\",\n },\n },\n defaultVariants: { variant: \"static\" },\n },\n);\n\n// The display name (spec §2/§5): the identity's name in the LABEL type role + the PRIMARY text\n// color. It carries the identity in the accessibility tree as text, so it is never the only part\n// dropped at small sizes — it truncates with an ellipsis rather than disappearing (spec §2/§7).\nexport const identityChipNameClass = \"min-w-0 truncate text-label text-text-primary\";\n\n// The optional supporting line (spec §2/§5): one handle / role / profile-context line that\n// disambiguates two identities sharing a name, in the CAPTION type role + the SECONDARY text\n// color. Supporting detail only — never a credential value and never a status color.\nexport const identityChipSecondaryClass = \"min-w-0 truncate text-caption text-text-secondary\";\n\n// The text block (spec §2): stacks the name above the optional secondary line; takes the\n// remaining inline space between the avatar and the reserved badge positions and lets the name\n// truncate (min-w-0) rather than overflow.\nexport const identityChipTextClass = \"flex min-w-0 flex-col\";\n\n// The trailing remove-control of the `removable` variant (spec §2/§4/§5/§6). It is the ONE\n// focusable part of a removable chip and owns its own activation, so it carries the target-size\n// floor, the focus ring, and the ghost hover/press fill — the control treatment lives HERE, not\n// on the chip body. The glyph takes the action-ghost foreground at the sm icon role; under reduced\n// motion the transition collapses to the instant endpoint. DEC-C: a disabled remove dims via the\n// disabled TOKEN, never a blanket opacity.\nexport const identityChipRemoveControlClass =\n \"inline-flex shrink-0 items-center justify-center rounded-(--radius-full) \" +\n \"min-h-(--size-target-mobile) min-w-(--size-target-mobile) \" +\n \"sm:min-h-(--size-target-desktop) sm:min-w-(--size-target-desktop) \" +\n \"text-action-ghost-fg cursor-pointer \" +\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant) \" +\n \"hover:bg-action-ghost-bg-hover active:bg-action-ghost-bg-hover \" +\n \"outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 \" +\n \"disabled:pointer-events-none disabled:text-text-disabled\";\n\n// The remove-control glyph (spec §5): one small decorative mark at the sm icon role, inheriting\n// the control's action-ghost foreground via currentColor.\nexport const identityChipRemoveGlyphClass = \"h-(--size-icon-sm) w-(--size-icon-sm)\";\n\nexport type IdentityChipVariantProps = VariantProps<typeof identityChipVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAqChC,MAAM,uBAAuB;AAAA,EAClC;AAAA;AAAA,IAEE;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA,MAER,SAAS;AAAA;AAAA;AAAA,QAGP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,QAKR,aAAa;AAAA,UACX;AAAA;AAAA,UAEA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA;AAAA,QACF;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,SAAS,SAAS;AAAA,EACvC;AACF;AAKO,MAAM,wBAAwB;AAK9B,MAAM,6BAA6B;AAKnC,MAAM,wBAAwB;AAQ9B,MAAM,iCACX;AAYK,MAAM,+BAA+B;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/identity-chip/identity-chip.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport { focusRing } from \"../../lib/focus-ring\";\n\n// An IdentityChip is a compact inline reference to a single identity — a person or an AI agent\n// (spec §1). It COMPOSES the committed primitives — the Avatar for the picture, the optional\n// AgentBadge for the actor kind, the optional VerifiedBadge for a surfaced verification, and a\n// Skeleton in the chip's shape while the identity is still resolving — rather than reinventing\n// any of them. This file binds ONLY the chip body's neutral surface + text-role + layout classes\n// and (for the interactive variants) the ghost hover/press fill, the focus ring, the target-size\n// floor, and the fast functional transition; every composed primitive owns its own tokens.\n//\n// brand != state (spec §3/§5/§8). A chip carries NO status of its own — it reports who, never a\n// result — so the chip body consumes NOTHING from the status tier: no --color-status-* token is\n// bound here, and the verified-status green lives entirely inside the composed VerifiedBadge,\n// never painted on the chip. The brand violet (Sovereign Violet, the action accent) is never a\n// chip FILL either: the brand is not a status and a chip is not an action, so the body paints\n// from neutral surface / text / border roles. The interactive variants are real controls, so\n// they legitimately bind the ACTION-GHOST hover/press fill and the focus ring — the restrained\n// neutral control treatment, never a brand-colored or status-colored chip.\n//\n// The motion is the functional fast transition on verdify easing, collapsing to the instant\n// endpoint under reduced motion — never the 350ms VerifiedBadge-only theatre duration: a chip\n// is not a verification (G-U3).\n\n// The chip container (spec §2/§3/§4/§5). A self-contained rounded unit that holds the avatar,\n// the name, and the reserved badge positions in a single inline row at the --space-1 gap with\n// --space-2 inline padding, on the NEUTRAL raised surface with the muted hairline that separates\n// it from a same-colored surface. `relative` so a loading-state Skeleton placed inside can sit\n// `absolute inset-0` (the committed Avatar/Skeleton pattern). `min-w-0` so the name can truncate\n// rather than overflow when the chip is width-constrained (spec §2 — the name is never dropped).\n//\n// The `variant` axis is about HOW the chip is used (spec §3), never status and never a brand\n// fill — so NONE of the variants recolors the body. `static` (default) is a passive frame: no\n// focus, no hit target, no hover (spec §3/§4/§6). `interactive` and `removable` are real controls\n// and add the ghost hover/press fill, the focus ring, the target-size floor, and the fast\n// functional transition — the difference is the keyboard model and which element takes focus\n// (the body for `interactive`, the trailing remove-control for `removable`), carried by the tsx,\n// not by recoloring here.\nexport const identityChipVariants = cva(\n [\n // shape / layout: a single inline row, never shrinking in a flex line, names truncatable\n \"inline-flex min-w-0 shrink-0 items-center gap-(--space-1) px-(--space-2)\",\n // full radius + the neutral raised surface + the muted separating hairline (spec §5)\n \"rounded-(--radius-full) bg-surface-raised border border-surface-border-muted\",\n // relative so a loading Skeleton can be positioned absolute inset-0 inside (Avatar pattern)\n \"relative\",\n // global-first: never wrap the row; logical alignment so it mirrors under dir=rtl (G-U6)\n \"whitespace-nowrap text-start\",\n ],\n {\n variants: {\n // STRUCTURAL axis = spec §3 (how the chip is USED, never status, never a brand fill).\n variant: {\n // static (default): a read-only inline reference — non-interactive, no focus, no hit\n // target, no hover. The common case (spec §3).\n static: \"\",\n // interactive: the chip body is itself a control (an account-switcher trigger, a chip\n // that opens the profile). It takes the focus ring, the target-size floor, the restrained\n // ghost hover/press fill, and the fast functional transition (spec §3/§4). DEC-C: a\n // disabled control dims the label/name via the disabled TOKEN, never a blanket opacity.\n interactive: [\n \"cursor-pointer\",\n // fast functional motion on verdify easing; instant under reduced motion (NEVER deliberate)\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n \"motion-reduce:duration-(--motion-duration-instant)\",\n // target-size floor — 44px touch / 40px pointer (spec §5/§7, WCAG 2.5.8)\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop)\",\n // restrained ghost hover/press fill — quiet neutral, never a status or brand color (spec §4)\n \"hover:bg-action-ghost-bg-hover active:bg-action-ghost-bg-hover\",\n // focus ring — always visible, never removed (spec §4/§7)\n focusRing,\n // disabled — DEC-C: dim the label via the disabled TOKEN, inert, never opacity-60 (spec §4)\n \"aria-disabled:pointer-events-none aria-disabled:text-text-disabled\",\n ],\n // removable: a token in an editable field. The chip BODY stays presentational (no focus\n // ring / target floor of its own) — the trailing remove-control is the focusable part and\n // owns the target size + focus ring (set on removeControlClass). The body keeps the static\n // surface (spec §3/§4).\n removable: \"\",\n },\n },\n defaultVariants: { variant: \"static\" },\n },\n);\n\n// The display name (spec §2/§5): the identity's name in the LABEL type role + the PRIMARY text\n// color. It carries the identity in the accessibility tree as text, so it is never the only part\n// dropped at small sizes — it truncates with an ellipsis rather than disappearing (spec §2/§7).\nexport const identityChipNameClass = \"min-w-0 truncate text-label text-text-primary\";\n\n// The optional supporting line (spec §2/§5): one handle / role / profile-context line that\n// disambiguates two identities sharing a name, in the CAPTION type role + the SECONDARY text\n// color. Supporting detail only — never a credential value and never a status color.\nexport const identityChipSecondaryClass = \"min-w-0 truncate text-caption text-text-secondary\";\n\n// The text block (spec §2): stacks the name above the optional secondary line; takes the\n// remaining inline space between the avatar and the reserved badge positions and lets the name\n// truncate (min-w-0) rather than overflow.\nexport const identityChipTextClass = \"flex min-w-0 flex-col\";\n\n// The trailing remove-control of the `removable` variant (spec §2/§4/§5/§6). It is the ONE\n// focusable part of a removable chip and owns its own activation, so it carries the target-size\n// floor, the focus ring, and the ghost hover/press fill — the control treatment lives HERE, not\n// on the chip body. The glyph takes the action-ghost foreground at the sm icon role; under reduced\n// motion the transition collapses to the instant endpoint. DEC-C: a disabled remove dims via the\n// disabled TOKEN, never a blanket opacity.\nexport const identityChipRemoveControlClass =\n \"inline-flex shrink-0 items-center justify-center rounded-(--radius-full) \" +\n \"min-h-(--size-target-mobile) min-w-(--size-target-mobile) \" +\n \"sm:min-h-(--size-target-desktop) sm:min-w-(--size-target-desktop) \" +\n \"text-action-ghost-fg cursor-pointer \" +\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify) \" +\n \"motion-reduce:duration-(--motion-duration-instant) \" +\n \"hover:bg-action-ghost-bg-hover active:bg-action-ghost-bg-hover \" +\n focusRing + \" \" +\n \"disabled:pointer-events-none disabled:text-text-disabled\";\n\n// The remove-control glyph (spec §5): one small decorative mark at the sm icon role, inheriting\n// the control's action-ghost foreground via currentColor.\nexport const identityChipRemoveGlyphClass = \"h-(--size-icon-sm) w-(--size-icon-sm)\";\n\nexport type IdentityChipVariantProps = VariantProps<typeof identityChipVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AACvC,SAAS,iBAAiB;AAqCnB,MAAM,uBAAuB;AAAA,EAClC;AAAA;AAAA,IAEE;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA,MAER,SAAS;AAAA;AAAA;AAAA,QAGP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,QAKR,aAAa;AAAA,UACX;AAAA;AAAA,UAEA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA;AAAA,QACF;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,SAAS,SAAS;AAAA,EACvC;AACF;AAKO,MAAM,wBAAwB;AAK9B,MAAM,6BAA6B;AAKnC,MAAM,wBAAwB;AAQ9B,MAAM,iCACX,mbAOA,YAAY;AAKP,MAAM,+BAA+B;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"input.variants.d.ts","sourceRoot":"","sources":["../../../src/components/input/input.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAKlE,eAAO,MAAM,aAAa;;;;8EAmDzB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAInE,eAAO,MAAM,oBAAoB;;8EAK/B,CAAC"}
1
+ {"version":3,"file":"input.variants.d.ts","sourceRoot":"","sources":["../../../src/components/input/input.variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAMlE,eAAO,MAAM,aAAa;;;;8EAmDzB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAInE,eAAO,MAAM,oBAAoB;;8EAK/B,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { cva } from "class-variance-authority";
2
+ import { focusRing } from "../../lib/focus-ring";
2
3
  const inputVariants = cva(
3
4
  [
4
5
  // shape + resting field: control-* carries the field, neutrals not brand
@@ -15,7 +16,7 @@ const inputVariants = cva(
15
16
  // focus: visible 2px signal-blue ring at 2px offset + focused border, never
16
17
  // removed (2.4.7); border+ring meet 3:1 non-text contrast (1.4.11)
17
18
  "outline-none",
18
- "focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2",
19
+ focusRing,
19
20
  "focus-visible:border-border-focus",
20
21
  // colors transition functionally (no theatre); border + ring only
21
22
  "transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)",
@@ -53,7 +54,7 @@ const inputVariants = cva(
53
54
  );
54
55
  const inputMessageVariants = cva("mt-(--space-1) text-caption", {
55
56
  variants: {
56
- tone: { help: "text-text-secondary", error: "text-status-critical-fg" }
57
+ tone: { help: "text-text-secondary", error: "text-status-critical-on-surface" }
57
58
  },
58
59
  defaultVariants: { tone: "help" }
59
60
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/input/input.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// The text field. Token binding lives ONLY here. Native <input>, no Radix.\n// The closed state set for a text field is default·hover·focus·disabled·read-only·error\n// (input.md §4) — loading and pressed do NOT apply and are dropped.\nexport const inputVariants = cva(\n [\n // shape + resting field: control-* carries the field, neutrals not brand\n \"block w-full rounded-md border bg-control-bg text-control-fg\",\n \"border-control-border placeholder:text-control-placeholder\",\n // DEC-A — the value SIZE is text-base (16px) so iOS never zooms on focus; the\n // brand BODY line-height + letter-spacing ride along via the role-suffix vars.\n // text-body itself (0.9375rem / 15px) is NEVER bound on a form field: under the\n // role-aware cn it would collapse against text-base, and 15px would reintroduce\n // the iOS focus-zoom that the 16px reset exists to prevent.\n \"text-base leading-(--text-body--line-height) tracking-(--text-body--letter-spacing)\",\n // hover shows a text caret; the border does NOT change color (restraint)\n \"cursor-text\",\n // focus: visible 2px signal-blue ring at 2px offset + focused border, never\n // removed (2.4.7); border+ring meet 3:1 non-text contrast (1.4.11)\n \"outline-none\",\n \"focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2\",\n \"focus-visible:border-border-focus\",\n // colors transition functionally (no theatre); border + ring only\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n // disabled: muted value, non-interactive (native disabled drives tab skip)\n \"disabled:cursor-not-allowed disabled:text-text-disabled\",\n // read-only: editable-looking, selectable, stays in the tab order\n \"read-only:cursor-default\",\n // ERROR is the only colored field state — it borrows the STATUS color, never\n // the brand (§3, §8). Driven by the native aria-invalid attribute.\n \"aria-invalid:border-status-critical-border\",\n \"aria-invalid:focus-visible:ring-status-critical-border\",\n // 44px mobile / 40px desktop target floor, logical block-size. DEC-B: tokens\n // expose only target-size FLOORS, no height scale — every size anchors this\n // floor and never sets a fixed height below it (a11y). Resting height emerges\n // from the size variant's vertical padding above this floor.\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop)\",\n ],\n {\n variants: {\n // DEC-B — the 16px no-zoom reset is a hard floor on every form-field size, so\n // (unlike a non-field control) the type role is held constant and the sizes\n // differ ONLY by vertical padding (density) ABOVE the shared target floor:\n // --space-1 (0.25rem) <= --space-2 (0.5rem) gives a coherent sm <= md height\n // progression, both >= the floor.\n size: {\n md: \"py-(--space-2)\",\n sm: \"py-(--space-1)\",\n },\n // logical inline padding; widened on the slot side to reserve room\n leadingSlot: { true: \"ps-(--space-9)\", false: \"ps-(--space-3)\" },\n trailingSlot: { true: \"pe-(--space-9)\", false: \"pe-(--space-3)\" },\n },\n defaultVariants: { size: \"md\", leadingSlot: false, trailingSlot: false },\n },\n);\n\nexport type InputVariantProps = VariantProps<typeof inputVariants>;\n\n// The message below the field. The error help text borrows the field's STATUS\n// color (the only colored field state); neutral help text is muted secondary.\nexport const inputMessageVariants = cva(\"mt-(--space-1) text-caption\", {\n variants: {\n tone: { help: \"text-text-secondary\", error: \"text-status-critical-fg\" },\n },\n defaultVariants: { tone: \"help\" },\n});\n"],"mappings":"AAAA,SAAS,WAA8B;AAKhC,MAAM,gBAAgB;AAAA,EAC3B;AAAA;AAAA,IAEE;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA;AAAA,IAEA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA;AAAA,MAEA,aAAa,EAAE,MAAM,kBAAkB,OAAO,iBAAiB;AAAA,MAC/D,cAAc,EAAE,MAAM,kBAAkB,OAAO,iBAAiB;AAAA,IAClE;AAAA,IACA,iBAAiB,EAAE,MAAM,MAAM,aAAa,OAAO,cAAc,MAAM;AAAA,EACzE;AACF;AAMO,MAAM,uBAAuB,IAAI,+BAA+B;AAAA,EACrE,UAAU;AAAA,IACR,MAAM,EAAE,MAAM,uBAAuB,OAAO,0BAA0B;AAAA,EACxE;AAAA,EACA,iBAAiB,EAAE,MAAM,OAAO;AAClC,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/input/input.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport { focusRing } from \"../../lib/focus-ring\";\n\n// The text field. Token binding lives ONLY here. Native <input>, no Radix.\n// The closed state set for a text field is default·hover·focus·disabled·read-only·error\n// (input.md §4) — loading and pressed do NOT apply and are dropped.\nexport const inputVariants = cva(\n [\n // shape + resting field: control-* carries the field, neutrals not brand\n \"block w-full rounded-md border bg-control-bg text-control-fg\",\n \"border-control-border placeholder:text-control-placeholder\",\n // DEC-A — the value SIZE is text-base (16px) so iOS never zooms on focus; the\n // brand BODY line-height + letter-spacing ride along via the role-suffix vars.\n // text-body itself (0.9375rem / 15px) is NEVER bound on a form field: under the\n // role-aware cn it would collapse against text-base, and 15px would reintroduce\n // the iOS focus-zoom that the 16px reset exists to prevent.\n \"text-base leading-(--text-body--line-height) tracking-(--text-body--letter-spacing)\",\n // hover shows a text caret; the border does NOT change color (restraint)\n \"cursor-text\",\n // focus: visible 2px signal-blue ring at 2px offset + focused border, never\n // removed (2.4.7); border+ring meet 3:1 non-text contrast (1.4.11)\n \"outline-none\",\n focusRing,\n \"focus-visible:border-border-focus\",\n // colors transition functionally (no theatre); border + ring only\n \"transition-colors duration-(--motion-duration-fast) ease-(--motion-easing-verdify)\",\n // disabled: muted value, non-interactive (native disabled drives tab skip)\n \"disabled:cursor-not-allowed disabled:text-text-disabled\",\n // read-only: editable-looking, selectable, stays in the tab order\n \"read-only:cursor-default\",\n // ERROR is the only colored field state — it borrows the STATUS color, never\n // the brand (§3, §8). Driven by the native aria-invalid attribute.\n \"aria-invalid:border-status-critical-border\",\n \"aria-invalid:focus-visible:ring-status-critical-border\",\n // 44px mobile / 40px desktop target floor, logical block-size. DEC-B: tokens\n // expose only target-size FLOORS, no height scale — every size anchors this\n // floor and never sets a fixed height below it (a11y). Resting height emerges\n // from the size variant's vertical padding above this floor.\n \"min-h-(--size-target-mobile) sm:min-h-(--size-target-desktop)\",\n ],\n {\n variants: {\n // DEC-B — the 16px no-zoom reset is a hard floor on every form-field size, so\n // (unlike a non-field control) the type role is held constant and the sizes\n // differ ONLY by vertical padding (density) ABOVE the shared target floor:\n // --space-1 (0.25rem) <= --space-2 (0.5rem) gives a coherent sm <= md height\n // progression, both >= the floor.\n size: {\n md: \"py-(--space-2)\",\n sm: \"py-(--space-1)\",\n },\n // logical inline padding; widened on the slot side to reserve room\n leadingSlot: { true: \"ps-(--space-9)\", false: \"ps-(--space-3)\" },\n trailingSlot: { true: \"pe-(--space-9)\", false: \"pe-(--space-3)\" },\n },\n defaultVariants: { size: \"md\", leadingSlot: false, trailingSlot: false },\n },\n);\n\nexport type InputVariantProps = VariantProps<typeof inputVariants>;\n\n// The message below the field. The error help text borrows the field's STATUS\n// color (the only colored field state); neutral help text is muted secondary.\nexport const inputMessageVariants = cva(\"mt-(--space-1) text-caption\", {\n variants: {\n tone: { help: \"text-text-secondary\", error: \"text-status-critical-on-surface\" },\n },\n defaultVariants: { tone: \"help\" },\n});\n"],"mappings":"AAAA,SAAS,WAA8B;AACvC,SAAS,iBAAiB;AAKnB,MAAM,gBAAgB;AAAA,EAC3B;AAAA;AAAA,IAEE;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA;AAAA,IAEA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA;AAAA,MAEA,aAAa,EAAE,MAAM,kBAAkB,OAAO,iBAAiB;AAAA,MAC/D,cAAc,EAAE,MAAM,kBAAkB,OAAO,iBAAiB;AAAA,IAClE;AAAA,IACA,iBAAiB,EAAE,MAAM,MAAM,aAAa,OAAO,cAAc,MAAM;AAAA,EACzE;AACF;AAMO,MAAM,uBAAuB,IAAI,+BAA+B;AAAA,EACrE,UAAU;AAAA,IACR,MAAM,EAAE,MAAM,uBAAuB,OAAO,kCAAkC;AAAA,EAChF;AAAA,EACA,iBAAiB,EAAE,MAAM,OAAO;AAClC,CAAC;","names":[]}
@@ -16,7 +16,7 @@ const labelVariants = cva(
16
16
  }
17
17
  );
18
18
  const requiredMarkVariants = cva([
19
- "inline-flex items-center gap-(--space-1) text-status-critical-fg"
19
+ "inline-flex items-center gap-(--space-1) text-status-critical-on-surface"
20
20
  ]);
21
21
  const optionalHintVariants = cva(["text-caption text-text-secondary"]);
22
22
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/label/label.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// Resting label text: the label type role + primary text color, laid out inline\n// with its mark/hint at the --space-2 gap. No focus ring, no target-size floor —\n// a Label is not interactive. `disabled` reflects the control's state visually.\nexport const labelVariants = cva(\n [\n \"inline-flex items-center gap-(--space-2)\",\n \"text-label font-medium text-text-primary select-none\",\n ],\n {\n variants: {\n disabled: {\n // reflects the associated control's disabled state; stays in the DOM\n true: \"text-text-disabled\",\n false: \"\",\n },\n },\n defaultVariants: { disabled: false },\n },\n);\n\n// The required mark — meaning carried by shape + text, never color alone. The\n// critical color is permitted ONLY here (paired with the asterisk glyph and the\n// visually-hidden \"required\" word), never on resting label text.\nexport const requiredMarkVariants = cva([\n \"inline-flex items-center gap-(--space-1) text-status-critical-fg\",\n]);\n\n// The optional hint — a short secondary note in the caption role + secondary color.\nexport const optionalHintVariants = cva([\"text-caption text-text-secondary\"]);\n\nexport type LabelVariantProps = VariantProps<typeof labelVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAKhC,MAAM,gBAAgB;AAAA,EAC3B;AAAA,IACE;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,UAAU;AAAA;AAAA,QAER,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,UAAU,MAAM;AAAA,EACrC;AACF;AAKO,MAAM,uBAAuB,IAAI;AAAA,EACtC;AACF,CAAC;AAGM,MAAM,uBAAuB,IAAI,CAAC,kCAAkC,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/label/label.variants.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\n// Resting label text: the label type role + primary text color, laid out inline\n// with its mark/hint at the --space-2 gap. No focus ring, no target-size floor —\n// a Label is not interactive. `disabled` reflects the control's state visually.\nexport const labelVariants = cva(\n [\n \"inline-flex items-center gap-(--space-2)\",\n \"text-label font-medium text-text-primary select-none\",\n ],\n {\n variants: {\n disabled: {\n // reflects the associated control's disabled state; stays in the DOM\n true: \"text-text-disabled\",\n false: \"\",\n },\n },\n defaultVariants: { disabled: false },\n },\n);\n\n// The required mark — meaning carried by shape + text, never color alone. The\n// critical color is permitted ONLY here (paired with the asterisk glyph and the\n// visually-hidden \"required\" word), never on resting label text.\nexport const requiredMarkVariants = cva([\n \"inline-flex items-center gap-(--space-1) text-status-critical-on-surface\",\n]);\n\n// The optional hint — a short secondary note in the caption role + secondary color.\nexport const optionalHintVariants = cva([\"text-caption text-text-secondary\"]);\n\nexport type LabelVariantProps = VariantProps<typeof labelVariants>;\n"],"mappings":"AAAA,SAAS,WAA8B;AAKhC,MAAM,gBAAgB;AAAA,EAC3B;AAAA,IACE;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,UAAU;AAAA;AAAA,QAER,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,UAAU,MAAM;AAAA,EACrC;AACF;AAKO,MAAM,uBAAuB,IAAI;AAAA,EACtC;AACF,CAAC;AAGM,MAAM,uBAAuB,IAAI,CAAC,kCAAkC,CAAC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/components/menu/menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,YAAY,IAAI,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjE,OAAO,EASL,KAAK,oBAAoB,EAC1B,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,SACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,IAAI,CAAC;CAAG;AAE9E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,2CAEpC;AAED,MAAM,WAAW,gBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,OAAO,CAAC;CAAG;AAEjF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,4FAYtB,CAAC;AAEH,MAAM,WAAW,gBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,OAAO,CAAC;CAAG;AAEjF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,yFAkBtB,CAAC;AAEH,MAAM,WAAW,aACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,IAAI,CAAC,EACjE,OAAO,CACR,EACD,oBAAoB;IACtB,kHAAkH;IAClH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,sFAmBnB,CAAC;AAEH,MAAM,WAAW,cACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,KAAK,CAAC;IAC1E;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,uFAyBpB,CAAC;AAEH,MAAM,WAAW,cACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,KAAK,CAAC;CAAG;AAE/E;;;GAGG;AACH,eAAO,MAAM,SAAS,uFAOpB,CAAC;AAEH,MAAM,WAAW,kBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,SAAS,CAAC;CAAG;AAEnF;;;GAGG;AACH,eAAO,MAAM,aAAa,2FAWxB,CAAC;AAEH,MAAM,WAAW,YACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,GAAG,CAAC;CAAG;AAE7E;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,2CAE1C;AAED,MAAM,WAAW,mBACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,UAAU,CAAC,EACvE,OAAO,CACR,EACD,oBAAoB;IACtB,yEAAyE;IACzE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,4FAmBzB,CAAC;AAEH,MAAM,WAAW,mBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,UAAU,CAAC;CAAG;AAEpF;;;GAGG;AACH,eAAO,MAAM,cAAc,4FAiBzB,CAAC"}
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../../src/components/menu/menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,YAAY,IAAI,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjE,OAAO,EASL,KAAK,oBAAoB,EAC1B,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,SACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,IAAI,CAAC;CAAG;AAE9E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,2CAEpC;AAED,MAAM,WAAW,gBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,OAAO,CAAC;CAAG;AAEjF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,4FAYtB,CAAC;AAEH,MAAM,WAAW,gBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,OAAO,CAAC;CAAG;AAEjF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,yFAkBtB,CAAC;AAEH,MAAM,WAAW,aACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,IAAI,CAAC,EACjE,OAAO,CACR,EACD,oBAAoB;IACtB,kHAAkH;IAClH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,sFAuBnB,CAAC;AAEH,MAAM,WAAW,cACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,KAAK,CAAC;IAC1E;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,uFAyBpB,CAAC;AAEH,MAAM,WAAW,cACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,KAAK,CAAC;CAAG;AAE/E;;;GAGG;AACH,eAAO,MAAM,SAAS,uFAOpB,CAAC;AAEH,MAAM,WAAW,kBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,SAAS,CAAC;CAAG;AAEnF;;;GAGG;AACH,eAAO,MAAM,aAAa,2FAWxB,CAAC;AAEH,MAAM,WAAW,YACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,GAAG,CAAC;CAAG;AAE7E;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,2CAE1C;AAED,MAAM,WAAW,mBACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,UAAU,CAAC,EACvE,OAAO,CACR,EACD,oBAAoB;IACtB,yEAAyE;IACzE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,4FAmBzB,CAAC;AAEH,MAAM,WAAW,mBACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,qBAAqB,CAAC,UAAU,CAAC;CAAG;AAEpF;;;GAGG;AACH,eAAO,MAAM,cAAc,4FAiBzB,CAAC"}
@@ -49,7 +49,7 @@ const MenuItem = React.forwardRef(function MenuItem2({ className, destructive, i
49
49
  children: [
50
50
  icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: menuItemIconClass, children: icon }) : null,
51
51
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children }),
52
- shortcut ? /* @__PURE__ */ jsx("span", { className: menuItemShortcutClass, children: shortcut }) : null
52
+ shortcut ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: menuItemShortcutClass, children: shortcut }) : null
53
53
  ]
54
54
  }
55
55
  );