BRAIDGROUP
RESEARCH & DEV
60. Framework Docs

Blend CSS-in-JS

Blend is Braid's CSS-in-JS framework (braid-lang/lib/frameworks/blend/blend.br, 618 lines). It generates atomic class names, supports theming (light/dark), responsive breakpoints, @keyframes/@font-face/@import, critical CSS extraction, minification, vendor prefixing, Z-index management, and spacing/typography scales.

Core API

Style Definition

// Define a scoped style — generates an atomic class name
fn style(properties: object) -> BlendStyle

// Define a global style (selector-based, no class name)
fn global_style(selector: string, properties: object) -> BlendStyle
let card_style = blend.style({
    backgroundColor: "#fff",
    borderRadius: "8px",
    padding: "16px",
    boxShadow: "0 2px 4px rgba(0,0,0,0.1)"
});

// Access the generated class
let class_name = blend.blend_class(card_style);
// Returns something like "blend-847291"

Unit & Color Helpers

fn px(val: int) -> string    // "42px"
fn rem(val: int) -> string   // "2rem"
fn em(val: int) -> string
fn percent(val: int) -> string
fn vh(val: int) -> string
fn vw(val: int) -> string

fn hex(val: string) -> string    // "#ff0000"
fn rgb(r, g, b) -> string        // "rgb(255,0,0)"
fn rgba(r, g, b, a) -> string    // "rgba(255,0,0,0.5)"

Stylesheet Generation

// Generate complete stylesheet CSS from one or more style objects
fn generate_stylesheet(styles: object) -> string

// Render a single style object to CSS
fn render_style(style_obj: object) -> string

// Inject stylesheet as a <style> element (returns a Bond VDOM node)
fn inject_stylesheet(css_string: string, id: string) -> object

Theme System

// Define design tokens
let tokens = blend.create_theme({
    primary: "#1a73e8",
    background: "#ffffff",
    text: "#1f1f1f",
    border: "#dadce0",
    surface: "#f8f9fa"
});

// Access a token as a CSS variable
let primary_var = blend.var("primary");
// Returns "var(--primary)"

Light/Dark Theme Config

let theme = blend.create_theme_config(
    { background: "#fff", text: "#000", primary: "#1a73e8" },
    { background: "#121212", text: "#eee", primary: "#bb86fc" }
);

theme.set_theme("dark");
let tokens = theme.get_tokens();
let css_vars = theme.generate_theme_variables();
// Outputs: :root { --background: #121212; --text: #eee; ... }

// Dark mode style — emits @media (prefers-color-scheme: dark)
let btn = blend.dark_mode_style(
    { background: "#fff", color: "#000" },
    { background: "#333", color: "#fff" }
);

@keyframes, @font-face, @import

// Keyframes animation
let fade_in = blend.keyframes("fadeIn", {
    "0%": { opacity: "0", transform: "translateY(10px)" },
    "100%": { opacity: "1", transform: "translateY(0)" }
});

// Usage in style
let animated = blend.style({
    animation: blend.animation("fadeIn", "0.3s", "ease-out", "0s", "1", "normal"),
    opacity: "0"
});

// Font face
let custom_font = blend.font_face({
    fontFamily: "Inter",
    src: "url('/fonts/Inter-Regular.woff2') format('woff2')",
    fontWeight: "400",
    fontStyle: "normal"
});

// External import
let external = blend.import_style("https://fonts.googleapis.com/css2?family=Inter");

Pseudo-classes & Media Queries

// Pseudo-class
let hover_btn = blend.pseudo("hover", {
    backgroundColor: "#1557b0",
    boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
});

// Media query
let responsive = blend.media("(max-width: 768px)", {
    padding: "8px",
    fontSize: "14px"
});

// Both can be combined:
let s = blend.style({ color: "red", fontSize: "16px" });
s.pseudo_class = "hover";
s.media_query = "(min-width: 768px)";

Responsive Breakpoints

let bp = blend.create_breakpoints();
// { xs: "0px", sm: "576px", md: "768px", lg: "992px", xl: "1200px" }

let mobile_up = blend.breakpoint_up(bp.sm);   // "(min-width: 576px)"
let tablet_down = blend.breakpoint_down(bp.md); // "(max-width: 768px)"
let between = blend.breakpoint_between(bp.sm, bp.lg);

