Skip to content

Commit 57a7d5a

Browse files
committed
WEB-2413: Improvements and fixes
1 parent 1154ffe commit 57a7d5a

6 files changed

Lines changed: 83 additions & 125 deletions

File tree

doc/design-tokens.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ exported from `@telefonica/mistica`. Tokens adapt automatically to the active sk
66

77
## Critical rules
88

9-
- **NEVER hardcode colors.** Always use `skinVars.colors.*` for all color values.
9+
- **NEVER hardcode colors in app/component UI code.** Always use `skinVars.colors.*` for all color values.
1010
- Use `skinVars.rawColors.*` (not `skinVars.colors.*`) when applying alpha with `applyAlpha`.
1111
- Use `skinVars.borderRadii.*` for border radius values.
12+
- For custom skins, palette-based skin authoring, or theme-level visual customization, see
13+
[theme-config.md](./theme-config.md).
1214
- Tokens are CSS custom properties at runtime (e.g. `var(--colorBrand)`), so they work in both inline styles
1315
and CSS.
1416

@@ -49,6 +51,12 @@ const semiTransparentBrand = applyAlpha(skinVars.rawColors.brand, 0.5);
4951
// applyAlpha(skinVars.colors.brand, 0.5) // Don't do this
5052
```
5153

54+
## Using palettes when authoring a skin
55+
56+
Palette exports are for skin authoring, not for styling components directly. If you need to customize default
57+
colors, radii, or related visual tokens, create or extend a `Skin` and then consume those values through
58+
`skinVars.*` in component code. See [theme-config.md](./theme-config.md) for the full custom-skin example.
59+
5260
## Border radius tokens
5361

5462
Access via `skinVars.borderRadii.*`:

doc/layout.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,22 @@ Vertically distributes its children using the given `space` separation.
7373
## Inline
7474

7575
Horizontally distributes its children using the given `space` separation. This component can be considered as
76-
an horizontal `Stack`.
76+
a horizontal `Stack`, and it covers the most common row-layout use cases you might otherwise solve with
77+
`display: flex`.
7778

78-
:information_source: Items can be aligned vertically. Check `Inline` component in
79+
It supports:
80+
81+
- horizontal distribution via `space={number}` or `space="between" | "around" | "evenly"`
82+
- vertical alignment of children via `alignItems="flex-start" | "flex-end" | "center" | "stretch" | "baseline"`
83+
- wrapping via `wrap` and row spacing via `verticalSpace`
84+
85+
:information_source: Check `Inline` in
7986
[Storybook](https://mistica-web.vercel.app/?path=/story/layout-inline--default) to learn more about it.
8087

8188
### numeric space
8289

8390
```tsx
84-
<Inline space={16}>
91+
<Inline space={16} alignItems="center">
8592
<Child1 />
8693
<Child2 />
8794
<Child3 />

