@psnext/design-system 1.2.1 → 1.4.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 (240) hide show
  1. package/dist/index.d.cts +5 -5
  2. package/dist/index.d.cts.map +1 -1
  3. package/dist/index.d.ts +5 -5
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index10.d.cts +7 -7
  6. package/dist/index10.d.cts.map +1 -1
  7. package/dist/index10.d.ts +7 -7
  8. package/dist/index11.d.cts +3 -3
  9. package/dist/index11.d.ts +3 -3
  10. package/dist/index12.d.cts +11 -11
  11. package/dist/index12.d.ts +12 -12
  12. package/dist/index13.d.cts +6 -6
  13. package/dist/index13.d.ts +6 -6
  14. package/dist/index14.d.cts +5 -5
  15. package/dist/index14.d.ts +5 -5
  16. package/dist/index15.d.cts +3 -3
  17. package/dist/index15.d.cts.map +1 -1
  18. package/dist/index15.d.ts +3 -3
  19. package/dist/index16.d.cts +2 -2
  20. package/dist/index16.d.ts +2 -2
  21. package/dist/index17.d.cts +4 -4
  22. package/dist/index17.d.ts +4 -4
  23. package/dist/index18.d.cts +11 -11
  24. package/dist/index18.d.ts +11 -11
  25. package/dist/index18.d.ts.map +1 -1
  26. package/dist/index19.d.cts +10 -10
  27. package/dist/index19.d.cts.map +1 -1
  28. package/dist/index19.d.ts +10 -10
  29. package/dist/index19.d.ts.map +1 -1
  30. package/dist/index2.d.cts +8 -8
  31. package/dist/index2.d.cts.map +1 -1
  32. package/dist/index2.d.ts +8 -8
  33. package/dist/index2.d.ts.map +1 -1
  34. package/dist/index20.d.cts +16 -16
  35. package/dist/index20.d.ts +16 -16
  36. package/dist/index20.d.ts.map +1 -1
  37. package/dist/index21.d.cts +4 -4
  38. package/dist/index21.d.cts.map +1 -1
  39. package/dist/index21.d.ts +4 -4
  40. package/dist/index22.d.cts +11 -11
  41. package/dist/index22.d.cts.map +1 -1
  42. package/dist/index22.d.ts +11 -11
  43. package/dist/index22.d.ts.map +1 -1
  44. package/dist/index23.d.cts +16 -16
  45. package/dist/index23.d.ts +16 -16
  46. package/dist/index24.d.cts +10 -10
  47. package/dist/index24.d.cts.map +1 -1
  48. package/dist/index24.d.ts +10 -10
  49. package/dist/index25.d.cts +2 -2
  50. package/dist/index25.d.ts +2 -2
  51. package/dist/index26.d.cts +14 -14
  52. package/dist/index26.d.cts.map +1 -1
  53. package/dist/index26.d.ts +14 -14
  54. package/dist/index26.d.ts.map +1 -1
  55. package/dist/index27.d.cts +7 -7
  56. package/dist/index27.d.ts +7 -7
  57. package/dist/index28.d.cts +5 -5
  58. package/dist/index28.d.ts +5 -5
  59. package/dist/index28.d.ts.map +1 -1
  60. package/dist/index29.d.cts +4 -4
  61. package/dist/index29.d.ts +4 -4
  62. package/dist/index3.d.cts +13 -13
  63. package/dist/index3.d.cts.map +1 -1
  64. package/dist/index3.d.ts +13 -13
  65. package/dist/index3.d.ts.map +1 -1
  66. package/dist/index30.d.cts +5 -5
  67. package/dist/index30.d.ts +5 -5
  68. package/dist/index31.d.cts +5 -5
  69. package/dist/index31.d.cts.map +1 -1
  70. package/dist/index31.d.ts +5 -5
  71. package/dist/index31.d.ts.map +1 -1
  72. package/dist/index32.d.cts +5 -5
  73. package/dist/index32.d.cts.map +1 -1
  74. package/dist/index32.d.ts +5 -5
  75. package/dist/index32.d.ts.map +1 -1
  76. package/dist/index33.d.cts +11 -11
  77. package/dist/index33.d.cts.map +1 -1
  78. package/dist/index33.d.ts +10 -10
  79. package/dist/index33.d.ts.map +1 -1
  80. package/dist/index34.d.cts +5 -5
  81. package/dist/index34.d.cts.map +1 -1
  82. package/dist/index34.d.ts +5 -5
  83. package/dist/index35.d.cts +15 -15
  84. package/dist/index35.d.cts.map +1 -1
  85. package/dist/index35.d.ts +16 -16
  86. package/dist/index35.d.ts.map +1 -1
  87. package/dist/index36.d.cts +3 -3
  88. package/dist/index36.d.ts +3 -3
  89. package/dist/index36.d.ts.map +1 -1
  90. package/dist/index37.d.cts +4 -4
  91. package/dist/index37.d.ts +4 -4
  92. package/dist/index37.d.ts.map +1 -1
  93. package/dist/index38.d.cts +2 -2
  94. package/dist/index38.d.ts +2 -2
  95. package/dist/index39.d.cts +17 -17
  96. package/dist/index39.d.cts.map +1 -1
  97. package/dist/index39.d.ts +17 -17
  98. package/dist/index4.d.cts +2 -2
  99. package/dist/index4.d.cts.map +1 -1
  100. package/dist/index4.d.ts +2 -2
  101. package/dist/index4.d.ts.map +1 -1
  102. package/dist/index40.d.cts +5 -5
  103. package/dist/index40.d.cts.map +1 -1
  104. package/dist/index40.d.ts +5 -5
  105. package/dist/index40.d.ts.map +1 -1
  106. package/dist/index41.d.cts +11 -11
  107. package/dist/index41.d.ts +11 -11
  108. package/dist/index41.d.ts.map +1 -1
  109. package/dist/index42.d.cts +8 -8
  110. package/dist/index42.d.cts.map +1 -1
  111. package/dist/index42.d.ts +8 -8
  112. package/dist/index43.d.cts +9 -9
  113. package/dist/index43.d.cts.map +1 -1
  114. package/dist/index43.d.ts +9 -9
  115. package/dist/index44.d.cts +8 -8
  116. package/dist/index44.d.cts.map +1 -1
  117. package/dist/index44.d.ts +8 -8
  118. package/dist/index45.d.cts +2 -2
  119. package/dist/index45.d.ts +2 -2
  120. package/dist/index46.d.cts +4 -4
  121. package/dist/index46.d.cts.map +1 -1
  122. package/dist/index46.d.ts +4 -4
  123. package/dist/index46.d.ts.map +1 -1
  124. package/dist/index47.d.cts +4 -4
  125. package/dist/index47.d.ts +4 -4
  126. package/dist/index47.d.ts.map +1 -1
  127. package/dist/index48.d.cts +3 -3
  128. package/dist/index48.d.cts.map +1 -1
  129. package/dist/index48.d.ts +3 -3
  130. package/dist/index48.d.ts.map +1 -1
  131. package/dist/index49.d.cts +11 -11
  132. package/dist/index49.d.cts.map +1 -1
  133. package/dist/index49.d.ts +11 -11
  134. package/dist/index49.d.ts.map +1 -1
  135. package/dist/index5.d.cts +7 -7
  136. package/dist/index5.d.ts +7 -7
  137. package/dist/index5.d.ts.map +1 -1
  138. package/dist/index50.d.cts +9 -9
  139. package/dist/index50.d.ts +9 -9
  140. package/dist/index50.d.ts.map +1 -1
  141. package/dist/index51.d.cts +5 -5
  142. package/dist/index51.d.ts +5 -5
  143. package/dist/index51.d.ts.map +1 -1
  144. package/dist/index52.d.cts +26 -26
  145. package/dist/index52.d.ts +27 -27
  146. package/dist/index52.d.ts.map +1 -1
  147. package/dist/index53.d.cts +5 -5
  148. package/dist/index53.d.cts.map +1 -1
  149. package/dist/index53.d.ts +5 -5
  150. package/dist/index53.d.ts.map +1 -1
  151. package/dist/index54.d.cts +2 -2
  152. package/dist/index54.d.cts.map +1 -1
  153. package/dist/index54.d.ts +2 -2
  154. package/dist/index54.d.ts.map +1 -1
  155. package/dist/index55.d.cts +2 -2
  156. package/dist/index55.d.cts.map +1 -1
  157. package/dist/index55.d.ts +2 -2
  158. package/dist/index55.d.ts.map +1 -1
  159. package/dist/index56.d.cts +2 -2
  160. package/dist/index56.d.ts +2 -2
  161. package/dist/index56.d.ts.map +1 -1
  162. package/dist/index57.d.cts +4 -4
  163. package/dist/index57.d.ts +4 -4
  164. package/dist/index57.d.ts.map +1 -1
  165. package/dist/index58.d.cts +9 -9
  166. package/dist/index58.d.ts +9 -9
  167. package/dist/index58.d.ts.map +1 -1
  168. package/dist/index59.d.cts +16 -11
  169. package/dist/index59.d.cts.map +1 -1
  170. package/dist/index59.d.ts +18 -13
  171. package/dist/index59.d.ts.map +1 -1
  172. package/dist/index6.d.cts +5 -5
  173. package/dist/index6.d.ts +5 -5
  174. package/dist/index6.d.ts.map +1 -1
  175. package/dist/index60.d.cts +5 -5
  176. package/dist/index60.d.cts.map +1 -1
  177. package/dist/index60.d.ts +7 -7
  178. package/dist/index60.d.ts.map +1 -1
  179. package/dist/index61.d.cts +4 -4
  180. package/dist/index61.d.cts.map +1 -1
  181. package/dist/index61.d.ts +4 -4
  182. package/dist/index61.d.ts.map +1 -1
  183. package/dist/index62.d.cts +2 -2
  184. package/dist/index62.d.ts +2 -2
  185. package/dist/index62.d.ts.map +1 -1
  186. package/dist/index63.d.cts +5 -5
  187. package/dist/index63.d.cts.map +1 -1
  188. package/dist/index63.d.ts +6 -6
  189. package/dist/index63.d.ts.map +1 -1
  190. package/dist/index64.d.cts +3 -3
  191. package/dist/index64.d.cts.map +1 -1
  192. package/dist/index64.d.ts +3 -3
  193. package/dist/index64.d.ts.map +1 -1
  194. package/dist/index65.d.cts +4 -4
  195. package/dist/index65.d.ts +5 -5
  196. package/dist/index65.d.ts.map +1 -1
  197. package/dist/index66.d.cts +2 -2
  198. package/dist/index66.d.ts +2 -2
  199. package/dist/index66.d.ts.map +1 -1
  200. package/dist/index67.d.cts +6 -6
  201. package/dist/index67.d.ts +8 -8
  202. package/dist/index67.d.ts.map +1 -1
  203. package/dist/index68.d.cts +6 -6
  204. package/dist/index68.d.ts +7 -7
  205. package/dist/index68.d.ts.map +1 -1
  206. package/dist/index7.d.cts +8 -8
  207. package/dist/index7.d.ts +8 -8
  208. package/dist/index70.d.cts +8 -8
  209. package/dist/index70.d.ts +8 -8
  210. package/dist/index8.d.cts +4 -4
  211. package/dist/index8.d.ts +4 -4
  212. package/dist/index8.d.ts.map +1 -1
  213. package/dist/index9.d.cts +2 -2
  214. package/dist/index9.d.cts.map +1 -1
  215. package/dist/index9.d.ts +2 -2
  216. package/dist/index9.d.ts.map +1 -1
  217. package/dist/patterns/DataTable/index.d.cts +3 -3
  218. package/dist/patterns/DataTable/index.d.cts.map +1 -1
  219. package/dist/patterns/DataTable/index.d.ts +3 -3
  220. package/dist/patterns/Footer/index.d.cts +7 -7
  221. package/dist/patterns/Footer/index.d.cts.map +1 -1
  222. package/dist/patterns/Footer/index.d.ts +7 -7
  223. package/dist/patterns/Footer/index.d.ts.map +1 -1
  224. package/dist/patterns/MediaObject/index.d.cts +9 -9
  225. package/dist/patterns/MediaObject/index.d.ts +13 -13
  226. package/dist/patterns/MediaObject/index.d.ts.map +1 -1
  227. package/dist/patterns/SectionCard/index.d.cts +2 -2
  228. package/dist/patterns/SectionCard/index.d.ts +2 -2
  229. package/dist/patterns/SectionCard/index.d.ts.map +1 -1
  230. package/dist/patterns/SectionHeading/index.d.cts +2 -2
  231. package/dist/patterns/SectionHeading/index.d.ts +2 -2
  232. package/dist/patterns/SectionHeading/index.d.ts.map +1 -1
  233. package/dist/primitives/Tabs/index.cjs +22 -17
  234. package/dist/primitives/Tabs/index.cjs.map +1 -1
  235. package/dist/primitives/Tabs/index.js +22 -17
  236. package/dist/primitives/Tabs/index.js.map +1 -1
  237. package/dist/styles/index.css +3 -0
  238. package/dist/styles/theme.css +11 -3
  239. package/dist/styles/typography.css +136 -0
  240. package/package.json +1 -1
