@bravely-studios/account-web 0.3.10 → 0.4.1
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.
- package/README.md +159 -5
- package/dist/ActivationStateMachine.d.ts +1 -1
- package/dist/ActivationStateMachine.d.ts.map +1 -1
- package/dist/ActivationStateMachine.js +6 -2
- package/dist/ActivationStateMachine.js.map +1 -1
- package/dist/BravelyAccountManager.d.ts +108 -2
- package/dist/BravelyAccountManager.d.ts.map +1 -1
- package/dist/BravelyAccountManager.js +376 -29
- package/dist/BravelyAccountManager.js.map +1 -1
- package/dist/components/BravelyProviderButtons.d.ts.map +1 -1
- package/dist/components/BravelyProviderButtons.js.map +1 -1
- package/dist/components/BravelySignInScreen.d.ts +65 -0
- package/dist/components/BravelySignInScreen.d.ts.map +1 -0
- package/dist/components/BravelySignInScreen.js +156 -0
- package/dist/components/BravelySignInScreen.js.map +1 -0
- package/dist/components/OfferSlotGrid.d.ts +228 -0
- package/dist/components/OfferSlotGrid.d.ts.map +1 -0
- package/dist/components/OfferSlotGrid.js +554 -0
- package/dist/components/OfferSlotGrid.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/installMetrics.d.ts +40 -0
- package/dist/installMetrics.d.ts.map +1 -0
- package/dist/installMetrics.js +128 -0
- package/dist/installMetrics.js.map +1 -0
- package/dist/storage.d.ts +23 -10
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +52 -16
- package/dist/storage.js.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// `<OfferSlotGrid>` — the canonical 3-slot purchase component for the Bravely
|
|
3
|
+
// web family (login-first cutover D3, spec `commerce.offer_page_fit`).
|
|
4
|
+
//
|
|
5
|
+
// The web sibling of Swift `OfferSlotGrid` (bravely-account-swift) and C#
|
|
6
|
+
// `BravelyOfferGrid` (Bravely.Account): three equal-width offer cards side by
|
|
7
|
+
// side (HOOK → GSO/Annual → FRONT_LTV/Lifetime) with the center GSO card
|
|
8
|
+
// visually dominant, cloning the `get.bravely.dev` purchase surface.
|
|
9
|
+
//
|
|
10
|
+
// Source-of-truth specs (clone targets — do NOT drift):
|
|
11
|
+
// - offer model (LOCKED 2026-05-31, names LOCKED 2026-06-01):
|
|
12
|
+
// `00 - AI Instructions/bravely-offer-structure.md`
|
|
13
|
+
// - web reference: `bravely-get/src/landing/{config.ts,LandingTemplate.tsx}`
|
|
14
|
+
// + the offer CSS in `bravely-get/src/app/globals.css`
|
|
15
|
+
//
|
|
16
|
+
// Geometry (spec `commerce.offer_page_fit`, option 3 — web viewport fit;
|
|
17
|
+
// v1.2 HEIGHT-FIRST, Jeff field feedback 2026-06-11):
|
|
18
|
+
// - HEIGHT-FIRST scale-to-fit, INCLUDING scale-up: the scale fills
|
|
19
|
+
// `viewportHeight × 0.92`; width binds only as a cap at
|
|
20
|
+
// `viewportWidth × 0.95` (cap binds ⇒ scale = min of both axes).
|
|
21
|
+
// Clamped to [0.5, 3.0].
|
|
22
|
+
// - Below 0.5× the scale floors at 0.5 and the page scrolls — NEVER clip.
|
|
23
|
+
// - NO max-width column cap (the old `max-w-[84rem]` cap is gone; on large
|
|
24
|
+
// displays the grid scales up past it edge-to-edge).
|
|
25
|
+
// - Below the 3-up breakpoint (901px) cards stack single-column and scroll
|
|
26
|
+
// naturally (three tall cards can't sensibly fit one phone screen).
|
|
27
|
+
// - Slot-card BASELINE ALIGNMENT (v1.2): in the 3-up layout the cards share
|
|
28
|
+
// row tracks (CSS subgrid) so every section row (name / tagline / price /
|
|
29
|
+
// price-sub / bullets / guarantee / bonus / nudge / CTA) equalizes to its
|
|
30
|
+
// tallest sibling — the LTV card's missing "/mo" unit can't pull its
|
|
31
|
+
// content up — and the CTA is pinned to the card bottom.
|
|
32
|
+
//
|
|
33
|
+
// Slots: the grid renders EXACTLY the `slots` it is given — provisioned
|
|
34
|
+
// slots only (J5). `buildOfferSlots()` produces the locked 3-slot copy;
|
|
35
|
+
// hosts filter it if a slot is unprovisioned for their surface.
|
|
36
|
+
//
|
|
37
|
+
// Analytics hooks (spec `analytics.install_path`): `onSlotViewed` fires once
|
|
38
|
+
// per rendered slot per mount (`slot_viewed`); `onSelect` is the
|
|
39
|
+
// `slot_selected` + checkout entry point. The host fires `paywall_shown`
|
|
40
|
+
// when it presents the page containing this grid.
|
|
41
|
+
//
|
|
42
|
+
// Brand compliance (HARD RULES):
|
|
43
|
+
// - NO payment-processor / infra names in any customer-visible string.
|
|
44
|
+
// - No "Name — descriptor" em-dash AI-voice: the plan NAME is bare
|
|
45
|
+
// ("Bravely Premium") and the plan word ("Annual"/"Lifetime") rides a
|
|
46
|
+
// muted descriptor span.
|
|
47
|
+
//
|
|
48
|
+
// Usage:
|
|
49
|
+
//
|
|
50
|
+
// ```tsx
|
|
51
|
+
// import {
|
|
52
|
+
// OfferSlotGrid,
|
|
53
|
+
// buildOfferSlots,
|
|
54
|
+
// offerThemeForSlug,
|
|
55
|
+
// planTokenForSlot,
|
|
56
|
+
// } from "@bravely-studios/account-web";
|
|
57
|
+
//
|
|
58
|
+
// <OfferSlotGrid
|
|
59
|
+
// slots={buildOfferSlots({ appName: "Scry", appSlug: "scry", type: "RVA" })}
|
|
60
|
+
// theme={offerThemeForSlug("scry")}
|
|
61
|
+
// onSelect={(slot) => {
|
|
62
|
+
// posthog.capture("slot_selected", { offer_slot: telemetryValueForSlot(slot) });
|
|
63
|
+
// manager.openCheckout(planTokenForSlot(slot, "RVA"));
|
|
64
|
+
// }}
|
|
65
|
+
// onSlotViewed={(slot) => posthog.capture("slot_viewed", { offer_slot: telemetryValueForSlot(slot) })}
|
|
66
|
+
// />
|
|
67
|
+
// ```
|
|
68
|
+
import { useEffect, useRef, } from "react";
|
|
69
|
+
// ---- Locked copy constants --------------------------------------------------
|
|
70
|
+
/** The 30-day guarantee label. */
|
|
71
|
+
export const OFFER_GUARANTEE_LINE = "30-Day Money-Back Guarantee";
|
|
72
|
+
/** Hover/disclosure tooltip for the guarantee badge. */
|
|
73
|
+
export const OFFER_GUARANTEE_TOOLTIP = "I-Hate-Your-Apps-Give-Me-My-Money-Back: 30 days, no questions.";
|
|
74
|
+
/** Footer note under the whole grid. */
|
|
75
|
+
export const OFFER_FOOTER_NOTE = "Bravely Studios · one account, every device.";
|
|
76
|
+
/** Footer line inside both bonus blocks. */
|
|
77
|
+
export const OFFER_BONUS_FOOTER = "One sign-in · instant unlock · sync everywhere";
|
|
78
|
+
/**
|
|
79
|
+
* The LOCKED value-stack-dominant tagline (2026-06-01) rendered under the
|
|
80
|
+
* plan name on BOTH bundle slots. Verbatim from `bravely-offer-structure.md`.
|
|
81
|
+
*/
|
|
82
|
+
export const OFFER_BUNDLE_TAGLINE = "all 9 apps, every platform, every device, + the bonus bundle";
|
|
83
|
+
/**
|
|
84
|
+
* Slot-1 nudge (v1.2 LOCKED, 2026-06-11): "the other 8 apps" — icons row 3
|
|
85
|
+
* + "+ 5 more" = 8 OTHER apps (9 in all incl. this one). ~~"other 9 apps"~~
|
|
86
|
+
* was wrong.
|
|
87
|
+
*/
|
|
88
|
+
const NUDGE = [
|
|
89
|
+
{ text: "Want the other 8 apps free? " },
|
|
90
|
+
{ text: "Go Annual →", em: "accent" },
|
|
91
|
+
];
|
|
92
|
+
// ---- Per-app themes (verbatim from the get.bravely.dev registry) ------------
|
|
93
|
+
/** Per-app offer themes for the 9 production utilities. */
|
|
94
|
+
export const OFFER_THEMES = {
|
|
95
|
+
scry: { accent: "#a78bfa", accentStrong: "#8b5cf6", cyan: "#22d3ee" },
|
|
96
|
+
printscreenly: { accent: "#ff6b6b", accentStrong: "#e05555", cyan: "#ee5a9f" },
|
|
97
|
+
asapdf: { accent: "#FFD60A", accentStrong: "#F0C000", cyan: "#FB923C" },
|
|
98
|
+
stickily: { accent: "#FFD93D", accentStrong: "#E0BF33", cyan: "#61A8DB" },
|
|
99
|
+
saycopypaste: { accent: "#0EA5E9", accentStrong: "#0284C7", cyan: "#34D399" },
|
|
100
|
+
diskaroo: { accent: "#06b6d4", accentStrong: "#0e7490", cyan: "#3b82f6" },
|
|
101
|
+
terminaltags: { accent: "#d97706", accentStrong: "#b45309", cyan: "#3b9be6" },
|
|
102
|
+
markdly: { accent: "#268559", accentStrong: "#1B6240", cyan: "#5AC8FA" },
|
|
103
|
+
todoingly: { accent: "#3B6EF0", accentStrong: "#1D4ED8", cyan: "#34D399" },
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Resolve a theme from the canonical app slug. Falls back to Scry's
|
|
107
|
+
* purple/cyan if the slug is unknown (mirrors the Swift lib).
|
|
108
|
+
*/
|
|
109
|
+
export function offerThemeForSlug(slug) {
|
|
110
|
+
return OFFER_THEMES[slug.toLowerCase()] ?? OFFER_THEMES.scry;
|
|
111
|
+
}
|
|
112
|
+
// ---- Slot ↔ plan/telemetry mapping ------------------------------------------
|
|
113
|
+
/**
|
|
114
|
+
* The catalog plan token `openCheckout()` should send for a slot. Slot-1
|
|
115
|
+
* tokens are interval-true per the 2026-06-10 catalog rename: `monthly` for
|
|
116
|
+
* RVA apps, `onetime` for IVA apps (the server also aliases legacy tokens,
|
|
117
|
+
* but new clients send the canonical key). GSO/FRONT_LTV resolve server-side
|
|
118
|
+
* to the universal bundle plans.
|
|
119
|
+
*/
|
|
120
|
+
export function planTokenForSlot(slot, type) {
|
|
121
|
+
switch (slot) {
|
|
122
|
+
case "HOOK":
|
|
123
|
+
return type === "IVA" ? "onetime" : "monthly";
|
|
124
|
+
case "GSO":
|
|
125
|
+
return "annual";
|
|
126
|
+
case "FRONT_LTV":
|
|
127
|
+
return "lifetime";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Telemetry value per the count-funnel spec (`offer_slot` property). */
|
|
131
|
+
export function telemetryValueForSlot(slot) {
|
|
132
|
+
switch (slot) {
|
|
133
|
+
case "HOOK":
|
|
134
|
+
return "hook";
|
|
135
|
+
case "GSO":
|
|
136
|
+
return "gso";
|
|
137
|
+
case "FRONT_LTV":
|
|
138
|
+
return "ltv";
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// ---- Bonus apps (the ordering rule) -----------------------------------------
|
|
142
|
+
const CANONICAL_BONUS_APPS = [
|
|
143
|
+
{ name: "Scry", note: "Remote desktop", slug: "scry" },
|
|
144
|
+
{ name: "PrintScreen.ly", note: "Screenshots & recording", slug: "printscreenly" },
|
|
145
|
+
{ name: "ASAPDF", note: "PDF edit, sign, share", slug: "asapdf" },
|
|
146
|
+
];
|
|
147
|
+
const BONUS_SUBSTITUTE = {
|
|
148
|
+
name: "Diskaroo",
|
|
149
|
+
note: "Disk-space visualizer",
|
|
150
|
+
slug: "diskaroo",
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* The canonical bonus-bundle example apps, in order: Scry → PrintScreen.ly →
|
|
154
|
+
* ASAPDF, "+ 5 more". Collision rule: if `<app>` IS one of those 3, drop it
|
|
155
|
+
* and append Diskaroo so the customer always sees 3 *other* apps.
|
|
156
|
+
*/
|
|
157
|
+
export function bonusAppsForSlug(slug) {
|
|
158
|
+
const normalized = slug.toLowerCase();
|
|
159
|
+
const apps = CANONICAL_BONUS_APPS.filter((a) => a.slug !== normalized);
|
|
160
|
+
if (apps.length < 3)
|
|
161
|
+
apps.push(BONUS_SUBSTITUTE);
|
|
162
|
+
return apps.slice(0, 3).map((a) => ({ ...a }));
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Build the canonical 3-slot offer copy — the verbatim strings from the
|
|
166
|
+
* locked offer structure, so every app's purchase surface reads identically
|
|
167
|
+
* (only `<App>` swaps). Render a subset by filtering the result (provisioned
|
|
168
|
+
* slots only).
|
|
169
|
+
*/
|
|
170
|
+
export function buildOfferSlots(args) {
|
|
171
|
+
const { appName, appSlug, type } = args;
|
|
172
|
+
const slug = appSlug.toLowerCase();
|
|
173
|
+
const extra = [...(args.extraHookBullets ?? [])];
|
|
174
|
+
// Scry-only extra HOOK bullet (E2E encryption) per the locked reference.
|
|
175
|
+
if (slug === "scry" && !extra.includes("End-to-end encrypted, peer-to-peer")) {
|
|
176
|
+
extra.push("End-to-end encrypted, peer-to-peer");
|
|
177
|
+
}
|
|
178
|
+
const bonusApps = bonusAppsForSlug(slug).map((a) => ({
|
|
179
|
+
...a,
|
|
180
|
+
iconSrc: args.bonusIconSrc?.(a.slug),
|
|
181
|
+
}));
|
|
182
|
+
const hook = type === "RVA"
|
|
183
|
+
? {
|
|
184
|
+
kind: "HOOK",
|
|
185
|
+
name: "Monthly",
|
|
186
|
+
tagline: "Start free",
|
|
187
|
+
priceBig: "$0.00",
|
|
188
|
+
priceUnit: "for 7 days",
|
|
189
|
+
priceSub: [
|
|
190
|
+
{ text: "then " },
|
|
191
|
+
{ text: "$9.99/mo", em: "accent" },
|
|
192
|
+
{ text: " · cancel anytime" },
|
|
193
|
+
],
|
|
194
|
+
bullets: [`Get ${appName} on all platforms`, "Full Pro access", ...extra, "Cancel anytime"],
|
|
195
|
+
nudge: NUDGE,
|
|
196
|
+
cta: "ghost",
|
|
197
|
+
ctaLabel: "Start free",
|
|
198
|
+
}
|
|
199
|
+
: {
|
|
200
|
+
kind: "HOOK",
|
|
201
|
+
name: "One-Time",
|
|
202
|
+
tagline: "Just this app",
|
|
203
|
+
priceBig: "$19.99",
|
|
204
|
+
priceUnit: "once",
|
|
205
|
+
priceSub: [{ text: "yours forever · all platforms" }],
|
|
206
|
+
bullets: [`Get ${appName} on all platforms`, ...extra, "Pay once — no subscription"],
|
|
207
|
+
guarantee: OFFER_GUARANTEE_LINE,
|
|
208
|
+
nudge: NUDGE,
|
|
209
|
+
cta: "ghost",
|
|
210
|
+
ctaLabel: `Get ${appName}`,
|
|
211
|
+
};
|
|
212
|
+
const gso = {
|
|
213
|
+
kind: "GSO",
|
|
214
|
+
badge: "Best Value",
|
|
215
|
+
name: "Bravely Premium",
|
|
216
|
+
nameSub: "Annual",
|
|
217
|
+
tagline: OFFER_BUNDLE_TAGLINE,
|
|
218
|
+
priceBig: "$7.99",
|
|
219
|
+
priceUnit: "/mo",
|
|
220
|
+
priceSub: [{ text: "$95.99 billed annually" }],
|
|
221
|
+
bullets: [`Get ${appName} on all platforms`, "Best per-month price"],
|
|
222
|
+
guarantee: OFFER_GUARANTEE_LINE,
|
|
223
|
+
bonus: {
|
|
224
|
+
label: "Bonus",
|
|
225
|
+
// v1.2 LOCKED bonus headline (2026-06-11): cyan "the 8 other premium
|
|
226
|
+
// utilities" + " — 9 apps in all" tail. BYTE-IDENTICAL across surfaces.
|
|
227
|
+
headline: [
|
|
228
|
+
{ text: "FREE full access to " },
|
|
229
|
+
{ text: "the 8 other premium utilities", em: "cyan" },
|
|
230
|
+
{ text: " — 9 apps in all" },
|
|
231
|
+
],
|
|
232
|
+
apps: bonusApps,
|
|
233
|
+
more: "+ 5 more",
|
|
234
|
+
value: "$500 value",
|
|
235
|
+
footer: OFFER_BONUS_FOOTER,
|
|
236
|
+
},
|
|
237
|
+
cta: "loud",
|
|
238
|
+
ctaLabel: "Get the Best Value",
|
|
239
|
+
highlighted: true,
|
|
240
|
+
};
|
|
241
|
+
const ltv = {
|
|
242
|
+
kind: "FRONT_LTV",
|
|
243
|
+
name: "Bravely Premium",
|
|
244
|
+
nameSub: "Lifetime",
|
|
245
|
+
tagline: OFFER_BUNDLE_TAGLINE,
|
|
246
|
+
priceBig: "$399",
|
|
247
|
+
priceSub: [{ text: "all future updates included" }],
|
|
248
|
+
bullets: [`Get ${appName} on all platforms`, "Pay once, yours forever"],
|
|
249
|
+
guarantee: OFFER_GUARANTEE_LINE,
|
|
250
|
+
bonus: {
|
|
251
|
+
label: "Bonus",
|
|
252
|
+
// v1.2 LOCKED bonus headline (LTV variant keeps the accent "lifetime"
|
|
253
|
+
// span). BYTE-IDENTICAL across surfaces.
|
|
254
|
+
headline: [
|
|
255
|
+
{ text: "FREE " },
|
|
256
|
+
{ text: "lifetime", em: "accent" },
|
|
257
|
+
{ text: " access to " },
|
|
258
|
+
{ text: "the 8 other premium utilities", em: "cyan" },
|
|
259
|
+
{ text: " — 9 apps in all" },
|
|
260
|
+
],
|
|
261
|
+
apps: bonusApps.map((a) => ({ ...a })),
|
|
262
|
+
more: "+ 5 more",
|
|
263
|
+
value: "$1,200 value",
|
|
264
|
+
footer: OFFER_BONUS_FOOTER,
|
|
265
|
+
},
|
|
266
|
+
cta: "solid",
|
|
267
|
+
ctaLabel: "Own it for life",
|
|
268
|
+
};
|
|
269
|
+
return [hook, gso, ltv];
|
|
270
|
+
}
|
|
271
|
+
// ---- Viewport fit (spec `commerce.offer_page_fit`, option 3; v1.2 HEIGHT-FIRST)
|
|
272
|
+
/** Below this viewport width the cards stack single-column + scroll. */
|
|
273
|
+
export const OFFER_FIT_MIN_WIDTH = 901;
|
|
274
|
+
/** Scale clamp floor — below this the scale floors and the page scrolls. */
|
|
275
|
+
export const OFFER_FIT_MIN_SCALE = 0.5;
|
|
276
|
+
/** Scale clamp ceiling — scale-up allowed to fill large displays. */
|
|
277
|
+
export const OFFER_FIT_MAX_SCALE = 3.0;
|
|
278
|
+
/**
|
|
279
|
+
* @deprecated v1.2 (2026-06-11): the height-first formula replaced the
|
|
280
|
+
* fixed-pad math with the 0.92/0.95 work-area fractions. Kept exported so
|
|
281
|
+
* existing imports keep compiling; `computeOfferFit` ignores `pad` now.
|
|
282
|
+
*/
|
|
283
|
+
export const OFFER_FIT_PAD = 24;
|
|
284
|
+
/** HEIGHT-FIRST (v1.2): the offer fills this fraction of the viewport height. */
|
|
285
|
+
export const OFFER_FIT_HEIGHT_FRACTION = 0.92;
|
|
286
|
+
/** HEIGHT-FIRST (v1.2): scaled content width is capped at this viewport fraction. */
|
|
287
|
+
export const OFFER_FIT_WIDTH_CAP_FRACTION = 0.95;
|
|
288
|
+
/** The grid's natural design width (px) used as the scale-fit basis. */
|
|
289
|
+
export const OFFER_NATURAL_WIDTH = 1200;
|
|
290
|
+
/**
|
|
291
|
+
* The canonical fit formula (plan §4, v1.2 HEIGHT-FIRST, Jeff field feedback
|
|
292
|
+
* 2026-06-11): the scale is chosen so the scaled grid FILLS
|
|
293
|
+
* `viewportHeight × 0.92`; the width only binds as a cap — if the scaled
|
|
294
|
+
* natural width would exceed `viewportWidth × 0.95`, the scale drops to the
|
|
295
|
+
* min of both axes. Clamped to [0.5, 3.0]; below 0.5 the scale floors and
|
|
296
|
+
* the surface falls back to scrolling — never clipping. Pure so tests can
|
|
297
|
+
* pin the math.
|
|
298
|
+
*
|
|
299
|
+
* The single-arg signature is unchanged from v1.1 and is the offer-step
|
|
300
|
+
* formula (the sign-in step never scales — it renders compact natural,
|
|
301
|
+
* see `SIGN_IN_COMPACT_MAX_WIDTH`).
|
|
302
|
+
*/
|
|
303
|
+
export function computeOfferFit(input) {
|
|
304
|
+
if (input.viewportWidth < OFFER_FIT_MIN_WIDTH)
|
|
305
|
+
return { mode: "stacked" };
|
|
306
|
+
if (!(input.naturalWidth > 0) || !(input.naturalHeight > 0)) {
|
|
307
|
+
return { mode: "fit", scale: 1, scrollFallback: false, widthCapBound: false };
|
|
308
|
+
}
|
|
309
|
+
const heightScale = (input.viewportHeight * OFFER_FIT_HEIGHT_FRACTION) / input.naturalHeight;
|
|
310
|
+
const widthCapScale = (input.viewportWidth * OFFER_FIT_WIDTH_CAP_FRACTION) / input.naturalWidth;
|
|
311
|
+
const raw = Math.min(heightScale, widthCapScale);
|
|
312
|
+
const scale = Math.min(Math.max(raw, OFFER_FIT_MIN_SCALE), OFFER_FIT_MAX_SCALE);
|
|
313
|
+
return {
|
|
314
|
+
mode: "fit",
|
|
315
|
+
scale,
|
|
316
|
+
scrollFallback: raw < OFFER_FIT_MIN_SCALE,
|
|
317
|
+
widthCapBound: widthCapScale < heightScale,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
const SYSTEM_FONT = '-apple-system, BlinkMacSystemFont, "Segoe UI Variable", "Segoe UI", Roboto, "Inter", "Helvetica Neue", Arial, sans-serif';
|
|
321
|
+
/**
|
|
322
|
+
* Render the canonical 3-up offer grid with full-viewport scale-to-fit.
|
|
323
|
+
* Mount it on a near-full-viewport surface; it owns its own scaling.
|
|
324
|
+
*/
|
|
325
|
+
export function OfferSlotGrid(props) {
|
|
326
|
+
const { slots, theme, onSelect, onSlotViewed, header, footerNote = OFFER_FOOTER_NOTE, guaranteeTooltip = OFFER_GUARANTEE_TOOLTIP, fitToViewport = true, naturalWidth = OFFER_NATURAL_WIDTH, isBusy = false, className, containerStyle, } = props;
|
|
327
|
+
const outerRef = useRef(null);
|
|
328
|
+
const innerRef = useRef(null);
|
|
329
|
+
// slot_viewed: once per slot per mount (cards mount together on web).
|
|
330
|
+
const viewedRef = useRef(new Set());
|
|
331
|
+
useEffect(() => {
|
|
332
|
+
for (const slot of slots) {
|
|
333
|
+
if (viewedRef.current.has(slot.kind))
|
|
334
|
+
continue;
|
|
335
|
+
viewedRef.current.add(slot.kind);
|
|
336
|
+
onSlotViewed?.(slot.kind);
|
|
337
|
+
}
|
|
338
|
+
// Fire for newly-added slots only; identity changes of the callback or
|
|
339
|
+
// re-renders of the same slots must not re-fire.
|
|
340
|
+
}, [slots, onSlotViewed]);
|
|
341
|
+
// FitToViewport-style measurement, extended with scale-UP (D3).
|
|
342
|
+
useEffect(() => {
|
|
343
|
+
if (!fitToViewport)
|
|
344
|
+
return;
|
|
345
|
+
const inEl = innerRef.current;
|
|
346
|
+
const outEl = outerRef.current;
|
|
347
|
+
if (!inEl || !outEl || typeof window === "undefined")
|
|
348
|
+
return;
|
|
349
|
+
const fit = () => {
|
|
350
|
+
// Reset to measure the natural size at the design width.
|
|
351
|
+
inEl.style.transform = "";
|
|
352
|
+
outEl.style.height = "";
|
|
353
|
+
// Available width = the smaller of the viewport and the host container
|
|
354
|
+
// (so a padded host can't cause horizontal clipping).
|
|
355
|
+
const outerW = outEl.clientWidth || window.innerWidth;
|
|
356
|
+
const availWidth = Math.min(window.innerWidth, outerW);
|
|
357
|
+
if (computeOfferFit({
|
|
358
|
+
viewportWidth: availWidth,
|
|
359
|
+
viewportHeight: window.innerHeight,
|
|
360
|
+
naturalWidth,
|
|
361
|
+
naturalHeight: 1,
|
|
362
|
+
}).mode === "stacked") {
|
|
363
|
+
inEl.style.width = "";
|
|
364
|
+
return; // natural single-column layout + scroll
|
|
365
|
+
}
|
|
366
|
+
// Lay the grid out at its NATURAL design width (it may exceed the
|
|
367
|
+
// container — the transform below brings it back inside). No max-width
|
|
368
|
+
// clamp: clamping before measuring would shrink the layout and feed
|
|
369
|
+
// the fit math a lie (the old 84rem-cap class of bug).
|
|
370
|
+
inEl.style.width = `${naturalWidth}px`;
|
|
371
|
+
const naturalH = inEl.scrollHeight;
|
|
372
|
+
if (!naturalH)
|
|
373
|
+
return; // not laid out yet (SSR/test DOM)
|
|
374
|
+
const refit = computeOfferFit({
|
|
375
|
+
viewportWidth: availWidth,
|
|
376
|
+
viewportHeight: window.innerHeight,
|
|
377
|
+
naturalWidth,
|
|
378
|
+
naturalHeight: naturalH,
|
|
379
|
+
});
|
|
380
|
+
const scale = refit.mode === "fit" ? refit.scale : 1;
|
|
381
|
+
// Scale about the top-LEFT then translate to center horizontally:
|
|
382
|
+
// when the inner block is wider than its container, `margin: auto`
|
|
383
|
+
// can't center it and a center origin would clip one side.
|
|
384
|
+
const tx = (outerW - naturalWidth * scale) / 2;
|
|
385
|
+
inEl.style.transformOrigin = "top left";
|
|
386
|
+
inEl.style.transform = `translateX(${tx}px) scale(${scale})`;
|
|
387
|
+
outEl.style.height = `${naturalH * scale}px`;
|
|
388
|
+
};
|
|
389
|
+
fit();
|
|
390
|
+
window.addEventListener("resize", fit);
|
|
391
|
+
const t = setTimeout(fit, 150);
|
|
392
|
+
const fonts = document.fonts;
|
|
393
|
+
if (fonts?.ready) {
|
|
394
|
+
void fonts.ready.then(fit).catch(() => undefined);
|
|
395
|
+
}
|
|
396
|
+
return () => {
|
|
397
|
+
window.removeEventListener("resize", fit);
|
|
398
|
+
clearTimeout(t);
|
|
399
|
+
};
|
|
400
|
+
}, [fitToViewport, naturalWidth, slots.length]);
|
|
401
|
+
const vars = {
|
|
402
|
+
["--bvy-accent"]: theme.accent,
|
|
403
|
+
["--bvy-accent-strong"]: theme.accentStrong,
|
|
404
|
+
["--bvy-cyan"]: theme.cyan,
|
|
405
|
+
fontFamily: SYSTEM_FONT,
|
|
406
|
+
color: "#f5f3ff",
|
|
407
|
+
width: "100%",
|
|
408
|
+
...containerStyle,
|
|
409
|
+
};
|
|
410
|
+
return (_jsxs("div", { className: className, style: vars, "data-bravely-component": "offer-slot-grid", "data-bravely-offer-grid": "", children: [_jsx("style", { children: OFFER_GRID_CSS }), _jsx("div", { ref: outerRef, style: { overflow: "hidden", width: "100%" }, children: _jsxs("div", { ref: innerRef, children: [header, _jsx("div", { className: "bvy-offer-grid", children: slots.map((slot) => (_jsx(SlotCard, { slot: slot, guaranteeTooltip: guaranteeTooltip, isBusy: isBusy, onSelect: onSelect }, slot.kind))) }), footerNote ? _jsx("div", { className: "bvy-offer-footnote", children: footerNote }) : null] }) })] }));
|
|
411
|
+
}
|
|
412
|
+
// ---- Internals ------------------------------------------------------------------
|
|
413
|
+
function RichText({ parts }) {
|
|
414
|
+
return (_jsx(_Fragment, { children: parts.map((p, i) => p.em ? (_jsx("span", { className: p.em === "accent" ? "bvy-em-accent" : "bvy-em-cyan", children: p.text }, i)) : (_jsx("span", { children: p.text }, i))) }));
|
|
415
|
+
}
|
|
416
|
+
function CheckIcon() {
|
|
417
|
+
return (_jsx("svg", { "aria-hidden": true, viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { d: "M16.7 5.3a1 1 0 0 1 0 1.4l-7.5 7.5a1 1 0 0 1-1.4 0L3.3 9.7a1 1 0 1 1 1.4-1.4l3.1 3.1 6.8-6.8a1 1 0 0 1 1.1-.3z" }) }));
|
|
418
|
+
}
|
|
419
|
+
function ShieldIcon() {
|
|
420
|
+
return (_jsxs("svg", { "aria-hidden": true, width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M12 3l7 3v6c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6z" }), _jsx("path", { d: "M9 12l2 2 4-4" })] }));
|
|
421
|
+
}
|
|
422
|
+
function Sparkle() {
|
|
423
|
+
return (_jsx("svg", { "aria-hidden": true, viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 2l1.7 5.6L19.3 9.3l-5.6 1.7L12 16.6l-1.7-5.6L4.7 9.3l5.6-1.7z" }) }));
|
|
424
|
+
}
|
|
425
|
+
function SlotCard({ slot, guaranteeTooltip, isBusy, onSelect, }) {
|
|
426
|
+
return (_jsxs("div", { className: `bvy-offer-card${slot.highlighted ? " bvy-gso" : ""}`, "data-bravely-slot": slot.kind, children: [slot.badge && _jsx("span", { className: "bvy-best-badge", children: slot.badge }), _jsxs("div", { className: "bvy-plan-name", children: [slot.name, slot.nameSub && _jsx("span", { className: "bvy-plan-name-sub", children: slot.nameSub })] }), _jsx("span", { className: "bvy-plan-tag", children: slot.tagline }), _jsxs("div", { className: "bvy-price", children: [_jsx("span", { className: "bvy-price-big", children: slot.priceBig }), slot.priceUnit && _jsx("span", { className: "bvy-price-unit", children: slot.priceUnit })] }), slot.priceSub && (_jsx("div", { className: "bvy-price-sub", children: _jsx(RichText, { parts: slot.priceSub }) })), _jsx("ul", { className: "bvy-offer-bullets", children: slot.bullets.map((b) => (_jsxs("li", { children: [_jsx(CheckIcon, {}), _jsx("span", { children: b })] }, b))) }), slot.guarantee && (_jsxs("div", { className: "bvy-offer-guarantee", title: guaranteeTooltip, children: [_jsx(ShieldIcon, {}), slot.guarantee] })), slot.bonus && (_jsxs("div", { className: "bvy-offer-bonus", children: [_jsxs("span", { className: "bvy-bonus-tag", children: [_jsx(Sparkle, {}), slot.bonus.label] }), _jsx("div", { className: "bvy-bonus-head", children: _jsx(RichText, { parts: slot.bonus.headline }) }), slot.bonus.apps.map((a) => (_jsxs("div", { className: "bvy-bonus-app", children: [_jsx("span", { className: "bvy-bonus-ic", children: a.iconSrc ? (_jsx("img", { src: a.iconSrc, alt: `${a.name} icon`, width: 40, height: 40 })) : (_jsx("span", { className: "bvy-bonus-monogram", "aria-hidden": true, children: a.name.slice(0, 1) })) }), _jsxs("span", { children: [_jsx("span", { className: "bvy-bonus-app-name", children: a.name }), _jsx("br", {}), _jsx("span", { className: "bvy-bonus-app-desc", children: a.note })] })] }, a.slug))), _jsx("div", { className: "bvy-bonus-more", children: slot.bonus.more }), _jsx("span", { className: "bvy-value-pill", children: slot.bonus.value }), _jsx("div", { className: "bvy-value-foot", children: slot.bonus.footer })] })), slot.nudge && (_jsx("div", { className: "bvy-offer-nudge", children: _jsx(RichText, { parts: slot.nudge }) })), _jsx("div", { className: "bvy-offer-spacer" }), _jsx("div", { className: "bvy-cta-wrap", children: _jsx("button", { type: "button", className: `bvy-cta${slot.cta === "ghost" ? " bvy-ghost" : slot.cta === "loud" ? " bvy-loud" : ""}`, disabled: isBusy, onClick: () => onSelect(slot.kind), "aria-label": slot.ctaLabel, "data-bravely-slot-cta": slot.kind, children: slot.ctaLabel }) })] }));
|
|
427
|
+
}
|
|
428
|
+
// Faithful translation of the get.bravely.dev offer CSS (globals.css), scoped
|
|
429
|
+
// under the component's data attribute with `bvy-` class prefixes so host
|
|
430
|
+
// styles can't collide. Theme colors ride the --bvy-* custom properties.
|
|
431
|
+
const OFFER_GRID_CSS = `
|
|
432
|
+
[data-bravely-offer-grid] .bvy-offer-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; align-items: stretch; }
|
|
433
|
+
@media (max-width: 900px) { [data-bravely-offer-grid] .bvy-offer-grid { grid-template-columns: 1fr; max-width: 460px; margin: 0 auto; gap: 16px; } }
|
|
434
|
+
@media (max-width: 560px) {
|
|
435
|
+
[data-bravely-offer-grid] .bvy-offer-card { padding: 24px 18px 20px; border-radius: 18px; }
|
|
436
|
+
[data-bravely-offer-grid] .bvy-price-big { font-size: 36px; }
|
|
437
|
+
[data-bravely-offer-grid] .bvy-bonus-head { font-size: 14.5px; }
|
|
438
|
+
}
|
|
439
|
+
[data-bravely-offer-grid] .bvy-offer-card {
|
|
440
|
+
position: relative; display: flex; flex-direction: column;
|
|
441
|
+
background: linear-gradient(180deg, #1e153f, #190f36);
|
|
442
|
+
border: 1px solid rgba(167, 139, 250, 0.18); border-radius: 20px;
|
|
443
|
+
padding: 30px 24px 24px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.45);
|
|
444
|
+
color: #f5f3ff;
|
|
445
|
+
}
|
|
446
|
+
[data-bravely-offer-grid] .bvy-offer-card.bvy-gso {
|
|
447
|
+
border: 2px solid var(--bvy-accent-strong);
|
|
448
|
+
background:
|
|
449
|
+
radial-gradient(420px 220px at 50% -40px, rgba(34, 211, 238, 0.12), rgba(34, 211, 238, 0) 70%),
|
|
450
|
+
linear-gradient(180deg, #241852, #190f36);
|
|
451
|
+
box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.16), 0 30px 70px rgba(139, 92, 246, 0.3);
|
|
452
|
+
}
|
|
453
|
+
[data-bravely-offer-grid] .bvy-best-badge {
|
|
454
|
+
position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
|
|
455
|
+
background: linear-gradient(90deg, var(--bvy-cyan), var(--bvy-accent));
|
|
456
|
+
color: #0b0716; font-weight: 800; font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase;
|
|
457
|
+
padding: 7px 18px; border-radius: 999px; box-shadow: 0 8px 22px rgba(34, 211, 238, 0.4); white-space: nowrap;
|
|
458
|
+
}
|
|
459
|
+
[data-bravely-offer-grid] .bvy-plan-name { font-size: 24px; font-weight: 800; letter-spacing: -0.01em; margin-top: 2px; }
|
|
460
|
+
[data-bravely-offer-grid] .bvy-plan-name-sub { margin-left: 8px; font-weight: 400; color: #8b82a8; }
|
|
461
|
+
[data-bravely-offer-grid] .bvy-plan-tag { display: block; color: #8b82a8; font-size: 14.5px; margin-top: 4px; min-height: 18px; }
|
|
462
|
+
[data-bravely-offer-grid] .bvy-price { margin: 16px 0 4px; display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
|
|
463
|
+
[data-bravely-offer-grid] .bvy-price-big { font-size: 42px; font-weight: 800; letter-spacing: -0.03em; line-height: 1; }
|
|
464
|
+
[data-bravely-offer-grid] .bvy-gso .bvy-price-big { color: var(--bvy-cyan); }
|
|
465
|
+
[data-bravely-offer-grid] .bvy-price-unit { font-size: 18px; font-weight: 700; color: #8b82a8; }
|
|
466
|
+
[data-bravely-offer-grid] .bvy-price-sub { color: #8b82a8; font-size: 14.5px; }
|
|
467
|
+
[data-bravely-offer-grid] .bvy-em-accent { color: var(--bvy-accent); font-weight: 800; }
|
|
468
|
+
[data-bravely-offer-grid] .bvy-em-cyan { color: var(--bvy-cyan); font-weight: 800; }
|
|
469
|
+
[data-bravely-offer-grid] .bvy-offer-bullets { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
|
|
470
|
+
[data-bravely-offer-grid] .bvy-offer-bullets li { display: flex; gap: 9px; align-items: flex-start; font-size: 15.5px; color: #e7e2ff; }
|
|
471
|
+
[data-bravely-offer-grid] .bvy-offer-bullets li svg { width: 18px; height: 18px; flex: 0 0 auto; margin-top: 1px; color: var(--bvy-cyan); }
|
|
472
|
+
[data-bravely-offer-grid] .bvy-offer-guarantee {
|
|
473
|
+
display: flex; align-items: center; gap: 8px; margin-top: 16px;
|
|
474
|
+
background: rgba(52, 211, 153, 0.1); border: 1px solid rgba(52, 211, 153, 0.32); color: #34d399;
|
|
475
|
+
font-size: 13.5px; font-weight: 700; padding: 9px 12px; border-radius: 10px;
|
|
476
|
+
}
|
|
477
|
+
[data-bravely-offer-grid] .bvy-offer-bonus {
|
|
478
|
+
position: relative; margin-top: 24px;
|
|
479
|
+
background: linear-gradient(180deg, rgba(34, 211, 238, 0.06), rgba(139, 92, 246, 0.05));
|
|
480
|
+
border: 1.5px dashed rgba(34, 211, 238, 0.45); border-radius: 16px; padding: 28px 16px 16px;
|
|
481
|
+
}
|
|
482
|
+
[data-bravely-offer-grid] .bvy-bonus-tag {
|
|
483
|
+
position: absolute; top: -15px; left: 50%; transform: translateX(-50%) rotate(-2deg);
|
|
484
|
+
display: inline-flex; align-items: center; gap: 7px;
|
|
485
|
+
background: linear-gradient(95deg, var(--bvy-accent-strong), var(--bvy-cyan));
|
|
486
|
+
color: #0b0716; font-weight: 900; font-size: 14px; letter-spacing: 0.22em; text-transform: uppercase; padding: 8px 22px;
|
|
487
|
+
clip-path: polygon(8px 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 8px 100%, 0 50%);
|
|
488
|
+
box-shadow: 0 10px 26px rgba(34, 211, 238, 0.45); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
|
|
489
|
+
}
|
|
490
|
+
[data-bravely-offer-grid] .bvy-bonus-tag svg { width: 14px; height: 14px; }
|
|
491
|
+
[data-bravely-offer-grid] .bvy-bonus-head { text-align: center; font-size: 15.5px; font-weight: 800; line-height: 1.35; color: #f5f3ff; margin: 2px 6px 14px; }
|
|
492
|
+
[data-bravely-offer-grid] .bvy-bonus-app { display: flex; gap: 11px; align-items: center; padding: 8px 6px; }
|
|
493
|
+
[data-bravely-offer-grid] .bvy-bonus-app + .bvy-bonus-app { border-top: 1px solid rgba(167, 139, 250, 0.12); }
|
|
494
|
+
[data-bravely-offer-grid] .bvy-bonus-ic {
|
|
495
|
+
flex: 0 0 auto; width: 40px; height: 40px; border-radius: 10px; overflow: hidden;
|
|
496
|
+
display: flex; align-items: center; justify-content: center;
|
|
497
|
+
background: rgba(167, 139, 250, 0.08); box-shadow: inset 0 0 0 1px rgba(167, 139, 250, 0.2);
|
|
498
|
+
}
|
|
499
|
+
[data-bravely-offer-grid] .bvy-bonus-ic img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
500
|
+
[data-bravely-offer-grid] .bvy-bonus-monogram { font-size: 16px; font-weight: 800; color: var(--bvy-accent); }
|
|
501
|
+
[data-bravely-offer-grid] .bvy-bonus-app-name { font-size: 15.5px; font-weight: 800; }
|
|
502
|
+
[data-bravely-offer-grid] .bvy-bonus-app-desc { font-size: 13px; color: #8b82a8; }
|
|
503
|
+
[data-bravely-offer-grid] .bvy-bonus-more { font-size: 14px; font-weight: 800; color: var(--bvy-accent); text-align: center; padding: 8px; }
|
|
504
|
+
[data-bravely-offer-grid] .bvy-value-pill {
|
|
505
|
+
display: block; text-align: center; margin: 12px auto 0; width: max-content;
|
|
506
|
+
background: linear-gradient(90deg, var(--bvy-accent-strong), var(--bvy-cyan)); color: #0b0716;
|
|
507
|
+
font-weight: 900; font-size: 22px; padding: 8px 24px; border-radius: 999px; box-shadow: 0 8px 20px rgba(139, 92, 246, 0.4);
|
|
508
|
+
}
|
|
509
|
+
[data-bravely-offer-grid] .bvy-value-foot { text-align: center; font-size: 12.5px; color: #8b82a8; margin-top: 10px; }
|
|
510
|
+
[data-bravely-offer-grid] .bvy-offer-nudge {
|
|
511
|
+
margin-top: 20px; text-align: center; font-size: 12.5px; color: #8b82a8;
|
|
512
|
+
border: 1px dashed rgba(167, 139, 250, 0.25); border-radius: 12px; padding: 12px;
|
|
513
|
+
}
|
|
514
|
+
[data-bravely-offer-grid] .bvy-offer-spacer { flex: 1 1 auto; }
|
|
515
|
+
[data-bravely-offer-grid] .bvy-cta-wrap { margin-top: 22px; }
|
|
516
|
+
[data-bravely-offer-grid] .bvy-cta {
|
|
517
|
+
display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
|
|
518
|
+
border: 0; cursor: pointer; font-family: inherit; font-weight: 800; font-size: 16.5px; padding: 15px 18px;
|
|
519
|
+
border-radius: 13px; color: #0b0716; background: linear-gradient(90deg, var(--bvy-accent), var(--bvy-accent-strong));
|
|
520
|
+
box-shadow: 0 12px 28px rgba(139, 92, 246, 0.35); transition: transform 0.12s ease;
|
|
521
|
+
}
|
|
522
|
+
[data-bravely-offer-grid] .bvy-cta.bvy-ghost { background: transparent; color: #f5f3ff; border: 1.5px solid rgba(167, 139, 250, 0.4); box-shadow: none; }
|
|
523
|
+
[data-bravely-offer-grid] .bvy-cta.bvy-loud { background: linear-gradient(90deg, var(--bvy-cyan), var(--bvy-accent)); font-size: 17.5px; box-shadow: 0 14px 34px rgba(34, 211, 238, 0.42); }
|
|
524
|
+
[data-bravely-offer-grid] .bvy-cta:hover { transform: translateY(-2px); }
|
|
525
|
+
[data-bravely-offer-grid] .bvy-cta:disabled { opacity: 0.7; cursor: default; transform: none; }
|
|
526
|
+
[data-bravely-offer-grid] .bvy-offer-footnote { margin-top: 28px; text-align: center; font-size: 12px; color: #8b82a8; }
|
|
527
|
+
/* Slot-card BASELINE ALIGNMENT (v1.2): in the 3-up layout the cards share the
|
|
528
|
+
parent's row tracks via subgrid, so each section row (name / tagline /
|
|
529
|
+
price / price-sub / bullets / guarantee / bonus / nudge / spacer / CTA)
|
|
530
|
+
equalizes to its tallest sibling and the CTA pins to the card bottom.
|
|
531
|
+
Cards missing a section (no "/mo" on LTV, no bonus on HOOK, no guarantee
|
|
532
|
+
on the RVA HOOK) leave the shared track empty instead of pulling their
|
|
533
|
+
content up. Non-subgrid browsers keep the flex-column card (CTA still
|
|
534
|
+
bottom-pinned by the spacer); stacked mode (<=900px) is unaffected.
|
|
535
|
+
MUST stay LAST in this stylesheet — it overrides the base flex card at
|
|
536
|
+
equal specificity. */
|
|
537
|
+
@supports (grid-template-rows: subgrid) {
|
|
538
|
+
@media (min-width: 901px) {
|
|
539
|
+
[data-bravely-offer-grid] .bvy-offer-grid { grid-template-rows: repeat(8, auto) 1fr auto; gap: 0 20px; }
|
|
540
|
+
[data-bravely-offer-grid] .bvy-offer-card { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: subgrid; grid-row: 1 / span 10; }
|
|
541
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-plan-name { grid-row: 1; }
|
|
542
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-plan-tag { grid-row: 2; }
|
|
543
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-price { grid-row: 3; }
|
|
544
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-price-sub { grid-row: 4; }
|
|
545
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-offer-bullets { grid-row: 5; }
|
|
546
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-offer-guarantee { grid-row: 6; align-self: start; }
|
|
547
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-offer-bonus { grid-row: 7; }
|
|
548
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-offer-nudge { grid-row: 8; align-self: start; }
|
|
549
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-offer-spacer { grid-row: 9; }
|
|
550
|
+
[data-bravely-offer-grid] .bvy-offer-card .bvy-cta-wrap { grid-row: 10; display: flex; }
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
`;
|
|
554
|
+
//# sourceMappingURL=OfferSlotGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OfferSlotGrid.js","sourceRoot":"","sources":["../../src/components/OfferSlotGrid.tsx"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,uEAAuE;AACvE,EAAE;AACF,0EAA0E;AAC1E,8EAA8E;AAC9E,yEAAyE;AACzE,qEAAqE;AACrE,EAAE;AACF,wDAAwD;AACxD,gEAAgE;AAChE,wDAAwD;AACxD,+EAA+E;AAC/E,2DAA2D;AAC3D,EAAE;AACF,yEAAyE;AACzE,sDAAsD;AACtD,qEAAqE;AACrE,4DAA4D;AAC5D,qEAAqE;AACrE,6BAA6B;AAC7B,4EAA4E;AAC5E,6EAA6E;AAC7E,yDAAyD;AACzD,6EAA6E;AAC7E,wEAAwE;AACxE,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,yEAAyE;AACzE,6DAA6D;AAC7D,EAAE;AACF,wEAAwE;AACxE,wEAAwE;AACxE,gEAAgE;AAChE,EAAE;AACF,6EAA6E;AAC7E,iEAAiE;AACjE,yEAAyE;AACzE,kDAAkD;AAClD,EAAE;AACF,iCAAiC;AACjC,yEAAyE;AACzE,qEAAqE;AACrE,0EAA0E;AAC1E,6BAA6B;AAC7B,EAAE;AACF,SAAS;AACT,EAAE;AACF,SAAS;AACT,WAAW;AACX,mBAAmB;AACnB,qBAAqB;AACrB,uBAAuB;AACvB,sBAAsB;AACtB,yCAAyC;AACzC,EAAE;AACF,iBAAiB;AACjB,+EAA+E;AAC/E,sCAAsC;AACtC,0BAA0B;AAC1B,qFAAqF;AACrF,2DAA2D;AAC3D,OAAO;AACP,yGAAyG;AACzG,KAAK;AACL,MAAM;AAEN,OAAO,EACL,SAAS,EACT,MAAM,GAIP,MAAM,OAAO,CAAC;AAqFf,gFAAgF;AAEhF,kCAAkC;AAClC,MAAM,CAAC,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAClE,wDAAwD;AACxD,MAAM,CAAC,MAAM,uBAAuB,GAClC,gEAAgE,CAAC;AACnE,wCAAwC;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,8CAA8C,CAAC;AAChF,4CAA4C;AAC5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,gDAAgD,CAAC;AACnF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAC/B,8DAA8D,CAAC;AAEjE;;;;GAIG;AACH,MAAM,KAAK,GAAc;IACvB,EAAE,IAAI,EAAE,8BAA8B,EAAE;IACxC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE;CACtC,CAAC;AAEF,gFAAgF;AAEhF,2DAA2D;AAC3D,MAAM,CAAC,MAAM,YAAY,GAA+B;IACtD,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACrE,aAAa,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IAC9E,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACvE,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACzE,YAAY,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IAC7E,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACzE,YAAY,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IAC7E,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACxE,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;CAC3E,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAmB,EAAE,IAAkB;IACtE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAChD,KAAK,KAAK;YACR,OAAO,QAAQ,CAAC;QAClB,KAAK,WAAW;YACd,OAAO,UAAU,CAAC;IACtB,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,qBAAqB,CAAC,IAAmB;IACvD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB,KAAK,KAAK;YACR,OAAO,KAAK,CAAC;QACf,KAAK,WAAW;YACd,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF,MAAM,oBAAoB,GAAoB;IAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE;IACtD,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,yBAAyB,EAAE,IAAI,EAAE,eAAe,EAAE;IAClF,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,QAAQ,EAAE;CAClE,CAAC;AACF,MAAM,gBAAgB,GAAkB;IACtC,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,uBAAuB;IAC7B,IAAI,EAAE,UAAU;CACjB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACvE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAoBD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAyB;IACvD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,yEAAyE;IACzE,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,oCAAoC,CAAC,EAAE,CAAC;QAC7E,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,GAAG,CAAC;QACJ,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;KACrC,CAAC,CAAC,CAAC;IAEJ,MAAM,IAAI,GACR,IAAI,KAAK,KAAK;QACZ,CAAC,CAAC;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,YAAY;YACrB,QAAQ,EAAE,OAAO;YACjB,SAAS,EAAE,YAAY;YACvB,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,OAAO,EAAE;gBACjB,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE;gBAClC,EAAE,IAAI,EAAE,mBAAmB,EAAE;aAC9B;YACD,OAAO,EAAE,CAAC,OAAO,OAAO,mBAAmB,EAAE,iBAAiB,EAAE,GAAG,KAAK,EAAE,gBAAgB,CAAC;YAC3F,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,YAAY;SACvB;QACH,CAAC,CAAC;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,eAAe;YACxB,QAAQ,EAAE,QAAQ;YAClB,SAAS,EAAE,MAAM;YACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,+BAA+B,EAAE,CAAC;YACrD,OAAO,EAAE,CAAC,OAAO,OAAO,mBAAmB,EAAE,GAAG,KAAK,EAAE,4BAA4B,CAAC;YACpF,SAAS,EAAE,oBAAoB;YAC/B,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,OAAO,OAAO,EAAE;SAC3B,CAAC;IAER,MAAM,GAAG,GAAkB;QACzB,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,oBAAoB;QAC7B,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAC,OAAO,OAAO,mBAAmB,EAAE,sBAAsB,CAAC;QACpE,SAAS,EAAE,oBAAoB;QAC/B,KAAK,EAAE;YACL,KAAK,EAAE,OAAO;YACd,qEAAqE;YACrE,wEAAwE;YACxE,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,sBAAsB,EAAE;gBAChC,EAAE,IAAI,EAAE,+BAA+B,EAAE,EAAE,EAAE,MAAM,EAAE;gBACrD,EAAE,IAAI,EAAE,kBAAkB,EAAE;aAC7B;YACD,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,kBAAkB;SAC3B;QACD,GAAG,EAAE,MAAM;QACX,QAAQ,EAAE,oBAAoB;QAC9B,WAAW,EAAE,IAAI;KAClB,CAAC;IAEF,MAAM,GAAG,GAAkB;QACzB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,UAAU;QACnB,OAAO,EAAE,oBAAoB;QAC7B,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC;QACnD,OAAO,EAAE,CAAC,OAAO,OAAO,mBAAmB,EAAE,yBAAyB,CAAC;QACvE,SAAS,EAAE,oBAAoB;QAC/B,KAAK,EAAE;YACL,KAAK,EAAE,OAAO;YACd,sEAAsE;YACtE,yCAAyC;YACzC,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,OAAO,EAAE;gBACjB,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE;gBAClC,EAAE,IAAI,EAAE,aAAa,EAAE;gBACvB,EAAE,IAAI,EAAE,+BAA+B,EAAE,EAAE,EAAE,MAAM,EAAE;gBACrD,EAAE,IAAI,EAAE,kBAAkB,EAAE;aAC7B;YACD,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,kBAAkB;SAC3B;QACD,GAAG,EAAE,OAAO;QACZ,QAAQ,EAAE,iBAAiB;KAC5B,CAAC;IAEF,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,kFAAkF;AAElF,wEAAwE;AACxE,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC,qEAAqE;AACrE,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAChC,iFAAiF;AACjF,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAC9C,qFAAqF;AACrF,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AACjD,wEAAwE;AACxE,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AA6BxC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,KAAoB;IAClD,IAAI,KAAK,CAAC,aAAa,GAAG,mBAAmB;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC1E,IAAI,CAAC,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAChF,CAAC;IACD,MAAM,WAAW,GACf,CAAC,KAAK,CAAC,cAAc,GAAG,yBAAyB,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC;IAC3E,MAAM,aAAa,GACjB,CAAC,KAAK,CAAC,aAAa,GAAG,4BAA4B,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,mBAAmB,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAChF,OAAO;QACL,IAAI,EAAE,KAAK;QACX,KAAK;QACL,cAAc,EAAE,GAAG,GAAG,mBAAmB;QACzC,aAAa,EAAE,aAAa,GAAG,WAAW;KAC3C,CAAC;AACJ,CAAC;AAsCD,MAAM,WAAW,GACf,0HAA0H,CAAC;AAE7H;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EACJ,KAAK,EACL,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,UAAU,GAAG,iBAAiB,EAC9B,gBAAgB,GAAG,uBAAuB,EAC1C,aAAa,GAAG,IAAI,EACpB,YAAY,GAAG,mBAAmB,EAClC,MAAM,GAAG,KAAK,EACd,SAAS,EACT,cAAc,GACf,GAAG,KAAK,CAAC;IAEV,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAE9C,sEAAsE;IACtE,MAAM,SAAS,GAAG,MAAM,CAAqB,IAAI,GAAG,EAAE,CAAC,CAAC;IACxD,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC/C,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjC,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,uEAAuE;QACvE,iDAAiD;IACnD,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;IAE1B,gEAAgE;IAChE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa;YAAE,OAAO;QAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QAE7D,MAAM,GAAG,GAAG,GAAS,EAAE;YACrB,yDAAyD;YACzD,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;YAC1B,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;YACxB,uEAAuE;YACvE,sDAAsD;YACtD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC;YACtD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACvD,IAAI,eAAe,CAAC;gBAClB,aAAa,EAAE,UAAU;gBACzB,cAAc,EAAE,MAAM,CAAC,WAAW;gBAClC,YAAY;gBACZ,aAAa,EAAE,CAAC;aACjB,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;gBACtB,OAAO,CAAC,wCAAwC;YAClD,CAAC;YACD,kEAAkE;YAClE,uEAAuE;YACvE,oEAAoE;YACpE,uDAAuD;YACvD,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,YAAY,IAAI,CAAC;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC;YACnC,IAAI,CAAC,QAAQ;gBAAE,OAAO,CAAC,kCAAkC;YACzD,MAAM,KAAK,GAAG,eAAe,CAAC;gBAC5B,aAAa,EAAE,UAAU;gBACzB,cAAc,EAAE,MAAM,CAAC,WAAW;gBAClC,YAAY;gBACZ,aAAa,EAAE,QAAQ;aACxB,CAAC,CAAC;YACH,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,kEAAkE;YAClE,mEAAmE;YACnE,2DAA2D;YAC3D,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/C,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,UAAU,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,cAAc,EAAE,aAAa,KAAK,GAAG,CAAC;YAC7D,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,QAAQ,GAAG,KAAK,IAAI,CAAC;QAC/C,CAAC,CAAC;QAEF,GAAG,EAAE,CAAC;QACN,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAI,QAAqD,CAAC,KAAK,CAAC;QAC3E,IAAI,KAAK,EAAE,KAAK,EAAE,CAAC;YACjB,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAC1C,YAAY,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAkB;QAC1B,CAAC,cAAwB,CAAC,EAAE,KAAK,CAAC,MAAM;QACxC,CAAC,qBAA+B,CAAC,EAAE,KAAK,CAAC,YAAY;QACrD,CAAC,YAAsB,CAAC,EAAE,KAAK,CAAC,IAAI;QACpC,UAAU,EAAE,WAAW;QACvB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,MAAM;QACb,GAAG,cAAc;KAClB,CAAC;IAEF,OAAO,CACL,eACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,IAAI,4BACY,iBAAiB,6BAChB,EAAE,aAE1B,0BAAQ,cAAc,GAAS,EAC/B,cAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,YAI9D,eAAK,GAAG,EAAE,QAAQ,aACf,MAAM,EACP,cAAK,SAAS,EAAC,gBAAgB,YAC5B,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACnB,KAAC,QAAQ,IAEP,IAAI,EAAE,IAAI,EACV,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,IAJb,IAAI,CAAC,IAAI,CAKd,CACH,CAAC,GACE,EACL,UAAU,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,oBAAoB,YAAE,UAAU,GAAO,CAAC,CAAC,CAAC,IAAI,IACvE,GACF,IACF,CACP,CAAC;AACJ,CAAC;AAED,oFAAoF;AAEpF,SAAS,QAAQ,CAAC,EAAE,KAAK,EAAwB;IAC/C,OAAO,CACL,4BACG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAClB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACL,eAAc,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,YACzE,CAAC,CAAC,IAAI,IADE,CAAC,CAEL,CACR,CAAC,CAAC,CAAC,CACF,yBAAe,CAAC,CAAC,IAAI,IAAV,CAAC,CAAiB,CAC9B,CACF,GACA,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CACL,mCAAiB,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc,YACtD,eAAM,CAAC,EAAC,gHAAgH,GAAG,GACvH,CACP,CAAC;AACJ,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,CACL,oCAEE,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAE,CAAC,EACd,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,aAEtB,eAAM,CAAC,EAAC,gDAAgD,GAAG,EAC3D,eAAM,CAAC,EAAC,eAAe,GAAG,IACtB,CACP,CAAC;AACJ,CAAC;AAED,SAAS,OAAO;IACd,OAAO,CACL,mCAAiB,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc,YACtD,eAAM,CAAC,EAAC,mEAAmE,GAAG,GAC1E,CACP,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,EAChB,IAAI,EACJ,gBAAgB,EAChB,MAAM,EACN,QAAQ,GAMT;IACC,OAAO,CACL,eACE,SAAS,EAAE,iBAAiB,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,uBAC7C,IAAI,CAAC,IAAI,aAE3B,IAAI,CAAC,KAAK,IAAI,eAAM,SAAS,EAAC,gBAAgB,YAAE,IAAI,CAAC,KAAK,GAAQ,EAEnE,eAAK,SAAS,EAAC,eAAe,aAC3B,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,OAAO,IAAI,eAAM,SAAS,EAAC,mBAAmB,YAAE,IAAI,CAAC,OAAO,GAAQ,IACtE,EACN,eAAM,SAAS,EAAC,cAAc,YAAE,IAAI,CAAC,OAAO,GAAQ,EAEpD,eAAK,SAAS,EAAC,WAAW,aACxB,eAAM,SAAS,EAAC,eAAe,YAAE,IAAI,CAAC,QAAQ,GAAQ,EACrD,IAAI,CAAC,SAAS,IAAI,eAAM,SAAS,EAAC,gBAAgB,YAAE,IAAI,CAAC,SAAS,GAAQ,IACvE,EACL,IAAI,CAAC,QAAQ,IAAI,CAChB,cAAK,SAAS,EAAC,eAAe,YAC5B,KAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,GAAI,GAC9B,CACP,EAED,aAAI,SAAS,EAAC,mBAAmB,YAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACvB,yBACE,KAAC,SAAS,KAAG,EACb,yBAAO,CAAC,GAAQ,KAFT,CAAC,CAGL,CACN,CAAC,GACC,EAEJ,IAAI,CAAC,SAAS,IAAI,CACjB,eAAK,SAAS,EAAC,qBAAqB,EAAC,KAAK,EAAE,gBAAgB,aAC1D,KAAC,UAAU,KAAG,EACb,IAAI,CAAC,SAAS,IACX,CACP,EAEA,IAAI,CAAC,KAAK,IAAI,CACb,eAAK,SAAS,EAAC,iBAAiB,aAC9B,gBAAM,SAAS,EAAC,eAAe,aAC7B,KAAC,OAAO,KAAG,EACV,IAAI,CAAC,KAAK,CAAC,KAAK,IACZ,EACP,cAAK,SAAS,EAAC,gBAAgB,YAC7B,KAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAI,GACpC,EACL,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAC1B,eAAkB,SAAS,EAAC,eAAe,aACzC,eAAM,SAAS,EAAC,cAAc,YAC3B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACX,cAAK,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAI,CACtE,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAC,oBAAoB,iCACjC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GACd,CACR,GACI,EACP,2BACE,eAAM,SAAS,EAAC,oBAAoB,YAAE,CAAC,CAAC,IAAI,GAAQ,EACpD,cAAM,EACN,eAAM,SAAS,EAAC,oBAAoB,YAAE,CAAC,CAAC,IAAI,GAAQ,IAC/C,KAdC,CAAC,CAAC,IAAI,CAeV,CACP,CAAC,EACF,cAAK,SAAS,EAAC,gBAAgB,YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAO,EACvD,eAAM,SAAS,EAAC,gBAAgB,YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAQ,EAC1D,cAAK,SAAS,EAAC,gBAAgB,YAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAO,IACrD,CACP,EAEA,IAAI,CAAC,KAAK,IAAI,CACb,cAAK,SAAS,EAAC,iBAAiB,YAC9B,KAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAI,GAC3B,CACP,EAED,cAAK,SAAS,EAAC,kBAAkB,GAAG,EACpC,cAAK,SAAS,EAAC,cAAc,YAC3B,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,UAAU,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EACnG,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,gBACtB,IAAI,CAAC,QAAQ,2BACF,IAAI,CAAC,IAAI,YAE/B,IAAI,CAAC,QAAQ,GACP,GACL,IACF,CACP,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,0EAA0E;AAC1E,yEAAyE;AACzE,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0HtB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { BravelyAccountManager, BravelyClientKilledError, OAuthError } from "./BravelyAccountManager.js";
|
|
2
|
-
export type { ActivationResult } from "./BravelyAccountManager.js";
|
|
1
|
+
export { BravelyAccountManager, BravelyClientKilledError, OAuthError, PRE_EXPIRY_REFRESH_WINDOW_MS, } from "./BravelyAccountManager.js";
|
|
2
|
+
export type { ActivationResult, RefreshOutcome } from "./BravelyAccountManager.js";
|
|
3
3
|
export { EntitlementCache, ENTITLEMENT_CACHE_TTL_SECONDS } from "./EntitlementCache.js";
|
|
4
4
|
export { ActivationStateMachine, AUTO_ADVANCE_MS, AUTO_ADVANCE_TO, POST_CHECKOUT_RETRY, type ActivationEvent, } from "./ActivationStateMachine.js";
|
|
5
5
|
export { parseDeprecation } from "./deprecation.js";
|
|
@@ -14,4 +14,7 @@ export { BravelyProviderButtons, type BravelyProviderButtonsProps, type BravelyP
|
|
|
14
14
|
export { useActivationLaneFromUrl, detectActivationLane, type ActivationLaneResult, type ActivationLaneSource, type UseActivationLaneFromUrlOptions, } from "./hooks/useActivationLaneFromUrl.js";
|
|
15
15
|
export { useFreshLaunchRestoration, renderFreshLaunchToastCopy, type FreshLaunchRestorationResult, type UseFreshLaunchRestorationOptions, } from "./hooks/useFreshLaunchRestoration.js";
|
|
16
16
|
export { displayNameFor, DISPLAY_NAMES } from "./displayName.js";
|
|
17
|
+
export { BravelySignInScreen, SIGN_IN_OFFLINE_HEADLINE, SIGN_IN_OFFLINE_BODY, SIGN_IN_OFFLINE_RETRY_LABEL, SIGN_IN_COMPACT_MAX_WIDTH, type BravelySignInScreenProps, } from "./components/BravelySignInScreen.js";
|
|
18
|
+
export { OfferSlotGrid, buildOfferSlots, bonusAppsForSlug, offerThemeForSlug, planTokenForSlot, telemetryValueForSlot, computeOfferFit, OFFER_THEMES, OFFER_GUARANTEE_LINE, OFFER_GUARANTEE_TOOLTIP, OFFER_FOOTER_NOTE, OFFER_BONUS_FOOTER, OFFER_BUNDLE_TAGLINE, OFFER_FIT_MIN_WIDTH, OFFER_FIT_MIN_SCALE, OFFER_FIT_MAX_SCALE, OFFER_FIT_PAD, OFFER_FIT_HEIGHT_FRACTION, OFFER_FIT_WIDTH_CAP_FRACTION, OFFER_NATURAL_WIDTH, type OfferSlotKind, type OfferAppType, type OfferCtaVariant, type OfferRich, type OfferRichSeg, type OfferBonusApp, type OfferBonus, type OfferSlotCopy, type OfferTheme, type OfferSlotGridProps, type BuildOfferSlotsArgs, type OfferFitInput, type OfferFitResult, } from "./components/OfferSlotGrid.js";
|
|
19
|
+
export { getOrMintInstallId, emitAppFirstOpenedIfNeeded, INSTALL_ID_STORAGE_KEY, FIRST_OPEN_SENTINEL_STORAGE_KEY, type FirstOpenResult, type EmitAppFirstOpenedOptions, } from "./installMetrics.js";
|
|
17
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Barrel re-exports for `@bravely-studios/account-web`.
|
|
2
|
-
export { BravelyAccountManager, BravelyClientKilledError, OAuthError } from "./BravelyAccountManager.js";
|
|
2
|
+
export { BravelyAccountManager, BravelyClientKilledError, OAuthError, PRE_EXPIRY_REFRESH_WINDOW_MS, } from "./BravelyAccountManager.js";
|
|
3
3
|
export { EntitlementCache, ENTITLEMENT_CACHE_TTL_SECONDS } from "./EntitlementCache.js";
|
|
4
4
|
export { ActivationStateMachine, AUTO_ADVANCE_MS, AUTO_ADVANCE_TO, POST_CHECKOUT_RETRY, } from "./ActivationStateMachine.js";
|
|
5
5
|
export { parseDeprecation } from "./deprecation.js";
|
|
@@ -13,4 +13,9 @@ export { BravelyProviderButtons, } from "./components/BravelyProviderButtons.js"
|
|
|
13
13
|
export { useActivationLaneFromUrl, detectActivationLane, } from "./hooks/useActivationLaneFromUrl.js";
|
|
14
14
|
export { useFreshLaunchRestoration, renderFreshLaunchToastCopy, } from "./hooks/useFreshLaunchRestoration.js";
|
|
15
15
|
export { displayNameFor, DISPLAY_NAMES } from "./displayName.js";
|
|
16
|
+
// ---- Login-first cutover surfaces (0.4.0: D1 sign-in screen, D3 offer grid,
|
|
17
|
+
// ---- D6 install metrics) ----------------------------------------------------
|
|
18
|
+
export { BravelySignInScreen, SIGN_IN_OFFLINE_HEADLINE, SIGN_IN_OFFLINE_BODY, SIGN_IN_OFFLINE_RETRY_LABEL, SIGN_IN_COMPACT_MAX_WIDTH, } from "./components/BravelySignInScreen.js";
|
|
19
|
+
export { OfferSlotGrid, buildOfferSlots, bonusAppsForSlug, offerThemeForSlug, planTokenForSlot, telemetryValueForSlot, computeOfferFit, OFFER_THEMES, OFFER_GUARANTEE_LINE, OFFER_GUARANTEE_TOOLTIP, OFFER_FOOTER_NOTE, OFFER_BONUS_FOOTER, OFFER_BUNDLE_TAGLINE, OFFER_FIT_MIN_WIDTH, OFFER_FIT_MIN_SCALE, OFFER_FIT_MAX_SCALE, OFFER_FIT_PAD, OFFER_FIT_HEIGHT_FRACTION, OFFER_FIT_WIDTH_CAP_FRACTION, OFFER_NATURAL_WIDTH, } from "./components/OfferSlotGrid.js";
|
|
20
|
+
export { getOrMintInstallId, emitAppFirstOpenedIfNeeded, INSTALL_ID_STORAGE_KEY, FIRST_OPEN_SENTINEL_STORAGE_KEY, } from "./installMetrics.js";
|
|
16
21
|
//# sourceMappingURL=index.js.map
|