doc/llms.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,17 @@ repository at `https://github.com/Telefonica/mistica-web/blob/master/doc/<filena
1717

1818
## Critical Rules
1919

20-
1. **NEVER hardcode colors.** Always use `skinVars.colors.*` design tokens from `@telefonica/mistica`.
20+
1. **NEVER hardcode colors in app/component UI code.** Always use `skinVars.colors.*` design tokens from
21+
`@telefonica/mistica`. The exception is skin authoring: when creating or extending a `Skin`, you may use
22+
built-in palette exports (for example `movistarNewPalette`) or your own custom palette/colors inside the
23+
skin definition.
2124
2. **Try not to use raw `<div>` for layout.** Use Mistica layout components: `Box`, `Stack`, `Inline`,
2225
`Align`, `ResponsiveLayout`, `GridLayout`, `Grid`.
2326
3. **NEVER set font sizes manually.** Use text components: `Text1`-`Text10`, `Title1`-`Title4`.
2427
4. **NEVER set border radius manually.** Use `skinVars.borderRadii.*` or Mistica components that handle it
25-
automatically.
28+
automatically. If you need to change the default visual styling of components (colors, border radius,
29+
etc.) and there is no specific prop for it, create or extend a custom skin instead of adding ad hoc style
30+
overrides.
2631
5. **Always wrap your app** with `<ThemeContextProvider>` and import `@telefonica/mistica/css/mistica.css`.
2732
6. **Always namespace React hooks**: `React.useState`, `React.useEffect`, `React.useRef`.
2833
7. **Add `'use client';`** directive to client components when using Next.js app router.
@@ -133,7 +138,10 @@ type ThemeConfig = {
133138
Available skins: `getMovistarNewSkin()`, `getVivoNewSkin()`, `getO2NewSkin()`, `getTelefonicaSkin()`,
134139
`getBlauSkin()`, `getTuSkin()`, and others via `getSkinByName()`. Legacy variants without the `New` suffix
135140
also exist (`getMovistarSkin()`, `getVivoSkin()`, `getO2Skin()`); prefer the `New` versions for new projects.
136-
You can also create a custom skin.
141+
You can also create a custom skin. If you need to customize default component colors, radii, or other visual
142+
tokens beyond the props exposed by a component, prefer extending a skin over overriding component styles.
143+
Built-in palette exports such as `movistarNewPalette`, `o2NewPalette`, `vivoNewPalette`, etc. are available
144+
for skin authoring, and custom skins may also define their own palette colors from scratch.
137145

138146
Built-in Link integrations: `Next12`, `Next13`, `Next14`, `ReactRouter5`, `ReactRouter6`.
139147

@@ -263,6 +271,9 @@ All tokens via `skinVars` from `@telefonica/mistica`:
263271

264272
- **Colors**: `skinVars.colors.*` (286 tokens for backgrounds, text, borders, controls, status, tags)
265273
- **Raw colors**: `skinVars.rawColors.*` (same tokens as RGB values, for use with `applyAlpha`)
274+
- **Palettes for skin authoring**: built-in palette exports such as `movistarNewPalette`, `o2NewPalette`,
275+
`vivoNewPalette`, etc. Use these only when creating/extending a `Skin`, not for styling app components
276+
directly.
266277
- **Border radii**: `skinVars.borderRadii.*` (container, button, input, popup, chip, sheet, avatar, tag, etc.)
267278
- **Text presets**: Handled by text components, not accessed directly
268279

@@ -278,7 +289,7 @@ All tokens via `skinVars` from `@telefonica/mistica`:
278289
- [Layout](./layout.md): Core layout primitives (Box, Stack, Inline, Align, Grid/GridItem, NegativeBox,
279290
Divider, HorizontalScroll, Boxed, Overlay, StackingGroup) and page layouts (ResponsiveLayout, HeaderLayout,
280291
GridLayout, MasterDetailLayout, FixedFooterLayout, ButtonFixedFooterLayout, ButtonLayout, DoubleField),
281-
vertical rhythm
292+
vertical rhythm, and `Inline` alignment/wrapping capabilities
282293
- [Forms](./forms.md): Form component, all form field types, DoubleField, useForm hook
283294
- [Analytics](./analytics.md): trackingEvent prop, logEvent setup, default tracking, GA4 support,
284295
TrackingConfig

doc/patterns.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
## Critical rules
44

5-
1. **NEVER hardcode colors.** Always use `skinVars.colors.*` from `@telefonica/mistica`.
5+
1. **NEVER hardcode colors in app/component UI code.** Always use `skinVars.colors.*` from
6+
`@telefonica/mistica`. For skins and theme-level customization, see [theme-config.md](./theme-config.md).
67
2. **NEVER use raw `<div>` for layout.** Use `Box`, `Stack`, `Inline`, `ResponsiveLayout`, `GridLayout`,
78
`Grid`.
89
3. **NEVER set font sizes manually.** Use text components (`Text1`-`Text10`, `Title1`-`Title4`).
910
4. **NEVER set border radius manually.** Use `skinVars.borderRadii.*` or components that handle it (`Boxed`,
10-
cards, etc.).
11+
cards, etc.). For theme-level visual customization without a dedicated component prop, use a custom skin.
1112
5. **Always wrap your app** with `ThemeContextProvider` and import `@telefonica/mistica/css/mistica.css`.
1213
6. **Always namespace React hooks**: `React.useState`, `React.useEffect`, `React.useRef`, etc.
1314
7. **Add `'use client';`** directive to client components when using Next.js app router.
@@ -123,7 +124,7 @@ import {skinVars, applyAlpha} from '@telefonica/mistica';
123124
const overlay = applyAlpha(skinVars.rawColors.backgroundBrand, 0.8);
124125
```
125126

126-
### DON'T: Hardcode colors
127+
### DON'T: Hardcode colors in component code
127128

128129
```tsx
129130
// BAD - hardcoded colors
@@ -136,6 +137,9 @@ const overlay = applyAlpha(skinVars.rawColors.backgroundBrand, 0.8);
136137
<Boxed><Text2 regular>Content in container</Text2></Boxed>
137138
```
138139

