# Dashboard Themes > Customize dashboard styles, define dashboard themes **Themes** give you full control over how your dashboards look — typography, colors, spacing, and visualization styling. Define them once to enforce consistent branding across your workspace, or apply them ad-hoc to a single dashboard. You can customize: - **Typography:** Font family and size for text and data labels - **Colors:** Dashboard backgrounds, borders, and other UI elements - **Canvas & block styling:** Padding, shadows, and background images - **Visualization styling:** Tables, KPI metrics, and chart color palettes ## High-level concepts ### Theme types There are two types of themes in Holistics: **reusable themes**, and **local themes**. Each serves different use cases: Name Description Reusable themes Themes that can be applied across multiple dashboards, providing consistency and efficiency. There are two sub-types: Built-in themes: Ready-to-use themes shipped by Holistics Custom themes: Themes created by your team's admins and analysts, saved for organization-wide use These themes can be selected from a dropdown menu when styling any dashboard. Local themes (or ad-hoc themes) Local customizations applied directly to a specific dashboard that cannot be reused elsewhere. Perfect for: Quick one-off styling adjustments Dashboard-specific branding requirements Prototyping theme ideas before creating reusable versions ### Theme components A theme is defined as a `PageTheme` object that contains the following sections: | Section | Description | | --- | --- | | `color` | Default [color palette](/docs/admin/dashboard-themes/color-palettes) for all charts in the dashboard | | `background` | Background of the outermost page viewport | | `canvas` | Styling for the main canvas area: background, border, shadow, opacity | | `block` | Default styling for all blocks: label, text, border, background, shadow, padding, opacity | | `viz` | Default styling for data visualizations | | `custom_css` | [Custom CSS](/docs/admin/dashboard-themes/custom-css) injected into the dashboard | See [AML Theme Reference](/reference/aml/theme) for full syntax details. ## Apply a theme You can apply reusable themes to your canvas dashboards using either the GUI or code approach: - **GUI:** Open **Themes setting** at the top right corner of your dashboard and choose from either built-in or custom themes: - **Code:** Reference the theme directly in your dashboard code in **Development** using the following syntax: ```tsx Dashboard ecommerce_dashboard { // highlight-next-line theme: H.themes.name // built-in themes } ``` ```tsx Dashboard ecommerce_dashboard { // highlight-next-line theme: theme_name // custom themes } ``` ## Create a theme :::tip Use the Theme Builder Themes are currently configured in AML code with no built-in visual editor. To make this easier, use the **[external Theme Builder](/docs/admin/dashboard-themes/theme-builder)**: an interactive sandbox to design and preview your theme visually, then copy the generated AML code into Holistics. ::: ### Create a local theme **Local themes** are defined directly within your dashboard code using the `theme` parameter. When your dashboard uses a local theme, you'll see a local theme indicator in the Theme Settings panel: **Syntax:** ```tsx Dashboard ecommerce_dashboard { // highlight-next-line theme {} // normal local theme } ``` ```tsx Dashboard ecommerce_dashboard { // highlight-next-line theme: PageTheme {} // normal local theme, using AML syntax } ``` ```tsx Dashboard ecommerce_dashboard { // highlight-next-line theme: theme_name.extend({}) // local theme created from extending a reusable theme } ``` ### Create a reusable theme To create a reusable custom theme, simply follow these steps: 1. Go to **Development > Library > Themes** and create a new `.theme.aml` file with a `PageTheme` definition. 2. Once saved, apply it from the **Theme settings** menu or reference it directly in your dashboard code via the `theme` parameter. For example, here we create a `themes.aml` file to declare a custom theme named **classic_blue**, and then reference it in the dashboard file under the `theme` parameter: ```mdx-code-block ``` ```aml Dashboard ecommerce_dashboard { title: "eCommerce dashboard" // highlight-next-line theme: classic_blue ... } ``` ```mdx-code-block ``` ```aml // highlight-next-line PageTheme classic_blue { background { bg_color: '#FFFFFF' bg_repeat: false bg_size: "cover" // bg_image: } canvas { border { border_radius: 4 border_width: 1 border_color: '#4896EA' border_style: "solid" } background { bg_color: '#D1E5FA' bg_repeat: false bg_size: "cover" // bg_image: } shadow: "none" opacity: 1 } // Block Theme block { label { font_family: "Inter" font_size: 14 font_color: '#1357A0' font_weight: "medium" font_style: "normal" // letter_spacing: // text_decoration: // text_transform: } text { font_family: "Inter" font_size: 12 font_color: '#1357A0' font_weight: "normal" font_style: "normal" // letter_spacing: // text_decoration: // text_transform: } border { border_width: 1 border_radius: 8 border_color: '#4896EA' border_style: "solid" } background { bg_color: '#E8F2FD' bg_repeat: false bg_size: "cover" // bg_image: } padding: 12 shadow: "none" opacity: 1 } //Viz Theme viz { // Table Theme table { general { bg_color: 'white' hover_color: '#C8DCF2' banding_color: '#EAF5FC' font_size: 12 font_color: '#505D6A' font_family: 'Arial' border_color: '#90A2B7' border_width: 1 grid_color: '#90A2B7' } header { bg_color: '#608EC3' font_size: 12 font_color: 'white' font_weight: 'bold' } // Pivot table properties sub_header { bg_color: '#AECEF2' font_size: 12 font_color: '#505D6A' font_weight: 'bold' } // Metric Sheet properties sub_title { font_size: 12 font_color: '#505D6A' font_weight: 'bold' } sparkline { line { color: '#255DD4' width: 2 } column { color: '#255DD4' width: 12 } } } // KPI Metric Theme metric_kpi { alignment: "center" label { font_family: "Inter" font_size: 14 font_color: '#64748B' font_weight: "medium" } value { font_family: "Inter" font_size: 32 font_color: '#1357A0' font_weight: "bold" } progress { text { font_size: 12 font_color: '#505D6A' } indicator { bg_color: '#4896EA' } track { bg_color: '#D1E5FA' } } trend { positive { text { font_color: '#15803D' } background { bg_color: '#DCFCE7' } } negative { text { font_color: '#B91C1C' } background { bg_color: '#FEE2E2' } } neutral { text { font_color: '#475569' } background { bg_color: '#F1F5F9' } } } } } } ``` ```mdx-code-block ``` **Result:** ### Set a chart color palette You can set a default [color palette](/docs/admin/dashboard-themes/color-palettes) for all charts in a dashboard by referencing it in your theme: ```aml PageTheme my_theme { // highlight-start color { data: palette_name } // highlight-end } ``` The palette priority order is: **viz-level palette > theme palette > project default palette**. If no palette is set at a given level, it falls through to the next. ### Add custom CSS You can include CSS snippets directly in your theme using the `custom_css` parameter and reuse it across dashboards. [Read more for details and examples](/docs/admin/dashboard-themes/custom-css). ```tsx PageTheme classic { // existing theme properties // highlight-start custom_css: @css /* your custom CSS rules here */ ;; // highlight-end } ``` ## Customize individual blocks Block and viz styling works at two levels: - **Theme level**: Define inside a `PageTheme` to set defaults for any dashboard using that theme: - `block {}` applies to all [block types](/docs/dashboards#block) - `viz {}` applies only to [Viz blocks](/docs/dashboards/visualization-blocks) - **Block level**: Define overrides on a specific block in your dashboard file using `BlockTheme` (for block container styling) or `VizTheme` (for viz content inside a Viz block) to customize that specific block only. ### Override block styling ```tsx Dashboard ecommerce_dashboard { block text_block: TextBlock { ... // highlight-start theme: BlockTheme { background { bg_color: 'transparent' } } // highlight-end } } ``` ### Override viz styling Currently, viz-level styling is supported for [Table](/docs/charts/table), [Pivot Table](/docs/charts/pivot-table), [Metric Sheet](/docs/charts/metric-sheets), and [KPI Metric](/docs/charts/metric-kpi) visualizations. ```mdx-code-block ``` ```tsx Dashboard ecommerce_dashboard { block table_name: VizBlock { ... viz: PivotTable { ... // highlight-start theme: VizTheme { table { general { bg_color: 'white' } } } // highlight-end } } } ``` ```mdx-code-block ``` ```tsx Dashboard ecommerce_dashboard { block kpi_name: VizBlock { ... viz: MetricKpi { ... // highlight-start theme: VizTheme { metric_kpi { alignment: "center" value { font_color: "#1357A0" font_weight: "bold" } trend { positive { background { bg_color: "#DCFCE7" } } negative { background { bg_color: "#FEE2E2" } } } } } // highlight-end } } } ``` ```mdx-code-block ``` ## Reuse theme values Theme definitions often repeat the same values - the same color code or font family appearing across `block`, `canvas`, and `viz` sections. You can use [AML reusability](/as-code/aml/reusability-overview) features to define these values once and reference them throughout, so a single change updates the whole theme. ### Use constants for reusable values ```tsx const classic_blue_border_color = "#4896EA" const classic_blue_font_color = "#1357A0" const classic_blue_font_family = "Inter" PageTheme classic_blue { // other properties omitted... canvas { border { // other properties omitted... border_color: classic_blue_border_color } } block { // other properties omitted... label { // other properties omitted... font_family: classic_blue_font_family } text { // other properties omitted... font_family: classic_blue_font_family } border { // other properties omitted... border_color: classic_blue_border_color } } } ``` ### Use AML Dict to avoid namespace pollution ```tsx // Instead of separate constant for each variable // const classic_blue_border_color = "#4896EA" // const classic_blue_font_color = "#1357A0" // const classic_blue_font_family = "Inter" // You can use an AML Dict instead const classic_blue_vars = { border_color: "#4896EA" font_color: "#1357A0" font_family: "Inter" } // then use it like this PageTheme classic_blue { // other properties omitted... canvas { border { // other properties omitted... border_color: classic_blue_vars("border_color") } } } ``` ## Syntax Reference For a full parameter reference for `PageTheme`, `BlockTheme`, and `VizTheme`, see the [AML Theme and Colors](/reference/aml/theme). :::tip Hover over `PageTheme`, `BlockTheme` or `VizTheme` in the code editor to see suggestions for available parameters. :::