@@ -81,7 +81,7 @@ const tabsListVariants = cva("relative inline-flex items-center text-muted-foreg
81
81
  }
82
82
  });
83
83
  /** Row (or column) of tab triggers; renders the sliding indicator for the `segmented` variant. */
84
- function TabsList({ className, children, ...props }) {
84
+ function TabsList({ className, children, tabPrefix, tabSuffix, ...props }) {
85
85
  const { variant, size, orientation } = React.useContext(TabsContext);
86
86
  const isSegmented = variant === "segmented";
87
87
  const listRef = React.useRef(null);
@@ -126,22 +126,27 @@ function TabsList({ className, children, ...props }) {
126
126
  orientation
127
127
  }), className),
128
128
  ...props,
129
- children: [isSegmented && indicator && /* @__PURE__ */ jsx("span", {
130
- "data-slot": "tabs-indicator",
131
- "aria-hidden": true,
132
- className: "absolute z-0 rounded-lg bg-background shadow-sm transition-all duration-200 ease-out motion-reduce:transition-none",
133
- style: orientation === "vertical" ? {
134
- top: indicator.top,
135
- height: indicator.height,
136
- left: 4,
137
- right: 4
138
- } : {
139
- left: indicator.left,
140
- width: indicator.width,
141
- top: 4,
142
- bottom: 4
143
- }
144
- }), children]
129
+ children: [
130
+ tabPrefix,
131
+ isSegmented && indicator && /* @__PURE__ */ jsx("span", {
132
+ "data-slot": "tabs-indicator",
133
+ "aria-hidden": true,
134
+ className: "absolute z-0 rounded-lg bg-background shadow-sm transition-all duration-200 ease-out motion-reduce:transition-none",
135
+ style: orientation === "vertical" ? {
136
+ top: indicator.top,
137
+ height: indicator.height,
138
+ left: 4,
139
+ right: 4
140
+ } : {
141
+ left: indicator.left,
142
+ width: indicator.width,
143
+ top: 4,
144
+ bottom: 4
145
+ }
146
+ }),
147
+ children,
148
+ tabSuffix
149
+ ]
145
150
  });
