CBDF Specification: Styles Section

Version 1.0 (Phase II)

Document: 03-Styles-Section • Date: 2026-03-25

1. Overview

The Styles section defines all visual formatting used in the document. It sits between the first FS (end of Meta) and the second FS (start of Text). It begins with a 4-byte LE length prefix.

Structure (after the FS marker):

[Length: 4 bytes LE] [Layout byte] [Background style] GS [sub-tables...]

The 4-byte length prefix counts the section content bytes only (everything after the length field itself). This is consistent with Document Structure spec Section 4A.

The section is organized into sub-tables separated by GS (0x1D). Each sub-table defines a category of styles (text, container, border, etc.). Empty sub-tables are represented as GS immediately followed by the next GS or FS.

If the meta section contains a "default style set" flag (value >= 1), the styles section may be empty or contain only delta overrides.

2. Layout Byte (1 byte)

The first byte of the Styles section selects one of 256 predefined page layouts. Each layout defines the arrangement of top-level panels.

Bit layout:

BitsFieldDescription
0-3Panel existence flagsBit 0: Header, Bit 1: Footer, Bit 2: Left aside, Bit 3: Right aside
4-5Column count00=1, 01=2, 10=3, 11=4 columns
6-7Row count00=1, 01=2, 10=3, 11=4 rows

The Main panel is ALWAYS implied (never needs a flag).

Common Layout Reference Table

HexBinaryPanelsColsRowsDescription
0x000000 0000Main11Single content area
0x010000 0001Header+Main11Header bar + body
0x030000 0011Hdr+Ftr+Main11Header + footer
0x070000 0111Hdr+Ftr+Left+Main11With left sidebar
0x0F0000 1111All panels+Main11Full layout
0x110001 0001Header+Main21Header + 2 cols
0x1F0001 1111All panels+Main21Full + 2 cols
0x2F0010 1111All panels+Main31Full + 3 cols
0x3F0011 1111All panels+Main41Full + 4 cols
0x4F0100 1111All panels+Main12Full + 2 rows
0xFF1111 1111All panels+Main44Maximum layout

Decoding example for 0x3F (0011 1111):

  • Bits 0-3 = 1111: Header(1) + Footer(1) + Left(1) + Right(1)
  • Bits 4-5 = 11: 4 columns
  • Bits 6-7 = 00: 1 row
  • Result: All panels, 4 columns, 1 row.
Layout Byte Bit Diagram

Click diagram to open full size in new tab

3. Sub-Table Header Byte

A Note About "Tiering"

In this spec, "tiering" means that a style record can have different sizes depending on how many properties you need.

Think of it like ordering a burger: small, medium, or large. You don't pay for the large if you only need the small.

Example with Text Styles:

  • Base tier (8 bytes): Font, size, bold/italic flags, text color, background color. This covers 90% of use cases.
  • Extended tier (12 bytes): Everything in base PLUS text shadow, letter spacing, line height. For documents that need more control.
  • Rare tier (16 bytes): Everything in extended PLUS font effects (flames, glow, etc.), text direction (RTL), word spacing. Only for heavily styled documents.

Key Rule

ALL text styles in a document use the SAME tier. If even one style needs a shadow, then ALL text styles in that document are extended tier (12 bytes each). This is signaled by the 2-bit tier field in the sub-table header byte.

This saves bytes because most simple emails only need base tier styles. A plain email with 3 text styles uses 3 x 8 = 24 bytes for text styling. If we forced the rare tier for everyone, it would be 3 x 16 = 48 bytes -- double the size for properties nobody used.

The trade-off: if you have 10 simple styles and 1 style that needs a shadow, all 11 become extended tier. You "waste" 4 bytes on each of the 10 simple ones. But this is still better than per-record variable sizing, which makes parsing much harder.

Style Tier System Diagram

Click diagram to open full size in new tab

Each sub-table (after the layout byte and background style) begins with a 1-byte header:

BitsFieldDescription
0-1Tier00=Base, 01=Base+Extended, 10=Base+Extended+Rare, 11=Reserved
2-7Count0-63 records in this sub-table

This is ONE byte, appearing ONCE per sub-table. ALL records in that sub-table use the SAME tier size. The parser reads the header, knows the record size and count, and parses all records sequentially.

Not all sub-tables use tiering. Sub-tables with fixed-size records (shadow, composite, nav bar) only use the count field (bits 2-7) with tier bits = 00.

4. Sub-Table Order

Sub-tables appear in this fixed order, separated by GS (0x1D):

PositionSub-tableTiered?Ref Name
1Container Background StylesYesBG
2Container Border StylesNoBORDER
3Container Spacing StylesNoSPACING
4Container Shadow StylesNoSHADOW
5Container Composite StylesNoCOMPOSITE
6Text StylesYesTEXT
7Font EffectsNoEFFECT
8Nav Bar StylesNoNAV
9Table StylesNoTABLE
10Image DefinitionsNoIMAGE
11Frame/iFrame DefinitionsNoFRAME
12Reserved (Form Styles)-(Phase III)

