@streamoid/ui 0.6.17 → 0.6.18

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 (131) hide show
  1. package/README.md +35 -18
  2. package/dist/docs/AGENTS.md +321 -0
  3. package/dist/docs/CreditWarningBanner.md +305 -0
  4. package/dist/docs/InvoiceHistoryMobile.md +222 -0
  5. package/dist/docs/ScAccess.md +259 -0
  6. package/dist/docs/ScAppCard.md +244 -0
  7. package/dist/docs/ScAppCardForCopilot.md +230 -0
  8. package/dist/docs/ScAppCardV3.md +273 -0
  9. package/dist/docs/ScAppField.md +308 -0
  10. package/dist/docs/ScAppListingCard.md +271 -0
  11. package/dist/docs/ScAppSwitchPanel.md +286 -0
  12. package/dist/docs/ScAppcardLogos.md +226 -0
  13. package/dist/docs/ScArtifaxInvite.md +262 -0
  14. package/dist/docs/ScArtifaxSidebar.md +330 -0
  15. package/dist/docs/ScAskAgentButton.md +307 -0
  16. package/dist/docs/ScBadges.md +261 -0
  17. package/dist/docs/ScBeacon.md +244 -0
  18. package/dist/docs/ScBillingHistoryHeader.md +210 -0
  19. package/dist/docs/ScBillingHistoryTableList.md +243 -0
  20. package/dist/docs/ScBillingLogsTableHeader.md +212 -0
  21. package/dist/docs/ScBillingLogsTableList.md +251 -0
  22. package/dist/docs/ScBriefCard.md +255 -0
  23. package/dist/docs/ScButton.md +251 -0
  24. package/dist/docs/ScCalendar.md +268 -0
  25. package/dist/docs/ScCalendarDateComps.md +264 -0
  26. package/dist/docs/ScCatalogixInvite.md +345 -0
  27. package/dist/docs/ScCatalogixSidebar.md +337 -0
  28. package/dist/docs/ScCatalogixStoreHeader.md +246 -0
  29. package/dist/docs/ScCatalogixStoreTableList.md +316 -0
  30. package/dist/docs/ScCheckField.md +233 -0
  31. package/dist/docs/ScCheckbox.md +272 -0
  32. package/dist/docs/ScCounter.md +235 -0
  33. package/dist/docs/ScCreditsUsageCard.md +247 -0
  34. package/dist/docs/ScCreditsUsageCardMobile.md +224 -0
  35. package/dist/docs/ScDefaultCard.md +269 -0
  36. package/dist/docs/ScDp.md +245 -0
  37. package/dist/docs/ScDrawer.md +318 -0
  38. package/dist/docs/ScFieldButton.md +255 -0
  39. package/dist/docs/ScFileField.md +268 -0
  40. package/dist/docs/ScGoogleSignIn.md +250 -0
  41. package/dist/docs/ScGuide.md +278 -0
  42. package/dist/docs/ScHDivider.md +213 -0
  43. package/dist/docs/ScHeader.md +222 -0
  44. package/dist/docs/ScImageField.md +253 -0
  45. package/dist/docs/ScInChatList.md +277 -0
  46. package/dist/docs/ScInChatMessage.md +205 -0
  47. package/dist/docs/ScInfoPopup.md +248 -0
  48. package/dist/docs/ScIntialProfileCover.md +233 -0
  49. package/dist/docs/ScInvoiceHistoryMobile.md +187 -0
  50. package/dist/docs/ScLogoUnit.md +232 -0
  51. package/dist/docs/ScMappingCard.md +241 -0
  52. package/dist/docs/ScMediaApproval.md +301 -0
  53. package/dist/docs/ScMediaSelect.md +310 -0
  54. package/dist/docs/ScMenuOptions.md +308 -0
  55. package/dist/docs/ScMobileBottomAction.md +252 -0
  56. package/dist/docs/ScMobileTopNav.md +279 -0
  57. package/dist/docs/ScModal.md +291 -0
  58. package/dist/docs/ScOnlyField.md +302 -0
  59. package/dist/docs/ScOnlyIcon.md +213 -0
  60. package/dist/docs/ScPagination.md +284 -0
  61. package/dist/docs/ScPairtext.md +287 -0
  62. package/dist/docs/ScPendingAction.md +238 -0
  63. package/dist/docs/ScPhtogenixInvite.md +275 -0
  64. package/dist/docs/ScPlanCard.md +302 -0
  65. package/dist/docs/ScPlanComparison.md +264 -0
  66. package/dist/docs/ScPlanDetailsCard.md +246 -0
  67. package/dist/docs/ScPlanDetailsCardMobile.md +240 -0
  68. package/dist/docs/ScPopUpMenu.md +224 -0
  69. package/dist/docs/ScProfile.md +234 -0
  70. package/dist/docs/ScProfileImageUpdate.md +261 -0
  71. package/dist/docs/ScProfileOptions.md +245 -0
  72. package/dist/docs/ScProfilePopup.md +396 -0
  73. package/dist/docs/ScProfileSettingsComp.md +250 -0
  74. package/dist/docs/ScProfileV2Mobile.md +216 -0
  75. package/dist/docs/ScProgressBar.md +267 -0
  76. package/dist/docs/ScQuickPrompt.md +277 -0
  77. package/dist/docs/ScRadio.md +228 -0
  78. package/dist/docs/ScReferralCardMobile.md +226 -0
  79. package/dist/docs/ScReferralTableHeader.md +260 -0
  80. package/dist/docs/ScReferralTableList.md +293 -0
  81. package/dist/docs/ScRole.md +226 -0
  82. package/dist/docs/ScRoleMobile.md +199 -0
  83. package/dist/docs/ScSelect.md +270 -0
  84. package/dist/docs/ScSelection.md +256 -0
  85. package/dist/docs/ScSelectionList.md +272 -0
  86. package/dist/docs/ScSelectionPill.md +240 -0
  87. package/dist/docs/ScSelectionPillGroup.md +302 -0
  88. package/dist/docs/ScSettingsNav.md +212 -0
  89. package/dist/docs/ScSettingsTabComp.md +260 -0
  90. package/dist/docs/ScSideBarLogoUnit.md +340 -0
  91. package/dist/docs/ScSidebar.md +243 -0
  92. package/dist/docs/ScSidebarIcons.md +232 -0
  93. package/dist/docs/ScSidebarMenu.md +283 -0
  94. package/dist/docs/ScSidebarProfile.md +231 -0
  95. package/dist/docs/ScSidebarSwitchMenu.md +258 -0
  96. package/dist/docs/ScSlider.md +194 -0
  97. package/dist/docs/ScStoreCard.md +252 -0
  98. package/dist/docs/ScStrLogo.md +253 -0
  99. package/dist/docs/ScStreamoidWordmark.md +302 -0
  100. package/dist/docs/ScSubAgent.md +226 -0
  101. package/dist/docs/ScTabComp.md +308 -0
  102. package/dist/docs/ScTabField.md +258 -0
  103. package/dist/docs/ScTabSwitcher.md +307 -0
  104. package/dist/docs/ScTableHeader.md +261 -0
  105. package/dist/docs/ScTableList.md +301 -0
  106. package/dist/docs/ScTableListMobile.md +282 -0
  107. package/dist/docs/ScTabs.md +268 -0
  108. package/dist/docs/ScTaxonomyPill.md +263 -0
  109. package/dist/docs/ScTextArea.md +259 -0
  110. package/dist/docs/ScTextField.md +324 -0
  111. package/dist/docs/ScThinkingStepIcon.md +249 -0
  112. package/dist/docs/ScTodoList.md +288 -0
  113. package/dist/docs/ScToggleSwitch.md +229 -0
  114. package/dist/docs/ScUsageHistoryMobile.md +194 -0
  115. package/dist/docs/ScVDivider.md +215 -0
  116. package/dist/docs/ScValueMappingL1.md +256 -0
  117. package/dist/docs/ScVersion.md +251 -0
  118. package/dist/docs/ScWorkspace.md +233 -0
  119. package/dist/docs/ScWorkspaceCard.md +234 -0
  120. package/dist/docs/ScWorkspaceSettingsMobile.md +265 -0
  121. package/dist/docs/ScWorkspaceSwitchCard.md +314 -0
  122. package/dist/docs/ScWorkspaceSwitchMobile.md +241 -0
  123. package/dist/docs/ScWorkspaceSwitchMobileV2.md +278 -0
  124. package/dist/docs/StreamoidSidebar.md +403 -0
  125. package/dist/docs/StreamoidWorkspaceSwitcher.md +307 -0
  126. package/dist/docs/UsageHistoryMobile.md +235 -0
  127. package/dist/docs/components.json +4849 -0
  128. package/dist/index.css +36 -36
  129. package/dist/index.d.mts +10 -0
  130. package/dist/index.d.ts +10 -0
  131. package/package.json +3 -2