146
151
  }
147
152
  const tabsTriggerVariants = cva("relative inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap text-foreground/70 outline-none transition-all hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["TabsPrimitive"],"sources":["../../../src/primitives/Tabs/Tabs.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { Tabs as TabsPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils\";\n\n// Tabs — built on Radix Tabs (content panels + roving-focus keyboard nav + a11y).\n// One component, four visual `variant`s, each supporting horizontal/vertical\n// `orientation`:\n// - \"line\": underline under the active tab.\n// - \"pill\" (default): a muted track; the active tab is an elevated pill.\n// - \"segmented\": a muted track with a single sliding indicator that animates\n// between tabs.\n// - \"fancy\": translucent glass card tabs; the active tab merges into the glass\n// content panel below (login-style). `size` controls the fancy vertical padding.\n// `variant`/`size`/`orientation` are set on the root and shared via context.\n\ntype TabsVariant = \"line\" | \"pill\" | \"segmented\" | \"fancy\";\ntype TabsSize = \"sm\" | \"md\" | \"lg\";\ntype TabsOrientation = \"horizontal\" | \"vertical\";\n\nconst TabsContext = React.createContext<{\n variant: TabsVariant;\n size: TabsSize;\n orientation: TabsOrientation;\n}>({ variant: \"pill\", size: \"md\", orientation: \"horizontal\" });\n\n/**\n * Tabbed interface root: holds the active value and shares `variant`/`size`/\n * `orientation` with its `TabsList`/`TabsTrigger`/`TabsContent` via context.\n */\nfunction Tabs({\n className,\n variant = \"pill\",\n size = \"md\",\n orientation = \"horizontal\",\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Root> & {\n /** Visual style of the tabs: underline, pill track, sliding segmented, or glass cards. */\n variant?: TabsVariant;\n /** Control density — drives padding and text size of the triggers. */\n size?: TabsSize;\n}) {\n const resolvedOrientation: TabsOrientation =\n orientation === \"vertical\" ? \"vertical\" : \"horizontal\";\n const ctx = React.useMemo(\n () => ({ variant, size, orientation: resolvedOrientation }),\n [variant, size, resolvedOrientation],\n );\n return (\n <TabsContext.Provider value={ctx}>\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n data-variant={variant}\n data-orientation={resolvedOrientation}\n orientation={resolvedOrientation}\n className={cn(\n \"group/tabs flex data-[orientation=horizontal]:flex-col\",\n variant === \"fancy\" ? \"gap-0\" : \"gap-2\",\n className,\n )}\n {...props}\n />\n </TabsContext.Provider>\n );\n}\n\nconst tabsListVariants = cva(\"relative inline-flex items-center text-muted-foreground\", {\n variants: {\n variant: {\n line: \"gap-1 bg-transparent\",\n pill: \"justify-center rounded-lg bg-muted p-[3px]\",\n segmented: \"justify-center rounded-xl bg-muted p-1\",\n fancy: \"w-full items-stretch gap-2 bg-transparent\",\n },\n orientation: {\n horizontal: \"\",\n vertical: \"h-fit flex-col\",\n },\n size: { sm: \"\", md: \"\", lg: \"\" },\n },\n compoundVariants: [\n // Track height for the horizontal pill/segmented variants.\n { variant: [\"pill\", \"segmented\"], orientation: \"horizontal\", size: \"sm\", class: \"h-8\" },\n { variant: [\"pill\", \"segmented\"], orientation: \"horizontal\", size: \"md\", class: \"h-9\" },\n { variant: [\"pill\", \"segmented\"], orientation: \"horizontal\", size: \"lg\", class: \"h-10\" },\n ],\n defaultVariants: { variant: \"pill\", orientation: \"horizontal\", size: \"md\" },\n});\n\n/** Row (or column) of tab triggers; renders the sliding indicator for the `segmented` variant. */\nfunction TabsList({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.List>) {\n const { variant, size, orientation } = React.useContext(TabsContext);\n const isSegmented = variant === \"segmented\";\n const listRef = React.useRef<HTMLDivElement>(null);\n const [indicator, setIndicator] = React.useState<{\n left: number;\n top: number;\n width: number;\n height: number;\n } | null>(null);\n\n React.useEffect(() => {\n if (!isSegmented) return;\n const list = listRef.current;\n if (!list) return;\n const update = () => {\n const active = list.querySelector<HTMLElement>(\n '[data-slot=\"tabs-trigger\"][data-state=\"active\"]',\n );\n if (!active) {\n setIndicator(null);\n return;\n }\n setIndicator({\n left: active.offsetLeft,\n top: active.offsetTop,\n width: active.offsetWidth,\n height: active.offsetHeight,\n });\n };\n update();\n const mutation = new MutationObserver(update);\n mutation.observe(list, { attributes: true, attributeFilter: [\"data-state\"], subtree: true });\n const resize = new ResizeObserver(update);\n resize.observe(list);\n return () => {\n mutation.disconnect();\n resize.disconnect();\n };\n }, [isSegmented]);\n\n return (\n <TabsPrimitive.List\n ref={listRef}\n data-slot=\"tabs-list\"\n className={cn(tabsListVariants({ variant, size, orientation }), className)}\n {...props}\n >\n {isSegmented && indicator && (\n <span\n data-slot=\"tabs-indicator\"\n aria-hidden\n className=\"absolute z-0 rounded-lg bg-background shadow-sm transition-all duration-200 ease-out motion-reduce:transition-none\"\n style={\n orientation === \"vertical\"\n ? { top: indicator.top, height: indicator.height, left: 4, right: 4 }\n : { left: indicator.left, width: indicator.width, top: 4, bottom: 4 }\n }\n />\n )}\n {children}\n </TabsPrimitive.List>\n );\n}\n\nconst tabsTriggerVariants = cva(\n \"relative inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap text-foreground/70 outline-none transition-all hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n line: \"h-[calc(100%-1px)] flex-1 rounded-none\",\n pill: \"h-[calc(100%-1px)] flex-1 rounded-10 border border-transparent data-[state=active]:bg-background data-[state=active]:shadow-sm\",\n segmented: \"z-[1] h-[calc(100%-1px)] flex-1 rounded-lg\",\n fancy:\n \"mb-1.5 flex-1 justify-between rounded-xl bg-[var(--glass-subtle)] backdrop-blur-glass hover:bg-[var(--glass-light)] data-[state=active]:mb-0 data-[state=active]:rounded-b-none data-[state=active]:bg-[var(--glass-light)]\",\n },\n orientation: { horizontal: \"\", vertical: \"w-full justify-start\" },\n size: { sm: \"\", md: \"\", lg: \"\" },\n },\n compoundVariants: [\n // Padding + text size for the track variants.\n { variant: [\"line\", \"pill\", \"segmented\"], size: \"sm\", class: \"px-1.5 py-1 text-xs\" },\n { variant: [\"line\", \"pill\", \"segmented\"], size: \"md\", class: \"px-2 py-1 text-sm\" },\n { variant: [\"line\", \"pill\", \"segmented\"], size: \"lg\", class: \"px-3 py-1 text-base\" },\n // Fancy footprint scales with size; the active tab adds bottom padding so it\n // merges into the panel while inactive tabs stay shorter (gap above content).\n { variant: \"fancy\", size: \"sm\", class: \"px-4 py-2 text-sm\" },\n { variant: \"fancy\", size: \"md\", class: \"px-4 py-3 text-sm\" },\n { variant: \"fancy\", size: \"lg\", class: \"px-4 py-4 text-base\" },\n // Underline position for the line variant (per orientation).\n {\n variant: \"line\",\n orientation: \"horizontal\",\n class:\n \"after:absolute after:inset-x-0 after:bottom-[-5px] after:h-0.5 after:bg-foreground after:opacity-0 after:transition-opacity data-[state=active]:after:opacity-100\",\n },\n {\n variant: \"line\",\n orientation: \"vertical\",\n class:\n \"after:absolute after:inset-y-0 after:right-[-5px] after:w-0.5 after:bg-foreground after:opacity-0 after:transition-opacity data-[state=active]:after:opacity-100\",\n },\n ],\n defaultVariants: { variant: \"pill\", orientation: \"horizontal\", size: \"md\" },\n },\n);\n\n/** Clickable tab button; its `value` selects the matching `TabsContent` panel. */\nfunction TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n const { variant, size, orientation } = React.useContext(TabsContext);\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(tabsTriggerVariants({ variant, size, orientation }), className)}\n {...props}\n />\n );\n}\n\n/** Panel shown when its `value` matches the active tab; styled as a glass panel for the `fancy` variant. */\nfunction TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {\n const { variant } = React.useContext(TabsContext);\n return (\n <TabsPrimitive.Content\n data-slot=\"tabs-content\"\n className={cn(\n \"flex-1 outline-none\",\n // Fancy: a glass panel the active tab merges into (flat top, matching tint).\n variant === \"fancy\" &&\n \"flex-none rounded-xl rounded-t-none bg-[var(--glass-light)] p-5 backdrop-blur-glass\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Trailing count badge for a tab trigger; goes dark on the `fancy` variant to match its cards. */\nfunction TabsCounter({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"tabs-counter\"\n className={cn(\n \"ml-1 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-muted px-1 text-xs font-medium text-muted-foreground\",\n \"group-data-[variant=fancy]/tabs:h-5 group-data-[variant=fancy]/tabs:min-w-5 group-data-[variant=fancy]/tabs:bg-inverse group-data-[variant=fancy]/tabs:text-inverse-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n TabsCounter,\n tabsListVariants,\n tabsTriggerVariants,\n};\n"],"mappings":";;;;;;AAuBA,MAAM,cAAc,MAAM,cAIvB;CAAE,SAAS;CAAQ,MAAM;CAAM,aAAa;AAAa,CAAC;;;;;AAM7D,SAAS,KAAK,EACZ,WACA,UAAU,QACV,OAAO,MACP,cAAc,cACd,GAAG,SAMF;CACD,MAAM,sBACJ,gBAAgB,aAAa,aAAa;CAC5C,MAAM,MAAM,MAAM,eACT;EAAE;EAAS;EAAM,aAAa;CAAoB,IACzD;EAAC;EAAS;EAAM;CAAmB,CACrC;CACA,OACE,oBAAC,YAAY,UAAb;EAAsB,OAAO;YAC3B,oBAACA,OAAc,MAAf;GACE,aAAU;GACV,gBAAc;GACd,oBAAkB;GAClB,aAAa;GACb,WAAW,GACT,0DACA,YAAY,UAAU,UAAU,SAChC,SACF;GACA,GAAI;EACL,CAAA;CACmB,CAAA;AAE1B;AAEA,MAAM,mBAAmB,IAAI,2DAA2D;CACtF,UAAU;EACR,SAAS;GACP,MAAM;GACN,MAAM;GACN,WAAW;GACX,OAAO;EACT;EACA,aAAa;GACX,YAAY;GACZ,UAAU;EACZ;EACA,MAAM;GAAE,IAAI;GAAI,IAAI;GAAI,IAAI;EAAG;CACjC;CACA,kBAAkB;EAEhB;GAAE,SAAS,CAAC,QAAQ,WAAW;GAAG,aAAa;GAAc,MAAM;GAAM,OAAO;EAAM;EACtF;GAAE,SAAS,CAAC,QAAQ,WAAW;GAAG,aAAa;GAAc,MAAM;GAAM,OAAO;EAAM;EACtF;GAAE,SAAS,CAAC,QAAQ,WAAW;GAAG,aAAa;GAAc,MAAM;GAAM,OAAO;EAAO;CACzF;CACA,iBAAiB;EAAE,SAAS;EAAQ,aAAa;EAAc,MAAM;CAAK;AAC5E,CAAC;;AAGD,SAAS,SAAS,EAChB,WACA,UACA,GAAG,SAC+C;CAClD,MAAM,EAAE,SAAS,MAAM,gBAAgB,MAAM,WAAW,WAAW;CACnE,MAAM,cAAc,YAAY;CAChC,MAAM,UAAU,MAAM,OAAuB,IAAI;CACjD,MAAM,CAAC,WAAW,gBAAgB,MAAM,SAK9B,IAAI;CAEd,MAAM,gBAAgB;EACpB,IAAI,CAAC,aAAa;EAClB,MAAM,OAAO,QAAQ;EACrB,IAAI,CAAC,MAAM;EACX,MAAM,eAAe;GACnB,MAAM,SAAS,KAAK,cAClB,qDACF;GACA,IAAI,CAAC,QAAQ;IACX,aAAa,IAAI;IACjB;GACF;GACA,aAAa;IACX,MAAM,OAAO;IACb,KAAK,OAAO;IACZ,OAAO,OAAO;IACd,QAAQ,OAAO;GACjB,CAAC;EACH;EACA,OAAO;EACP,MAAM,WAAW,IAAI,iBAAiB,MAAM;EAC5C,SAAS,QAAQ,MAAM;GAAE,YAAY;GAAM,iBAAiB,CAAC,YAAY;GAAG,SAAS;EAAK,CAAC;EAC3F,MAAM,SAAS,IAAI,eAAe,MAAM;EACxC,OAAO,QAAQ,IAAI;EACnB,aAAa;GACX,SAAS,WAAW;GACpB,OAAO,WAAW;EACpB;CACF,GAAG,CAAC,WAAW,CAAC;CAEhB,OACE,qBAACA,OAAc,MAAf;EACE,KAAK;EACL,aAAU;EACV,WAAW,GAAG,iBAAiB;GAAE;GAAS;GAAM;EAAY,CAAC,GAAG,SAAS;EACzE,GAAI;YAJN,CAMG,eAAe,aACd,oBAAC,QAAD;GACE,aAAU;GACV,eAAA;GACA,WAAU;GACV,OACE,gBAAgB,aACZ;IAAE,KAAK,UAAU;IAAK,QAAQ,UAAU;IAAQ,MAAM;IAAG,OAAO;GAAE,IAClE;IAAE,MAAM,UAAU;IAAM,OAAO,UAAU;IAAO,KAAK;IAAG,QAAQ;GAAE;EAEzE,CAAA,GAEF,QACiB;;AAExB;AAEA,MAAM,sBAAsB,IAC1B,0XACA;CACE,UAAU;EACR,SAAS;GACP,MAAM;GACN,MAAM;GACN,WAAW;GACX,OACE;EACJ;EACA,aAAa;GAAE,YAAY;GAAI,UAAU;EAAuB;EAChE,MAAM;GAAE,IAAI;GAAI,IAAI;GAAI,IAAI;EAAG;CACjC;CACA,kBAAkB;EAEhB;GAAE,SAAS;IAAC;IAAQ;IAAQ;GAAW;GAAG,MAAM;GAAM,OAAO;EAAsB;EACnF;GAAE,SAAS;IAAC;IAAQ;IAAQ;GAAW;GAAG,MAAM;GAAM,OAAO;EAAoB;EACjF;GAAE,SAAS;IAAC;IAAQ;IAAQ;GAAW;GAAG,MAAM;GAAM,OAAO;EAAsB;EAGnF;GAAE,SAAS;GAAS,MAAM;GAAM,OAAO;EAAoB;EAC3D;GAAE,SAAS;GAAS,MAAM;GAAM,OAAO;EAAoB;EAC3D;GAAE,SAAS;GAAS,MAAM;GAAM,OAAO;EAAsB;EAE7D;GACE,SAAS;GACT,aAAa;GACb,OACE;EACJ;EACA;GACE,SAAS;GACT,aAAa;GACb,OACE;EACJ;CACF;CACA,iBAAiB;EAAE,SAAS;EAAQ,aAAa;EAAc,MAAM;CAAK;AAC5E,CACF;;AAGA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,MAAM,EAAE,SAAS,MAAM,gBAAgB,MAAM,WAAW,WAAW;CACnE,OACE,oBAACA,OAAc,SAAf;EACE,aAAU;EACV,WAAW,GAAG,oBAAoB;GAAE;GAAS;GAAM;EAAY,CAAC,GAAG,SAAS;EAC5E,GAAI;CACL,CAAA;AAEL;;AAGA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA6D;CAChG,MAAM,EAAE,YAAY,MAAM,WAAW,WAAW;CAChD,OACE,oBAACA,OAAc,SAAf;EACE,aAAU;EACV,WAAW,GACT,uBAEA,YAAY,WACV,uFACF,SACF;EACA,GAAI;CACL,CAAA;AAEL;;AAGA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAuC;CAC1E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,iIACA,kLACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"index.js","names":["TabsPrimitive"],"sources":["../../../src/primitives/Tabs/Tabs.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { Tabs as TabsPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils\";\n\n// Tabs — built on Radix Tabs (content panels + roving-focus keyboard nav + a11y).\n// One component, four visual `variant`s, each supporting horizontal/vertical\n// `orientation`:\n// - \"line\": underline under the active tab.\n// - \"pill\" (default): a muted track; the active tab is an elevated pill.\n// - \"segmented\": a muted track with a single sliding indicator that animates\n// between tabs.\n// - \"fancy\": translucent glass card tabs; the active tab merges into the glass\n// content panel below (login-style). `size` controls the fancy vertical padding.\n// `variant`/`size`/`orientation` are set on the root and shared via context.\n\ntype TabsVariant = \"line\" | \"pill\" | \"segmented\" | \"fancy\";\ntype TabsSize = \"sm\" | \"md\" | \"lg\";\ntype TabsOrientation = \"horizontal\" | \"vertical\";\n\nconst TabsContext = React.createContext<{\n variant: TabsVariant;\n size: TabsSize;\n orientation: TabsOrientation;\n}>({ variant: \"pill\", size: \"md\", orientation: \"horizontal\" });\n\n/**\n * Tabbed interface root: holds the active value and shares `variant`/`size`/\n * `orientation` with its `TabsList`/`TabsTrigger`/`TabsContent` via context.\n */\nfunction Tabs({\n className,\n variant = \"pill\",\n size = \"md\",\n orientation = \"horizontal\",\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Root> & {\n /** Visual style of the tabs: underline, pill track, sliding segmented, or glass cards. */\n variant?: TabsVariant;\n /** Control density — drives padding and text size of the triggers. */\n size?: TabsSize;\n}) {\n const resolvedOrientation: TabsOrientation =\n orientation === \"vertical\" ? \"vertical\" : \"horizontal\";\n const ctx = React.useMemo(\n () => ({ variant, size, orientation: resolvedOrientation }),\n [variant, size, resolvedOrientation],\n );\n return (\n <TabsContext.Provider value={ctx}>\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n data-variant={variant}\n data-orientation={resolvedOrientation}\n orientation={resolvedOrientation}\n className={cn(\n \"group/tabs flex data-[orientation=horizontal]:flex-col\",\n variant === \"fancy\" ? \"gap-0\" : \"gap-2\",\n className,\n )}\n {...props}\n />\n </TabsContext.Provider>\n );\n}\n\nconst tabsListVariants = cva(\"relative inline-flex items-center text-muted-foreground\", {\n variants: {\n variant: {\n line: \"gap-1 bg-transparent\",\n pill: \"justify-center rounded-lg bg-muted p-[3px]\",\n segmented: \"justify-center rounded-xl bg-muted p-1\",\n fancy: \"w-full items-stretch gap-2 bg-transparent\",\n },\n orientation: {\n horizontal: \"\",\n vertical: \"h-fit flex-col\",\n },\n size: { sm: \"\", md: \"\", lg: \"\" },\n },\n compoundVariants: [\n // Track height for the horizontal pill/segmented variants.\n { variant: [\"pill\", \"segmented\"], orientation: \"horizontal\", size: \"sm\", class: \"h-8\" },\n { variant: [\"pill\", \"segmented\"], orientation: \"horizontal\", size: \"md\", class: \"h-9\" },\n { variant: [\"pill\", \"segmented\"], orientation: \"horizontal\", size: \"lg\", class: \"h-10\" },\n ],\n defaultVariants: { variant: \"pill\", orientation: \"horizontal\", size: \"md\" },\n});\n\n/** Row (or column) of tab triggers; renders the sliding indicator for the `segmented` variant. */\nfunction TabsList({\n className,\n children,\n tabPrefix,\n tabSuffix,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.List> & {\n tabPrefix?: React.ReactNode;\n tabSuffix?: React.ReactNode;\n}) {\n const { variant, size, orientation } = React.useContext(TabsContext);\n const isSegmented = variant === \"segmented\";\n const listRef = React.useRef<HTMLDivElement>(null);\n const [indicator, setIndicator] = React.useState<{\n left: number;\n top: number;\n width: number;\n height: number;\n } | null>(null);\n\n React.useEffect(() => {\n if (!isSegmented) return;\n const list = listRef.current;\n if (!list) return;\n const update = () => {\n const active = list.querySelector<HTMLElement>(\n '[data-slot=\"tabs-trigger\"][data-state=\"active\"]',\n );\n if (!active) {\n setIndicator(null);\n return;\n }\n setIndicator({\n left: active.offsetLeft,\n top: active.offsetTop,\n width: active.offsetWidth,\n height: active.offsetHeight,\n });\n };\n update();\n const mutation = new MutationObserver(update);\n mutation.observe(list, { attributes: true, attributeFilter: [\"data-state\"], subtree: true });\n const resize = new ResizeObserver(update);\n resize.observe(list);\n return () => {\n mutation.disconnect();\n resize.disconnect();\n };\n }, [isSegmented]);\n\n return (\n <TabsPrimitive.List\n ref={listRef}\n data-slot=\"tabs-list\"\n className={cn(tabsListVariants({ variant, size, orientation }), className)}\n {...props}\n >\n {tabPrefix}\n {isSegmented && indicator && (\n <span\n data-slot=\"tabs-indicator\"\n aria-hidden\n className=\"absolute z-0 rounded-lg bg-background shadow-sm transition-all duration-200 ease-out motion-reduce:transition-none\"\n style={\n orientation === \"vertical\"\n ? { top: indicator.top, height: indicator.height, left: 4, right: 4 }\n : { left: indicator.left, width: indicator.width, top: 4, bottom: 4 }\n }\n />\n )}\n {children}\n {tabSuffix}\n </TabsPrimitive.List>\n );\n}\n\nconst tabsTriggerVariants = cva(\n \"relative inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap text-foreground/70 outline-none transition-all hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n line: \"h-[calc(100%-1px)] flex-1 rounded-none\",\n pill: \"h-[calc(100%-1px)] flex-1 rounded-10 border border-transparent data-[state=active]:bg-background data-[state=active]:shadow-sm\",\n segmented: \"z-[1] h-[calc(100%-1px)] flex-1 rounded-lg\",\n fancy:\n \"mb-1.5 flex-1 justify-between rounded-xl bg-[var(--glass-subtle)] backdrop-blur-glass hover:bg-[var(--glass-light)] data-[state=active]:mb-0 data-[state=active]:rounded-b-none data-[state=active]:bg-[var(--glass-light)]\",\n },\n orientation: { horizontal: \"\", vertical: \"w-full justify-start\" },\n size: { sm: \"\", md: \"\", lg: \"\" },\n },\n compoundVariants: [\n // Padding + text size for the track variants.\n { variant: [\"line\", \"pill\", \"segmented\"], size: \"sm\", class: \"px-1.5 py-1 text-xs\" },\n { variant: [\"line\", \"pill\", \"segmented\"], size: \"md\", class: \"px-2 py-1 text-sm\" },\n { variant: [\"line\", \"pill\", \"segmented\"], size: \"lg\", class: \"px-3 py-1 text-base\" },\n // Fancy footprint scales with size; the active tab adds bottom padding so it\n // merges into the panel while inactive tabs stay shorter (gap above content).\n { variant: \"fancy\", size: \"sm\", class: \"px-4 py-2 text-sm\" },\n { variant: \"fancy\", size: \"md\", class: \"px-4 py-3 text-sm\" },\n { variant: \"fancy\", size: \"lg\", class: \"px-4 py-4 text-base\" },\n // Underline position for the line variant (per orientation).\n {\n variant: \"line\",\n orientation: \"horizontal\",\n class:\n \"after:absolute after:inset-x-0 after:bottom-[-5px] after:h-0.5 after:bg-foreground after:opacity-0 after:transition-opacity data-[state=active]:after:opacity-100\",\n },\n {\n variant: \"line\",\n orientation: \"vertical\",\n class:\n \"after:absolute after:inset-y-0 after:right-[-5px] after:w-0.5 after:bg-foreground after:opacity-0 after:transition-opacity data-[state=active]:after:opacity-100\",\n },\n ],\n defaultVariants: { variant: \"pill\", orientation: \"horizontal\", size: \"md\" },\n },\n);\n\n/** Clickable tab button; its `value` selects the matching `TabsContent` panel. */\nfunction TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n const { variant, size, orientation } = React.useContext(TabsContext);\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(tabsTriggerVariants({ variant, size, orientation }), className)}\n {...props}\n />\n );\n}\n\n/** Panel shown when its `value` matches the active tab; styled as a glass panel for the `fancy` variant. */\nfunction TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {\n const { variant } = React.useContext(TabsContext);\n return (\n <TabsPrimitive.Content\n data-slot=\"tabs-content\"\n className={cn(\n \"flex-1 outline-none\",\n // Fancy: a glass panel the active tab merges into (flat top, matching tint).\n variant === \"fancy\" &&\n \"flex-none rounded-xl rounded-t-none bg-[var(--glass-light)] p-5 backdrop-blur-glass\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Trailing count badge for a tab trigger; goes dark on the `fancy` variant to match its cards. */\nfunction TabsCounter({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"tabs-counter\"\n className={cn(\n \"ml-1 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-muted px-1 text-xs font-medium text-muted-foreground\",\n \"group-data-[variant=fancy]/tabs:h-5 group-data-[variant=fancy]/tabs:min-w-5 group-data-[variant=fancy]/tabs:bg-inverse group-data-[variant=fancy]/tabs:text-inverse-foreground\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n TabsCounter,\n tabsListVariants,\n tabsTriggerVariants,\n};\n"],"mappings":"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"}