Empty sub-table: [GS] immediately (header byte with count=0, or just GS).

The page-level background style appears BEFORE the first GS and after the layout byte. It is a single record (not a sub-table) using the Container Background Style format.

Styles Section Layout Diagram

Click diagram to open full size in new tab

5. Page-Level Background Style

Immediately after the layout byte, before the first GS, sits a single background style record for the entire page (Layer 0). This uses the Container Background Style format (see Section 6A).

If the first byte after the layout byte is GS, the page has no background style (transparent/default).

6. Style Record Formats

6A. Container Background Style

All tiers are FIXED SIZE to maintain sub-table indexability. Gradient color stops have a fixed count per tier (0, 2, or 4 stops).

Base tier (6 bytes) -- no gradient:

ByteFieldDescription
0-1Background colorR5G6B5 or transparency code
2-3Background image ID0=none; references built-in image table
4Color opacity0-255 maps to 0-100%. Controls BG color over BG image.
5Image flagsBit 0: Repeat X, Bit 1: Repeat Y, Bit 2: Fixed, Bit 3: Cover, Bit 4: Contain

Extended tier (12 bytes) -- 2 gradient stops:

ByteFieldDescription
0-5(Same as base tier)
6Gradient type + angleTypes: 0=none, 1=linear, 2=radial, 3=conic. Angle: 0-15 (22.5° steps)
7ReservedMust be 0
8-9Gradient color stop 1R5G6B5
10-11Gradient color stop 2R5G6B5

Rare tier (20 bytes) -- 4 gradient stops + animation:

ByteFieldDescription
0-11(Same as extended tier)
12-13Gradient color stop 3R5G6B5
14-15Gradient color stop 4R5G6B5
16Animation type + speedTypes: 0=none, 1=scroll, 2=pulse, 3=fade, 4=parallax. Speed: 0-15
17Event flagsBit 0: On hover change, Bit 1: On click change
18Hover style IDReferences another BG style
19User-settable flagBit 0: User's browser may override this style

Gradient Stop Limits

Base tier = 0 stops, Extended = 2, Rare = 4. If a design needs more than 4 gradient stops, use overlapping containers with different gradient backgrounds.

6B. Container Border Style (9 bytes, fixed)

ByteFieldDescription
0-1Border colorR5G6B5
2-3Outside-of-border colorR5G6B5 or transparency
4-5Border thickness per sideBits 0-3: Top, 4-7: Right, 8-11: Bottom, 12-15: Left (0-15 px each)
6-8Corner radius6 bits each (0-50%): UL, UR, LR, LL

6C. Container Spacing Style (4 bytes, fixed)

All values are percentages of the parent container.

ByteFieldDescription
0-1Margin per sideBits 0-3: Top, 4-7: Right, 8-11: Bottom, 12-15: Left (0-15%)
2-3Padding per sideBits 0-3: Top, 4-7: Right, 8-11: Bottom, 12-15: Left (0-15%)

The "Egg" (content area) size = container - margin - border - padding. If top/bottom margin = 0, it inherits the left margin value.

6D. Container Shadow Style (4 bytes, fixed)

ByteFieldDescription
0-1Shadow colorR5G6B5
2-3Shadow geometryBits 0-5: X offset, 6-11: Y offset (signed 6-bit), 12-15: Blur (0-15 px)

6E. Container Composite Style (5 bytes, fixed)

Cross-references into the other container sub-tables:

ByteFieldDescription
0Background style IDIndex into BG sub-table
1Border style IDIndex into BORDER sub-table
2Spacing style IDIndex into SPACING sub-table
3Shadow style IDIndex into SHADOW sub-table
4Overflow + Layer IDBits 0-1: Overflow (0=visible, 1=hidden, 2=scroll, 3=auto), Bits 2-7: Layer ID (0-63)

This design allows sharing: multiple panels can reference the same border style, same spacing, etc. without duplication.

6F. Text Style

Base tier (8 bytes):

ByteFieldDescription
0-1Font IDBits 0-11: Font family index (0-4095), Bits 12-15: Sub-variant hints
2Font size1-255 points; 0 = inherit/default
3FlagsBit 0: Bold, 1: Italic, 2: Underline, 3: Strikethrough, 4: Subscript, 5: Superscript, 6-7: Alignment
4-5Text foreground colorR5G6B5 or transparency code
6-7Text background colorR5G6B5 or transparency code

Extended tier adds 4 bytes (total 12):

ByteFieldDescription
8-9Text shadowBits 0-5: X offset, 6-11: Y offset (signed 6-bit), 12-15: Blur (0-15 px)
10Letter spacingSigned int8, -128 to +127, in 0.1em units
11Line height0=auto; 1-255 = value/10 (0.1 to 25.5)

Rare tier adds 4 bytes (total 16):

ByteFieldDescription
12Font effect + intensityBits 0-3: Effect ID (0-15), Bits 4-7: Intensity (0-15)
13Transform + direction + word spacingBits 0-1: Transform, 2-3: Direction, 4-7: Word spacing
14-15Effect colorR5G6B5 (used by glow/shadow/gradient effects)

