@xsolla/xui-core 0.162.0 → 0.163.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,10 +63,32 @@ Every component accepts `themeMode` and `themeProductContext` props to override
63
63
 
64
64
  For custom components, use `useResolvedTheme` instead of `useDesignSystem`.
65
65
 
66
+ ## Responsive Typography
67
+
68
+ By default, `XUIProvider` injects CSS custom properties (`--xui-font-size-*`, `--xui-lh-*`) with `@media` queries so text scales between mobile and desktop breakpoints. Pass `responsive={false}` to disable this — all components will use the fixed common/desktop values instead.
69
+
70
+ ```tsx
71
+ // Default — responsive scaling via CSS vars + @media
72
+ <XUIProvider>
73
+ <App />
74
+ </XUIProvider>
75
+
76
+ // Opt-out — fixed sizes, no @media queries injected
77
+ <XUIProvider responsive={false}>
78
+ <App />
79
+ </XUIProvider>
80
+ ```
81
+
82
+ The `responsive` flag is also available from `useDesignSystem()` if a component needs to branch on it:
83
+
84
+ ```tsx
85
+ const { responsive } = useDesignSystem();
86
+ ```
87
+
66
88
  ## Exports
67
89
 
68
- - `XUIProvider` — Root context provider; accepts `initialMode` (see theme modes above)
69
- - `useDesignSystem` — Hook returning `{ theme, mode, setMode }`; falls back to dark theme if no provider
90
+ - `XUIProvider` — Root context provider; accepts `initialMode` (see theme modes above) and `responsive` (opt-out of responsive typography, defaults to `true`)
91
+ - `useDesignSystem` — Hook returning `{ theme, mode, setMode, responsive }`; falls back to dark theme if no provider
70
92
  - `useResolvedTheme` — Hook returning resolved theme with per-component overrides applied; same return shape as `useDesignSystem`
71
93
  - `ThemeOverrideProps` — Type: `{ themeMode?: ThemeMode; themeProductContext?: ProductContext }`
72
94
  - `themeConfig` — Function returning the full theme object for a given `ThemeMode`
@@ -74,7 +96,7 @@ For custom components, use `useResolvedTheme` instead of `useDesignSystem`.
74
96
  - `ModalIdContext` — Context holding the current modal's ID for portal-based components
75
97
  - `useModalId` — Hook returning the current modal ID, or `null` if outside a modal
76
98
  - `breakpoints` — Responsive breakpoints: `{ mobile: 0, desktop: 768 }`
77
- - `responsiveTypographyScale` — Raw responsive font-size and line-height data (13 steps × 3 device modes)
99
+ - `responsiveTypographyScale` — Raw responsive font-size and line-height data (13 steps × 2 device modes: common/mobile)
78
100
  - `SCALE_STEPS` — Array of all scale step identifiers
79
101
  - `generateTypographyCSS` — Returns the full CSS string for responsive typography custom properties
80
102
  - `cssVar` — Helper to get CSS variable references: `cssVar.fontSize("350")` → `"var(--xui-font-size-350)"`
@@ -83,7 +105,7 @@ For custom components, use `useResolvedTheme` instead of `useDesignSystem`.
83
105
  - `fontFacesCSS` — Raw `@font-face` CSS string (for SSR or manual injection)
84
106
  - `ThemeMode` — Type: `"dark"` | `"light"` | `"ltg-dark"` | `"blueprints"`
85
107
  - `ThemeColors` — Type of the colour token object
86
- - `ProductContext` — Type of the `themeProductContext` prop (e.g. `"b2c"`, `"paystation"`)
108
+ - `ProductContext` — Type of the `themeProductContext` prop: `"b2c"` | `"b2b"`
87
109
  - `colors` — Raw colour tokens for all themes
88
110
  - `spacing` — Spacing scale (`xs`, `s`, `m`, `l`, `xl`)
89
111
  - `radius` — Border-radius tokens (button, card, input, tag, avatar variants)
