Initial commit
This commit is contained in:
12
.claude-plugin/plugin.json
Normal file
12
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "quarto",
|
||||||
|
"description": "Collection of skills for Quarto document creation",
|
||||||
|
"version": "0.0.0-2025.11.28",
|
||||||
|
"author": {
|
||||||
|
"name": "Garrick Aden-Buie (Posit, PBC)",
|
||||||
|
"email": "garrick@posit.co"
|
||||||
|
},
|
||||||
|
"skills": [
|
||||||
|
"./skills/brand-yml"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# quarto
|
||||||
|
|
||||||
|
Collection of skills for Quarto document creation
|
||||||
68
plugin.lock.json
Normal file
68
plugin.lock.json
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||||
|
"pluginId": "gh:posit-dev/skills:quarto",
|
||||||
|
"normalized": {
|
||||||
|
"repo": null,
|
||||||
|
"ref": "refs/tags/v20251128.0",
|
||||||
|
"commit": "f026c20bc2cfe1047a6bc3351b6c4d7902ef1720",
|
||||||
|
"treeHash": "ce436a7c5d8d9ef05ddffe2881164ced6bc9608f69ed15a10a6d5eb791a26fb7",
|
||||||
|
"generatedAt": "2025-11-28T10:27:40.229594Z",
|
||||||
|
"toolVersion": "publish_plugins.py@0.2.0"
|
||||||
|
},
|
||||||
|
"origin": {
|
||||||
|
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||||
|
"branch": "master",
|
||||||
|
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||||
|
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "quarto",
|
||||||
|
"description": "Collection of skills for Quarto document creation"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.md",
|
||||||
|
"sha256": "4b23f4c6f5763c0ceea2addbe86c6fcfb02db59745e85c637a2516a507832d94"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".claude-plugin/plugin.json",
|
||||||
|
"sha256": "1e734b1cecbf4327e77dce3f79afd900ccaf4fc93c44d718b859257b31e9cc84"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/brand-yml/README.md",
|
||||||
|
"sha256": "3ead89473df4809ad5d7effbbe513a691de054acd985e808025ff0726d0241e6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/brand-yml/SKILL.md",
|
||||||
|
"sha256": "25ac6c5b31223486df06ea742f952ff608a186dfa07f801d3dab10fdf52a0ebc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/brand-yml/references/brand-yml-in-r.md",
|
||||||
|
"sha256": "780fb3bbe9a2750ca5b8ad6e26ee33252442111a6f2304cb94b9dfacf3ca1f40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/brand-yml/references/shiny-r.md",
|
||||||
|
"sha256": "0109581d56119a7a6c1dbb1b06254deee018ef922da2ceec2a7039b1244cb59d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/brand-yml/references/quarto.md",
|
||||||
|
"sha256": "81427cd4b7154faa638d5e5e56a569239cca83d13f3a208bbf2d20f43e29d30e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/brand-yml/references/brand-yml-spec.md",
|
||||||
|
"sha256": "4c1c8800cb9a80563a78ba3b7ac7590f775535fc91c338f04e0b9ed61e5ec606"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "skills/brand-yml/references/shiny-python.md",
|
||||||
|
"sha256": "6d034f3bba828070478c62e2b8272ea6572971f2fd607b1128504d50125cf2db"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dirSha256": "ce436a7c5d8d9ef05ddffe2881164ced6bc9608f69ed15a10a6d5eb791a26fb7"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"scannedAt": null,
|
||||||
|
"scannerVersion": null,
|
||||||
|
"flags": []
|
||||||
|
}
|
||||||
|
}
|
||||||
82
skills/brand-yml/README.md
Normal file
82
skills/brand-yml/README.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# brand.yml Skill
|
||||||
|
|
||||||
|
Create and use `_brand.yml` files for consistent branding across Shiny applications and Quarto documents.
|
||||||
|
|
||||||
|
## What This Skill Does
|
||||||
|
|
||||||
|
This skill helps Claude:
|
||||||
|
- Create `_brand.yml` files from brand guidelines
|
||||||
|
- Apply brand styling to Shiny for R apps using bslib
|
||||||
|
- Apply brand styling to Shiny for Python apps using ui.Theme
|
||||||
|
- Use brand.yml in Quarto documents, presentations, and PDFs
|
||||||
|
- Troubleshoot brand integration issues
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use this skill when working with:
|
||||||
|
- Brand styling and corporate identity
|
||||||
|
- Colors, fonts, and logos in Shiny or Quarto
|
||||||
|
- Creating or modifying brand.yml files
|
||||||
|
- Applying consistent branding across multiple projects
|
||||||
|
|
||||||
|
## What is brand.yml?
|
||||||
|
|
||||||
|
brand.yml is a YAML-based specification that translates brand guidelines into a portable, machine-readable format. It enables consistent styling across Shiny apps (R and Python) and Quarto documents (HTML, PDFs, presentations, dashboards) from a single `_brand.yml` file.
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
- **Complete specification**: Full brand.yml spec with all sections, fields, and validation rules
|
||||||
|
- **Framework integration guides**: Separate guides for Shiny R, Shiny Python, and Quarto
|
||||||
|
- **Self-contained**: All necessary information to create and use brand.yml files without external documentation
|
||||||
|
- **Best practices**: Guidance on file structure, naming conventions, and common patterns
|
||||||
|
|
||||||
|
## Skill Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
brand-yml/
|
||||||
|
├── SKILL.md # Main skill file with workflows and decision tree
|
||||||
|
└── references/
|
||||||
|
├── brand-yml-spec.md # Complete brand.yml specification
|
||||||
|
├── shiny-r.md # Shiny for R integration (bslib)
|
||||||
|
├── shiny-python.md # Shiny for Python integration (ui.Theme)
|
||||||
|
└── quarto.md # Quarto integration (all formats)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The skill automatically loads based on keywords related to brand styling, colors, fonts, or brand.yml files. Claude will:
|
||||||
|
|
||||||
|
1. Determine the user's goal (creating, using, or troubleshooting)
|
||||||
|
2. Load the appropriate reference documentation
|
||||||
|
3. Guide the user through the workflow
|
||||||
|
4. Create or modify files as needed
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
**Creating a brand.yml file:**
|
||||||
|
> "Create a _brand.yml file for our company with primary color #0066cc and Inter font from Google Fonts"
|
||||||
|
|
||||||
|
**Applying to Shiny R:**
|
||||||
|
> "Add brand styling to this Shiny app using our _brand.yml file"
|
||||||
|
|
||||||
|
**Applying to Quarto:**
|
||||||
|
> "Use our brand colors in this Quarto presentation"
|
||||||
|
|
||||||
|
**Troubleshooting:**
|
||||||
|
> "Why aren't the brand colors showing up in my Shiny app?"
|
||||||
|
|
||||||
|
## Marketplace Registration
|
||||||
|
|
||||||
|
This skill is registered in two marketplace categories:
|
||||||
|
|
||||||
|
- **shiny**: For Shiny app developers
|
||||||
|
- **quarto**: For Quarto document creators
|
||||||
|
|
||||||
|
Both point to the same skill directory but provide context-appropriate discovery.
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
- [brand.yml project](https://posit-dev.github.io/brand-yml/)
|
||||||
|
- [Shiny for R brand.yml guide](https://rstudio.github.io/bslib/articles/brand-yml/)
|
||||||
|
- [Shiny for Python brand.yml docs](https://shiny.posit.co/py/api/core/ui.Theme.html#shiny.ui.Theme.from_brand)
|
||||||
|
- [Quarto brand.yml docs](https://quarto.org/docs/authoring/brand.html)
|
||||||
383
skills/brand-yml/SKILL.md
Normal file
383
skills/brand-yml/SKILL.md
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
---
|
||||||
|
name: brand-yml
|
||||||
|
description: >
|
||||||
|
Create and use brand.yml files for consistent branding across Shiny apps and Quarto documents.
|
||||||
|
Use when working with brand styling, colors, fonts, logos, or corporate identity in Shiny or
|
||||||
|
Quarto projects. Covers: (1) Creating new _brand.yml files from brand guidelines, (2) Applying
|
||||||
|
brand.yml to Shiny for R apps with bslib, (3) Applying brand.yml to Shiny for Python apps with
|
||||||
|
ui.Theme, (4) Using brand.yml in Quarto documents, presentations, dashboards, and PDFs, (5)
|
||||||
|
Modifying existing brand.yml files, (6) Troubleshooting brand integration issues. Includes
|
||||||
|
complete specifications and framework-specific integration guides.
|
||||||
|
---
|
||||||
|
|
||||||
|
# brand.yml Skill
|
||||||
|
|
||||||
|
Create and use `_brand.yml` files for consistent branding across Shiny applications and Quarto documents.
|
||||||
|
|
||||||
|
## What is brand.yml?
|
||||||
|
|
||||||
|
brand.yml is a YAML-based format that translates brand guidelines into a machine-readable file usable across Shiny and Quarto. A single `_brand.yml` file defines:
|
||||||
|
|
||||||
|
- **Colors** - Palette and semantic colors (primary, success, warning, etc.)
|
||||||
|
- **Typography** - Fonts, sizes, weights, line heights
|
||||||
|
- **Logos** - Multiple sizes and light/dark variants
|
||||||
|
- **Meta** - Company name, links, identity information
|
||||||
|
|
||||||
|
## File Naming Convention
|
||||||
|
|
||||||
|
- **Standard name**: `_brand.yml` (auto-discovered by Shiny and Quarto)
|
||||||
|
- **Custom names**: Any name like `company-brand.yml` (requires explicit paths)
|
||||||
|
- **Location**: Typically at project root, or in `_brand/` or `brand/` subdirectories
|
||||||
|
|
||||||
|
## Decision Tree
|
||||||
|
|
||||||
|
Determine the user's goal and follow the appropriate workflow:
|
||||||
|
|
||||||
|
1. **Creating a new _brand.yml file?** → Follow "Creating brand.yml Files"
|
||||||
|
2. **Using brand.yml in Shiny for R?** → Read `references/shiny-r.md`
|
||||||
|
3. **Using brand.yml in Shiny for Python?** → Read `references/shiny-python.md`
|
||||||
|
4. **Using brand.yml in Quarto?** → Read `references/quarto.md`
|
||||||
|
5. **Using brand.yml in R (general)?** → Read `references/brand-yml-in-r.md` (R Markdown, theming functions, programmatic access)
|
||||||
|
6. **Modifying existing _brand.yml?** → Follow "Modifying Existing Files"
|
||||||
|
7. **Troubleshooting integration?** → Follow "Troubleshooting"
|
||||||
|
|
||||||
|
## Creating brand.yml Files
|
||||||
|
|
||||||
|
When creating `_brand.yml` files from brand guidelines:
|
||||||
|
|
||||||
|
### Step 1: Gather Information
|
||||||
|
|
||||||
|
Collect brand information:
|
||||||
|
- **Colors**: Primary, secondary, accent colors with hex values
|
||||||
|
- **Fonts**: Font families and where they're sourced (Google Fonts, local files, etc.)
|
||||||
|
- **Logos**: Logo file paths or URLs for different sizes
|
||||||
|
- **Company info**: Name, website, social links (optional)
|
||||||
|
|
||||||
|
### Step 2: Read the Specification
|
||||||
|
|
||||||
|
Load `references/brand-yml-spec.md` to understand the complete brand.yml structure, field options, and syntax.
|
||||||
|
|
||||||
|
### Step 3: Build the File Incrementally
|
||||||
|
|
||||||
|
Start with the essential sections and add optional elements:
|
||||||
|
|
||||||
|
**Minimum viable _brand.yml:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
brand-blue: "#0066cc"
|
||||||
|
primary: brand-blue
|
||||||
|
background: "#ffffff"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 600]
|
||||||
|
base: Inter
|
||||||
|
```
|
||||||
|
|
||||||
|
**Add colors as needed:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
brand-blue: "#0066cc"
|
||||||
|
brand-orange: "#ff6600"
|
||||||
|
brand-gray: "#666666"
|
||||||
|
primary: brand-blue
|
||||||
|
secondary: brand-gray
|
||||||
|
warning: brand-orange
|
||||||
|
foreground: "#333333"
|
||||||
|
background: "#ffffff"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Add typography details:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 600, 700]
|
||||||
|
style: [normal, italic]
|
||||||
|
- family: Fira Code
|
||||||
|
source: google
|
||||||
|
weight: [400, 500]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
size: 16px
|
||||||
|
line-height: 1.5
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
monospace: Fira Code
|
||||||
|
```
|
||||||
|
|
||||||
|
**Add logos:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logo:
|
||||||
|
small: logos/icon.png
|
||||||
|
medium: logos/header.png
|
||||||
|
large: logos/full.svg
|
||||||
|
```
|
||||||
|
|
||||||
|
**Add meta information:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
meta:
|
||||||
|
name: Company Name
|
||||||
|
link: https://example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Apply Best Practices
|
||||||
|
|
||||||
|
Follow these rules from `references/brand-yml-spec.md`:
|
||||||
|
|
||||||
|
- All fields are optional - only include what's needed
|
||||||
|
- Use hex color format: `"#0066cc"`
|
||||||
|
- Prefer simple syntax (strings over objects) when possible
|
||||||
|
- Use lowercase names with hyphens: `brand-blue`, `success-green`
|
||||||
|
- Include `https://` in all URLs
|
||||||
|
- Define colors/fonts before referencing them
|
||||||
|
- For color ranges (shades/tints), choose the midpoint color
|
||||||
|
|
||||||
|
### Step 5: Validate Structure
|
||||||
|
|
||||||
|
Check that:
|
||||||
|
- YAML syntax is valid (proper indentation, quotes on hex colors)
|
||||||
|
- Color references match palette names
|
||||||
|
- Font families are defined before use
|
||||||
|
- File paths are relative to `_brand.yml` location
|
||||||
|
- All URLs include protocol (`https://`)
|
||||||
|
|
||||||
|
## Modifying Existing Files
|
||||||
|
|
||||||
|
When modifying existing `_brand.yml` files:
|
||||||
|
|
||||||
|
1. **Read the current file** to understand existing structure
|
||||||
|
2. **Consult brand-yml-spec.md** for valid field options
|
||||||
|
3. **Maintain consistency** with existing naming patterns
|
||||||
|
4. **Preserve references** - if other colors/elements reference a name, update consistently
|
||||||
|
5. **Test integration** - verify changes apply correctly in Shiny/Quarto
|
||||||
|
|
||||||
|
Common modifications:
|
||||||
|
- **Adding colors**: Add to `color.palette`, then reference in semantic colors
|
||||||
|
- **Changing fonts**: Update in `typography.fonts`, ensure weights/styles are available
|
||||||
|
- **Adding logo variants**: Use `light`/`dark` structure for multiple variants
|
||||||
|
- **Light/dark mode**: Add `light` and `dark` variants to colors
|
||||||
|
|
||||||
|
## Using with Shiny for R
|
||||||
|
|
||||||
|
When the user wants to apply brand.yml to a Shiny for R app:
|
||||||
|
|
||||||
|
1. **Read `references/shiny-r.md`** for complete integration guide
|
||||||
|
2. **Key function**: `bs_theme(brand = TRUE)` or `bs_theme(brand = "path")`
|
||||||
|
3. **Automatic discovery**: Place `_brand.yml` at app root
|
||||||
|
4. **Page functions**: Works with `page_fluid()`, `page_sidebar()`, etc.
|
||||||
|
|
||||||
|
Quick example:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(shiny)
|
||||||
|
library(bslib)
|
||||||
|
|
||||||
|
ui <- page_fluid(
|
||||||
|
theme = bs_theme(brand = TRUE),
|
||||||
|
# ... UI elements
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using with Shiny for Python
|
||||||
|
|
||||||
|
When the user wants to apply brand.yml to a Shiny for Python app:
|
||||||
|
|
||||||
|
1. **Read `references/shiny-python.md`** for complete integration guide
|
||||||
|
2. **Key function**: `ui.Theme.from_brand(__file__)`
|
||||||
|
3. **Automatic discovery**: Place `_brand.yml` at app root
|
||||||
|
4. **Installation**: Requires `pip install "shiny[theme]"`
|
||||||
|
|
||||||
|
Quick example (Shiny Express):
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny.express import ui
|
||||||
|
|
||||||
|
ui.page_opts(theme=ui.Theme.from_brand(__file__))
|
||||||
|
```
|
||||||
|
|
||||||
|
Quick example (Shiny Core):
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny import App, ui
|
||||||
|
|
||||||
|
app_ui = ui.page_fluid(
|
||||||
|
theme=ui.Theme.from_brand(__file__),
|
||||||
|
# ... UI elements
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using with Quarto
|
||||||
|
|
||||||
|
When the user wants to apply brand.yml to Quarto documents:
|
||||||
|
|
||||||
|
1. **Read `references/quarto.md`** for complete integration guide
|
||||||
|
2. **Automatic discovery**: Place `_brand.yml` at project root with `_quarto.yml`
|
||||||
|
3. **Supported formats**: HTML, dashboards, RevealJS, Typst PDFs
|
||||||
|
4. **Theme layering**: Use `brand` keyword to control precedence
|
||||||
|
|
||||||
|
Quick example (document):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Document"
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
brand: _brand.yml
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Quick example (project in `_quarto.yml`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
project:
|
||||||
|
brand: _brand.yml
|
||||||
|
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
theme: default
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Brand Not Applying
|
||||||
|
|
||||||
|
**Shiny:**
|
||||||
|
- Verify file is named `_brand.yml` (with underscore)
|
||||||
|
- Check file location (app directory or parent directories)
|
||||||
|
- Try explicit path: `bs_theme(brand = "path/to/_brand.yml")` or `ui.Theme.from_brand("path")`
|
||||||
|
- For Python: Ensure `libsass` is installed
|
||||||
|
|
||||||
|
**Quarto:**
|
||||||
|
- Verify `_brand.yml` is at project root
|
||||||
|
- Ensure `_quarto.yml` exists for project-level branding
|
||||||
|
- Try explicit path in document frontmatter
|
||||||
|
- Check theme layering order if using custom themes
|
||||||
|
|
||||||
|
### Colors Not Matching
|
||||||
|
|
||||||
|
- Ensure hex colors have quotes: `"#0066cc"` not `#0066cc`
|
||||||
|
- Verify color names match palette definitions exactly
|
||||||
|
- Check semantic colors (primary, success, etc.) reference valid palette names
|
||||||
|
- Ensure palette is defined before semantic colors
|
||||||
|
|
||||||
|
### Fonts Not Loading
|
||||||
|
|
||||||
|
- Verify Google Fonts spelling and availability
|
||||||
|
- Check internet connection (required for Google Fonts)
|
||||||
|
- Ensure `source: google` or `source: bunny` is specified
|
||||||
|
- Verify font family names match exactly in typography elements
|
||||||
|
- For Typst: Check font cache with `quarto typst fonts`
|
||||||
|
|
||||||
|
### YAML Syntax Errors
|
||||||
|
|
||||||
|
- Check indentation (use spaces, not tabs)
|
||||||
|
- Ensure hex colors have quotes: `"#447099"`
|
||||||
|
- Verify colons have space after them: `primary: blue`
|
||||||
|
- Check list items have hyphens: `- family: Inter`
|
||||||
|
- Use YAML validator if syntax issues persist
|
||||||
|
|
||||||
|
## Reference Documentation
|
||||||
|
|
||||||
|
Load these as needed for detailed information:
|
||||||
|
|
||||||
|
- **`references/brand-yml-spec.md`**: Complete brand.yml specification with all sections, fields, examples, and validation rules
|
||||||
|
- **`references/shiny-r.md`**: Using brand.yml with Shiny for R via bslib (bs_theme, automatic discovery, Shiny-specific integration)
|
||||||
|
- **`references/shiny-python.md`**: Using brand.yml with Shiny for Python via ui.Theme (from_brand(), installation, performance)
|
||||||
|
- **`references/quarto.md`**: Using brand.yml with Quarto (formats, light/dark mode, layering, extensions, Typst)
|
||||||
|
- **`references/brand-yml-in-r.md`**: General R usage including R Markdown integration, theming functions (ggplot2, gt, flextable, plotly, thematic), and programmatic brand access
|
||||||
|
|
||||||
|
## Key Principles
|
||||||
|
|
||||||
|
- **Start simple**: Begin with colors and one font family
|
||||||
|
- **Keep it concise**: Only include fields directly relevant to the brand
|
||||||
|
- **Prefer standard names**: Use Bootstrap color names when possible (blue, green, red, etc.)
|
||||||
|
- **Use automatic discovery**: Name file `_brand.yml` for auto-detection
|
||||||
|
- **Test across targets**: Verify brand applies correctly in all intended formats
|
||||||
|
- **Version control**: Include `_brand.yml` in git repository
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Light/Dark Mode Colors
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
primary:
|
||||||
|
light: "#0066cc"
|
||||||
|
dark: "#3399ff"
|
||||||
|
background:
|
||||||
|
light: "#ffffff"
|
||||||
|
dark: "#1a1a1a"
|
||||||
|
foreground:
|
||||||
|
light: "#333333"
|
||||||
|
dark: "#e0e0e0"
|
||||||
|
```
|
||||||
|
|
||||||
|
Light/dark color modes were added in Quarto version 1.8 and currently are not supported in the R or Python brand.yml packages.
|
||||||
|
|
||||||
|
### Logo Variants
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logo:
|
||||||
|
images:
|
||||||
|
logo-dark: logos/logo-dark.svg
|
||||||
|
logo-white: logos/logo-white.svg
|
||||||
|
icon: logos/icon.png
|
||||||
|
small: icon
|
||||||
|
medium:
|
||||||
|
light: logo-dark
|
||||||
|
dark: logo-white
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple Font Weights
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [300, 400, 500, 600, 700]
|
||||||
|
style: [normal, italic]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
weight: 400
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
### Color Aliases
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
navy: "#003366"
|
||||||
|
ocean-blue: "#0066cc"
|
||||||
|
sky-blue: "#3399ff"
|
||||||
|
primary-color: ocean-blue # Alias
|
||||||
|
brand-blue: ocean-blue # Alias
|
||||||
|
blue: sky-blue # Alias for primary colors
|
||||||
|
primary: brand-blue
|
||||||
|
```
|
||||||
|
|
||||||
|
Include Bootstrap color names when possible, either defined directly or as aliases: `blue`, `indigo`, `purple`, `pink`, `red`, `orange`, `yellow`, `green`, `teal`, `cyan`, `white`, `black`. This is useful for consistency and these colors are picked up automatically by tools that use brand.yml.
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- **Read specification first**: Always consult `brand-yml-spec.md` when creating or modifying files
|
||||||
|
- **Framework-specific guides**: Load the appropriate reference (shiny-r.md, shiny-python.md, quarto.md) for integration details
|
||||||
|
- **Validate incrementally**: Start with minimal structure, test, then add complexity
|
||||||
|
- **Use references**: Define colors in palette, then reference by name in semantic colors
|
||||||
|
- **Standard file name**: Use `_brand.yml` for automatic discovery
|
||||||
|
- **Explicit paths**: Use custom file names only when necessary (shared branding, multiple variants)
|
||||||
447
skills/brand-yml/references/brand-yml-in-r.md
Normal file
447
skills/brand-yml/references/brand-yml-in-r.md
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
# Using brand.yml in R
|
||||||
|
|
||||||
|
Guide for using brand.yml in R projects beyond Shiny, including R Markdown documents, theming functions for plots and tables, and programmatic access to brand data.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The brand.yml R package provides tools for applying brand styling to R visualizations and documents. These tools work in any R context, including R Markdown documents, Quarto, standalone scripts, and Shiny applications.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```r
|
||||||
|
# Install brand.yml package
|
||||||
|
install.packages("brand.yml")
|
||||||
|
```
|
||||||
|
|
||||||
|
## R Markdown Integration
|
||||||
|
|
||||||
|
Use brand.yml in R Markdown documents (without `runtime: shiny`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Report"
|
||||||
|
output:
|
||||||
|
html_document:
|
||||||
|
theme:
|
||||||
|
version: 5 # Required for brand.yml
|
||||||
|
brand: true # Auto-discover _brand.yml
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Or specify a path:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Report"
|
||||||
|
output:
|
||||||
|
html_document:
|
||||||
|
theme:
|
||||||
|
version: 5
|
||||||
|
brand: "path/to/brand.yml"
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important**: Set `version: 5` to use Bootstrap 5, which has the best brand.yml support.
|
||||||
|
|
||||||
|
### Other R Markdown Formats
|
||||||
|
|
||||||
|
Brand.yml works with various R Markdown output formats:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "Branded Report"
|
||||||
|
output:
|
||||||
|
html_document:
|
||||||
|
theme:
|
||||||
|
version: 5
|
||||||
|
brand: _brand.yml
|
||||||
|
pdf_document: default
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
## Programmatic Access
|
||||||
|
|
||||||
|
Read and access brand data programmatically in any R script or document:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Read from default location (_brand.yml in project)
|
||||||
|
brand <- read_brand_yml()
|
||||||
|
|
||||||
|
# Read from specific path
|
||||||
|
brand <- read_brand_yml("path/to/brand.yml")
|
||||||
|
|
||||||
|
# Access brand elements
|
||||||
|
brand$color$palette$blue # "#447099"
|
||||||
|
brand$color$primary # blue -> "#447099"
|
||||||
|
brand$typography$base$family # "Open Sans"
|
||||||
|
brand$meta$name # "Company Name"
|
||||||
|
|
||||||
|
# Access all colors
|
||||||
|
brand$color$palette # List of all palette colors
|
||||||
|
brand$color$foreground # Foreground color
|
||||||
|
brand$color$background # Background color
|
||||||
|
```
|
||||||
|
|
||||||
|
Use programmatically accessed brand data to:
|
||||||
|
- Display brand colors in custom visualizations
|
||||||
|
- Show brand logo with correct paths
|
||||||
|
- Apply brand fonts to custom elements
|
||||||
|
- Build branded themes dynamically
|
||||||
|
- Generate branded reports programmatically
|
||||||
|
|
||||||
|
## Branded Theming Functions
|
||||||
|
|
||||||
|
The brand.yml package includes helper functions to apply brand colors to plots and tables from popular R packages. These functions work in any R context (scripts, R Markdown, Quarto, Shiny).
|
||||||
|
|
||||||
|
### theme_brand_ggplot2()
|
||||||
|
|
||||||
|
Apply brand colors to ggplot2 visualizations:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(ggplot2)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Automatic brand detection
|
||||||
|
ggplot(mtcars, aes(mpg, hp)) +
|
||||||
|
geom_point() +
|
||||||
|
theme_brand_ggplot2()
|
||||||
|
|
||||||
|
# Explicit brand file
|
||||||
|
ggplot(mtcars, aes(mpg, hp)) +
|
||||||
|
geom_point() +
|
||||||
|
theme_brand_ggplot2(brand = "_brand.yml")
|
||||||
|
|
||||||
|
# Override specific colors
|
||||||
|
ggplot(mtcars, aes(mpg, hp)) +
|
||||||
|
geom_point() +
|
||||||
|
theme_brand_ggplot2(
|
||||||
|
background = "white",
|
||||||
|
foreground = "brand-gray",
|
||||||
|
accent = "brand-blue"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||||
|
- `background`, `foreground`, `accent`: Primary color settings
|
||||||
|
- `base_size`: Base font size (default: 11)
|
||||||
|
- Additional parameters for fine-grained control: `title_color`, `line_color`, `rect_fill`, `panel_background_fill`, `panel_grid_major_color`, etc.
|
||||||
|
|
||||||
|
### theme_brand_gt()
|
||||||
|
|
||||||
|
Apply brand colors to gt tables:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(gt)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Create branded table
|
||||||
|
mtcars |>
|
||||||
|
head() |>
|
||||||
|
gt() |>
|
||||||
|
theme_brand_gt()
|
||||||
|
|
||||||
|
# With explicit brand
|
||||||
|
mtcars |>
|
||||||
|
head() |>
|
||||||
|
gt() |>
|
||||||
|
theme_brand_gt(brand = "_brand.yml")
|
||||||
|
|
||||||
|
# Override colors
|
||||||
|
mtcars |>
|
||||||
|
head() |>
|
||||||
|
gt() |>
|
||||||
|
theme_brand_gt(
|
||||||
|
background = "white",
|
||||||
|
foreground = "brand-gray"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `table`: The gt table object to theme
|
||||||
|
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||||
|
- `background`: Table background color (default: `brand.color.background`)
|
||||||
|
- `foreground`: Text color (default: `brand.color.foreground`)
|
||||||
|
|
||||||
|
### theme_brand_flextable()
|
||||||
|
|
||||||
|
Apply brand colors to flextable tables:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(flextable)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Create branded flextable
|
||||||
|
mtcars |>
|
||||||
|
head() |>
|
||||||
|
flextable() |>
|
||||||
|
theme_brand_flextable()
|
||||||
|
|
||||||
|
# With explicit brand
|
||||||
|
mtcars |>
|
||||||
|
head() |>
|
||||||
|
flextable() |>
|
||||||
|
theme_brand_flextable(brand = "_brand.yml")
|
||||||
|
|
||||||
|
# Override colors
|
||||||
|
mtcars |>
|
||||||
|
head() |>
|
||||||
|
flextable() |>
|
||||||
|
theme_brand_flextable(
|
||||||
|
background = "white",
|
||||||
|
foreground = "brand-gray"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `table`: The flextable object to theme
|
||||||
|
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||||
|
- `background`: Table background color (default: `brand.color.background`)
|
||||||
|
- `foreground`: Text color (default: `brand.color.foreground`)
|
||||||
|
|
||||||
|
### theme_brand_plotly()
|
||||||
|
|
||||||
|
Apply brand colors to plotly visualizations:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(plotly)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Create branded plotly chart
|
||||||
|
plot_ly(mtcars, x = ~mpg, y = ~hp, type = "scatter", mode = "markers") |>
|
||||||
|
theme_brand_plotly()
|
||||||
|
|
||||||
|
# With explicit brand
|
||||||
|
plot_ly(mtcars, x = ~mpg, y = ~hp, type = "scatter", mode = "markers") |>
|
||||||
|
theme_brand_plotly(brand = "_brand.yml")
|
||||||
|
|
||||||
|
# Override colors
|
||||||
|
plot_ly(mtcars, x = ~mpg, y = ~hp, type = "scatter", mode = "markers") |>
|
||||||
|
theme_brand_plotly(
|
||||||
|
background = "white",
|
||||||
|
foreground = "brand-gray",
|
||||||
|
accent = "brand-blue"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `plot`: The plotly plot object to theme
|
||||||
|
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||||
|
- `background`: Plot background color (default: `brand.color.background`)
|
||||||
|
- `foreground`: Text/foreground color (default: `brand.color.foreground`)
|
||||||
|
- `accent`: Accent/highlight color (default: `brand.color.primary`)
|
||||||
|
|
||||||
|
### theme_brand_thematic()
|
||||||
|
|
||||||
|
Apply brand colors to base R graphics via thematic:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(thematic)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Create theme object
|
||||||
|
theme <- theme_brand_thematic()
|
||||||
|
|
||||||
|
# Use with thematic_with_theme()
|
||||||
|
thematic::thematic_with_theme(theme, {
|
||||||
|
plot(mtcars$mpg, mtcars$hp)
|
||||||
|
})
|
||||||
|
|
||||||
|
# Or use with ggplot2
|
||||||
|
thematic::thematic_with_theme(theme, {
|
||||||
|
ggplot(mtcars, aes(mpg, hp)) +
|
||||||
|
geom_point()
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### theme_brand_thematic_on()
|
||||||
|
|
||||||
|
Immediately activate brand theming globally for base R graphics:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(thematic)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Turn on brand theming globally
|
||||||
|
theme_brand_thematic_on()
|
||||||
|
|
||||||
|
# Now all plots use brand colors
|
||||||
|
plot(mtcars$mpg, mtcars$hp)
|
||||||
|
hist(mtcars$mpg)
|
||||||
|
|
||||||
|
# Turn off later
|
||||||
|
thematic::thematic_off()
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters (both functions):**
|
||||||
|
- `brand`: NULL (auto-detect), file path, brand object, or FALSE
|
||||||
|
- `background`: Background color (default: `brand.color.background`)
|
||||||
|
- `foreground`: Foreground color (default: `brand.color.foreground`)
|
||||||
|
- `accent`: Accent color (default: `brand.color.primary`)
|
||||||
|
- `...`: Additional arguments passed to thematic package
|
||||||
|
|
||||||
|
**Difference:**
|
||||||
|
- `theme_brand_thematic()`: Returns theme object for scoped use
|
||||||
|
- `theme_brand_thematic_on()`: Immediately applies theme globally
|
||||||
|
|
||||||
|
## R Markdown Example
|
||||||
|
|
||||||
|
Complete example showing theming functions in R Markdown:
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
---
|
||||||
|
title: "Branded Report"
|
||||||
|
output:
|
||||||
|
html_document:
|
||||||
|
theme:
|
||||||
|
version: 5
|
||||||
|
brand: _brand.yml
|
||||||
|
---
|
||||||
|
|
||||||
|
```{r setup}
|
||||||
|
library(ggplot2)
|
||||||
|
library(gt)
|
||||||
|
library(brand.yml)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sales Analysis
|
||||||
|
|
||||||
|
```{r plot}
|
||||||
|
ggplot(mtcars, aes(mpg, hp, color = factor(cyl))) +
|
||||||
|
geom_point(size = 3) +
|
||||||
|
labs(title = "MPG vs Horsepower", color = "Cylinders") +
|
||||||
|
theme_brand_ggplot2()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Summary
|
||||||
|
|
||||||
|
```{r table}
|
||||||
|
mtcars |>
|
||||||
|
head(10) |>
|
||||||
|
gt() |>
|
||||||
|
theme_brand_gt() |>
|
||||||
|
tab_header(title = "Motor Trend Car Data")
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
## Quarto Integration
|
||||||
|
|
||||||
|
Works seamlessly in Quarto documents:
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
---
|
||||||
|
title: "Branded Analysis"
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
brand: _brand.yml
|
||||||
|
---
|
||||||
|
|
||||||
|
```{r}
|
||||||
|
#| label: branded-plot
|
||||||
|
library(ggplot2)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
|
||||||
|
geom_point() +
|
||||||
|
theme_brand_ggplot2()
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
## Script Usage
|
||||||
|
|
||||||
|
Use in standalone R scripts:
|
||||||
|
|
||||||
|
```r
|
||||||
|
#!/usr/bin/env Rscript
|
||||||
|
|
||||||
|
library(brand.yml)
|
||||||
|
library(ggplot2)
|
||||||
|
|
||||||
|
# Read brand
|
||||||
|
brand <- read_brand_yml("_brand.yml")
|
||||||
|
|
||||||
|
# Create branded plot
|
||||||
|
p <- ggplot(mtcars, aes(mpg, hp)) +
|
||||||
|
geom_point(color = brand$color$primary) +
|
||||||
|
theme_brand_ggplot2()
|
||||||
|
|
||||||
|
# Save with brand colors
|
||||||
|
ggsave("output.png", p, width = 8, height = 6)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
- **Consistency**: Same brand styling across all R outputs (plots, tables, documents)
|
||||||
|
- **Automatic detection**: Functions find `_brand.yml` automatically
|
||||||
|
- **Flexible override**: Easy to customize colors when needed
|
||||||
|
- **Works everywhere**: R scripts, R Markdown, Quarto, Shiny
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- **Place `_brand.yml` at project root** for automatic discovery
|
||||||
|
- **Use `read_brand_yml()`** for programmatic access to brand data
|
||||||
|
- **Combine theming functions** for cohesive branded reports
|
||||||
|
- **Set `version: 5`** in R Markdown YAML for Bootstrap 5 support
|
||||||
|
- **Test theme functions** individually before combining in documents
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Branded Report with Multiple Visualizations
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(brand.yml)
|
||||||
|
library(ggplot2)
|
||||||
|
library(gt)
|
||||||
|
|
||||||
|
# Load brand
|
||||||
|
brand <- read_brand_yml()
|
||||||
|
|
||||||
|
# Create consistent visualizations
|
||||||
|
plot1 <- ggplot(data1, aes(x, y)) +
|
||||||
|
geom_point() +
|
||||||
|
theme_brand_ggplot2()
|
||||||
|
|
||||||
|
plot2 <- ggplot(data2, aes(x, y)) +
|
||||||
|
geom_line() +
|
||||||
|
theme_brand_ggplot2()
|
||||||
|
|
||||||
|
table1 <- data3 |>
|
||||||
|
gt() |>
|
||||||
|
theme_brand_gt()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dynamic Brand Colors
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
brand <- read_brand_yml()
|
||||||
|
|
||||||
|
# Use brand colors in custom visualizations
|
||||||
|
my_colors <- c(
|
||||||
|
brand$color$primary,
|
||||||
|
brand$color$secondary,
|
||||||
|
brand$color$success
|
||||||
|
)
|
||||||
|
|
||||||
|
# Apply to plot
|
||||||
|
plot(data, col = my_colors[factor(group)])
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Branding
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
# Use different brands for different contexts
|
||||||
|
if (Sys.getenv("BRAND_MODE") == "internal") {
|
||||||
|
brand <- read_brand_yml("internal-brand.yml")
|
||||||
|
} else {
|
||||||
|
brand <- read_brand_yml("external-brand.yml")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Apply to visualizations
|
||||||
|
theme <- theme_brand_ggplot2(brand = brand)
|
||||||
|
```
|
||||||
408
skills/brand-yml/references/brand-yml-spec.md
Normal file
408
skills/brand-yml/references/brand-yml-spec.md
Normal file
@@ -0,0 +1,408 @@
|
|||||||
|
# brand.yml Specification
|
||||||
|
|
||||||
|
Complete specification for creating valid `_brand.yml` files for the brand.yml project.
|
||||||
|
|
||||||
|
## File Naming Convention
|
||||||
|
|
||||||
|
- **Conventional name**: `_brand.yml` (auto-discovered by Shiny and Quarto)
|
||||||
|
- **Custom names**: Any `.yml` file (e.g., `my-brand.yml`) requires explicit paths
|
||||||
|
- **Location**: Typically at project root or in `_brand/` or `brand/` subdirectories
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
All fields are **optional**. Only include fields directly relevant to the brand.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
meta: # Company/project identity information
|
||||||
|
logo: # Logo files and variants
|
||||||
|
color: # Color palette and semantic colors
|
||||||
|
typography: # Fonts and text styling
|
||||||
|
defaults: # Framework-specific customizations
|
||||||
|
```
|
||||||
|
|
||||||
|
## Meta Section
|
||||||
|
|
||||||
|
Company or project metadata.
|
||||||
|
|
||||||
|
### Simple Format
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
meta:
|
||||||
|
name: Acme
|
||||||
|
link: https://acmecorp.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Extended Format
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
meta:
|
||||||
|
name:
|
||||||
|
short: Acme
|
||||||
|
full: Acme Corporation International
|
||||||
|
link:
|
||||||
|
home: https://www.acmecorp.com
|
||||||
|
docs: https://docs.acmecorp.com
|
||||||
|
github: https://github.com/acmecorp
|
||||||
|
bluesky: https://bsky.app/profile/acmecorp.bsky.social
|
||||||
|
mastodon: https://mastodon.social/@acmecorp
|
||||||
|
linkedin: https://www.linkedin.com/company/acmecorp
|
||||||
|
facebook: https://www.facebook.com/acmecorp
|
||||||
|
twitter: https://twitter.com/acmecorp
|
||||||
|
```
|
||||||
|
|
||||||
|
**Requirements:**
|
||||||
|
- All links must include `https://` prefix
|
||||||
|
- Additional custom fields are allowed
|
||||||
|
|
||||||
|
## Logo Section
|
||||||
|
|
||||||
|
Logo files for different contexts and sizes.
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logo:
|
||||||
|
images: # Named logo resources (optional)
|
||||||
|
name: path # Map names to file paths or URLs
|
||||||
|
small: path # Icon-sized logo (favicons, mobile)
|
||||||
|
medium: path # Standard logo (headers, navigation)
|
||||||
|
large: path # Large logo (hero, title slides)
|
||||||
|
```
|
||||||
|
|
||||||
|
### File Paths
|
||||||
|
|
||||||
|
- **Local files**: Relative paths from `_brand.yml` location (e.g., `logos/logo.png`)
|
||||||
|
- **Remote files**: Full URLs with `http://` or `https://`
|
||||||
|
|
||||||
|
### Light/Dark Variants
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logo:
|
||||||
|
medium:
|
||||||
|
light: logo-dark.png # For light backgrounds
|
||||||
|
dark: logo-white.png # For dark backgrounds
|
||||||
|
```
|
||||||
|
|
||||||
|
### With Alt Text
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logo:
|
||||||
|
images:
|
||||||
|
header:
|
||||||
|
path: logos/header.svg
|
||||||
|
alt: Company logo
|
||||||
|
medium: header
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complete Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logo:
|
||||||
|
images:
|
||||||
|
header: logos/header-logo.png
|
||||||
|
header-white: logos/header-logo-white.png
|
||||||
|
icon: logos/icon.png
|
||||||
|
full:
|
||||||
|
path: logos/full-logo.svg
|
||||||
|
alt: Acme Corporation logo
|
||||||
|
small: icon
|
||||||
|
medium:
|
||||||
|
light: header
|
||||||
|
dark: header-white
|
||||||
|
large: full
|
||||||
|
```
|
||||||
|
|
||||||
|
## Color Section
|
||||||
|
|
||||||
|
Brand color palette and semantic color assignments.
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette: # Named brand colors
|
||||||
|
name: "#hex" # Flat list of color names and hex values
|
||||||
|
# Semantic theme colors (all optional)
|
||||||
|
foreground: "#color" # Main text color
|
||||||
|
background: "#color" # Main background color
|
||||||
|
primary: "#color" # Links, buttons, primary actions
|
||||||
|
secondary: "#color" # Lighter text, disabled states
|
||||||
|
tertiary: "#color" # Hover states, accents
|
||||||
|
success: "#color" # Positive actions
|
||||||
|
info: "#color" # Neutral information
|
||||||
|
warning: "#color" # Cautions
|
||||||
|
danger: "#color" # Errors, negative actions
|
||||||
|
light: "#color" # High contrast on dark
|
||||||
|
dark: "#color" # High contrast on light
|
||||||
|
```
|
||||||
|
|
||||||
|
### Color Palette Best Practices
|
||||||
|
|
||||||
|
- Use hex color values: `"#447099"`
|
||||||
|
- Use descriptive names following Sass conventions: `blue`, `brand-orange`, `success-green`
|
||||||
|
- Create aliases by referencing other palette colors: `purple: burgundy`
|
||||||
|
- Include Bootstrap color names when possible: `blue`, `indigo`, `purple`, `pink`, `red`, `orange`, `yellow`, `green`, `teal`, `cyan`, `white`, `black`
|
||||||
|
- When brands define ranges of shades, choose the midpoint as the primary color
|
||||||
|
|
||||||
|
### Referencing Colors
|
||||||
|
|
||||||
|
Theme colors can reference palette names:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
brand-blue: "#447099"
|
||||||
|
brand-orange: "#EE6331"
|
||||||
|
primary: brand-blue # References palette
|
||||||
|
warning: brand-orange # References palette
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complete Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
white: "#FFFFFF"
|
||||||
|
black: "#151515"
|
||||||
|
blue: "#447099"
|
||||||
|
orange: "#EE6331"
|
||||||
|
green: "#72994E"
|
||||||
|
teal: "#419599"
|
||||||
|
burgundy: "#9A4665"
|
||||||
|
foreground: black
|
||||||
|
background: white
|
||||||
|
primary: blue
|
||||||
|
success: green
|
||||||
|
info: teal
|
||||||
|
warning: orange
|
||||||
|
danger: burgundy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Typography Section
|
||||||
|
|
||||||
|
Font definitions and text element styling.
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
typography:
|
||||||
|
fonts: # Font definitions
|
||||||
|
- family: Name
|
||||||
|
source: type # file, google, bunny, or system
|
||||||
|
# Additional source-specific fields
|
||||||
|
base: # Body text (optional)
|
||||||
|
headings: # Heading text (optional)
|
||||||
|
monospace: # Code text (optional)
|
||||||
|
monospace-inline: # Inline code (optional)
|
||||||
|
monospace-block: # Code blocks (optional)
|
||||||
|
link: # Hyperlinks (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Font Sources
|
||||||
|
|
||||||
|
#### Local/Remote Files
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
fonts:
|
||||||
|
- family: Open Sans
|
||||||
|
source: file
|
||||||
|
files:
|
||||||
|
- path: fonts/OpenSans-Regular.ttf
|
||||||
|
weight: 400
|
||||||
|
style: normal
|
||||||
|
- path: fonts/OpenSans-Bold.ttf
|
||||||
|
weight: 700
|
||||||
|
style: normal
|
||||||
|
- path: https://example.com/fonts/OpenSans-Italic.ttf
|
||||||
|
weight: 400
|
||||||
|
style: italic
|
||||||
|
```
|
||||||
|
|
||||||
|
Proprietary fonts, should be downloaded and stored adjacent to the brand.yml file and referenced via relative paths in the `path` field.
|
||||||
|
|
||||||
|
#### Google Fonts
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
fonts:
|
||||||
|
- family: Roboto
|
||||||
|
source: google
|
||||||
|
weight: [400, 700] # Optional: specific weights
|
||||||
|
style: [normal, italic] # Optional: specific styles
|
||||||
|
display: block # Optional: font-display property
|
||||||
|
```
|
||||||
|
|
||||||
|
Weight options:
|
||||||
|
- Array of numbers: `[400, 700]`
|
||||||
|
- Range (variable fonts): `400..900`
|
||||||
|
- Named weights: `[thin, normal, bold]`
|
||||||
|
|
||||||
|
#### Bunny Fonts (GDPR-compliant alternative)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: bunny
|
||||||
|
weight: [400, 600]
|
||||||
|
style: [normal, italic]
|
||||||
|
```
|
||||||
|
|
||||||
|
Same syntax as Google Fonts.
|
||||||
|
|
||||||
|
### Typographic Elements
|
||||||
|
|
||||||
|
All elements support these fields:
|
||||||
|
- `family`: Font family name (must match a defined font)
|
||||||
|
- `weight`: `100`-`900` or `thin`, `normal`, `bold`, etc.
|
||||||
|
- `style`: `normal` or `italic`
|
||||||
|
- `size`: CSS units (`16px`, `1rem`, `0.9em`)
|
||||||
|
- `line-height`: Number or CSS unit
|
||||||
|
- `color`: Hex value or reference to color name
|
||||||
|
- `background-color`: Hex value or reference to color name
|
||||||
|
|
||||||
|
#### Simple Format (String)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
typography:
|
||||||
|
base: Open Sans
|
||||||
|
headings: Roboto
|
||||||
|
monospace: Fira Code
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Extended Format (Object)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
typography:
|
||||||
|
base:
|
||||||
|
family: Open Sans
|
||||||
|
weight: 400
|
||||||
|
size: 16px
|
||||||
|
line-height: 1.5
|
||||||
|
headings:
|
||||||
|
family: Roboto
|
||||||
|
weight: 600
|
||||||
|
style: normal
|
||||||
|
line-height: 1.2
|
||||||
|
color: "#333333"
|
||||||
|
monospace:
|
||||||
|
family: Fira Code
|
||||||
|
weight: 400
|
||||||
|
size: 0.9em
|
||||||
|
monospace-inline:
|
||||||
|
color: "#7d12ba"
|
||||||
|
background-color: "#f8f9fa"
|
||||||
|
monospace-block:
|
||||||
|
color: foreground
|
||||||
|
background-color: background
|
||||||
|
line-height: 1.4
|
||||||
|
link:
|
||||||
|
weight: 600
|
||||||
|
color: primary
|
||||||
|
decoration: underline
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: Base text color uses `color.foreground` by default. Do not specify color in base unless overriding.
|
||||||
|
|
||||||
|
### Complete Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Open Sans
|
||||||
|
source: google
|
||||||
|
weight: [400, 600, 700]
|
||||||
|
style: [normal, italic]
|
||||||
|
- family: Roboto Slab
|
||||||
|
source: google
|
||||||
|
weight: [600, 900]
|
||||||
|
- family: Fira Code
|
||||||
|
source: bunny
|
||||||
|
weight: [400, 500]
|
||||||
|
base:
|
||||||
|
family: Open Sans
|
||||||
|
size: 16px
|
||||||
|
line-height: 1.5
|
||||||
|
headings:
|
||||||
|
family: Roboto Slab
|
||||||
|
weight: 600
|
||||||
|
monospace: Fira Code
|
||||||
|
link:
|
||||||
|
color: primary
|
||||||
|
weight: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
## Defaults Section
|
||||||
|
|
||||||
|
Framework-specific customizations. Use sparingly - only when brand requirements cannot be met through the standard sections above.
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
defaults:
|
||||||
|
bootstrap: # Bootstrap/bslib customizations
|
||||||
|
functions: # SCSS function declarations (string)
|
||||||
|
defaults: # Bootstrap variable overrides (mapping)
|
||||||
|
mixins: # SCSS mixins (string)
|
||||||
|
rules: # Additional SCSS rules (string)
|
||||||
|
quarto: # Quarto-specific settings
|
||||||
|
format: # Format-specific options
|
||||||
|
shiny: # Shiny-specific settings
|
||||||
|
theme:
|
||||||
|
defaults: # Bootstrap variables
|
||||||
|
rules: # Additional SCSS rules
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
defaults:
|
||||||
|
bootstrap:
|
||||||
|
defaults:
|
||||||
|
navbar-bg: $brand-orange
|
||||||
|
rules: |
|
||||||
|
.btn-primary {
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
shiny:
|
||||||
|
theme:
|
||||||
|
defaults:
|
||||||
|
navbar-padding-y: 1rem
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: Colors from `color.palette` are available as Sass variables: `$brand-{color_name}`
|
||||||
|
|
||||||
|
## Validation Rules
|
||||||
|
|
||||||
|
When creating `_brand.yml` files:
|
||||||
|
|
||||||
|
1. **All fields are optional** - only include what's needed
|
||||||
|
2. **Prefer hex colors** - use `"#447099"` format
|
||||||
|
3. **Prefer simple syntax** - use strings instead of objects when possible
|
||||||
|
4. **Follow Sass naming** - color/font names use lowercase and hyphens
|
||||||
|
5. **Include URLs with protocol** - always use `https://`
|
||||||
|
6. **Reference before use** - define colors/fonts before referencing them
|
||||||
|
7. **Keep it concise** - simpler is better
|
||||||
|
|
||||||
|
## Complete Minimal Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
blue: "#0066cc"
|
||||||
|
gray: "#666666"
|
||||||
|
primary: blue
|
||||||
|
foreground: gray
|
||||||
|
background: "#ffffff"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 600]
|
||||||
|
base: Inter
|
||||||
|
headings:
|
||||||
|
weight: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete Comprehensive Example
|
||||||
|
|
||||||
|
See the example in the document provided to you (brand-yml.prompt.txt) for a full-featured _brand.yml with all options demonstrated.
|
||||||
504
skills/brand-yml/references/quarto.md
Normal file
504
skills/brand-yml/references/quarto.md
Normal file
@@ -0,0 +1,504 @@
|
|||||||
|
# Using brand.yml with Quarto
|
||||||
|
|
||||||
|
Guide for applying brand.yml styling to Quarto documents, presentations, websites, and PDFs.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Quarto automatically integrates `_brand.yml` to provide unified visual styling across multiple output formats including HTML, dashboards, RevealJS presentations, and Typst PDFs.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
Place `_brand.yml` at your project root:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-project/
|
||||||
|
├── _quarto.yml
|
||||||
|
├── _brand.yml
|
||||||
|
├── index.qmd
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Quarto automatically discovers and applies `_brand.yml` - no configuration needed.
|
||||||
|
|
||||||
|
## Supported Formats
|
||||||
|
|
||||||
|
Brand styling automatically applies to:
|
||||||
|
|
||||||
|
- **HTML documents** - Web pages, reports
|
||||||
|
- **HTML dashboards** - Interactive dashboards
|
||||||
|
- **RevealJS presentations** - Slide decks
|
||||||
|
- **Typst PDFs** - PDF documents via Typst
|
||||||
|
- **Websites** - Multi-page Quarto websites
|
||||||
|
|
||||||
|
## Document-Level Usage
|
||||||
|
|
||||||
|
Specify brand in document frontmatter:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Document"
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
brand: _brand.yml
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use default discovery:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Document"
|
||||||
|
format: html
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
If `_brand.yml` exists at project root, it's automatically applied.
|
||||||
|
|
||||||
|
## Project-Level Usage
|
||||||
|
|
||||||
|
Configure in `_quarto.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
project:
|
||||||
|
type: website
|
||||||
|
brand: _brand.yml
|
||||||
|
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
theme: default
|
||||||
|
```
|
||||||
|
|
||||||
|
## Custom Brand File Location
|
||||||
|
|
||||||
|
Specify a non-standard path:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Document"
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
brand: branding/company-brand.yml
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Or in project config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
project:
|
||||||
|
brand: path/to/brand.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Light/Dark Mode
|
||||||
|
|
||||||
|
Specify color variants for light and dark modes:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
blue: "#0066cc"
|
||||||
|
primary:
|
||||||
|
light: "#0066cc"
|
||||||
|
dark: "#3399ff"
|
||||||
|
background:
|
||||||
|
light: "#ffffff"
|
||||||
|
dark: "#1a1a1a"
|
||||||
|
foreground:
|
||||||
|
light: "#333333"
|
||||||
|
dark: "#e0e0e0"
|
||||||
|
```
|
||||||
|
|
||||||
|
Any color in `color` or `typography` can have light/dark variants.
|
||||||
|
|
||||||
|
## Theme Layering
|
||||||
|
|
||||||
|
Control precedence with the `"brand"` keyword:
|
||||||
|
|
||||||
|
### Default (Brand Lowest Priority)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format:
|
||||||
|
revealjs:
|
||||||
|
theme:
|
||||||
|
- custom.scss
|
||||||
|
- cosmo
|
||||||
|
```
|
||||||
|
|
||||||
|
Priority: `cosmo` > `custom.scss` > `_brand.yml`
|
||||||
|
|
||||||
|
### Brand Highest Priority
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format:
|
||||||
|
revealjs:
|
||||||
|
theme:
|
||||||
|
- cosmo
|
||||||
|
- custom.scss
|
||||||
|
- brand
|
||||||
|
```
|
||||||
|
|
||||||
|
Priority: `_brand.yml` > `custom.scss` > `cosmo`
|
||||||
|
|
||||||
|
### Brand in Middle
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
theme:
|
||||||
|
- cosmo
|
||||||
|
- brand
|
||||||
|
- custom.scss
|
||||||
|
```
|
||||||
|
|
||||||
|
Priority: `custom.scss` > `_brand.yml` > `cosmo`
|
||||||
|
|
||||||
|
## Accessing Brand Data in Documents
|
||||||
|
|
||||||
|
### Shortcodes
|
||||||
|
|
||||||
|
Use shortcodes to access brand values (requires Quarto extensions):
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- Access colors -->
|
||||||
|
Our primary color is {{{< brand-color primary >}}}.
|
||||||
|
|
||||||
|
<!-- Access meta information -->
|
||||||
|
Welcome to {{{< brand-meta name >}}}.
|
||||||
|
```
|
||||||
|
|
||||||
|
### SCSS Variables
|
||||||
|
|
||||||
|
Access brand colors in custom SCSS:
|
||||||
|
|
||||||
|
```scss
|
||||||
|
// Custom SCSS file
|
||||||
|
.branded-element {
|
||||||
|
color: $brand-primary;
|
||||||
|
background: $brand-background;
|
||||||
|
border-color: $brand-secondary;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Brand colors are automatically available as Sass variables: `$brand-{color-name}`.
|
||||||
|
|
||||||
|
## Typst PDF Support
|
||||||
|
|
||||||
|
Brand styling works with Typst PDF output:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "My Document"
|
||||||
|
format:
|
||||||
|
typst:
|
||||||
|
brand: _brand.yml
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typst Color Variables
|
||||||
|
|
||||||
|
Access colors in Typst templates:
|
||||||
|
|
||||||
|
- `brand-color.{name}` - Palette colors (e.g., `brand-color.blue`, `brand-color.primary`)
|
||||||
|
- `brand-background-color.{name}` - Lighter background variants
|
||||||
|
|
||||||
|
### Typst Typography Support
|
||||||
|
|
||||||
|
| Element | family | weight | color | background-color | line-height |
|
||||||
|
|---------|--------|--------|-------|------------------|-------------|
|
||||||
|
| base | ✓ | ✓ | ✓ | - | ✓ |
|
||||||
|
| headings | ✓ | ✓ | ✓ | - | ✓ |
|
||||||
|
| title | ✓ | ✓ | ✓ | - | ✓ |
|
||||||
|
| monospace-inline | ✓ | ✓ | ✓ | ✓ | - |
|
||||||
|
| monospace-block | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
| link | - | ✓ | ✓ | ✓ | - |
|
||||||
|
|
||||||
|
### Typst Font Handling
|
||||||
|
|
||||||
|
Quarto automatically downloads Google Fonts and caches them for Typst. Check fonts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
quarto typst fonts --ignore-system-fonts --font-path .quarto/typst-font-cache/
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable font fallback in Typst:
|
||||||
|
|
||||||
|
```typst
|
||||||
|
#set text(fallback: false)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete Examples
|
||||||
|
|
||||||
|
### Simple HTML Document
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "Quarterly Report"
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Executive Summary
|
||||||
|
|
||||||
|
Content here uses brand colors and typography automatically.
|
||||||
|
```
|
||||||
|
|
||||||
|
With `_brand.yml` at project root:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
blue: "#0066cc"
|
||||||
|
primary: blue
|
||||||
|
background: "#ffffff"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 600]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
size: 16px
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
### RevealJS Presentation
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "Company Overview"
|
||||||
|
format:
|
||||||
|
revealjs:
|
||||||
|
theme:
|
||||||
|
- default
|
||||||
|
- brand
|
||||||
|
logo: logo.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
Slides automatically use brand colors and fonts.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Website with Brand
|
||||||
|
|
||||||
|
`_quarto.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
project:
|
||||||
|
type: website
|
||||||
|
brand: _brand.yml
|
||||||
|
|
||||||
|
website:
|
||||||
|
title: "My Company"
|
||||||
|
navbar:
|
||||||
|
left:
|
||||||
|
- href: index.qmd
|
||||||
|
text: Home
|
||||||
|
- about.qmd
|
||||||
|
|
||||||
|
format:
|
||||||
|
html:
|
||||||
|
theme: cosmo
|
||||||
|
css: styles.css
|
||||||
|
```
|
||||||
|
|
||||||
|
Brand colors and typography apply across all pages.
|
||||||
|
|
||||||
|
### Dashboard
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "Sales Dashboard"
|
||||||
|
format:
|
||||||
|
dashboard:
|
||||||
|
brand: _brand.yml
|
||||||
|
theme: default
|
||||||
|
---
|
||||||
|
|
||||||
|
## Row
|
||||||
|
|
||||||
|
```{python}
|
||||||
|
# Dashboard content
|
||||||
|
```
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typst PDF
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "Technical Report"
|
||||||
|
format:
|
||||||
|
typst:
|
||||||
|
brand: _brand.yml
|
||||||
|
margin:
|
||||||
|
x: 2cm
|
||||||
|
y: 2cm
|
||||||
|
---
|
||||||
|
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
PDF uses brand colors and fonts via Typst.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Brand Extensions
|
||||||
|
|
||||||
|
Create reusable brand packages:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
quarto create extension brand
|
||||||
|
```
|
||||||
|
|
||||||
|
Structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-brand-extension/
|
||||||
|
├── _extension.yml
|
||||||
|
├── brand.yml
|
||||||
|
├── logo.png
|
||||||
|
└── fonts/
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
`_extension.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
title: Company Brand
|
||||||
|
author: Your Name
|
||||||
|
version: 1.0.0
|
||||||
|
contributes:
|
||||||
|
brand: brand.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Install extension in projects:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
quarto add username/my-brand-extension
|
||||||
|
```
|
||||||
|
|
||||||
|
**Requirement**: Brand extensions need `_quarto.yml` project file.
|
||||||
|
|
||||||
|
## Sample _brand.yml for Quarto
|
||||||
|
|
||||||
|
Minimal example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
brand-blue: "#0066cc"
|
||||||
|
brand-gray: "#666666"
|
||||||
|
primary: brand-blue
|
||||||
|
foreground: brand-gray
|
||||||
|
background: "#ffffff"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 600]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
size: 1rem
|
||||||
|
line-height: 1.6
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
line-height: 1.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Complete example with light/dark mode:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
meta:
|
||||||
|
name: My Company
|
||||||
|
link: https://mycompany.com
|
||||||
|
|
||||||
|
logo:
|
||||||
|
small: logo-icon.png
|
||||||
|
medium:
|
||||||
|
light: logo-dark.svg
|
||||||
|
dark: logo-white.svg
|
||||||
|
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
blue: "#0066cc"
|
||||||
|
navy: "#003366"
|
||||||
|
gray: "#666666"
|
||||||
|
light-gray: "#f5f5f5"
|
||||||
|
primary: blue
|
||||||
|
secondary: gray
|
||||||
|
success: "#28a745"
|
||||||
|
info: blue
|
||||||
|
warning: "#ffc107"
|
||||||
|
danger: "#dc3545"
|
||||||
|
foreground:
|
||||||
|
light: navy
|
||||||
|
dark: "#e0e0e0"
|
||||||
|
background:
|
||||||
|
light: "#ffffff"
|
||||||
|
dark: "#1a1a1a"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 500, 600, 700]
|
||||||
|
style: [normal, italic]
|
||||||
|
- family: Fira Code
|
||||||
|
source: google
|
||||||
|
weight: [400, 500]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
size: 1rem
|
||||||
|
line-height: 1.6
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
line-height: 1.2
|
||||||
|
monospace:
|
||||||
|
family: Fira Code
|
||||||
|
size: 0.9em
|
||||||
|
link:
|
||||||
|
color: primary
|
||||||
|
weight: 500
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- **Automatic discovery**: Place `_brand.yml` at project root for automatic application
|
||||||
|
- **Light/dark variants**: Use for websites with theme toggles
|
||||||
|
- **Layer strategically**: Use `brand` keyword to control theme precedence
|
||||||
|
- **Test across formats**: Verify brand applies correctly to HTML, PDF, and presentations
|
||||||
|
- **Extension for reuse**: Create brand extensions for multi-project consistency
|
||||||
|
- **Version control**: Include `_brand.yml` in git repository
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Brand not applying?**
|
||||||
|
- Verify file is named `_brand.yml` (with underscore)
|
||||||
|
- Check file is at project root or specified in `brand:` field
|
||||||
|
- Ensure `_quarto.yml` exists for project-level branding
|
||||||
|
- Try explicit path in frontmatter
|
||||||
|
|
||||||
|
**Colors not matching?**
|
||||||
|
- Ensure hex colors have quotes: `"#0066cc"`
|
||||||
|
- Check color references match palette definitions
|
||||||
|
- Verify theme layering order
|
||||||
|
|
||||||
|
**Fonts not loading?**
|
||||||
|
- Verify Google Fonts spelling
|
||||||
|
- Check internet connection (required for Google Fonts)
|
||||||
|
- For Typst, check font cache: `quarto typst fonts`
|
||||||
|
- Ensure `source: google` is specified correctly
|
||||||
|
|
||||||
|
**Typst-specific issues?**
|
||||||
|
- Check font cache path: `.quarto/typst-font-cache/`
|
||||||
|
- Add `#set text(fallback: false)` to debug font issues
|
||||||
|
- Verify typography properties are supported (see table above)
|
||||||
|
|
||||||
|
**Brand extension not working?**
|
||||||
|
- Ensure `_quarto.yml` exists in project
|
||||||
|
- Verify extension is installed: `quarto list extensions`
|
||||||
|
- Check extension contributes brand: look for `contributes.brand` in `_extension.yml`
|
||||||
395
skills/brand-yml/references/shiny-python.md
Normal file
395
skills/brand-yml/references/shiny-python.md
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
# Using brand.yml with Shiny for Python
|
||||||
|
|
||||||
|
Guide for applying brand.yml styling to Shiny for Python applications using ui.Theme.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Shiny for Python integrates brand.yml through the `ui.Theme.from_brand()` method, which creates custom themes from `_brand.yml` files. This enables consistent branding across Shiny apps with minimal configuration.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Shiny with theme support
|
||||||
|
pip install "shiny[theme]"
|
||||||
|
|
||||||
|
# Or install separately
|
||||||
|
pip install shiny libsass
|
||||||
|
|
||||||
|
# Optional: Install brand_yml for programmatic access
|
||||||
|
pip install brand_yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Automatic Discovery
|
||||||
|
|
||||||
|
Place `_brand.yml` at your app directory root:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-app/
|
||||||
|
├── _brand.yml
|
||||||
|
├── app.py
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Then use `ui.Theme.from_brand()`:
|
||||||
|
|
||||||
|
**Shiny Express:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny.express import ui
|
||||||
|
|
||||||
|
ui.page_opts(theme=ui.Theme.from_brand(__file__))
|
||||||
|
|
||||||
|
# ... rest of app
|
||||||
|
```
|
||||||
|
|
||||||
|
**Shiny Core:**
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny import App, ui
|
||||||
|
|
||||||
|
app_ui = ui.page_fluid(
|
||||||
|
ui.Theme.from_brand(__file__),
|
||||||
|
ui.h2("My App"),
|
||||||
|
# ... rest of UI
|
||||||
|
)
|
||||||
|
|
||||||
|
def server(input, output, session):
|
||||||
|
pass
|
||||||
|
|
||||||
|
app = App(app_ui, server)
|
||||||
|
```
|
||||||
|
|
||||||
|
## ui.Theme.from_brand() Parameters
|
||||||
|
|
||||||
|
```python
|
||||||
|
ui.Theme.from_brand(brand)
|
||||||
|
```
|
||||||
|
|
||||||
|
The `brand` parameter accepts:
|
||||||
|
|
||||||
|
### File Path (Most Common)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Use __file__ for app directory
|
||||||
|
ui.Theme.from_brand(__file__)
|
||||||
|
|
||||||
|
# Explicit file path
|
||||||
|
ui.Theme.from_brand("path/to/_brand.yml")
|
||||||
|
|
||||||
|
# Explicit directory (auto-finds _brand.yml)
|
||||||
|
ui.Theme.from_brand("branding/")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Brand Object
|
||||||
|
|
||||||
|
```python
|
||||||
|
from brand_yml import Brand
|
||||||
|
|
||||||
|
brand = Brand.from_yaml("_brand.yml")
|
||||||
|
ui.Theme.from_brand(brand)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Search Behavior
|
||||||
|
|
||||||
|
When given `__file__` or a directory path, the method searches for `_brand.yml`:
|
||||||
|
|
||||||
|
1. In the specified directory
|
||||||
|
2. In `_brand/` subdirectory
|
||||||
|
3. In `brand/` subdirectory
|
||||||
|
4. In parent directories (recursive)
|
||||||
|
|
||||||
|
## Complete Examples
|
||||||
|
|
||||||
|
### Shiny Express App
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny.express import input, render, ui
|
||||||
|
|
||||||
|
ui.page_opts(
|
||||||
|
title="My Dashboard",
|
||||||
|
theme=ui.Theme.from_brand(__file__)
|
||||||
|
)
|
||||||
|
|
||||||
|
with ui.sidebar():
|
||||||
|
ui.input_slider("n", "Number of observations", 1, 100, 50)
|
||||||
|
|
||||||
|
@render.plot
|
||||||
|
def histogram():
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
data = np.random.randn(input.n())
|
||||||
|
plt.hist(data, bins=20)
|
||||||
|
plt.xlabel("Value")
|
||||||
|
plt.ylabel("Frequency")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shiny Core App
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny import App, render, ui
|
||||||
|
|
||||||
|
app_ui = ui.page_sidebar(
|
||||||
|
ui.sidebar(
|
||||||
|
ui.input_slider("n", "Number of observations", 1, 100, 50),
|
||||||
|
),
|
||||||
|
ui.output_plot("histogram"),
|
||||||
|
title="My Dashboard",
|
||||||
|
theme=ui.Theme.from_brand(__file__)
|
||||||
|
)
|
||||||
|
|
||||||
|
def server(input, output, session):
|
||||||
|
@render.plot
|
||||||
|
def histogram():
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
data = np.random.randn(input.n())
|
||||||
|
plt.hist(data, bins=20)
|
||||||
|
plt.xlabel("Value")
|
||||||
|
plt.ylabel("Frequency")
|
||||||
|
|
||||||
|
app = App(app_ui, server)
|
||||||
|
```
|
||||||
|
|
||||||
|
### With Custom Path
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny.express import ui
|
||||||
|
|
||||||
|
# Shared brand file
|
||||||
|
ui.page_opts(theme=ui.Theme.from_brand("../shared-branding/_brand.yml"))
|
||||||
|
|
||||||
|
# Named brand file
|
||||||
|
ui.page_opts(theme=ui.Theme.from_brand("company-brand.yml"))
|
||||||
|
|
||||||
|
# Directory with _brand.yml inside
|
||||||
|
ui.page_opts(theme=ui.Theme.from_brand("branding/"))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple Page Types
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny import App, ui
|
||||||
|
|
||||||
|
# page_fluid
|
||||||
|
app_ui = ui.page_fluid(
|
||||||
|
theme=ui.Theme.from_brand(__file__),
|
||||||
|
# ... content
|
||||||
|
)
|
||||||
|
|
||||||
|
# page_sidebar
|
||||||
|
app_ui = ui.page_sidebar(
|
||||||
|
theme=ui.Theme.from_brand(__file__),
|
||||||
|
ui.sidebar(
|
||||||
|
# ... sidebar content
|
||||||
|
),
|
||||||
|
# ... main content
|
||||||
|
)
|
||||||
|
|
||||||
|
# page_navbar
|
||||||
|
app_ui = ui.page_navbar(
|
||||||
|
ui.nav_panel("Tab 1", # ...),
|
||||||
|
ui.nav_panel("Tab 2", # ...),
|
||||||
|
title="My App",
|
||||||
|
theme=ui.Theme.from_brand(__file__)
|
||||||
|
)
|
||||||
|
|
||||||
|
# page_fillable
|
||||||
|
app_ui = ui.page_fillable(
|
||||||
|
theme=ui.Theme.from_brand(__file__),
|
||||||
|
# ... content
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Combining with Custom Theme Rules
|
||||||
|
|
||||||
|
Extend brand.yml themes with custom Sass:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from shiny.express import ui
|
||||||
|
|
||||||
|
theme = (
|
||||||
|
ui.Theme.from_brand(__file__)
|
||||||
|
.add_rules("""
|
||||||
|
.custom-card {
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
|
||||||
|
ui.page_opts(theme=theme)
|
||||||
|
```
|
||||||
|
|
||||||
|
Available theme methods (chainable):
|
||||||
|
- `.add_defaults()` - Override Bootstrap variables
|
||||||
|
- `.add_functions()` - Add Sass functions
|
||||||
|
- `.add_mixins()` - Add Sass mixins
|
||||||
|
- `.add_rules()` - Add CSS rules
|
||||||
|
- `.add_uses()` - Add Sass declarations
|
||||||
|
|
||||||
|
## Programmatic Access with brand_yml
|
||||||
|
|
||||||
|
For advanced use cases, access brand data programmatically:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from brand_yml import Brand
|
||||||
|
|
||||||
|
# Read brand file
|
||||||
|
brand = Brand.from_yaml("_brand.yml")
|
||||||
|
|
||||||
|
# Or from string
|
||||||
|
yaml_content = """
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
blue: "#0066cc"
|
||||||
|
primary: blue
|
||||||
|
"""
|
||||||
|
brand = Brand.from_yaml_str(yaml_content)
|
||||||
|
|
||||||
|
# Access brand elements
|
||||||
|
brand.meta.name # Organization name
|
||||||
|
brand.color.palette.blue # "#0066cc"
|
||||||
|
brand.color.primary # "blue"
|
||||||
|
brand.typography.base.family # Font family name
|
||||||
|
|
||||||
|
# Use in UI
|
||||||
|
from shiny import ui
|
||||||
|
|
||||||
|
app_ui = ui.page_fluid(
|
||||||
|
theme=ui.Theme.from_brand(brand),
|
||||||
|
ui.h2(brand.meta.name),
|
||||||
|
# ... more content
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sample _brand.yml for Shiny
|
||||||
|
|
||||||
|
Minimal example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
brand-blue: "#0066cc"
|
||||||
|
brand-gray: "#666666"
|
||||||
|
primary: brand-blue
|
||||||
|
foreground: brand-gray
|
||||||
|
background: "#ffffff"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 600]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
size: 16px
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
More complete example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
meta:
|
||||||
|
name: My Company
|
||||||
|
link: https://mycompany.com
|
||||||
|
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
blue: "#0066cc"
|
||||||
|
navy: "#003366"
|
||||||
|
gray: "#666666"
|
||||||
|
light-gray: "#f5f5f5"
|
||||||
|
primary: blue
|
||||||
|
secondary: gray
|
||||||
|
success: "#28a745"
|
||||||
|
info: blue
|
||||||
|
warning: "#ffc107"
|
||||||
|
danger: "#dc3545"
|
||||||
|
foreground: navy
|
||||||
|
background: "#ffffff"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 500, 600, 700]
|
||||||
|
style: [normal, italic]
|
||||||
|
- family: Fira Code
|
||||||
|
source: google
|
||||||
|
weight: [400, 500]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
size: 16px
|
||||||
|
line-height: 1.5
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
line-height: 1.2
|
||||||
|
monospace:
|
||||||
|
family: Fira Code
|
||||||
|
size: 14px
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- **Use __file__**: Most reliable way to locate `_brand.yml` in app directory
|
||||||
|
- **Start simple**: Begin with colors and one font
|
||||||
|
- **Test paths**: If brand doesn't apply, try explicit paths
|
||||||
|
- **Version control**: Include `_brand.yml` in git repository
|
||||||
|
- **Precompile for production**: Use `.to_css()` to avoid runtime Sass compilation
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Development
|
||||||
|
theme = ui.Theme.from_brand(__file__)
|
||||||
|
|
||||||
|
# Production (precompile)
|
||||||
|
theme_css = ui.Theme.from_brand(__file__).to_css()
|
||||||
|
# Save to static/theme.css, then reference in production
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Theme not applying?**
|
||||||
|
- Check file is named `_brand.yml` (with underscore)
|
||||||
|
- Verify `libsass` is installed: `pip install libsass`
|
||||||
|
- Try explicit path: `ui.Theme.from_brand("path/to/_brand.yml")`
|
||||||
|
- Check for YAML syntax errors
|
||||||
|
|
||||||
|
**Colors not matching?**
|
||||||
|
- Ensure hex colors have quotes: `"#0066cc"`
|
||||||
|
- Verify color names match palette definitions
|
||||||
|
- Check semantic colors reference valid palette names
|
||||||
|
|
||||||
|
**Fonts not loading?**
|
||||||
|
- Verify Google Fonts spelling and availability
|
||||||
|
- Ensure `source: google` is specified
|
||||||
|
- Check font family names match exactly
|
||||||
|
- Internet connection required for Google Fonts
|
||||||
|
|
||||||
|
**Import errors?**
|
||||||
|
- Install theme support: `pip install "shiny[theme]"`
|
||||||
|
- Or install libsass separately: `pip install libsass`
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
For production apps with many instances, precompile the theme:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# build_theme.py
|
||||||
|
from shiny import ui
|
||||||
|
|
||||||
|
theme = ui.Theme.from_brand("_brand.yml")
|
||||||
|
css = theme.to_css()
|
||||||
|
|
||||||
|
with open("static/brand-theme.css", "w") as f:
|
||||||
|
f.write(css)
|
||||||
|
|
||||||
|
# Then in app.py, reference the CSS file directly
|
||||||
|
# This avoids runtime Sass compilation overhead
|
||||||
|
```
|
||||||
378
skills/brand-yml/references/shiny-r.md
Normal file
378
skills/brand-yml/references/shiny-r.md
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
# Using brand.yml with Shiny for R
|
||||||
|
|
||||||
|
Guide for applying brand.yml styling to Shiny applications using the bslib package.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The bslib package integrates brand.yml to provide unified visual theming across Shiny applications. Define colors, fonts, and logos once in `_brand.yml`, and bslib automatically applies them to your Shiny app UI.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```r
|
||||||
|
# Install bslib (includes brand.yml support)
|
||||||
|
install.packages("bslib")
|
||||||
|
|
||||||
|
# Optional: Install brand.yml package for theming plots/tables
|
||||||
|
install.packages("brand.yml")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Automatic Discovery
|
||||||
|
|
||||||
|
Place `_brand.yml` at your app directory root:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-app/
|
||||||
|
├── _brand.yml
|
||||||
|
├── app.R
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Then use `bs_theme()` in your app:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(shiny)
|
||||||
|
library(bslib)
|
||||||
|
|
||||||
|
ui <- page_fluid(
|
||||||
|
theme = bs_theme(), # Automatically finds _brand.yml
|
||||||
|
titlePanel("My App"),
|
||||||
|
# ... rest of UI
|
||||||
|
)
|
||||||
|
|
||||||
|
server <- function(input, output, session) {
|
||||||
|
# ...
|
||||||
|
}
|
||||||
|
|
||||||
|
shinyApp(ui, server)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Search Paths
|
||||||
|
|
||||||
|
bslib automatically searches for `_brand.yml` in this order:
|
||||||
|
|
||||||
|
1. Current app directory
|
||||||
|
2. `_brand/` subdirectory
|
||||||
|
3. `brand/` subdirectory
|
||||||
|
4. Parent directories (recursive)
|
||||||
|
|
||||||
|
## bs_theme() Brand Parameter
|
||||||
|
|
||||||
|
The `brand` parameter controls how branding is applied:
|
||||||
|
|
||||||
|
### Automatic (Default)
|
||||||
|
|
||||||
|
```r
|
||||||
|
theme = bs_theme()
|
||||||
|
```
|
||||||
|
|
||||||
|
Searches for `_brand.yml` and applies it if found. No error if file doesn't exist.
|
||||||
|
|
||||||
|
### Required Brand
|
||||||
|
|
||||||
|
```r
|
||||||
|
theme = bs_theme(brand = TRUE)
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires `_brand.yml` to exist. Throws error if not found.
|
||||||
|
|
||||||
|
### Explicit Path
|
||||||
|
|
||||||
|
```r
|
||||||
|
theme = bs_theme(brand = "path/to/my-brand.yml")
|
||||||
|
```
|
||||||
|
|
||||||
|
Uses specific brand file. Path can be:
|
||||||
|
- Relative to app directory: `"branding/company-brand.yml"`
|
||||||
|
- Absolute: `"/Users/name/brands/company.yml"`
|
||||||
|
- Directory (auto-finds `_brand.yml`): `"branding/"`
|
||||||
|
|
||||||
|
### Inline Brand Definition
|
||||||
|
|
||||||
|
```r
|
||||||
|
theme = bs_theme(
|
||||||
|
brand = list(
|
||||||
|
color = list(
|
||||||
|
palette = list(
|
||||||
|
blue = "#0066cc",
|
||||||
|
gray = "#666666"
|
||||||
|
),
|
||||||
|
primary = "blue",
|
||||||
|
foreground = "gray"
|
||||||
|
),
|
||||||
|
typography = list(
|
||||||
|
fonts = list(
|
||||||
|
list(family = "Inter", source = "google", weight = c(400, 600))
|
||||||
|
),
|
||||||
|
base = "Inter"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disable Branding
|
||||||
|
|
||||||
|
```r
|
||||||
|
theme = bs_theme(brand = FALSE)
|
||||||
|
```
|
||||||
|
|
||||||
|
Ignores `_brand.yml` even if it exists.
|
||||||
|
|
||||||
|
## Using with page_*() Functions
|
||||||
|
|
||||||
|
All bslib page functions support automatic brand discovery:
|
||||||
|
|
||||||
|
```r
|
||||||
|
# page_fluid
|
||||||
|
ui <- page_fluid(
|
||||||
|
theme = bs_theme(),
|
||||||
|
# ... content
|
||||||
|
)
|
||||||
|
|
||||||
|
# page_sidebar
|
||||||
|
ui <- page_sidebar(
|
||||||
|
theme = bs_theme(),
|
||||||
|
sidebar = sidebar(
|
||||||
|
# ... sidebar content
|
||||||
|
),
|
||||||
|
# ... main content
|
||||||
|
)
|
||||||
|
|
||||||
|
# page_navbar
|
||||||
|
ui <- page_navbar(
|
||||||
|
theme = bs_theme(),
|
||||||
|
nav_panel("Tab 1", # ...),
|
||||||
|
nav_panel("Tab 2", # ...)
|
||||||
|
)
|
||||||
|
|
||||||
|
# page_fillable
|
||||||
|
ui <- page_fillable(
|
||||||
|
theme = bs_theme(),
|
||||||
|
# ... content
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Branded Plots and Tables in Shiny
|
||||||
|
|
||||||
|
Use theming functions from the brand.yml package to style plots and tables within Shiny apps. See `brand-yml-in-r.md` for complete documentation of theming functions.
|
||||||
|
|
||||||
|
### Basic Example
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(shiny)
|
||||||
|
library(bslib)
|
||||||
|
library(ggplot2)
|
||||||
|
library(gt)
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
ui <- page_sidebar(
|
||||||
|
theme = bs_theme(brand = TRUE),
|
||||||
|
|
||||||
|
sidebar = sidebar(
|
||||||
|
selectInput("dataset", "Dataset:", c("mtcars", "iris"))
|
||||||
|
),
|
||||||
|
|
||||||
|
card(
|
||||||
|
card_header("Branded Plot"),
|
||||||
|
plotOutput("plot")
|
||||||
|
),
|
||||||
|
card(
|
||||||
|
card_header("Branded Table"),
|
||||||
|
gt_output("table")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
server <- function(input, output, session) {
|
||||||
|
output$plot <- renderPlot({
|
||||||
|
ggplot(mtcars, aes(mpg, hp)) +
|
||||||
|
geom_point() +
|
||||||
|
theme_brand_ggplot2()
|
||||||
|
})
|
||||||
|
|
||||||
|
output$table <- render_gt({
|
||||||
|
head(mtcars) |>
|
||||||
|
gt() |>
|
||||||
|
theme_brand_gt()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
shinyApp(ui, server)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- Consistent styling across UI, plots, and tables
|
||||||
|
- Automatic brand detection from `_brand.yml`
|
||||||
|
- Works with ggplot2, gt, flextable, plotly, and base R graphics
|
||||||
|
|
||||||
|
For detailed theming function documentation, see `brand-yml-in-r.md`.
|
||||||
|
|
||||||
|
## Complete Shiny Example
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(shiny)
|
||||||
|
library(bslib)
|
||||||
|
|
||||||
|
ui <- page_sidebar(
|
||||||
|
theme = bs_theme(brand = TRUE), # Require _brand.yml
|
||||||
|
|
||||||
|
sidebar = sidebar(
|
||||||
|
title = "Controls",
|
||||||
|
selectInput("dataset", "Dataset:",
|
||||||
|
choices = c("iris", "mtcars")),
|
||||||
|
numericInput("n", "Number of rows:", 10, min = 1, max = 50)
|
||||||
|
),
|
||||||
|
|
||||||
|
card(
|
||||||
|
card_header("Data Summary"),
|
||||||
|
tableOutput("summary")
|
||||||
|
),
|
||||||
|
|
||||||
|
card(
|
||||||
|
card_header("Data Details"),
|
||||||
|
verbatimTextOutput("details")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
server <- function(input, output, session) {
|
||||||
|
dataset <- reactive({
|
||||||
|
get(input$dataset)
|
||||||
|
})
|
||||||
|
|
||||||
|
output$summary <- renderTable({
|
||||||
|
head(dataset(), input$n)
|
||||||
|
})
|
||||||
|
|
||||||
|
output$details <- renderPrint({
|
||||||
|
summary(dataset())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
shinyApp(ui, server)
|
||||||
|
```
|
||||||
|
|
||||||
|
With `_brand.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
color:
|
||||||
|
palette:
|
||||||
|
brand-blue: "#0066cc"
|
||||||
|
brand-gray: "#666666"
|
||||||
|
primary: brand-blue
|
||||||
|
foreground: brand-gray
|
||||||
|
background: "#ffffff"
|
||||||
|
|
||||||
|
typography:
|
||||||
|
fonts:
|
||||||
|
- family: Inter
|
||||||
|
source: google
|
||||||
|
weight: [400, 600]
|
||||||
|
base:
|
||||||
|
family: Inter
|
||||||
|
size: 16px
|
||||||
|
headings:
|
||||||
|
family: Inter
|
||||||
|
weight: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
## R Markdown Shiny Documents
|
||||||
|
|
||||||
|
Use brand.yml in R Markdown documents with Shiny runtime:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "Interactive Dashboard"
|
||||||
|
output:
|
||||||
|
html_document:
|
||||||
|
theme:
|
||||||
|
version: 5 # Required for brand.yml
|
||||||
|
brand: true # Auto-discover _brand.yml
|
||||||
|
runtime: shiny
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Or specify a path:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "Interactive Dashboard"
|
||||||
|
output:
|
||||||
|
html_document:
|
||||||
|
theme:
|
||||||
|
version: 5
|
||||||
|
brand: "path/to/brand.yml"
|
||||||
|
runtime: shiny
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important**: Set `version: 5` to use Bootstrap 5, which has the best brand.yml support.
|
||||||
|
|
||||||
|
**Note**: For R Markdown documents without `runtime: shiny`, see `brand-yml-in-r.md`.
|
||||||
|
|
||||||
|
## Programmatic Brand Access
|
||||||
|
|
||||||
|
For advanced use cases, access brand data programmatically within Shiny:
|
||||||
|
|
||||||
|
```r
|
||||||
|
library(brand.yml)
|
||||||
|
|
||||||
|
server <- function(input, output, session) {
|
||||||
|
# Read brand data
|
||||||
|
brand <- read_brand_yml()
|
||||||
|
|
||||||
|
# Use in custom UI elements
|
||||||
|
output$brand_info <- renderUI({
|
||||||
|
div(
|
||||||
|
style = paste0("color: ", brand$color$primary, ";"),
|
||||||
|
h3(brand$meta$name),
|
||||||
|
p("Welcome to our branded app!")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
# Use in plots with custom styling
|
||||||
|
output$custom_plot <- renderPlot({
|
||||||
|
plot(mtcars$mpg, mtcars$hp,
|
||||||
|
col = brand$color$primary,
|
||||||
|
pch = 19)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For complete documentation on programmatic access and theming functions, see `brand-yml-in-r.md`.
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- **Start simple**: Begin with colors and one font family
|
||||||
|
- **Test automatically**: Automatic discovery works well for most cases
|
||||||
|
- **Use explicit paths**: For shared brand files across multiple apps
|
||||||
|
- **Version control**: Include `_brand.yml` in your git repository
|
||||||
|
- **Validate early**: Use `brand = TRUE` during development to catch missing files
|
||||||
|
- **Combine with theming functions**: Style plots and tables consistently (see `brand-yml-in-r.md`)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Brand not applying to Shiny UI?**
|
||||||
|
- Check file is named `_brand.yml` (with underscore)
|
||||||
|
- Verify file is in app directory or parent directories
|
||||||
|
- Try explicit path: `bs_theme(brand = "path/to/_brand.yml")`
|
||||||
|
- Check for YAML syntax errors
|
||||||
|
|
||||||
|
**Colors not matching?**
|
||||||
|
- Verify hex colors have quotes: `"#0066cc"`
|
||||||
|
- Check color names match palette definitions
|
||||||
|
- Ensure primary/secondary colors reference valid palette names
|
||||||
|
|
||||||
|
**Fonts not loading?**
|
||||||
|
- Verify Google Fonts spelling and availability
|
||||||
|
- Check `source: google` is specified correctly
|
||||||
|
- Ensure font family names match exactly in typography elements
|
||||||
|
|
||||||
|
**Plots/tables not branded?**
|
||||||
|
- Ensure brand.yml package is installed: `install.packages("brand.yml")`
|
||||||
|
- Use theming functions: `theme_brand_ggplot2()`, `theme_brand_gt()`, etc.
|
||||||
|
- See `brand-yml-in-r.md` for complete theming documentation
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- **[brand-yml-in-r.md](brand-yml-in-r.md)**: General R usage, R Markdown integration, theming functions, and programmatic access
|
||||||
|
- **[brand-yml-spec.md](brand-yml-spec.md)**: Complete brand.yml file specification
|
||||||
Reference in New Issue
Block a user