{"id":50909848,"url":"https://github.com/idev-games/state-js","last_synced_at":"2026-06-16T09:01:47.767Z","repository":{"id":360230082,"uuid":"1247774639","full_name":"iDev-Games/State-JS","owner":"iDev-Games","description":"State.js is a CSS‑reactive framework that makes UI state and updates flow through CSS instead of JavaScript logic.","archived":false,"fork":false,"pushed_at":"2026-06-10T22:18:10.000Z","size":5653,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-11T00:08:42.410Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://idev-games.github.io/State-JS/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iDev-Games.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-23T19:03:56.000Z","updated_at":"2026-06-10T22:16:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/iDev-Games/State-JS","commit_stats":null,"previous_names":["idev-games/state-js"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/iDev-Games/State-JS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iDev-Games%2FState-JS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iDev-Games%2FState-JS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iDev-Games%2FState-JS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iDev-Games%2FState-JS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iDev-Games","download_url":"https://codeload.github.com/iDev-Games/State-JS/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iDev-Games%2FState-JS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34398408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-16T09:01:45.854Z","updated_at":"2026-06-16T09:01:47.738Z","avatar_url":"https://github.com/iDev-Games.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# State.js\n\n![State.js Logo](logo.png)\n\n**State.js** is a CSS‑reactive framework that makes UI state and updates flow through CSS instead of JavaScript logic, enabling data‑driven animations and reactive UIs. Build dynamic, interactive interfaces using pure CSS and HTML.\n\n[![License](https://img.shields.io/badge/License-MIT-blue)](#license)\n![npm bundle size](https://img.shields.io/bundlephobia/min/%40idevgames%2Fstate-js)\n![npm](https://img.shields.io/npm/dy/%40idevgames%2Fstate-js?logo=NPM)\n![jsDelivr hits (npm)](https://img.shields.io/jsdelivr/npm/hm/%40idevgames%2Fstate-js)\n[![GitHub tag](https://img.shields.io/github/tag/iDev-Games/State-JS?include_prereleases=\u0026sort=semver\u0026color=blue)](https://github.com/iDev-Games/State-JS/releases/)\n\n---\n\n## What is State.js?\n\nState.js is a super simple, efficient and lightweight CSS framework that exposes DOM element states as CSS variables. Track data attributes, form inputs, media playback, and element visibility - all automatically exposed for use in your CSS animations and transitions.\n\n**A CSS-first approach to reactive interfaces.**\n\nUsing nothing but CSS, HTML and State.js, you can create:\n- 📊 Dynamic dashboards and data visualizations\n- 🎯 Interactive web applications with writing only CSS\n- 🎨 Data-driven animations in CSS\n- 🎮 Complex UIs (including game interfaces, health bars, score systems)\n\nState.js is really lightweight and created with vanilla JavaScript without requiring any dependencies. Perfect for CSS-first development and reactive UI patterns!\n\n---\n\n## Installation\n\n### Via NPM\n```bash\nnpm i @idevgames/state-js\n```\n\n### Via CDN\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/@idevgames/state-js/src/state.js\"\u003e\u003c/script\u003e\n```\n\n### Download Directly\nDownload [state.js](src/state.js) and include it in your project:\n```html\n\u003cscript src=\"/js/state.js\"\u003e\u003c/script\u003e\n```\n\n---\n\n## Quick Start\n\n### 1. Basic Element Visibility Tracking\n\nState.js automatically tracks when elements become visible:\n\n```html\n\u003cdiv class=\"fadeIn\" data-state\u003e\u003c/div\u003e\n```\n\n```css\n.fadeIn {\n    opacity: 0;\n}\n\n.fadeIn.state {\n    animation: fadeIn 1s forwards ease-in-out;\n}\n\n@keyframes fadeIn {\n    0% { opacity: 0; }\n    100% { opacity: 1; }\n}\n```\n\n### 2. Data Attribute Tracking (Progress Bars \u0026 Meters)\n\nWatch data attributes and expose them as CSS variables. Here's an example using a health bar (perfect for games, but works for any progress indicator):\n\n```html\n\u003cdiv id=\"player\"\n     data-state\n     data-state-watch=\"health,score\"\n     data-state-var=\"true\"\n     data-health=\"100\"\n     data-health-min=\"0\"\n     data-health-max=\"100\"\n     data-score=\"0\"\u003e\n\n    \u003cdiv class=\"health-bar\"\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\n```css\n#player .health-bar {\n    width: var(--state-health-percent);\n    background: linear-gradient(90deg, red 0%, yellow 50%, green 100%);\n}\n\n/* Automatically triggered animations */\n[data-health=\"0\"] {\n    animation: death 2s forwards;\n}\n\n[data-health=\"10\"],\n[data-health=\"20\"],\n[data-health=\"30\"] {\n    animation: pulse-red 1s infinite;\n}\n```\n\n**Update the state** by simply changing the data attribute:\n\n```javascript\n// Change health (State.js watches and updates CSS vars automatically)\ndocument.getElementById('player').setAttribute('data-health', '75');\n```\n\n### 3. Form Input Tracking with Auto-Binding\n\n**No JavaScript needed!** Automatically bind form inputs to update other elements:\n\n```html\n\u003c!-- Input automatically updates the healthBar element --\u003e\n\u003cinput type=\"range\"\n       id=\"healthSlider\"\n       data-state\n       data-state-bind=\"healthBar\"\n       data-state-attr=\"health\"\n       min=\"0\"\n       max=\"100\"\n       value=\"75\"\u003e\n\n\u003c!-- This element auto-updates when slider changes --\u003e\n\u003cdiv id=\"healthBar\"\n     data-state\n     data-state-watch=\"health\"\n     data-health=\"75\"\u003e\n\n    \u003cdiv class=\"bar\" style=\"width: var(--state-health-percent)\"\u003e\u003c/div\u003e\n    \u003cspan data-state-display=\"health\"\u003e75\u003c/span\u003e\n\u003c/div\u003e\n```\n\n**Bind to multiple elements** (comma-separated):\n\n```html\n\u003cinput data-state-bind=\"player,enemyHealthBar,scoreDisplay\" data-state-attr=\"health\"\u003e\n```\n\n### 4. Button Triggers (No JavaScript!)\n\n**Make any element clickable to control state:**\n\n```html\n\u003c!-- Player with power-up state --\u003e\n\u003cdiv id=\"player\"\n     data-state\n     data-state-toggles=\"powered\"\n     data-powered=\"false\"\u003e\n    Player Character\n\u003c/div\u003e\n\n\u003c!-- Button that toggles the power-up on/off --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-toggle=\"powered\"\u003e\n    Toggle Power-Up\n\u003c/button\u003e\n\n\u003c!-- Button that sets health to a specific value --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"health\"\n        data-state-value=\"100\"\u003e\n    Full Health\n\u003c/button\u003e\n\n\u003c!-- Button that increments score by 10 (perfect for clickers!) --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"score\"\n        data-state-increment=\"10\"\u003e\n    Add 10 Points\n\u003c/button\u003e\n```\n\n**Trigger Modes:**\n\n- **Toggle:** `data-state-toggle=\"attribute\"` - Flips between true/false\n- **Set:** `data-state-attr=\"attribute\"` + `data-state-value=\"value\"` - Sets specific value\n- **Increment:** `data-state-attr=\"attribute\"` + `data-state-increment=\"amount\"` - Adds to current value\n- **Decrement:** `data-state-attr=\"attribute\"` + `data-state-decrement=\"amount\"` - Subtracts from current value\n\n**Advanced: Dynamic Calculations**\n\nBoth increment and decrement support `calc()` expressions with CSS variables:\n\n```html\n\u003c!-- Static increment --\u003e\n\u003cbutton data-state-increment=\"10\"\u003eAdd 10\u003c/button\u003e\n\n\u003c!-- Dynamic: increment scales with level --\u003e\n\u003cbutton data-state-increment=\"calc(var(--state-level) * 5)\"\u003e\n    Level-scaled Click\n\u003c/button\u003e\n\n\u003c!-- Dynamic: cost increases with score --\u003e\n\u003cbutton data-state-increment=\"calc(1 + var(--state-score) * 0.1)\"\u003e\n    Increasing Returns\n\u003c/button\u003e\n```\n\n**Both increment and decrement automatically respect `data-[attr]-min` and `data-[attr]-max` bounds!**\n\n**Conditional Triggers:**\n\nUse `data-state-condition` to only execute operations when a condition is met (perfect for costs, requirements, unlock systems):\n\n```html\n\u003c!-- Only works if score \u003e= 20 --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"level\"\n        data-state-increment=\"1\"\n        data-state-condition=\"score \u003e= 20\"\u003e\n    Level Up (costs 20)\n\u003c/button\u003e\n\n\u003c!-- Complex conditions with AND/OR --\u003e\n\u003cbutton data-state-condition=\"gold \u003e= 100 and level \u003c 10\"\u003e\n    Affordable Upgrade\n\u003c/button\u003e\n\n\u003c!-- Multiple attributes --\u003e\n\u003cbutton data-state-condition=\"health \u003e 0 and mana \u003e= 50\"\u003e\n    Cast Spell\n\u003c/button\u003e\n```\n\nWhen a condition fails, the button gets the `state-disabled` class automatically! Style it with CSS:\n\n```css\n.state-disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n    pointer-events: none;\n}\n```\n\n**Chaining Multiple Operations:**\n\nUse `data-state-trigger-chain` to perform multiple operations sequentially (perfect for complex game mechanics):\n\n```html\n\u003c!-- Level up button that both spends gold AND increases level --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-condition=\"gold \u003e= 100\"\n        data-state-trigger-chain=\"spendGold,gainLevel\"\u003e\n    Level Up (costs 100 gold)\n\u003c/button\u003e\n\n\u003c!-- Hidden trigger: deduct gold --\u003e\n\u003cbutton id=\"spendGold\"\n        data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"gold\"\n        data-state-decrement=\"100\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n\n\u003c!-- Hidden trigger: add level --\u003e\n\u003cbutton id=\"gainLevel\"\n        data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"level\"\n        data-state-increment=\"1\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n```\n\n**Auto-firing Triggers:**\n\nUse `data-state-autofire=\"true\"` to automatically fire a trigger whenever its condition becomes true (perfect for passive income, auto-unlocks, achievements, and automatic progression):\n\n```html\n\u003c!-- Passive income: auto-collect gold whenever it reaches 10 --\u003e\n\u003cbutton id=\"autoCollect\"\n        data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"gold\"\n        data-state-decrement=\"10\"\n        data-state-condition=\"gold \u003e= 10\"\n        data-state-autofire=\"true\"\n        data-state-trigger-chain=\"addScore\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n\n\u003cbutton id=\"addScore\"\n        data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"score\"\n        data-state-increment=\"10\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n\n\u003c!-- Auto-unlock: automatically upgrade when level reaches 5 --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"upgraded\"\n        data-state-set=\"true\"\n        data-state-condition=\"level \u003e= 5\"\n        data-state-autofire=\"true\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n\n\u003c!-- Achievement system: auto-trigger when condition met --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"achievements\"\n        data-state-attr=\"firstWin\"\n        data-state-set=\"true\"\n        data-state-condition=\"wins \u003e= 1\"\n        data-state-autofire=\"true\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n```\n\nThe magic: When the condition transitions from `false` → `true`, the trigger fires automatically! No click required. No visibility required. **This is the missing primitive for automatic game mechanics.**\n\n**Works with any element:**\n\n```html\n\u003cdiv data-state-trigger data-state-bind=\"player\" data-state-toggle=\"shielded\"\u003e\n    Click me to toggle shield!\n\u003c/div\u003e\n```\n\n---\n\n## New in v1.1.0: Seven Game Development Extensions\n\nState.js v1.1.0 adds seven powerful declarative primitives specifically designed for game development and interactive experiences. Build complete games with **zero hand-written JavaScript logic**.\n\n### 1. data-state-interval — Repeating Timer Triggers\n\nAutomatically fire triggers at regular intervals (perfect for passive income, cooldowns, game ticks):\n\n```html\n\u003c!-- Passive gold income: +1 gold every second --\u003e\n\u003cbutton id=\"passiveGold\"\n        data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"gold\"\n        data-state-increment=\"1\"\n        data-state-interval=\"1000\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n\n\u003c!-- Health regeneration: +5 HP every 2 seconds (only if alive) --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"health\"\n        data-state-increment=\"5\"\n        data-state-interval=\"2000\"\n        data-state-condition=\"health \u003e 0 and health \u003c 100\"\n        style=\"display:none\"\u003e\n\u003c/button\u003e\n```\n\n**How it works:**\n- Fires the trigger automatically every N milliseconds\n- Respects `data-state-condition` (won't fire if condition is false)\n- Uses a single efficient shared scheduler for all interval triggers\n- Perfect for idle games, passive effects, and time-based mechanics\n\n### 2. data-state-set — Set Exact Value\n\nSet an attribute to an exact value (unlike increment/decrement). Supports `calc()` expressions:\n\n```html\n\u003c!-- Reset health to full --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"health\"\n        data-state-set=\"100\"\u003e\n    Full Heal\n\u003c/button\u003e\n\n\u003c!-- Set mana to half of max --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"mana\"\n        data-state-set=\"calc(var(--state-manamax) / 2)\"\u003e\n    Restore 50% Mana\n\u003c/button\u003e\n\n\u003c!-- Level-scaled restore --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"gold\"\n        data-state-set=\"calc(var(--state-level) * 100)\"\u003e\n    Set Gold to Level × 100\n\u003c/button\u003e\n```\n\n**Use cases:**\n- Reset/restore mechanics\n- Level-scaled rewards\n- Percentage-based calculations\n- Achievement unlocks (set boolean flags)\n\n### 3. data-state-text — Template String Interpolation\n\nDisplay dynamic text using {token} syntax that updates automatically:\n\n```html\n\u003cdiv id=\"player\"\n     data-state\n     data-state-watch=\"level,health,healthmax,gold\"\n     data-level=\"1\"\n     data-health=\"100\"\n     data-healthmax=\"100\"\n     data-gold=\"0\"\u003e\n\u003c/div\u003e\n\n\u003c!-- Text updates automatically when attributes change --\u003e\n\u003ch1 data-state\n    data-state-bind=\"player\"\n    data-state-text=\"Level {level} Hero\"\u003e\n\u003c/h1\u003e\n\n\u003cp data-state\n   data-state-bind=\"player\"\n   data-state-text=\"HP: {health}/{healthmax}\"\u003e\n\u003c/p\u003e\n\n\u003cdiv data-state\n     data-state-bind=\"player\"\n     data-state-text=\"Gold: {gold} | Level: {level}\"\u003e\n\u003c/div\u003e\n\n\u003c!-- Works with any attribute --\u003e\n\u003cspan data-state\n      data-state-bind=\"player\"\n      data-state-text=\"You have {gold} gold coins!\"\u003e\n\u003c/span\u003e\n```\n\n**How it works:**\n- Replaces `{attributeName}` tokens with current attribute values\n- Updates automatically when any referenced attribute changes\n- Supports multiple tokens in one template\n- No manual display element management required\n\n### 4. data-state-class — Conditional CSS Classes\n\nDynamically add/remove CSS classes based on conditions:\n\n```html\n\u003c!-- Add 'critical' class when health is low --\u003e\n\u003cdiv id=\"healthBar\"\n     data-state\n     data-state-bind=\"player\"\n     data-state-class=\"critical\"\n     data-state-class-condition=\"health \u003c= 20\"\u003e\n\u003c/div\u003e\n\n\u003c!-- Multiple conditional classes using numbered suffixes --\u003e\n\u003cdiv id=\"player\"\n     data-state\n     data-state-bind=\"game\"\n     data-state-class=\"low-health\"\n     data-state-class-condition=\"health \u003c= 30\"\n     data-state-class-2=\"powered-up\"\n     data-state-class-condition-2=\"powerup == true\"\n     data-state-class-3=\"max-level\"\n     data-state-class-condition-3=\"level \u003e= 99\"\u003e\n\u003c/div\u003e\n\n\u003c!-- Style the classes in CSS --\u003e\n\u003cstyle\u003e\n.critical {\n    animation: critical-pulse 0.5s infinite;\n    border: 3px solid red;\n}\n\n.low-health {\n    filter: hue-rotate(180deg);\n}\n\n.powered-up {\n    box-shadow: 0 0 20px gold;\n    animation: glow 1s infinite;\n}\n\n.max-level {\n    background: linear-gradient(45deg, gold, orange);\n}\n\u003c/style\u003e\n```\n\n**Features:**\n- Supports up to 10 class/condition pairs per element (use `-2`, `-3`, etc.)\n- Classes add/remove automatically when conditions change\n- Perfect for visual state feedback\n- Works with any CSS animations or effects\n\n### 5. data-state-sound — Procedural Sound Effects\n\nPlay procedurally generated Web Audio sounds on trigger clicks (no audio files needed!):\n\n```html\n\u003c!-- Built-in sounds: click, levelup, buy, error, coin --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"score\"\n        data-state-increment=\"1\"\n        data-state-sound=\"click\"\u003e\n    Click (+1 score)\n\u003c/button\u003e\n\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"level\"\n        data-state-increment=\"1\"\n        data-state-sound=\"levelup\"\n        data-state-condition=\"xp \u003e= 100\"\u003e\n    Level Up!\n\u003c/button\u003e\n\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"shop\"\n        data-state-attr=\"gold\"\n        data-state-decrement=\"50\"\n        data-state-sound=\"buy\"\n        data-state-condition=\"gold \u003e= 50\"\u003e\n    Buy Item (50g)\n\u003c/button\u003e\n\n\u003c!-- Error sound when clicking disabled buttons --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-sound=\"error\"\n        data-state-condition=\"gold \u003e= 1000\"\u003e\n    Expensive Item (1000g)\n\u003c/button\u003e\n\n\u003c!-- Coin pickup sound --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"gold\"\n        data-state-increment=\"10\"\n        data-state-sound=\"coin\"\u003e\n    Collect Gold\n\u003c/button\u003e\n```\n\n**Built-in sounds:**\n- **click** - 80ms sawtooth beep (UI feedback)\n- **levelup** - 3-note arpeggio C4→E4→G4 (achievements)\n- **buy** - 100ms sine tone at 600Hz (purchases)\n- **error** - 80ms square wave at 120Hz (failures)\n- **coin** - Rising pitch 880→1200Hz (pickups)\n\n**Features:**\n- Zero external dependencies (uses Web Audio API)\n- Procedurally generated (no audio files to load)\n- Plays on trigger click before executing the action\n- Respects browser autoplay policies\n\n### 6. data-state-persist — localStorage Save/Restore\n\nAutomatically save and restore state to localStorage:\n\n```html\n\u003cdiv id=\"gameState\"\n     data-state\n     data-state-watch=\"level,gold,health,xp\"\n     data-state-persist=\"true\"\n     data-state-persist-key=\"my-game-save\"\n     data-level=\"1\"\n     data-gold=\"0\"\n     data-health=\"100\"\n     data-xp=\"0\"\u003e\n\u003c/div\u003e\n```\n\n**How it works:**\n- Automatically loads saved state on page load\n- Saves changes to localStorage with 500ms debounce (prevents excessive writes)\n- Saves all attributes listed in `data-state-watch`\n- Uses element ID as save key if `data-state-persist-key` not specified\n- Perfect for idle games, progress persistence, user preferences\n\n**Clear saved data:**\n```javascript\n// From browser console or your own JS:\nlocalStorage.removeItem('my-game-save');\n```\n\n### 7. data-state-event — CustomEvent Dispatch\n\nDispatch CustomEvents when triggers fire (perfect for external integrations, analytics, achievements):\n\n```html\n\u003c!-- Dispatch event when score increases --\u003e\n\u003cbutton data-state\n        data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"score\"\n        data-state-increment=\"10\"\n        data-state-event=\"score-increased\"\u003e\n    +10 Score\n\u003c/button\u003e\n\n\u003c!-- Listen to events in JavaScript --\u003e\n\u003cscript\u003e\ndocument.addEventListener('state:score-increased', (e) =\u003e {\n    console.log('Score changed!', e.detail);\n    // e.detail contains:\n    // {\n    //   element: \u003cthe trigger button\u003e,\n    //   attr: \"score\",\n    //   oldValue: \"0\",\n    //   newValue: \"10\",\n    //   boundId: \"player\"\n    // }\n});\n\n// Track level-ups\ndocument.addEventListener('state:level-up', (e) =\u003e {\n    // Send to analytics\n    gtag('event', 'level_up', { level: e.detail.newValue });\n});\n\n// Achievement tracking\ndocument.addEventListener('state:achievement-unlocked', (e) =\u003e {\n    showNotification(`Achievement unlocked: ${e.detail.attr}!`);\n});\n\u003c/script\u003e\n```\n\n**Use cases:**\n- Analytics integration\n- Achievement systems\n- External UI updates\n- Debug logging\n- Third-party integrations\n\n**Event naming:**\n- Event name is prefixed with `state:` (e.g., `data-state-event=\"win\"` → `state:win`)\n- Events bubble up the DOM\n- Not cancelable (fire-and-forget)\n\n---\n\n## Complete Game Example (All Declarative)\n\nCombining all extensions, here's a complete idle clicker game:\n\n```html\n\u003cdiv id=\"game\"\n     data-state\n     data-state-watch=\"gold,goldPerClick,goldPerSecond,level\"\n     data-state-persist=\"true\"\n     data-state-persist-key=\"idle-game-v1\"\n     data-gold=\"0\"\n     data-goldPerClick=\"1\"\n     data-goldPerSecond=\"0\"\n     data-level=\"1\"\u003e\n\n    \u003c!-- Display with template interpolation --\u003e\n    \u003ch1 data-state\n        data-state-bind=\"game\"\n        data-state-text=\"Level {level} Miner\"\u003e\n    \u003c/h1\u003e\n\n    \u003cp data-state\n       data-state-bind=\"game\"\n       data-state-text=\"Gold: {gold} | Per Click: {goldPerClick} | Per Second: {goldPerSecond}\"\u003e\n    \u003c/p\u003e\n\n    \u003c!-- Manual clicking --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"game\"\n            data-state-attr=\"gold\"\n            data-state-increment=\"calc(var(--state-goldPerClick))\"\n            data-state-sound=\"coin\"\n            data-state-event=\"gold-mined\"\u003e\n        Mine Gold\n    \u003c/button\u003e\n\n    \u003c!-- Upgrades with conditional classes --\u003e\n    \u003cbutton id=\"upgradeClick\"\n            data-state\n            data-state-trigger\n            data-state-bind=\"game\"\n            data-state-trigger-chain=\"payUpgrade,addPower\"\n            data-state-condition=\"gold \u003e= 50\"\n            data-state-sound=\"buy\"\n            data-state-class=\"affordable\"\n            data-state-class-condition=\"gold \u003e= 50\"\u003e\n        Upgrade Pickaxe (50g)\n    \u003c/button\u003e\n\n    \u003c!-- Hidden triggers for upgrade chain --\u003e\n    \u003cbutton id=\"payUpgrade\"\n            data-state-trigger\n            data-state-bind=\"game\"\n            data-state-attr=\"gold\"\n            data-state-decrement=\"50\"\n            style=\"display:none\"\u003e\n    \u003c/button\u003e\n\n    \u003cbutton id=\"addPower\"\n            data-state-trigger\n            data-state-bind=\"game\"\n            data-state-attr=\"goldPerClick\"\n            data-state-increment=\"1\"\n            style=\"display:none\"\u003e\n    \u003c/button\u003e\n\n    \u003c!-- Passive income with intervals --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"game\"\n            data-state-attr=\"gold\"\n            data-state-increment=\"calc(var(--state-goldPerSecond))\"\n            data-state-interval=\"1000\"\n            data-state-condition=\"goldPerSecond \u003e 0\"\n            style=\"display:none\"\u003e\n    \u003c/button\u003e\n\n    \u003c!-- Auto-level-up when gold reaches threshold --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"game\"\n            data-state-attr=\"level\"\n            data-state-increment=\"1\"\n            data-state-condition=\"gold \u003e= 500\"\n            data-state-autofire=\"true\"\n            data-state-sound=\"levelup\"\n            data-state-event=\"level-up\"\n            style=\"display:none\"\u003e\n    \u003c/button\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n/* Visual feedback with conditional classes */\n.affordable {\n    background: gold;\n    animation: pulse 0.5s infinite;\n}\n\n#game[data-level=\"10\"],\n#game[data-level=\"25\"],\n#game[data-level=\"50\"] {\n    animation: milestone-celebration 1s ease-out;\n}\n\u003c/style\u003e\n```\n\n**This game has:**\n- ✅ Manual clicking with dynamic rewards\n- ✅ Upgrade system with costs\n- ✅ Passive income ticking every second\n- ✅ Auto-level-up when reaching milestones\n- ✅ Sound effects for all actions\n- ✅ Visual feedback for affordability\n- ✅ Persistent save/load with localStorage\n- ✅ Event dispatch for analytics/achievements\n- ✅ **ZERO hand-written game logic JavaScript!**\n\n---\n\n## CSS Variables Created\n\nState.js automatically creates CSS variables based on your configuration:\n\n### Visibility \u0026 Position\n- `--state-visible` (0 or 1)\n- `--state-intersection` (0-100%)\n- `--state-viewport-x` (0-100%)\n- `--state-viewport-y` (0-100%)\n\n### Watched Data Attributes\nWhen using `data-state-watch=\"health,score,level\"`:\n\n- `--state-health` (raw value)\n- `--state-health-percent` (0-100%)\n- `--state-health-normalized` (0-1)\n- `--state-health-deg` (0-360deg)\n- `--state-health-reverse` (100%-0%)\n- `--state-score` (raw value)\n- `--state-level` (raw value)\n\n### Form Inputs\n- `--state-value` (current value)\n- `--state-value-percent` (percentage of range)\n- `--state-min`, `--state-max` (range bounds)\n\n### Media Elements\n- `--state-time` (current time)\n- `--state-progress` (0-100%)\n- `--state-playing` (0 or 1)\n- `--state-volume` (0-100)\n\n### Dimensions\n- `--state-width` (px)\n- `--state-height` (px)\n- `--state-aspect-ratio` (calculated)\n\n---\n\n## Data Attributes API\n\n### Activation\n```html\n\u003cdiv data-state\u003e\u003c/div\u003e\n\u003c!-- OR --\u003e\n\u003cdiv class=\"enable-state\"\u003e\u003c/div\u003e\n```\n\n### Configuration Attributes\n\n| Attribute | Description | Example |\n|-----------|-------------|---------|\n| `data-state-var=\"true\"` | Enable all CSS variables | `data-state-var=\"true\"` |\n| `data-state-watch=\"attr1,attr2\"` | Watch specific data attributes | `data-state-watch=\"health,mana,xp\"` |\n| `data-state-bind=\"id1,id2\"` | Auto-bind input to element IDs | `data-state-bind=\"player,enemy\"` |\n| `data-state-attr=\"attrName\"` | Which attribute to update when binding | `data-state-attr=\"health\"` |\n| `data-state-value=\"value\"` | Value to set when trigger is clicked (supports calc()) | `data-state-value=\"100\"` or `calc(var(--state-level) * 10)` |\n| `data-state-increment=\"amount\"` | Amount to add when trigger is clicked (supports calc(), respects min/max) | `data-state-increment=\"10\"` or `calc(var(--state-level) * 5)` |\n| `data-state-decrement=\"amount\"` | Amount to subtract when trigger is clicked (supports calc(), respects min/max) | `data-state-decrement=\"5\"` or `calc(var(--state-cost))` |\n| `data-state-trigger` | Make element clickable to trigger state changes | `data-state-trigger` |\n| `data-state-trigger-chain=\"id1,id2\"` | Click other triggers sequentially after this one | `data-state-trigger-chain=\"payCost,addLevel\"` |\n| `data-state-condition=\"expression\"` | Only execute if condition is true (adds `state-disabled` class when false) | `data-state-condition=\"score \u003e= 20\"` or `\"gold \u003e= 100 and level \u003c 10\"` |\n| `data-state-autofire=\"true\"` | Automatically fire trigger when condition becomes true (requires `data-state-condition`) | `data-state-autofire=\"true\"` |\n| `data-state-toggle=\"attrName\"` | Toggle boolean attribute on/off when clicked | `data-state-toggle=\"powered\"` |\n| `data-state-display=\"attrName\"` | Auto-display attribute value as text | `data-state-display=\"health\"` |\n| **NEW v1.1.0** | **Game Development Extensions** | |\n| `data-state-interval=\"ms\"` | Auto-fire trigger every N milliseconds (respects conditions) | `data-state-interval=\"1000\"` |\n| `data-state-set=\"value\"` | Set attribute to exact value (supports calc()) | `data-state-set=\"100\"` or `calc(var(--state-max))` |\n| `data-state-text=\"template\"` | Template string with expression support (v1.6.0: supports full expressions + string concat) | `data-state-text=\"{30 + (level - 1) * 10}hp\"` or `\"{health \u003e 0 ? health + 'hp' : 'DEAD'}\"` |\n| `data-state-compute=\"expr\"` | Computed attributes with expressions (v1.6.0: supports string concatenation) | `data-state-compute=\"label = hp + 'hp'; max = level * 100\"` |\n| `data-state-class=\"className\"` | Conditional CSS class application | `data-state-class=\"critical\"` |\n| `data-state-class-condition=\"expr\"` | Condition for class (use with data-state-class) | `data-state-class-condition=\"health \u003c= 20\"` |\n| `data-state-sound=\"soundName\"` | Play Web Audio sound on trigger (click, levelup, buy, error, coin) | `data-state-sound=\"coin\"` |\n| `data-state-persist=\"true\"` | Auto-save/restore to localStorage | `data-state-persist=\"true\"` |\n| `data-state-persist-key=\"key\"` | localStorage key (optional, defaults to element ID) | `data-state-persist-key=\"my-game\"` |\n| `data-state-event=\"eventName\"` | Dispatch CustomEvent as \"state:eventName\" | `data-state-event=\"score-up\"` |\n| **NEW v1.2.0** | **HTML Includes** | |\n| `data-state-include=\"path\"` | Fetch and inject HTML component from URL | `data-state-include=\"components/card.html\"` |\n| `data-state-toggles=\"attr1,attr2\"` | Boolean state toggles | `data-state-toggles=\"active,locked\"` |\n| `data-state-dimensions=\"true\"` | Track width/height | `data-state-dimensions=\"true\"` |\n| `data-state-media=\"true\"` | Track media playback | `data-state-media=\"true\"` |\n| `data-state-global=\"true\"` | Set CSS vars on `:root` | `data-state-global=\"true\"` |\n| `data-state-increment=\"10\"` | Update increment for selectors | `data-state-increment=\"10\"` |\n| **NEW v1.4.0** | **Event-Based Triggers** | |\n| `data-state-trigger-on=\"eventName\"` | Fire trigger on DOM event (default: \"click\") | `data-state-trigger-on=\"mouseenter\"` or `\"input\"` or `\"focus\"` |\n| `data-state-debounce=\"ms\"` | Delay trigger execution until events stop (in milliseconds) | `data-state-debounce=\"500\"` |\n| `data-state-throttle=\"ms\"` | Limit trigger firing rate (max once per N ms) | `data-state-throttle=\"200\"` |\n| **NEW v1.5.0** | **Instance Management** | |\n| `data-state-instantiate=\"id\"` | Clone element by ID and insert into DOM | `data-state-instantiate=\"enemy-template\"` |\n| `data-state-remove=\"selector\"` | Remove element(s) by ID or CSS selector | `data-state-remove=\".enemy\"` |\n| `data-state-target=\"selector\"` | Where to insert cloned element (default: body) | `data-state-target=\"#game\"` |\n| `data-state-insert=\"mode\"` | Insert mode: append, prepend, before, after | `data-state-insert=\"prepend\"` |\n| `data-state-set-*=\"value\"` | Override attribute on cloned element | `data-state-set-health=\"100\"` |\n| **NEW v1.5.1** | **Random Number Generation** | |\n| `data-state-random=\"max\"` | Generate random number (1 to max, dice shorthand) | `data-state-random=\"6\"` |\n| `data-state-random=\"min,max\"` | Generate random number (min to max, explicit range) | `data-state-random=\"0,100\"` |\n\n### Important Notes\n\n#### Data Attribute Naming (HTML Requirement)\n\n**All data attributes must be lowercase.** This is an HTML specification requirement, not a State.js limitation.\n\n```html\n\u003c!-- ✅ Correct: lowercase --\u003e\n\u003cdiv data-state-watch=\"health,mana\"\u003e\u003c/div\u003e\n\n\u003c!-- ❌ Wrong: will be lowercased by browser --\u003e\n\u003cdiv data-state-watch=\"Health,Mana\"\u003e\u003c/div\u003e  \u003c!-- becomes \"health,mana\" --\u003e\n```\n\nHTML automatically lowercases all attribute names. If you write `data-myAttribute`, the browser converts it to `data-myattribute`. State.js expects lowercase names throughout.\n\n#### Trigger Chain Atomicity\n\n**Trigger chains are not transactional.** If a link in the chain fails its condition, subsequent links still fire.\n\n```html\n\u003c!-- If link2 condition fails, link3 and link4 still execute --\u003e\n\u003cbutton data-state-trigger\n        data-state-trigger-chain=\"link1,link2,link3,link4\"\u003e\n\u003c/button\u003e\n```\n\nThis is intentional behavior. Each link in a chain is independent. If you need atomic transactions, use a single trigger with complex conditions instead of chains.\n\n#### data-state-value: Numeric and Boolean Duality\n\n**`data-state-value` works on both numeric attributes AND boolean toggles.** It writes the raw attribute directly, enabling idempotent state assignment (set to known state vs. blind toggle).\n\n```html\n\u003c!-- Numeric: Set exact value --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"health\"\n        data-state-value=\"100\"\u003e\n  Reset Health\n\u003c/button\u003e\n\n\u003c!-- Boolean: Set to known state (not toggle) --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"modal\"\n        data-state-attr=\"open\"\n        data-state-value=\"false\"\u003e\n  Close Modal (idempotent - always closed)\n\u003c/button\u003e\n```\n\nUse `data-state-toggle` for flip behavior, `data-state-value` for assignment.\n\n#### Autofire Edge Case\n\n**Autofire won't re-trigger if condition was already true at page load.**\n\n```html\n\u003c!-- If enemyHp is already 0 on page load, this won't fire --\u003e\n\u003cdiv data-state-trigger\n     data-state-condition=\"enemyHp == 0\"\n     data-state-autofire=\"true\"\n     data-state-trigger-chain=\"showVictory\"\u003e\n\u003c/div\u003e\n```\n\nAutofire detects when a condition *becomes* true (transitions from false→true). If the condition is already true at initialization, autofire won't trigger. Initialize your state values carefully to avoid this.\n\n#### Instantiate: Beyond Game Attributes\n\n**`data-state-set-*` works for display content, not just game attributes.** Use it to pass visual data (icons, labels, text) into templates.\n\n```html\n\u003c!-- Game attributes (common pattern) --\u003e\n\u003cbutton data-state-instantiate=\"enemy\"\n        data-state-set-health=\"100\"\n        data-state-set-damage=\"20\"\u003e\n\u003c/button\u003e\n\n\u003c!-- Display content (powerful, less obvious) --\u003e\n\u003cbutton data-state-instantiate=\"achievement-card\"\n        data-state-set-icon=\"🏆\"\n        data-state-set-title=\"First Victory\"\n        data-state-set-description=\"Defeated your first enemy\"\u003e\n  Unlock Achievement\n\u003c/button\u003e\n\n\u003c!-- Template uses data-state-display to show values --\u003e\n\u003ctemplate id=\"achievement-card\"\u003e\n  \u003cdiv class=\"card\"\u003e\n    \u003cspan data-state-display=\"icon\"\u003e\u003c/span\u003e\n    \u003ch3 data-state-display=\"title\"\u003e\u003c/h3\u003e\n    \u003cp data-state-display=\"description\"\u003e\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\nThis unlocks template use cases beyond game mechanics - UI cards, notifications, dynamic lists, etc.\n\n---\n\n### Per-State Configuration\n\n```html\n\u003cdiv data-state\n     data-state-watch=\"health\"\n     data-health=\"100\"\n     data-health-min=\"0\"\n     data-health-max=\"100\"\u003e\n\u003c/div\u003e\n```\n\n---\n\n## New in v1.2.0: HTML Includes\n\n**Build reusable, modular HTML components** - just like any modern framework, but with zero build tools.\n\nHTML Includes let you fetch and inject components declaratively. Create a component once, use it everywhere. Perfect for health bars, UI cards, player stats, inventory items, or any repeating UI pattern.\n\n### Basic Usage\n\n```html\n\u003c!-- From external file (cached after first load) --\u003e\n\u003cdiv data-state-include=\"components/health-bar.html\"\u003e\u003c/div\u003e\n\n\u003c!-- From inline template (instant, zero latency) --\u003e\n\u003cdiv data-state-include=\"#health-bar-template\"\u003e\u003c/div\u003e\n\n\u003c!-- Override component attributes --\u003e\n\u003cdiv data-state-include=\"components/health-bar.html\"\n     id=\"player-health\"\n     data-hp=\"75\"\n     data-hp-max=\"150\"\u003e\u003c/div\u003e\n\n\u003c!-- Element tag doesn't matter, gets replaced --\u003e\n\u003ci data-state-include=\"components/icon.html\"\u003e\u003c/i\u003e\n```\n\n### Creating a Component\n\n**Option 1: External File (for modularity)**\n\n**components/health-bar.html:**\n```html\n\u003cdiv class=\"health-bar\"\n     data-state\n     data-state-watch=\"hp\"\n     data-state-var=\"true\"\n     data-hp=\"100\"\n     data-hp-max=\"100\"\u003e\n    \u003cdiv class=\"fill\" style=\"width: var(--state-hp-percent); background: green; height: 20px;\"\u003e\u003c/div\u003e\n    \u003cspan data-state-display=\"hp\"\u003e\u003c/span\u003e\n\u003c/div\u003e\n```\n\n**Option 2: Inline Template (for performance)**\n\n```html\n\u003c!-- Define template once in your HTML --\u003e\n\u003ctemplate id=\"health-bar-template\"\u003e\n    \u003cdiv class=\"health-bar\"\n         data-state\n         data-state-watch=\"hp\"\n         data-state-var=\"true\"\n         data-hp=\"100\"\n         data-hp-max=\"100\"\u003e\n        \u003cdiv class=\"fill\" style=\"width: var(--state-hp-percent); background: green; height: 20px;\"\u003e\u003c/div\u003e\n        \u003cspan data-state-display=\"hp\"\u003e\u003c/span\u003e\n    \u003c/div\u003e\n\u003c/template\u003e\n\n\u003c!-- Use it anywhere (instant, no network request) --\u003e\n\u003cdiv data-state-include=\"#health-bar-template\" data-hp=\"75\"\u003e\u003c/div\u003e\n\u003cdiv data-state-include=\"#health-bar-template\" data-hp=\"50\"\u003e\u003c/div\u003e\n\u003cdiv data-state-include=\"#health-bar-template\" data-hp=\"100\"\u003e\u003c/div\u003e\n```\n\n### How It Works\n\n**Template Mode (`#id`):**\n1. **Clones** from `\u003ctemplate\u003e` tag or element by ID (instant, zero latency)\n2. **Merges** attributes from include element to cloned component\n3. **Replaces** include element with component\n4. **Initializes** State.js on the injected component\n\n**Fetch Mode (`path.html`):**\n1. **Fetches** HTML from URL (cached after first load)\n2. **Merges** attributes from include element to fetched component\n3. **Replaces** include element with component\n4. **Initializes** State.js on the injected component\n\nAll State.js features (triggers, persistence, intervals, sounds, etc.) work perfectly in included components!\n\n### Use Cases\n\n- **Health/Mana Bars** - Define once, use for player, enemies, NPCs\n- **Inventory Items** - Consistent item cards across inventory, shop, tooltip\n- **UI Cards** - Stat displays, achievement cards, notifications\n- **Player Stats** - Level, XP, gold displays\n- **Navigation** - Shared headers, footers, menus across pages\n\n### Configuration\n\n| Attribute | Description | Example |\n|-----------|-------------|---------|\n| `data-state-include=\"path.html\"` | Fetch and inject HTML from URL | `data-state-include=\"components/card.html\"` |\n| `data-state-include=\"#id\"` | Clone from template or element by ID | `data-state-include=\"#card-template\"` |\n\n**Note:** Any other attributes on the include element are copied to the injected component, allowing you to override default values.\n\n### Performance Strategy\n\n**Use templates (`#id`) for:**\n- Critical, frequently-used components (zero latency)\n- Components needed immediately on page load\n- Single-page apps where all components fit in initial HTML\n\n**Use files (`path.html`) for:**\n- Large component libraries (keeps HTML small)\n- Components used across multiple pages (modularity)\n- Production apps with proper HTTP caching\n\n**Local Development:** File-based includes require HTTP/HTTPS (browser security prevents `file://` fetching). Run any simple local server - Python's `python -m http.server`, Node's `npx http-server`, or VS Code Live Server. Template-based includes work anywhere, including `file://`!\n\n### Security Considerations\n\n⚠️ **Important**: For security, external file fetches are **disabled by default** in State.js v1.4.2+.\n\n**Template-based includes are always safe** and require no configuration:\n```html\n\u003cdiv data-state-include=\"#my-template\"\u003e\u003c/div\u003e \u003c!-- ✅ Always works --\u003e\n```\n\n**To enable external file fetches**:\n```javascript\n// Only enable if you trust the source AND use HTTPS\nstate.allowExternalIncludes = true;\n```\n\n**Security Best Practices**:\n\n1. **Prefer templates over external files** when possible\n2. **Use HTTPS only** - never fetch over HTTP\n3. **Same-origin policy** - fetch from your own domain\n4. **Content Security Policy** - add CSP headers to your server\n5. **DOMPurify (optional)** - for extra protection with external content:\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"state.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  // DOMPurify auto-detected and used if available\n  state.allowExternalIncludes = true;\n\u003c/script\u003e\n```\n\n**Attack Vectors to Avoid**:\n- ❌ User-controlled URLs: `data-state-include=\"${userInput}\"`\n- ❌ HTTP endpoints: `data-state-include=\"http://...\"`\n- ❌ Untrusted CDNs: `data-state-include=\"https://random-cdn.com/...\"`\n- ❌ Third-party domains without CORS/CSP protection\n\n**Why Template-Based Includes Are Secure**:\nTemplates (`#id`) are already in your HTML - if they're malicious, your page is already compromised. The security boundary is your deployment pipeline, not runtime injection.\n\n---\n\n## New in v1.3.0: Computed State \u0026 Debug API\n\n### Computed State\n\n**Automatically calculate derived values** from your data attributes - no manual updates needed!\n\nComputed state keeps calculated values in sync with their dependencies. Perfect for health percentages, damage calculations, level-up requirements, or any derived game logic.\n\n#### Basic Usage\n\n```html\n\u003cdiv id=\"player\"\n     data-state\n     data-state-watch=\"hp,maxHp\"\n     data-state-compute=\"hpPercent = hp / maxHp * 100\"\n     data-hp=\"75\"\n     data-maxHp=\"100\"\u003e\n\n    \u003cdiv class=\"health-bar\" style=\"width: var(--state-hpPercent)%;\"\u003e\u003c/div\u003e\n    \u003cspan\u003eHP: \u003cspan data-state-display=\"hpPercent\"\u003e\u003c/span\u003e%\u003c/span\u003e\n\u003c/div\u003e\n```\n\n#### Multiple Computations\n\nUse semicolons to define multiple computed values:\n\n```html\n\u003cdiv data-state\n     data-state-watch=\"hp,maxHp,level\"\n     data-state-compute=\"\n         hpPercent = hp / maxHp * 100;\n         isCritical = hp \u003c 20;\n         nextLevelXp = level * 100\n     \"\n     data-hp=\"15\"\n     data-maxHp=\"100\"\n     data-level=\"5\"\u003e\n\u003c/div\u003e\n```\n\n#### Supported Expressions\n\n- **Math operators**: `+`, `-`, `*`, `/`, `%`, `()`\n- **Comparisons**: `\u003c`, `\u003e`, `\u003c=`, `\u003e=`, `==`, `!=`\n- **Logical operators**: `\u0026\u0026`, `||`, `!`\n- **Ternary**: `condition ? valueA : valueB`\n- **Attribute references**: Use attribute names directly (e.g., `hp`, `maxHp`)\n\n#### Examples\n\n```html\n\u003c!-- Percentage calculation --\u003e\n\u003cdiv data-state-compute=\"progress = completed / total * 100\"\u003e\n\n\u003c!-- Ternary operator --\u003e\n\u003cdiv data-state-compute=\"status = hp \u003e 0 ? 'alive' : 'dead'\"\u003e\n\n\u003c!-- Complex formula --\u003e\n\u003cdiv data-state-compute=\"damage = (attack * 2) - defense\"\u003e\n\n\u003c!-- Boolean check --\u003e\n\u003cdiv data-state-compute=\"canLevelUp = xp \u003e= level * 100\"\u003e\n\n\u003c!-- Multiple dependencies --\u003e\n\u003cdiv data-state-compute=\"totalStats = strength + agility + intelligence\"\u003e\n\u003c/div\u003e\n```\n\n#### How It Works\n\n1. **Parse** - State.js parses your compute expressions on setup\n2. **Auto-update** - When any dependency changes, computed values recalculate automatically\n3. **Expose** - Computed values become `data-${name}` attributes and `--state-${name}` CSS variables\n4. **Display** - Use `data-state-display` to show computed values in your UI\n\n#### Use Cases\n\n- **Health/Mana percentages** for progress bars\n- **Damage calculations** for combat systems\n- **Level-up requirements** (XP needed, stats gained)\n- **Resource management** (inventory space, currency conversions)\n- **Status checks** (isCritical, canAfford, isComplete)\n- **Score calculations** (combos, multipliers, totals)\n\n---\n\n### Debug API\n\n**Console tools for inspecting and debugging reactive state** - perfect for development and testing.\n\nState.js provides a JavaScript API accessible via the browser console for debugging your application state.\n\n#### State.inspectAll()\n\nReturns an array of all reactive elements with their current state:\n\n```javascript\n// In browser console\nState.inspectAll()\n/* Returns:\n[\n  {\n    element: \u003cdiv id=\"player\"\u003e,\n    id: \"player\",\n    state: { hp: \"75\", maxHp: \"100\", hpPercent: \"75\" },\n    config: { ... }\n  },\n  ...\n]\n*/\n```\n\n#### State.inspect(selector)\n\nInspect a specific element's state:\n\n```javascript\nState.inspect('#player')\n/* Returns:\n{\n  element: \u003cdiv id=\"player\"\u003e,\n  id: \"player\",\n  state: { hp: \"75\", maxHp: \"100\", hpPercent: \"75\" },\n  config: { watchAttrs: [\"hp\", \"maxHp\"], ... }\n}\n*/\n```\n\n#### State.trace(attrName, enabled)\n\nEnable/disable console logging for attribute changes:\n\n```javascript\n// Enable tracing for HP changes\nState.trace('hp', true)\n// Now every time data-hp changes, you'll see:\n// State.js [hp]: { element: \u003cdiv\u003e, id: \"player\", attribute: \"hp\", oldValue: \"75\", newValue: \"65\" }\n\n// Disable tracing\nState.trace('hp', false)\n```\n\n#### Usage Examples\n\n```javascript\n// Debug all reactive elements\nconst elements = State.inspectAll()\nconsole.table(elements.map(e =\u003e e.state))\n\n// Check specific element state\nconst player = State.inspect('#player')\nconsole.log('Player HP:', player.state.hp)\n\n// Trace multiple attributes\nState.trace('hp')\nState.trace('gold')\nState.trace('xp')\n// Now see all changes to hp, gold, and xp in real-time\n\n// Find elements with low HP\nState.inspectAll()\n  .filter(e =\u003e parseFloat(e.state.hp) \u003c 20)\n  .forEach(e =\u003e console.log(`${e.id} is critical!`))\n```\n\n#### Use Cases\n\n- **Debugging** - See all state changes in real-time\n- **Testing** - Verify attribute values during development\n- **Optimization** - Track which attributes update frequently\n- **Learning** - Understand how State.js works internally\n\n---\n\n## New in v1.4.0: Event-Based Triggers\n\n**Fire triggers on ANY DOM event** - not just clicks! Listen to hover, focus, input, scroll, and more with built-in debounce/throttle support.\n\nEvent-based triggers let you respond to any DOM event declaratively. Perfect for form interactions, hover effects, scroll tracking, visibility detection, and real-time input validation - all without writing JavaScript event listeners.\n\n### Basic Usage\n\nUse `data-state-trigger-on` to specify which event should fire the trigger:\n\n```html\n\u003c!-- Default: click (backward compatible) --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"score\"\n        data-state-increment=\"1\"\u003e\n    Click to score\n\u003c/button\u003e\n\n\u003c!-- Explicit click --\u003e\n\u003cbutton data-state-trigger\n        data-state-trigger-on=\"click\"\n        data-state-bind=\"player\"\n        data-state-attr=\"score\"\n        data-state-increment=\"1\"\u003e\n    Click to score\n\u003c/button\u003e\n\n\u003c!-- Hover to increment --\u003e\n\u003cdiv data-state-trigger\n     data-state-trigger-on=\"mouseenter\"\n     data-state-bind=\"stats\"\n     data-state-attr=\"hovers\"\n     data-state-increment=\"1\"\u003e\n    Hover over me!\n\u003c/div\u003e\n\n\u003c!-- Fire on focus --\u003e\n\u003cinput data-state-trigger\n       data-state-trigger-on=\"focus\"\n       data-state-bind=\"form\"\n       data-state-attr=\"activeField\"\n       data-state-set=\"username\"\u003e\n\n\u003c!-- Fire on form submission --\u003e\n\u003cform data-state-trigger\n      data-state-trigger-on=\"submit\"\n      data-state-bind=\"stats\"\n      data-state-attr=\"submits\"\n      data-state-increment=\"1\"\u003e\n    \u003c!-- Form automatically prevents page reload --\u003e\n    \u003cinput type=\"text\" name=\"username\"\u003e\n    \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\n\n### Supported Events\n\n**Mouse Events:**\n- `click` - Default trigger behavior\n- `dblclick` - Double-click\n- `mouseenter` - Mouse enters element\n- `mouseleave` - Mouse leaves element\n- `mouseover` - Mouse moves over element\n- `mouseout` - Mouse moves out of element\n\n**Form Events:**\n- `input` - Text input, range slider changes (fires on every keystroke)\n- `change` - Select dropdowns, checkboxes, radio buttons (fires on blur/commit)\n- `focus` - Element gains focus\n- `blur` - Element loses focus\n- `submit` - Form submission (automatically calls `preventDefault()`)\n\n**Keyboard Events:**\n- `keydown` - Key is pressed down\n- `keyup` - Key is released\n- `keypress` - Key is pressed (deprecated but supported)\n\n**Scroll Events:**\n- `scroll` - Element scrolls (use with throttle!)\n\n**Custom Events:**\n- `intersect` - Element becomes visible (custom event from IntersectionObserver)\n- Any CustomEvent dispatched via JavaScript\n\n### Debounce (Delay After Rapid Events)\n\nUse `data-state-debounce` to delay execution until events stop firing:\n\n```html\n\u003c!-- Search input: only fire 300ms after user stops typing --\u003e\n\u003cinput type=\"text\"\n       data-state-trigger\n       data-state-trigger-on=\"input\"\n       data-state-debounce=\"300\"\n       data-state-bind=\"search\"\n       data-state-attr=\"query\"\n       data-state-increment=\"1\"\u003e\n\n\u003c!-- Resize handler: only fire 500ms after window stops resizing --\u003e\n\u003cdiv data-state-trigger\n     data-state-trigger-on=\"resize\"\n     data-state-debounce=\"500\"\n     data-state-bind=\"layout\"\n     data-state-attr=\"width\"\n     data-state-set=\"calc(100)\"\u003e\n\u003c/div\u003e\n```\n\n**How debounce works:**\n1. Event fires (e.g., user types a character)\n2. Timer starts counting down from specified ms\n3. If another event fires before timer completes, reset the timer\n4. When timer completes without interruption, execute trigger\n5. **Use for:** Text input, resize, autocomplete, validation\n\n### Throttle (Limit Firing Rate)\n\nUse `data-state-throttle` to limit how often a trigger can fire:\n\n```html\n\u003c!-- Scroll tracking: fire at most once per 200ms (5x/second max) --\u003e\n\u003cdiv data-state-trigger\n     data-state-trigger-on=\"scroll\"\n     data-state-throttle=\"200\"\n     data-state-bind=\"stats\"\n     data-state-attr=\"scrolls\"\n     data-state-increment=\"1\"\n     style=\"height: 200px; overflow-y: scroll;\"\u003e\n    \u003cdiv style=\"height: 1000px;\"\u003eScroll content...\u003c/div\u003e\n\u003c/div\u003e\n\n\u003c!-- Mouse tracking: limit to 100ms (10x/second max) --\u003e\n\u003cdiv data-state-trigger\n     data-state-trigger-on=\"mousemove\"\n     data-state-throttle=\"100\"\n     data-state-bind=\"cursor\"\n     data-state-attr=\"moves\"\n     data-state-increment=\"1\"\u003e\n    Track mouse movement\n\u003c/div\u003e\n```\n\n**How throttle works:**\n1. Event fires and trigger executes immediately\n2. Start cooldown timer for specified ms\n3. Any events during cooldown are ignored\n4. After cooldown completes, next event can fire\n5. **Use for:** Scroll, mousemove, resize, frequent events\n\n**Debounce vs Throttle:**\n- **Debounce:** Wait until activity stops → fires once at the end\n- **Throttle:** Fire regularly during activity → fires multiple times at limited rate\n\n### Visibility Detection\n\nThe `intersect` event fires when an element enters the viewport:\n\n```html\n\u003c!-- Track when user scrolls element into view --\u003e\n\u003cdiv data-state-trigger\n     data-state-trigger-on=\"intersect\"\n     data-state-bind=\"analytics\"\n     data-state-attr=\"views\"\n     data-state-increment=\"1\"\u003e\n    Content that tracks visibility\n\u003c/div\u003e\n\n\u003c!-- Lazy-load content --\u003e\n\u003cdiv data-state-trigger\n     data-state-trigger-on=\"intersect\"\n     data-state-bind=\"lazySection\"\n     data-state-attr=\"loaded\"\n     data-state-set=\"true\"\u003e\n    \u003c!-- Fires once when scrolled into view --\u003e\n\u003c/div\u003e\n```\n\n**How it works:**\n- State.js uses IntersectionObserver to track visibility\n- When element becomes visible for the first time, dispatches `intersect` CustomEvent\n- Trigger fires and can update state, trigger chains, play sounds, etc.\n- **Use for:** Analytics, lazy loading, scroll-triggered animations, achievement tracking\n\n### Form Auto-Submit Prevention\n\nForm `submit` events automatically call `preventDefault()` to prevent page reload:\n\n```html\n\u003cform id=\"contactForm\"\n      data-state\n      data-state-watch=\"submits\"\n      data-submits=\"0\"\u003e\n\n    \u003cinput type=\"text\" name=\"email\" required\u003e\n\n    \u003c!-- Submit increments counter WITHOUT reloading page --\u003e\n    \u003cbutton type=\"submit\"\n            data-state-trigger\n            data-state-trigger-on=\"submit\"\n            data-state-bind=\"contactForm\"\n            data-state-attr=\"submits\"\n            data-state-increment=\"1\"\n            data-state-sound=\"buy\"\n            data-state-event=\"form-submitted\"\u003e\n        Submit\n    \u003c/button\u003e\n\u003c/form\u003e\n\n\u003cp\u003eSubmissions: \u003cspan data-state-display=\"submits\"\u003e0\u003c/span\u003e\u003c/p\u003e\n```\n\n**No JavaScript required!** The form won't reload the page - State.js handles it automatically.\n\n### Combining with Conditions\n\nEvent triggers respect `data-state-condition` just like click triggers:\n\n```html\n\u003cdiv id=\"game\"\n     data-state\n     data-state-watch=\"gold,active\"\n     data-state-toggles=\"active\"\n     data-gold=\"0\"\n     data-active=\"false\"\u003e\n\n    \u003c!-- Only track hovers when game is active --\u003e\n    \u003cdiv data-state-trigger\n         data-state-trigger-on=\"mouseenter\"\n         data-state-condition=\"active == true\"\n         data-state-bind=\"game\"\n         data-state-attr=\"gold\"\n         data-state-increment=\"1\"\u003e\n        Hover to collect gold (only when active)\n    \u003c/div\u003e\n\n    \u003c!-- Only track input when game is active --\u003e\n    \u003cinput data-state-trigger\n           data-state-trigger-on=\"input\"\n           data-state-debounce=\"500\"\n           data-state-condition=\"active == true\"\n           data-state-bind=\"game\"\n           data-state-attr=\"gold\"\n           data-state-increment=\"5\"\u003e\n\u003c/div\u003e\n```\n\n**Result:** Triggers are disabled (get `state-disabled` class) when condition is false, just like click triggers!\n\n### Real-World Examples\n\n#### Live Search Counter\n\n```html\n\u003cdiv id=\"search\"\n     data-state\n     data-state-watch=\"queries\"\n     data-queries=\"0\"\u003e\n\n    \u003c!-- Debounced search: only counts after user stops typing --\u003e\n    \u003cinput type=\"text\"\n           placeholder=\"Search...\"\n           data-state-trigger\n           data-state-trigger-on=\"input\"\n           data-state-debounce=\"500\"\n           data-state-bind=\"search\"\n           data-state-attr=\"queries\"\n           data-state-increment=\"1\"\n           data-state-event=\"search-query\"\u003e\n\n    \u003cp\u003eSearches performed: \u003cspan data-state-display=\"queries\"\u003e0\u003c/span\u003e\u003c/p\u003e\n\u003c/div\u003e\n```\n\n#### Scroll Progress Tracker\n\n```html\n\u003cdiv id=\"article\"\n     data-state\n     data-state-watch=\"scrollEvents\"\n     data-scrollEvents=\"0\"\u003e\n\n    \u003cdiv class=\"content\"\n         data-state-trigger\n         data-state-trigger-on=\"scroll\"\n         data-state-throttle=\"200\"\n         data-state-bind=\"article\"\n         data-state-attr=\"scrollEvents\"\n         data-state-increment=\"1\"\n         style=\"height: 300px; overflow-y: scroll;\"\u003e\n        \u003cdiv style=\"height: 2000px;\"\u003eLong scrollable content...\u003c/div\u003e\n    \u003c/div\u003e\n\n    \u003cp\u003eScroll events: \u003cspan data-state-display=\"scrollEvents\"\u003e0\u003c/span\u003e\u003c/p\u003e\n\u003c/div\u003e\n```\n\n#### Form Field Tracking\n\n```html\n\u003cdiv id=\"formTracking\"\n     data-state\n     data-state-watch=\"focusCount,changes\"\n     data-focusCount=\"0\"\n     data-changes=\"0\"\u003e\n\n    \u003c!-- Track focus --\u003e\n    \u003cinput type=\"text\"\n           placeholder=\"Username\"\n           data-state-trigger\n           data-state-trigger-on=\"focus\"\n           data-state-bind=\"formTracking\"\n           data-state-attr=\"focusCount\"\n           data-state-increment=\"1\"\u003e\n\n    \u003c!-- Track changes --\u003e\n    \u003cselect data-state-trigger\n            data-state-trigger-on=\"change\"\n            data-state-bind=\"formTracking\"\n            data-state-attr=\"changes\"\n            data-state-increment=\"1\"\u003e\n        \u003coption\u003eOption 1\u003c/option\u003e\n        \u003coption\u003eOption 2\u003c/option\u003e\n    \u003c/select\u003e\n\n    \u003cp\u003eFields focused: \u003cspan data-state-display=\"focusCount\"\u003e0\u003c/span\u003e\u003c/p\u003e\n    \u003cp\u003eChanges made: \u003cspan data-state-display=\"changes\"\u003e0\u003c/span\u003e\u003c/p\u003e\n\u003c/div\u003e\n```\n\n### Use Cases\n\n**Event-based triggers are perfect for:**\n- 📝 Live search/autocomplete (input + debounce)\n- 📊 Analytics tracking (focus, scroll, visibility)\n- 🎯 Hover effects and interactions (mouseenter/leave)\n- 📋 Form validation and submission (submit, change, blur)\n- 📜 Scroll progress indicators (scroll + throttle)\n- 👀 Lazy loading and content reveal (intersect)\n- ⌨️ Keyboard shortcut tracking (keydown/up)\n- 🎮 Interactive games (mousemove, keypress)\n- 📱 Mobile gesture tracking (with Touch.js integration)\n\n### Performance Tips\n\n1. **Always throttle scroll and mousemove events** (100-200ms recommended)\n2. **Debounce text input** for search/autocomplete (300-500ms recommended)\n3. **Use intersect for lazy loading** instead of scroll events\n4. **Combine with conditions** to disable triggers when not needed\n5. **Prefer change over input** for dropdowns/checkboxes (fires less frequently)\n\n### Configuration\n\n| Attribute | Description | Example |\n|-----------|-------------|---------|\n| `data-state-trigger-on=\"eventName\"` | Which DOM event fires the trigger (default: \"click\") | `data-state-trigger-on=\"mouseenter\"` |\n| `data-state-debounce=\"ms\"` | Delay trigger execution until events stop (in milliseconds) | `data-state-debounce=\"500\"` |\n| `data-state-throttle=\"ms\"` | Limit trigger firing rate (max once per N milliseconds) | `data-state-throttle=\"200\"` |\n\n**Special behaviors:**\n- `submit` events automatically call `event.preventDefault()`\n- `intersect` is a custom event fired by IntersectionObserver\n- `click` is the default if `data-state-trigger-on` is omitted\n- Triggers with `trigger-on=\"click\"` still get `cursor: pointer` style\n\n---\n\n## New in v1.5.0: Instance Management\n\nDynamically create and remove DOM elements using declarative triggers - perfect for spawning enemies, creating projectiles, managing inventory items, and building dynamic UI systems.\n\n### Basic Instantiation\n\nClone any element by ID and insert it into the DOM:\n\n```html\n\u003c!-- Spawn button --\u003e\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"enemy-template\"\n        data-state-target=\"#game\"\n        data-state-insert=\"append\"\u003e\n  Spawn Enemy\n\u003c/button\u003e\n\n\u003c!-- Template element (hidden) --\u003e\n\u003cdiv id=\"enemy-template\" class=\"enemy\" data-state\u003e\n  \u003c!-- Your enemy content --\u003e\n\u003c/div\u003e\n```\n\n**What happens:**\n1. Clones `#enemy-template` element\n2. Generates unique ID: `enemy-template-1`, `enemy-template-2`, etc.\n3. Inserts into `#game` container\n4. Automatically initializes State.js on the clone\n5. Updates instance count on source element\n\n### Attribute Overrides\n\nCustomize each cloned instance with different attributes:\n\n```html\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"enemy-template\"\n        data-state-target=\"#game\"\n        data-state-set-health=\"100\"\n        data-state-set-type=\"goblin\"\n        data-state-set-level=\"5\"\u003e\n  Spawn Goblin (Lvl 5, 100 HP)\n\u003c/button\u003e\n\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"enemy-template\"\n        data-state-target=\"#game\"\n        data-state-set-health=\"200\"\n        data-state-set-type=\"orc\"\n        data-state-set-level=\"10\"\u003e\n  Spawn Orc (Lvl 10, 200 HP)\n\u003c/button\u003e\n```\n\n**How attribute overrides work:**\n- Use `data-state-set-*` to set attributes on cloned instances\n- Most attributes become `data-*` (e.g., `data-state-set-health=\"100\"` → `data-health=\"100\"`)\n- **Special case:** `data-state-set-class=\"enemy\"` sets the actual `class` attribute (not `data-class`)\n\n**Common use cases:**\n```html\n\u003c!-- Set data attributes --\u003e\n\u003cbutton data-state-instantiate=\"item\"\n        data-state-set-name=\"Sword\"\n        data-state-set-damage=\"50\"\u003e\n  \u003c!-- Creates: data-name=\"Sword\" data-damage=\"50\" --\u003e\n\u003c/button\u003e\n\n\u003c!-- Set CSS class for styling/removal --\u003e\n\u003cbutton data-state-instantiate=\"enemy\"\n        data-state-set-class=\"monster goblin\"\u003e\n  \u003c!-- Creates: class=\"monster goblin\" --\u003e\n\u003c/button\u003e\n\n\u003c!-- Combine both --\u003e\n\u003cbutton data-state-instantiate=\"card\"\n        data-state-set-class=\"playing-card\"\n        data-state-set-suit=\"hearts\"\n        data-state-set-rank=\"ace\"\u003e\n  \u003c!-- Creates: class=\"playing-card\" data-suit=\"hearts\" data-rank=\"ace\" --\u003e\n\u003c/button\u003e\n```\n\n### Insert Modes\n\nControl where the cloned element is inserted:\n\n```html\n\u003c!-- Append to end (default) --\u003e\n\u003cbutton data-state-instantiate=\"item\"\n        data-state-target=\"#inventory\"\n        data-state-insert=\"append\"\u003eAdd Item (End)\u003c/button\u003e\n\n\u003c!-- Prepend to beginning --\u003e\n\u003cbutton data-state-instantiate=\"item\"\n        data-state-target=\"#inventory\"\n        data-state-insert=\"prepend\"\u003eAdd Item (Start)\u003c/button\u003e\n\n\u003c!-- Insert before target --\u003e\n\u003cbutton data-state-instantiate=\"notification\"\n        data-state-target=\"#top-bar\"\n        data-state-insert=\"before\"\u003eAdd Before\u003c/button\u003e\n\n\u003c!-- Insert after target --\u003e\n\u003cbutton data-state-instantiate=\"notification\"\n        data-state-target=\"#top-bar\"\n        data-state-insert=\"after\"\u003eAdd After\u003c/button\u003e\n```\n\n### Instance Counting\n\nSource elements automatically track how many instances have been created:\n\n```html\n\u003cdiv id=\"enemy-template\" data-state data-state-watch=\"enemy-templateCount\"\u003e\n  \u003c!-- Template content --\u003e\n\u003c/div\u003e\n\n\u003cp\u003eEnemies spawned: \u003cspan data-state-display=\"enemy-templateCount\"\u003e0\u003c/span\u003e\u003c/p\u003e\n```\n\n**Automatic counter attribute:** `data-{sourceId}Count` is updated on the source element each time an instance is created.\n\n### Removing Elements\n\nRemove elements by ID or CSS selector:\n\n```html\n\u003c!-- Remove by ID (single element) --\u003e\n\u003cbutton data-state-trigger\n        data-state-remove=\"enemy-template-1\"\u003e\n  Remove Enemy #1\n\u003c/button\u003e\n\n\u003c!-- Remove all matching selector --\u003e\n\u003cbutton data-state-trigger\n        data-state-remove=\".enemy\"\u003e\n  Clear All Enemies\n\u003c/button\u003e\n\n\u003c!-- Remove by attribute --\u003e\n\u003cbutton data-state-trigger\n        data-state-remove=\"[data-type='goblin']\"\u003e\n  Remove All Goblins\n\u003c/button\u003e\n```\n\n**How it works:**\n- **ID removal** (no `.` or `[`): Removes single element by ID\n- **Selector removal** (starts with `.` or contains `[`): Removes all matching elements\n\n### Conditional Removal\n\nOnly remove elements that meet specific conditions:\n\n```html\n\u003c!-- Remove enemies with 0 HP --\u003e\n\u003cbutton data-state-trigger\n        data-state-remove=\".enemy\"\n        data-state-condition=\"health \u003c= 0\"\u003e\n  Remove Dead Enemies\n\u003c/button\u003e\n\n\u003c!-- Remove low-value items --\u003e\n\u003cbutton data-state-trigger\n        data-state-remove=\".item\"\n        data-state-condition=\"value \u003c 10\"\u003e\n  Sell Junk Items\n\u003c/button\u003e\n```\n\n### Complete Example: Enemy Spawner\n\n```html\n\u003cdiv id=\"game\"\u003e\n  \u003c!-- Spawn controls --\u003e\n  \u003cbutton data-state-trigger\n          data-state-instantiate=\"enemy\"\n          data-state-target=\"#battlefield\"\n          data-state-set-health=\"100\"\n          data-state-set-type=\"goblin\"\u003e\n    Spawn Goblin\n  \u003c/button\u003e\n\n  \u003cbutton data-state-trigger\n          data-state-instantiate=\"enemy\"\n          data-state-target=\"#battlefield\"\n          data-state-set-health=\"200\"\n          data-state-set-type=\"orc\"\u003e\n    Spawn Orc\n  \u003c/button\u003e\n\n  \u003c!-- Cleanup controls --\u003e\n  \u003cbutton data-state-trigger\n          data-state-remove=\".enemy\"\n          data-state-condition=\"health \u003c= 0\"\u003e\n    Remove Dead\n  \u003c/button\u003e\n\n  \u003cbutton data-state-trigger\n          data-state-remove=\".enemy\"\u003e\n    Clear All\n  \u003c/button\u003e\n\n  \u003c!-- Instance counter --\u003e\n  \u003cp\u003eTotal spawned: \u003cspan data-state-display=\"enemyCount\"\u003e0\u003c/span\u003e\u003c/p\u003e\n\n  \u003c!-- Battlefield container --\u003e\n  \u003cdiv id=\"battlefield\"\u003e\u003c/div\u003e\n\u003c/div\u003e\n\n\u003c!-- Hidden template --\u003e\n\u003cdiv id=\"enemy\" class=\"enemy\"\n     data-state\n     data-state-watch=\"health,type,enemyCount\"\n     data-health=\"100\"\n     data-type=\"enemy\"\n     style=\"display: none;\"\u003e\n\n  \u003ch3\u003e\u003cspan data-state-display=\"type\"\u003eEnemy\u003c/span\u003e\u003c/h3\u003e\n  \u003cp\u003eHP: \u003cspan data-state-display=\"health\"\u003e100\u003c/span\u003e\u003c/p\u003e\n\n  \u003cbutton data-state-trigger\n          data-state-attr=\"health\"\n          data-state-increment=\"-25\"\u003e\n    Attack (-25 HP)\n  \u003c/button\u003e\n\u003c/div\u003e\n```\n\n### Use Cases\n\n**Perfect for:**\n- 🎮 **Game Development:** Spawn enemies, projectiles, particles, loot drops\n- 📦 **Inventory Systems:** Add/remove items, manage equipment slots\n- 🃏 **Card Games:** Deal cards, shuffle decks, create hands\n- 📝 **Dynamic Forms:** Add/remove form fields, repeating sections\n- 🔔 **Notifications:** Create toast messages, alerts, popups\n- 📊 **Data Visualization:** Generate chart elements, data points\n- 🛒 **Shopping Carts:** Add/remove products, update quantities\n- 💬 **Chat Systems:** Add messages, manage conversation threads\n\n### Security\n\nInstance management uses `DOMParser` for secure element cloning (same as v1.4.2 HTML includes):\n\n- ✅ No `innerHTML` usage\n- ✅ Safe from XSS attacks\n- ✅ CSP compliant\n- ✅ Zero external dependencies\n\n### Reading Element Values at Instantiate Time (v1.6.1)\n\n**The final piece for pur declarative apps** - Read values from form inputs or any element at trigger-time.\n\nUse `data-state-set-*-from` to capture user input when cloning, enabling fully declarative forms without any JavaScript.\n\n#### Basic Usage\n\n```html\n\u003c!-- Text input → clone --\u003e\n\u003cinput id=\"taskName\" placeholder=\"Enter task name\"\u003e\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"task-tpl\"\n        data-state-set-label-from=\"#taskName\"\u003e\n    Add Task\n\u003c/button\u003e\n\n\u003c!-- Template uses the captured value --\u003e\n\u003cdiv id=\"task-tpl\" data-state data-label=\"New task\" style=\"display:none\"\u003e\n    \u003cspan data-state-display=\"label\"\u003eNew task\u003c/span\u003e\n\u003c/div\u003e\n```\n\n**How it works:**\n1. User types in `#taskName` input\n2. Click triggers instantiate\n3. State.js reads `input.value` at click-time\n4. Sets `data-label` on the clone with the input's current value\n5. Template displays the user's text - no JavaScript required!\n\n#### Supported Elements\n\n**The `-from` attribute works with any element:**\n\n- **`\u003cinput\u003e`** - Reads `.value` property\n- **`\u003ctextarea\u003e`** - Reads `.value` property\n- **`\u003cselect\u003e`** - Reads `.value` property (selected option)\n- **Contenteditable** - Reads `.textContent` property\n- **Any element** - Falls back to `.textContent`\n\n#### Multiple Inputs Example\n\n```html\n\u003cinput id=\"expenseName\" placeholder=\"Description\"\u003e\n\u003cinput id=\"expenseAmount\" type=\"number\" placeholder=\"Amount\"\u003e\n\u003cselect id=\"expenseCategory\"\u003e\n    \u003coption value=\"food\"\u003eFood\u003c/option\u003e\n    \u003coption value=\"transport\"\u003eTransport\u003c/option\u003e\n\u003c/select\u003e\n\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"expense-tpl\"\n        data-state-set-label-from=\"#expenseName\"\n        data-state-set-amount-from=\"#expenseAmount\"\n        data-state-set-category-from=\"#expenseCategory\"\u003e\n    Add Expense\n\u003c/button\u003e\n```\n\n#### Complex Selectors\n\n**Full CSS selector support** - not limited to IDs:\n\n```html\n\u003c!-- Class selector --\u003e\n\u003cbutton data-state-set-value-from=\".active-input\"\u003e\n\n\u003c!-- Attribute selector --\u003e\n\u003cbutton data-state-set-name-from=\"input[name='username']\"\u003e\n\n\u003c!-- Complex selector --\u003e\n\u003cbutton data-state-set-text-from=\".form-active .description-field\"\u003e\n\n\u003c!-- Descendant selector --\u003e\n\u003cbutton data-state-set-content-from=\"#panel textarea\"\u003e\n```\n\n#### Combining Static and Dynamic Values\n\nYou can combine static fallbacks with dynamic `-from` values:\n\n```html\n\u003c!-- If input is empty or not found, uses \"Default Task\" --\u003e\n\u003cbutton data-state-set-label=\"Default Task\"\n        data-state-set-label-from=\"#taskInput\"\u003e\n```\n\n**Priority:** `-from` takes precedence if the element is found and has a value.\n\n#### Real-World Example: Budget Tracker\n\n**Before v1.6.1 (required JavaScript):**\n```html\n\u003cinput id=\"incomeName\"\u003e\n\u003cbutton id=\"addBtn\" data-state-instantiate=\"entry-tpl\"\u003eAdd\u003c/button\u003e\n\n\u003cscript\u003e\n// JS needed to read input value\naddBtn.addEventListener('mousedown', () =\u003e {\n    addBtn.setAttribute('data-state-set-label',\n        document.getElementById('incomeName').value);\n});\n\u003c/script\u003e\n```\n\n**After v1.6.1 (fully declerative):**\n```html\n\u003cinput id=\"incomeName\"\u003e\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"entry-tpl\"\n        data-state-set-label-from=\"#incomeName\"\u003e\n    Add\n\u003c/button\u003e\n```\n\n**Result:** The 15 lines of JavaScript are eliminated entirely. Pure declarative forms.\n\n#### Contenteditable Support\n\nWorks with rich text editors:\n\n```html\n\u003cdiv contenteditable id=\"noteEditor\"\u003e\n    Type your \u003cb\u003eformatted\u003c/b\u003e note here\n\u003c/div\u003e\n\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"note-tpl\"\n        data-state-set-content-from=\"#noteEditor\"\u003e\n    Save Note\n\u003c/button\u003e\n```\n\n#### Edge Cases\n\n**Element not found:**\n- Treated as empty string\n- Instantiate continues normally\n- Clone gets empty value for that attribute\n\n**Empty input value:**\n- Sets empty string on clone: `data-label=\"\"`\n- Does not fall back to static value\n- `-from` always wins when element exists\n\n**Should State.js clear the input after adding?**\n- No - that's a UX decision that varies by use case\n- Some apps clear (budget demo style)\n- Some apps keep value (edit mode style)\n- Use trigger chains to reset if needed: `data-state-trigger-chain=\"addEntry,clearInput\"`\n\n### Configuration\n\n| Attribute | Description | Example |\n|-----------|-------------|---------|\n| `data-state-instantiate=\"id\"` | ID of element to clone | `data-state-instantiate=\"enemy\"` |\n| `data-state-remove=\"selector\"` | ID or CSS selector of element(s) to remove | `data-state-remove=\".enemy\"` |\n| `data-state-target=\"selector\"` | Where to insert cloned element (default: body) | `data-state-target=\"#game\"` |\n| `data-state-insert=\"mode\"` | Insert mode: append, prepend, before, after (default: append) | `data-state-insert=\"prepend\"` |\n| `data-state-set-*=\"value\"` | Override attribute on cloned element (becomes `data-*`) | `data-state-set-health=\"100\"` → `data-health=\"100\"` |\n| `data-state-set-class=\"value\"` | Special: Sets actual `class` attribute (not `data-class`) | `data-state-set-class=\"enemy\"` → `class=\"enemy\"` |\n| `data-state-condition=\"expr\"` | Condition for removal (only with remove) | `data-state-condition=\"health \u003c= 0\"` |\n\n**Auto-generated:**\n- Unique IDs: `{sourceId}-{counter}` (e.g., `enemy-1`, `enemy-2`)\n- Instance count: `data-{sourceId}Count` on source element\n- Clones automatically have `display: none` removed if present on template\n\n---\n\n## New in v1.5.1: Random Number Generation\n\n**Essential for game development** - Generate random numbers declaratively using pure HTML attributes.\n\nState.js provides simple, zero-dependency random number generation for:\n- 🎲 Dice rolls\n- 🎁 Loot drops\n- ⚔️ Damage calculation\n- 🎰 Probability systems\n- 🎮 Procedural generation\n\n### Basic Usage\n\n```html\n\u003c!-- Dice shorthand: 1-6 --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"damage\"\n        data-state-random=\"6\"\u003e\n  Roll 1d6 Damage\n\u003c/button\u003e\n\n\u003c!-- Explicit range: 0-100 --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"loot\"\n        data-state-attr=\"rarity\"\n        data-state-random=\"0,100\"\u003e\n  Roll Loot Rarity\n\u003c/button\u003e\n\n\u003c!-- Any range: 10-20 --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"enemy\"\n        data-state-attr=\"health\"\n        data-state-random=\"10,20\"\u003e\n  Spawn with Random HP\n\u003c/button\u003e\n```\n\n### Syntax Options\n\n**Dice shorthand (1 to N):**\n```html\ndata-state-random=\"6\"     \u003c!-- 1-6 (common d6) --\u003e\ndata-state-random=\"20\"    \u003c!-- 1-20 (common d20) --\u003e\ndata-state-random=\"100\"   \u003c!-- 1-100 (percentile) --\u003e\n```\n\n**Explicit range (min to max):**\n```html\ndata-state-random=\"1,6\"    \u003c!-- 1-6 (explicit) --\u003e\ndata-state-random=\"0,100\"  \u003c!-- 0-100 (percentage) --\u003e\ndata-state-random=\"10,50\"  \u003c!-- 10-50 (custom range) --\u003e\n```\n\n### Advanced Patterns\n\n**Random with conditions:**\n```html\n\u003c!-- Only roll if player has attempts left --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"player\"\n        data-state-attr=\"reward\"\n        data-state-random=\"1,100\"\n        data-state-condition=\"attempts \u003e 0\"\u003e\n  Try Your Luck\n\u003c/button\u003e\n```\n\n**Random with trigger chains:**\n```html\n\u003c!-- Roll damage, then apply to enemy --\u003e\n\u003cbutton data-state-trigger\n        data-state-bind=\"combat\"\n        data-state-attr=\"damage\"\n        data-state-random=\"1,6\"\n        data-state-trigger-chain=\"applyDamage\"\u003e\n  Attack\n\u003c/button\u003e\n\n\u003cdiv id=\"applyDamage\"\n     data-state-trigger\n     data-state-bind=\"enemy\"\n     data-state-attr=\"health\"\n     data-state-decrement=\"calc(var(--state-damage))\"\u003e\u003c/div\u003e\n```\n\n**Random intervals:**\n```html\n\u003c!-- Random event every 5 seconds --\u003e\n\u003cdiv data-state-trigger\n     data-state-interval=\"5000\"\n     data-state-bind=\"game\"\n     data-state-attr=\"event\"\n     data-state-random=\"1,10\"\u003e\n\u003c/div\u003e\n```\n\n**Random with instantiate:**\n```html\n\u003c!-- Spawn enemy with random health --\u003e\n\u003cbutton data-state-trigger\n        data-state-instantiate=\"enemy-template\"\n        data-state-attr=\"health\"\n        data-state-random=\"50,100\"\n        data-state-set-health=\"calc(var(--state-health))\"\u003e\n  Spawn Random Enemy\n\u003c/button\u003e\n```\n\n### Configuration\n\n| Attribute | Description | Example |\n|-----------|-------------|---------|\n| `data-state-random=\"max\"` | Dice shorthand: 1 to max | `data-state-random=\"6\"` → 1-6 |\n| `data-state-random=\"min,max\"` | Explicit range: min to max | `data-state-random=\"0,100\"` → 0-100 |\n\n**Requirements:**\n- Must have `data-state-trigger` attribute\n- Must specify `data-state-attr` (which attribute to set)\n- Must have `data-state-bind` or be inside `[data-state]` element\n- Uses native `Math.random()` - zero dependencies\n\n**How it works:**\n1. When trigger fires, checks for `data-state-random`\n2. Parses range (single number = dice shorthand, two numbers = explicit)\n3. Generates random integer in range using `Math.floor(Math.random() * (max - min + 1)) + min`\n4. Sets the attribute value to the random number\n5. Works seamlessly with conditions, chains, intervals, and all other State.js features\n\n---\n\n## New in v1.6.0: Expression-Based Templates\n\n**Templating without leaving HTML** - Computed values, string concatenation, and conditional logic in pure declarative attributes.\n\nCSS has fundamental limitations - you cannot use `calc()` in the `content` property, and you cannot concatenate strings from custom properties. State.js v1.6.0 solves this with expression-based templates.\n\n### The Problem (Before v1.6.0)\n\n```css\n/* This doesn't work in CSS! */\n.enemy-label:after {\n  --hp: calc(30 + (var(--state-level) - 1) * 10);\n  content: var(--hp) \"hp\";  /* Can't concatenate! */\n}\n```\n\n### The Solution (v1.6.0)\n\n```html\n\u003c!-- Simple: Computed value + string --\u003e\n\u003cspan data-state-text=\"{30 + (level - 1) * 10}hp\"\u003e30hp\u003c/span\u003e\n\n\u003c!-- Conditional: Ternary operator --\u003e\n\u003cspan data-state-text=\"{health \u003e 0 ? health + 'hp' : 'DEAD'}\"\u003e100hp\u003c/span\u003e\n\n\u003c!-- Complex: Multiple expressions --\u003e\n\u003cspan data-state-text=\"Level {level} - {xp}/{xpMax} XP\"\u003eLevel 5 - 750/1000 XP\u003c/span\u003e\n```\n\n### Basic Usage\n\n**Simple attribute display (still works):**\n```html\n\u003cspan data-state-text=\"HP: {health}\"\u003eHP: 100\u003c/span\u003e\n```\n\n**String concatenation:**\n```html\n\u003cspan data-state-text=\"{health}hp\"\u003e100hp\u003c/span\u003e\n\u003cspan data-state-text=\"{gold} gold\"\u003e500 gold\u003c/span\u003e\n```\n\n**Computed numeric expressions:**\n```html\n\u003c!-- Enemy HP scales with player level --\u003e\n\u003cspan data-state-text=\"{30 + (level - 1) * 10}hp\"\u003e30hp\u003c/span\u003e\n\n\u003c!-- Damage range --\u003e\n\u003cspan data-state-text=\"{minDmg + '-' + maxDmg}\"\u003e10-15\u003c/span\u003e\n\n\u003c!-- Percentage --\u003e\n\u003cspan data-state-text=\"{health / maxHealth * 100}%\"\u003e75%\u003c/span\u003e\n```\n\n**Conditional display with ternary:**\n```html\n\u003c!-- Show different text based on condition --\u003e\n\u003cspan data-state-text=\"{health \u003e 0 ? health + 'hp' : 'DEAD'}\"\u003e100hp\u003c/span\u003e\n\n\u003c!-- Loot rarity --\u003e\n\u003cspan data-state-text=\"{rarity \u003e= 75 ? 'Legendary' : rarity \u003e= 25 ? 'Rare' : 'Common'}\"\u003eCommon\u003c/span\u003e\n\n\u003c!-- Status indicator --\u003e\n\u003cspan data-state-text=\"{active ? 'Online' : 'Offline'}\"\u003eOnline\u003c/span\u003e\n```\n\n**Multiple expressions in one template:**\n```html\n\u003cspan data-state-text=\"Level {level} Hero\"\u003eLevel 5 Hero\u003c/span\u003e\n\u003cspan data-state-text=\"{name} - {health}/{maxHealth}hp\"\u003eWarrior - 75/100hp\u003c/span\u003e\n\u003cspan data-state-text=\"XP: {xp}/{xpMax} ({xp / xpMax * 100}%)\"\u003eXP: 750/1000 (75%)\u003c/span\u003e\n```\n\n### Advanced Patterns\n\n**Nested expressions:**\n```html\n\u003cspan data-state-text=\"{level \u003e 10 ? 'Veteran (' + level + ')' : 'Novice'}\"\u003eNovice\u003c/span\u003e\n```\n\n**Math operations:**\n```html\n\u003cspan data-state-text=\"{health + shield}hp total\"\u003e{health + shield}hp total\u003c/span\u003e\n\u003cspan data-state-text=\"DPS: {damage * attackSpeed}\"\u003eDPS: 45\u003c/span\u003e\n```\n\n**Logical operations:**\n```html\n\u003cspan data-state-text=\"{gold \u003e= 100 and level \u003e= 5 ? 'Can Buy' : 'Locked'}\"\u003eLocked\u003c/span\u003e\n```\n\n### String Concatenation in Computed State\n\n**v1.6.0 also adds string concatenation to `data-state-compute`:**\n\n```html\n\u003cdiv data-state\n     data-state-watch=\"hp,level\"\n     data-state-compute=\"\n       enemyHp = 30 + (level - 1) * 10;\n       hpLabel = enemyHp + 'hp';\n       status = hp \u003e 0 ? 'Alive' : 'Dead'\n     \"\u003e\n  \u003cspan data-state-display=\"hpLabel\"\u003e30hp\u003c/span\u003e\n  \u003cspan data-state-display=\"status\"\u003eAlive\u003c/span\u003e\n\u003c/div\u003e\n```\n\n**Compute creates attributes, then display them:**\n- Computation result stored as `data-hpLabel=\"30hp\"`\n- Can be used in CSS, displayed with `data-state-display`, or referenced elsewhere\n- Reusable across multiple elements\n\n### Expression Syntax Reference\n\n**Operators supported:**\n- **Arithmetic**: `+`, `-`, `*`, `/`\n- **Comparison**: `==`, `!=`, `\u003c`, `\u003e`, `\u003c=`, `\u003e=`\n- **Logical**: `and`/`\u0026\u0026`, `or`/`||`, `not`/`!`\n- **Ternary**: `condition ? trueValue : falseValue`\n- **Grouping**: `(expression)`\n\n**String concatenation:**\n```html\n{value + 'suffix'}\n{'prefix' + value}\n{value1 + ' ' + value2}\n```\n\n**Values:**\n- Attribute names: `{health}` resolves to `data-health` attribute value\n- Numbers: `{100}`, `{3.14}`\n- Strings: `{'text'}`, `{\"text\"}`\n- Booleans: `{true}`, `{false}`\n\n**Examples:**\n```html\n\u003c!-- Math + string --\u003e\n{10 + 5 + 'hp'}  → \"15hp\"\n\n\u003c!-- Ternary + concat --\u003e\n{health \u003e 0 ? health + 'hp' : 'DEAD'}  → \"100hp\" or \"DEAD\"\n\n\u003c!-- Complex expression --\u003e\n{level \u003e 10 ? 'Veteran Lv' + level : 'Novice'}  → \"Veteran Lv15\"\n\n\u003c!-- Multiple operations --\u003e\n{(damage + bonusDmg) * critMultiplier + ' damage'}  → \"150 damage\"\n```\n\n### Why Expression Templates?\n\n**Solves CSS limitations:**\n- ✅ Computed values in display text (impossible in CSS `content`)\n- ✅ String concatenation (impossible in CSS)\n- ✅ Conditional text (no if/else in CSS)\n- ✅ Complex calculations for display\n\n**More intuitive than alternatives:**\n- Better than: Compute → attribute → display (two steps)\n- Syntax: `{expr}` feels natural\n- Inline conditionals: Ternary in template, not separate elements\n\n### Use Cases\n\n**Game development:**\n```html\n\u003c!-- Scaling enemy stats --\u003e\n\u003cspan data-state-text=\"{30 + (level - 1) * 10}hp\"\u003e30hp\u003c/span\u003e\n\n\u003c!-- Loot system --\u003e\n\u003cspan data-state-text=\"{rarity \u003e= 80 ? 'Legendary' : rarity \u003e= 50 ? 'Rare' : 'Common'}\"\u003eCommon\u003c/span\u003e\n\n\u003c!-- Combat log --\u003e\n\u003cdiv data-state-text=\"{attacker} dealt {damage} damage to {defender}\"\u003e...\u003c/div\u003e\n```\n\n**Dynamic UIs:**\n```html\n\u003c!-- User status --\u003e\n\u003cspan data-state-text=\"{online ? 'Active now' : 'Last seen ' + lastSeen}\"\u003eActive now\u003c/span\u003e\n\n\u003c!-- Shopping cart --\u003e\n\u003cspan data-state-text=\"{itemCount} items ({total} gold)\"\u003e3 items (150 gold)\u003c/span\u003e\n\n\u003c!-- Progress indicators --\u003e\n\u003cspan data-state-text=\"{completed}/{total} tasks ({completed/total*100}%)\"\u003e7/10 tasks (70%)\u003c/span\u003e\n```\n\n**Form validation:**\n```html\n\u003cspan data-state-text=\"{length \u003c 8 ? 'Too short' : length \u003e 20 ? 'Too long' : 'Valid'}\"\u003eValid\u003c/span\u003e\n```\n\n### Configuration\n\n**Expression Templates:**\n| Attribute | Description | Example |\n|-----------|-------------|---------|\n| `data-state-text=\"{expr}\"` | Template with expressions | `data-state-text=\"{hp}hp\"` |\n| `data-state-text=\"text {expr} text\"` | Mixed static + dynamic | `data-state-text=\"Level {level} Hero\"` |\n\n**Computed State with Strings:**\n| Attribute | Description | Example |\n|-----------|-------------|---------|\n| `data-state-compute=\"name=expr\"` | Compute and store result | `data-state-compute=\"label = hp + 'hp'\"` |\n| `data-state-compute=\"a=expr; b=expr\"` | Multiple computations | `data-state-compute=\"sum = a + b; label = sum + 'hp'\"` |\n\n**Requirements:**\n- `data-state-text` requires `data-state-bind` pointing to element with watched attributes\n- Expressions evaluated using existing State.js expression parser\n- String concatenation using `+` operator (auto-detects strings vs numbers)\n- All watched attributes available as identifiers in expressions\n\n---\n\n## State-Animations.css\n\nState.js includes **state-animations.css** - a companion stylesheet with predefined animations for common UI patterns and interactive elements.\n\n### Include in your project:\n```html\n\u003clink rel=\"stylesheet\" href=\"src/state-animations.css\"\u003e\n```\n\n### Available Animation Classes:\n\n#### UI Feedback \u0026 Notifications\n- `.state-notification` - Notification slide\n- `.state-warning` - Warning shake\n- `.state-success` - Success bounce\n- `.state-error` - Error shake\n- `.state-loading` - Loading spin\n\n#### Progress \u0026 Meter States\n- `.state-health-low` - Low value warning pulse\n- `.state-health-critical` - Critical state shake\n- `[data-health=\"0\"]` - Empty state animation\n- `[data-health=\"100\"]` - Full/complete glow\n\n#### Counter \u0026 Score Animations\n- `.state-score-increase` - Value increase pop\n- `.state-score-milestone` - Milestone celebration\n- `.state-level-up` - Level/tier change flash\n\n#### Status Indicators\n- `.state-powered` - Active/powered state glow\n- `.state-invincible` - Protected state shimmer\n- `.state-shielded` - Shield/protection pulse\n- `.state-stunned` - Disabled/paused effect\n- `.state-poisoned` - Negative effect pulse\n- `.state-frozen` - Frozen/locked shake\n- `.state-burning` - Active damage flicker\n- `.state-healing` - Positive effect sparkle\n\n[View full animation documentation →](animations.html)\n\n---\n\n## Advanced Examples\n\n### Multi-Attribute UI Component (Character Stats Demo)\n\n```html\n\u003cdiv id=\"player\"\n     data-state\n     data-state-watch=\"health,mana,xp,level\"\n     data-state-var=\"true\"\n     data-health=\"100\"\n     data-mana=\"80\"\n     data-xp=\"450\"\n     data-level=\"5\"\n     data-health-max=\"100\"\n     data-mana-max=\"100\"\n     data-xp-max=\"1000\"\u003e\n\n    \u003cdiv class=\"health-bar\" style=\"width: var(--state-health-percent)\"\u003e\u003c/div\u003e\n    \u003cdiv class=\"mana-bar\" style=\"width: var(--state-mana-percent)\"\u003e\u003c/div\u003e\n    \u003cdiv class=\"xp-bar\" style=\"width: var(--state-xp-percent)\"\u003e\u003c/div\u003e\n    \u003cdiv class=\"level\"\u003eLevel \u003cspan style=\"--content: var(--state-level)\"\u003e\u003c/span\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\n### Video Progress Indicator\n\n```html\n\u003cvideo data-state\n       data-state-media=\"true\"\n       data-state-var=\"true\"\u003e\n    \u003csource src=\"video.mp4\"\u003e\n\u003c/video\u003e\n\n\u003cstyle\u003e\n    video::after {\n        content: \"\";\n        width: var(--state-progress);\n        height: 5px;\n        background: red;\n        position: absolute;\n        bottom: 0;\n        left: 0;\n    }\n\u003c/style\u003e\n```\n\n### Boolean Toggle States\n\n```html\n\u003cdiv data-state\n     data-state-toggles=\"active,locked,complete\"\n     data-active=\"true\"\n     data-locked=\"false\"\n     data-complete=\"false\"\u003e\n\u003c/div\u003e\n```\n\n```css\n/* Automatically applied classes */\n.state-active {\n    filter: brightness(1.2);\n    transform: scale(1.05);\n}\n\n.state-locked {\n    filter: grayscale(1) brightness(0.6);\n    cursor: not-allowed;\n}\n\n.state-complete {\n    animation: complete-check 0.5s forwards;\n}\n```\n\n### Clicker Game (Fully declarative)\n\n```html\n\u003cdiv id=\"clicker\"\n     data-state\n     data-state-watch=\"score\"\n     data-state-var=\"true\"\n     data-score=\"0\"\n     data-score-max=\"100\"\u003e\n\n    \u003ch1\u003eScore: \u003cspan data-state-display=\"score\"\u003e0\u003c/span\u003e\u003c/h1\u003e\n\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"clicker\"\n            data-state-attr=\"score\"\n            data-state-increment=\"1\"\u003e\n        Click Me!\n    \u003c/button\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n/* Celebrate milestones with CSS alone */\n#clicker[data-score=\"10\"],\n#clicker[data-score=\"20\"],\n#clicker[data-score=\"30\"] {\n    animation: milestone-burst 0.5s ease-out;\n}\n\n#clicker[data-score=\"100\"] {\n    animation: victory-flash 1s ease-out;\n}\n\n/* Progress bar using CSS variables */\n#clicker::after {\n    content: \"\";\n    width: var(--state-score-percent);\n    height: 10px;\n    background: linear-gradient(90deg, red, yellow, green);\n}\n\u003c/style\u003e\n```\n\n### Volume Control (Increment \u0026 Decrement with Auto-Clamping)\n\n```html\n\u003cdiv id=\"audio\"\n     data-state\n     data-state-watch=\"volume\"\n     data-state-var=\"true\"\n     data-volume=\"50\"\n     data-volume-min=\"0\"\n     data-volume-max=\"100\"\u003e\n\n    \u003ch2\u003eVolume: \u003cspan data-state-display=\"volume\"\u003e50\u003c/span\u003e%\u003c/h2\u003e\n\n    \u003c!-- Decrement button (auto-stops at 0) --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"audio\"\n            data-state-attr=\"volume\"\n            data-state-decrement=\"10\"\u003e\n        -\n    \u003c/button\u003e\n\n    \u003c!-- Increment button (auto-stops at 100) --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"audio\"\n            data-state-attr=\"volume\"\n            data-state-increment=\"10\"\u003e\n        +\n    \u003c/button\u003e\n\n    \u003c!-- Visual bar updates automatically --\u003e\n    \u003cdiv class=\"volume-bar\" style=\"width: var(--state-volume-percent);\"\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\n### Idle Game with Dynamic Scaling (No JavaScript!)\n\n```html\n\u003cdiv id=\"idleGame\"\n     data-state\n     data-state-watch=\"gold,level,clickPower\"\n     data-state-var=\"true\"\n     data-gold=\"0\"\n     data-level=\"1\"\n     data-clickPower=\"1\"\u003e\n\n    \u003ch1\u003eGold: \u003cspan data-state-display=\"gold\"\u003e0\u003c/span\u003e\u003c/h1\u003e\n    \u003ch2\u003eLevel: \u003cspan data-state-display=\"level\"\u003e1\u003c/span\u003e\u003c/h2\u003e\n    \u003cp\u003eClick Power: \u003cspan data-state-display=\"clickPower\"\u003e1\u003c/span\u003e\u003c/p\u003e\n\n    \u003c!-- Basic click: adds clickPower to gold --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"idleGame\"\n            data-state-attr=\"gold\"\n            data-state-increment=\"calc(var(--state-clickPower))\"\u003e\n        Mine Gold\n    \u003c/button\u003e\n\n    \u003c!-- Upgrade: increases clickPower, costs gold --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"idleGame\"\n            data-state-attr=\"clickPower\"\n            data-state-increment=\"1\"\u003e\n        Upgrade Pick (+1 power)\n    \u003c/button\u003e\n\n    \u003c!-- Level up: costs increase with level --\u003e\n    \u003cbutton data-state\n            data-state-trigger\n            data-state-bind=\"idleGame\"\n            data-state-attr=\"level\"\n            data-state-increment=\"1\"\u003e\n        Level Up\n    \u003c/button\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n/* Different animations per level */\n#idleGame[data-level=\"5\"],\n#idleGame[data-level=\"10\"] {\n    animation: level-milestone 1s ease-out;\n}\n\n/* Click power visualization */\n#idleGame::after {\n    content: \"\";\n    width: calc(var(--state-clickPower) * 10px);\n    height: 5px;\n    background: gold;\n}\n\u003c/style\u003e\n```\n\n---\n\n## Integration with Other Libraries\n\nState.js is part of a complete CSS/HTML UI development toolkit from iDev Games:\n\n### The iDev Games CSS Framework Suite\n\n**Five libraries working together for pure CSS/HTML interactive experiences:**\n\n1. **[Keys.js](https://github.com/iDev-Games/Keys-JS)** - Keyboard input tracking\n   - `--key-space`, `--key-up`, `--key-down`, etc.\n\n2. **[Cursor.js](https://github.com/iDev-Games/Cursor-JS)** - Mouse position tracking\n   - `--cursor-x`, `--cursor-y`, `--cursor-speed`, etc.\n\n3. **[Touch.js](https://github.com/iDev-Games/Touch-JS)** - Touch gesture tracking\n   - `--touch-x`, `--touch-velocity-x`, `--touch-distance`, etc.\n\n4. **[Motion.js](https://github.com/iDev-Games/Motion-JS)** - Time/animation tracking\n   - `--motion-progress`, `--motion-time`, `--motion-loop`, etc.\n\n5. **State.js** ⭐ - UI state \u0026 data binding\n   - `--state-health`, `--state-score`, `--state-level`, etc.\n\n### Combined Example\n\n```html\n\u003cdiv id=\"game\"\n     data-state\n     data-state-watch=\"health,score\"\n     data-health=\"100\"\n     data-score=\"0\"\n\n     data-cursor\n     data-cursor-var=\"true\"\n\n     data-keys\n     data-keys-watch=\"space,up,down\"\u003e\n\n    \u003c!-- Health bar follows cursor --\u003e\n    \u003cdiv class=\"health-bar\" style=\"\n        width: var(--state-health-percent);\n        transform: translateY(var(--cursor-y));\n    \"\u003e\u003c/div\u003e\n\n    \u003c!-- Score pulses when space pressed --\u003e\n    \u003cdiv class=\"score\" style=\"\n        transform: scale(calc(1 + var(--key-space) * 0.5));\n    \"\u003e\n        Score: \u003cspan data-state-value=\"score\"\u003e\u003c/span\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n\n\u003cstyle\u003e\n    /* When health is low AND cursor is idle */\n    body.cursor-idle [data-health=\"10\"],\n    body.cursor-idle [data-health=\"20\"] {\n        animation: warning-pulse 1s infinite;\n    }\n\n    /* When up arrow pressed AND health full */\n    .key-up[data-health=\"100\"] {\n        animation: victory-jump 0.5s ease-out;\n    }\n\u003c/style\u003e\n```\n\n**Result:** A complete interactive UI system with dynamic data, user input tracking, and reactive animations - all in CSS! Perfect for games, dashboards, data visualizations, and interactive experiences.\n\n---\n\n## Browser Support\n\nState.js uses modern browser APIs:\n- IntersectionObserver API\n- MutationObserver API\n- CSS Custom Properties\n\n**Supported browsers:**\n- Chrome/Edge 58+\n- Firefox 55+\n- Safari 12.1+\n- Opera 45+\n\n---\n\n## Performance\n\nState.js is optimized for performance:\n- ✅ Passive event listeners\n- ✅ requestAnimationFrame for DOM updates\n- ✅ Map-based attribute caching\n- ✅ Conditional updates (only when values change)\n- ✅ Efficient MutationObserver usage\n\n---\n\n## Documentation\n\n- [Live Demo \u0026 Documentation](index.html)\n- [state-Animations.css Documentation](animations.html)\n- [GitHub Repository](https://github.com/iDev-Games/State-JS)\n\n---\n\n## Examples\n\nCheck out the documentation page code as an example:\n[https://github.com/iDev-Games/State-JS/blob/master/index.html](https://github.com/iDev-Games/State-JS/blob/master/index.html)\n\n---\n\n## Philosophy\n\n**Declarative over Imperative**\n\nState.js follows the same philosophy as all iDev Games libraries:\n- ✅ Describe what you want (HTML data attributes)\n- ✅ Style how it looks (CSS)\n- ❌ No complex JavaScript APIs to learn\n- ❌ No framework dependencies\n\n**The goal:** Enable developers to build reactive, data-driven interfaces using HTML and CSS skills they already have - whether for dashboards, web apps, visualizations, or games.\n\n---\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details\n\n---\n\n## Author\n\n**iDev Games**\n\n- GitHub: [@iDev-Games](https://github.com/iDev-Games)\n- Dev.to: [@idevgames](https://dev.to/idevgames)\n\n---\n\n## Contributing\n\nContributions, issues, and feature requests are welcome!\n\nFeel free to check the [issues page](https://github.com/iDev-Games/State-JS/issues).\n\n---\n\n## Show your support\n\nGive a ⭐️ if this project helped you!\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidev-games%2Fstate-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidev-games%2Fstate-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidev-games%2Fstate-js/lists"}