aural-ui 4.2.4 → 4.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 (47) hide show
  1. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +4 -4
  2. package/dist/components/badge/Badge.stories.tsx +3 -3
  3. package/dist/components/button/Button.stories.tsx +288 -366
  4. package/dist/components/button/index.tsx +3 -43
  5. package/dist/components/card/Card.stories.tsx +2 -2
  6. package/dist/components/card/index.tsx +1 -1
  7. package/dist/components/clamp-lines/index.tsx +0 -1
  8. package/dist/components/drawer/index.tsx +1 -1
  9. package/dist/components/hover-card/HoverCard.stories.tsx +7 -7
  10. package/dist/components/index.ts +1 -1
  11. package/dist/components/marquee/Marquee.stories.tsx +2 -6
  12. package/dist/components/offer-label/OfferLabel.stories.tsx +267 -0
  13. package/dist/components/offer-label/index.tsx +32 -0
  14. package/dist/components/offer-label/meta.ts +6 -0
  15. package/dist/components/otp-inputs/OtpInputs.stories.tsx +1 -1
  16. package/dist/components/popover/Popover.stories.tsx +1 -1
  17. package/dist/components/slider/index.tsx +1 -6
  18. package/dist/components/table/Table.stories.tsx +4 -4
  19. package/dist/components/toggle/Toggle.stories.tsx +4 -4
  20. package/dist/components/tooltip/index.tsx +1 -2
  21. package/dist/components/typography/Typography.stories.tsx +7 -19
  22. package/dist/components/typography/index.tsx +0 -2
  23. package/dist/fonts/LabGrotesque-Medium.ttf +0 -0
  24. package/dist/icons/all-icons.tsx +9 -7
  25. package/dist/icons/chain-link-icon/ChainLinkIcon.stories.tsx +167 -0
  26. package/dist/icons/chain-link-icon/index.tsx +30 -0
  27. package/dist/icons/chain-link-icon/meta.ts +8 -0
  28. package/dist/icons/clock-icon/ClockIcon.stories.tsx +210 -0
  29. package/dist/icons/clock-icon/index.tsx +28 -0
  30. package/dist/icons/clock-icon/meta.ts +8 -0
  31. package/dist/icons/headphone-icon/HeadphoneIcon.stories.tsx +186 -0
  32. package/dist/icons/headphone-icon/index.tsx +49 -0
  33. package/dist/icons/headphone-icon/meta.ts +8 -0
  34. package/dist/icons/index.ts +5 -1
  35. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +3 -3
  36. package/dist/icons/underline-icon/UnderlineIcon.stories.tsx +238 -0
  37. package/dist/icons/underline-icon/index.tsx +58 -0
  38. package/dist/icons/underline-icon/meta.ts +8 -0
  39. package/dist/index.cjs +86 -86
  40. package/dist/index.js +86 -86
  41. package/package.json +5 -5
  42. package/dist/fonts/LabGrotesqueTRIAL-Bold.otf +0 -0
  43. package/dist/fonts/LabGrotesqueTRIAL-Light.otf +0 -0
  44. package/dist/fonts/LabGrotesqueTRIAL-Medium.otf +0 -0
  45. package/dist/fonts/LabGrotesqueTRIAL-Regular.otf +0 -0
  46. package/dist/fonts/PPSupplySans-Regular (1).otf +0 -0
  47. package/dist/fonts/PPSupplySans-Ultralight.otf +0 -0
@@ -80,18 +80,6 @@ export const innerButtonVariants = cva(
80
80
  },
81
81
  },
