Supporting copy sits in Muted Pine Grey at a comfortable line height.
",
+ "css": ".ds-card { background: #ffffff; border: 1px solid #d3dad9; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); padding: 16px; transition: transform 180ms ease, box-shadow 180ms ease; } .ds-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); } .ds-card-title { margin: 0 0 6px; font-size: 1.125rem; font-weight: 600; color: #1e3c38; line-height: 1.3; } .ds-card-body { margin: 0; font-size: 1rem; font-weight: 400; color: #667a77; line-height: 1.6; }"
+ },
+ {
+ "name": "Text Input",
+ "kind": "input",
+ "refersTo": "input",
+ "description": "Editor/admin field with a divider stroke and brand focus outline.",
+ "html": "",
+ "css": ".ds-field { display: grid; gap: 6px; color: #1e3c38; font-weight: 600; } .ds-field-label { font-size: 1rem; } .ds-field-desc { font-weight: 400; font-size: 12px; line-height: 1.4; color: #667a77; } .ds-input { width: 100%; padding: 10px 12px; border: 1px solid #d3dad9; border-radius: 10px; background: #fff; color: #1e3c38; font: inherit; } .ds-input:focus-visible { outline: 2px solid #497671; outline-offset: 2px; } .ds-input::placeholder { color: #828e8d; }"
+ },
+ {
+ "name": "Badge",
+ "kind": "chip",
+ "refersTo": "badge",
+ "description": "Uppercase status marker overlaid on product media.",
+ "html": "Sale",
+ "css": ".ds-badge { display: inline-block; padding: 2px 8px; border-radius: 8px; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; color: #fff; line-height: 1.4; } .ds-badge-sale { background: #f44336; }"
+ },
+ {
+ "name": "Tag",
+ "kind": "chip",
+ "refersTo": "badge",
+ "description": "Low-emphasis metadata pill in brand tint.",
+ "html": "Digital",
+ "css": ".ds-tag { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 0.72rem; color: #497671; background: rgba(73,118,113,0.08); border: 1px solid rgba(73,118,113,0.15); }"
+ }
+ ],
+ "narrative": {
+ "northStar": "The Operator's Workbench",
+ "overview": "This is a tool before it is a brand. The platform chrome is a dependable workbench an operator returns to session after session to build and run a marketplace: state is always legible, controls map to what they change, and nothing competes with the work. The palette is a calm Muted Pine teal-green, warm enough to feel like commerce, quiet enough to disappear behind a tenant's own theme. The system is configuration-first: every storefront is themed per tenant from a runtime bootstrap, so the platform's identity stays neutral and the tenant's leads. Components are tactile and confident; depth is real but restrained, with structural elevation reserved for things that genuinely float.",
+ "keyCharacteristics": [
+ "Quiet, neutral chrome so per-tenant themes lead the storefront.",
+ "Muted Pine teal-green primary; retail-warm but low-drama.",
+ "Tactile, confident components with decisive states.",
+ "Legible state above decoration in every tool surface.",
+ "WCAG 2.2 AA; contrast holds across tenant themes, not just the default."
+ ],
+ "rules": [
+ { "name": "The Quiet Chrome Rule", "body": "The platform's own surfaces stay neutral so tenant themes carry storefront identity. Never introduce a platform-branded color that would fight a tenant's palette.", "section": "colors" },
+ { "name": "The Variable-Only Rule", "body": "Components and widgets consume CSS custom properties only. A hardcoded hex in a component is a bug (ADR-008) that breaks per-tenant theming.", "section": "colors" },
+ { "name": "The One Family Rule", "body": "DM Sans in multiple weights carries the entire system. Do not pair a second sans; do not add a display serif. Contrast is weight and size.", "section": "typography" },
+ { "name": "The Uppercase-Is-Earned Rule", "body": "Tracked uppercase lives on badges/tags exclusively. It is forbidden as a section eyebrow.", "section": "typography" },
+ { "name": "The Lift-on-Intent Rule", "body": "Resting surfaces carry at most shadow-sm. shadow-md is a response to hover/focus; shadow-lg means the element floats above the page.", "section": "elevation" }
+ ],
+ "dos": [
+ "Do consume theme CSS custom properties, never hardcode hex in a component (ADR-008).",
+ "Do keep platform chrome neutral so tenant themes lead the storefront.",
+ "Do carry hierarchy with DM Sans weight and size; one family only.",
+ "Do keep resting surfaces on shadow-sm; reserve shadow-lg for genuinely floating elements.",
+ "Do make state unambiguous in every tool surface.",
+ "Do give every hover/transform a prefers-reduced-motion fallback.",
+ "Do hold 4.5:1 body-text contrast across every tenant theme, not just Dexar."
+ ],
+ "donts": [
+ "Don't ship dated enterprise admin: cluttered gray dashboards, tiny dense tables, 2010-era Bootstrap backoffice.",
+ "Don't ship generic AI-SaaS template: cream/violet gradient landings, hero-metric card rows, tracked-uppercase eyebrows, identical card grids.",
+ "Don't ship consumer-toy UI: bubbly rounded-everything, mascots, candy colors, gamified surfaces.",
+ "Don't use tracked uppercase anywhere except badges/tags.",
+ "Don't exceed ~2.75rem on display headings.",
+ "Don't add a second type family or a display serif.",
+ "Don't let platform-branded color fight a tenant's palette."
+ ]
+ }
+}
diff --git a/.impeccable/live/config.json b/.impeccable/live/config.json
new file mode 100644
index 0000000..65e5faf
--- /dev/null
+++ b/.impeccable/live/config.json
@@ -0,0 +1,6 @@
+{
+ "files": ["src/index.html"],
+ "insertBefore": "