6G. Font Effect (4 bytes, fixed)

For effects that need more parameters than the 4+4 bits in the text style rare tier. Referenced by effect ID 15 ("Custom") in the text style.

ByteFieldDescription
0Effect typeSame IDs as text style effect (0-15)
1Parameter AEffect-specific (e.g., blur radius, density)
2Parameter BEffect-specific (e.g., animation speed, angle)
3Animation flagsBits 0-3: Speed, 4-5: Loop mode, 6-7: Reserved

6H. Nav Bar Style (12 bytes, fixed)

ByteFieldDescription
0Orientation + item countBit 0: Orientation (0=horiz, 1=vert), Bits 1-7: Max items (0-127)
1-2Background colorR5G6B5
3-4Item background colorR5G6B5
5-6Item hover colorR5G6B5
7Item text style IDIndex into TEXT sub-table
8Divider + spacingBits 0-1: Divider style, Bits 2-7: Item spacing (0-63 px)
9Active item text style IDFor "current page" indicator
10Collapse breakpoint0=never; 1-255 = viewport width / 4 (4-1020px in 4px steps)
11Icon/text modeBits 0-1: Mode (0=text, 1=icon, 2=icon+text, 3=auto)

6I. Table Style (6 bytes, fixed)

ByteFieldDescription
0Table flagsBit 0: Border collapse, 1: Header row, 2: Stripe odd rows, 3-4: Width mode
1Border spacing0-255 px (if not collapsed)
2-3Stripe colorR5G6B5 (alternating row color if bit 2 set)
4Header row text style ID
5Body cell text style ID

6J. Image Definition (8 bytes, fixed)

Defines how an image is displayed. Does NOT contain image data (that's in the Resources section).

ByteFieldDescription
0Image source type0=Resource, 1=Built-in, 2=AI-generated
1Resource IDFor type 0: resource ID; type 1: built-in ID; type 2: 0
2-3Width16 bits, in pixels; 0=auto
4-5Height16 bits, in pixels; 0=auto
6Fit mode + alignmentBits 0-2: Fit, 3-4: H-align, 5-6: V-align
7Border style IDIndex into BORDER sub-table; 0=no border

When the Resources section is skipped (abortable download), the renderer uses Width and Height to display a placeholder box.

6K. Frame/iFrame Definition (8 bytes, fixed)

ByteFieldDescription
0Source type0=External URL, 1=Inline CBDF sub-document
1Resource IDFor type 1; or 0 if URL provided inline
2-3Width16 bits, in pixels
4-5Height16 bits, in pixels
6Border style IDIndex into BORDER sub-table
7Sandbox flagsBit 0: Allow scripts, 1: Allow links, 2: Allow forms, 3: Allow popups

7. Complete Styles Section Layout

[Length: 4 bytes LE]
[Layout byte: 1 byte]
[Page background: BG record (variable if extended/rare tier)]
GS [Header: 1B] RS [BG record 0] RS [BG record 1] ...        -- BG styles
GS [Header: 1B] RS [Border 0] RS [Border 1] ...               -- Border styles
GS [Header: 1B] RS [Spacing 0] RS [Spacing 1] ...             -- Spacing styles
GS [Header: 1B] RS [Shadow 0] RS [Shadow 1] ...               -- Shadow styles
GS [Header: 1B] RS [Composite 0] RS [Composite 1] ...         -- Composite styles
GS [Header: 1B] RS [Text 0] RS [Text 1] ...                   -- Text styles
GS [Header: 1B] RS [Effect 0] RS [Effect 1] ...               -- Font effects
GS [Header: 1B] RS [Nav 0] RS [Nav 1] ...                     -- Nav bar styles
GS [Header: 1B] RS [Table 0] RS [Table 1] ...                 -- Table styles
GS [Header: 1B] RS [Image 0] RS [Image 1] ...                 -- Image defs
GS [Header: 1B] RS [Frame 0] RS [Frame 1] ...                 -- Frame defs
GS                                                             -- Reserved (forms)

Minimum styles section (no styles, just structure):

[0x00 0x00 0x00 0x02] [0x00] [GS][GS][GS][GS][GS][GS][GS][GS][GS][GS][GS][GS]
(4-byte length=2, layout byte=0x00 (main only, no bg), 12 empty GS markers)

8. Record Size Summary

All style record types have FIXED sizes within each tier. There are no variable-length records. This guarantees that the parser can index into any sub-table by offset: record_offset = header_size + (index * record_size).

Style TypeBaseExtendedRare
Container Background6 B12 B20 B
Container Border9 B--
Container Spacing4 B--
Container Shadow4 B--
Container Composite5 B--
Text Style8 B12 B16 B
Font Effect4 B--
Nav Bar12 B--
Table6 B--
Image Definition8 B--
Frame Definition8 B--

- means that style type does not use tiering (only one fixed size).