82
82
  compoundVariants: [
83
- {
84
- variant: "primary",
85
- noise: "low",
86
- className:
87
- "[background-image:var(--button-fm-noise-low),_radial-gradient(ellipse_var(--gradientSizeX)_var(--gradientSizeY)_at_50%_var(--gradientPositionY),_var(--color-fm-primary-600),_var(--color-fm-button-fg-end)),_linear-gradient(_to_top,_color-mix(in_srgb,var(--color-fm-primary-600)_50%,_transparent),_color-mix(in_srgb,var(--color-fm-primary-200)_50%,_transparent))]",
88
- },
89
- {
90
- variant: "primary",
91
- noise: "medium",
92
- className:
93
- "[background-image:var(--button-fm-noise),_radial-gradient(ellipse_var(--gradientSizeX)_var(--gradientSizeY)_at_50%_var(--gradientPositionY),_var(--color-fm-primary-600),_var(--color-fm-button-fg-end)),_linear-gradient(_to_top,_color-mix(in_srgb,var(--color-fm-primary-600)_50%,_transparent),_color-mix(in_srgb,var(--color-fm-primary-200)_50%,_transparent))]",
94
- },
95
83
  {
96
84
  variant: "primary",
97
85
  noise: "strong",
@@ -103,31 +91,6 @@ export const innerButtonVariants = cva(
103
91
  noise: "low",
104
92
  className: "[background-image:var(--button-fm-noise-low)]",
105
93
  },
106
- {
107
- variant: "secondary",
108
- noise: "medium",
109
- className: "[background-image:var(--button-fm-noise)]",
110
- },
111
- {
112
- variant: "secondary",
113
- noise: "strong",
114
- className: "[background-image:var(--button-fm-noise-strong)]",
115
- },
116
- {
117
- variant: "chipActive",
118
- noise: "low",
119
- className: "[background-image:var(--button-fm-noise-low)]",
120
- },
121
- {
122
- variant: "chipActive",
123
- noise: "medium",
124
- className: "[background-image:var(--button-fm-noise)]",
125
- },
126
- {
127
- variant: "chipActive",
128
- noise: "strong",
129
- className: "[background-image:var(--button-fm-noise-strong)]",
130
- },
131
94
  ],
132
95
  defaultVariants: {
133
96
  variant: "primary",
@@ -148,7 +111,6 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
148
111
  isDisabled?: boolean
149
112
  size?: "sm" | "md" | "lg"
150
113
  variant?: "primary" | "secondary" | "outline" | "text" | "chip" | "chipActive"
151
- noise?: "none" | "low" | "medium" | "strong"
152
114
  }
153
115
 
154
116
  export const RawButton = forwardRef<HTMLButtonElement, ButtonProps>(
@@ -156,7 +118,6 @@ export const RawButton = forwardRef<HTMLButtonElement, ButtonProps>(
156
118
  {
157
119
  variant = "primary",
158
120
  size = "md",
159
- noise: noiseProp,
160
121
  children,
161
122
  className = "",
162
123
  innerClassName = "",
@@ -169,12 +130,11 @@ export const RawButton = forwardRef<HTMLButtonElement, ButtonProps>(
169
130
  ref
170
131
  ) => {
171
132
  const noise =
172
- noiseProp ??
173
- (variant === "primary"
174
- ? "medium"
133
+ variant === "primary"
134
+ ? "strong"
175
135
  : variant === "secondary"
176
136
  ? "low"
177
- : "none")
137
+ : "none"
178
138
 
179
139
  const iconColor = isDisabled
180
140
  ? "var(--icon-fm-inactive)"
@@ -443,7 +443,7 @@ export const UseCases: Story = {
443
443
  <div className="mx-auto max-w-md">
444
444
  <Card>
445
445
  <CardHeader>
446
- <CardTitle className="text-fm-primary font-fm-text text-fm-lg leading-fm-lg flex items-center gap-2 font-semibold">
446
+ <CardTitle className="text-fm-primary font-fm-text text-fm-lg leading-fm-lg flex items-center gap-2 font-medium">
447
447
  <MusicalNoteIcon className="text-fm-secondary size-4 shrink-0" />
448
448
  Midnight Dreams
449
449
  </CardTitle>
@@ -503,7 +503,7 @@ export const UseCases: Story = {
503
503
  <Card>
504
504
  <CardHeader className="border-b">
505
505
  <CardTitle className="text-fm-primary font-fm-brand text-fm-xl leading-fm-xl flex items-center gap-3 font-semibold">
506
- <div className="bg-fm-surface-secondary text-fm-primary flex size-10 shrink-0 items-center justify-center rounded-full font-semibold">
506
+ <div className="bg-fm-surface-secondary text-fm-primary flex size-10 shrink-0 items-center justify-center rounded-full font-medium">
507
507
  NC
508
508
  </div>
509
509
  Neon Collective
@@ -31,7 +31,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
31
31
  return (
32
32
  <div
33
33
  data-slot="card-title"
34
- className={cn("leading-none font-semibold", className)}
34
+ className={cn("leading-none font-medium", className)}
35
35
  {...props}
36
36
  />
37
37
  )
@@ -123,7 +123,6 @@ export const ClampLines = ({
123
123
  <Button
124
124
  data-nosnippet
125
125
  variant="text"
126
- noise="none"
127
126
  innerClassName={cn("px-0! h-fit inline", classes.clampLineBtnInnerClass)}
128
127
  className={cn(
129
128
  "text-fm-tertiary ml-1 cursor-pointer underline",
@@ -175,7 +175,7 @@ function DrawerTitle({
175
175
  return (
176
176
  <DrawerPrimitive.Title
177
177
  data-slot="drawer-title"
178
- className={cn("text-fm-primary font-semibold", className)}
178
+ className={cn("text-fm-primary font-medium", className)}
179
179
  {...props}
180
180
  />
181
181
  )
@@ -76,7 +76,7 @@ export const Parts: Story = {
76
76
  </HoverCardTrigger>
77
77
  <HoverCardContent>
78
78
  <div className="space-y-1">
79
- <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
79
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
80
80
  Aural Artist
81
81
  </p>
82
82
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -106,7 +106,7 @@ export const Parts: Story = {
106
106
  </HoverCardTrigger>
107
107
  <HoverCardContent>
108
108
  <div className="space-y-2">
109
- <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
109
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
110
110
  Frosted glass panel
111
111
  </p>
112
112
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -255,7 +255,7 @@ export const UseCases: Story = {
255
255
  Midnights ·{" "}
256
256
  <HoverCard openDelay={300} closeDelay={150}>
257
257
  <HoverCardTrigger asChild>
258
- <button className="text-fm-primary cursor-pointer font-semibold underline underline-offset-2 outline-none">
258
+ <button className="text-fm-primary cursor-pointer font-medium underline underline-offset-2 outline-none">
259
259
  Taylor Swift
260
260
  </button>
261
261
  </HoverCardTrigger>
@@ -268,7 +268,7 @@ export const UseCases: Story = {
268
268
  </span>
269
269
  </div>
270
270
  <div className="space-y-0.5">
271
- <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
271
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
272
272
  Taylor Swift
273
273
  </p>
274
274
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -337,7 +337,7 @@ export const UseCases: Story = {
337
337
  </HoverCardTrigger>
338
338
  <HoverCardContent className="w-64">
339
339
  <div className="space-y-2">
340
- <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
340
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
341
341
  {album.name}
342
342
  </p>
343
343
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -388,7 +388,7 @@ export const UseCases: Story = {
388
388
  >
389
389
  <HoverCard openDelay={300} closeDelay={200}>
390
390
  <HoverCardTrigger asChild>
391
- <button className="text-fm-primary cursor-pointer font-semibold underline underline-offset-2 outline-none">
391
+ <button className="text-fm-primary cursor-pointer font-medium underline underline-offset-2 outline-none">
392
392
  {handle}
393
393
  </button>
394
394
  </HoverCardTrigger>
@@ -401,7 +401,7 @@ export const UseCases: Story = {
401
401
  </span>
402
402
  </div>
403
403
  <div>
404
- <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
404
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
405
405
  {name}
406
406
  </p>
407
407
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -23,9 +23,9 @@ export * from "./if-else"
23
23
  export * from "./label"
24
24
  export * from "./list"
25
25
  export * from "./marquee"
26
+ export * from "./offer-label"
26
27
  export * from "./otp-inputs"
27
28
  export * from "./overlay"
28
- export * from "./otp-inputs"
29
29
  export * from "./pagination"
30
30
  export * from "./popover"
31
31
  export * from "./radio"
@@ -77,11 +77,7 @@ function TokenChip({
77
77
  }: {
78
78
  label: string
79
79
  surface:
80
- | "secondary"
81
- | "info-sec"
82
- | "positive-sec"
83
- | "warning-sec"
84
- | "negative-sec"
80
+ "secondary" | "info-sec" | "positive-sec" | "warning-sec" | "negative-sec"
85
81
  }) {
86
82
  const surfaceClass = {
87
83
  secondary: "bg-fm-surface-secondary border-fm-divider-secondary",
@@ -344,7 +340,7 @@ export const UseCases: Story = {
344
340
  Announcements Ticker
345
341
  </h4>
346
342
  <div className="border-fm-divider-secondary bg-fm-surface-secondary flex items-center gap-3 overflow-hidden rounded-lg border px-4 py-2">
347
- <div className="bg-fm-surface-negative-sec text-fm-primary text-fm-xs leading-fm-xs shrink-0 rounded px-2 py-0.5 font-semibold tracking-widest uppercase">
343
+ <div className="bg-fm-surface-negative-sec text-fm-primary text-fm-xs leading-fm-xs shrink-0 rounded px-2 py-0.5 font-medium tracking-widest uppercase">
348
344
  Live
349
345
  </div>
350
346
  <Marquee duration="28s" pauseOnHover className="flex-1">
@@ -0,0 +1,267 @@
1
+ import React from "react"
2
+ import type { Meta, StoryObj } from "@storybook/react-vite"
3
+
4
+ import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
5
+
6
+ import { OfferLabel } from "."
7
+
8
+ const meta: Meta<typeof OfferLabel> = {
9
+ title: "Components/UI/OfferLabel",
10
+ component: OfferLabel,
11
+ parameters: {
12
+ layout: "centered",
13
+ docs: {
14
+ description: {
15
+ component:
16
+ "An inline label that renders text with a decorative gradient underline stroke beneath it — ideal for surfacing promotional copy, highlighted offers, or key phrases.",
17
+ },
18
+ page: () => (
19
+ <AuralComponentDocsPage
20
+ features={[
21
+ {
22
+ title: "Gradient Underline",
23
+ description: "Animated SVG accent",
24
+ },
25
+ {
26
+ title: "Composable Text",
27
+ description: "Accepts any className",
28
+ },
29
+ {
30
+ title: "SSR Safe",
31
+ description: "Stable gradient ID prop",
32
+ },
33
+ ]}
34
+ />
35
+ ),
36
+ },
37
+ },
38
+ tags: ["autodocs"],
39
+ argTypes: {
40
+ text: {
41
+ control: "text",
42
+ description: "The label text to display",
43
+ },
44
+ className: {
45
+ control: "text",
46
+ description: "CSS classes applied to the inner text span",
47
+ },
48
+ iconId: {
49
+ control: "text",
50
+ description: "Optional stable ID for the underline gradient",
51
+ },
52
+ },
53
+ }
54
+
55
+ export default meta
56
+ type Story = StoryObj<typeof OfferLabel>
57
+
58
+ // ─── 1. Playground ────────────────────────────────────────────────────────────
59
+
60
+ export const Playground: Story = {
61
+ args: {
62
+ text: "Limited Offer",
63
+ className:
64
+ "text-fm-primary font-fm-brand text-fm-2xl leading-fm-2xl font-bold",
65
+ },
66
+ render: (args) => (
67
+ <div className="w-full max-w-sm space-y-4">
68
+ <div className="flex justify-center py-4">
69
+ <OfferLabel {...args} />
70
+ </div>
71
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
72
+ <code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">{`<OfferLabel text="${args.text}" className="${args.className ?? ""}" />`}</code>
73
+ </div>
74
+ </div>
75
+ ),
76
+ parameters: {
77
+ docs: {
78
+ description: {
79
+ story:
80
+ "Adjust the text and className using the controls panel in the sidebar.",
81
+ },
82
+ },
83
+ },
84
+ }
85
+
86
+ // ─── 2. All Variants ──────────────────────────────────────────────────────────
87
+
88
+ export const AllVariants: Story = {
89
+ render: () => (
90
+ <div className="space-y-8">
91
+ <div className="space-y-4">
92
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
93
+ Typography Scale
94
+ </h4>
95
+ <div className="flex flex-wrap items-end gap-6">
96
+ <div className="space-y-2 text-center">
97
+ <OfferLabel
98
+ text="Headline"
99
+ className="text-fm-primary font-fm-brand text-fm-4xl leading-fm-4xl font-bold"
100
+ iconId="variant-4xl"
101
+ />
102
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
103
+ 4xl / bold
104
+ </p>
105
+ </div>
106
+ <div className="space-y-2 text-center">
107
+ <OfferLabel
108
+ text="Subheading"
109
+ className="text-fm-primary font-fm-brand text-fm-2xl leading-fm-2xl font-semibold"
110
+ iconId="variant-2xl"
111
+ />
112
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
113
+ 2xl / semibold
114
+ </p>
115
+ </div>
116
+ <div className="space-y-2 text-center">
117
+ <OfferLabel
118
+ text="Body label"
119
+ className="text-fm-primary font-fm-text text-fm-lg leading-fm-lg font-medium"
120
+ iconId="variant-lg"
121
+ />
122
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
123
+ lg / medium
124
+ </p>
125
+ </div>
126
+ <div className="space-y-2 text-center">
127
+ <OfferLabel
128
+ text="Small"
129
+ className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm"
130
+ iconId="variant-sm"
131
+ />
132
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
133
+ sm / regular
134
+ </p>
135
+ </div>
136
+ </div>
137
+ </div>
138
+
139
+ <div className="space-y-4">
140
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
141
+ Text Color
142
+ </h4>
143
+ <div className="flex flex-wrap items-end gap-6">
144
+ <div className="space-y-2 text-center">
145
+ <OfferLabel
146
+ text="Primary"
147
+ className="text-fm-primary font-fm-brand text-fm-2xl leading-fm-2xl font-bold"
148
+ iconId="color-primary"
149
+ />
150
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
151
+ text-fm-primary
152
+ </p>
153
+ </div>
154
+ <div className="space-y-2 text-center">
155
+ <OfferLabel
156
+ text="Secondary"
157
+ className="text-fm-secondary font-fm-brand text-fm-2xl leading-fm-2xl font-bold"
158
+ iconId="color-secondary"
159
+ />
160
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
161
+ text-fm-secondary
162
+ </p>
163
+ </div>
164
+ <div className="space-y-2 text-center">
165
+ <OfferLabel
166
+ text="Tertiary"
167
+ className="text-fm-tertiary font-fm-brand text-fm-2xl leading-fm-2xl font-bold"
168
+ iconId="color-tertiary"
169
+ />
170
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
171
+ text-fm-tertiary
172
+ </p>
173
+ </div>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ ),
178
+ parameters: {
179
+ docs: {
180
+ description: {
181
+ story:
182
+ "OfferLabel across different type scales and text color tokens — the gradient underline adapts naturally to each.",
183
+ },
184
+ },
185
+ },
186
+ }
187
+
188
+ // ─── 3. Use Cases ─────────────────────────────────────────────────────────────
189
+
190
+ export const UseCases: Story = {
191
+ render: () => (
192
+ <div className="mx-auto max-w-3xl space-y-8 p-8">
193
+ <div className="space-y-4">
194
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
195
+ Promotional Hero Banner
196
+ </h4>
197
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary mx-auto max-w-md space-y-3 rounded-xl border p-6 text-center">
198
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm tracking-widest uppercase">
199
+ Pocket FM Premium
200
+ </p>
201
+ <div className="flex justify-center">
202
+ <OfferLabel
203
+ text="3 Months Free"
204
+ className="text-fm-primary font-fm-brand text-fm-4xl leading-fm-4xl font-bold"
205
+ iconId="use-case-hero"
206
+ />
207
+ </div>
208
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-md">
209
+ Unlock unlimited access to all audio stories.
210
+ </p>
211
+ </div>
212
+ </div>
213
+
214
+ <div className="space-y-4">
215
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
216
+ Inline Promotional Copy
217
+ </h4>
218
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary mx-auto max-w-md rounded-xl border p-5">
219
+ <p className="text-fm-primary font-fm-text text-fm-lg leading-fm-xl">
220
+ Subscribe today and get{" "}
221
+ <OfferLabel
222
+ text="50% off"
223
+ className="text-fm-primary font-fm-brand text-fm-lg leading-fm-xl font-semibold"
224
+ iconId="use-case-inline"
225
+ />{" "}
226
+ your first month — no strings attached.
227
+ </p>
228
+ </div>
229
+ </div>
230
+
231
+ <div className="space-y-4">
232
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
233
+ Pricing Card Highlight
234
+ </h4>
235
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary mx-auto max-w-sm space-y-4 rounded-xl border p-6">
236
+ <div className="space-y-1">
237
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm tracking-widest uppercase">
238
+ Annual Plan
239
+ </p>
240
+ <div className="flex items-baseline gap-1">
241
+ <OfferLabel
242
+ text="₹999"
243
+ className="text-fm-primary font-fm-brand text-fm-5xl leading-fm-5xl font-bold"
244
+ iconId="use-case-price"
245
+ />
246
+ <span className="text-fm-secondary font-fm-text text-fm-md leading-fm-md">
247
+ / year
248
+ </span>
249
+ </div>
250
+ </div>
251
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
252
+ Save 40% compared to the monthly plan.
253
+ </p>
254
+ </div>
255
+ </div>
256
+ </div>
257
+ ),
258
+ parameters: {
259
+ layout: "fullscreen",
260
+ docs: {
261
+ description: {
262
+ story:
263
+ "Real-world usage: promotional hero banners, inline highlighted copy, and pricing card accents.",
264
+ },
265
+ },
266
+ },
267
+ }
@@ -0,0 +1,32 @@
1
+ import React from "react"
2
+ import { UnderlineIcon } from "@icons/underline-icon"
3
+ import { cn } from "@lib/utils"
4
+
5
+ export interface IOfferLabelProps {
6
+ className?: string
7
+ iconClass?: string
8
+ /**
9
+ * Optional stable ID for the underline gradient. Can help if SSR hydration mismatches occur.
10
+ */
11
+ iconId?: string
12
+ text: string
13
+ }
14
+
15
+ export function OfferLabel({
16
+ text,
17
+ className,
18
+ iconId,
19
+ iconClass,
20
+ }: IOfferLabelProps) {
21
+ return (
22
+ <span className="relative inline-block pb-1">
23
+ <span className={className}>{text}</span>
24
+ <UnderlineIcon
25
+ id={iconId}
26
+ aria-hidden="true"
27
+ withAccessibility={false}
28
+ className={cn("absolute left-0 w-8", iconClass)}
29
+ />
30
+ </span>
31
+ )
32
+ }
@@ -0,0 +1,6 @@
1
+ export const meta = {
2
+ dependencies: {},
3
+ devDependencies: {},
4
+ internalDependencies: ["underline-icon"],
5
+ tokens: [],
6
+ }
@@ -376,7 +376,7 @@ export const Interactive: Story = {
376
376
  <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-xl border p-6">
377
377
  <div className="space-y-4">
378
378
  <div className="space-y-1">
379
- <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
379
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
380
380
  Verify your identity
381
381
  </p>
382
382
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -291,7 +291,7 @@ export const Configurations: Story = {
291
291
  <PopoverContent className="w-64 rounded-lg p-4">
292
292
  <div className="flex items-start justify-between gap-3">
293
293
  <div className="space-y-1">
294
- <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
294
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
295
295
  Quick note
296
296
  </p>
297
297
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -61,12 +61,7 @@ interface SliderProps extends React.ComponentProps<
61
61
  typeof SliderPrimitive.Root
62
62
  > {
63
63
  variant?:
64
- | "default"
65
- | "primary"
66
- | "secondary"
67
- | "positive"
68
- | "warning"
69
- | "info"
64
+ "default" | "primary" | "secondary" | "positive" | "warning" | "info"
70
65
  size?: "sm" | "md" | "lg"
71
66
  showLabel?: boolean
72
67
  label?: string
@@ -298,8 +298,8 @@ export const Parts: Story = {
298
298
  </TableBody>
299
299
  <TableFooter>
300
300
  <TableRow>
301
- <TableCell className="font-semibold">Total</TableCell>
302
- <TableCell className="text-right font-semibold">2.09M</TableCell>
301
+ <TableCell className="font-medium">Total</TableCell>
302
+ <TableCell className="text-right font-medium">2.09M</TableCell>
303
303
  </TableRow>
304
304
  </TableFooter>
305
305
  </Table>
@@ -846,10 +846,10 @@ export const UseCases: Story = {
846
846
  </TableBody>
847
847
  <TableFooter>
848
848
  <TableRow>
849
- <TableCell colSpan={4} className="font-semibold">
849
+ <TableCell colSpan={4} className="font-medium">
850
850
  4 albums
851
851
  </TableCell>
852
- <TableCell className="font-semibold">
852
+ <TableCell className="font-medium">
853
853
  {albums.reduce((s, a) => s + a.tracks, 0)}
854
854
  </TableCell>
855
855
  <TableCell />
@@ -491,19 +491,19 @@ export const Interactive: Story = {
491
491
  <div className="flex flex-col gap-1">
492
492
  <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
493
493
  Shuffle:{" "}
494
- <span className="font-semibold">
494
+ <span className="font-medium">
495
495
  {playback.shuffle ? "ON" : "OFF"}
496
496
  </span>
497
497
  </p>
498
498
  <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
499
499
  Repeat:{" "}
500
- <span className="font-semibold">
500
+ <span className="font-medium">
501
501
  {playback.repeat ? "ON" : "OFF"}
502
502
  </span>
503
503
  </p>
504
504
  <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
505
505
  Mute:{" "}
506
- <span className="font-semibold">
506
+ <span className="font-medium">
507
507
  {playback.mute ? "ON" : "OFF"}
508
508
  </span>
509
509
  </p>
@@ -536,7 +536,7 @@ export const Interactive: Story = {
536
536
  onPressedChange={() => toggleFormat("bold")}
537
537
  aria-label="Toggle bold"
538
538
  >
539
- <span className="font-bold">B</span>
539
+ <span className="font-medium">B</span>
540
540
  </Toggle>
541
541
  <Toggle
542
542
  size="sm"
@@ -305,8 +305,7 @@ function TooltipContent({
305
305
 
306
306
  export function withTooltip<
307
307
  T extends
308
- | keyof React.JSX.IntrinsicElements
309
- | React.ForwardRefExoticComponent<any>,
308
+ keyof React.JSX.IntrinsicElements | React.ForwardRefExoticComponent<any>,
310
309
  >(Component: T) {
311
310
  return React.forwardRef<
312
311
  React.ElementRef<T>,