styling and palette

Prezillo uses a cascading style system with global style definitions, inline overrides, and a document-wide color palette.

Style Resolution Cascade

Styles resolve in layers, with later layers overriding earlier ones:

graph LR
    D["Built-in Defaults"] --> S["Style Chain<br/>(si/ti → parent p)"]
    S --> O["Inline Override<br/>(s/ts on object)"]

    style D fill:#e8e8e8,stroke:#999
    style S fill:#d4e6f1,stroke:#2980b9
    style O fill:#d5f5e3,stroke:#27ae60
  1. Built-in defaults: Hard-coded fallback values (e.g., fill #cccccc, strokeWidth 1)
  2. Style chain: The object’s si (shape style) or ti (text style) references a global StoredStyle in the st map. That style may have a parent (p field), forming a chain. Properties are inherited up the chain until a value is found.
  3. Inline overrides: The object’s s (shape style) or ts (text style) fields contain direct property overrides that take highest precedence.

StoredStyle Fields

Global styles are stored in the st map, keyed by StyleId.

Field Type Description
n string Style name (user-visible, e.g., "Primary", "Heading")
t 'S' | 'T' Type: S=shape style, T=text style
p string Parent StyleId (for inheritance chain)

Shape style properties (when t='S'):

Field Type Description
f ColorValue Fill color (hex string or palette reference)
fo number Fill opacity (0–1)
s ColorValue Stroke color (hex string or palette reference)
sw number Stroke width
so number Stroke opacity (0–1)
sd string Stroke dasharray (SVG format, e.g., "5,5")
sc 'butt' | 'round' | 'square' Stroke linecap
sj 'miter' | 'round' | 'bevel' Stroke linejoin
sh [number, number, number, ColorValue] Shadow: [offsetX, offsetY, blur, color]
cr number Corner radius (for rects using this style)

Text style properties (when t='T'):

Field Type Description
ff string Font family (e.g., "Inter, system-ui")
fs number Font size in pixels
fw 'normal' | 'bold' | number Font weight
fi boolean Font italic
td 'u' | 's' Text decoration: u=underline, s=strikethrough
fc ColorValue Text fill color (hex string or palette reference)
ta 'l' | 'c' | 'r' | 'j' Text align: left/center/right/justify
va 't' | 'm' | 'b' Vertical align: top/middle/bottom
lh number Line height multiplier
ls number Letter spacing in pixels
lb string List bullet character (UTF-8, e.g., "•")

ShapeStyle and TextStyle (Inline)

The s and ts fields on objects use the same property names as StoredStyle, but without the n, t, and p fields. They contain only the properties being overridden.

// Example: object with style reference + inline override
{
  t: 'R',
  xy: [100, 200],
  wh: [300, 150],
  si: 'Nz9cK_vW3xRb',           // references "Primary" style
  s: { f: '#ff0000', sw: 3 }     // overrides fill and stroke width
}

Palette System

The palette provides a set of named color and gradient slots that can be referenced by any style or object. This allows changing the document’s color theme by updating a single palette entry.

StoredPalette Structure

The palette is stored as a single entry in the pl map under the key 'default':

Field Type Description
n string Palette name (e.g., "Default", "Office Blue")
bg StoredPaletteColor Background color slot
tx StoredPaletteColor Text color slot
a1a6 StoredPaletteColor Accent color slots 1–6
g1g4 StoredBackgroundGradient Gradient slots 1–4

Where StoredPaletteColor is simply { c: string } (a hex color).

Palette Slot Codes

Color slots:

Code Name
bg Background
tx Text
a1 Accent 1
a2 Accent 2
a3 Accent 3
a4 Accent 4
a5 Accent 5
a6 Accent 6

Gradient slots:

Code Name
g1 Gradient 1
g2 Gradient 2
g3 Gradient 3
g4 Gradient 4

StoredPaletteRef

A palette reference replaces a literal color value in any ColorValue field:

Field Type Description
pi PaletteSlot Palette slot code (e.g., 'a1', 'tx', 'g2')
o number Opacity override (0–1, default 1)
t number Tint/shade adjustment (-1 to 1, 0 = original). Positive values tint toward white, negative values shade toward black.

ColorValue Union

Any color field (f, s, fc, shadow color, etc.) accepts either a raw hex string or a palette reference:

type ColorValue = string | StoredPaletteRef

Examples:

// Raw hex color
{ f: '#4a90d9' }

// Palette reference: accent 1, full opacity
{ f: { pi: 'a1' } }

// Palette reference: text color at 50% opacity, slightly lighter
{ fc: { pi: 'tx', o: 0.5, t: 0.2 } }

When a palette slot is updated, all objects and styles referencing that slot automatically reflect the new color — resolution happens at render time.

Default Styles

A new document is initialized with these styles:

Shape styles:

Name Fill Stroke Stroke Width Notes
Default Shape #e0e0e0 #999999 1
Primary #4a90d9 #2d5a87 2 Corner radius 8
Secondary #5cb85c #3d8b3d (inherited) Parent: Primary
Accent #f0ad4e #c87f0a (inherited) Parent: Primary
Outline none #333333 2 Dashed (5,5)
Connector none #666666 2

Text styles:

Name Font Family Size Weight Color Notes
Default Text system-ui 16 normal #333333
Heading Inter, system-ui 48 bold #1a1a2e
Body Inter, system-ui 18 normal #333333 Line height 1.5
Caption (inherited) 14 (inherited) #666666 Parent: Body, italic

Default Palette

Slot Color Description
bg #ffffff Background (white)
tx #333333 Text (dark gray)
a1 #4a90d9 Accent 1 (blue)
a2 #5cb85c Accent 2 (green)
a3 #f0ad4e Accent 3 (orange)
a4 #d9534f Accent 4 (red)
a5 #9b59b6 Accent 5 (purple)
a6 #1abc9c Accent 6 (teal)
g1 Blue gradient (180°) #4a90d9#2d5a87
g2 Green gradient (135°) #5cb85c#3d8b3d
g3 Orange radial gradient #f0ad4e#c87f0a
g4 Purple gradient (90°) #667eea#764ba2

See Also