# SmartCanvas SDK Capabilities

This document describes all available operations and capabilities of the SmartCanvas SDK for DOM manipulation and enhancement.

## Table of Contents
- [Overview](#overview)
- [Policy Tiers](#policy-tiers)
- [Anchor Selectors](#anchor-selectors)
- [Operations](#operations)
- [Overlays](#overlays)
- [Best Practices](#best-practices)

## Overview

The SmartCanvas SDK allows you to safely modify web pages through a controlled patching system. All modifications are applied through "patches" that contain:
- An anchor selector to find the target element
- One or more operations to apply
- A policy tier that controls what modifications are allowed

## Policy Tiers

The SDK uses three policy tiers to control what operations are allowed:

### 1. **additive** (default)
- **Purpose**: Safest tier - only add new elements and classes
- **Allowed**: Adding HTML, adding prefixed classes, safe styles
- **Not Allowed**: Modifying existing text or attributes
- **Use When**: Adding badges, tooltips, or decorative elements

### 2. **moderate**
- **Purpose**: Allows limited modifications to existing elements
- **Allowed**: Everything from additive + title attribute
- **Not Allowed**: Text changes, color changes
- **Use When**: Adding accessibility improvements or metadata

### 3. **surgical**
- **Purpose**: Full control over content modification
- **Allowed**: Everything including setText, background/text colors
- **Required For**: Changing headlines, CTAs, or any text content
- **Use When**: A/B testing copy variations or personalizing content

## Anchor Selectors

Anchors define how to find elements in the DOM. The SDK supports four types:

### 1. CSS Selector
```json
{
  "by": "css",
  "value": "h1.hero-title"
}
```
- **Use**: Standard CSS selectors
- **Example**: `"h1"`, `".button-primary"`, `"#hero-section h2"`

### 2. Data Attribute
```json
{
  "by": "data",
  "key": "testid",
  "value": "hero-banner"  // optional
}
```
- **Use**: Target elements by data attributes
- **Example**: Finds `<div data-testid="hero-banner">`
- **Note**: If value is omitted, matches any element with that data attribute

### 3. ARIA Selector
```json
{
  "by": "aria",
  "role": "button",     // optional
  "label": "Submit"     // optional
}
```
- **Use**: Target accessible elements
- **Example**: Finds `<button role="button" aria-label="Submit">`
- **Note**: Can use role, label, or both

### 4. Element Reference
```json
{
  "by": "ref",
  "el": elementReference
}
```
- **Use**: Direct element reference (programmatic use only)
- **Note**: Cannot be serialized in JSON configs

## Operations

### 1. setText
**Purpose**: Replace the text content of an element
```json
{
  "kind": "setText",
  "text": "New headline text"
}
```
- **Requires**: `tier: "surgical"`
- **Effect**: Replaces all text content in the element
- **Common Use**: A/B testing headlines, CTAs, product descriptions
- **Note**: Removes all child elements, use carefully

### 2. setStyle
**Purpose**: Modify CSS styles on an element
```json
{
  "kind": "setStyle",
  "prop": "backgroundColor",
  "value": "#ff0000",
  "important": true  // optional, adds !important
}
```
- **Allowed Properties (any tier)**:
  - `outline`, `outlineColor`, `outlineWidth`, `outlineStyle`
  - `boxShadow`, `filter`
  - `scrollMargin` and related properties
  - CSS variables (`--custom-var`)
- **Additional Properties (surgical tier)**:
  - `backgroundColor`, `color`
- **Common Use**: Highlighting elements, adding visual emphasis
- **Note**: Value can be `null` to remove a style

### 3. addClass
**Purpose**: Add a CSS class to an element
```json
{
  "kind": "addClass",
  "className": "syntro-highlight"
}
```
- **Requirement**: Class must start with `syntro-`, `sc-`, or `sx-`
- **Common Use**: Apply pre-defined styles, mark elements
- **Note**: Won't add duplicate classes

### 4. removeClass
**Purpose**: Remove a CSS class from an element
```json
{
  "kind": "removeClass",
  "className": "syntro-hidden"
}
```
- **Requirement**: Can only remove prefixed classes
- **Common Use**: Revealing hidden elements, removing states
- **Note**: Safe if class doesn't exist

### 5. setAttr
**Purpose**: Set or remove HTML attributes
```json
{
  "kind": "setAttr",
  "name": "data-tracked",
  "value": "true"  // or null to remove
}
```
- **Allowed Attributes (any tier)**:
  - `data-*` (any data attribute)
  - `aria-*` (accessibility attributes)
  - `role`
- **Additional Attributes (moderate/surgical)**:
  - `title`
- **Common Use**: Tracking, accessibility improvements
- **Note**: Setting to `null` removes the attribute

### 6. append
**Purpose**: Add HTML content at the end of an element
```json
{
  "kind": "append",
  "html": "<span class='syntro-badge'>NEW</span>"
}
```
- **Effect**: Inserts after existing children
- **Common Use**: Adding badges, icons, supplementary content
- **Note**: HTML is sanitized for safety

### 7. prepend
**Purpose**: Add HTML content at the beginning of an element
```json
{
  "kind": "prepend",
  "html": "<span class='syntro-icon'>★</span>"
}
```
- **Effect**: Inserts before existing children
- **Common Use**: Adding icons, prefixes, notifications
- **Note**: HTML is sanitized for safety

### 8. insertAdjacent
**Purpose**: Insert HTML at specific positions relative to element
```json
{
  "kind": "insertAdjacent",
  "where": "afterbegin",
  "html": "<div class='syntro-alert'>Important!</div>"
}
```
- **Positions**:
  - `beforebegin`: Before the element itself
  - `afterbegin`: Inside element, before first child
  - `beforeend`: Inside element, after last child
  - `afterend`: After the element itself
- **Common Use**: Complex insertions, wrapping elements
- **Note**: More flexible than append/prepend

## Overlays

The SDK supports overlay elements that don't modify the DOM. These are defined in `overlayRecipe.steps`:

### Tooltips
Floating information bubbles that appear near target elements.

```json
{
  "kind": "tooltip",
  "id": "feature_tooltip_1",
  "anchor": {
    "by": "css",
    "value": ".pricing-card"
  },
  "content": {
    "title": "Best Value",
    "body": "This plan includes all features at the lowest per-user cost"
  },
  "placement": "top",
  "trigger": "hover",
  "ctaButtons": [
    {
      "label": "Learn More",
      "actionId": "learn_more_click"
    }
  ],
  "dismiss": {
    "onEsc": true,
    "closeButton": true
  }
}
```

**Properties:**
- `kind`: Must be `"tooltip"`
- `id`: Unique identifier for tracking
- `anchor`: Element selector (same as patches)
- `content.title`: Optional heading text
- `content.body`: Required tooltip body text
- `placement`: `"top"`, `"bottom"`, `"left"`, `"right"`, or `"auto"`
- `trigger`: `"immediate"`, `"hover"`, or `"click"`
- `offsetPx`: Distance from anchor element (optional)
- `blocking`: If true, blocks page interaction (optional)
- `ctaButtons`: Array of action buttons (optional)
- `dismiss.onEsc`: Close on Escape key
- `dismiss.closeButton`: Show X button
- `dismiss.timeoutMs`: Auto-dismiss after milliseconds

### Highlights
Visual emphasis rings that draw attention to elements.

```json
{
  "kind": "highlight",
  "id": "cta_highlight_1",
  "anchor": {
    "by": "css",
    "value": ".hero-cta button"
  },
  "copy": "Click here to get started",
  "ring": {
    "paddingPx": 8,
    "radiusPx": 4
  },
  "ringColor": "#3b82f6",
  "scrim": {
    "opacity": 0.5
  },
  "blocking": true,
  "dismiss": {
    "onClickOutside": true,
    "onEsc": true
  }
}
```

**Properties:**
- `kind`: Must be `"highlight"`
- `id`: Unique identifier for tracking
- `anchor`: Element selector (same as patches)
- `copy`: Text to display near the highlight (optional)
- `ring.paddingPx`: Space between element and ring
- `ring.radiusPx`: Corner radius of ring
- `ringColor`: Color of the highlight ring
- `scrim.opacity`: Opacity of background dimming (0-1)
- `blocking`: If true, blocks interaction outside highlight
- `dismiss.onClickOutside`: Close when clicking outside
- `dismiss.onEsc`: Close on Escape key
- `dismiss.timeoutMs`: Auto-dismiss after milliseconds

### Overlay Recipe Structure

Overlays are defined in `overlayRecipe`:

```json
{
  "overlayRecipe": {
    "id": "onboarding_flow",
    "version": 1,
    "routes": ["/dashboard", "/home"],
    "steps": [
      { "kind": "tooltip", ... },
      { "kind": "highlight", ... }
    ]
  }
}
```

- `id`: Recipe identifier
- `version`: Version number for tracking changes
- `routes`: URL paths where this recipe applies (optional)
- `steps`: Array of tooltip and highlight steps

## Best Practices

### 1. Element Selection
- Use the most specific selector that won't break
- Prefer data attributes over classes for stability
- Test selectors across different page states

### 2. Tier Selection
- Start with the lowest tier that works
- Only use `surgical` when modifying text
- Document why a specific tier is needed

### 3. Operation Order
- Operations are applied in array order
- Plan sequences carefully (e.g., addClass before setStyle)
- Test operation combinations

### 4. Performance
- Batch related patches together
- Avoid selecting too many elements
- Use CSS classes instead of inline styles when possible

### 5. Compatibility
- All HTML is sanitized to prevent XSS
- Classes must be prefixed to avoid conflicts
- Test across different browsers and devices

## Example: Complete A/B Test

```json
{
  "configVersion": "1.0",
  "patches": [
    {
      "id": "hero_headline_test",
      "anchor": {
        "by": "css",
        "value": "h1.hero-title"
      },
      "tier": "surgical",
      "operations": [
        {
          "kind": "setText",
          "text": "Start Your Free Trial Today"
        },
        {
          "kind": "addClass",
          "className": "syntro-tested"
        }
      ]
    },
    {
      "id": "cta_enhancement",
      "anchor": {
        "by": "data",
        "key": "testid",
        "value": "primary-cta"
      },
      "tier": "additive",
      "operations": [
        {
          "kind": "setStyle",
          "prop": "boxShadow",
          "value": "0 4px 6px rgba(0,0,0,0.1)"
        },
        {
          "kind": "append",
          "html": "<span class='syntro-arrow'>→</span>"
        }
      ]
    }
  ]
}
```

This example:
1. Changes the hero headline text (requires surgical tier)
2. Enhances the CTA button with shadow and an arrow icon (uses additive tier)
3. Properly tracks both changes with IDs