@@ -47,6 +47,9 @@
47
47
  /* ── Base layer (suite-wide defaults) ─────────────────────── */
48
48
  @import "./base.css";
49
49
 
50
+ /* ── Global flow-content typography (raw/markdown tags) ────── */
51
+ @import "./typography.css";
52
+
50
53
  /* Scan the design-system component source so the utility classes
51
54
  they use are emitted into the compiled stylesheet. */
52
55
  @source "../";
@@ -120,7 +120,15 @@
120
120
  --shadow-2xl: var(--shadow-2xl);
121
121
 
122
122
  /* ── Font families (→ font-sans / font-heading / font-mono) ── */
123
- --font-sans: var(--font-definitions-font-family-body);
124
- --font-heading: var(--font-definitions-font-family-headings);
125
- --font-mono: var(--font-definitions-font-family-monospace);
123
+ /* Brand font first, then a system fallback stack so text stays styled if the
124
+ web font fails to load / during FOUT. `--font-sans` also drives the base
125
+ body font (Tailwind's --default-font-family). */
126
+ --font-sans:
127
+ var(--font-definitions-font-family-body), ui-sans-serif, system-ui, -apple-system,
128
+ "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
129
+ "Segoe UI Symbol", "Noto Color Emoji";
130
+ --font-heading: var(--font-definitions-font-family-headings), ui-sans-serif, system-ui,
131
+ -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
132
+ --font-mono: var(--font-definitions-font-family-monospace), ui-monospace, SFMono-Regular,
133
+ "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
126
134
  }