@@ -0,0 +1,224 @@
1
+ ---
2
+ component: ScCreditsUsageCardMobile
3
+ package: "@streamoid/ui"
4
+ category: mobile
5
+ status: stable
6
+ renders: div
7
+ tags: [mobile, billing, credits, usage, meter, buy-credits, card, cxo]
8
+ related: [ScCreditsUsageCard, ScPlanDetailsCardMobile, ScButton, CreditWarningBanner]
9
+ do_not_confuse_with: [ScCreditsUsageCard, ScPlanDetailsCardMobile, CreditWarningBanner]
10
+ used_by: [cxo]
11
+ ---
12
+
13
+ # ScCreditsUsageCardMobile
14
+
15
+ **The credits-remaining block on CXO's mobile billing screen.** A bordered
16
+ full-width card: credits icon + "Credits usage" label, a divider, the
17
+ `used / total` figure with a "remaining" sub-line, and a full-width
18
+ **secondary** `ScButton` for buying credits.
19
+
20
+ ## TL;DR for agents
21
+
22
+ - **Reach for it when:** you are laying out the mobile (narrow, single-column)
23
+ billing screen and need the credits meter above the invoice/usage tabs.
24
+ - **Don't reach for it when:** you're on desktop (→ `ScCreditsUsageCard`, which
25
+ additionally has a `progress` bar and a disable-able buy button), or you want a
26
+ low-credits *alert* rather than a summary (→ `CreditWarningBanner`).
27
+ - **Four things that will bite you:**
28
+ 1. **Every text prop has a real demo default.** Render it bare and you ship
29
+ `"8,450 / 30,000"` and `"21,550 (60%) Remaining"`.
30
+ 2. **There is no progress bar.** The desktop card's `progress` prop does not
31
+ exist here — the percentage lives inside the `remainingText` string you build.
32
+ 3. **There is no way to disable the buy button.** The desktop card's
33
+ `buyButtonState` is absent; omit `onBuyClick` and the button still looks live.
34
+ 4. The card is already `width: 100%`; `usageText`/`remainingText` are opaque
35
+ strings — the card does no formatting, no maths, no locale handling.
36
+
37
+ ---
38
+
39
+ ## 1. How to use it
40
+
41
+ ### Import
42
+
43
+ ```tsx
44
+ import { ScCreditsUsageCardMobile } from "@streamoid/ui";
45
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
46
+ ```
47
+
48
+ ### Minimal usage
49
+
50
+ ```tsx
51
+ <ScCreditsUsageCardMobile
52
+ usageText={`${used.toLocaleString()} / ${total.toLocaleString()}`}
53
+ remainingText={`${remaining.toLocaleString()} (${pct}%) Remaining`}
54
+ onBuyClick={openBuyCredits}
55
+ />
56
+ ```
57
+
58
+ ### Props
59
+
60
+ | Prop | Type | Default | Notes |
61
+ |---|---|---|---|
62
+ | `usageLabel` | `string` | `"Credits usage"` | ⚠️ Header label beside the credits icon. Hardcoded English default. |
63
+ | `usageText` | `string` | `"8,450 / 30,000"` | ⚠️ Demo default. The big `used / total` line. You build the whole string. |
64
+ | `remainingText` | `string` | `"21,550 (60%) Remaining"` | ⚠️ Demo default. The grey sub-line. Includes the percentage — the card computes nothing. |
65
+ | `buyButtonText` | `string` | `"Buy credits"` | ⚠️ Hardcoded English default. |
66
+ | `onBuyClick` | `() => void` | – | Wired to the internal `ScButton`'s `onClick`. |
67
+ | `className` | `string` | – | Appended after internal classes (safely — this card uses `className ?? ""`). |
68
+ | `...props` | `React.HTMLAttributes<HTMLDivElement>` | – | Spread onto the card root. `style`, `data-*`, `onClick` land on the **card**, not the button. |
69
+
70
+ ### What the card renders, top to bottom
71
+
72
+ | Region | Content | Configurable? |
73
+ |---|---|---|
74
+ | Header | `SiconCredits` (24×24, tertiary token) + `usageLabel` | label only — the icon is fixed |
75
+ | Divider | 0.5px `--alias-border-divider` | no |
76
+ | Usage | `usageText` (18px/500 primary) then `remainingText` (14px/500 tertiary) | text only |
77
+ | Action | `ScButton variant="secondary" size="md"`, forced to `width: 100% !important` | `buyButtonText`, `onBuyClick` |
78
+
79
+ ### Recipes
80
+
81
+ ```tsx
82
+ // The CXO idiom: caller owns all formatting
83
+ const pct = Math.round((remaining / total) * 100);
84
+
85
+ <ScCreditsUsageCardMobile
86
+ usageLabel="Credits usage"
87
+ usageText={`${used.toLocaleString("en-US")} / ${total.toLocaleString("en-US")}`}
88
+ remainingText={`${remaining.toLocaleString("en-US")} (${pct}%) Remaining`}
89
+ buyButtonText="Buy credits"
90
+ onBuyClick={() => setShowBuyCredits(true)}
91
+ />
92
+
93
+ // Loading — this card has NO isLoading prop (unlike ScPlanDetailsCardMobile).
94
+ // Either render your own skeleton, or pass placeholder strings:
95
+ <ScCreditsUsageCardMobile usageText="—" remainingText="Loading…" onBuyClick={undefined} />
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 2. Where to use it
101
+
102
+ - **CXO mobile billing screen**, stacked directly under `ScPlanDetailsCardMobile`
103
+ and above the `ScTabSwitcher` that toggles Invoice history / Usage history.
104
+ - Any narrow single-column surface (mobile drawer, bottom sheet) that needs a
105
+ credits summary with a single CTA.
106
+
107
+ It composes `SiconCredits` and one `ScButton` internally. Do **not** nest your own
108
+ button — pass `buyButtonText` / `onBuyClick`.
109
+
110
+ ---
111
+
112
+ ## 3. When to use it
113
+
114
+ ### Use it when
115
+
116
+ - The viewport is the mobile breakpoint and the card must be full-width.
117
+ - A single "Buy credits" action is the only affordance you need.
118
+ - You already have the numbers formatted as display strings.
119
+
120
+ ### Don't use it — reach for this instead
121
+
122
+ | Situation | Use instead |
123
+ |---|---|
124
+ | Desktop billing page | `ScCreditsUsageCard` — same prop names **plus** `progress`, `buyButtonState`, `buyButtonHoverText` |
125
+ | You need a visual usage bar | `ScCreditsUsageCard` (has `progress`), or compose `ScProgressBar` yourself |
126
+ | Low-credits warning / nudge in a sidebar | `CreditWarningBanner` |
127
+ | Current-plan summary (name, price, Upgrade) | `ScPlanDetailsCardMobile` |
128
+ | A plan tile in a pricing grid | `ScPlanCard` |
129
+ | A row of the usage-log list | `UsageHistoryMobile` |
130
+
131
+ ### Don't confuse with
132
+
133
+ | You may actually want | Not this |
134
+ |---|---|
135
+ | `ScCreditsUsageCard` — the desktop twin, with a progress bar and a disable-able button | This mobile twin has neither |
136
+ | `CreditWarningBanner` — takes numbers (`availableCredits`, `remainingPct`) and decides its own tone | This card takes pre-built strings and never changes colour |
137
+ | `ScPlanDetailsCardMobile` — visually near-identical card, one slot down the screen | Different content and a *gradient* button |
138
+
139
+ ---
140
+
141
+ ## 4. Why to use it
142
+
143
+ - **Matches its desktop twin's anatomy prop-for-prop** (`usageLabel`,
144
+ `usageText`, `remainingText`, `buyButtonText`, `onBuyClick`), so a responsive
145
+ screen can swap components at the breakpoint without reshaping its data.
146
+ - **Correct token usage.** Unlike most of the `*Mobile` family, this card uses the
147
+ real `--alias-text-and-icons-*` names, so it genuinely flips between dark and
148
+ light themes.
149
+ - **The CTA is a real `ScButton`**, so it inherits the shared button shape, focus
150
+ behaviour and theme flip — the `width: 100% !important` override is the only
151
+ mobile-specific bit, and it's already done for you.
152
+ - **One place to change** the card chrome (radius `--radius-3xl`, 1px
153
+ `--alias-border-subtle`, `backdrop-filter: blur(4px)`) shared with
154
+ `ScPlanDetailsCardMobile`.
155
+
156
+ ---
157
+
158
+ ## Gotchas
159
+
160
+ **1. All four text props have shipping-quality demo defaults.** There is no
161
+ "empty" state — forget a prop and you ship believable wrong numbers.
162
+
163
+ ```tsx
164
+ // WRONG — renders "Credits usage / 8,450 / 30,000 / 21,550 (60%) Remaining"
165
+ <ScCreditsUsageCardMobile onBuyClick={buy} />
166
+
167
+ // RIGHT
168
+ <ScCreditsUsageCardMobile
169
+ usageText={`${used} / ${total}`}
170
+ remainingText={`${remaining} (${pct}%) Remaining`}
171
+ onBuyClick={buy}
172
+ />
173
+ ```
174
+
175
+ **2. No `progress` prop.** The desktop `ScCreditsUsageCard` draws a bar; this one
176
+ does not. The only percentage the user sees is the one you typed into
177
+ `remainingText`, so keep it consistent with `usageText` yourself.
178
+
179
+ **3. No `buyButtonState`.** You cannot disable the CTA through the card. If the
180
+ user must not buy (no permission, no payment method), don't render the card's
181
+ action path — conditionally render your own `ScButton` outside the card, or gate
182
+ inside `onBuyClick`.
183
+
184
+ **4. No `isLoading` / skeleton.** Its sibling `ScPlanDetailsCardMobile` *does*
185
+ have one. Passing `isLoading` here is a type error; render your own placeholder.
186
+
187
+ **5. `style` and `onClick` go to the card, not the button.** `...props` is spread
188
+ on the root `div`, so `onClick` makes the whole card clickable *in addition to*
189
+ the button. That is almost never what you want.
190
+
191
+ **6. `backdrop-filter: blur(4px)` on the root creates a containing block.** Any
192
+ `position: fixed` descendant (a portal-less popover, a sticky footer) will be
193
+ positioned against this card instead of the viewport.
194
+
195
+ **7. The header icon is not swappable.** `SiconCredits` is hardcoded, with its
196
+ colour pinned to `--alias-text-and-icons-tertiary`. There is no `icon` prop.
197
+
198
+ **8. `usageLabel` / `buyButtonText` are the only localisable strings.** Everything
199
+ else you supply, so a localised surface must format numbers and the word
200
+ "Remaining" itself.
201
+
202
+ ---
203
+
204
+ ## In the wild
205
+
206
+ ```tsx
207
+ // cxo-dashboard src/app/components/mobile-billing-content.tsx:171
208
+ <ScCreditsUsageCardMobile
209
+ usageText={usageText}
210
+ remainingText={remainingText}
211
+ onBuyClick={onBuyCredits}
212
+ className="w-full"
213
+ />
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Related
219
+
220
+ - `ScCreditsUsageCard` — the desktop twin; has `progress` and `buyButtonState`.
221
+ - `ScPlanDetailsCardMobile` — the card directly above it on the same screen.
222
+ - `CreditWarningBanner` — the alert form, driven by numbers not strings.
223
+ - `ScButton` — what the CTA actually is; `variant="secondary"`, `size="md"`.
224
+ - `UsageHistoryMobile` / `InvoiceHistoryMobile` — the list rows below the tabs.
@@ -0,0 +1,269 @@
1
+ ---
2
+ component: ScDefaultCard
3
+ package: "@streamoid/ui"
4
+ category: cards
5
+ status: stable
6
+ renders: div
7
+ tags: [card, option, choice, picker, default, hover, title, description, centered, catalogix]
8
+ related: [ScMappingCard, ScStoreCard, ScAppListingCard, ScRadio, ScTabField, ScModal, ScDrawer]
9
+ do_not_confuse_with: [ScAppListingCard, ScStoreCard, ScMappingCard, ScBriefCard, ScRadio]
10
+ used_by: [catalogix]
11
+ ---
12
+
13
+ # ScDefaultCard
14
+
15
+ **The generic "pick this option" card.** A full-width bordered box with a centred
16
+ title and an optional smaller description underneath. Two visual states — default
17
+ and hover — and nothing else: no icon, no badge, no button, no state machine.
18
+
19
+ ## TL;DR for agents
20
+
21
+ - **Reach for it when:** a screen asks "which of these routes do you want?" and each
22
+ route is a title plus a one-line cost/time hint — stacked vertically, often with
23
+ "or" separators between them.
24
+ - **Don't reach for it when:** the card needs an icon and lives in a grid
25
+ (→ `ScAppListingCard`), it carries a mapping lifecycle
26
+ (→ `ScMappingCard`), it's a store summary (→ `ScStoreCard`), or the choice is a
27
+ **form value you will save** (→ `ScRadio` / `ScTabField`).
28
+ - **Three things that will bite you:**
29
+ 1. `title` defaults to `"Title"` and `description` to `"Description"` — forget
30
+ either and you ship placeholder copy.
31
+ 2. `cursor: pointer` is baked in, but there is **no `role`, `tabIndex` or key
32
+ handling**. Every Catalogix call site hand-adds `role="button" tabIndex={0}`;
33
+ only the Products/taxonomy ones also add `onKeyDown` (ConnectOptions forgets
34
+ it — copy the Products version, not that one).
35
+ 3. `state="hover"` force-renders the hover skin. It is for Figma parity /
36
+ screenshots, **not** for wiring your own mouse handlers — real `:hover`
37
+ already works.
38
+
39
+ ---
40
+
41
+ ## 1. How to use it
42
+
43
+ ### Import
44
+
45
+ ```tsx
46
+ import { ScDefaultCard } from "@streamoid/ui";
47
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
48
+ ```
49
+
50
+ ### Minimal usage
51
+
52
+ ```tsx
53
+ <ScDefaultCard
54
+ title="Use Catalogix taxonomy"
55
+ description="Average Time : Instant."
56
+ role="button"
57
+ tabIndex={0}
58
+ onClick={choose}
59
+ />
60
+ ```
61
+
62
+ ### Props
63
+
64
+ | Prop | Type | Default | Notes |
65
+ |---|---|---|---|
66
+ | `title` | `string` | `"Title"` | ⚠️ Real default. `text-md-regular`, primary, centred, `word-break: break-word`. |
67
+ | `description` | `string` | `"Description"` | ⚠️ Real default. `text-xs-regular`, tertiary, centred. Only rendered when `showDescription` is true **and** the string is non-empty. |
68
+ | `showDescription` | `boolean` | `true` | ⚠️ Defaults to **true**, so the description renders unless you opt out. `false` → title-only card. |
69
+ | `state` | `"default"` \| `"hover"` | `"default"` | Forces the visual state. `"hover"` applies the same skin as real `:hover`. |
70
+ | `className` | `string` | – | Appended after the internal classes, so it wins on equal specificity. |
71
+ | `...props` | `HTMLAttributes<HTMLDivElement>` | – | `onClick`, `role`, `tabIndex`, `onKeyDown`, `style`, `aria-*`, `data-*` all land on the root div. |
72
+
73
+ ### What renders in each state
74
+
75
+ | Region | `state="default"` | `state="hover"` (or real `:hover`) |
76
+ |---|---|---|
77
+ | Background | `--alias-surface-base` | `--alias-surface-basesubtle` — ⚠️ **identical (`#ffffff`) in light mode** |
78
+ | Border | `--alias-border-subtle` | `--alias-border-default` — the only hover cue that survives light mode |
79
+ | Content | title (+ description if `showDescription && description`) | same |
80
+
81
+ ### Recipes
82
+
83
+ ```tsx
84
+ // The Catalogix idiom: a stack of routes with "or" separators, fully accessible
85
+ {OPTIONS.map((option, idx) => (
86
+ <Fragment key={option.key}>
87
+ <ScDefaultCard
88
+ title={option.title}
89
+ description={option.desc}
90
+ showDescription
91
+ role="button"
92
+ tabIndex={0}
93
+ onClick={() => setSelectedOption(option.key)}
94
+ onKeyDown={(e) => {
95
+ if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setSelectedOption(option.key); }
96
+ }}
97
+ />
98
+ {idx < OPTIONS.length - 1 && <div className="or-separator">or</div>}
99
+ </Fragment>
100
+ ))}
101
+
102
+ // Title-only card
103
+ <ScDefaultCard title="Start from scratch" showDescription={false} role="button" tabIndex={0} onClick={go} />
104
+
105
+ // Design-parity screenshot of the hover skin (never wire this to onMouseEnter)
106
+ <ScDefaultCard title="Use your own taxonomy" description="Average Time : 30 mins." state="hover" />
107
+ ```
108
+
109
+ ---
110
+
111
+ ## 2. Where to use it
112
+
113
+ - **Catalogix "Choose your store taxonomy"** — three stacked cards ("Use Catalogix
114
+ taxonomy" / "Use your own taxonomy" / "Copy from existing store"), separated by
115
+ "or".
116
+ - **Catalogix "Add Active Feed" → Connect options** — the same control, reused for
117
+ feed connection methods. The call site's own comment records that this card
118
+ *replaced* a hand-rolled `.option` + `.hr-divider-sm` block.
119
+ - Any **empty state or drawer that offers 2–4 mutually exclusive routes**, inside
120
+ `ScModal` / `ScDrawer` or a page-level empty state.
121
+
122
+ It composes nothing from the DS and is composed by nothing — you always place it.
123
+
124
+ ---
125
+
126
+ ## 3. When to use it
127
+
128
+ ### Use it when
129
+
130
+ - The card is a **navigation/branching choice**, and clicking it immediately does
131
+ something (opens a modal, pushes a route, selects a method).
132
+ - The content is exactly **title + optional one-line hint**, centred.
133
+ - Cards are stacked full-width, not tiled in a grid.
134
+
135
+ ### Don't use it — reach for this instead
136
+
137
+ | Situation | Use instead |
138
+ |---|---|
139
+ | Tile with an icon chip in a product grid | `ScAppListingCard` |
140
+ | Tile in the app-switcher grid (gradient border, `active`) | `ScAppCardV3` |
141
+ | Store summary (name, product count, status beacon) | `ScStoreCard` |
142
+ | A source→target mapping row with confirm/ignore lifecycle | `ScMappingCard` |
143
+ | A value-mapping/curation row with an "updated" dot | `ScValueMappingL1` |
144
+ | A **saved** single-choice form value | `ScRadio` (list) or `ScTabField` (segmented) |
145
+ | A filter/segmented view switch | `ScSelectionPill` / `ScSelectionPillGroup` |
146
+ | A row in a table | `ScTableList` / `ScCatalogixStoreTableList` |
147
+ | An agent quick-prompt card | `ScBriefCard` (via `ScQuickPrompt`) |
148
+ | The card needs a CTA button inside it | `ScPlanCard` / `ScWorkspaceSwitchCard`, or compose your own with `ScButton` |
149
+
150
+ ### Don't confuse with
151
+
152
+ | You may actually want | Not this |
153
+ |---|---|
154
+ | `ScAppListingCard` — icon + left-aligned title + description, scale-up hover, grid tile | `ScDefaultCard` is centred, full-width, chrome-light |
155
+ | `ScBriefCard` — centred description-only card with a coral gradient border (agent runtime) | This card has a plain subtle border and a title |
156
+ | `ScMappingCard` — three-status lifecycle + action footer | This card has no states beyond default/hover |
157
+ | `ScRadio` — a real form control with a selected state | This card has **no selected state at all** (see Gotcha 4) |
158
+
159
+ ---
160
+
161
+ ## 4. Why to use it
162
+
163
+ - **It removes a hand-rolled pattern that already existed twice.** The Catalogix
164
+ connect-options screen and the choose-taxonomy screen had independently built the
165
+ same box; both now render this card, so the padding, radius, hairline border and
166
+ hover feel are identical.
167
+ - **Light-mode-safe hover.** The hover recipe changes *both* the background and the
168
+ border. Because light mode collapses all `surface-*` tokens to white, the border
169
+ step is what keeps the hover legible — a hand-rolled card that only changes
170
+ background loses its hover entirely in light mode.
171
+ - **The hairline border is 0.5px** (`0.03125rem`), matching `ScStoreCard` and the
172
+ divider family rather than the 1px used by the app cards — consistent with the
173
+ Catalogix card language.
174
+ - **`state="hover"` gives you deterministic screenshots** for Figma parity checks
175
+ without simulating pointer events (headless Chrome cannot force `:hover`
176
+ reliably).
177
+ - **`word-break: break-word` on both lines**, so a long taxonomy name never blows
178
+ out the card width.
179
+
180
+ ---
181
+
182
+ ## Gotchas
183
+
184
+ **1. Placeholder defaults ship.** `title="Title"` and `description="Description"`
185
+ are real strings.
186
+
187
+ ```tsx
188
+ // WRONG — renders "Title" / "Description"
189
+ <ScDefaultCard onClick={go} />
190
+
191
+ // RIGHT
192
+ <ScDefaultCard title="Copy from existing store" description="Average Time : 1 min." onClick={go} />
193
+ ```
194
+
195
+ **2. Not keyboard accessible on its own.** `cursor: pointer` says "click me" but
196
+ there is no `role`, `tabIndex`, `onKeyDown` or focus ring. Always add:
197
+
198
+ ```tsx
199
+ <ScDefaultCard
200
+ title={o.title}
201
+ description={o.desc}
202
+ role="button"
203
+ tabIndex={0}
204
+ onClick={pick}
205
+ onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); pick(); } }}
206
+ />
207
+ ```
208
+
209
+ **3. `description=""` hides the line even with `showDescription` true.** The guard is
210
+ `showDescription && Boolean(description)`. That is usually what you want, but it
211
+ means an empty string and `showDescription={false}` are indistinguishable, and the
212
+ card's height changes between them — watch out in equal-height rows.
213
+
214
+ **4. There is no selected/active state.** `state` only has `default` and `hover`. If
215
+ your flow needs to show which option is currently chosen, you must add it via
216
+ `className` (or use `ScRadio` / `ScTabField` / `ScSelectionPill` instead). Both
217
+ Catalogix screens dodge this by navigating away on click.
218
+
219
+ **5. Hover's background change is invisible in light mode.** `surface-base` and
220
+ `surface-basesubtle` are both `#ffffff` in the light theme; only the border darkens.
221
+ Do not rely on the fill to communicate hover.
222
+
223
+ **6. `width: 100%` is baked in.** The card always fills its parent. To get a narrower
224
+ card, constrain the parent — setting `width` via `className` fights the module class
225
+ at equal specificity (yours wins because it is appended, but inline `style` is safer).
226
+
227
+ **7. `state="hover"` is design parity, not interaction.** Never drive it from
228
+ `onMouseEnter`; you would double up on the real `:hover` and break touch devices.
229
+
230
+ **8. No icon slot.** If your design shows a glyph above the title, this is the wrong
231
+ card — use `ScAppListingCard`, or render your own icon above a `ScDefaultCard`
232
+ (the Catalogix taxonomy screen puts `SiconStores` *outside* the cards, above the
233
+ heading).
234
+
235
+ ---
236
+
237
+ ## In the wild
238
+
239
+ ```tsx
240
+ // catalogix/dashboard app/containers/Products/index.jsx:1684
241
+ <ScDefaultCard
242
+ title="Use Catalogix taxonomy"
243
+ description="Average Time : Instant."
244
+ role="button"
245
+ tabIndex={0}
246
+ onClick={() => {
247
+ setShowCurationModal(true);
248
+ }}
249
+ onKeyDown={(e) => {
250
+ if (e.key === "Enter" || e.key === " ") {
251
+ e.preventDefault();
252
+ setShowCurationModal(true);
253
+ }
254
+ }}
255
+ />
256
+ ```
257
+
258
+ Also at `app/containers/StoreSettingsV2/FeedImport/Feed/ConnectOptions/index.jsx:67`
259
+ (feed connect methods) and twice more in `Products/index.jsx` (lines 1703, 1728).
260
+
261
+ ---
262
+
263
+ ## Related
264
+
265
+ - `ScMappingCard` — the feed-mapping card when you need a confirm/ignore lifecycle.
266
+ - `ScStoreCard` — the store-listing card (name + beacon + counts).
267
+ - `ScAppListingCard` / `ScAppCardV3` — icon-bearing product tiles for grids.
268
+ - `ScRadio` / `ScTabField` / `ScSelectionPillGroup` — when the choice is a saved value.
269
+ - `ScModal` / `ScDrawer` — the containers these cards usually sit in.