@@ -119,7 +141,7 @@ export const Card = ({ title, themeMode, themeProductContext }: CardProps) => {
119
141
  <XUIProvider initialMode="dark">
120
142
  <Card title="Dark card" />
121
143
  <Card title="Light card" themeMode="light" />
122
- <Card title="Paystation card" themeMode="light" themeProductContext="paystation" />
144
+ <Card title="B2C card" themeMode="light" themeProductContext="b2c" />
123
145
  </XUIProvider>
124
146
  ```
125
147
 
package/index.d.mts CHANGED
@@ -16,7 +16,7 @@ import React from 'react';
16
16
  * - Body default/accent use "compact" line-heights (moderate)
17
17
  * - Body paragraph uses "text" line-heights (generous, for reading)
18
18
  */
19
- type ProductContext = "b2c" | "b2b" | "paystation" | "presentation";
19
+ type ProductContext = "b2c" | "b2b";
20
20
  interface TypographyVariant {
21
21
  fontSize: number;
22
22
  lineHeight: string;
@@ -3316,11 +3316,10 @@ declare const MOBILE_MAX_WIDTH: number;
3316
3316
  interface ResponsiveValue {
3317
3317
  common: number;
3318
3318
  mobile: number;
3319
- desktop: number;
3320
3319
  }
3321
3320
  type ScaleStep = "75" | "100" | "125" | "150" | "175" | "200" | "250" | "300" | "350" | "450" | "550" | "650" | "750";
3322
3321
  declare const SCALE_STEPS: ScaleStep[];
3323
- /** Font-size scale: 13 steps from 10px to 64px (desktop) */
3322
+ /** Font-size scale: 13 steps from 10px to 64px */
3324
3323
  declare const fontSize: Record<ScaleStep, ResponsiveValue>;
3325
3324
  /** Line-height/display: tight line-heights for headings (roughly 1:1 with font-size) */
3326
3325
  declare const lineHeightDisplay: Record<ScaleStep, ResponsiveValue>;
@@ -3351,15 +3350,26 @@ declare const FontLoader: React.FC;
3351
3350
  /**
3352
3351
  * @font-face CSS for all toolkit fonts, loaded from Xsolla CDN.
3353
3352
  *
3354
- * Pilat Wide — B2C heading/display font, registered at weights 400, 600, 700, 800.
3353
+ * Pilat Wide — B2C heading/display font, weights 600, 700, 800.
3354
+ * Pilat — B2B heading/display font, weights 300, 400, 500, 600, 700, 800.
3355
+ * Aktiv Grotesk — body font for all contexts, weights 400, 500, 600.
3356
+ * Four editions loaded via unicode-range: Latin, CN/SG, JP, KR.
3357
+ * The browser downloads only the subset needed for characters on the page.
3355
3358
  *
3356
- * Pilat B2B heading/display font, registered at weights 300, 400, 600, 700, 800.
3359
+ * Weight coverage notes (intentional gaps licensing constraint, Xsolla
3360
+ * does not hold rights to the omitted cuts):
3361
+ * - Pilat Wide 400 — not licensed. Components using weight 400 on Pilat
3362
+ * Wide will render at 600 via browser substitution (heavier).
3363
+ * - Aktiv Grotesk 300 — not licensed. (No component currently requests it.)
3364
+ * - Aktiv Grotesk 700 — not licensed. Substitutes to 600 (lighter).
3365
+ * - CJK editions (cn-sg, jp, kr) — 400/500/600 only; no 700/800.
3366
+ * Heavy weights on CJK text fall back to the Latin file (no glyphs)
3367
+ * and then to the system fallback stack.
3357
3368
  *
3358
- * Aktiv Grotesk body font for all contexts,
3359
- * mapped from the Sharp Grotesk CDN files (same typeface under a legacy name).
3360
- * Registered at weights 300, 400, 500, 600, 700.
3369
+ * Do not add @font-face entries for the omitted weights without first
3370
+ * confirming the licence has been extended.
3361
3371
  */
3362
- declare const fontFacesCSS = "\n /* \u2500\u2500 Pilat Wide (B2C headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Medium_/Pilat_Test_Medium.ttf') format('truetype');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_Bold_bee67c470a/Pilat_Test_Demi_Bold_bee67c470a.ttf') format('truetype');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_b12b40d234/Pilat_Test_Bold_b12b40d234.ttf') format('truetype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Heavy_2885678ca4/Pilat_Test_Heavy_2885678ca4.otf') format('opentype');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Pilat (B2B headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/55a03110b2400b778d485de2c8d064c0.woff2') format('woff2');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/e968c9cc76e48ff6111c90534549bbf9.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/ed4fe74e88aaacc6978f06a862e75b08.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/7450f429979af7eaa8fa4d4d91cee927.woff2') format('woff2');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/218d647ff7690c1e312f6943e29af375.woff2') format('woff2');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 served from Sharp Grotesk CDN files \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Light_c4650750bb/Pilat_Test_Light_c4650750bb.otf') format('opentype');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Book_5cb49cd592/Pilat_Test_Book_5cb49cd592.otf') format('opentype');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_e9bed59107/Pilat_Test_Demi_e9bed59107.otf') format('opentype');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n";
3372
+ declare const fontFacesCSS = "\n /* \u2500\u2500 Pilat Wide (B2C headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat-wide/pilat-wide-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat-wide/pilat-wide-700.woff2') format('woff2');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat-wide/pilat-wide-800.woff2') format('woff2');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Pilat (B2B headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-300.woff2') format('woff2');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-700.woff2') format('woff2');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-800.woff2') format('woff2');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Latin \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/latin/aktiv-grotesk-latin-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+0000-024F, U+0250-02AF, U+0300-036F, U+0370-03FF, U+0400-04FF, U+2000-206F, U+20A0-20CF, U+2100-214F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/latin/aktiv-grotesk-latin-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+0000-024F, U+0250-02AF, U+0300-036F, U+0370-03FF, U+0400-04FF, U+2000-206F, U+20A0-20CF, U+2100-214F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/latin/aktiv-grotesk-latin-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+0000-024F, U+0250-02AF, U+0300-036F, U+0370-03FF, U+0400-04FF, U+2000-206F, U+20A0-20CF, U+2100-214F;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Chinese / SG \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/cn-sg/aktiv-grotesk-cn-sg-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/cn-sg/aktiv-grotesk-cn-sg-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/cn-sg/aktiv-grotesk-cn-sg-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Japanese \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/jp/aktiv-grotesk-jp-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF65-FF9F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/jp/aktiv-grotesk-jp-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF65-FF9F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/jp/aktiv-grotesk-jp-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF65-FF9F;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Korean \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/kr/aktiv-grotesk-kr-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF, U+FFA0-FFDC;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/kr/aktiv-grotesk-kr-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF, U+FFA0-FFDC;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/kr/aktiv-grotesk-kr-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF, U+FFA0-FFDC;\n }\n";
3363
3373
 
3364
3374
  declare const TypographyStyleLoader: React.FC;
3365
3375
 
@@ -6665,6 +6675,8 @@ interface DesignSystemContextType {
6665
6675
  productContext: ProductContext;
6666
6676
  setProductContext: (productContext: ProductContext) => void;
6667
6677
  theme: ReturnType<typeof themeConfig>;
6678
+ /** Whether the app uses responsive typography (CSS vars + @media). Defaults to true. */
6679
+ responsive: boolean;
6668
6680
  }
6669
6681
  declare const XUIProvider: React.FC<{
6670
6682
  children: React.ReactNode;
@@ -6674,6 +6686,12 @@ declare const XUIProvider: React.FC<{
6674
6686
  productContext?: never;
6675
6687
  /** Load toolkit fonts from the Xsolla CDN. Defaults to true on web, no-ops on native. */
6676
6688
  loadFonts?: boolean;
6689
+ /**
6690
+ * Enable responsive typography via CSS custom properties and @media queries.
6691
+ * When false, all components use fixed (common/desktop) values — suitable for
6692
+ * apps that don't need mobile scaling. Defaults to true.
6693
+ */
6694
+ responsive?: boolean;
6677
6695
  }>;
6678
6696
  declare const useDesignSystem: () => DesignSystemContextType;
6679
6697
  interface ThemeOverrideProps {
@@ -9944,6 +9962,8 @@ declare const useResolvedTheme: (overrides?: ThemeOverrideProps) => {
9944
9962
  };
9945
9963
  setMode: (mode: ThemeMode) => void;
9946
9964
  setProductContext: (productContext: ProductContext) => void;
9965
+ /** Whether the app uses responsive typography (CSS vars + @media). Defaults to true. */
9966
+ responsive: boolean;
9947
9967
  };
9948
9968
  declare const useId: () => string;
9949
9969
  /**
package/index.d.ts CHANGED
@@ -16,7 +16,7 @@ import React from 'react';
16
16
  * - Body default/accent use "compact" line-heights (moderate)
17
17
  * - Body paragraph uses "text" line-heights (generous, for reading)
18
18
  */
19
- type ProductContext = "b2c" | "b2b" | "paystation" | "presentation";
19
+ type ProductContext = "b2c" | "b2b";
20
20
  interface TypographyVariant {
21
21
  fontSize: number;
22
22
  lineHeight: string;
@@ -3316,11 +3316,10 @@ declare const MOBILE_MAX_WIDTH: number;
3316
3316
  interface ResponsiveValue {
3317
3317
  common: number;
3318
3318
  mobile: number;
3319
- desktop: number;
3320
3319
  }
3321
3320
  type ScaleStep = "75" | "100" | "125" | "150" | "175" | "200" | "250" | "300" | "350" | "450" | "550" | "650" | "750";
3322
3321
  declare const SCALE_STEPS: ScaleStep[];
3323
- /** Font-size scale: 13 steps from 10px to 64px (desktop) */
3322
+ /** Font-size scale: 13 steps from 10px to 64px */
3324
3323
  declare const fontSize: Record<ScaleStep, ResponsiveValue>;
3325
3324
  /** Line-height/display: tight line-heights for headings (roughly 1:1 with font-size) */
3326
3325
  declare const lineHeightDisplay: Record<ScaleStep, ResponsiveValue>;
@@ -3351,15 +3350,26 @@ declare const FontLoader: React.FC;
3351
3350
  /**
3352
3351
  * @font-face CSS for all toolkit fonts, loaded from Xsolla CDN.
3353
3352
  *
3354
- * Pilat Wide — B2C heading/display font, registered at weights 400, 600, 700, 800.
3353
+ * Pilat Wide — B2C heading/display font, weights 600, 700, 800.
3354
+ * Pilat — B2B heading/display font, weights 300, 400, 500, 600, 700, 800.
3355
+ * Aktiv Grotesk — body font for all contexts, weights 400, 500, 600.
3356
+ * Four editions loaded via unicode-range: Latin, CN/SG, JP, KR.
3357
+ * The browser downloads only the subset needed for characters on the page.
3355
3358
  *
3356
- * Pilat B2B heading/display font, registered at weights 300, 400, 600, 700, 800.
3359
+ * Weight coverage notes (intentional gaps licensing constraint, Xsolla
3360
+ * does not hold rights to the omitted cuts):
3361
+ * - Pilat Wide 400 — not licensed. Components using weight 400 on Pilat
3362
+ * Wide will render at 600 via browser substitution (heavier).
3363
+ * - Aktiv Grotesk 300 — not licensed. (No component currently requests it.)
3364
+ * - Aktiv Grotesk 700 — not licensed. Substitutes to 600 (lighter).
3365
+ * - CJK editions (cn-sg, jp, kr) — 400/500/600 only; no 700/800.
3366
+ * Heavy weights on CJK text fall back to the Latin file (no glyphs)
3367
+ * and then to the system fallback stack.
3357
3368
  *
3358
- * Aktiv Grotesk body font for all contexts,
3359
- * mapped from the Sharp Grotesk CDN files (same typeface under a legacy name).
3360
- * Registered at weights 300, 400, 500, 600, 700.
3369
+ * Do not add @font-face entries for the omitted weights without first
3370
+ * confirming the licence has been extended.
3361
3371
  */
3362
- declare const fontFacesCSS = "\n /* \u2500\u2500 Pilat Wide (B2C headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Medium_/Pilat_Test_Medium.ttf') format('truetype');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_Bold_bee67c470a/Pilat_Test_Demi_Bold_bee67c470a.ttf') format('truetype');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_b12b40d234/Pilat_Test_Bold_b12b40d234.ttf') format('truetype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Heavy_2885678ca4/Pilat_Test_Heavy_2885678ca4.otf') format('opentype');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Pilat (B2B headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/55a03110b2400b778d485de2c8d064c0.woff2') format('woff2');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/e968c9cc76e48ff6111c90534549bbf9.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/ed4fe74e88aaacc6978f06a862e75b08.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/7450f429979af7eaa8fa4d4d91cee927.woff2') format('woff2');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/merchant-bucket-prod/files/uploaded/722279/218d647ff7690c1e312f6943e29af375.woff2') format('woff2');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 served from Sharp Grotesk CDN files \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Light_c4650750bb/Pilat_Test_Light_c4650750bb.otf') format('opentype');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Book_5cb49cd592/Pilat_Test_Book_5cb49cd592.otf') format('opentype');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Demi_e9bed59107/Pilat_Test_Demi_e9bed59107.otf') format('opentype');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/strapi-v2-bucket-prod/Pilat_Test_Bold_195d1b44fa/Pilat_Test_Bold_195d1b44fa.otf') format('opentype');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n";
3372
+ declare const fontFacesCSS = "\n /* \u2500\u2500 Pilat Wide (B2C headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat-wide/pilat-wide-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat-wide/pilat-wide-700.woff2') format('woff2');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat Wide';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat-wide/pilat-wide-800.woff2') format('woff2');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Pilat (B2B headings) \u2500\u2500 */\n\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-300.woff2') format('woff2');\n font-weight: 300;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-700.woff2') format('woff2');\n font-weight: 700;\n font-style: normal;\n font-display: swap;\n }\n @font-face {\n font-family: 'Pilat';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/pilat/pilat-800.woff2') format('woff2');\n font-weight: 800;\n font-style: normal;\n font-display: swap;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Latin \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/latin/aktiv-grotesk-latin-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+0000-024F, U+0250-02AF, U+0300-036F, U+0370-03FF, U+0400-04FF, U+2000-206F, U+20A0-20CF, U+2100-214F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/latin/aktiv-grotesk-latin-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+0000-024F, U+0250-02AF, U+0300-036F, U+0370-03FF, U+0400-04FF, U+2000-206F, U+20A0-20CF, U+2100-214F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/latin/aktiv-grotesk-latin-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+0000-024F, U+0250-02AF, U+0300-036F, U+0370-03FF, U+0400-04FF, U+2000-206F, U+20A0-20CF, U+2100-214F;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Chinese / SG \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/cn-sg/aktiv-grotesk-cn-sg-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/cn-sg/aktiv-grotesk-cn-sg-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/cn-sg/aktiv-grotesk-cn-sg-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FE30-FE4F, U+FF00-FFEF;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Japanese \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/jp/aktiv-grotesk-jp-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF65-FF9F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/jp/aktiv-grotesk-jp-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF65-FF9F;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/jp/aktiv-grotesk-jp-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF65-FF9F;\n }\n\n /* \u2500\u2500 Aktiv Grotesk (body) \u2014 Korean \u2500\u2500 */\n\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/kr/aktiv-grotesk-kr-400.woff2') format('woff2');\n font-weight: 400;\n font-style: normal;\n font-display: swap;\n unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF, U+FFA0-FFDC;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/kr/aktiv-grotesk-kr-500.woff2') format('woff2');\n font-weight: 500;\n font-style: normal;\n font-display: swap;\n unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF, U+FFA0-FFDC;\n }\n @font-face {\n font-family: 'Aktiv Grotesk';\n src: url('https://cdn.xsolla.net/xsolla-ui-toolkit-prod/fonts/v1/aktiv-grotesk/kr/aktiv-grotesk-kr-600.woff2') format('woff2');\n font-weight: 600;\n font-style: normal;\n font-display: swap;\n unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF, U+FFA0-FFDC;\n }\n";
3363
3373
 
3364
3374
  declare const TypographyStyleLoader: React.FC;
3365
3375
 
@@ -6665,6 +6675,8 @@ interface DesignSystemContextType {
6665
6675
  productContext: ProductContext;
6666
6676
  setProductContext: (productContext: ProductContext) => void;
6667
6677
  theme: ReturnType<typeof themeConfig>;
6678
+ /** Whether the app uses responsive typography (CSS vars + @media). Defaults to true. */
6679
+ responsive: boolean;
6668
6680
  }
6669
6681
  declare const XUIProvider: React.FC<{
6670
6682
  children: React.ReactNode;
@@ -6674,6 +6686,12 @@ declare const XUIProvider: React.FC<{
6674
6686
  productContext?: never;
6675
6687
  /** Load toolkit fonts from the Xsolla CDN. Defaults to true on web, no-ops on native. */
6676
6688
  loadFonts?: boolean;
6689
+ /**
6690
+ * Enable responsive typography via CSS custom properties and @media queries.
6691
+ * When false, all components use fixed (common/desktop) values — suitable for
6692
+ * apps that don't need mobile scaling. Defaults to true.
6693
+ */
6694
+ responsive?: boolean;
6677
6695
  }>;
6678
6696
  declare const useDesignSystem: () => DesignSystemContextType;
6679
6697
  interface ThemeOverrideProps {
@@ -9944,6 +9962,8 @@ declare const useResolvedTheme: (overrides?: ThemeOverrideProps) => {
9944
9962
  };
9945
9963
  setMode: (mode: ThemeMode) => void;
9946
9964
  setProductContext: (productContext: ProductContext) => void;
9965
+ /** Whether the app uses responsive typography (CSS vars + @media). Defaults to true. */
9966
+ responsive: boolean;
9947
9967
  };
9948
9968
  declare const useId: () => string;
9949
9969
  /**