# Panda CSS Theming > This document contains all theming documentation for Panda CSS ## Table of Contents - [Animation Styles](#animation-styles) - [Layer Styles](#layer-styles) - [Spec](#spec) - [Using Panda Studio](#using-panda-studio) - [Text Styles](#text-styles) - [Tokens](#tokens) - [Using Tokens](#using-tokens) --- ## Animation Styles Define reusable animation css properties. Animation styles focus solely on animations, allowing you to orchestrate animation properties. ## Defining Animation Styles Animation styles are defined in the `animationStyles` property of the theme. Here's an example of an animation style: ```js filename="animation-styles.ts" import { defineAnimationStyles } from '@pandacss/dev' export const animationStyles = defineAnimationStyles({ 'slide-fade-in': { value: { transformOrigin: 'var(--transform-origin)', animationDuration: 'fast', '&[data-placement^=top]': { animationName: 'slide-from-top, fade-in' }, '&[data-placement^=bottom]': { animationName: 'slide-from-bottom, fade-in' }, '&[data-placement^=left]': { animationName: 'slide-from-left, fade-in' }, '&[data-placement^=right]': { animationName: 'slide-from-right, fade-in' } } } }) ``` > **Good to know:** The `value` property maps to style objects that will be applied to the element. ## Update the Config To use the animation styles, we need to update the `config` object in the `panda.config.ts` file. ```js filename="panda.config.ts" import { defineConfig } from '@pandacss/dev' import { animationStyles } from './animation-styles' export default defineConfig({ theme: { extend: { animationStyles } } }) ``` This should automatically update the generated theme with the specified `animationStyles`. If this doesn't happen, you can run the `panda codegen` command. ## Using Animation Styles Now we can use the `animationStyle` property in our components. ```jsx import { css } from '../styled-system/css' function App() { return (
This is an element with slide-fade-in animation style.
) } ``` Take advantage of it in your conditions: ```ts export const popoverSlotRecipe = defineSlotRecipe({ slots: anatomy.keys(), base: { content: { _open: { animationStyle: 'scale-fade-in' }, _closed: { animationStyle: 'scale-fade-out' } } } }) ``` ## Nesting animation styles Animation styles support nested structures with a special `DEFAULT` key. This allows you to create variants of an animation style while having a default fallback. When you define a `DEFAULT` key within a nested animation style, you can reference the parent key directly to use the default value. ```js filename="panda.config.ts" export default defineConfig({ theme: { extend: { animationStyles: { fade: { DEFAULT: { value: { animationName: 'fade-in', animationDuration: '300ms', animationTimingFunction: 'ease-in-out' } }, slow: { value: { animationName: 'fade-in', animationDuration: '600ms', animationTimingFunction: 'ease-in-out' } }, fast: { value: { animationName: 'fade-in', animationDuration: '150ms', animationTimingFunction: 'ease-in-out' } } } } } } }) ``` Now you can use the default fade animation or specific speed variants: ```jsx import { css } from '../styled-system/css' function App() { return (
Default fade speed
Slow fade
Fast fade
) } ``` ## Best Practices ### Avoid Overuse To ensure the performance and readability of your design system, avoid overusing animations. Use them sparingly to enhance user experience without overwhelming the user. ### Consistent Naming Conventions We recommend using consistent naming conventions for animation styles. Here are common ideas on how to name animation styles: - Based on the type of animation (`slide`, `fade`, `bounce`) - Based on the direction or trigger (`slide-from-top`, `fade-in`, `bounce-on-click`) - Descriptive or functional names that explain the style's intended use (`modal-open`, `button-hover`, `alert-show`) By following these guidelines, you can create a clear and maintainable animation system in your design. --- ## Layer Styles Define reusable container styles properties. Layer styles provide a way to create consistent and visually appealing elements. - Color or text color - Background color - Border width and border color - Box shadow - Opacity ## Defining layer styles Layer styles are defined in the `layerStyles` property of the theme. Here's an example of a layer style: ```js filename="layer-styles.ts" import { defineLayerStyles } from '@pandacss/dev' const layerStyles = defineLayerStyles({ container: { description: 'container styles', value: { background: 'gray.50', border: '2px solid', borderColor: 'gray.500' } } }) ``` > **Good to know:** The `value` property maps to style objects that will be applied to the element. ## Update the config To use the layer styles, we need to update the `config` object in the `panda.config.ts` file. ```js filename="panda.config.ts" import { defineConfig } from '@pandacss/dev' import { layerStyles } from './layer-styles' export default defineConfig({ theme: { extend: { layerStyles } } }) ``` This should automatically update the generated theme the specified `layerStyles`. If this doesn't happen, you can run the `panda codegen` command. ## Using layer styles Now we can use `layerStyle` property in our components. ```jsx import { css } from '../styled-system/css' function App() { return
This is inside a container style
} ``` ## Nesting layer styles Layer styles support nested structures with a special `DEFAULT` key. This allows you to create variants of a layer style while having a default fallback. When you define a `DEFAULT` key within a nested layer style, you can reference the parent key directly to use the default value. ```js filename="panda.config.ts" export default defineConfig({ theme: { extend: { layerStyles: { card: { DEFAULT: { value: { background: 'white', border: '1px solid', borderColor: 'gray.200', borderRadius: 'md', boxShadow: 'sm' } }, elevated: { value: { background: 'white', border: 'none', borderRadius: 'lg', boxShadow: 'lg' } }, outlined: { value: { background: 'transparent', border: '2px solid', borderColor: 'gray.300', borderRadius: 'md', boxShadow: 'none' } } } } } } }) ``` Now you can use the default card style or specific variants: ```jsx import { css } from '../styled-system/css' function App() { return (
Default card style
Elevated card
Outlined card
) } ``` --- ## Spec Document your design system in Panda. A spec is a readable JSON representation of the theme structure in your panda config. They're designed to be used for **documentation purposes** in your own docs websites and Storybook. Some common use cases: - Document tokens in your theme (colors, spacing, fonts, etc.) - Showcase the recipes and slot recipes (include their variants and default variants) - Document the typography styles and layer styles ## Spec Command To create the spec files, run the following command in your terminal: ```bash pnpm panda spec ``` Learn more about the spec CLI flags [here](/docs/references/cli#spec) ## Spec Output The spec command generates a set of JSON files that represent your entire design system. Here's an example of the output structure: ```sh styled-system/ └── specs/ # Generated documentation-ready spec files ├── animation-styles.json # Animation style presets (empty if none defined) ├── color-palette.json # List of palette names (blue, teal, etc.) ├── conditions.json # Condition selectors (_hover, _focus, ...) ├── keyframes.json # Keyframe definitions (spin, ping, ...) ├── layer-styles.json # Layer style definitions (card, overlay, ...) ├── patterns.json # Pattern definitions + their properties ├── recipes.json # Component recipes + variants + defaults ├── semantic-tokens.json # Semantic tokens with conditions (base, dark, etc.) ├── text-styles.json # Text style definitions (xs, sm, md, ...) └── tokens.json # Raw design tokens grouped by category ``` Below is a breakdown of what each file contains and how it can be used. ### `tokens.json` #### Structure This file contains an array of raw design tokens grouped by category ```json { "type": "tokens", "data": [ { "type": "colors", "values": [ { "name": "purple.800", "value": "#6b21a8", "cssVar": "var(--colors-purple-800)" } ], "tokenFunctionExamples": ["token('colors.purple.800')", "token.var('colors.purple.800')"], "functionExamples": ["css({ color: 'purple.800' })"], "jsxExamples": [""] } ] } ``` Each token in the `values` array includes: - **name**: token key (e.g., 2xs, md, primary) - **value**: resolved CSS value (e.g., "1rem", "#F6E458") - **cssVar**: the generated CSS custom property - **tokenFunctionExamples**: examples of how to use the token in the `token` function - **functionExamples**: examples of how to use the token in the `css` function - **jsxExamples**: examples of how to use the token in JSX #### Usage Here's an example of how to document color tokens: ```tsx import { grid } from 'styled-system/patterns' import tokens from 'styled-system/specs/tokens.json' const Demo = () => { const colors = tokens.data.find(token => token.type === 'colors') return (
{colors?.values.map(color => (

{color.name}

{color.value}

))}
) } ``` Your color token documentation should look similar to this: ![Token Spec Documentation](/token-spec.png) ### `semantic-tokens.json` #### Structure This file contains an array of semantic token definitions grouped by category, with conditional values for different modes (e.g., light/dark). ```json { "type": "semantic-tokens", "data": [ { "type": "colors", "values": [ { "name": "bg", "values": [ { "value": "{colors.white}", "condition": "base" }, { "value": "{colors.dark}", "condition": "dark" } ], "cssVar": "var(--colors-bg)" } ], "tokenFunctionExamples": ["token('colors.bg')", "token.var('colors.bg')"], "functionExamples": ["css({ color: 'bg' })"], "jsxExamples": [""] } ] } ``` Each semantic token in the `values` array includes: - **name**: the semantic token key (e.g., `bg`, `fg.muted`, `accent`) - **values**: an array of conditional mappings, each with: - **value**: the resolved token reference (e.g., `{colors.white}`) - **condition**: the condition name (e.g., `base`, `dark`) - **cssVar**: the generated CSS custom property - **tokenFunctionExamples**: examples of how to use the token in the `token` function - **functionExamples**: examples of how to use the token in the `css` function - **jsxExamples**: examples of how to use the token in JSX #### Usage Here's an example of how to document semantic color tokens with their conditional values: ```tsx import semanticTokens from 'styled-system/specs/semantic-tokens.json' const Demo = () => { const colors = semanticTokens.data.find(token => token.type === 'colors') return (
{colors?.values.map(token => (

{token.name}

{token.cssVar}

{token.values.map(({ condition, value }) => (
{condition}

{value}

))}
))}
) } ``` ### `recipes.json` #### Structure This file contains an array of recipe definitions for styling components with variant support. ```json { "type": "recipes", "data": [ { "name": "button", "description": "A button style", "variants": { "shape": ["square", "circle"], "color": ["main", "black", "white"], "size": ["sm", "md", "lg"] }, "defaultVariants": { "shape": "square", "color": "main", "size": "md" }, "functionExamples": ["button({ shape: 'square' })", "button({ color: 'main' })", "button({ size: 'sm' })"], "jsxExamples": ["