140+
If you need brand-specific defaults, put those colors in a custom skin and then consume them through
141+
`skinVars.colors.*` instead of styling individual components with palette values.
142+
139143
## Responsive patterns
140144

141145
### Conditional rendering by screen size

doc/theme-config.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ If your app doesn't follow the branding of mistica builtin skins (Movistar, Vivo
9595
can still use mistica with your custom skin. Just import the `Skin` type and create a new skin config that
9696
implements the `Skin` interface (you need to define all the required color constants):
9797

98+
If you need to customize default component colors, border radii, or similar visual tokens and there is no
99+
component prop for that, prefer a custom skin over ad hoc CSS/style overrides. You can:
100+
101+
- start from a built-in skin like `getMovistarNewSkin()` and override the tokens you need
102+
- start from a built-in palette export like `movistarNewPalette`
103+
- define your own palette/colors from scratch
104+
98105
```ts
99106
import type {Skin} from '@telefonica/mistica';
100107

@@ -121,4 +128,35 @@ const skin: Skin = {
121128
</ThemeContextProvider>;
122129
```
123130

131+
You can also extend an existing skin instead of defining everything from scratch:
132+
133+
```ts
134+
import {getMovistarNewSkin, movistarNewPalette, type Skin} from '@telefonica/mistica';
135+
136+
const baseSkin = getMovistarNewSkin();
137+
const palette = {
138+
...movistarNewPalette,
139+
brandPrimary: '#0050D8',
140+
};
141+
142+
const skin: Skin = {
143+
...baseSkin,
144+
name: 'Acme',
145+
colors: {
146+
...baseSkin.colors,
147+
brand: palette.brandPrimary,
148+
backgroundBrand: palette.brandPrimary,
149+
backgroundBrandTop: palette.brandPrimary,
150+
backgroundBrandBottom: palette.blue800,
151+
buttonPrimaryBackground: palette.brandPrimary,
152+
buttonPrimaryBackgroundHover: palette.blue800,
153+
buttonPrimaryBackgroundPressed: palette.blue800,
154+
textButtonPrimary: palette.white,
155+
},
156+
};
157+
```
158+
159+
If you also need different default radii, override `borderRadii` in the custom skin rather than setting
160+
border radius ad hoc in component styles.
161+
124162
You can see an example in the [examples folder](../examples/custom-skin/).

skills/mistica/SKILL.md

Lines changed: 4 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -72,118 +72,8 @@ Based on what the user needs, read the appropriate documentation files:
7272
| **Migration from older versions** | `node_modules/@telefonica/mistica/doc/migration-guide.md` |
7373
| **Lottie animations** | `node_modules/@telefonica/mistica/doc/lottie.md` |
7474

