@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,246 @@
1
+ ---
2
+ component: ScPlanDetailsCard
3
+ package: "@streamoid/ui"
4
+ category: billing
5
+ status: stable
6
+ renders: div
7
+ tags: [current-plan, plan-summary, billing, subscription, active, badge, skeleton, loading, upgrade]
8
+ related: [ScPlanDetailsCardMobile, ScCreditsUsageCard, ScPlanCard, ScBadges, ScPairtext]
9
+ do_not_confuse_with: [ScPlanCard, ScPlanDetailsCardMobile, ScCreditsUsageCard, ScPlanComparison]
10
+ used_by: [cxo]
11
+ ---
12
+
13
+ # ScPlanDetailsCard
14
+
15
+ **The "this is the plan you're on" card at the top of the Billing page.** A
16
+ `Current plan` label with a billing icon, a green status badge, a divider, then
17
+ `Free · 30,000 credits` over `₹0.00 / month`, with a right-aligned CTA — plus a
18
+ built-in shimmer skeleton for while the subscription is still loading.
19
+
20
+ ## TL;DR for agents
21
+
22
+ - **Reach for it when:** you need the single current-subscription summary strip,
23
+ usually side by side with `ScCreditsUsageCard`.
24
+ - **Don't reach for it when:** you're rendering a *buyable* plan tile
25
+ (→ `ScPlanCard`), the mobile billing screen (→ `ScPlanDetailsCardMobile`), or the
26
+ credits meter (→ `ScCreditsUsageCard`).
27
+ - **Four things that will bite you:**
28
+ 1. `planPrice` must be the **whole** string including the period
29
+ (`"₹0.00 / month"`). `ScPlanCard.price` is the exact opposite — no period.
30
+ 2. The badge is **always `variant="success"` (green)** and is pinned to a
31
+ **53px width**. `"Active"` fits; `"Past due"` and `"Cancelled"` render green
32
+ and overflow that fixed width (`ScBadges` sets no `overflow: hidden` and no
33
+ `nowrap`, so the label wraps and the pill grows taller).
34
+ 3. `isLoading` replaces the badge, the text and the button with skeletons, so
35
+ `onUpgrade` is unreachable while loading.
36
+ 4. Its CTA is a default-`variant`/`type` `ScButton`, which paints a
37
+ `Math.random()` canvas noise texture — non-deterministic in snapshots, blank
38
+ in SSR.
39
+
40
+ ---
41
+
42
+ ## 1. How to use it
43
+
44
+ ### Import
45
+
46
+ ```tsx
47
+ import { ScPlanDetailsCard } from "@streamoid/ui";
48
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
49
+ ```
50
+
51
+ ### Minimal usage
52
+
53
+ ```tsx
54
+ <ScPlanDetailsCard
55
+ planName="Pro"
56
+ planCredits="30,000 credits"
57
+ planPrice="₹4,999.00 / month"
58
+ upgradeButtonText="Manage Plan"
59
+ onUpgrade={() => setShowPlans(true)}
60
+ />
61
+ ```
62
+
63
+ ### Props
64
+
65
+ | Prop | Type | Default | Notes |
66
+ |---|---|---|---|
67
+ | `planName` | `string` | `"Free"` | ⚠️ Real default. Left half of the dotted name row. |
68
+ | `planCredits` | `string` | `"30,000 credits"` | ⚠️ Real default. Right half of the dotted row. Pre-formatted by you. |
69
+ | `planPrice` | `string` | `"₹0.00 / month"` | ⚠️ Real default. Rendered verbatim — **include the period yourself**. |
70
+ | `badgeText` | `string` | `"Active"` | ⚠️ Real default. Badge label. Colour is fixed to success — see Gotcha 2. |
71
+ | `badgeSubText` | `string` | – | Optional muted text after a dot separator, e.g. `"Downgrades on 12 Aug"`. `nowrap`. |
72
+ | `currentPlanLabel` | `string` | `"Current plan"` | ⚠️ Real default. Header text beside the billing icon. |
73
+ | `upgradeButtonText` | `string` | `"Upgrade"` | ⚠️ Real default. CTA label. |
74
+ | `isLoading` | `boolean` | `false` | Swaps badge / name row / price / button for shimmer pills. |
75
+ | `onUpgrade` | `() => void` | – | CTA click. Not reachable while `isLoading`. |
76
+ | `className` | `string` | – | Appended to the root class. |
77
+ | `...props` | `HTMLAttributes<HTMLDivElement>` | – | Spread onto the root div (`style`, `onClick`, `data-*`, `aria-*`). |
78
+
79
+ ### What renders in each state
80
+
81
+ | Region | `isLoading={false}` | `isLoading={true}` |
82
+ |---|---|---|
83
+ | Header | billing icon + `currentPlanLabel` | same (never skeletonised) |
84
+ | Badge area | `ScBadges` + optional dot + `badgeSubText` | one 53×28 shimmer pill |
85
+ | Name row | `planName` · dot · `planCredits` | two shimmer pills, `aria-label="Loading plan details"` |
86
+ | Price | `planPrice` | one shimmer pill |
87
+ | CTA | `ScButton` (`size="md"`) | one 120×40 shimmer pill |
88
+
89
+ ### Recipes
90
+
91
+ ```tsx
92
+ // Live plan + a scheduled-downgrade note, loading-aware (the real CXO idiom)
93
+ <ScPlanDetailsCard
94
+ planName={planName}
95
+ planCredits={planCreditsText} // "30,000 credits"
96
+ planPrice={planAmount} // "₹4,999.00 / month"
97
+ badgeText="Active"
98
+ badgeSubText={scheduledDowngradeText} // undefined ⇒ dot + text omitted
99
+ currentPlanLabel="Current plan"
100
+ upgradeButtonText={downgradeScheduled ? "Cancel downgrade" : "Manage Plan"}
101
+ isLoading={isPlanDetailsLoading}
102
+ className="flex-1 min-w-0"
103
+ onUpgrade={handlePrimaryAction}
104
+ />
105
+
106
+ // Side by side with the credits meter — both must be flex-1 min-w-0 or the
107
+ // nowrap text inside will blow the row out
108
+ <div className="flex items-start w-full" style={{ gap: "var(--spacing-6xl)" }}>
109
+ <ScPlanDetailsCard className="flex-1 min-w-0" {...plan} />
110
+ <ScCreditsUsageCard className="flex-1 min-w-0" {...credits} />
111
+ </div>
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 2. Where to use it
117
+
118
+ - **Top-left card of the Billing overview**, paired with `ScCreditsUsageCard` in a
119
+ two-column row. One per page.
120
+ - Rendered from the shared **`@streamoid/settings`** billing page
121
+ (`packages/settings/src/billing-content.tsx`), which **CXO** mounts via
122
+ `src/app/components/settings-content.tsx`.
123
+ - This card does not adapt on its own — `.planInfo` is a fixed 2.875rem tall and its
124
+ text is `nowrap`. Below `md` you are expected to swap to
125
+ `ScPlanDetailsCardMobile`. Note that the shared settings billing page has **no
126
+ mobile branch** today: the only wiring of the mobile twin is CXO's
127
+ `src/app/components/mobile-billing-content.tsx:161`, reached from CXO's orphaned
128
+ local `billing-content.tsx`. Treat mobile billing as unwired until that moves
129
+ into `@streamoid/settings`.
130
+
131
+ ---
132
+
133
+ ## 3. When to use it
134
+
135
+ ### Use it when
136
+
137
+ - You need to state the **one** subscription currently in force, with a status
138
+ badge and a single primary action ("Manage Plan" / "Cancel downgrade").
139
+ - The data arrives async and you want the shimmer skeleton for free.
140
+
141
+ ### Don't use it — reach for this instead
142
+
143
+ | Situation | Use instead |
144
+ |---|---|
145
+ | A plan the user could switch to, with a price and an Upgrade CTA | `ScPlanCard` |
146
+ | Mobile/narrow billing screen | `ScPlanDetailsCardMobile` |
147
+ | Credits remaining / progress meter | `ScCreditsUsageCard` |
148
+ | Feature comparison between plans | `ScPlanComparison` |
149
+ | A generic titled card with a slot | `ScDefaultCard` |
150
+ | A status pill on its own | `ScBadges` |
151
+ | A non-success status ("Past due", "Cancelled") | Nothing here fits — the badge is hardcoded green. Render your own `ScBadges` above the card, or fix the DS first. |
152
+
153
+ ### Don't confuse with
154
+
155
+ | You may actually want | Not this |
156
+ |---|---|
157
+ | `ScPlanCard` — a buyable tile, price parsed, gradient Pro border | This is the read-only current-plan strip |
158
+ | `ScPlanDetailsCardMobile` — an identical prop list on a narrow, stacked layout | Not a responsive mode of this card; it is a separate export you must switch to yourself |
159
+ | `ScCreditsUsageCard` — same visual shell, same `ScPairtext` header, but a progress bar and a "Buy credits" CTA | Easy to mix up in a diff: both are 1.5rem-padded bordered cards with a header row and a divider |
160
+
161
+ ---
162
+
163
+ ## 4. Why to use it
164
+
165
+ - **The skeleton is already correct.** Five shimmer pills at the exact widths of
166
+ the real content, so the card doesn't reflow when data lands — a common source
167
+ of layout jank on billing pages.
168
+ - **The dotted `name · credits` row** uses a `::after` pseudo-dot in a 24px box,
169
+ matching the same separator used in the badge row and in the mobile twin.
170
+ - **Composed from DS parts** (`ScPairtext`, `ScBadges`, `ScHDivider`, `ScButton`),
171
+ so icon sizing, badge radius, divider colour and button height all track the
172
+ tokens rather than local guesses.
173
+
174
+ ---
175
+
176
+ ## Gotchas
177
+
178
+ **1. `planPrice` includes the period; `ScPlanCard.price` must not.** The two
179
+ sibling cards take opposite conventions.
180
+
181
+ ```tsx
182
+ // RIGHT here
183
+ <ScPlanDetailsCard planPrice="₹4,999.00 / month" />
184
+ // RIGHT there
185
+ <ScPlanCard price="₹4,999.00" /> // card appends "/ month"
186
+ ```
187
+
188
+ **2. The badge is green and 53px wide, always.** `variant="success"` is hardcoded
189
+ in the JSX and `.scBadgesInstance` sets `width: 3.3125rem !important`. `ScBadges`
190
+ has no `overflow: hidden` and no `white-space: nowrap`, so anything longer than
191
+ `"Active"` wraps inside that 53px box and makes the pill taller than the 28px
192
+ skeleton it replaces; nothing you pass makes it red or amber.
193
+ Use `badgeSubText` for the nuance ("Downgrades on 12 Aug") instead of trying to
194
+ recolour the badge.
195
+
196
+ **3. `isLoading` hides the CTA.** The button is replaced by a skeleton, so guard
197
+ against users being unable to act if a fetch hangs.
198
+
199
+ **4. Long text does not truncate — it overflows.** `.planName` is
200
+ `white-space: nowrap` with no `overflow: hidden`, and `.planInfo` is a fixed
201
+ 2.875rem tall. Give the card `min-width: 0` and keep `planCredits` short.
202
+
203
+ **5. You cannot add or change the CTA icon.** The JSX passes
204
+ `icon={<SiconHome />}` to `ScButton` without a `styleVariant`, so `ScButton`
205
+ renders label-only and the icon is dead code. There is no icon prop.
206
+
207
+ **6. The CTA is a `primary`/`primary` `ScButton`.** That combination generates a
208
+ canvas noise texture with `Math.random()` and needs a DOM — expect snapshot churn
209
+ and nothing painted during SSR. (See `SC-Button/README.md` Gotcha 7.)
210
+
211
+ **7. Missing `className` leaks the string `"undefined"` into the class list.** The
212
+ root is `styles.scPlanDetailsCard + " " + className`. Harmless visually, but it
213
+ shows up in DOM snapshots and breaks naive `class="…"` equality assertions.
214
+
215
+ **8. `onUpgrade` is not the only click target.** Because `...props` is spread onto
216
+ the root, a stray `onClick` you pass fires for clicks anywhere in the card,
217
+ including the CTA.
218
+
219
+ ---
220
+
221
+ ## In the wild
222
+
223
+ ```tsx
224
+ // npm-components packages/settings/src/billing-content.tsx:2027
225
+ <ScPlanDetailsCard
226
+ planName={planName}
227
+ planCredits={planCreditsText}
228
+ planPrice={planAmount}
229
+ badgeText="Active"
230
+ badgeSubText={scheduledDowngradeText}
231
+ currentPlanLabel="Current plan"
232
+ upgradeButtonText={subscription?.downgradeScheduled ? "Cancel downgrade" : "Manage Plan"}
233
+ isLoading={isPlanDetailsLoading}
234
+ className="flex-1 min-w-0"
235
+ onUpgrade={() => { /* log + open plans, or cancel the downgrade */ }}
236
+ />
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Related
242
+
243
+ - `ScPlanDetailsCardMobile` — the mobile twin, same prop names.
244
+ - `ScCreditsUsageCard` — the card that sits next to it.
245
+ - `ScPlanCard` — the buyable tiles the CTA navigates to.
246
+ - `ScBadges` / `ScPairtext` / `ScHDivider` / `ScButton` — the parts it composes.
@@ -0,0 +1,240 @@
1
+ ---
2
+ component: ScPlanDetailsCardMobile
3
+ package: "@streamoid/ui"
4
+ category: mobile
5
+ status: stable
6
+ renders: div
7
+ tags: [mobile, billing, plan, current-plan, upgrade, skeleton, loading, card, cxo]
8
+ related: [ScPlanDetailsCard, ScCreditsUsageCardMobile, ScPlanCard, ScBadges, ScButton]
9
+ do_not_confuse_with: [ScPlanDetailsCard, ScPlanCard, ScPlanComparison, ScCreditsUsageCardMobile]
10
+ used_by: [cxo]
11
+ ---
12
+
13
+ # ScPlanDetailsCardMobile
14
+
15
+ **The current-plan summary on CXO's mobile billing screen.** A bordered full-width
16
+ card: billing icon + "Current plan" label with a green `ScBadges` status on the
17
+ right, a divider, `planName · planCredits` with the price under it, and a
18
+ full-width **blue-gradient** Upgrade button. Has a built-in shimmer skeleton state.
19
+
20
+ ## TL;DR for agents
21
+
22
+ - **Reach for it when:** the mobile billing screen needs the "what plan am I on"
23
+ block at the top.
24
+ - **Don't reach for it when:** you're on desktop (→ `ScPlanDetailsCard`, identical
25
+ prop surface), you're rendering *purchasable* plans (→ `ScPlanCard`), or you want
26
+ a feature-by-plan grid (→ `ScPlanComparison`).
27
+ - **Five things that will bite you:**
28
+ 1. **The Upgrade button's gradient is a hardcoded inline `style`** — raw
29
+ `rgb()` blue, not tokens. It overrides `variant="primary"` and you cannot
30
+ change or theme it from outside.
31
+ 2. **The badge is always `variant="success"`.** There is no way to show a red
32
+ "Past due" or amber "Trialing" — `badgeText` only changes the words.
33
+ 3. **Every text prop has a demo default**, including `planPrice = "₹0.00 / month"`
34
+ — a rupee price on an app that bills in dollars.
35
+ 4. `isLoading` replaces the badge, the plan lines **and the button** with
36
+ skeletons, so `onUpgrade` is unreachable while loading.
37
+ 5. Its prop *types* are identical to the desktop `ScPlanDetailsCard` (only the
38
+ `planName` default differs: `"Pro"` here, `"Free"` there), which makes picking
39
+ the wrong one silent.
40
+
41
+ ---
42
+
43
+ ## 1. How to use it
44
+
45
+ ### Import
46
+
47
+ ```tsx
48
+ import { ScPlanDetailsCardMobile } from "@streamoid/ui";
49
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
50
+ ```
51
+
52
+ ### Minimal usage
53
+
54
+ ```tsx
55
+ <ScPlanDetailsCardMobile
56
+ planName={plan.name}
57
+ planCredits={`${plan.credits.toLocaleString()} credits`}
58
+ planPrice={`$${plan.price} / month`}
59
+ badgeText="Active"
60
+ onUpgrade={openUpgrade}
61
+ />
62
+ ```
63
+
64
+ ### Props
65
+
66
+ | Prop | Type | Default | Notes |
67
+ |---|---|---|---|
68
+ | `planName` | `string` | `"Pro"` | ⚠️ Demo default. First half of the `name · credits` line. |
69
+ | `planCredits` | `string` | `"30,000 credits"` | ⚠️ Demo default. Second half, after a dot separator. You append the word "credits". |
70
+ | `planPrice` | `string` | `"₹0.00 / month"` | ⚠️ Demo default **in rupees**. Grey sub-line. You format currency and period. |
71
+ | `badgeText` | `string` | `"Active"` | ⚠️ Text of the badge. The badge is hardwired to `variant="success"` / `styleVariant="opaque"`. |
72
+ | `badgeSubText` | `string` | – | Optional extra grey text after the badge, preceded by a 4px dot. Renders only when truthy. |
73
+ | `currentPlanLabel` | `string` | `"Current plan"` | ⚠️ Header label beside the billing icon. |
74
+ | `upgradeButtonText` | `string` | `"Upgrade"` | ⚠️ CTA label. |
75
+ | `isLoading` | `boolean` | `false` | Swaps badge, plan lines and button for shimmer skeletons. See the state table. |
76
+ | `onUpgrade` | `() => void` | – | The CTA's `onClick`. Unreachable while `isLoading`. |
77
+ | `className` | `string` | – | Appended after internal classes (safely — uses `className ?? ""`). |
78
+ | `...props` | `React.HTMLAttributes<HTMLDivElement>` | – | Spread onto the card root, **not** the button. |
79
+
80
+ ### What renders in each state
81
+
82
+ | Region | `isLoading={false}` | `isLoading={true}` |
83
+ |---|---|---|
84
+ | Header left | `SiconBilling` + `currentPlanLabel` | unchanged — always visible |
85
+ | Header right | `ScBadges` (success/opaque) + optional dot + `badgeSubText` | one 53×28 shimmer pill |
86
+ | Plan info | `planName` · `planCredits`, then `planPrice` | two inline pills (`aria-label="Loading plan details"`) + a price pill |
87
+ | Action | gradient `ScButton` with `upgradeButtonText` | one full-width 40px shimmer pill |
88
+
89
+ ### Recipes
90
+
91
+ ```tsx
92
+ // Real load-then-show, the CXO shape
93
+ <ScPlanDetailsCardMobile
94
+ isLoading={!plan}
95
+ planName={plan?.name ?? ""}
96
+ planCredits={plan ? `${plan.credits.toLocaleString("en-US")} credits` : ""}
97
+ planPrice={plan ? `$${plan.amount.toFixed(2)} / month` : ""}
98
+ badgeText={plan?.status === "active" ? "Active" : "Inactive"}
99
+ onUpgrade={() => setShowPlans(true)}
100
+ />
101
+
102
+ // Add a renewal note after the badge
103
+ <ScPlanDetailsCardMobile
104
+ planName="Pro"
105
+ planCredits="30,000 credits"
106
+ planPrice="$49.00 / month"
107
+ badgeText="Active"
108
+ badgeSubText="Renews Aug 12"
109
+ onUpgrade={openUpgrade}
110
+ />
111
+
112
+ // You want a non-green status? The badge can't do it — render your own beside the card.
113
+ // (badgeText="Past due" still renders GREEN.)
114
+ ```
115
+
116
+ ---
117
+
118
+ ## 2. Where to use it
119
+
120
+ - **CXO mobile billing screen**, the first block on the page, directly above
121
+ `ScCreditsUsageCardMobile` and the invoice/usage `ScTabSwitcher`.
122
+ - Any narrow single-column surface that needs a "your current subscription" summary
123
+ with one upgrade path.
124
+
125
+ It composes `SiconBilling`, one `ScBadges` and one `ScButton` internally. Don't nest
126
+ your own badge or button — use `badgeText` / `upgradeButtonText`.
127
+
128
+ ---
129
+
130
+ ## 3. When to use it
131
+
132
+ ### Use it when
133
+
134
+ - The viewport is the mobile breakpoint and the card must be full-width.
135
+ - The plan is a **fact to display**, with exactly one forward action (Upgrade).
136
+ - You want a skeleton state for free while the subscription request is in flight.
137
+
138
+ ### Don't use it — reach for this instead
139
+
140
+ | Situation | Use instead |
141
+ |---|---|
142
+ | Desktop billing page | `ScPlanDetailsCard` — same props, desktop metrics |
143
+ | A tile in a "choose a plan" grid (price, features, CTA) | `ScPlanCard` |
144
+ | Feature-by-plan comparison table | `ScPlanComparison` |
145
+ | Credits remaining / buy credits | `ScCreditsUsageCardMobile` |
146
+ | A status chip on its own, any colour | `ScBadges` directly |
147
+ | Non-green plan status (past due, canceled) | `ScBadges` beside a plain card — this component can't recolour its badge |
148
+
149
+ ### Don't confuse with
150
+
151
+ | You may actually want | Not this |
152
+ |---|---|
153
+ | `ScPlanDetailsCard` — the desktop twin with an **identical** prop list | Nothing in the types tells you which one you imported; check the `Mobile` suffix |
154
+ | `ScPlanCard` — a purchasable plan tile (formatted price, feature list) | This card describes the plan you already have |
155
+ | `ScCreditsUsageCardMobile` — same chrome, one slot lower on the screen | Credits, not plan; secondary button, not gradient |
156
+
157
+ ---
158
+
159
+ ## 4. Why to use it
160
+
161
+ - **The skeleton is already built.** Five separately-sized shimmer pills with a
162
+ shared 1.1s `skeletonShimmer` keyframe, and an `aria-label` on the plan row.
163
+ Hand-rolling that is where mobile billing screens usually look cheap.
164
+ - **Prop-identical to the desktop card**, so a responsive screen can pick the
165
+ component at the breakpoint and pass the same view-model object to both.
166
+ - **Card chrome is shared with `ScCreditsUsageCardMobile`** — `--radius-3xl`, 1px
167
+ `--alias-border-subtle`, `backdrop-filter: blur(4px)`, 16px padding — so the two
168
+ stacked cards line up exactly.
169
+ - **Correct token usage** (`--alias-text-and-icons-*`, `--alias-surface-base`), so
170
+ the card body genuinely flips light/dark — the gradient button is the one
171
+ exception (see Gotcha 1).
172
+
173
+ ---
174
+
175
+ ## Gotchas
176
+
177
+ **1. The Upgrade button's colour is an inline style you cannot reach.** The
178
+ component renders `variant="primary"` *and then* overrides its background with a
179
+ literal gradient:
180
+
181
+ ```tsx
182
+ style={{ backgroundImage: "linear-gradient(154deg, rgb(18, 57, 255) 0%, rgb(73, 206, 255) 100%)" }}
183
+ ```
184
+
185
+ Raw `rgb()`, no tokens, so it is the same blue in light and dark mode, and
186
+ `className` on the card can't win against an inline style on the button. If the
187
+ brand blue must change, change the DS.
188
+
189
+ **2. The badge is always green.** `variant="success"` is hardcoded.
190
+
191
+ ```tsx
192
+ // MISLEADING — renders "Past due" in success green
193
+ <ScPlanDetailsCardMobile badgeText="Past due" />
194
+ ```
195
+
196
+ **3. Demo defaults everywhere, and the price default is in rupees.** Rendering the
197
+ card bare gives you `Pro · 30,000 credits` / `₹0.00 / month` / `Active`, which looks
198
+ like real data in a screenshot.
199
+
200
+ **4. `isLoading` hides the CTA.** While loading there is no button at all, so
201
+ `onUpgrade` cannot fire. Don't rely on the button existing for focus management.
202
+
203
+ **5. `planCredits` is not a number.** You append the word "credits" (and do the
204
+ locale grouping). The card only inserts the dot separator.
205
+
206
+ **6. `badgeSubText` is dropped when falsy.** Empty string means "no dot, no text" —
207
+ which is usually what you want, but means you can't render a deliberate blank.
208
+
209
+ **7. `...props` lands on the card root.** `onClick` makes the *whole card*
210
+ clickable in addition to the Upgrade button; `style` restyles the card, never the
211
+ button.
212
+
213
+ **8. `backdrop-filter: blur(4px)` creates a containing block,** so any
214
+ `position: fixed` descendant anchors to this card rather than the viewport.
215
+
216
+ ---
217
+
218
+ ## In the wild
219
+
220
+ ```tsx
221
+ // cxo-dashboard src/app/components/mobile-billing-content.tsx:161
222
+ <ScPlanDetailsCardMobile
223
+ planName={planName}
224
+ planCredits={planCredits}
225
+ planPrice={planPrice}
226
+ badgeText={badgeText}
227
+ onUpgrade={onUpgrade}
228
+ className="w-full"
229
+ />
230
+ ```
231
+
232
+ ---
233
+
234
+ ## Related
235
+
236
+ - `ScPlanDetailsCard` — the desktop twin; identical props.
237
+ - `ScCreditsUsageCardMobile` — the credits card immediately below it.
238
+ - `ScPlanCard` / `ScPlanComparison` — the "choose a plan" surfaces.
239
+ - `ScBadges` — the status chip it renders; use directly if you need another colour.
240
+ - `ScButton` — the CTA, here with its background overridden.