@@ -0,0 +1,136 @@
1
+ /* ============================================================
2
+ Global flow-content typography — default styling for raw HTML
3
+ tags (markdown / CMS output) rendered WITHOUT design-system
4
+ component classes.
5
+
6
+ Scoped to `:not([class]):not([data-slot])`: Tailwind's preflight strips margins,
7
+ list markers, link styling, etc., and DS components re-style their
8
+ own elements via utility classes — so anything that already has a
9
+ `class` is component-managed and left alone. Bare tags (what a
10
+ markdown renderer emits) get a readable default here.
11
+
12
+ `@layer base` so component/app utilities always win. All values
13
+ come from the design-system tokens.
14
+ ============================================================ */
15
+
16
+ @layer base {
17
+ /* ── Vertical rhythm (block flow) ─────────────────────────── */
18
+ :where(p, ul, ol, blockquote, pre, table, hr, figure):not([class]):not([data-slot]) {
19
+ margin-block: 0 1rem;
20
+ }
21
+ :where(h1, h2, h3, h4, h5, h6):not([class]):not([data-slot]) {
22
+ margin-block: 1.5rem 0.5rem;
23
+ }
24
+ /* No leading gap on the first block of a flow container. */
25
+ :where(p, ul, ol, blockquote, pre, table, hr, figure, h1, h2, h3, h4, h5, h6):not(
26
+ [class]
27
+ ):first-child {
28
+ margin-block-start: 0;
29
+ }
30
+
31
+ /* ── Paragraph / inline text ──────────────────────────────── */
32
+ p:not([class]):not([data-slot]) {
33
+ font-size: var(--paragraph-regular-font-size);
34
+ line-height: var(--paragraph-regular-line-height);
35
+ }
36
+ a:not([class]):not([data-slot]) {
37
+ color: inherit;
38
+ text-decoration: underline;
39
+ text-underline-offset: 2px;
40
+ }
41
+ a:not([class]):not([data-slot]):hover {
42
+ text-decoration-thickness: 2px;
43
+ }
44
+ strong:not([class]):not([data-slot]),
45
+ b:not([class]):not([data-slot]) {
46
+ font-weight: 600;
47
+ }
48
+ em:not([class]):not([data-slot]),
49
+ i:not([class]):not([data-slot]) {
50
+ font-style: italic;
51
+ }
52
+ small:not([class]):not([data-slot]) {
53
+ font-size: var(--paragraph-small-font-size);
54
+ }
55
+
56
+ /* ── Lists ────────────────────────────────────────────────── */
57
+ ul:not([class]):not([data-slot]),
58
+ ol:not([class]):not([data-slot]) {
59
+ padding-inline-start: 1.5rem;
60
+ }
61
+ ul:not([class]):not([data-slot]) {
62
+ list-style: disc;
63
+ }
64
+ ol:not([class]):not([data-slot]) {
65
+ list-style: decimal;
66
+ }
67
+ li:not([class]):not([data-slot]) {
68
+ margin-block: 0.25rem;
69
+ }
70
+ /* Nested lists tighten up and lose the extra block margin. */
71
+ :where(ul, ol):not([class]):not([data-slot]) :where(ul, ol):not([class]):not([data-slot]) {
72
+ margin-block: 0.25rem 0;
73
+ }
74
+
75
+ /* ── Code ─────────────────────────────────────────────────── */
76
+ code:not([class]):not([data-slot]),
77
+ kbd:not([class]):not([data-slot]),
78
+ samp:not([class]):not([data-slot]) {
79
+ font-family: var(--font-definitions-font-family-monospace);
80
+ font-size: 0.875em;
81
+ }
82
+ /* Inline code chip (a bare <code> not inside a <pre>). */
83
+ :not(pre) > code:not([class]):not([data-slot]) {
84
+ border-radius: var(--rounded-sm);
85
+ background-color: var(--muted);
86
+ padding: 0.125rem 0.375rem;
87
+ }
88
+ pre:not([class]):not([data-slot]) {
89
+ overflow-x: auto;
90
+ border-radius: var(--rounded-lg);
91
+ background-color: var(--muted);
92
+ padding: 1rem;
93
+ font-size: var(--paragraph-small-font-size);
94
+ line-height: var(--paragraph-small-line-height);
95
+ }
96
+ pre:not([class]):not([data-slot]) code {
97
+ font-family: var(--font-definitions-font-family-monospace);
98
+ background-color: transparent;
99
+ padding: 0;
100
+ }
101
+
102
+ /* ── Blockquote ───────────────────────────────────────────── */
103
+ blockquote:not([class]):not([data-slot]) {
104
+ border-inline-start: 3px solid var(--border);
105
+ padding-inline-start: 1rem;
106
+ color: var(--muted-foreground);
107
+ font-style: italic;
108
+ }
109
+
110
+ /* ── Rule / media ─────────────────────────────────────────── */
111
+ hr:not([class]):not([data-slot]) {
112
+ border: 0;
113
+ border-top: 1px solid var(--border);
114
+ }
115
+ img:not([class]):not([data-slot]),
116
+ video:not([class]):not([data-slot]) {
117
+ max-width: 100%;
118
+ height: auto;
119
+ border-radius: var(--rounded-lg);
120
+ }
121
+
122
+ /* ── Tables ───────────────────────────────────────────────── */
123
+ table:not([class]):not([data-slot]) {
124
+ width: 100%;
125
+ border-collapse: collapse;
126
+ font-size: var(--paragraph-small-font-size);
127
+ }
128
+ :where(th, td):not([class]):not([data-slot]) {
129
+ border-bottom: 1px solid var(--border);
130
+ padding: 0.5rem 0.75rem;
131
+ text-align: start;
132
+ }
133
+ th:not([class]):not([data-slot]) {
134
+ font-weight: 600;
135
+ }
136
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psnext/design-system",
3
- "version": "1.2.1",
3
+ "version": "1.4.0",
4
4
  "description": "Sapient AI Products design system — primitives, patterns, and layouts.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,