From a113d503ffc3f7051318064b8267fa69d02eb0ad Mon Sep 17 00:00:00 2001 From: alwkala Date: Wed, 2 Sep 2026 05:48:39 +0300 Subject: [PATCH] release(design): v1.7.0 sovereign brain mcp integration, fail-open protocol & latency classes --- .tidyfactor | 4 +- CHANGELOG.md | 10 ++ SKILL.md | 8 ++ brand.json | 6 +- dist/tidyfactor-design.skill | Bin 15598424 -> 15605757 bytes dist/tidyfactor-design/.tidyfactor | 4 +- dist/tidyfactor-design/CHANGELOG.md | 10 ++ dist/tidyfactor-design/SKILL.md | 8 ++ dist/tidyfactor-design/brand.json | 6 +- dist/tidyfactor-design/package.json | 2 +- .../references/commands/handoff.md | 4 + .../references/memory/02-design-tokens.md | 7 +- .../references/memory/04-motion-principles.md | 15 ++- .../references/memory/05-component-anatomy.md | 19 ++++ .../references/memory/06-quality-bar.md | 9 ++ .../references/memory/10-python-tooling.md | 17 ++-- .../memory/14-nav-footer-catalog.md | 31 ++++++ .../references/workflows/brief.md | 34 ++++--- package.json | 2 +- references/commands/handoff.md | 4 + references/memory/02-design-tokens.md | 7 +- references/memory/04-motion-principles.md | 15 ++- references/memory/05-component-anatomy.md | 19 ++++ references/memory/06-quality-bar.md | 9 ++ references/memory/10-python-tooling.md | 17 ++-- references/memory/14-nav-footer-catalog.md | 31 ++++++ .../memory/19-heritage-lanes-atmosphere.md | 3 + .../memory/20-brain-baas-integration.md | 96 ++++++++++++++++++ references/workflows/brief.md | 34 ++++--- 29 files changed, 371 insertions(+), 60 deletions(-) create mode 100644 references/memory/20-brain-baas-integration.md diff --git a/.tidyfactor b/.tidyfactor index fb339b9..82fafa3 100644 --- a/.tidyfactor +++ b/.tidyfactor @@ -2,10 +2,10 @@ "ecosystem": "tidyfactor", "track": "design", "name": "tidyfactor-design", - "version": "1.6.0", + "version": "1.7.0", "npmPackage": "@alwkala/tidyfactor-design", "github": "https://github.com/TidyFactor/Design", - "skillFile": "../tidyfactor-design-v1.6.0.skill", + "skillFile": "../tidyfactor-design-v1.7.0.skill", "category": "design-system", "type": "interactive-prototyping", "outputs": [ diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bbd79b..04ca2b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to the **[@tidyfactor/design](https://www.npmjs.com/package/@tidyfactor/design)** package will be documented in this file. +## [1.7.0] - 2026-09-02 + +### 🧠 Added — Sovereign Brain MCP Integration & Deterministic Fail-Open Protocol +- **Brain Integration Contract (`references/memory/20-brain-baas-integration.md`)**: Operational specification codifying the sovereign self-hosted architecture, tenant isolation within local/agency SQLite databases, Design System Knowledge Item (KI) payload schemas, and tool latency classes. +- **Fail-Open Resolution Protocol (`references/workflows/brief.md`)**: Embedded deterministic context discovery: (1) Local workspace auto-sensing first, (2) Optional Brain MCP context acceleration (`search_knowledge_base`) when active, (3) Instant 0ms silent fallback to 3-question CDL interview if MCP is absent or offline. +- **Optional Knowledge Item Sync (`references/commands/handoff.md`)**: Added explicit `--sync-brain` flag to export verified Design System Baselines and token maps to local Brain MCP storage. +- **Tooling Scope & Latency Declarations**: Enriched `SKILL.md` with explicit Rule 10 Tooling Scope and updated `10-python-tooling.md` with execution latency classifications (sub-second AST audits vs async batch media inference). + +--- + ## [1.6.0] - 2026-09-01 ### Added - Runtime Tooling Manifest & Egyptian Heritage Design Lanes diff --git a/SKILL.md b/SKILL.md index 9bb7f9f..b71adf2 100644 --- a/SKILL.md +++ b/SKILL.md @@ -44,3 +44,11 @@ Read only the command file that matches the request. Do not load all commands si 3. **Single CSS Foundation**: Lock Native, Tailwind, daisyUI, Pico, or Hybrid once per project; never mix foundations. 4. **Typography Discipline**: Arabic display headings use El Messiri, body copy uses Tajawal. Never use Amiri for headings above 24px. 5. **7-Axis Pre-Emit Critique**: All components and layouts must be evaluated with `/* Pre-emit critique: P5 H5 E5 S5 R5 V5 D5 */`. + +## Tooling Scope (Rule 10) + +- **Languages**: Python 3 (stdlib, Pillow/rembg for asset optimization) +- **Mutations**: Read-only audits (`audit_design`), file creation (`extract_palette`), image processing (`optimize_assets`) +- **Network**: None required +- **Companion MCP**: Invocable via `tidyfactor-brain`'s `run_skill_tool(skill_id="tidyfactor-design", ...)` + diff --git a/brand.json b/brand.json index 96eef03..a4ee2de 100644 --- a/brand.json +++ b/brand.json @@ -1,13 +1,13 @@ { "name": "TidyFactor Design", - "version": "1.6.0", + "version": "1.7.0", "schemaVersion": "brand-core-v2", "meta": { "product": "TidyFactor Design System", "tagline": "Code-Native Interactive Prototyping Engine", "description": "A zero-bundler, framework-free design system and UI prototyping engine with pluggable CSS foundations and full Arabic/RTL support.", - "version": "1.6.0", - "lastUpdated": "2026-09-01" + "version": "1.7.0", + "lastUpdated": "2026-09-02" }, "identity": { "logo": { diff --git a/dist/tidyfactor-design.skill b/dist/tidyfactor-design.skill index a19cd3fe3349d3cf77d70e280e21ceb5d1ba5b21..279de5dfe34cb5d5a71c3900245a4d52eff047a1 100644 GIT binary patch delta 38121 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 sIwf`hJw8|+^S&DbYV!~l` tokens with +exact waveform bounding boxes (`patternUnits="userSpaceOnUse"`) to guarantee 0px gap +interlocking across 100% viewport width without manual DOM duplication or layout shifts. + ## Naming convention `--color-*`, `--font-*`, `--space-*`, `--radius-*`, `--shadow-*`, -`--ease-*`/`--duration-*` — consistent prefixing so any command (or a human +`--ease-*`/`--duration-*`, `--pattern-*`, `--motif-*` — consistent prefixing so any command (or a human reading the CSS) can immediately tell a value's category. ## Contrast policy diff --git a/dist/tidyfactor-design/references/memory/04-motion-principles.md b/dist/tidyfactor-design/references/memory/04-motion-principles.md index 04213e3..74d8f54 100644 --- a/dist/tidyfactor-design/references/memory/04-motion-principles.md +++ b/dist/tidyfactor-design/references/memory/04-motion-principles.md @@ -25,5 +25,18 @@ Adapted from classic animation principles, applied to UI motion rather than char --- -## 3. Non-negotiable: `prefers-reduced-motion` +## 3. SVG Stroke Dash & Parallax Choreography + +### A. SVG Stroke Dash Tracing (`.lotus-stroke-animated`) +- For cultural emblems, watermarks, and architectural line art, set `strokeDasharray` and `strokeDashoffset` equal to the total path perimeter (e.g. `1200-1600px` or `.getTotalLength()`). +- Animate `strokeDashoffset: 0` using GSAP timeline `power2.inOut` with micro-staggers (100-150ms) across petals/lines during initial page load. + +### B. Interactive Parallax with Optical Counter-Movement (Desktop $\ge 992px$) +- Foreground hero visual frames receive soft directional tilt (`xOffset * 0.5`, `yOffset * 0.5`). +- Deep background watermarks and particles receive inverted counter-movement (`-xOffset * 0.8`, `-yOffset * 0.8`) with longer easing durations (1.2s vs 0.8s) to establish multi-plane spatial depth. +- On `mouseleave`, smoothly tween all planes back to origin `(0, 0)` via `power2.out`. + +--- + +## 4. Non-negotiable: `prefers-reduced-motion` Every entrance, scroll, parallax, or ambient spotlight effect in `motion.js` must check `window.matchMedia('(prefers-reduced-motion: reduce)')` and fall back to instant or opacity-only transitions globally. diff --git a/dist/tidyfactor-design/references/memory/05-component-anatomy.md b/dist/tidyfactor-design/references/memory/05-component-anatomy.md index 069b277..f60f757 100644 --- a/dist/tidyfactor-design/references/memory/05-component-anatomy.md +++ b/dist/tidyfactor-design/references/memory/05-component-anatomy.md @@ -20,6 +20,25 @@ - Layout: Asymmetric split (Cover viewport on one side, editorial hierarchy on the other). - Visuals: Multi-layered spine shadow (`box-shadow: -8px 10px 24px rgba(0,0,0,0.25)`), dynamic hover lift (`translateY(-4px)`), and category badge. +### C. Continuous Architectural Friezes & Motifs (`.lotus-frieze-fullwidth`) +- Layout: Full-width continuous ribbon utilizing SVG `` tiled over a single `` element with zero gap. +- Break Pattern: Optional centered floating medallion (`.lotus-frieze-center-emblem`) with subtle border elevation and micro-rotation on hover. + +### D. Royal Cartouche & Shenu Ribbon Badges (`.section-eyebrow`, `.badge`) +- Styling: Dual-tone background gradients, gold border (`rgba(201, 136, 24, 0.45)`), inset highlight glow, and authentic cultural iconography. + +### E. Responsive Positioning Protocol for Floating Badges & Frame Elements +- Desktop (`min-width: 992px`): Positioned absolutely outside frame boundaries (`position: absolute; inset-inline-end: -8px;`). +- Mobile (`max-width: 768px`): Must convert to centered static blocks (`position: relative; inset: auto; width: 100%; justify-content: center;`) to eliminate mobile horizontal scrolling and layout clipping. + +### F. Header & Navigation Bar (`.navbar`) +- Layout: Single-line sticky frosted glass island with gold rim (`white-space: nowrap`). +- Brand Lockup: Logo emblem medallion (`.brand-emblem`) + Bold title (`.brand-title`) + Micro pedigree (`.brand-pedigree`). +- Prohibition: Zero emojis anywhere in the navigation bar. Use crisp inline SVGs (`currentColor`). + +### G. Mobile Navigation Drawer (`.mobile-drawer`) +- Structure: Full-height frosted overlay (`backdrop-filter: blur(20px)`), body scroll lock, $\ge 44\times 44\text{px}$ touch targets, and docked bottom action buttons. + --- ## 3. The Full 8-State Matrix (Apply per Interactive Component) diff --git a/dist/tidyfactor-design/references/memory/06-quality-bar.md b/dist/tidyfactor-design/references/memory/06-quality-bar.md index 19a5d73..d548901 100644 --- a/dist/tidyfactor-design/references/memory/06-quality-bar.md +++ b/dist/tidyfactor-design/references/memory/06-quality-bar.md @@ -66,6 +66,15 @@ Before handing back any output, score the artifact on 6 axes: 10. **Diagonal Stripe Background Overlays**: Using `repeating-linear-gradient(...)` stripe overlays in hero/section backgrounds. 11. **Disjointed Display Heading Letter-Spacing**: Using letter-spacing tighter than `-0.04em` on H1 display headings causing characters to collide. +--- + +## 🚫 5 Header & Navigation Anti-Pattern Traps (Auto-Reject) +1. **Vertical Text-Wrapping Link Trap**: Link labels breaking/wrapping into 2 stacked lines inside a single link container (e.g. `المبادرات \n والتدريب` or `المؤلفات \n والأبحاث`). Navigation items must strictly stay 1–2 words and enforce `white-space: nowrap;`. +2. **The Escaping Action Overflow Trap**: Primary CTA buttons or action toggles spilling outside the navbar pill container due to link congestion or missing container boundaries. Header items must never cause horizontal clipping or overflow. +3. **Compound Title Congestion**: Cramming 6+ verbose compound phrases side-by-side (`المؤهلات والأكاديميا`, `المؤلفات والأبحاث`, `المسيرة المهنية`, `الأثر الميداني`, `المبادرات والتدريب`). When links exceed 5–6 items, mandatory escalation to Submenu/Mega Menu applies. +4. **Duplicate Primary CTA Intent**: Duplicating the conversion action in both the menu links and the header button (e.g. having `حجز استشارة` in the nav links right next to `تواصل مباشر` on the CTA button). The CTA is the single primary conversion button. +5. **Amateur Avatar & Emoji Trap**: Using plain circular placeholder avatars with raw single letters (e.g. a teal circle with a plain letter "ش") or emoji labels (`🌙 ليلي`). Always use authentic SVG royal emblems, cartouches, or clean linear SVG icons. + ## Optical Alignment & Typography Hygiene - **Data Table Numbers**: Multi-digit metrics or numbers missing `font-variant-numeric: tabular-nums` or monospace font alignment. - **Orphaned Headline Words**: Single hanging words on display headers missing `text-wrap: balance` or `text-wrap: pretty`. diff --git a/dist/tidyfactor-design/references/memory/10-python-tooling.md b/dist/tidyfactor-design/references/memory/10-python-tooling.md index c74513f..4d41d9c 100644 --- a/dist/tidyfactor-design/references/memory/10-python-tooling.md +++ b/dist/tidyfactor-design/references/memory/10-python-tooling.md @@ -1,18 +1,19 @@ + # 10 · Python Tooling & Asset Refinement Guide The **TidyFactor Design** skill includes a lightweight Python tooling suite in `scripts/` to provide AI Agents with local media manipulation, palette extraction, background removal, and image optimization capabilities. --- -## 🛠️ Tooling Suite Inventory +## 🛠️ Tooling Suite Inventory & Latency Classes + +| Script | Responsibility | Latency Class | Isolation Scope | Invoked By | +|---|---|---|---|---| +| **`scripts/audit_design.py`** | Anti-pattern & token compliance auditor | Sub-second (<100ms) | In-process stdlib | `audit`, `perf` | +| **`scripts/extract_palette.py`** | WCAG 2.1 AAA contrast & palette derivation | Sub-second (<150ms) | `Pillow` (stdlib fallback) | `tokens`, `palette`, `init` | +| **`scripts/optimize_assets.py`** | Neural bg removal & WebP image optimization | Async Batch (2–8s) | `isolation_recommended: true` (`rembg`, `onnxruntime`) | `assets`, `deploy` | +| **`scripts/minify_assets.py`** | CSS/JS minification | Sub-second (<100ms) | Standard Python | `deploy` | -| Script | Primary Responsibility | Dependencies | Command Trigger | -|---|---|---|---| -| **`scripts/extract_palette.py`** | Image color quantization, WCAG 2.1 AA contrast check, `brand.json` & `tokens.css` sync | `Pillow` | `palette`, `tokens`, `init`, `clone` | -| **`scripts/remove_backgrounds.py`** | AI background removal (`rembg`) for transparent PNG logos, product shots, & cutouts | `rembg`, `Pillow` | `init`, `components`, `page`, `retrofit` | -| **`scripts/optimize_assets.py`** | Resizes heavy assets to design token bounds (heroes max 1200px, cards 400px, logos 240px) | `Pillow` | `deploy`, `audit` | -| **`scripts/minify_assets.py`** | Bundles & minifies CSS/JS for presentation deployment | Standard Python | `deploy` | -| **`scripts/inspect_images.py`** | Inspects image dimensions, color channels, and alpha channel status | Standard Python | `audit` | --- diff --git a/dist/tidyfactor-design/references/memory/14-nav-footer-catalog.md b/dist/tidyfactor-design/references/memory/14-nav-footer-catalog.md index 5bd84b2..79d6da4 100644 --- a/dist/tidyfactor-design/references/memory/14-nav-footer-catalog.md +++ b/dist/tidyfactor-design/references/memory/14-nav-footer-catalog.md @@ -14,6 +14,37 @@ Reference catalog for Navigation (N1–N9) and Footer (Ft1–Ft8) components. - **N8: Vertical Rail** — Fixed left/right navigation rail for web app dashboards. - **N9: Fullscreen Overlay** — Trigger button opening full-viewport navigation overlay. +--- + +## 🏛️ Navigation & Header Design Invariants (Strict Quality Bar) + +### 1. Zero Emoji Invariant (`No Emojis in Nav/Menu`) +- **Prohibition**: Emojis (e.g. 🏠, 📞, 📚, ⚡) are strictly prohibited in navigation links, headers, submenus, and action controls. Emojis represent an amateur AI-slop anti-pattern. +- **Enforcement**: Use lightweight inline SVG vector icons or ultra-lightweight linear icon sets (Lucide, Feather, Heroicons with 1.5–2px stroke) styled dynamically via `currentColor` or brand tokens. + +### 2. Single-Line Discipline (`white-space: nowrap; flex-wrap: nowrap;`) +- **One-Line Invariant**: Navigation items must strictly fit in a single horizontal row on desktop viewports. Multi-line navigation wrapping is unacceptable. +- **Label Conciseness**: Labels must be 1 to 2 words maximum (e.g. `الرئيسية`, `المسيرة`, `المؤلفات`, `المبادرات`, `حاسبة الأسعار`). +- **Stacked Sub-descriptor Option**: If descriptive context is needed, stack a micro-caption (`font-size: 0.7rem`) vertically under the primary title within the link container, preserving compact horizontal width. +- **SEO vs Navigation Separation**: Full explanatory copy and SEO keywords belong in page body content and schema markup—navigation is dedicated exclusively to rapid, intuitive orientation. + +### 3. Submenu & Mega Menu Fallback Protocol +- If a project requires more than 5–6 primary destinations, do NOT crowd the header bar. +- **Mandatory Escalation**: Group links into structured **Submenus (Dropdowns)** or an architectural **Mega Menu** with frosted glass backdrops, golden borders, and categorical grouping. + +### 4. Mobile-First Navigation & Drawer Architecture (Must Rules) +- **Automatic Viewport Folding**: On screens `< 1024px` or `< 768px`, desktop navigation links must seamlessly fold into a slide-out drawer (`.mobile-drawer`) or bottom sheet. +- **Touch Target Integrity**: Minimum 44×44px hit areas for all hamburger triggers, menu links, and controls (WCAG 2.5.5). +- **Body Scroll Lock**: Automatically lock document scrolling when the mobile drawer is active (`body.menu-open { overflow: hidden; }`). +- **Zero Horizontal Overflow**: No absolute badge or floating frame element may cause horizontal scrolling on mobile viewports (`overflow-x: clip / hidden; width: 100vw;`). +- **Compact Sticky Height**: Mobile header height capped at 52–62px with logo/brand text truncation protection (`text-overflow: ellipsis; white-space: nowrap;`). + +### 5. Header Action Controls Cap (Max 3 Controls) +- Header action clusters must not exceed **3 controls maximum** (e.g. Primary CTA + Language Switcher + Theme Toggle). +- All action controls must share geometric harmony (coordinated pill radii, consistent padding, and unified border treatment). + +--- + ## Footer Archetypes - **Ft1: Mast-Headed** — Giant brand wordmark overlaying top of footer section with multi-column links below. diff --git a/dist/tidyfactor-design/references/workflows/brief.md b/dist/tidyfactor-design/references/workflows/brief.md index c547fd6..55ad3f2 100644 --- a/dist/tidyfactor-design/references/workflows/brief.md +++ b/dist/tidyfactor-design/references/workflows/brief.md @@ -6,20 +6,26 @@ Discovers and records core design system baselines (Foundation, School, Typograp ## Steps -1. **Check Existing State**: - - Inspect `brand.json` and `.tidyfactor/design-brief.md` for existing tokens and school choices. - -2. **Conduct Structured Discovery (Max 3 Questions)**: - - If not specified, ask: - 1. **CSS Foundation (D1)**: Native CSS, Tailwind, or DaisyUI? - 2. **Design School (D2)**: Swiss Clean, Neo-Brutalist, Luxury Glassmorphic, or Warm Editorial? - 3. **Layout Archetype (D4)**: L1 Landing Story, L2 Split Screen, or L3 Dashboard? - -3. **Record Decisions**: - - Save `.tidyfactor/design-brief.md` with confirmed parameters. - -4. **Report Summary**: - - Confirm baseline parameters and prompt user to invoke `/init` or `/components`. +1. **Check Existing State (Local Auto-Sensing First)**: + - Scan workspace for `BRAND-GUIDELINES.md`, `brand.json`, and `.tidyfactor/design-brief.md`. + - If present, immediately extract tokens, typography, and palette baselines without prompting. + +2. **Check Active MCP Acceleration (Fail-Open Fallback)**: + - If local files do not exist AND `search_knowledge_base` is available in active agent tools: + Query `search_knowledge_base(query="design tokens", scope="project")` for existing project baselines. + - If MCP is unavailable, empty, or returns error: Silently proceed to Step 3 with 0ms delay. + +3. **Conduct Structured Discovery (Max 3 Questions)**: + - If parameters remain unresolved, present at most 3 concise multiple-choice options: + 1. **CSS Foundation (D1)**: (A) Native CSS (Default), (B) Tailwind CSS, (C) daisyUI, (D) Pico CSS. + 2. **Design School (D2)**: (A) Swiss Modern, (B) Neo-Brutalism, (C) Editorial Luxury, (D) Egyptian / Regional Heritage. + 3. **Layout Archetype (D4)**: (A) Split Hero Canvas, (B) Narrative Editorial, (C) Command Dashboard. + +4. **Record Decisions**: + - Persist confirmed parameters into `.tidyfactor/design-brief.md`. + +5. **Report Summary**: + - Present a concise baseline summary and suggest next action (`/init`, `/tokens`, `/components`). --- diff --git a/package.json b/package.json index a0907bd..0c2bff2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tidyfactor/design", - "version": "1.6.0", + "version": "1.7.0", "description": "TidyFactor Design track — code-native UI design lifecycle engine (Figma alternative) with Contextual Decision Layer (CDL)", "main": "SKILL.md", "bin": { diff --git a/references/commands/handoff.md b/references/commands/handoff.md index a94eff4..32e6ca0 100644 --- a/references/commands/handoff.md +++ b/references/commands/handoff.md @@ -44,6 +44,10 @@ For each shared component in `design-system/components.css`: - Cubic-bezier curves and duration values - Reduced-motion fallback rules (`prefers-reduced-motion: reduce`) +### 5. Optional Brain MCP Sync (`--sync-brain`) +When invoked with `--sync-brain`, the command packages the Design System Baseline into an Atomic Knowledge Item (KI) per `20-brain-baas-integration.md` and exports it to the active project's Brain MCP storage via `extract_knowledge_item`. +- **Fail-Open Policy**: If Brain MCP is unavailable or offline, silently skip KI export and complete the local `docs/handoff/` generation. + ## Checklist - [ ] Complete token mapping table generated diff --git a/references/memory/02-design-tokens.md b/references/memory/02-design-tokens.md index 3b11bed..0b300b2 100644 --- a/references/memory/02-design-tokens.md +++ b/references/memory/02-design-tokens.md @@ -29,9 +29,14 @@ the palette, not pure black). (ease-out for entrances, ease-in for exits, a signature easing curve for the brand's characteristic motion if `school` calls for one). +**Decorative Patterns & Friezes** — continuous horizontal ribbons, architectural +friezes, and cultural repeating motifs. Defined via SVG `` tokens with +exact waveform bounding boxes (`patternUnits="userSpaceOnUse"`) to guarantee 0px gap +interlocking across 100% viewport width without manual DOM duplication or layout shifts. + ## Naming convention `--color-*`, `--font-*`, `--space-*`, `--radius-*`, `--shadow-*`, -`--ease-*`/`--duration-*` — consistent prefixing so any command (or a human +`--ease-*`/`--duration-*`, `--pattern-*`, `--motif-*` — consistent prefixing so any command (or a human reading the CSS) can immediately tell a value's category. ## Contrast policy diff --git a/references/memory/04-motion-principles.md b/references/memory/04-motion-principles.md index 04213e3..74d8f54 100644 --- a/references/memory/04-motion-principles.md +++ b/references/memory/04-motion-principles.md @@ -25,5 +25,18 @@ Adapted from classic animation principles, applied to UI motion rather than char --- -## 3. Non-negotiable: `prefers-reduced-motion` +## 3. SVG Stroke Dash & Parallax Choreography + +### A. SVG Stroke Dash Tracing (`.lotus-stroke-animated`) +- For cultural emblems, watermarks, and architectural line art, set `strokeDasharray` and `strokeDashoffset` equal to the total path perimeter (e.g. `1200-1600px` or `.getTotalLength()`). +- Animate `strokeDashoffset: 0` using GSAP timeline `power2.inOut` with micro-staggers (100-150ms) across petals/lines during initial page load. + +### B. Interactive Parallax with Optical Counter-Movement (Desktop $\ge 992px$) +- Foreground hero visual frames receive soft directional tilt (`xOffset * 0.5`, `yOffset * 0.5`). +- Deep background watermarks and particles receive inverted counter-movement (`-xOffset * 0.8`, `-yOffset * 0.8`) with longer easing durations (1.2s vs 0.8s) to establish multi-plane spatial depth. +- On `mouseleave`, smoothly tween all planes back to origin `(0, 0)` via `power2.out`. + +--- + +## 4. Non-negotiable: `prefers-reduced-motion` Every entrance, scroll, parallax, or ambient spotlight effect in `motion.js` must check `window.matchMedia('(prefers-reduced-motion: reduce)')` and fall back to instant or opacity-only transitions globally. diff --git a/references/memory/05-component-anatomy.md b/references/memory/05-component-anatomy.md index 069b277..f60f757 100644 --- a/references/memory/05-component-anatomy.md +++ b/references/memory/05-component-anatomy.md @@ -20,6 +20,25 @@ - Layout: Asymmetric split (Cover viewport on one side, editorial hierarchy on the other). - Visuals: Multi-layered spine shadow (`box-shadow: -8px 10px 24px rgba(0,0,0,0.25)`), dynamic hover lift (`translateY(-4px)`), and category badge. +### C. Continuous Architectural Friezes & Motifs (`.lotus-frieze-fullwidth`) +- Layout: Full-width continuous ribbon utilizing SVG `` tiled over a single `` element with zero gap. +- Break Pattern: Optional centered floating medallion (`.lotus-frieze-center-emblem`) with subtle border elevation and micro-rotation on hover. + +### D. Royal Cartouche & Shenu Ribbon Badges (`.section-eyebrow`, `.badge`) +- Styling: Dual-tone background gradients, gold border (`rgba(201, 136, 24, 0.45)`), inset highlight glow, and authentic cultural iconography. + +### E. Responsive Positioning Protocol for Floating Badges & Frame Elements +- Desktop (`min-width: 992px`): Positioned absolutely outside frame boundaries (`position: absolute; inset-inline-end: -8px;`). +- Mobile (`max-width: 768px`): Must convert to centered static blocks (`position: relative; inset: auto; width: 100%; justify-content: center;`) to eliminate mobile horizontal scrolling and layout clipping. + +### F. Header & Navigation Bar (`.navbar`) +- Layout: Single-line sticky frosted glass island with gold rim (`white-space: nowrap`). +- Brand Lockup: Logo emblem medallion (`.brand-emblem`) + Bold title (`.brand-title`) + Micro pedigree (`.brand-pedigree`). +- Prohibition: Zero emojis anywhere in the navigation bar. Use crisp inline SVGs (`currentColor`). + +### G. Mobile Navigation Drawer (`.mobile-drawer`) +- Structure: Full-height frosted overlay (`backdrop-filter: blur(20px)`), body scroll lock, $\ge 44\times 44\text{px}$ touch targets, and docked bottom action buttons. + --- ## 3. The Full 8-State Matrix (Apply per Interactive Component) diff --git a/references/memory/06-quality-bar.md b/references/memory/06-quality-bar.md index 19a5d73..d548901 100644 --- a/references/memory/06-quality-bar.md +++ b/references/memory/06-quality-bar.md @@ -66,6 +66,15 @@ Before handing back any output, score the artifact on 6 axes: 10. **Diagonal Stripe Background Overlays**: Using `repeating-linear-gradient(...)` stripe overlays in hero/section backgrounds. 11. **Disjointed Display Heading Letter-Spacing**: Using letter-spacing tighter than `-0.04em` on H1 display headings causing characters to collide. +--- + +## 🚫 5 Header & Navigation Anti-Pattern Traps (Auto-Reject) +1. **Vertical Text-Wrapping Link Trap**: Link labels breaking/wrapping into 2 stacked lines inside a single link container (e.g. `المبادرات \n والتدريب` or `المؤلفات \n والأبحاث`). Navigation items must strictly stay 1–2 words and enforce `white-space: nowrap;`. +2. **The Escaping Action Overflow Trap**: Primary CTA buttons or action toggles spilling outside the navbar pill container due to link congestion or missing container boundaries. Header items must never cause horizontal clipping or overflow. +3. **Compound Title Congestion**: Cramming 6+ verbose compound phrases side-by-side (`المؤهلات والأكاديميا`, `المؤلفات والأبحاث`, `المسيرة المهنية`, `الأثر الميداني`, `المبادرات والتدريب`). When links exceed 5–6 items, mandatory escalation to Submenu/Mega Menu applies. +4. **Duplicate Primary CTA Intent**: Duplicating the conversion action in both the menu links and the header button (e.g. having `حجز استشارة` in the nav links right next to `تواصل مباشر` on the CTA button). The CTA is the single primary conversion button. +5. **Amateur Avatar & Emoji Trap**: Using plain circular placeholder avatars with raw single letters (e.g. a teal circle with a plain letter "ش") or emoji labels (`🌙 ليلي`). Always use authentic SVG royal emblems, cartouches, or clean linear SVG icons. + ## Optical Alignment & Typography Hygiene - **Data Table Numbers**: Multi-digit metrics or numbers missing `font-variant-numeric: tabular-nums` or monospace font alignment. - **Orphaned Headline Words**: Single hanging words on display headers missing `text-wrap: balance` or `text-wrap: pretty`. diff --git a/references/memory/10-python-tooling.md b/references/memory/10-python-tooling.md index c74513f..4d41d9c 100644 --- a/references/memory/10-python-tooling.md +++ b/references/memory/10-python-tooling.md @@ -1,18 +1,19 @@ + # 10 · Python Tooling & Asset Refinement Guide The **TidyFactor Design** skill includes a lightweight Python tooling suite in `scripts/` to provide AI Agents with local media manipulation, palette extraction, background removal, and image optimization capabilities. --- -## 🛠️ Tooling Suite Inventory +## 🛠️ Tooling Suite Inventory & Latency Classes + +| Script | Responsibility | Latency Class | Isolation Scope | Invoked By | +|---|---|---|---|---| +| **`scripts/audit_design.py`** | Anti-pattern & token compliance auditor | Sub-second (<100ms) | In-process stdlib | `audit`, `perf` | +| **`scripts/extract_palette.py`** | WCAG 2.1 AAA contrast & palette derivation | Sub-second (<150ms) | `Pillow` (stdlib fallback) | `tokens`, `palette`, `init` | +| **`scripts/optimize_assets.py`** | Neural bg removal & WebP image optimization | Async Batch (2–8s) | `isolation_recommended: true` (`rembg`, `onnxruntime`) | `assets`, `deploy` | +| **`scripts/minify_assets.py`** | CSS/JS minification | Sub-second (<100ms) | Standard Python | `deploy` | -| Script | Primary Responsibility | Dependencies | Command Trigger | -|---|---|---|---| -| **`scripts/extract_palette.py`** | Image color quantization, WCAG 2.1 AA contrast check, `brand.json` & `tokens.css` sync | `Pillow` | `palette`, `tokens`, `init`, `clone` | -| **`scripts/remove_backgrounds.py`** | AI background removal (`rembg`) for transparent PNG logos, product shots, & cutouts | `rembg`, `Pillow` | `init`, `components`, `page`, `retrofit` | -| **`scripts/optimize_assets.py`** | Resizes heavy assets to design token bounds (heroes max 1200px, cards 400px, logos 240px) | `Pillow` | `deploy`, `audit` | -| **`scripts/minify_assets.py`** | Bundles & minifies CSS/JS for presentation deployment | Standard Python | `deploy` | -| **`scripts/inspect_images.py`** | Inspects image dimensions, color channels, and alpha channel status | Standard Python | `audit` | --- diff --git a/references/memory/14-nav-footer-catalog.md b/references/memory/14-nav-footer-catalog.md index 5bd84b2..79d6da4 100644 --- a/references/memory/14-nav-footer-catalog.md +++ b/references/memory/14-nav-footer-catalog.md @@ -14,6 +14,37 @@ Reference catalog for Navigation (N1–N9) and Footer (Ft1–Ft8) components. - **N8: Vertical Rail** — Fixed left/right navigation rail for web app dashboards. - **N9: Fullscreen Overlay** — Trigger button opening full-viewport navigation overlay. +--- + +## 🏛️ Navigation & Header Design Invariants (Strict Quality Bar) + +### 1. Zero Emoji Invariant (`No Emojis in Nav/Menu`) +- **Prohibition**: Emojis (e.g. 🏠, 📞, 📚, ⚡) are strictly prohibited in navigation links, headers, submenus, and action controls. Emojis represent an amateur AI-slop anti-pattern. +- **Enforcement**: Use lightweight inline SVG vector icons or ultra-lightweight linear icon sets (Lucide, Feather, Heroicons with 1.5–2px stroke) styled dynamically via `currentColor` or brand tokens. + +### 2. Single-Line Discipline (`white-space: nowrap; flex-wrap: nowrap;`) +- **One-Line Invariant**: Navigation items must strictly fit in a single horizontal row on desktop viewports. Multi-line navigation wrapping is unacceptable. +- **Label Conciseness**: Labels must be 1 to 2 words maximum (e.g. `الرئيسية`, `المسيرة`, `المؤلفات`, `المبادرات`, `حاسبة الأسعار`). +- **Stacked Sub-descriptor Option**: If descriptive context is needed, stack a micro-caption (`font-size: 0.7rem`) vertically under the primary title within the link container, preserving compact horizontal width. +- **SEO vs Navigation Separation**: Full explanatory copy and SEO keywords belong in page body content and schema markup—navigation is dedicated exclusively to rapid, intuitive orientation. + +### 3. Submenu & Mega Menu Fallback Protocol +- If a project requires more than 5–6 primary destinations, do NOT crowd the header bar. +- **Mandatory Escalation**: Group links into structured **Submenus (Dropdowns)** or an architectural **Mega Menu** with frosted glass backdrops, golden borders, and categorical grouping. + +### 4. Mobile-First Navigation & Drawer Architecture (Must Rules) +- **Automatic Viewport Folding**: On screens `< 1024px` or `< 768px`, desktop navigation links must seamlessly fold into a slide-out drawer (`.mobile-drawer`) or bottom sheet. +- **Touch Target Integrity**: Minimum 44×44px hit areas for all hamburger triggers, menu links, and controls (WCAG 2.5.5). +- **Body Scroll Lock**: Automatically lock document scrolling when the mobile drawer is active (`body.menu-open { overflow: hidden; }`). +- **Zero Horizontal Overflow**: No absolute badge or floating frame element may cause horizontal scrolling on mobile viewports (`overflow-x: clip / hidden; width: 100vw;`). +- **Compact Sticky Height**: Mobile header height capped at 52–62px with logo/brand text truncation protection (`text-overflow: ellipsis; white-space: nowrap;`). + +### 5. Header Action Controls Cap (Max 3 Controls) +- Header action clusters must not exceed **3 controls maximum** (e.g. Primary CTA + Language Switcher + Theme Toggle). +- All action controls must share geometric harmony (coordinated pill radii, consistent padding, and unified border treatment). + +--- + ## Footer Archetypes - **Ft1: Mast-Headed** — Giant brand wordmark overlaying top of footer section with multi-column links below. diff --git a/references/memory/19-heritage-lanes-atmosphere.md b/references/memory/19-heritage-lanes-atmosphere.md index f310896..fc000ae 100644 --- a/references/memory/19-heritage-lanes-atmosphere.md +++ b/references/memory/19-heritage-lanes-atmosphere.md @@ -16,10 +16,13 @@ Complete operational grammar, palettes, atmospheric textures, and anti-patterns - `papyrus-bg`: `#FAF8F2` (Sacred Papyrus) * **Atmosphere & Texture**: - Fine Papyrus grain overlay (`feTurbulence` with 0.035 opacity). + - Continuous Full-Width Frieze Ribbon (`.lotus-frieze-fullwidth` with SVG `` repeat). + - 4-Corner Lotus Filigree Brackets (`.corner-bracket`) framing key academic and authority portraits. - Shallow stone relief deboss on cards (`Low-Relief`). - Warm sunlit alabaster ambient glow. * **Anti-Patterns**: - Never use stock pyramids, pharaonic tourist masks, or fake pseudo-hieroglyphs. + - Never create segmented image dividers that break or produce seams on wide viewports (always use SVG ``). --- diff --git a/references/memory/20-brain-baas-integration.md b/references/memory/20-brain-baas-integration.md new file mode 100644 index 0000000..0eb7603 --- /dev/null +++ b/references/memory/20-brain-baas-integration.md @@ -0,0 +1,96 @@ + +# Brain MCP & Sovereign BaaS Integration Contract + +Authoritative operational specification governing how `tidyfactor-design` integrates with self-hosted `tidyfactor-brain` MCP instances and sovereign BaaS nodes without creating hard dependencies or blocking offline workflows. + +--- + +## 🏛️ 1. Sovereign Architecture Model (Self-Hosted Primacy) + +TidyFactor operates on a **Sovereign, Self-Hosted Architecture**: +- **Zero Centralized SaaS Dependency**: `tidyfactor-brain` and its MCP server run locally on the developer's machine or on an agency's self-hosted server instance (Apache G5 / PHP Flight / SQLite WAL). +- **Tenant Definition**: In this sovereign architecture, a `tenant` represents an isolated client project / domain workspace (e.g. `tenant_dr_sh`, `tenant_alwkala`) mapped to a dedicated SQLite file (`data/tenants/{tenant_id}_brain.sqlite`) or scoped directory (`~/.gemini/knowledge/projects/{project_id}/`). +- **No Global Auth Overhead**: Local stdio connections run authentication-free. Self-hosted remote SSE nodes authenticate via static bearer tokens configured in the agency's `mcp_config.json`. + +--- + +## ⚡ 2. The Deterministic Fail-Open Contract + +Brain MCP is an **optional acceleration layer**, NEVER a required runtime dependency. + +### Strict Resolution Algorithm: + +``` +Step 1: Check Local Disk Workspace + ├── IF `BRAND-GUIDELINES.md` or `.tidyfactor/design-brief.md` exists: + │ └── LOAD directly from disk. Done. + └── ELSE: Proceed to Step 2. + +Step 2: Check Active MCP Toolset Availability + ├── IF tool `search_knowledge_base` is present in agent's active tool list: + │ ├── Execute: `search_knowledge_base(query="design tokens", scope="project", project_id=CURRENT_PROJECT)` + │ ├── IF valid design KI returned: + │ │ └── POPULATE context baseline. Done. + │ └── ELSE (Empty/Error): + │ └── Silent fallback (0ms delay) to Step 3. + └── ELSE (Tool not registered / Standalone environment / Offline): + └── Silent fallback (0ms delay) to Step 3. + +Step 3: Interactive Micro-Discovery (CDL 3-Question Dialogue) + └── Present concise, structured A/B/C/D choices to the user. Done. +``` + +### Invariants: +1. **Zero Connection Attempts**: Skills must NEVER attempt raw HTTP connections or socket calls to non-existent servers. They only query native MCP tools if registered in the active agent session. +2. **Zero Delay & Zero Noise**: Missing MCP server must NEVER yield warning messages, stack traces, or connection timeouts. The bypass must be instant and silent. + +--- + +## 📦 3. Design System Knowledge Item (KI) Contract + +When exporting design baselines via explicit `--sync-brain` flag on `handoff`, the skill formats the deliverable as a structured Atomic KI conforming to the following JSON payload: + +```json +{ + "schema_version": "1.0.0", + "ki_type": "design_system_baseline", + "project_id": "current-project-slug", + "timestamp": "2026-09-02T05:00:00Z", + "tokens": { + "css_foundation": "native|tailwind|daisyui|pico|hybrid", + "design_school": "neobrutalism|editorial-luxury|swiss-modern|minimal-mono|heritage-egyptian", + "palette": { + "primary": "#HEX", + "secondary": "#HEX", + "accent": "#HEX", + "surface": "#HEX", + "text": "#HEX" + }, + "typography": { + "display_heading": "El Messiri", + "body_copy": "Tajawal", + "font_family_latin": "Inter" + }, + "layout_archetype": "hero-split-canvas|editorial-asymmetric|command-center-grid" + }, + "artifacts": [ + "design-system/tokens.css", + "design-system/base.css", + "brand.json" + ] +} +``` + +--- + +## 🛠️ 4. Tooling Execution Bridge (`run_skill_tool`) + +When `tidyfactor-brain` executes `tidyfactor-design` scripts via `manifest.json`: + +| Tool Name | Script Entrypoint | Latency Class | Execution Mode | +|---|---|---|---| +| `audit_design` | `scripts/audit_design.py` | Sub-second (<100ms) | Direct CLI / In-memory AST | +| `extract_palette` | `scripts/extract_palette.py` | Sub-second (<150ms) | WCAG Color Math Engine | +| `optimize_media` | `scripts/optimize_assets.py` | Async Batch (2–8s) | `isolation_recommended: true` (rembg/onnx) | + +--- diff --git a/references/workflows/brief.md b/references/workflows/brief.md index c547fd6..55ad3f2 100644 --- a/references/workflows/brief.md +++ b/references/workflows/brief.md @@ -6,20 +6,26 @@ Discovers and records core design system baselines (Foundation, School, Typograp ## Steps -1. **Check Existing State**: - - Inspect `brand.json` and `.tidyfactor/design-brief.md` for existing tokens and school choices. - -2. **Conduct Structured Discovery (Max 3 Questions)**: - - If not specified, ask: - 1. **CSS Foundation (D1)**: Native CSS, Tailwind, or DaisyUI? - 2. **Design School (D2)**: Swiss Clean, Neo-Brutalist, Luxury Glassmorphic, or Warm Editorial? - 3. **Layout Archetype (D4)**: L1 Landing Story, L2 Split Screen, or L3 Dashboard? - -3. **Record Decisions**: - - Save `.tidyfactor/design-brief.md` with confirmed parameters. - -4. **Report Summary**: - - Confirm baseline parameters and prompt user to invoke `/init` or `/components`. +1. **Check Existing State (Local Auto-Sensing First)**: + - Scan workspace for `BRAND-GUIDELINES.md`, `brand.json`, and `.tidyfactor/design-brief.md`. + - If present, immediately extract tokens, typography, and palette baselines without prompting. + +2. **Check Active MCP Acceleration (Fail-Open Fallback)**: + - If local files do not exist AND `search_knowledge_base` is available in active agent tools: + Query `search_knowledge_base(query="design tokens", scope="project")` for existing project baselines. + - If MCP is unavailable, empty, or returns error: Silently proceed to Step 3 with 0ms delay. + +3. **Conduct Structured Discovery (Max 3 Questions)**: + - If parameters remain unresolved, present at most 3 concise multiple-choice options: + 1. **CSS Foundation (D1)**: (A) Native CSS (Default), (B) Tailwind CSS, (C) daisyUI, (D) Pico CSS. + 2. **Design School (D2)**: (A) Swiss Modern, (B) Neo-Brutalism, (C) Editorial Luxury, (D) Egyptian / Regional Heritage. + 3. **Layout Archetype (D4)**: (A) Split Hero Canvas, (B) Narrative Editorial, (C) Command Dashboard. + +4. **Record Decisions**: + - Persist confirmed parameters into `.tidyfactor/design-brief.md`. + +5. **Report Summary**: + - Present a concise baseline summary and suggest next action (`/init`, `/tokens`, `/components`). ---