75-
## Critical Rules
76-
77-
These rules MUST be followed in ALL generated code:
78-
79-
1. **NEVER hardcode colors.** Always use `skinVars.colors.*` from `@telefonica/mistica`. For semi-transparent
80-
colors, use `applyAlpha(skinVars.rawColors.*, alpha)`.
81-
82-
2. **NEVER use raw `<div>` for layout or spacing.** Use Mistica layout components:
83-
84-
- `Box` for padding
85-
- `Stack` for vertical spacing
86-
- `Inline` for horizontal spacing
87-
- `ResponsiveLayout` for page content containers
88-
- `GridLayout` for column-based layouts
89-
- `Grid`/`GridItem` for CSS grid
90-
91-
3. **NEVER set font sizes or font families manually.** Use text components: `Text1`-`Text10` for body text,
92-
`Title1`-`Title4` for headings.
93-
94-
4. **NEVER set border radius manually.** Use `skinVars.borderRadii.*` or Mistica components that handle it
95-
(`Boxed`, cards, etc.).
96-
97-
5. **Always wrap the app root** with `<ThemeContextProvider>` and import
98-
`@telefonica/mistica/css/mistica.css`.
99-
100-
6. **Always namespace React hooks**: write `React.useState`, `React.useEffect`, not bare `useState`.
101-
102-
7. **Add `'use client';`** directive when using Next.js app router.
103-
104-
8. **Use the `to` prop** (not `href`) for client-side navigation after configuring the Link component in
105-
theme.
106-
107-
9. **Wrap unbounded `RowList`** with `<NegativeBox>` when placed inside `ResponsiveLayout`.
108-
109-
10. **Use `small` prop on buttons** inside cards and `EmptyStateCard`.
110-
111-
11. **Always set `font-family` on `body` using the correct font for the active skin.** Mistica does NOT inject
112-
a font — without it browsers fall back to their default serif font (Times New Roman on desktop). Each skin
113-
has a designated font:
114-
115-
| Skin | Font family |
116-
| ---------------------------- | ------------------- |
117-
| `movistar-new` _(preferred)_ | `'Movistar Sans'` |
118-
| `movistar` _(legacy)_ | `'On Air'` |
119-
| `o2-new`, `o2` | `'On Air'` |
120-
| `vivo-new` _(preferred)_ | `'Vivo Type'` |
121-
| `vivo` _(legacy)_ | `'Roboto'` |
122-
| `telefonica`, `tu` | `'Telefonica Sans'` |
123-
| `blau` | `'Roboto'` |
124-
| `esimflag` | `'On Air'` |
125-
126-
Read `node_modules/@telefonica/mistica/doc/fonts.md` for `@font-face` declarations for each font.
127-
128-
12. **Always set `body` background using `skinVars.colors.background`.** Without it the page background won't
129-
match the theme, especially in dark mode. Set it inside a component rendered under `ThemeContextProvider`:
130-
131-
```tsx
132-
const GlobalStyles = () => <style>{`body { background-color: ${skinVars.colors.background}; }`}</style>;
133-
```
134-
135-
13. **Do NOT wrap these components in `ResponsiveLayout`**they already contain one internally:
136-
`HeaderLayout`, `MainSectionHeaderLayout`, `Hero`, `CoverHero`, `MasterDetailLayout`,
137-
`ButtonFixedFooterLayout`, `NavigationBar`, `MainNavigationBar`, `FunnelNavigationBar`, `Tabs`,
138-
`SuccessFeedbackScreen`, `ErrorFeedbackScreen`, `InfoFeedbackScreen`, `LoadingScreen`,
139-
`BrandLoadingScreen`. Place them at page level, side by side with `ResponsiveLayout` blocks.
140-
141-
14. **Use carousels only for horizontal content.** `Carousel` and `CenteredCarousel` are horizontal-scroll
142-
componentsalways place them **inside** `ResponsiveLayout`. `Slideshow` bleeds full-width automatically
143-
and should be placed **outside** `ResponsiveLayout`.
144-
145-
## Quick Reference
146-
147-
### Standard page structure
148-
149-
```tsx
150-
<ThemeContextProvider theme={misticaTheme}>
151-
{/* GlobalStyles: set body font (see rule 11) and background (see rule 12) */}
152-
<GlobalStyles />
153-
{/* These components have their own internal ResponsiveLayout — place them at page level */}
154-
<MainNavigationBar sections={[...]} />
155-
<HeaderLayout header={<Header title="Page Title" />} />
156-
{/* Slideshow goes outside ResponsiveLayout — it bleeds full-width automatically */}
157-
<Slideshow items={[...]} />
158-
<ResponsiveLayout>
159-
<Box paddingY={24}>
160-
<Stack space={32}>
161-
<Stack space={16}>{/* section elements */}</Stack>
162-
{/* Carousel and CenteredCarousel go INSIDE ResponsiveLayout */}
163-
<Carousel itemsPerPage={{mobile: 1, tablet: 2, desktop: 3}} items={[...]} />
164-
</Stack>
165-
</Box>
166-
</ResponsiveLayout>
167-
</ThemeContextProvider>
168-
```
169-
170-
### Vertical rhythm: 24px container padding, 32px between sections, 16px between elements.
171-
172-
### Card asset pattern
173-
174-
```tsx
175-
<Circle backgroundColor={skinVars.colors.brandLow} size={40}>
176-
<IconShopRegular color={skinVars.colors.brand} />
177-
</Circle>
178-
```
179-
180-
### Color usage
75+
## Rules
18176

182-
```tsx
183-
import {skinVars, applyAlpha} from '@telefonica/mistica';
184-
185-
skinVars.colors.textPrimary; // text color
186-
skinVars.colors.brand; // brand color
187-
skinVars.colors.backgroundContainer; // container bg
188-
applyAlpha(skinVars.rawColors.brand, 0.5); // semi-transparent
189-
```
77+
Treat `node_modules/@telefonica/mistica/doc/llms.md` as the canonical source of truth for critical rules,
78+
page structure, and Mistica best practices. Do not rely on abbreviated rules here when `llms.md` is
79+
available.

0 commit comments

Comments
 (0)