[{"number":1,"slug":"types","title":"Component Types","description":"Incorrect classification of components in Leptos leads to SSR issues, unsafe browser API usage, and inconsistent state handling. Mixing state, effects, and DOM APIs without clear boundaries breaks hydration and component predictability.","keywords":["leptos component types","ssr component classification","leptos state vs effects","interactive component leptos"],"canonical":"https://canonrs.dev/rules/types","category":"component-architecture"},{"number":2,"slug":"ownership","title":"Ownership Rules","description":"Incorrect ownership handling in Leptos causes move errors, broken reactivity, and invalid closures. Passing non-reactive data or using improper children types leads to rendering inconsistencies and runtime failures.","keywords":["leptos ownership rules","storedvalue leptos usage","childrenfn leptos reactivity","leptos move closure pattern"],"canonical":"https://canonrs.dev/rules/ownership","category":"state-reactivity"},{"number":3,"slug":"lists","title":"Lists and Iteration","description":"Improper list rendering in Leptos causes FnOnce errors and hydration mismatches. Using iterators with closures breaks ownership and reactivity, leading to unstable UI behavior.","keywords":["leptos list iteration","leptos for component pattern","storedvalue list leptos","leptos map collect_view error"],"canonical":"https://canonrs.dev/rules/lists","category":"state-reactivity"},{"number":4,"slug":"hydration","title":"Anti-Hydration Rules","description":"Hydration mismatches occur when SSR output differs from client rendering in Leptos. Conditional rendering, async state, and improper list usage create DOM divergence and runtime errors.","keywords":["leptos hydration rules","ssr client mismatch leptos","leptos suspense usage","leptos for hydration issue"],"canonical":"https://canonrs.dev/rules/hydration","category":"core-runtime"},{"number":5,"slug":"ssr-effects","title":"SSR Effects and Browser API Safety","description":"Using browser APIs or async runtime features during SSR leads to runtime panics and undefined behavior. Leptos components must isolate client-only logic to prevent crashes and security issues.","keywords":["leptos ssr effects","browser api ssr panic","leptos cfg wasm guard","spawn_local ssr error"],"canonical":"https://canonrs.dev/rules/ssr-effects","category":"core-runtime"},{"number":6,"slug":"visual-state","title":"Visual State Declaration","description":"Coupling component state with visual styling breaks theming, dark mode, and design system evolution. Inline styles and hardcoded colors prevent scalable UI architecture.","keywords":["leptos visual state pattern","css data attributes state","design system tokens usage","tailwind semantic tokens"],"canonical":"https://canonrs.dev/rules/visual-state","category":"design-system"},{"number":7,"slug":"token-governance","title":"Theme and Token Governance","description":"Direct token imports and hardcoded styles create coupling, build instability, and design drift in monorepos. Lack of token governance prevents scalable theming and consistent UI across apps.","keywords":["design system token governance","tailwind token pipeline","monorepo token architecture","css variable theming"],"canonical":"https://canonrs.dev/rules/token-governance","category":"design-system"},{"number":8,"slug":"overlay-islands","title":"Overlay Islands (Client-Only Architecture)","description":"Dynamic overlays with reactive lists cause hydration mismatch in Leptos SSR. The client DOM diverges from server-rendered HTML when reactive lists are nested inside overlays. Use the island pattern to isolate client-only rendering.","keywords":["leptos overlay hydration mismatch","ssr dynamic overlay issue","leptos island pattern","client only overlay leptos"],"canonical":"https://canonrs.dev/rules/overlay-islands","category":"core-runtime"},{"number":9,"slug":"clipboard-apis","title":"Clipboard and Browser APIs","description":"Using modern clipboard APIs in Leptos callbacks fails due to focus requirements and async constraints. This causes runtime errors and unreliable clipboard operations.","keywords":["leptos clipboard api","execcommand clipboard rust","clipboard callback error leptos","wasm clipboard copy pattern"],"canonical":"https://canonrs.dev/rules/clipboard-apis","category":"behavior"},{"number":10,"slug":"modal-state","title":"Modal Reactive State Management","description":"Passing static props to modals prevents reactive updates and leads to stale UI data. Modal components must maintain synchronization with parent state to ensure correct behavior.","keywords":["leptos modal signal props","reactive modal state leptos","signal derive leptos modal","leptos stale props issue"],"canonical":"https://canonrs.dev/rules/modal-state","category":"state-reactivity"},{"number":11,"slug":"multi-callback-ownership","title":"Multi-Callback Ownership","description":"Using the same value across multiple callbacks causes move errors due to ownership rules in Rust. This leads to compilation failures and incorrect closure behavior.","keywords":["rust closure ownership error","leptos callback clone pattern","use of moved value fix","multi callback ownership rust"],"canonical":"https://canonrs.dev/rules/multi-callback-ownership","category":"state-reactivity"},{"number":12,"slug":"select-vs-combobox","title":"canon-rule-12-select-vs-combobox","description":"Confusing Select and Combobox leads to incorrect architectural decisions affecting SSR, performance, and accessibility. These components have distinct responsibilities and cannot be interchanged.","keywords":["select vs combobox ui","component choice forms","leptos select combobox","ui component selection rule"],"canonical":"https://canonrs.dev/rules/select-vs-combobox","category":"component-architecture"},{"number":13,"slug":"specialization-vs-substitution","title":"canon-rule-13-specialization-vs-substitution","description":"Using specialized components as replacements for base components leads to feature creep and loss of semantic clarity. Base components become overloaded and difficult to maintain.","keywords":["component specialization vs substitution","ui component design patterns","avoid god component frontend","explicit component architecture"],"canonical":"https://canonrs.dev/rules/specialization-vs-substitution","category":"component-architecture"},{"number":14,"slug":"datatable-vs-virtualtable","title":"canon-rule-14-datatable-vs-virtualtable","description":"Choosing between DataTable and VirtualTable affects SSR, performance, and accessibility. Mixing both concerns leads to incorrect architecture and degraded user experience.","keywords":["datatable vs virtualtable","frontend table performance pattern","ssr vs virtualization table","ui component choice tables"],"canonical":"https://canonrs.dev/rules/datatable-vs-virtualtable","category":"component-architecture"},{"number":15,"slug":"pagination-vs-virtualization","title":"canon-rule-15-pagination-vs-virtualization","description":"Choosing between pagination and virtualization impacts backend design, SEO, and performance. Mixing both leads to architectural conflicts and inconsistent UX.","keywords":["pagination vs virtualization","frontend navigation strategy","virtualization performance pattern","ui data rendering choice"],"canonical":"https://canonrs.dev/rules/pagination-vs-virtualization","category":"component-architecture"},{"number":16,"slug":"client-vs-server-filtering","title":"canon-rule-16-client-vs-server-filtering","description":"Choosing between client-side and server-side filtering impacts performance, security, and scalability. Mixing both incorrectly leads to inefficient data handling and poor UX.","keywords":["client vs server filtering","frontend data filtering strategy","backend filtering performance","reactive filtering pattern"],"canonical":"https://canonrs.dev/rules/client-vs-server-filtering","category":"state-reactivity"},{"number":17,"slug":"human-vs-machine-scale","title":"canon-rule-17-human-vs-machine-scale","description":"Choosing components without considering scale leads to performance issues or unnecessary complexity. Human-scale and machine-scale components have fundamentally different constraints.","keywords":["human vs machine scale components","frontend scale architecture","ui performance scaling pattern","component selection based on scale"],"canonical":"https://canonrs.dev/rules/human-vs-machine-scale","category":"component-architecture"},{"number":18,"slug":"client-vs-server-sorting","title":"Client vs Server","description":"Sorting data in the wrong layer leads to performance issues or unnecessary backend complexity. The strategy must align with dataset size and location.","keywords":["client vs server sorting","data sorting architecture","frontend backend sorting strategy","sorting performance pattern"],"canonical":"https://canonrs.dev/rules/client-vs-server-sorting","category":"state-reactivity"},{"number":19,"slug":"streaming-vs-snapshot","title":"canon-rule-19-streaming-vs-snapshot","description":"Using the wrong data delivery model leads to inefficiency and complexity. Streaming and snapshot approaches must align with data behavior and requirements.","keywords":["streaming vs snapshot data","real time vs fetch architecture","frontend data strategy pattern","websocket vs rest decision"],"canonical":"https://canonrs.dev/rules/streaming-vs-snapshot","category":"state-reactivity"},{"number":20,"slug":"realtime-vs-eventual","title":"canon-rule-20-realtime-vs-eventual","description":"Confusing real-time guarantees with eventual consistency leads to incorrect system design and poor UX expectations. Each model has distinct constraints.","keywords":["realtime vs eventual consistency","frontend data sync strategy","websocket vs polling decision","state consistency architecture"],"canonical":"https://canonrs.dev/rules/realtime-vs-eventual","category":"state-reactivity"},{"number":21,"slug":"canonical-color-tokens","title":"Canonical Color Tokens vs Semantic Intents","description":"Using non canonical color tokens creates incompatibility and design drift. Components must rely on a stable token contract.","keywords":["canonical color tokens","design system token standard","semantic intent mapping","frontend token contract"],"canonical":"https://canonrs.dev/rules/canonical-color-tokens","category":"design-system"},{"number":22,"slug":"tailwind-v4-rust-integration","title":"Tailwind v4 + Rust Integration","description":"Tailwind jit cannot parse rust syntax for arbitrary values, causing missing utilities and styling failures. Pre compilation is required.","keywords":["tailwind rust integration","jit rust parsing issue","css utility precompile","frontend tailwind architecture"],"canonical":"https://canonrs.dev/rules/tailwind-v4-rust-integration","category":"build-tooling"},{"number":23,"slug":"state-tokens","title":"State Tokens (Hover, Focus, Disabled, Pressed)","description":"Using color variants for interaction states breaks theme portability and consistency. State behavior must be standardized via tokens.","keywords":["state tokens design system","css hover focus tokens","opacity state pattern","frontend interaction tokens"],"canonical":"https://canonrs.dev/rules/state-tokens","category":"design-system"},{"number":24,"slug":"density-size-scaling","title":"Density & Size Scaling","description":"Inconsistent sizing and density break visual harmony and usability. A unified scaling system ensures predictable layouts.","keywords":["density scaling design system","modular scale ui tokens","responsive size tokens css","frontend spacing architecture"],"canonical":"https://canonrs.dev/rules/density-size-scaling","category":"design-system"},{"number":25,"slug":"theme-presets-contract","title":"Theme Presets Contract","description":"Themes defining non-color properties cause fragmentation and break system consistency. Theme scope must be strictly limited to color palettes.","keywords":["theme presets contract design system","color only theme architecture","design system theme constraints","css theming token rules"],"canonical":"https://canonrs.dev/rules/theme-presets-contract","category":"design-system"},{"number":26,"slug":"elevation-shadow-system","title":"Elevation & Shadow System","description":"Inconsistent shadow usage breaks visual hierarchy and theme predictability. Elevation must be standardized through system tokens.","keywords":["shadow tokens design system","elevation hierarchy css","z index layering tokens","frontend shadow system"],"canonical":"https://canonrs.dev/rules/elevation-shadow-system","category":"design-system"},{"number":27,"slug":"motion-timing-tokens","title":"Motion & Timing Tokens","description":"Hardcoded animation values create inconsistency and accessibility issues. Motion must be tokenized.","keywords":["motion timing tokens css","animation duration tokens","frontend easing functions design system","accessibility motion preferences"],"canonical":"https://canonrs.dev/rules/motion-timing-tokens","category":"design-system"},{"number":28,"slug":"responsive-grid-contract","title":"Responsive Grid Contract","description":"Inconsistent breakpoints and grid systems create unpredictable layouts across devices. A unified mobile-first grid contract ensures consistency.","keywords":["responsive grid 12 column system","mobile first breakpoints css","layout consistency design system","tailwind grid responsive patterns"],"canonical":"https://canonrs.dev/rules/responsive-grid-contract","category":"component-architecture"},{"number":29,"slug":"typography-contract","title":"Typography Contract","description":"Typography inconsistency reduces readability and breaks design system coherence. A strict typographic scale ensures hierarchy and accessibility.","keywords":["typography scale design system","font tokens css system","wcag readable text guidelines","responsive typography patterns"],"canonical":"https://canonrs.dev/rules/typography-contract","category":"design-system"},{"number":30,"slug":"iconography-system","title":"Iconography System","description":"Using inconsistent icon systems or raster assets degrades performance and accessibility. A unified SVG-based system ensures consistency.","keywords":["svg icon system design","lucide icons usage frontend","accessible icons aria patterns","icon size scale ui system"],"canonical":"https://canonrs.dev/rules/iconography-system","category":"design-system"},{"number":31,"slug":"accessibility-contract","title":"Accessibility Contract (ARIA + Roles)","description":"Lack of accessibility standards leads to unusable interfaces for assistive technologies. Strict WCAG compliance is required.","keywords":["wcag accessibility frontend","aria roles implementation","keyboard navigation ui","accessible components design"],"canonical":"https://canonrs.dev/rules/accessibility-contract","category":"accessibility"},{"number":32,"slug":"theme-persistence-contract","title":"Theme Persistence Contract","description":"Using client-only storage for theme state causes SSR mismatch and visual flash. Persistence must be SSR-safe.","keywords":["theme persistence ssr cookies","avoid flash of incorrect theme","leptos theme hydration","cookie based ui state"],"canonical":"https://canonrs.dev/rules/theme-persistence-contract","category":"state-reactivity"},{"number":33,"slug":"density-accessibility-mapping","title":"Density & Accessibility Mapping","description":"Incorrect density scaling can break accessibility and usability across devices. Density must respect WCAG constraints.","keywords":["density scaling accessibility wcag","ui density tokens design system","touch target minimum size","responsive density mapping"],"canonical":"https://canonrs.dev/rules/density-accessibility-mapping","category":"accessibility"},{"number":34,"slug":"theme-density-enforcement","title":"Theme & Density Enforcement (Lint Rules)","description":"Manual enforcement of theme and density rules leads to inconsistency and drift. Automated validation is required.","keywords":["design system lint rules","ci enforcement tokens css","frontend rule validation","automated ui compliance checks"],"canonical":"https://canonrs.dev/rules/theme-density-enforcement","category":"governance"},{"number":35,"slug":"token-usage-validation","title":"Token Usage Validation","description":"Hardcoded visual values break consistency and scalability of the design system. Token usage must be enforced.","keywords":["design system token validation","css token enforcement rules","frontend style consistency check","avoid hardcoded ui values"],"canonical":"https://canonrs.dev/rules/token-usage-validation","category":"design-system"},{"number":36,"slug":"component-compliance-levels","title":"Component Compliance Levels","description":"Without defined compliance levels, components cannot balance strict rules and real constraints. Classification is required.","keywords":["component compliance levels design system","frontend rule enforcement levels","ui component governance classification","design system compliance model"],"canonical":"https://canonrs.dev/rules/component-compliance-levels","category":"governance"},{"number":37,"slug":"provider-taxonomy-boundaries","title":"Provider Taxonomy & Boundaries","description":"Mixing provider responsibilities causes coupling and SSR issues. Providers must remain orthogonal.","keywords":["provider architecture design system","reactive providers separation","ssr safe providers leptos","frontend context boundaries"],"canonical":"https://canonrs.dev/rules/provider-taxonomy-boundaries","category":"component-architecture"},{"number":38,"slug":"theme-engine-contract","title":"Theme Engine Contract","description":"Multiple components writing css variables causes inconsistency and conflicts. A single engine must control output.","keywords":["theme engine css variables","design system theme computation","centralized theming architecture","frontend css variable management"],"canonical":"https://canonrs.dev/rules/theme-engine-contract","category":"design-system"},{"number":39,"slug":"settings-ui-compliance","title":"Settings UI Compliance","description":"Settings components mixing persistence and state logic break separation of concerns. UI must remain stateless.","keywords":["settings ui stateless pattern","callback driven ui design","frontend provider interaction","design system settings components"],"canonical":"https://canonrs.dev/rules/settings-ui-compliance","category":"component-architecture"},{"number":40,"slug":"legacy-exception-annotation","title":"canon-rule-40-legacy-exception-annotation","description":"Legacy code without annotation introduces hidden violations and inconsistency. Exceptions must be explicit.","keywords":["legacy exception annotation pattern","code governance exceptions","frontend rule override annotation","technical debt tracking system"],"canonical":"https://canonrs.dev/rules/legacy-exception-annotation","category":"governance"},{"number":41,"slug":"leptos-resource-consumption","title":"Leptos Resource Consumption Contract","description":"Treating Resource as Future breaks reactivity and causes silent rendering failures. It must be consumed correctly.","keywords":["leptos resource get vs await","reactive resource consumption","ssr resource pattern leptos","transition component usage"],"canonical":"https://canonrs.dev/rules/leptos-resource-consumption","category":"state-reactivity"},{"number":42,"slug":"ui-data-surfaces","title":"UI Data Surfaces","description":"Duplicating components per data strategy creates redundancy and complexity. Data must be abstracted.","keywords":["ui adapter pattern data source","single renderer multiple data sources","frontend virtual table architecture","data abstraction components"],"canonical":"https://canonrs.dev/rules/ui-data-surfaces","category":"component-architecture"},{"number":43,"slug":"domain-components-and-commands","title":"Domain Components and Commands","description":"Mixing state mutation and rendering inside the same component breaks CQRS and leads to tightly coupled UI logic. Domain components must remain read-only while command execution is delegated to a separate layer.","keywords":["cqrs frontend leptos","separate read write components","domain vs command components","leptos state mutation pattern"],"canonical":"https://canonrs.dev/rules/domain-components-and-commands","category":"component-architecture"},{"number":44,"slug":"orchestrators","title":"Orchestrators","description":"Coupling domain rendering with command execution removes separation of concerns and breaks SSR safety. Orchestrators act as a coordination layer between read and write components without introducing business logic.","keywords":["orchestrator pattern frontend","leptos cqrs coordination","signals refresh pattern","callback coordination ui"],"canonical":"https://canonrs.dev/rules/orchestrators","category":"state-reactivity"},{"number":45,"slug":"demo-components","title":"Demo Components & Ephemeral State","description":"Using production-grade patterns in demos introduces unnecessary complexity and hides the core concept being demonstrated. Demo components should prioritize clarity over architectural correctness.","keywords":["demo vs production components","leptos signals demo pattern","avoid over engineering examples","ui documentation patterns"],"canonical":"https://canonrs.dev/rules/demo-components","category":"governance"},{"number":46,"slug":"command-palette-intent-surfaces","title":"Command Palette & Intent Surfaces","description":"Relying solely on buttons for actions leads to UI clutter and poor scalability. A command palette decouples user intent from visual elements and centralizes action execution.","keywords":["command palette frontend architecture","intent surface ui pattern","command registry design","keyboard driven ui commands"],"canonical":"https://canonrs.dev/rules/command-palette-intent-surfaces","category":"behavior"},{"number":47,"slug":"tree-context-selection","title":"Tree, Context & Selection","description":"Coupling navigation components with actions or business logic leads to rigid and non-scalable systems. Tree structures must expose only hierarchy and selection while delegating actions to command systems.","keywords":["tree selection context pattern","frontend navigation decoupling","command registry contextual actions","hierarchical ui design pattern"],"canonical":"https://canonrs.dev/rules/tree-context-selection","category":"component-architecture"},{"number":48,"slug":"context-provider","title":"Context Provider Pattern","description":"Passing state through multiple component layers creates prop drilling and tightly coupled APIs. Context providers centralize state and allow components to consume it directly.","keywords":["leptos context provider pattern","avoid prop drilling frontend","global state sharing signals","context vs props architecture"],"canonical":"https://canonrs.dev/rules/context-provider","category":"state-reactivity"},{"number":49,"slug":"drag-drop-as-intent","title":"Drag & Drop as Intent (Not Action)","description":"Embedding business logic directly inside drag-and-drop handlers couples UI gestures with domain logic. Drag operations should emit intent events that are later converted into commands.","keywords":["drag drop command pattern","event driven ui architecture","decoupled drag and drop","undo redo drag operations"],"canonical":"https://canonrs.dev/rules/drag-drop-as-intent","category":"behavior"},{"number":50,"slug":"provider-singleton-pattern","title":"Provider Singleton & Runtime Separation","description":"Duplicating providers creates parallel reactive contexts leading to invisible bugs and broken interactions. Provider lifecycle must be controlled centrally.","keywords":["provider singleton pattern","leptos context duplication","reactive runtime separation","provider scope architecture"],"canonical":"https://canonrs.dev/rules/provider-singleton-pattern","category":"state-reactivity"},{"number":51,"slug":"callbacks-as-commands","title":"Callbacks as Commands","description":"Direct state mutations inside UI callbacks prevent undo, replay, and audit capabilities. This breaks command-based architectures and tightly couples UI with side effects.","keywords":["callbacks as commands pattern","command pattern ui architecture","leptos callback command execution","cqrs ui callbacks"],"canonical":"https://canonrs.dev/rules/callbacks-as-commands","category":"behavior"},{"number":52,"slug":"command-history-runtime","title":"Command History as First-Class Runtime","description":"Local command histories fragment state management and prevent global undo and replay. A centralized runtime provider is required for consistency across components.","keywords":["command history provider pattern","global undo redo architecture","leptos command history context","shared state command runtime"],"canonical":"https://canonrs.dev/rules/command-history-runtime","category":"state-reactivity"},{"number":53,"slug":"client-only-runtime-islands","title":"Client-Only Runtime Islands","description":"Accessing browser APIs during SSR causes panics and hydration mismatches in Leptos. Code that depends on window, document, or wasm-specific features must be isolated into client-only runtime islands.","keywords":["leptos ssr panic window","wasm32 cfg leptos","hydration mismatch leptos","client only islands rust"],"canonical":"https://canonrs.dev/rules/client-only-runtime-islands","category":"core-runtime"},{"number":54,"slug":"render-must-be-total","title":"canon-rule-54-render-must-be-total","description":"Render closures in Leptos are executed during SSR and must never panic. Using unwrap or expect inside reactive attributes introduces runtime failures before user interaction.","keywords":["leptos render panic","ssr safe closures","reactive attribute unwrap","total rendering pattern"],"canonical":"https://canonrs.dev/rules/render-must-be-total","category":"state-reactivity"},{"number":55,"slug":"canonical-css-entry-points","title":"Canonical CSS Entry Points","description":"Importing CSS from internal folders creates fragile dependencies and breaks monorepo scalability. Design system styles must be consumed only through canonical workspace packages.","keywords":["monorepo css architecture","canonical css packages","postcss resolve imports","design system distribution css"],"canonical":"https://canonrs.dev/rules/canonical-css-entry-points","category":"styling-css"},{"number":56,"slug":"monorepo-css-build-pipeline","title":"Monorepo CSS Build Pipeline","description":"Directly importing CSS from generators or crates breaks build consistency and portability. CSS must be generated and copied into canonical packages as immutable artifacts.","keywords":["css build pipeline monorepo","design tokens build artifacts","copy vs link css","canonical dist css"],"canonical":"https://canonrs.dev/rules/monorepo-css-build-pipeline","category":"build-tooling"},{"number":57,"slug":"postcss-canon-config","title":"PostCSS Canon Configuration","description":"Incorrect PostCSS configuration breaks module resolution and CSS ordering in monorepos. Canon setup requires ESM config, proper plugin order, and strict import sequencing.","keywords":["postcss esm config","tailwind postcss plugin order","css import resolution node","postcss canonical setup"],"canonical":"https://canonrs.dev/rules/postcss-canon-config","category":"build-tooling"},{"number":58,"slug":"leptos-assets-dev-constraint","title":"Leptos Assets Dev Constraint","description":"Leptos dev server silently fails to serve nested asset paths, returning placeholder responses. Only first-level files in the assets directory are valid during development.","keywords":["leptos assets dir limitation","css not loading leptos dev","leptos public folder rules","tailwind leptos dev fix"],"canonical":"https://canonrs.dev/rules/leptos-assets-dev-constraint","category":"build-tooling"},{"number":59,"slug":"css-cascade-ownership","title":"CSS Cascade Ownership","description":"Multiple CSS bundles without defined precedence create unpredictable styling behavior. A single stylesheet must own the final cascade to ensure deterministic rendering.","keywords":["css cascade control","single stylesheet architecture","css layering strategy","design system precedence"],"canonical":"https://canonrs.dev/rules/css-cascade-ownership","category":"styling-css"},{"number":60,"slug":"css-artifacts-are-immutable","title":"CSS Artifacts Are Immutable","description":"Editing generated CSS artifacts introduces drift and breaks reproducibility. All changes must originate from the generator and propagate via rebuild.","keywords":["immutable build artifacts css","design system build consistency","css generation pipeline","no manual patch dist css"],"canonical":"https://canonrs.dev/rules/css-artifacts-are-immutable","category":"build-tooling"},{"number":61,"slug":"no-relative-css-imports","title":"No Relative CSS Imports","description":"Relative CSS imports create brittle dependencies that break with refactors and prevent package portability. Only canonical package imports should be used across boundaries.","keywords":["relative css imports problem","monorepo css imports","canonical css packages","postcss path resolution"],"canonical":"https://canonrs.dev/rules/no-relative-css-imports","category":"styling-css"},{"number":62,"slug":"single-source-of-truth-tokens","title":"Single Source of Truth for Design Tokens","description":"Multiple token definitions across files lead to divergence and inconsistency in design systems. Tokens must exist in a single canonical source and propagate through build artifacts.","keywords":["design tokens single source","tailwind tokens architecture","css tokens monorepo","design system consistency"],"canonical":"https://canonrs.dev/rules/single-source-of-truth-tokens","category":"design-system"},{"number":63,"slug":"leptos-reactivity-closures","title":"Leptos Reactivity - No .get() Outside Closures","description":"Accessing reactive values outside tracked closures breaks dependency tracking in Leptos. Calling .get() outside reactive contexts results in stale UI and prevents automatic re-rendering.","keywords":["leptos memo get closure","reactive tracking leptos","signal vs memo leptos","leptos stale ui fix"],"canonical":"https://canonrs.dev/rules/leptos-reactivity-closures","category":"state-reactivity"},{"number":64,"slug":"css-build-pipeline-mandatory","title":"CSS Build Pipeline is Mandatory","description":"Leptos does not generate CSS automatically, leading to missing styles when Tailwind is not built explicitly. CSS must be produced through a dedicated build step before runtime.","keywords":["leptos css missing","tailwind build pipeline leptos","css not generated leptos","tailwind cli build step"],"canonical":"https://canonrs.dev/rules/css-build-pipeline-mandatory","category":"build-tooling"},{"number":65,"slug":"theme-provider-dom-sync","title":"data-theme Sync is ThemeProvider Responsibility","description":"Theme state in Rust signals does not affect CSS unless synchronized to the DOM. Without updating attributes like data-theme, styles based on selectors never activate.","keywords":["leptos themeprovider dom sync","data theme attribute css","leptos theming signals dom","css tokens not applying"],"canonical":"https://canonrs.dev/rules/theme-provider-dom-sync","category":"design-system"},{"number":66,"slug":"workbench-setup-checklist","title":"Workbench Setup Checklist","description":"Skipping initial environment validation leads to hidden configuration issues such as missing CSS pipelines. A mandatory checklist ensures system readiness before development begins.","keywords":["leptos setup checklist","css pipeline validation","tailwind setup verification","monorepo environment validation"],"canonical":"https://canonrs.dev/rules/workbench-setup-checklist","category":"governance"},{"number":67,"slug":"leptos-csr-css-loading","title":"Leptos CSR Does NOT Load CSS via `<Stylesheet />`","description":"In CSR mode, Leptos does not inject CSS using the Stylesheet component. Applications relying on it fail to load styles because no HTML link tag is created.","keywords":["leptos csr stylesheet issue","css not loading leptos csr","leptos meta stylesheet csr","html link css leptos"],"canonical":"https://canonrs.dev/rules/leptos-csr-css-loading","category":"core-runtime"},{"number":68,"slug":"asset-must-exist-in-dist","title":"Asset Must Exist in Final dist/","description":"Referencing assets that do not exist in the final dist directory causes silent runtime failures. Build outputs must be physically verified before deployment.","keywords":["dist assets verification","missing css dist","build output validation","trunk asset missing"],"canonical":"https://canonrs.dev/rules/asset-must-exist-in-dist","category":"build-tooling"},{"number":69,"slug":"trunk-only-serves-dist","title":"Trunk Only Serves What's in dist/","description":"Trunk serves only files present in the dist directory, ignoring source folders like public or style. Misunderstanding this leads to missing assets at runtime.","keywords":["trunk dist assets","leptos trunk css 404","trunk asset pipeline","dist only serving trunk"],"canonical":"https://canonrs.dev/rules/trunk-only-serves-dist","category":"build-tooling"},{"number":70,"slug":"css-pipeline-health-checks","title":"CSS Pipeline Requires Health Checks","description":"CSS build pipelines can fail silently, producing empty or incomplete outputs. Automated validation is required to guarantee correctness before runtime.","keywords":["css pipeline validation","tailwind verify build","css health check script","missing css classes detection"],"canonical":"https://canonrs.dev/rules/css-pipeline-health-checks","category":"build-tooling"},{"number":71,"slug":"debug-theme-verify-file-first","title":"Debug Theme by Verifying File First","description":"Most theming issues originate from missing or broken CSS files, not application logic. Debugging must start by verifying file existence and loading.","keywords":["debug css file first","leptos theme debugging","missing css file fix","verify stylesheet loading"],"canonical":"https://canonrs.dev/rules/debug-theme-verify-file-first","category":"governance"},{"number":72,"slug":"layout-h1-prohibition","title":"Layout H1 Prohibition","description":"Using multiple h1 elements across layout and page components breaks semantic structure and accessibility. Layouts must not define document identity elements.","keywords":["html h1 best practice","multiple h1 accessibility issue","semantic heading structure","wcag heading hierarchy"],"canonical":"https://canonrs.dev/rules/layout-h1-prohibition","category":"accessibility"},{"number":73,"slug":"componentpage-template-contract","title":"ComponentPage Template Contract","description":"Reimplementing documentation page structure in product code creates duplication and inconsistency across components. Component pages must delegate structure to a centralized template to maintain a single source of truth.","keywords":["componentpage template leptos","design system ssot template","avoid duplicated page layout","leptos component documentation pattern"],"canonical":"https://canonrs.dev/rules/componentpage-template-contract","category":"component-architecture"},{"number":74,"slug":"block-semantic-html","title":"Block Semantic HTML","description":"Improper HTML semantics in design system blocks break accessibility, screen reader navigation, and document hierarchy. Blocks must enforce semantic structure with ARIA attributes and correct heading levels.","keywords":["wcag semantic html blocks","aria labelledby section pattern","heading hierarchy accessibility","accessible table markup"],"canonical":"https://canonrs.dev/rules/block-semantic-html","category":"accessibility"},{"number":75,"slug":"primitive-css-prohibition","title":"Primitive CSS Prohibition","description":"Adding CSS or visual logic to primitives breaks architectural separation and portability. Primitives must remain pure structural HTML without styling or responsive logic.","keywords":["primitive vs ui separation","no css in primitives","design system layering","leptos primitive architecture"],"canonical":"https://canonrs.dev/rules/primitive-css-prohibition","category":"design-system"},{"number":76,"slug":"navigation-vs-action-contract","title":"Navigation vs Action Component Contract","description":"Mixing navigation and action semantics creates invalid HTML and accessibility issues. Components must strictly separate link navigation from button actions.","keywords":["a vs button html semantics","invalid nested interactive elements","navigation vs action components","accessibility button link rules"],"canonical":"https://canonrs.dev/rules/navigation-vs-action-contract","category":"component-architecture"},{"number":77,"slug":"monorepo-path-stability","title":"Monorepo Path Stability","description":"Hardcoded paths in monorepo configurations break builds during refactors and environment changes. Path resolution must be relative and dynamically calculated.","keywords":["monorepo path resolution","relative path config js","postcss path issues","cargo workspace path dependency"],"canonical":"https://canonrs.dev/rules/monorepo-path-stability","category":"build-tooling"},{"number":78,"slug":"token-definition-completeness","title":"Token Definition Completeness","description":"Partial use of design tokens creates inconsistent UI and breaks theming. Components must fully adopt all applicable tokens without hardcoded values.","keywords":["design token completeness","no hardcoded css values","token based theming","css variables system design"],"canonical":"https://canonrs.dev/rules/token-definition-completeness","category":"design-system"},{"number":79,"slug":"componentpage-template-contract","title":"ComponentPage Template Contract","description":"Using generic layout classes in templates causes inconsistent page structure and styling conflicts. ComponentPage must enforce canonical layout classes for centralized control.","keywords":["canon page layout classes","centralized layout template","component page css contract","design system layout consistency"],"canonical":"https://canonrs.dev/rules/componentpage-template-contract","category":"design-system"},{"number":80,"slug":"workspace-watch-configuration","title":"Workspace Watch Configuration","description":"cargo-leptos does not monitor external path dependencies by default, causing stale builds during development. Explicit watch configuration is required for local packages.","keywords":["cargo leptos watch additional files","rust watch path dependency","leptos hot reload issue","monorepo watch config"],"canonical":"https://canonrs.dev/rules/workspace-watch-configuration","category":"build-tooling"},{"number":81,"slug":"flex-layout-ownership","title":"Flex Layout Ownership","description":"Incorrect flex ownership causes layout inconsistencies and unpredictable sizing. Flex growth must be controlled by parent and UI layers, not primitives.","keywords":["flex grow not working","flexbox parent child contract","ui wrapper flex pattern","leptos flex layout issue"],"canonical":"https://canonrs.dev/rules/flex-layout-ownership","category":"component-architecture"},{"number":82,"slug":"css-build-pipeline-health","title":"CSS Build Pipeline Health","description":"CSS changes do not propagate automatically without explicit compilation, leading to stale styles in development. The build pipeline must be executed and validated for every change.","keywords":["postcss build required","css not updating leptos","tailwind build pipeline issue","compiled css not refreshed"],"canonical":"https://canonrs.dev/rules/css-build-pipeline-health","category":"build-tooling"},{"number":83,"slug":"layout-zones-contract","title":"Layout Zones Contract","description":"Unstructured layouts lead to inconsistent UI hierarchy and unpredictable responsive behavior. Canon enforces fixed spatial zones to standardize component placement and eliminate layout ambiguity.","keywords":["layout zones architecture","ui spatial hierarchy system","canonical layout containers","component placement rules"],"canonical":"https://canonrs.dev/rules/layout-zones-contract","category":"component-architecture"},{"number":84,"slug":"svg-dark-mode-contract","title":"SVG Dark Mode Contract","description":"SVG files loaded via img tags do not inherit CSS properties like currentColor, causing incorrect colors in dark mode. Proper strategies are required to ensure theming compatibility.","keywords":["svg currentcolor not working","img svg css inheritance","dark mode svg fix","svg color css filter"],"canonical":"https://canonrs.dev/rules/svg-dark-mode-contract","category":"styling-css"},{"number":85,"slug":"leptos-asset-pipeline-dev","title":"Leptos Asset Pipeline in Dev Mode","description":"Leptos development mode does not use Trunk for asset handling, leading to missing files when relying on Trunk hooks. Assets must be served from the configured public directory.","keywords":["leptos asset pipeline dev","trunk ignored leptos watch","public assets directory leptos","leptos asset serving config"],"canonical":"https://canonrs.dev/rules/leptos-asset-pipeline-dev","category":"build-tooling"},{"number":86,"slug":"children-childrenfn-contract","title":"Children vs ChildrenFn Contract","description":"Using the wrong children type in Leptos components causes FnOnce errors and broken reactivity. Components must correctly distinguish between Children and ChildrenFn.","keywords":["leptos childrenfn vs children","fnonce vs fn leptos","leptos wrapper component children","leptos reactive children pattern"],"canonical":"https://canonrs.dev/rules/children-childrenfn-contract","category":"state-reactivity"},{"number":87,"slug":"leptos-ssr-script-placement","title":"Leptos SSR Script Placement","description":"Scripts placed in index.html execute before hydration and bind to stale DOM nodes, causing inconsistent behavior. Proper placement ensures scripts run against the hydrated DOM.","keywords":["leptos script placement ssr","hydration event binding issue","index html script problem","leptos shell script injection"],"canonical":"https://canonrs.dev/rules/leptos-ssr-script-placement","category":"core-runtime"},{"number":89,"slug":"primitives-no-browser-apis","title":"Primitives Must Never Touch Browser APIs","description":"Accessing browser APIs inside primitives breaks SSR compatibility and violates architectural separation. Primitives must remain environment-agnostic.","keywords":["no browser api primitives","ssr safe components design","leptos primitives architecture","separation runtime js"],"canonical":"https://canonrs.dev/rules/primitives-no-browser-apis","category":"component-architecture"},{"number":90,"slug":"hydration-is-dom-replacement","title":"Hydration Is DOM Replacement, Not Enhancement","description":"Assuming hydration enhances existing DOM leads to broken interactions and lost event bindings. Hydration replaces nodes entirely, invalidating pre-existing references.","keywords":["hydration dom replacement","leptos hydration behavior","ssr dom identity issue","event listener lost hydration"],"canonical":"https://canonrs.dev/rules/hydration-is-dom-replacement","category":"core-runtime"},{"number":91,"slug":"markdown-render-only","title":"Markdown and Code Blocks Are Render-Only","description":"Embedding behavior inside markdown components creates SSR coupling and unreliable runtime behavior. Markdown must remain purely declarative.","keywords":["markdown render only pattern","separate behavior from content","leptos markdown components","ssr safe markdown rendering"],"canonical":"https://canonrs.dev/rules/markdown-render-only","category":"component-architecture"},{"number":92,"slug":"ssr-debug-heuristic","title":"If It Works in Prod but Not Dev, Suspect Hydration Order","description":"Differences between development and production behavior often indicate hydration timing issues. Recognizing this pattern reduces debugging time.","keywords":["ssr debug heuristic","hydration timing issue","dev vs prod behavior","leptos hydration debugging"],"canonical":"https://canonrs.dev/rules/ssr-debug-heuristic","category":"governance"},{"number":93,"slug":"leptos-wasm-dev-builds-must-use-release-mode","title":"Leptos WASM Dev Builds Must Use Release Mode","description":"Debug-mode WASM builds are too large and slow for interactive development, causing browser freezes and misleading debugging. Development must use optimized builds.","keywords":["leptos wasm release mode","wasm debug build size issue","browser stall wasm","cargo leptos watch release"],"canonical":"https://canonrs.dev/rules/leptos-wasm-dev-builds-must-use-release-mode","category":"build-tooling"},{"number":94,"slug":"leptos-workspace-features-must-be-explicit","title":"Leptos Workspace Features Must Be Explicit","description":"Leptos macro expansion fails when required features like nightly are not declared at the workspace level. Missing workspace feature flags cause cascading E0282 errors in view! macros despite correct code.","keywords":["leptos workspace features nightly","cargo workspace feature resolution","leptos E0282 error fix","view macro type inference leptos"],"canonical":"https://canonrs.dev/rules/leptos-workspace-features-must-be-explicit","category":"build-tooling"},{"number":95,"slug":"ssr-requires-complete-html-shell","title":"SSR Requires Complete HTML Shell","description":"Leptos SSR requires a full HTML document structure to support meta injection and hydration. Missing html head or body tags causes runtime panics and empty responses.","keywords":["leptos ssr html shell","leptos_meta head tag error","hydration scripts placement leptos","ssr empty response fix"],"canonical":"https://canonrs.dev/rules/ssr-requires-complete-html-shell","category":"core-runtime"},{"number":96,"slug":"ssr-requires-explicit-provider-tree","title":"SSR Requires Explicit Provider Tree","description":"SSR in Leptos does not auto-inject context providers, causing runtime panics when contexts are missing. All required providers must be explicitly declared in the component tree.","keywords":["leptos provider tree ssr","context not found leptos fix","leptos theme provider missing","ssr provider dependency order"],"canonical":"https://canonrs.dev/rules/ssr-requires-explicit-provider-tree","category":"state-reactivity"},{"number":97,"slug":"leptos-08-requires-floating-nightly-toolchain","title":"Leptos 0.8 Requires Floating Nightly Toolchain","description":"Pinned nightly toolchains or minor versions break compatibility with Leptos 0.8 due to evolving unstable features. Floating versions are required to maintain compatibility.","keywords":["leptos nightly toolchain required","rustc version mismatch leptos","floating version cargo leptos","leptos edition2024 error"],"canonical":"https://canonrs.dev/rules/leptos-08-requires-floating-nightly-toolchain","category":"build-tooling"},{"number":98,"slug":"axum-leptos-ssr-closures-must-own-state","title":"Axum + Leptos SSR Closures Must Own State","description":"Sharing state across Axum router closures causes borrow checker errors due to move semantics. Each closure must own its own cloned state to satisfy lifetime requirements.","keywords":["axum closure ownership rust","borrow of moved value fix","leptos options clone closure","rust move closure pattern"],"canonical":"https://canonrs.dev/rules/axum-leptos-ssr-closures-must-own-state","category":"component-architecture"},{"number":99,"slug":"csr-islands-must-not-own-routing-or-providers","title":"CSR Islands Must Not Own Routing or Providers","description":"CSR islands in SSR architectures must remain isolated UI units without owning routing or global providers. Violations cause hydration mismatches and context conflicts.","keywords":["csr islands architecture ssr","leptos islands routing conflict","provider duplication issue","hydration mismatch islands"],"canonical":"https://canonrs.dev/rules/csr-islands-must-not-own-routing-or-providers","category":"core-runtime"},{"number":100,"slug":"build-orchestrators-must-be-workspace-scoped","title":"Build Orchestrators Must Be Workspace-Scoped","description":"Build orchestrator configuration in Leptos fails when defined at crate level instead of workspace root. Tools like cargo-leptos require centralized metadata to resolve paths, assets, and hot reload correctly.","keywords":["cargo leptos workspace config","leptos build metadata error","workspace metadata leptos","cargo leptos configuration root"],"canonical":"https://canonrs.dev/rules/build-orchestrators-must-be-workspace-scoped","category":"build-tooling"},{"number":101,"slug":"workbench-assets-must-be-product-scoped","title":"Workbench Assets Must Be Product-Scoped","description":"Placing illustrative assets inside the design system creates coupling and violates separation of concerns. Design systems must remain focused on primitives and behavior, not product-specific visuals.","keywords":["design system asset scope","product scoped assets","monorepo asset ownership","ui illustration separation"],"canonical":"https://canonrs.dev/rules/workbench-assets-must-be-product-scoped","category":"governance"},{"number":102,"slug":"runtime-js-is-shell-infrastructure","title":"Runtime JS Is Shell Infrastructure","description":"Embedding runtime JavaScript logic inside components breaks separation of concerns and leads to inconsistent behavior. Interaction logic like clipboard and event handling must be centralized.","keywords":["leptos runtime js separation","shell infrastructure js","component event handling architecture","js behavior separation ui"],"canonical":"https://canonrs.dev/rules/runtime-js-is-shell-infrastructure","category":"behavior"},{"number":103,"slug":"critical-runtime-js-must-be-inline-in-ssr","title":"Critical Runtime JS Must Be Inline in SSR","description":"External runtime scripts in Leptos SSR environments execute unpredictably due to script ordering issues. This leads to silent failures where listeners do not attach correctly after hydration.","keywords":["leptos ssr script order","hydration script race condition","inline runtime js ssr","leptos event listener fail"],"canonical":"https://canonrs.dev/rules/critical-runtime-js-must-be-inline-in-ssr","category":"core-runtime"},{"number":104,"slug":"autoreload-breaks-script-order-guarantees","title":"AutoReload Breaks Script Order Guarantees","description":"Leptos AutoReload injects scripts dynamically, breaking execution order guarantees. This causes runtime scripts to execute in unexpected phases, leading to intermittent failures.","keywords":["leptos autoreload script order","ssr hot reload issue","script execution race leptos","autoreload injection problem"],"canonical":"https://canonrs.dev/rules/autoreload-breaks-script-order-guarantees","category":"build-tooling"},{"number":105,"slug":"visual-indicators-must-have-a-single-owner","title":"canon-rule-105-visual-indicators-must-have-a-single-owner","description":"Splitting visual indicators across multiple components creates ambiguity and fragile styling. This leads to duplicated visuals and patch-based fixes.","keywords":["ui visual ownership pattern","component indicator duplication","ui architecture ownership","css visual conflict"],"canonical":"https://canonrs.dev/rules/visual-indicators-must-have-a-single-owner","category":"component-architecture"},{"number":106,"slug":"ui-neutralizes-hostile-css-not-primitives","title":"canon-rule-106-ui-neutralizes-hostile-css-not-primitives","description":"Applying CSS fixes inside primitives breaks architectural layering and contaminates core abstractions. Global CSS issues must be handled at the UI layer.","keywords":["ui css neutralization pattern","primitive purity css","layer separation ui css","design system layering css"],"canonical":"https://canonrs.dev/rules/ui-neutralizes-hostile-css-not-primitives","category":"component-architecture"},{"number":107,"slug":"token-architecture-theme-specificity","title":"Token Architecture & Theme Specificity","description":"Incorrect token placement in CSS creates specificity conflicts and prevents themes from overriding values. Mixing structural and color tokens leads to unpredictable behavior.","keywords":["css token architecture","theme specificity css","design system tokens separation","css variable override issue"],"canonical":"https://canonrs.dev/rules/token-architecture-theme-specificity","category":"design-system"},{"number":108,"slug":"visual-surfaces-contract","title":"Visual Surfaces Contract","description":"Inconsistent visual hierarchy arises when components define their own styling instead of using semantic surfaces. This leads to design drift and complex dark mode handling.","keywords":["design system surfaces","css surface tokens","semantic ui surfaces","token based styling components"],"canonical":"https://canonrs.dev/rules/visual-surfaces-contract","category":"design-system"},{"number":111,"slug":"model-first-css-second","title":"Model First, CSS Second","description":"Using CSS to compensate for architectural flaws leads to fragile systems and hidden technical debt. Structural issues must be resolved at the model level, not visually masked.","keywords":["css architecture anti pattern","model vs css responsibility","ui structure vs styling","css workaround problem"],"canonical":"https://canonrs.dev/rules/model-first-css-second","category":"component-architecture"},{"number":112,"slug":"ui-owns-visual-style","title":"UI Owns Visual Style","description":"Mixing visual styling into primitives breaks separation of concerns and reduces reusability. UI layer must exclusively control appearance while primitives remain structural.","keywords":["ui layer styling pattern","primitive vs ui separation","design system layering","css ownership ui layer"],"canonical":"https://canonrs.dev/rules/ui-owns-visual-style","category":"component-architecture"},{"number":113,"slug":"states-are-data-not-style","title":"States Are Data, Not Style","description":"Encoding state as visual style creates tight coupling and limits flexibility. State must remain semantic and independent from appearance to support scalable theming.","keywords":["state vs style css","data attributes state pattern","semantic state ui","css state mapping"],"canonical":"https://canonrs.dev/rules/states-are-data-not-style","category":"design-system"},{"number":114,"slug":"single-visual-authority","title":"Single Visual Authority","description":"Multiple layers rendering the same visual signal cause conflicts and unpredictable UI behavior. Visual responsibility must be uniquely assigned to a single component.","keywords":["visual authority ui pattern","duplicate ui signals","css ownership conflict","component visual ownership"],"canonical":"https://canonrs.dev/rules/single-visual-authority","category":"component-architecture"},{"number":115,"slug":"reset-awareness-and-boundaries","title":"Reset Awareness & CSS Boundaries","description":"Ignoring global CSS resets leads to inconsistent component behavior across environments. UI components must explicitly handle reset effects without breaking architectural layers.","keywords":["css reset handling ui","global css normalization issue","ui reset boundary pattern","css reset component conflict"],"canonical":"https://canonrs.dev/rules/reset-awareness-and-boundaries","category":"styling-css"},{"number":116,"slug":"wasm-externref-table-limits","title":"WASM Externref Table Limits","description":"Excessive JS↔WASM references exhaust browser externref tables, causing runtime crashes. Each callback or handler adds entries, leading to resource exhaustion at scale.","keywords":["wasm externref table limit","leptos callback memory issue","js wasm reference overflow","externref table grow error"],"canonical":"https://canonrs.dev/rules/wasm-externref-table-limits","category":"core-runtime"},{"number":117,"slug":"design-system-callbacks-are-props-not-handlers","title":"Design System Callbacks Are Props, Not Handlers","description":"Creating inline event handlers in UI components increases externref usage and leads to runtime crashes. Callback handling must be decoupled from component rendering.","keywords":["leptos callback props pattern","wasm event handler externref","ui callback architecture","design system event delegation"],"canonical":"https://canonrs.dev/rules/design-system-callbacks-are-props-not-handlers","category":"component-architecture"},{"number":118,"slug":"view-type-boundary","title":"View<\\_> Type Boundary Prohibition","description":"Using View<_> outside component boundaries causes type inference explosions and compilation failures. Open inference propagates across the codebase, breaking type resolution.","keywords":["rust view type inference","leptos anyview pattern","view generic error rust","type boundary leptos"],"canonical":"https://canonrs.dev/rules/view-type-boundary","category":"component-architecture"},{"number":119,"slug":"no-optional-into-ui-layer","title":"No #[prop(optional, into)] in UI Layer","description":"Using #[prop(optional, into)] in UI components causes type ambiguity and widespread compiler errors. It breaks ergonomics and increases complexity at call sites.","keywords":["leptos prop optional into error","ui component option types","leptos type inference props","rust option prop pattern"],"canonical":"https://canonrs.dev/rules/no-optional-into-ui-layer","category":"component-architecture"},{"number":120,"slug":"dom-events-vs-semantic-callbacks","title":"DOM Events vs Semantic Callbacks Boundary","description":"Mixing DOM events with semantic callbacks breaks abstraction boundaries and creates type confusion in Leptos components. UI APIs become coupled to browser details, leading to errors and inconsistent usage patterns.","keywords":["leptos dom vs semantic events","callback type mismatch rust leptos","ui event abstraction pattern","on_click vs on:click leptos"],"canonical":"https://canonrs.dev/rules/dom-events-vs-semantic-callbacks","category":"component-architecture"},{"number":121,"slug":"storedvalue-for-noncopy-in-view","title":"StoredValue for Non-Copy Values in view! Closures","description":"Leptos view closures require Fn semantics for reactivity, but moving non-Copy values forces FnOnce and breaks compilation. This commonly occurs when String, Vec, or structs are captured directly inside view! closures.","keywords":["leptos storedvalue usage","fnonce vs fn leptos","closure move error leptos","leptos non copy closure"],"canonical":"https://canonrs.dev/rules/storedvalue-for-noncopy-in-view","category":"state-reactivity"},{"number":122,"slug":"no-conditional-rendering-with-closures","title":"No Conditional Rendering with .then() Closures","description":"Using bool.then closures for conditional rendering introduces FnOnce semantics, type inference failures, and hydration mismatches. This creates unstable DOM structures and breaks reactive rendering.","keywords":["leptos show component","leptos conditional rendering fix","then closure leptos error","leptos hydration mismatch"],"canonical":"https://canonrs.dev/rules/no-conditional-rendering-with-closures","category":"component-architecture"},{"number":123,"slug":"component-architecture-taxonomy","title":"Component Architecture Taxonomy and Contracts","description":"Lack of strict component classification leads to boundary leakage, inconsistent responsibilities, and architectural decay. Without taxonomy, primitives, UI, and domain logic mix unpredictably.","keywords":["component architecture layers ui","design system taxonomy","primitive ui component separation","frontend architecture contracts"],"canonical":"https://canonrs.dev/rules/component-architecture-taxonomy","category":"component-architecture"},{"number":124,"slug":"primitive-contract-types","title":"Primitive Contract Types","description":"Primitives without strict contracts accumulate state, styling, and logic, breaking SSR safety and type clarity. Hybrid primitives introduce coupling and unpredictable behavior.","keywords":["primitive component rules","ssr safe primitives leptos","no prop into pattern rust","design system primitive types"],"canonical":"https://canonrs.dev/rules/primitive-contract-types","category":"component-architecture"},{"number":125,"slug":"ui-component-contracts","title":"UI Component Contracts","description":"UI components without strict contracts leak primitives, mix domain logic, and create type ambiguity. This results in poor ergonomics and inconsistent APIs across the design system.","keywords":["ui component patterns adapter controlled","leptos callback design","ui abstraction layer design","component api ergonomics"],"canonical":"https://canonrs.dev/rules/ui-component-contracts","category":"component-architecture"},{"number":126,"slug":"component-domain-contracts","title":"Component Domain Contracts","description":"Mixing domain logic with UI concerns creates untestable and tightly coupled components. Without clear contracts, business rules leak across layers and become inconsistent.","keywords":["domain component architecture","stateful vs orchestrator component","frontend business logic separation","reactive state management patterns"],"canonical":"https://canonrs.dev/rules/component-domain-contracts","category":"component-architecture"},{"number":127,"slug":"block-composition-contracts","title":"Block Composition Contracts","description":"Blocks without strict boundaries accumulate domain logic, routing, and global state, becoming unmanageable. This breaks separation between structure and behavior.","keywords":["block component architecture","semantic vs interactive blocks","frontend composition patterns","design system block layer"],"canonical":"https://canonrs.dev/rules/block-composition-contracts","category":"component-architecture"},{"number":128,"slug":"layout-shell-and-zone-contracts","title":"Layout Shell and Zone Contracts","description":"Layouts without strict classification mix structure with business logic, creating tightly coupled and untestable systems. This breaks reuse and introduces hidden dependencies.","keywords":["layout shell zone pattern","leptos layout architecture","separation layout business logic","structural layout contracts"],"canonical":"https://canonrs.dev/rules/layout-shell-and-zone-contracts","category":"component-architecture"},{"number":129,"slug":"ssr-event-safety","title":"SSR Event Safety","description":"Event handlers attached to dynamically generated nodes during SSR cause hydration mismatches due to non-deterministic listener reconstruction. This leads to runtime panics.","keywords":["leptos ssr event handler issue","hydration mismatch dynamic list","event handler iterator problem","ssr closure mismatch leptos"],"canonical":"https://canonrs.dev/rules/ssr-event-safety","category":"core-runtime"},{"number":130,"slug":"controlled-ui-contract","title":"Controlled UI Contract","description":"Passing plain values instead of signals to UI components breaks reactive updates and causes stale UI state. Components lose synchronization with application state.","keywords":["leptos signal ui pattern","reactive state ui components","signal vs value leptos","frontend reactivity architecture"],"canonical":"https://canonrs.dev/rules/controlled-ui-contract","category":"state-reactivity"},{"number":131,"slug":"reactive-boundary-ownership","title":"Reactive Boundary Ownership","description":"Reactive boundaries re-execute closures multiple times, and moving non-Copy values into them causes FnOnce violations. This leads to compilation failures and unstable reactive behavior.","keywords":["leptos reactive boundary ownership","storedvalue vs clone rust","closure ownership leptos","reactive closure fnonce error"],"canonical":"https://canonrs.dev/rules/reactive-boundary-ownership","category":"state-reactivity"},{"number":132,"slug":"layout-composition-over-abstraction","title":"Layout Composition Over Abstraction","description":"Layouts that orchestrate composition or manage slots introduce ownership issues and hydration mismatches. This leads to unpredictable rendering and tight coupling.","keywords":["layout composition pattern frontend","children ownership leptos","layout abstraction anti pattern","ssr layout issues leptos"],"canonical":"https://canonrs.dev/rules/layout-composition-over-abstraction","category":"component-architecture"},{"number":133,"slug":"children-consumption-locality","title":"Children Consumption Locality","description":"Passing Children across layers causes move errors and closure violations because Children is FnOnce. This breaks SSR rendering and introduces ownership complexity.","keywords":["leptos children fnonce issue","children ownership rust ui","view macro children error","reactive rendering children leptos"],"canonical":"https://canonrs.dev/rules/children-consumption-locality","category":"state-reactivity"},{"number":134,"slug":"layouts-are-css-and-semantics-only","title":"Layouts Are CSS and Semantics Only","description":"Embedding behavior or state inside layouts breaks structural purity and introduces coupling with UI logic. Layouts must remain deterministic and CSS-driven.","keywords":["layout css semantics only","stateless layout architecture","leptos layout purity","structure vs behavior separation"],"canonical":"https://canonrs.dev/rules/layouts-are-css-and-semantics-only","category":"styling-css"},{"number":135,"slug":"ui-vs-layout-responsibility-boundary","title":"UI vs Layout Responsibility Boundary","description":"Blurring responsibilities between UI and layouts creates coupling and breaks system evolution. Each layer must own a distinct concern.","keywords":["ui layout separation pattern","architecture boundary ui layout","leptos layout responsibility","component layering rules"],"canonical":"https://canonrs.dev/rules/ui-vs-layout-responsibility-boundary","category":"component-architecture"},{"number":136,"slug":"controllers-are-csr-only","title":"Controllers Are CSR-Only","description":"Executing controllers during SSR introduces hydration mismatches and runtime errors due to browser-only APIs. Controllers must run exclusively in CSR.","keywords":["csr only controller pattern","ssr controller error leptos","wasm controller gating","hydration mismatch controller"],"canonical":"https://canonrs.dev/rules/controllers-are-csr-only","category":"core-runtime"},{"number":137,"slug":"providers-must-have-single-owner","title":"Providers Must Have a Single Owner","description":"Multiple provider instantiations create duplicated state and desynchronized UI. A single ownership model is required for consistent state flow.","keywords":["provider single owner pattern","state duplication context issue","leptos provider ownership","context lifecycle architecture"],"canonical":"https://canonrs.dev/rules/providers-must-have-single-owner","category":"state-reactivity"},{"number":138,"slug":"children-must-be-consumed-immediately","title":"Children Must Be Consumed Immediately","description":"Forwarding or storing Children breaks ownership semantics in Leptos due to FnOnce behavior. This leads to compilation errors and unstable rendering.","keywords":["leptos children ownership","fnonce children issue","children forwarding error","component render ownership"],"canonical":"https://canonrs.dev/rules/children-must-be-consumed-immediately","category":"component-architecture"},{"number":139,"slug":"slots-are-ui-level-only","title":"Slots Are UI-Level Only","description":"Using slots in layouts introduces ownership complexity and breaks SSR safety due to Fn and lifetime boundaries. This leads to brittle composition and logic-heavy layouts.","keywords":["ui slots pattern","leptos slot ownership","layout vs ui slots","component slot architecture"],"canonical":"https://canonrs.dev/rules/slots-are-ui-level-only","category":"component-architecture"},{"number":140,"slug":"layouts-are-structural-not-behavioral","title":"Layouts Are Structural, Not Behavioral","description":"Layouts containing behavior or state introduce coupling and break SSR determinism. They must remain purely structural.","keywords":["layout structural only rule","leptos layout behavior issue","ssr deterministic layout","layout architecture separation"],"canonical":"https://canonrs.dev/rules/layouts-are-structural-not-behavioral","category":"component-architecture"},{"number":141,"slug":"csr-composition-belongs-to-app-layer","title":"CSR Composition Belongs to the App Layer","description":"Placing CSR behavior outside the application layer introduces SSR crashes, hydration issues, and runtime leakage. Design systems and layouts become environment-aware and lose portability.","keywords":["csr composition app layer","leptos csr architecture","ssr csr separation pattern","runtime logic layering ui"],"canonical":"https://canonrs.dev/rules/csr-composition-belongs-to-app-layer","category":"component-architecture"},{"number":142,"slug":"children-must-always-be-optional","title":"canon-rule-142-children-must-always-be-optional","description":"Requiring children as mandatory props creates brittle APIs and breaks composability. Components must support absence of children without structural failure.","keywords":["leptos optional children prop","component api flexibility","children option pattern ui","safe children rendering leptos"],"canonical":"https://canonrs.dev/rules/children-must-always-be-optional","category":"component-architecture"},{"number":143,"slug":"ui-must-be-hydration-deterministic","title":"canon-rule-143-ui-must-be-hydration-deterministic","description":"SSR hydration requires identical HTML between server and client. Reactive logic in rendered output creates mismatches and causes runtime failures.","keywords":["leptos hydration deterministic ui","ssr csr mismatch html","hydration error leptos","deterministic rendering ssr"],"canonical":"https://canonrs.dev/rules/ui-must-be-hydration-deterministic","category":"core-runtime"},{"number":144,"slug":"providers-expose-state-apps-own-interaction","title":"canon-rule-144-providers-expose-state-apps-own-interaction","description":"Embedding interaction logic inside providers creates coupling and breaks ownership boundaries. Providers must expose state only, leaving interaction decisions to the application layer.","keywords":["provider state separation pattern","leptos provider architecture","state vs interaction boundary","context provider design rules"],"canonical":"https://canonrs.dev/rules/providers-expose-state-apps-own-interaction","category":"state-reactivity"},{"number":145,"slug":"ui-must-not-mutate-global-state-implicitly","title":"canon-rule-145-ui-must-not-mutate-global-state-implicitly","description":"Implicit global state mutations hide side effects and reduce predictability. UI components must expose behavior via explicit callbacks instead of mutating shared state directly.","keywords":["explicit callbacks ui pattern","avoid implicit state mutation","leptos ui state handling","callback driven state architecture"],"canonical":"https://canonrs.dev/rules/ui-must-not-mutate-global-state-implicitly","category":"state-reactivity"},{"number":146,"slug":"ui-content-must-be-ssr-stable","title":"canon-rule-146-ui-content-must-be-ssr-stable","description":"Dynamic content rendered during SSR creates mismatches during hydration due to DOM differences. UI must produce stable content identical across server and client.","keywords":["ssr stable content leptos","hydration mismatch content","static rendering ssr ui","leptos ssr content rules"],"canonical":"https://canonrs.dev/rules/ui-content-must-be-ssr-stable","category":"core-runtime"},{"number":147,"slug":"reactive-closures-are-data-not-structure","title":"canon-rule-147-reactive-closures-are-data-not-structure","description":"Reactive closures evaluated differently in SSR and CSR cause structural instability when used for rendering decisions. They must be limited to data binding only.","keywords":["reactive closures leptos rules","data binding vs structure","leptos show conditional rendering","hydration safe closures"],"canonical":"https://canonrs.dev/rules/reactive-closures-are-data-not-structure","category":"state-reactivity"},{"number":148,"slug":"ui-must-never-infer-intent-from-state","title":"canon-rule-148-ui-must-never-infer-intent-from-state","description":"Inferring intent from state transitions introduces implicit behavior and duplicated logic in UI components. This leads to unpredictable flows and hidden side effects.","keywords":["intent vs state ui","explicit callbacks pattern","state transition logic frontend","ui event architecture"],"canonical":"https://canonrs.dev/rules/ui-must-never-infer-intent-from-state","category":"state-reactivity"},{"number":149,"slug":"controllers-must-be-temporal-not-structural","title":"canon-rule-149-controllers-must-be-temporal-not-structural","description":"Controllers mixing structural rendering with temporal logic break composability and reuse. Controllers must focus exclusively on timing and coordination concerns.","keywords":["controller temporal logic pattern","async coordination architecture","separation controller ui","leptos controller design"],"canonical":"https://canonrs.dev/rules/controllers-must-be-temporal-not-structural","category":"behavior"},{"number":150,"slug":"ui-must-be-deterministic-under-ssr-and-hydration","title":"canon-rule-150-ui-must-be-deterministic-under-ssr-and-hydration","description":"SSR and hydration require identical HTML output between server and client. Any runtime-dependent rendering breaks this contract and leads to failures.","keywords":["ssr deterministic rendering","hydration mismatch leptos","ui rendering contract ssr","deterministic html output"],"canonical":"https://canonrs.dev/rules/ui-must-be-deterministic-under-ssr-and-hydration","category":"core-runtime"},{"number":151,"slug":"visual-feedback-must-never-encode-application-state","title":"canon-rule-151-visual-feedback-must-never-encode-application-state","description":"Using visual indicators to drive application logic creates hidden coupling and breaks state authority. Visual feedback must reflect state, not define it.","keywords":["ui feedback state separation","visual state anti pattern","data first architecture ui","avoid ui driven logic"],"canonical":"https://canonrs.dev/rules/visual-feedback-must-never-encode-application-state","category":"state-reactivity"},{"number":152,"slug":"provider-callback-hydration-ownership","title":"canon-rule-152-provider-callback-hydration-ownership","description":"Heap-owned callbacks capturing provider context can be dropped before hydration reattachment, causing runtime panics. This breaks deterministic hydration in SSR environments.","keywords":["leptos provider callback error","hydration ownership issue","callback dropped before attach","wasm hydration panic"],"canonical":"https://canonrs.dev/rules/provider-callback-hydration-ownership","category":"core-runtime"},{"number":153,"slug":"layouts-must-be-event-free-during-hydration","title":"canon-rule-153-layouts-must-be-event-free-during-hydration","description":"Attaching DOM event listeners inside layouts during SSR hydration causes non-deterministic runtime failures due to unstable DOM nodes. This leads to panics and inconsistent behavior.","keywords":["leptos hydration event issue","layout event listener ssr","hydration callback error","ssr event timing problem"],"canonical":"https://canonrs.dev/rules/layouts-must-be-event-free-during-hydration","category":"core-runtime"},{"number":154,"slug":"css-layout-deterministic","title":"Deterministic Layout via Canonical CSS (SSR-Safe)","description":"Runtime layout manipulation causes DOM divergence between SSR and client hydration, leading to errors. Layout must be resolved deterministically via CSS.","keywords":["css deterministic layout","ssr layout mismatch","data attribute css pattern","layout rendering consistency"],"canonical":"https://canonrs.dev/rules/css-layout-deterministic","category":"styling-css"},{"number":155,"slug":"css-token-contract-is-architecture","title":"CSS Token Contract Is Architecture","description":"Mixing CSS token formats causes runtime failures, theming inconsistencies, and unpredictable behavior. Tokens must follow a single deterministic format to ensure safe consumption and transformations.","keywords":["css token numeric hsl","design system token format","hsl var double wrap error","theming token consistency"],"canonical":"https://canonrs.dev/rules/css-token-contract-is-architecture","category":"design-system"},{"number":156,"slug":"css-variable-scope-is-non-negotiable","title":"CSS Variable Scope Is Non-Negotiable","description":"Incorrect CSS variable scope prevents variables from resolving at runtime, leading to silent failures and broken themes. Scope alignment between definition and mapping is mandatory.","keywords":["css variable scope issue","css var undefined root","theming variable scope","css cascade variable resolution"],"canonical":"https://canonrs.dev/rules/css-variable-scope-is-non-negotiable","category":"design-system"},{"number":157,"slug":"design-system-css-build-time-flattened","title":"Design System CSS Must Be Build-Time Flattened","description":"Serving CSS with runtime @import chains causes silent failures and missing styles in production. Browsers cannot resolve module paths reliably, leading to incomplete styling.","keywords":["css import runtime issue","tailwind build flatten css","postcss import problem","design system css bundling"],"canonical":"https://canonrs.dev/rules/design-system-css-build-time-flattened","category":"build-tooling"},{"number":158,"slug":"design-system-packages-immutable-contracts","title":"Design System Packages Are Immutable Contracts (No Direct File Imports)","description":"Direct file imports from design system internals create tight coupling and break versioning guarantees. Applications become fragile and fail across environments.","keywords":["design system package contract","no relative imports architecture","frontend package boundaries","versioned design system usage"],"canonical":"https://canonrs.dev/rules/design-system-packages-immutable-contracts","category":"governance"},{"number":159,"slug":"css-ui-fail-safe-template","title":"UI CSS Must Be Fail-Safe, Token-Only, and Attribute-Scoped","description":"UI styles break when primitives fail to emit expected structure or tokens are inconsistently applied. This leads to fragile styling and unpredictable rendering.","keywords":["fail safe css ui pattern","data attribute css scoping","token based css architecture","resilient design system css"],"canonical":"https://canonrs.dev/rules/css-ui-fail-safe-template","category":"design-system"},{"number":160,"slug":"css-bootstrap-no-build","title":"First App Must Not Require CSS Build","description":"Requiring CSS build steps in initial setup increases friction and couples users to toolchains prematurely. This breaks onboarding simplicity and predictability.","keywords":["css bootstrap no build","zero build frontend setup","onboarding css strategy","prebuilt css architecture"],"canonical":"https://canonrs.dev/rules/css-bootstrap-no-build","category":"build-tooling"},{"number":161,"slug":"css-load-order","title":"Canonical CSS Load Order Is Mandatory","description":"Incorrect CSS load order breaks cascade rules and causes inconsistent styling. Tokens and themes may be overridden unexpectedly.","keywords":["css load order cascade","design system css order","theming override issue","frontend css layering"],"canonical":"https://canonrs.dev/rules/css-load-order","category":"styling-css"},{"number":162,"slug":"providers-not-ui","title":"Providers Are Infrastructure, Not UI","description":"Treating providers as UI components mixes state management with presentation and breaks architectural boundaries. This leads to coupling and poor composition.","keywords":["provider vs ui separation","context architecture frontend","state provider pattern","ui composition rules"],"canonical":"https://canonrs.dev/rules/providers-not-ui","category":"component-architecture"},{"number":163,"slug":"hydration-effects-only","title":"DOM Effects Are Hydration-Only","description":"Executing DOM effects during SSR causes mismatches and runtime failures. Effects must run only in hydration context to preserve deterministic rendering.","keywords":["ssr dom effects issue","hydrate feature rust leptos","dom mutation ssr error","hydration safe effects"],"canonical":"https://canonrs.dev/rules/hydration-effects-only","category":"core-runtime"},{"number":164,"slug":"pkg-served-by-ssr","title":"WASM and JS Assets Must Be Served by SSR","description":"Missing asset routing for WASM and JS breaks hydration and prevents client initialization. Applications render HTML but fail to become interactive.","keywords":["wasm asset routing ssr","leptos pkg serve issue","hydration missing assets","ssr static asset config"],"canonical":"https://canonrs.dev/rules/pkg-served-by-ssr","category":"build-tooling"},{"number":165,"slug":"workbench-is-canon","title":"CanonRS Workbench Is a Canonical Reference","description":"Ignoring working reference implementations leads to architectural drift and inconsistent decisions. Proven patterns must guide design decisions.","keywords":["reference implementation architecture","canonical design patterns","frontend architecture governance","workbench as source of truth"],"canonical":"https://canonrs.dev/rules/workbench-is-canon","category":"governance"},{"number":166,"slug":"dist-is-readonly","title":"Dist Is Read-Only","description":"Editing build artifacts directly breaks reproducibility and hides underlying architectural issues. Changes become non-traceable and inconsistent across environments.","keywords":["dist folder readonly","build artifact immutability","frontend reproducible builds","css build output integrity"],"canonical":"https://canonrs.dev/rules/dist-is-readonly","category":"build-tooling"},{"number":167,"slug":"canonrs-css-single-entrypoint","title":"CanonRS CSS Has a Single Entrypoint","description":"Multiple CSS entrypoints cause inconsistent imports, ordering issues, and missing tokens. This leads to unpredictable styling behavior across applications.","keywords":["css single entrypoint pattern","design system css import order","frontend css architecture","canonical css bundle"],"canonical":"https://canonrs.dev/rules/canonrs-css-single-entrypoint","category":"styling-css"},{"number":168,"slug":"ui-must-declare-required-tokens","title":"UI Must Declare Required Tokens","description":"Using undefined CSS variables results in invisible or broken UI elements. Token usage must be explicit and verifiable to ensure reliable rendering.","keywords":["css token validation ui","design system token usage","undefined css variable issue","ui token contract"],"canonical":"https://canonrs.dev/rules/ui-must-declare-required-tokens","category":"design-system"},{"number":169,"slug":"token-order-is-architectural","title":"Token Import Order Is Architectural","description":"Incorrect token import order causes partial styling and broken component rendering. The cascade must follow a strict architectural sequence.","keywords":["css token order cascade","design system token import order","frontend css layering tokens","token dependency order"],"canonical":"https://canonrs.dev/rules/token-order-is-architectural","category":"styling-css"},{"number":170,"slug":"html-css-contract-must-match","title":"HTML and CSS Must Share the Same Contract","description":"Mismatch between rendered HTML attributes and CSS selectors results in missing styles. The contract between markup and styling must be consistent.","keywords":["html css contract mismatch","data attribute styling pattern","css selector issue frontend","ui contract consistency"],"canonical":"https://canonrs.dev/rules/html-css-contract-must-match","category":"component-architecture"},{"number":171,"slug":"no-phantom-variables","title":"Phantom Variables Are Forbidden","description":"Referencing undefined variables creates silent UI failures and unpredictable styling. Every variable must be traceable to a defined token.","keywords":["css phantom variables issue","design system variable validation","undefined css variable fix","token completeness check"],"canonical":"https://canonrs.dev/rules/no-phantom-variables","category":"design-system"},{"number":172,"slug":"site-does-not-own-design","title":"The Site Does Not Own Design","description":"Allowing applications to define design rules leads to fragmentation and inconsistency across the system. Design must be centralized.","keywords":["design system ownership pattern","ui centralization architecture","frontend design governance","component design separation"],"canonical":"https://canonrs.dev/rules/site-does-not-own-design","category":"governance"},{"number":173,"slug":"css-is-a-first-class-system","title":"CSS Is a First-Class System","description":"Treating CSS as secondary leads to unstructured styling and hard-to-debug issues. CSS must follow strict architectural rules like any other system.","keywords":["css architecture system","design system css governance","frontend styling rules","css structured approach"],"canonical":"https://canonrs.dev/rules/css-is-a-first-class-system","category":"governance"},{"number":174,"slug":"tokens-are-compile-time-contracts","title":"canon-rule-174-tokens-are-compile-time-contracts","description":"Tokens defined without compile-time validation lead to drift, inconsistency, and runtime errors. Token usage must be enforced during build.","keywords":["compile time tokens validation","design system token contract","css token build enforcement","frontend token architecture"],"canonical":"https://canonrs.dev/rules/tokens-are-compile-time-contracts","category":"build-tooling"},{"number":175,"slug":"dark-light-css-concern-not-component","title":"Dark/Light Is a CSS Concern, Not a Component Concern","description":"Embedding dark/light logic inside components creates duplication, inconsistency, and hydration mismatches. Theme resolution must be handled exclusively by CSS token layers.","keywords":["css theming tokens pattern","dark mode separation frontend","component theme agnostic design","design system theme architecture"],"canonical":"https://canonrs.dev/rules/dark-light-css-concern-not-component","category":"design-system"},{"number":176,"slug":"governance-is-the-single-source-of-truth","title":"Governance Is the Single Source of Truth","description":"Decisions made outside governance create drift, inconsistency, and duplicated logic. The system loses determinism and becomes difficult to maintain.","keywords":["governance architecture pattern","single source of truth design system","frontend governance enforcement","contract resolution architecture"],"canonical":"https://canonrs.dev/rules/governance-is-the-single-source-of-truth","category":"governance"},{"number":177,"slug":"canonrs-css-generated-artifact-never-design-surface","title":"canonrs.css Is a Generated Artifact, Never a Design Surface","description":"Editing generated CSS files directly creates divergence between source and output, breaking reproducibility. This leads to inconsistent builds and debugging complexity.","keywords":["generated css artifact pattern","build determinism css","frontend generated files rule","css build pipeline integrity"],"canonical":"https://canonrs.dev/rules/canonrs-css-generated-artifact-never-design-surface","category":"build-tooling"},{"number":178,"slug":"contracts-are-read-only-apis","title":"Contracts Are Read-Only APIs (DEPRECATED)","description":"Deprecated rules must not be referenced or extended to avoid fragmentation of authority. Only canonical rules define current behavior.","keywords":["deprecated rules governance","canonical rule authority","api contract deprecation pattern","design system rule versioning"],"canonical":"https://canonrs.dev/rules/contracts-are-read-only-apis","category":"governance"},{"number":179,"slug":"no-visual-surfaces-in-core-or-families","title":"No Visual Surface Tokens in Core or Families","description":"Defining visual surfaces in foundational layers breaks theming flexibility and causes regressions in dark mode. Visual decisions must remain in the theme layer.","keywords":["design system token layering","theme vs core tokens separation","css semantic tokens pattern","dark mode token architecture"],"canonical":"https://canonrs.dev/rules/no-visual-surfaces-in-core-or-families","category":"design-system"},{"number":180,"slug":"semantic-token-names-canonical-suffixes","title":"Semantic Token Names Must Follow Canonical Suffixes","description":"Inconsistent token naming breaks references between layers and causes silent styling failures. Standardized suffixes ensure predictable token resolution.","keywords":["semantic token naming pattern","css token suffix rules","design system naming convention","token validation css"],"canonical":"https://canonrs.dev/rules/semantic-token-names-canonical-suffixes","category":"design-system"},{"number":181,"slug":"token-cascade-is-architecture-not-convention","title":"Token Cascade Is Architecture, Not Convention","description":"Treating token cascade as convention leads to violations and inconsistent layering. The cascade must be enforced as a structural constraint.","keywords":["token cascade architecture","css layering enforcement","design system cascade rules","frontend token validation"],"canonical":"https://canonrs.dev/rules/token-cascade-is-architecture-not-convention","category":"governance"},{"number":182,"slug":"semantic-role-must-affect-visual-contrast","title":"Semantic Role Must Affect Visual Contrast","description":"When semantic roles share identical visuals, users cannot distinguish context or feedback. Visual contrast must reflect semantic meaning.","keywords":["semantic contrast ui design","design system visual hierarchy","feedback vs surface styling","ui contrast semantics"],"canonical":"https://canonrs.dev/rules/semantic-role-must-affect-visual-contrast","category":"design-system"},{"number":183,"slug":"overlay-positioning-is-a-primitive","title":"Overlay Positioning Is a Primitive, Not a Controller Concern","description":"Handling overlay positioning in controllers leads to duplication, instability, and hydration issues. Positioning must be centralized and reusable.","keywords":["overlay positioning primitive","ui geometry architecture","popover positioning pattern","frontend overlay system"],"canonical":"https://canonrs.dev/rules/overlay-positioning-is-a-primitive","category":"component-architecture"},{"number":184,"slug":"floating-overlays-expose-position-only-via-css-vars","title":"Floating Overlays Expose Position Only via CSS Variables","description":"Exposing overlay positioning through multiple channels creates inconsistency and breaks rendering contracts. A single CSS variable interface ensures predictable integration.","keywords":["css variables overlay positioning","floating ui css contract","frontend overlay positioning pattern","css custom properties layout"],"canonical":"https://canonrs.dev/rules/floating-overlays-expose-position-only-via-css-vars","category":"styling-css"},{"number":185,"slug":"overlays-must-be-anchor-relative","title":"Overlays Must Be Anchor-Relative","description":"Viewport-based overlay positioning breaks spatial consistency and user expectations. Overlays must maintain a clear relationship with their trigger element.","keywords":["overlay anchor positioning","ui positioning primitives","popover relative placement","frontend overlay architecture"],"canonical":"https://canonrs.dev/rules/overlays-must-be-anchor-relative","category":"component-architecture"},{"number":186,"slug":"overlay-visibility-is-data-state","title":"Overlay Visibility Is Controlled Only via data-state","description":"Controlling visibility through DOM mutations or conditional rendering breaks SSR determinism. Visibility must be driven by declarative state.","keywords":["data state visibility css","hydration safe visibility pattern","overlay state css control","ssr visibility architecture"],"canonical":"https://canonrs.dev/rules/overlay-visibility-is-data-state","category":"core-runtime"},{"number":187,"slug":"floating-primitives-expose-css-vars-only","title":"Floating Primitives Enforce CSS-Variable-Only Positioning","description":"Allowing primitives to manipulate layout directly creates inconsistencies and breaks separation of concerns. Positioning must be enforced through a single contract.","keywords":["floating ui css enforcement","overlay positioning contract","css variable layout control","frontend primitives architecture"],"canonical":"https://canonrs.dev/rules/floating-primitives-expose-css-vars-only","category":"governance"},{"number":188,"slug":"overlay-positioning-is-not-ui-logic","title":"Overlay Positioning Is Not UI Logic","description":"Embedding positioning logic in UI or controllers leads to duplication and divergence. Positioning must remain centralized and reusable.","keywords":["overlay positioning separation","ui vs primitive architecture","popover logic centralization","frontend overlay design pattern"],"canonical":"https://canonrs.dev/rules/overlay-positioning-is-not-ui-logic","category":"component-architecture"},{"number":191,"slug":"pages-use-page-behaviors-only","title":"Pages Must Delegate Wiring to Page Behaviors Only","description":"Embedding logic or wiring directly in pages leads to uncontrolled growth and architectural drift. Pages must remain declarative entry points.","keywords":["page behavior architecture","frontend page composition pattern","ui wiring separation","behavior layer design"],"canonical":"https://canonrs.dev/rules/pages-use-page-behaviors-only","category":"behavior"},{"number":192,"slug":"page-behaviors-do-not-implement-logic","title":"Page Behaviors Must Not Implement New Logic","description":"Allowing page behaviors to implement logic leads to duplication and loss of reuse. Behavior must remain centralized in framework layers.","keywords":["page behavior architecture rule","frontend behavior separation","logic centralization pattern","framework behavior design"],"canonical":"https://canonrs.dev/rules/page-behaviors-do-not-implement-logic","category":"behavior"},{"number":193,"slug":"framework-behaviors-are-the-only-source-of-interactivity","title":"Framework Behaviors Are the Only Source of Interactivity","description":"Distributing interactivity across pages and UI components creates inconsistent behavior and increases bug surface. Interaction must be centralized.","keywords":["frontend behavior centralization","ui interaction architecture","event handling framework pattern","behavior layer design"],"canonical":"https://canonrs.dev/rules/framework-behaviors-are-the-only-source-of-interactivity","category":"behavior"},{"number":194,"slug":"ui-components-are-pure-render-functions","title":"UI Components Are Pure Render Functions","description":"Mixing logic or side effects into UI components breaks deterministic rendering and hydration. Components must remain pure.","keywords":["pure ui component pattern","ssr safe components design","frontend render purity","component architecture rules"],"canonical":"https://canonrs.dev/rules/ui-components-are-pure-render-functions","category":"component-architecture"},{"number":195,"slug":"interactive-components-require-explicit-id","title":"Interactive Components Require Explicit ID","description":"Auto-generated or optional IDs break SSR and CSR determinism, causing hydration mismatches and unreliable behavior attachment. Stable identifiers must be explicit.","keywords":["deterministic id ssr csr","component id requirement pattern","hydration id mismatch","frontend behavior registry id"],"canonical":"https://canonrs.dev/rules/interactive-components-require-explicit-id","category":"component-architecture"},{"number":196,"slug":"ssr-csr-separation-wasm-bloat-prevention","title":"SSR/CSR Separation for WASM Bloat Prevention","description":"Mixing SSR and CSR code causes large WASM bundles, increased build time, and runtime inefficiency. Clear separation ensures optimal performance.","keywords":["wasm bloat prevention","ssr csr separation rust","leptos feature flags wasm","frontend wasm optimization"],"canonical":"https://canonrs.dev/rules/ssr-csr-separation-wasm-bloat-prevention","category":"build-tooling"},{"number":197,"slug":"feature-flags-are-architectural-boundaries","title":"Feature Flags Are Architectural Boundaries","description":"Using feature flags as conditional shortcuts breaks architectural boundaries and introduces cross-target leakage. Flags must define strict separation.","keywords":["feature flags architecture rust","ssr csr boundary enforcement","build graph separation","frontend feature flag misuse"],"canonical":"https://canonrs.dev/rules/feature-flags-are-architectural-boundaries","category":"governance"},{"number":198,"slug":"runtime-crates-must-not-leak-cross-target-types","title":"Runtime Crates Must Not Leak Cross-Target Types","description":"Sharing runtime-specific types across targets breaks type identity and introduces fragile dependencies. Boundaries must remain strict.","keywords":["runtime type isolation","cross target rust types","shared contract pattern","workspace architecture boundaries"],"canonical":"https://canonrs.dev/rules/runtime-crates-must-not-leak-cross-target-types","category":"governance"},{"number":199,"slug":"server-adapters-are-integration-code","title":"Server Adapters Are Integration Code","description":"Embedding server-specific logic into framework code couples architecture to a specific runtime and breaks portability. Adapters must remain isolated.","keywords":["server adapter architecture","integration layer pattern","framework agnostic design","ssr adapter separation"],"canonical":"https://canonrs.dev/rules/server-adapters-are-integration-code","category":"governance"},{"number":200,"slug":"shared-crates-must-be-zero-dependency-runtime","title":"Shared Crates Must Be Zero-Dependency Runtime","description":"Adding runtime dependencies to shared crates breaks portability and contaminates architecture. Shared must remain pure contract layer.","keywords":["shared crate architecture rust","zero dependency runtime pattern","contract layer design","workspace isolation rules"],"canonical":"https://canonrs.dev/rules/shared-crates-must-be-zero-dependency-runtime","category":"governance"},{"number":201,"slug":"presets-only-color-source","title":"Presets Are the Only Source of Color Values","description":"Defining color values outside presets creates duplication and breaks palette switching. Color data must remain centralized.","keywords":["design system color source","preset color architecture","css color token centralization","theming palette management"],"canonical":"https://canonrs.dev/rules/presets-only-color-source","category":"design-system"},{"number":202,"slug":"themes-resolve-context-not-palette","title":"Themes Resolve Context, Not Palette","description":"Themes defining color values override presets and break palette consistency. Themes must only map semantic meaning to preset values.","keywords":["theme vs preset separation","design system context mapping","css theme architecture","semantic token mapping"],"canonical":"https://canonrs.dev/rules/themes-resolve-context-not-palette","category":"design-system"},{"number":203,"slug":"semantic-tokens-bridge-theme-families","title":"Semantic Tokens Are the Only Bridge Between Theme and Families","description":"Skipping semantic tokens couples components directly to palette and breaks context resolution. A strict token cascade is required.","keywords":["semantic token architecture","design system token cascade","frontend dependency inversion tokens","css token layering pattern"],"canonical":"https://canonrs.dev/rules/semantic-tokens-bridge-theme-families","category":"design-system"},{"number":204,"slug":"theme-files-must-be-last-in-cascade","title":"Theme Files Must Be Last in the Cascade","description":"Incorrect import order causes theme overrides to be ignored and breaks light dark context resolution. CSS cascade must enforce deterministic override priority.","keywords":["css cascade theme order","theme override last import","design system css order","light dark css issue"],"canonical":"https://canonrs.dev/rules/theme-files-must-be-last-in-cascade","category":"styling-css"},{"number":205,"slug":"ui-tokens-bind-semantic-never-presets","title":"UI Tokens Must Bind to Semantic Tokens, Never to Presets","description":"Direct binding to preset tokens bypasses context resolution and breaks theme behavior. Semantic layer must remain the abstraction boundary.","keywords":["semantic token binding ui","design system token layering","preset vs semantic tokens","css token architecture"],"canonical":"https://canonrs.dev/rules/ui-tokens-bind-semantic-never-presets","category":"design-system"},{"number":206,"slug":"ui-inventory-is-fixed","title":"UI Inventory Is Fixed and Canonical","description":"Uncontrolled UI component growth leads to breaking changes and inconsistent APIs. UI inventory must be explicit and versioned.","keywords":["ui inventory governance","design system component control","frontend api stability","component registry validation"],"canonical":"https://canonrs.dev/rules/ui-inventory-is-fixed","category":"governance"},{"number":207,"slug":"preset-switching-never-changes-component-css","title":"Preset Switching Must Never Change Component CSS","description":"Coupling components to preset values prevents runtime theming and requires rebuilds. Proper token indirection enables dynamic switching.","keywords":["preset switching css tokens","component token indirection","design system theming runtime","frontend preset architecture"],"canonical":"https://canonrs.dev/rules/preset-switching-never-changes-component-css","category":"design-system"},{"number":208,"slug":"working-theme-toggle-proves-correct-token-architecture","title":"A Working Theme Toggle Is Proof of Correct Token Architecture","description":"Visual bugs during theme toggle indicate token architecture issues, not logic errors. Proper separation ensures automatic updates via CSS.","keywords":["theme toggle architecture test","css token cascade debug","design system toggle issue","frontend theming validation"],"canonical":"https://canonrs.dev/rules/working-theme-toggle-proves-correct-token-architecture","category":"governance"},{"number":209,"slug":"axum-version-must-match-adapter","title":"Axum Version Must Match Adapter Version","description":"Version mismatches between adapter and framework cause type conflicts and build instability. Dependency alignment is mandatory.","keywords":["axum version mismatch","rust dependency conflict axum","ssr adapter compatibility","cargo dependency alignment"],"canonical":"https://canonrs.dev/rules/axum-version-must-match-adapter","category":"build-tooling"},{"number":210,"slug":"cdylib-mandatory-for-hydration","title":"cdylib Is Mandatory for Hydration","description":"Missing crate type prevents wasm generation and causes silent hydration failures. Explicit configuration is required.","keywords":["cdylib wasm rust","leptos hydration build error","wasm crate type config","frontend rust wasm setup"],"canonical":"https://canonrs.dev/rules/cdylib-mandatory-for-hydration","category":"build-tooling"},{"number":211,"slug":"ssr-meta-requires-html-shell","title":"SSR Meta Requires Explicit HTML Shell","description":"Missing html shell causes runtime errors and invalid meta rendering. SSR requires explicit document structure.","keywords":["ssr html shell leptos","meta rendering error ssr","frontend html structure requirement","leptos meta fix"],"canonical":"https://canonrs.dev/rules/ssr-meta-requires-html-shell","category":"core-runtime"},{"number":212,"slug":"hydration-bootstrap-tooling-owned","title":"Hydration Bootstrap Is Tooling-Owned","description":"Manual wasm bootstrap conflicts with tooling lifecycle and causes duplicated initialization. Ownership must remain in tooling.","keywords":["wasm bootstrap leptos","hydration lifecycle control","frontend wasm startup pattern","tooling owned bootstrap"],"canonical":"https://canonrs.dev/rules/hydration-bootstrap-tooling-owned","category":"core-runtime"},{"number":213,"slug":"streaming-ssr-requires-executor","title":"Streaming SSR Requires Explicit Executor Initialization","description":"Streaming SSR fails silently or crashes when no async executor is initialized. Deterministic scheduling requires explicit executor setup.","keywords":["streaming ssr executor rust","async executor initialization","leptos streaming issue","tokio executor setup"],"canonical":"https://canonrs.dev/rules/streaming-ssr-requires-executor","category":"core-runtime"},{"number":214,"slug":"lib-owns-app-structure","title":"lib.rs Owns Application Structure and UI Semantics","description":"Distributing UI structure across entrypoints breaks determinism and creates divergence between SSR and CSR. A single semantic root is required.","keywords":["lib rs architecture leptos","ui composition centralization","ssr csr semantic root","frontend app structure pattern"],"canonical":"https://canonrs.dev/rules/lib-owns-app-structure","category":"component-architecture"},{"number":215,"slug":"main-owns-runtime-bootstrap","title":"main.rs Owns Runtime and Server Bootstrap Exclusively","description":"Mixing application logic into bootstrap breaks determinism and entangles SSR CSR execution paths. Runtime initialization must remain isolated.","keywords":["main rs bootstrap pattern","runtime initialization separation","ssr architecture rust","frontend bootstrap isolation"],"canonical":"https://canonrs.dev/rules/main-owns-runtime-bootstrap","category":"core-runtime"},{"number":216,"slug":"app-must-not-define-html","title":"App Components Must Not Define HTML Structure","description":"Embedding document structure in components causes invalid markup and hydration failures. HTML boundaries must remain in shell.","keywords":["ssr html structure separation","component document boundary","frontend html shell pattern","leptos invalid html fix"],"canonical":"https://canonrs.dev/rules/app-must-not-define-html","category":"component-architecture"},{"number":217,"slug":"entrypoints-must-be-explicit","title":"Entry Points Must Be Explicit, Public, and Isolated","description":"Implicit entrypoints cause build ambiguity and feature leakage across targets. Explicit contracts ensure correct integration.","keywords":["entrypoint visibility rust","ssr csr entrypoint pattern","feature isolation build","frontend integration contract"],"canonical":"https://canonrs.dev/rules/entrypoints-must-be-explicit","category":"build-tooling"},{"number":218,"slug":"legacy-rendering-apis-forbidden","title":"Legacy Rendering APIs Are Forbidden","description":"Using legacy rendering APIs bypasses canonical integration paths and introduces hidden technical debt. Forward-only architecture must be enforced.","keywords":["legacy rendering api removal","ssr canonical integration","frontend api deprecation","leptos rendering migration"],"canonical":"https://canonrs.dev/rules/legacy-rendering-apis-forbidden","category":"governance"},{"number":219,"slug":"leptos-consistent-ports","title":"Leptos Product Must Declare Consistent Ports Across Workspace and Local Config","description":"Port mismatches between workspace and product configs cause runtime inconsistency and broken development workflows. Configuration must be deterministic.","keywords":["leptos port mismatch","workspace config alignment","frontend dev server port","cargo leptos serve issue"],"canonical":"https://canonrs.dev/rules/leptos-consistent-ports","category":"build-tooling"},{"number":220,"slug":"unique-build-targets","title":"Workspace Metadata Must Define Unique Build Targets Per Product","description":"Shared build directories cause artifact collisions and corrupted outputs across products. Isolation is required for deterministic builds.","keywords":["leptos site root conflict","workspace build isolation","wasm artifact overwrite","frontend multi product build"],"canonical":"https://canonrs.dev/rules/unique-build-targets","category":"build-tooling"},{"number":221,"slug":"critical-config-alignment","title":"Leptos.toml Critical Fields Must Align With Workspace Metadata","description":"Divergent configuration fields create inconsistent builds and runtime behavior across tools. Critical fields must remain aligned.","keywords":["leptos config alignment","workspace metadata consistency","frontend build config mismatch","cargo leptos config issue"],"canonical":"https://canonrs.dev/rules/critical-config-alignment","category":"build-tooling"},{"number":222,"slug":"cargo-metadata-resolvable","title":"Workspace Members Must Be Fully Resolvable by Cargo Metadata","description":"Invalid workspace member paths break cargo metadata resolution and cause partial builds or missing crates. All members must resolve correctly.","keywords":["cargo metadata workspace issue","workspace member path error","rust workspace resolution","cargo build workspace failure"],"canonical":"https://canonrs.dev/rules/cargo-metadata-resolvable","category":"build-tooling"},{"number":223,"slug":"feature-flag-isolation","title":"Feature Flag Scopes Must Not Leak Between Products","description":"Feature flag leakage across products causes incorrect compilation and bloated binaries. Isolation is required for deterministic builds.","keywords":["feature flag isolation rust","workspace feature leakage","ssr csr feature separation","cargo feature boundaries"],"canonical":"https://canonrs.dev/rules/feature-flag-isolation","category":"build-tooling"},{"number":224,"slug":"hyphen-naming-convention","title":"Workspace Package Names Must Use Hyphens Consistently","description":"Inconsistent naming between hyphens and underscores causes tool resolution issues and build failures. Naming must be uniform.","keywords":["cargo naming convention hyphen","rust package naming rules","workspace naming consistency","binary name mismatch rust"],"canonical":"https://canonrs.dev/rules/hyphen-naming-convention","category":"governance"},{"number":225,"slug":"workspace-exact-version-policy-v2","title":"Workspace Dependency Version Policy Must Prevent ABI Drift Without Blocking Patch Compatibility","description":"Uncontrolled semver ranges or over pinning cause ABI conflicts or ecosystem friction. A balanced strategy ensures stability and compatibility.","keywords":["rust workspace version policy","abi drift dependency rust","cargo lockfile enforcement","duplicate crate prevention"],"canonical":"https://canonrs.dev/rules/workspace-exact-version-policy-v2","category":"build-tooling"},{"number":226,"slug":"root-relative-paths","title":"Workspace Leptos Paths Must Be Root-Relative","description":"Relative paths tied to product directories break when tooling runs from workspace root. Paths must resolve deterministically.","keywords":["leptos path root relative","workspace asset resolution","cargo leptos path issue","frontend path config error"],"canonical":"https://canonrs.dev/rules/root-relative-paths","category":"build-tooling"},{"number":227,"slug":"workspace-dependency-inheritance","title":"Products Must Inherit Workspace Dependencies","description":"Duplicating dependency versions in products causes drift and conflicts. Workspace must remain the single source of truth.","keywords":["cargo workspace dependency inheritance","rust dependency duplication issue","workspace true cargo","version drift rust"],"canonical":"https://canonrs.dev/rules/workspace-dependency-inheritance","category":"build-tooling"},{"number":228,"slug":"wasm-target-configuration","title":"Workspace Must Define WASM Target Configuration","description":"Missing wasm target configuration causes build failures and inconsistent outputs. Explicit setup ensures reproducibility.","keywords":["wasm target cargo config","rust wasm build setup","wasm optimization flags","frontend wasm compilation"],"canonical":"https://canonrs.dev/rules/wasm-target-configuration","category":"build-tooling"},{"number":229,"slug":"design-system-css-artifact-isolation","title":"Design System CSS Must Be Consumed as an Independent Artifact","description":"Coupling design system css into product pipelines creates hidden dependencies and breaks versioning. Artifact isolation is required.","keywords":["design system css isolation","frontend css artifact pattern","tailwind design system coupling","css build separation"],"canonical":"https://canonrs.dev/rules/design-system-css-artifact-isolation","category":"design-system"},{"number":230,"slug":"wasm-artifact-budget-is-hard-contract","title":"WASM Artifact Budget Is a Hard Contract","description":"Unbounded wasm size growth causes severe performance issues and goes unnoticed without enforcement. Size must be treated as a hard constraint.","keywords":["wasm size budget enforcement","frontend wasm performance","bundle size control rust","wasm build optimization guard"],"canonical":"https://canonrs.dev/rules/wasm-artifact-budget-is-hard-contract","category":"build-tooling"},{"number":231,"slug":"ssr-link-isolation-refined","title":"SSR Crates Must Be Link-Time Isolated From WASM Graph","description":"Server dependencies leaking into wasm builds cause bloated binaries and runtime failures. Isolation must be enforced at dependency graph level.","keywords":["ssr wasm dependency isolation","rust feature graph separation","cargo link graph wasm","leptos ssr csr isolation"],"canonical":"https://canonrs.dev/rules/ssr-link-isolation-refined","category":"build-tooling"},{"number":232,"slug":"builds-deterministic-from-workspace-root","title":"Product Builds Must Be Deterministic From Workspace Root","description":"Builds that depend on current working directory cause inconsistent behavior across environments. Determinism requires root based execution.","keywords":["workspace deterministic build","cwd independent build","makefile root path rust","ci reproducible builds"],"canonical":"https://canonrs.dev/rules/builds-deterministic-from-workspace-root","category":"build-tooling"},{"number":233,"slug":"css-cascade-is-build-enforced-order","title":"CSS Cascade Order Is Build-Enforced Architecture","description":"Incorrect css ordering causes token conflicts and unstable themes. Order must be enforced at build level.","keywords":["css cascade architecture order","design system css layering","frontend css build order","token specificity issues css"],"canonical":"https://canonrs.dev/rules/css-cascade-is-build-enforced-order","category":"styling-css"},{"number":234,"slug":"tokens-engine-single-source-of-truth","title":"Tokens Engine Is the Single Source of CSS Truth","description":"Multiple sources defining tokens cause inconsistencies and loss of control. Tokens must originate from a single engine.","keywords":["design tokens single source","css token engine architecture","frontend token generation","design system token governance"],"canonical":"https://canonrs.dev/rules/tokens-engine-single-source-of-truth","category":"design-system"},{"number":235,"slug":"ui-must-consume-semantic-not-theme","title":"UI Layer Must Consume Semantic Tokens, Never Theme Directly","description":"Direct theme usage in ui creates coupling and breaks theme abstraction. Semantic layer must remain the interface.","keywords":["semantic token ui binding","design system theme separation","css token abstraction layer","frontend token usage pattern"],"canonical":"https://canonrs.dev/rules/ui-must-consume-semantic-not-theme","category":"design-system"},{"number":236,"slug":"cli-defines-workspace-topology","title":"CanonRS CLI Defines Workspace Topology","description":"Manual workspace structure changes cause instability and break architectural guarantees. Topology must be controlled centrally.","keywords":["workspace topology cli control","cargo workspace structure governance","frontend monorepo architecture","build system topology control"],"canonical":"https://canonrs.dev/rules/cli-defines-workspace-topology","category":"governance"},{"number":237,"slug":"cli-owns-leptos-metadata","title":"CLI Owns Leptos Metadata Blocks","description":"Manual edits to leptos metadata cause configuration drift and runtime errors. Ownership must remain centralized.","keywords":["leptos metadata management cli","workspace config governance","frontend metadata control","cargo leptos config sync"],"canonical":"https://canonrs.dev/rules/cli-owns-leptos-metadata","category":"governance"},{"number":238,"slug":"workspace-graph-must-be-acyclic","title":"Workspace Dependency Graph Must Be Acyclic","description":"Circular dependencies break build stability and violate architectural layering. Dependency graph must remain acyclic.","keywords":["rust dependency cycle fix","workspace graph acyclic","cargo dependency cycle error","frontend architecture layering"],"canonical":"https://canonrs.dev/rules/workspace-graph-must-be-acyclic","category":"component-architecture"},{"number":239,"slug":"cli-sync-must-be-idempotent","title":"CLI Sync Operations Must Be Idempotent","description":"Non idempotent cli operations cause unstable builds and unnecessary diffs. Outputs must remain deterministic.","keywords":["cli idempotent operations","deterministic build output","workspace sync stability","frontend cli consistency"],"canonical":"https://canonrs.dev/rules/cli-sync-must-be-idempotent","category":"governance"},{"number":240,"slug":"generated-artifacts-must-not-be-committed","title":"Generated Artifacts Must Not Be Committed","description":"Committing generated artifacts causes merge conflicts and version drift. Build outputs must remain reproducible and excluded from source control.","keywords":["generated artifacts gitignore","build reproducibility rust","ci regenerate artifacts","css bundle commit issue"],"canonical":"https://canonrs.dev/rules/generated-artifacts-must-not-be-committed","category":"build-tooling"},{"number":241,"slug":"tokens-engine-is-build-step-not-runtime","title":"Tokens Engine Is Build Infrastructure, Not Runtime Code","description":"Including build tooling in runtime creates dependency leaks and bloated binaries. Tokens engine must remain isolated.","keywords":["tokens engine build only","runtime dependency leak rust","design system generator separation","frontend build vs runtime"],"canonical":"https://canonrs.dev/rules/tokens-engine-is-build-step-not-runtime","category":"governance"},{"number":242,"slug":"cascade-order-is-a-contract","title":"Cascade Order Is a Contract, Not a Preference","description":"Changing cascade order breaks token resolution and causes visual instability. Order must be treated as architectural contract.","keywords":["css cascade contract order","design system layering css","token shadowing css issue","frontend cascade enforcement"],"canonical":"https://canonrs.dev/rules/cascade-order-is-a-contract","category":"styling-css"},{"number":243,"slug":"data-theme-is-the-only-activation-boundary","title":"data-theme Is the Only Theme Activation Boundary","description":"Multiple theme activation mechanisms create conflicts and inconsistent behavior. A single boundary ensures deterministic theming.","keywords":["data theme css pattern","frontend theme activation boundary","design system theming control","css theme isolation"],"canonical":"https://canonrs.dev/rules/data-theme-is-the-only-activation-boundary","category":"design-system"},{"number":244,"slug":"semantic-layer-is-mandatory-abstraction","title":"Semantic Layer Is a Mandatory Abstraction","description":"Skipping semantic layer creates coupling and breaks reusability. Semantic tokens must be the abstraction boundary.","keywords":["semantic token abstraction layer","design system token bridge","frontend token architecture","css semantic layer"],"canonical":"https://canonrs.dev/rules/semantic-layer-is-mandatory-abstraction","category":"design-system"},{"number":245,"slug":"families-must-not-leak-global-state","title":"Families Must Not Leak Global State","description":"Families overriding global tokens break cascade determinism and theme stability. Isolation is required.","keywords":["family token isolation","design system layering css","token override prevention","frontend cascade architecture"],"canonical":"https://canonrs.dev/rules/families-must-not-leak-global-state","category":"design-system"},{"number":246,"slug":"css-bundle-must-be-layer-free","title":"CSS Bundle Must Be Layer-Free","description":"Layer directives in final css introduce runtime instability and tool interference. Bundle must be flattened.","keywords":["css bundle flattening","remove @layer css build","frontend css artifact generation","design system css build output"],"canonical":"https://canonrs.dev/rules/css-bundle-must-be-layer-free","category":"build-tooling"},{"number":247,"slug":"entry-order-is-architectural","title":"CSS Entry Order Is Architectural, Not Cosmetic","description":"Entry order defines authority in cascade and cannot be changed without breaking system behavior. Order is structural.","keywords":["css entry order architecture","cascade authority layers","design system import order","frontend css generation order"],"canonical":"https://canonrs.dev/rules/entry-order-is-architectural","category":"styling-css"},{"number":248,"slug":"tokens-engine-is-the-only-source-of-truth","title":"Tokens Engine Is the Only Source of Truth","description":"Manual edits to generated token files create drift and break reproducibility. Single source is required.","keywords":["tokens engine single source","generated css immutability","design system governance tokens","frontend token build pipeline"],"canonical":"https://canonrs.dev/rules/tokens-engine-is-the-only-source-of-truth","category":"governance"},{"number":249,"slug":"products-must-not-depend-on-generated-css","title":"Products Must Not Depend on .generated CSS","description":"Direct dependency on internal css layers couples products to implementation details and breaks versioning. Isolation is required.","keywords":["design system css isolation","frontend css artifact usage","token layer coupling issue","css bundle consumption pattern"],"canonical":"https://canonrs.dev/rules/products-must-not-depend-on-generated-css","category":"design-system"},{"number":250,"slug":"design-system-must-not-depend-on-products","title":"Design System Must Not Depend on Products","description":"Reverse dependencies from design system to products create cycles and break architectural layering. Dependency direction must be strictly enforced.","keywords":["design system dependency rules","rust workspace dependency direction","avoid circular dependencies frontend","architecture layering enforcement"],"canonical":"https://canonrs.dev/rules/design-system-must-not-depend-on-products","category":"component-architecture"},{"number":251,"slug":"artifacts-must-be-statically-identifiable","title":"All Build Artifacts Must Be Statically Identifiable","description":"Dynamic artifact naming causes cache issues and deployment confusion. Artifacts must be deterministic and identifiable.","keywords":["artifact naming deterministic build","css wasm naming convention","frontend build artifact control","cache safe file naming"],"canonical":"https://canonrs.dev/rules/artifacts-must-be-statically-identifiable","category":"build-tooling"},{"number":252,"slug":"theme-switching-must-be-attribute-driven","title":"Theme Switching Must Be Attribute-Driven","description":"Imperative theme manipulation introduces inconsistencies and hydration issues. Theme switching must rely on declarative attributes.","keywords":["data theme attribute switching","css theming declarative pattern","frontend theme toggle css","avoid js theme mutation"],"canonical":"https://canonrs.dev/rules/theme-switching-must-be-attribute-driven","category":"design-system"},{"number":253,"slug":"token-cascade-order-is-immutable","title":"Token Cascade Order Is Immutable","description":"Reordering token cascade breaks resolution guarantees and causes silent regressions. Order must remain fixed.","keywords":["token cascade order css","design system layering immutability","frontend css resolution order","token dependency chain"],"canonical":"https://canonrs.dev/rules/token-cascade-order-is-immutable","category":"styling-css"},{"number":254,"slug":"canonrs-must-build-without-products","title":"CanonRS Must Build Independently of Products","description":"Design system depending on products creates coupling and blocks independent versioning. Build must remain isolated.","keywords":["design system independent build","frontend architecture decoupling","rust workspace isolation","design system versioning independence"],"canonical":"https://canonrs.dev/rules/canonrs-must-build-without-products","category":"build-tooling"},{"number":255,"slug":"cli-authority-over-workspace-generation","title":"CLI Is the Sole Authority Over Workspace Generation","description":"Manual workspace edits break determinism and architecture control. Generation must be centralized.","keywords":["workspace generation cli control","build topology governance","frontend monorepo cli authority","cargo workspace automation"],"canonical":"https://canonrs.dev/rules/cli-authority-over-workspace-generation","category":"governance"},{"number":256,"slug":"generated-workspace-is-ephemeral","title":"Generated Workspace Is Ephemeral and Immutable","description":"Treating generated workspace as source code breaks reproducibility and build determinism. It must remain disposable.","keywords":["ephemeral workspace build","generated workspace immutability","frontend build artifact governance","cli workspace regeneration"],"canonical":"https://canonrs.dev/rules/generated-workspace-is-ephemeral","category":"governance"},{"number":257,"slug":"tokens-engine-is-mandatory-pre-build-step","title":"Tokens Engine Is a Mandatory Pre-Build Step","description":"Skipping token generation leads to incomplete css cascade and inconsistent builds. Generation must be enforced.","keywords":["tokens engine prebuild step","css generation pipeline","frontend build order enforcement","design system build sequence"],"canonical":"https://canonrs.dev/rules/tokens-engine-is-mandatory-pre-build-step","category":"build-tooling"},{"number":258,"slug":"mode-drives-build-profiles","title":"Mode Drives Build Profiles","description":"Manual profile configuration creates inconsistency and misalignment with execution mode. Profiles must be derived from mode.","keywords":["build profile mapping mode","cli driven build config","ssr csr profile alignment","frontend build profiles rust"],"canonical":"https://canonrs.dev/rules/mode-drives-build-profiles","category":"build-tooling"},{"number":259,"slug":"products-must-not-define-build-topology","title":"Products Must Not Define Build Topology","description":"Allowing products to control build topology creates inconsistency and breaks framework governance. Build structure must remain centralized.","keywords":["build topology control cli","workspace governance rust","frontend architecture separation","leptos metadata ownership"],"canonical":"https://canonrs.dev/rules/products-must-not-define-build-topology","category":"build-tooling"},{"number":260,"slug":"cli-autodiscovery-must-be-explicit-or-fail","title":"CLI Autodiscovery Must Be Explicit or Fail","description":"Implicit fallback paths hide configuration errors and create unpredictable behavior. Discovery must be explicit.","keywords":["cli root discovery rules","explicit config resolution","fail fast cli pattern","workspace root detection rust"],"canonical":"https://canonrs.dev/rules/cli-autodiscovery-must-be-explicit-or-fail","category":"governance"},{"number":261,"slug":"css-size-drift-must-be-monitored","title":"CSS Bundle Size Drift Must Be Monitored","description":"Unmonitored css growth leads to performance degradation and architectural decay. Size must be tracked and enforced.","keywords":["css bundle size monitoring","frontend performance css size","ci size threshold check","design system css bloat"],"canonical":"https://canonrs.dev/rules/css-size-drift-must-be-monitored","category":"build-tooling"},{"number":262,"slug":"no-runtime-css-regeneration","title":"No Runtime CSS Regeneration","description":"Runtime css generation introduces nondeterminism and hydration issues. Styles must be fully static.","keywords":["runtime css generation problem","static css build architecture","frontend deterministic styling","avoid dynamic css injection"],"canonical":"https://canonrs.dev/rules/no-runtime-css-regeneration","category":"build-tooling"},{"number":263,"slug":"workspace-must-declare-crate-boundary-visibility","title":"Workspace Crate Boundaries Must Be Explicitly Declared","description":"Implicit crate roles create ambiguity and increase coupling risks. Boundaries must be explicit.","keywords":["crate role metadata rust","workspace architecture roles","cargo metadata canonrs","frontend crate boundaries"],"canonical":"https://canonrs.dev/rules/workspace-must-declare-crate-boundary-visibility","category":"component-architecture"},{"number":264,"slug":"behavior-registry-is-single-entry-point","title":"Behavior Registry Is the Single Runtime Entry Point","description":"Multiple behavior initialization paths cause duplication and nondeterministic runtime behavior. A single entry point is required.","keywords":["behavior registry pattern","single runtime entrypoint wasm","frontend behavior initialization","leptos behavior bootstrap"],"canonical":"https://canonrs.dev/rules/behavior-registry-is-single-entry-point","category":"behavior"},{"number":265,"slug":"interactive-owns-state-behavior-does-not","title":"Interactive Owns All State — Behavior Owns None","description":"State duplication between behavior and interactive layers causes divergence and hydration issues. Ownership must be singular.","keywords":["state ownership interactive layer","behavior stateless pattern","reactive state architecture","leptos state separation"],"canonical":"https://canonrs.dev/rules/interactive-owns-state-behavior-does-not","category":"state-reactivity"},{"number":266,"slug":"primitives-must-not-generate-ids","title":"Primitives Must Never Generate IDs","description":"Auto-generated ids create nondeterministic markup and hydration issues. Identity must be externally controlled.","keywords":["deterministic id generation ssr","leptos hydration id mismatch","frontend component identity","primitive id contract"],"canonical":"https://canonrs.dev/rules/primitives-must-not-generate-ids","category":"component-architecture"},{"number":267,"slug":"data-attributes-are-contract-not-style","title":"Data Attributes Are Contract, Not Styling Mechanism","description":"Using classes for state or behavior creates coupling and ambiguity. Structural contracts must be explicit.","keywords":["data attributes contract pattern","css class misuse state","frontend semantic attributes","ui behavior contract attributes"],"canonical":"https://canonrs.dev/rules/data-attributes-are-contract-not-style","category":"component-architecture"},{"number":268,"slug":"behavior-cleanup-is-mandatory","title":"Behavior Cleanup Is Mandatory and Deterministic","description":"Missing cleanup in behaviors causes memory leaks and duplicated listeners in SPA environments. Lifecycle must be deterministic.","keywords":["wasm event listener cleanup","behavior lifecycle rust","frontend memory leak listeners","leptos on_cleanup pattern"],"canonical":"https://canonrs.dev/rules/behavior-cleanup-is-mandatory","category":"behavior"},{"number":269,"slug":"custom-events-are-runtime-contracts","title":"Custom Events Are Public Runtime Contracts","description":"Unstructured event naming creates hidden coupling and breaking changes. Events must follow stable contracts.","keywords":["custom event naming convention","frontend runtime contracts events","canonical event namespace pattern","behavior event stability"],"canonical":"https://canonrs.dev/rules/custom-events-are-runtime-contracts","category":"behavior"},{"number":270,"slug":"behavior-dom-scope-isolation","title":"Behavior Must Never Traverse Beyond Its Container Scope","description":"Global DOM queries introduce coupling and unpredictable side effects across components. Scope must be isolated.","keywords":["dom query scope isolation","frontend behavior container pattern","avoid document query selector","component isolation dom"],"canonical":"https://canonrs.dev/rules/behavior-dom-scope-isolation","category":"behavior"},{"number":271,"slug":"behavior-idempotent-registration","title":"Behavior Execution Must Be Idempotent","description":"Repeated behavior registration causes duplicate listeners and inconsistent runtime state. Execution must be idempotent.","keywords":["idempotent behavior registration","frontend event duplication fix","wasm behavior guard pattern","leptos container attribute guard"],"canonical":"https://canonrs.dev/rules/behavior-idempotent-registration","category":"behavior"},{"number":272,"slug":"no-global-mutable-wasm-state","title":"Global Mutable State Is Forbidden in wasm Scope","description":"Global mutable state in wasm introduces race conditions and hidden coupling. State must be localized and reactive.","keywords":["wasm global mutable state issue","reactive state rust leptos","avoid static mut rust wasm","frontend state isolation"],"canonical":"https://canonrs.dev/rules/no-global-mutable-wasm-state","category":"state-reactivity"},{"number":273,"slug":"mutationobserver-explicit-justification","title":"MutationObserver Requires Explicit Architectural Justification","description":"Uncontrolled MutationObserver usage degrades performance and causes layout thrashing. Usage must be justified.","keywords":["mutationobserver performance issues","dom observer control pattern","frontend performance dom watch","behavior dom monitoring rules"],"canonical":"https://canonrs.dev/rules/mutationobserver-explicit-justification","category":"behavior"},{"number":274,"slug":"interactive-feature-isolation","title":"Interactive Features Must Be Strictly Isolated","description":"Cross feature state mutation creates hidden dependencies and regression chains. Features must remain isolated.","keywords":["feature state isolation signals","reactive state modularization","frontend signal scoping","leptos feature boundaries"],"canonical":"https://canonrs.dev/rules/interactive-feature-isolation","category":"state-reactivity"},{"number":275,"slug":"interactive-container-bound-hooks","title":"Interactive Hooks Must Be Container-Bound","description":"Global hook binding breaks isolation and introduces cross component interference. Hooks must be scoped.","keywords":["container bound hooks pattern","frontend hook isolation","reactive hook scoping rust","leptos container id binding"],"canonical":"https://canonrs.dev/rules/interactive-container-bound-hooks","category":"state-reactivity"},{"number":276,"slug":"interactive-ssr-determinism","title":"Interactive Must Remain Deterministic Under SSR Without wasm","description":"Interactive logic depending on wasm execution breaks SSR determinism and causes hydration mismatches. SSR must be independent.","keywords":["ssr deterministic rendering leptos","wasm gating interactive logic","frontend hydration consistency","ssr csr symmetry rust"],"canonical":"https://canonrs.dev/rules/interactive-ssr-determinism","category":"core-runtime"},{"number":277,"slug":"interactive-must-not-emit-dom-events","title":"Interactive Must Not Emit DOM Events","description":"Emitting DOM events from the interactive layer breaks separation between runtime behavior and state orchestration. This introduces hidden coupling and unpredictable execution flows.","keywords":["dom event dispatch architecture","interactive vs behavior separation","frontend event layer design","runtime event coupling issues"],"canonical":"https://canonrs.dev/rules/interactive-must-not-emit-dom-events","category":"behavior"},{"number":278,"slug":"primitive-must-not-encode-design-tokens","title":"Primitive Must Not Encode Design Tokens in Rust","description":"Embedding design tokens directly in Rust primitives breaks token cascade and theming flexibility. Visual decisions must remain in the CSS layer.","keywords":["design tokens rust primitives","css token separation architecture","avoid inline styles components","data attribute styling system"],"canonical":"https://canonrs.dev/rules/primitive-must-not-encode-design-tokens","category":"design-system"},{"number":279,"slug":"ui-must-not-know-behavior","title":"UI Layer Must Not Be Aware of Behavior Layer","description":"When UI depends on behavior modules, architectural boundaries collapse and SSR determinism is compromised. Layers must remain strictly isolated.","keywords":["ui behavior separation architecture","ssr safe layering frontend","data attribute driven behavior","frontend decoupling patterns"],"canonical":"https://canonrs.dev/rules/ui-must-not-know-behavior","category":"component-architecture"},{"number":280,"slug":"interactive-must-be-feature-flag-safe","title":"Interactive Must Be Safe Under Feature Flag Removal","description":"Feature flags that alter DOM structure create hydration mismatches and unstable rendering. Structural output must remain consistent.","keywords":["feature flags ssr hydration","dom stability rendering","conditional rendering pitfalls","frontend feature isolation"],"canonical":"https://canonrs.dev/rules/interactive-must-be-feature-flag-safe","category":"core-runtime"},{"number":281,"slug":"no-cross-crate-layer-leaks","title":"Cross-Crate Layer Leakage Is Forbidden","description":"Accessing internal layers across crates creates hidden coupling and breaks modular guarantees. Public boundaries must be respected.","keywords":["rust crate boundaries architecture","layer isolation workspace","pub(crate) enforcement rust","modular system design rust"],"canonical":"https://canonrs.dev/rules/no-cross-crate-layer-leaks","category":"governance"},{"number":282,"slug":"no-raw-text-nodes","title":"No Raw Text Nodes in SSR Boundaries","description":"Raw text nodes rendered directly in SSR cause hydration mismatches when WASM expects structured elements.","keywords":["leptos hydration error","ssr text node mismatch","wasm dom hydration","tachys hydration panic"],"canonical":"https://canonrs.dev/rules/no-raw-text-nodes","category":"core-runtime"},{"number":283,"slug":"stable-dom-structure-required","title":"Stable DOM Structure Required for Hydration","description":"Hydration requires identical DOM structure between server and client. Any structural divergence causes runtime failure.","keywords":["dom structure hydration","ssr mismatch leptos","wasm hydration failure","deterministic dom tree"],"canonical":"https://canonrs.dev/rules/stable-dom-structure-required","category":"core-runtime"},{"number":284,"slug":"children-must-be-structurally-stable","title":"Children Must Be Structurally Stable","description":"Dynamic children insertion or removal alters DOM shape and breaks hydration consistency.","keywords":["leptos children mismatch","dom children stability","ssr hydration children","component composition rules"],"canonical":"https://canonrs.dev/rules/children-must-be-structurally-stable","category":"component-architecture"},{"number":285,"slug":"overlay-must-use-container-pattern","title":"Overlay Must Use Container Pattern","description":"Overlay components require structural separation from content to ensure proper layering and interaction control.","keywords":["overlay container pattern","ui layering architecture","blocking overlay design","frontend overlay structure"],"canonical":"https://canonrs.dev/rules/overlay-must-use-container-pattern","category":"component-architecture"},{"number":286,"slug":"overlay-must-block-interaction","title":"Overlay Must Block Interaction","description":"Overlays must prevent user interaction with underlying content during blocking states.","keywords":["overlay pointer events css","blocking ui interaction","z-index overlay behavior","frontend loading overlay"],"canonical":"https://canonrs.dev/rules/overlay-must-block-interaction","category":"behavior"},{"number":287,"slug":"state-must-control-visibility","title":"State Must Control Visibility","description":"Component state must explicitly control DOM visibility. Implicit or disconnected state leads to inconsistent UI behavior.","keywords":["state visibility binding","leptos state dom control","css state selectors","reactive ui visibility"],"canonical":"https://canonrs.dev/rules/state-must-control-visibility","category":"state-reactivity"},{"number":288,"slug":"aria-hidden-must-match-visibility","title":"aria-hidden Must Match Visibility","description":"ARIA visibility must reflect actual DOM visibility. Mismatches cause incorrect screen reader behavior.","keywords":["aria hidden accessibility","dom visibility aria","screen reader mismatch","wcag aria rules"],"canonical":"https://canonrs.dev/rules/aria-hidden-must-match-visibility","category":"accessibility"},{"number":289,"slug":"overlay-must-be-visually-present","title":"Overlay Must Be Visually Present","description":"An overlay must provide visible feedback. Invisible overlays break user perception and interaction clarity.","keywords":["loading overlay ui","spinner overlay design","visual feedback loading","frontend ux overlay"],"canonical":"https://canonrs.dev/rules/overlay-must-be-visually-present","category":"design-system"},{"number":290,"slug":"interactive-components-must-emit-events","title":"Interactive Components Must Emit Events","description":"Interactive components must emit events to integrate with the system. Silent state changes break composability.","keywords":["custom event frontend","rs-change event pattern","component interaction events","ui event architecture"],"canonical":"https://canonrs.dev/rules/interactive-components-must-emit-events","category":"behavior"},{"number":291,"slug":"data-rs-value-is-canonical-output","title":"data-rs-value Is Canonical Output","description":"Components must expose their state through a canonical data attribute to enable system-wide integration.","keywords":["data attribute state","dom value exposure","frontend component integration","canonical value pattern"],"canonical":"https://canonrs.dev/rules/data-rs-value-is-canonical-output","category":"behavior"},{"number":292,"slug":"select-is-canonical-interaction-model","title":"Select Is Canonical Interaction Model","description":"All interactive components must follow a unified interaction contract. Divergence breaks composability.","keywords":["select pattern ui","interaction architecture frontend","unified component behavior","canonical ui model"],"canonical":"https://canonrs.dev/rules/select-is-canonical-interaction-model","category":"behavior"},{"number":293,"slug":"no-duplicate-state-outside-dom","title":"No Duplicate State Outside DOM","description":"State duplication between DOM and internal logic leads to divergence and inconsistency.","keywords":["single source of truth dom","state duplication frontend","dom state pattern","reactive ui state"],"canonical":"https://canonrs.dev/rules/no-duplicate-state-outside-dom","category":"state-reactivity"},{"number":294,"slug":"no-hidden-interactive-elements","title":"No Hidden Interactive Elements","description":"Hidden elements must not receive focus or interaction. Violations break accessibility and UX.","keywords":["hidden focus accessibility","aria hidden focus issue","keyboard navigation hidden elements","wcag focus rules"],"canonical":"https://canonrs.dev/rules/no-hidden-interactive-elements","category":"accessibility"},{"number":295,"slug":"no-conditional-rendering-for-structure","title":"No Conditional Rendering for Structure","description":"Conditional rendering that changes DOM structure breaks hydration guarantees.","keywords":["conditional rendering ssr","hydration mismatch leptos","stable dom structure","ssr best practices"],"canonical":"https://canonrs.dev/rules/no-conditional-rendering-for-structure","category":"core-runtime"},{"number":296,"slug":"components-must-be-composable","title":"Components Must Be Composable","description":"Components must integrate seamlessly with other system parts. Isolation breaks system value.","keywords":["component composition frontend","reusable ui architecture","composable design system","integration patterns"],"canonical":"https://canonrs.dev/rules/components-must-be-composable","category":"component-architecture"},{"number":297,"slug":"overlay-state-must-be-deterministic","title":"Overlay State Must Be Deterministic","description":"Overlay behavior must be fully determined by state. Implicit conditions lead to inconsistency.","keywords":["overlay state control","deterministic ui state","reactive overlay behavior","frontend state patterns"],"canonical":"https://canonrs.dev/rules/overlay-state-must-be-deterministic","category":"state-reactivity"},{"number":298,"slug":"dom-is-single-source-of-truth","title":"DOM Is Single Source of Truth","description":"All system state must be derivable from DOM to ensure consistency across layers.","keywords":["dom state architecture","frontend state source of truth","data attributes state","reactive dom pattern"],"canonical":"https://canonrs.dev/rules/dom-is-single-source-of-truth","category":"governance"},{"number":299,"slug":"no-implicit-visual-state","title":"No Implicit Visual State","description":"Visual state must be explicitly defined. Implicit styling leads to inconsistency.","keywords":["state driven css","visual state mapping","design system consistency","frontend styling state"],"canonical":"https://canonrs.dev/rules/no-implicit-visual-state","category":"design-system"},{"number":300,"slug":"no-side-effects-in-primitives","title":"No Side Effects in Primitives","description":"Primitives must be pure and predictable. Side effects break determinism and SSR safety.","keywords":["pure components frontend","no side effects ui","leptos primitives rules","ssr safe components"],"canonical":"https://canonrs.dev/rules/no-side-effects-in-primitives","category":"component-architecture"},{"number":301,"slug":"events-must-be-standardized","title":"Events Must Be Standardized","description":"Event naming and structure must be standardized to ensure interoperability.","keywords":["event naming frontend","standardized events ui","rs-change pattern","component event architecture"],"canonical":"https://canonrs.dev/rules/events-must-be-standardized","category":"behavior"},{"number":302,"slug":"state-must-be-serializable-in-dom","title":"State Must Be Serializable in DOM","description":"All component state must be externally observable through the DOM to guarantee SSR/CSR consistency, enable behavior integration, and support system-wide orchestration.","keywords":["dom state serialization","data attributes state","ssr consistency","frontend integration"],"canonical":"https://canonrs.dev/rules/state-must-be-serializable-in-dom","category":"governance"},{"number":303,"slug":"no-random-or-time-based-rendering","title":"No Random or Time-Based Rendering","description":"Rendering must be deterministic between SSR and client. Randomness or time-based values introduce divergence and break hydration.","keywords":["ssr determinism","hydration mismatch random","time rendering bug","frontend consistency"],"canonical":"https://canonrs.dev/rules/no-random-or-time-based-rendering","category":"core-runtime"},{"number":304,"slug":"no-optional-dom-nodes","title":"No Optional DOM Nodes","description":"Conditional DOM nodes break structural determinism required for hydration.","keywords":["stable dom structure","ssr mismatch","hydration bug","frontend rendering rules"],"canonical":"https://canonrs.dev/rules/no-optional-dom-nodes","category":"core-runtime"},{"number":305,"slug":"all-text-must-be-wrapped","title":"All Text Must Be Wrapped","description":"Raw text nodes introduce implicit DOM structures that break hydration expectations.","keywords":["text node hydration","leptos mismatch","wrap text dom","ssr bug"],"canonical":"https://canonrs.dev/rules/all-text-must-be-wrapped","category":"core-runtime"},{"number":306,"slug":"components-must-declare-behavior","title":"Components Must Declare Behavior","description":"Interactive components must explicitly declare their behavior to ensure predictable attachment.","keywords":["component behavior binding","data rs behavior","frontend interaction","ui architecture"],"canonical":"https://canonrs.dev/rules/components-must-declare-behavior","category":"behavior"},{"number":307,"slug":"no-inline-style-for-logic","title":"No Inline Style for Logic","description":"Inline styles must not encode logic or dynamic state.","keywords":["css architecture","inline style logic","state driven css","frontend patterns"],"canonical":"https://canonrs.dev/rules/no-inline-style-for-logic","category":"styling-css"},{"number":308,"slug":"all-interactions-must-emit-events","title":"All Interactions Must Emit Events","description":"All state changes must emit events to enable reactive integration across the system.","keywords":["ui events architecture","state change events","frontend events","rs change pattern"],"canonical":"https://canonrs.dev/rules/all-interactions-must-emit-events","category":"behavior"},{"number":309,"slug":"no-component-specific-event-names","title":"No Component-Specific Event Names","description":"Event naming must be standardized to enable cross-component integration.","keywords":["event naming frontend","canonical events","ui architecture patterns","event consistency"],"canonical":"https://canonrs.dev/rules/no-component-specific-event-names","category":"governance"},{"number":310,"slug":"components-must-be-ssr-safe","title":"Components Must Be SSR Safe","description":"All components must render identically in SSR and client environments.","keywords":["ssr safe components","hydration consistency","frontend rendering safety","leptos ssr"],"canonical":"https://canonrs.dev/rules/components-must-be-ssr-safe","category":"core-runtime"},{"number":311,"slug":"no-implicit-dom-order-dependency","title":"No Implicit DOM Order Dependency","description":"Component behavior must not depend on implicit DOM ordering.","keywords":["dom order dependency","frontend architecture patterns","robust components","selector based logic"],"canonical":"https://canonrs.dev/rules/no-implicit-dom-order-dependency","category":"component-architecture"},{"number":312,"slug":"behaviors-must-be-idempotent","title":"Behaviors Must Be Idempotent","description":"Behaviors may attach multiple times due to hydration, re-rendering, or hot-reload. They must not duplicate effects or side effects.","keywords":["idempotent behavior dom","attach guard frontend","duplicate event listeners","wasm hydration behavior"],"canonical":"https://canonrs.dev/rules/behaviors-must-be-idempotent","category":"behavior"},{"number":313,"slug":"no-dom-mutation-outside-behavior-layer","title":"No DOM Mutation Outside Behavior Layer","description":"DOM mutation must be centralized in the behavior layer to ensure predictability and separation of concerns.","keywords":["dom mutation architecture","behavior layer pattern","frontend separation of concerns","ui mutation control"],"canonical":"https://canonrs.dev/rules/no-dom-mutation-outside-behavior-layer","category":"component-architecture"},{"number":314,"slug":"state-must-not-live-in-behavior","title":"State Must Not Live in Behavior","description":"Behavior must not own state. State must be stored in DOM or signals to remain observable and consistent.","keywords":["state externalization dom","behavior state anti pattern","frontend architecture","observable state"],"canonical":"https://canonrs.dev/rules/state-must-not-live-in-behavior","category":"behavior"},{"number":315,"slug":"every-state-change-must-update-dom","title":"Every State Change Must Update DOM","description":"State changes must always be reflected in DOM to maintain synchronization across system layers.","keywords":["state dom sync","reactive dom update","frontend state architecture","data attribute sync"],"canonical":"https://canonrs.dev/rules/every-state-change-must-update-dom","category":"state-reactivity"},{"number":316,"slug":"no-implicit-default-state","title":"No Implicit Default State","description":"Default state must be explicitly declared to avoid ambiguity and inconsistent initialization.","keywords":["default state frontend","explicit state initialization","component state patterns","predictable ui"],"canonical":"https://canonrs.dev/rules/no-implicit-default-state","category":"state-reactivity"},{"number":317,"slug":"all-components-must-be-composable","title":"All Components Must Be Composable","description":"Components must be designed for composition without hidden constraints or coupling.","keywords":["component composition","reusable ui components","frontend architecture patterns","composability"],"canonical":"https://canonrs.dev/rules/all-components-must-be-composable","category":"component-architecture"},{"number":318,"slug":"no-hidden-side-effects","title":"No Hidden Side Effects","description":"All side effects must be explicit and traceable to avoid unpredictable behavior.","keywords":["side effects frontend","reactive architecture","explicit state changes","predictable ui"],"canonical":"https://canonrs.dev/rules/no-hidden-side-effects","category":"state-reactivity"},{"number":319,"slug":"behaviors-must-be-stateless","title":"Behaviors Must Be Stateless","description":"Behaviors must not retain internal state to remain predictable and re-attachable.","keywords":["stateless behavior dom","frontend behavior patterns","dom driven state","reactive ui"],"canonical":"https://canonrs.dev/rules/behaviors-must-be-stateless","category":"behavior"},{"number":320,"slug":"dom-is-the-single-source-of-truth","title":"DOM Is the Single Source of Truth","description":"The DOM must be the canonical source of truth for all component state and interaction.","keywords":["dom source of truth","frontend architecture","state consistency","ui synchronization"],"canonical":"https://canonrs.dev/rules/dom-is-the-single-source-of-truth","category":"governance"},{"number":321,"slug":"integration-must-be-declarative","title":"Integration Must Be Declarative","description":"Component integration must be defined declaratively through attributes, not imperative code.","keywords":["declarative ui integration","data attributes integration","frontend architecture","decoupled components"],"canonical":"https://canonrs.dev/rules/integration-must-be-declarative","category":"governance"},{"number":322,"slug":"island-dom-shape-must-be-static","title":"Island DOM Shape Must Be Static","description":"The DOM structure rendered by an island must be identical between SSR and hydration.","keywords":["leptos islands hydration","island dom shape","tachys hydration error","SSR hydrate mismatch"],"canonical":"https://canonrs.dev/rules/island-dom-shape-must-be-static","category":"islands-architecture"},{"number":323,"slug":"island-props-must-be-serializable","title":"Island Props Must Be Serializable","description":"All props passed to a Leptos island must implement Serialize and Deserialize.","keywords":["leptos island props","serde island","island compile error","wasm props serialization"],"canonical":"https://canonrs.dev/rules/island-props-must-be-serializable","category":"islands-architecture"},{"number":324,"slug":"island-view-must-be-isomorphic","title":"Island View Must Be Isomorphic","description":"The first render of an island must produce identical output on SSR and client.","keywords":["isomorphic rendering leptos","SSR hydration match","island first render","deterministic island"],"canonical":"https://canonrs.dev/rules/island-view-must-be-isomorphic","category":"islands-architecture"},{"number":325,"slug":"dynamic-lists-must-live-outside-islands","title":"Dynamic Lists Must Live Outside Islands","description":"Dynamic lists rendered inside islands cause hydration marker mismatches in Leptos 0.8.","keywords":["leptos island list","For component island","iterator island hydration","island children dynamic"],"canonical":"https://canonrs.dev/rules/dynamic-lists-must-live-outside-islands","category":"islands-architecture"},{"number":326,"slug":"island-event-handlers-must-be-cfg-gated","title":"Island Event Handlers Must Be Cfg-Gated","description":"Event handler logic inside islands must be conditionally compiled with cfg feature flags.","keywords":["leptos island cfg hydrate","web_sys SSR error","island event handler cfg","wasm_bindgen SSR"],"canonical":"https://canonrs.dev/rules/island-event-handlers-must-be-cfg-gated","category":"islands-architecture"},{"number":327,"slug":"signals-are-ssot-for-island-state","title":"Signals Are the SSOT for Island State","description":"In Leptos islands, signals are the single source of truth. DOM attributes are outputs, never inputs.","keywords":["leptos signal SSOT","island state management","reactive state leptos","DOM attribute output"],"canonical":"https://canonrs.dev/rules/signals-are-ssot-for-island-state","category":"islands-architecture"},{"number":328,"slug":"island-crate-must-be-linked-in-wasm-entry","title":"Island Crate Must Be Linked in WASM Entry Point","description":"In a Rust workspace, the crate containing islands must be explicitly linked in the WASM entry point crate.","keywords":["leptos island workspace","island not found wasm","wasm bundle missing island","use crate as workspace"],"canonical":"https://canonrs.dev/rules/island-crate-must-be-linked-in-wasm-entry","category":"islands-architecture"},{"number":329,"slug":"hydration-scripts-must-declare-islands-mode","title":"HydrationScripts Must Declare Islands Mode","description":"The HydrationScripts component must receive islands=true to enable island bootstrap in Leptos 0.8.","keywords":["HydrationScripts islands","leptos island bootstrap","island not interactive","leptos 0.8 islands setup"],"canonical":"https://canonrs.dev/rules/hydration-scripts-must-declare-islands-mode","category":"islands-architecture"},{"number":330,"slug":"island-props-must-use-serde-enums","title":"Island Props Must Use Serde Enums","description":"Props of Leptos islands that need to be serialized across the SSR/hydration boundary must use enums with serde derives. Primitive optional types silently fail serialization.","keywords":["leptos island props serde","island serialization","data-props null","option bool island"],"canonical":"https://canonrs.dev/rules/island-props-must-use-serde-enums","category":"islands-architecture"},{"number":331,"slug":"island-ssr-state-must-be-materialized","title":"Island SSR State Must Be Fully Materialized Without Signals","description":"Every initial state value rendered in SSR must be pre-computed as a static string. Reactive signals are not available during SSR and produce empty or incorrect output when used as the sole source of truth for `data-rs-state`.","keywords":["leptos ssr signal","island initial state","data-rs-state ssr","hydration state mismatch"],"canonical":"https://canonrs.dev/rules/island-ssr-state-must-be-materialized","category":"islands-architecture"},{"number":332,"slug":"group-override-selector-must-match-base-specificity","title":"Group Override Selector Must Match Base Specificity","description":"CSS selectors in group or container components that override styles of child components must have specificity greater than or equal to the base selector of the child component.","keywords":["css specificity group","override cascade","not selector specificity","button group hover not applying"],"canonical":"https://canonrs.dev/rules/group-override-selector-must-match-base-specificity","category":"css-architecture"},{"number":333,"slug":"island-descendant-selector-over-child-combinator","title":"Island CSS Must Use Descendant Selector Not Child Combinator","description":"CSS selectors targeting elements inside Leptos islands must use the descendant combinator (space) instead of the direct child combinator (`>`). Leptos injects `<leptos-island>` and `<leptos-children>` wrapper elements between a parent component and its slotted children, breaking child selectors.","keywords":["leptos island css","child combinator island","leptos-children wrapper","descendant selector leptos"],"canonical":"https://canonrs.dev/rules/island-descendant-selector-over-child-combinator","category":"css-architecture"},{"number":334,"slug":"island-state-must-propagate-via-context","title":"Island State Must Propagate Via Context","description":"When multiple islands in the same tree need to share reactive state, the only correct pattern is `provide_context(RwSignal)` at the root island and `use_context` in child islands. Direct prop drilling of signals or DOM-based state sharing violates the signal contract.","keywords":["leptos provide_context","island context","RwSignal shared","tabs island pattern"],"canonical":"https://canonrs.dev/rules/island-state-must-propagate-via-context","category":"islands-architecture"},{"number":335,"slug":"island-must-not-own-ui-structure","title":"Island Must Not Own UI Structure When Content Is Compositional","description":"Islands must control state, not render UI structure. When content is compositional — cards, tables, grids, rich components — it belongs in the SSR shell. Passing rich content as `Vec<String>` or serialized data to an island destroys composability and type safety.","keywords":["leptos island children","island SSR composition","island structure separation"],"canonical":"https://canonrs.dev/rules/island-must-not-own-ui-structure","category":"islands-architecture"},{"number":336,"slug":"token-references-must-resolve","title":"Token References Must Resolve to Existing Design Tokens","description":"Every CSS custom property used in a component token must reference a design token that exists in the token system. Unresolved references produce silent visual failures — the browser uses the inherited or initial value with no error.","keywords":["css custom property undefined","token chain broken","theme-primary-bg missing"],"canonical":"https://canonrs.dev/rules/token-references-must-resolve","category":"tokens"},{"number":337,"slug":"hover-must-not-override-active-state","title":"Hover State Must Not Override Active State","description":"CSS hover styles applied without guarding against active state will override the active appearance on mouse-over, creating a visual regression where the selected item loses its active styling during hover.","keywords":["css specificity hover active","not selector active state","data-rs-state hover override"],"canonical":"https://canonrs.dev/rules/hover-must-not-override-active-state","category":"css-contracts"},{"number":338,"slug":"island-boundary-rule","title":"Island Boundary Rule","description":"Islands in CanonRS must never wrap layout structure. An island is a JS initialization boundary, not a layout container. Every component must render its full DOM in SSR via `#[component]`, and delegate JS initialization to a minimal `#[island]`.","keywords":["leptos island ssr","island boundary","flex layout island","wasm init pattern"],"canonical":"https://canonrs.dev/rules/island-boundary-rule","category":"leptos-architecture"},{"number":339,"slug":"pointer-capture-must-register-on-document","title":"Pointer Capture Must Register Move and Up on Document","description":"Any interaction that uses pointer capture for drag behavior must register `pointermove` and `pointerup` on the `document`, not on the handle element. Registering on the element causes events to stop firing when the pointer leaves the element boundary during fast movement.","keywords":["pointermove document","pointer capture drag","setPointerCapture","pointerup outside element","wasm drag interaction"],"canonical":"https://canonrs.dev/rules/pointer-capture-must-register-on-document","category":"interaction-architecture"},{"number":340,"slug":"passthrough-boundary-must-be-zero-logic","title":"Passthrough Boundary Must Be Zero Logic","description":"Passthrough boundaries define a strict boundary between SSR and UI. They must not contain any logic, transformation, or interpretation of props. They forward typed data directly to UI components.","keywords":[],"canonical":"https://canonrs.dev/rules/passthrough-boundary-must-be-zero-logic","category":"boundary-architecture"},{"number":341,"slug":"init-boundary-must-be-dom-driven-zero-state","title":"Init Boundary Must Be DOM-Driven and Zero State","description":"Init boundaries define the scope for lightweight client-side behavior. They must not implement logic. All behavior is delegated to the WASM init layer, which operates directly on the DOM.","keywords":[],"canonical":"https://canonrs.dev/rules/init-boundary-must-be-dom-driven-zero-state","category":"runtime-architecture"},{"number":342,"slug":"interaction-boundary-must-delegate-to-client-module","title":"Interaction Boundary Must Delegate to Client Module","description":"Components with complex interaction must delegate all behavior to a client-side interaction module. The boundary defines the scope and may act as a bootstrap trigger, but must never implement interaction logic.","keywords":[],"canonical":"https://canonrs.dev/rules/interaction-boundary-must-delegate-to-client-module","category":"interaction-architecture"}]