// Shorthand for responsive styles
let desktop_card = blend.responsive_style(bp.lg, {
    display: "flex",
    gap: "24px"
});

Dark Mode Auto-Switching

// Blend automatically wraps dark mode styles in:
@media (prefers-color-scheme: dark) {
  .blend-xxx { background: #333; color: #fff; }
}

// Generated by render_with_dark_mode(selector, light_props, dark_props)
// Also available: theme.dark_mode_global_style(selector, properties)
// which maps theme token keys to dark values

Critical CSS Extraction

let extractor = blend.create_critical_css_extractor();
extractor.mark_above_fold(".hero");
extractor.add_rule(hero_style);

let critical_css = extractor.extract_critical(all_styles);
let split = extractor.split_critical_async(full_css);
// split.critical — inline in <head>
// split.async — load asynchronously

CSS Minification

let minified = blend.minify_css(raw_css_string);
// Strips comments, collapses whitespace, minimal output

Vendor Prefixing

// Auto-prefixes: transform, transition, animation, appearance,
// user-select, backdrop-filter, clip-path, mask, box-decoration-break

let prefixed = blend.apply_vendor_prefixes_to_properties({
    transform: "rotate(45deg)",
    appearance: "none"
});
// Adds -webkit-transform, -moz-transform, etc.

Z-Index Management

let z = blend.create_z_index_system();
// Predefined layers: base(0), dropdown(100), sticky(200),
// navbar(300), modal-backdrop(400), modal(500),
// popover(600), tooltip(700), toast(800), loading(900), max(9999)

let modal_layer = z.get_layer("modal");     // 500
let next_idx = z.get_next();                // 1, 2, 3...
z.set_layer("my-layer", 250);

Spacing Scale

let spacing = blend.create_spacing_scale(4);
// Factors: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64]

spacing.get(3);     // "12px" (3 * 4)
spacing.margin(4);  // "margin: 16px"
spacing.padding(6); // "padding: 24px"
spacing.gap(8);     // "gap: 32px"

Typography Scale

let type = blend.create_typography_scale(16, 1.25);
// Default ratio: 1.25 (major third)
// Levels: h1-h6, body, small, caption

type.get_size("h1");       // ~61px (16 * 1.25^5)
type.get_line_height("h1"); // 1.2
type.heading_style("h2");
// { fontSize: "49px", lineHeight: "1.25" }

Theme Toggle Example

import bond;
import blend;

let theme = blend.create_theme_config(
    { bg: "#fff", text: "#333", card: "#f5f5f5" },
    { bg: "#1a1a2e", text: "#eee", card: "#16213e" }
);

fn ToggleButton() {
    return bond.button(
        theme.current_theme == "light" ? "Switch to Dark" : "Switch to Light",
        {
            onClick: fn() { theme.toggle_theme(); },
            class: blend.blend_class(blend.style({
                padding: "12px 24px",
                cursor: "pointer",
                border: "none",
                borderRadius: "6px",
                background: blend.var("bg"),
                color: blend.var("text")
            }))
        }
    );
}

Responsive Component Example

import bond;
import blend;

let bp = blend.create_breakpoints();

let mobile_card = blend.style({
    width: "100%",
    padding: "12px",
    fontSize: "14px"
});

let desktop_card = blend.responsive_style(bp.lg, {
    width: "600px",
    padding: "32px",
    fontSize: "18px"
});

let combined = blend.generate_stylesheet([mobile_card, desktop_card]);
let style_element = blend.inject_stylesheet(combined, "card-styles");

fn ResponsiveCard(props) {
    return bond.fragment([
        style_element,
        bond.div({ class: blend.blend_class(mobile_card) }, [
            bond.h2(props.title, {}),
            bond.p(props.body, {})
        ])
    ]);
}

Internal Architecture

Blend converts camelCase property names to kebab-case via camel_to_kebab(str), generates unique class names via simple_hash(stringify_properties(properties)), and renders styles as either global selectors or atomic classes. The BlendStyle struct carries all metadata needed for media queries, pseudo-classes, dark mode, animations, font faces, and imports — enabling a single unified rendering pipeline via render_style().