chati-dev 4.2.2 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -53
- package/bin/chati.js +170 -5
- package/framework/agents/build/dev.md +509 -76
- package/framework/agents/deploy/devops.md +40 -25
- package/framework/agents/discover/brief.md +158 -22
- package/framework/agents/discover/brownfield-wu.md +26 -14
- package/framework/agents/discover/greenfield-wu.md +102 -14
- package/framework/agents/plan/architect-data-engineer.md +6 -6
- package/framework/agents/plan/architect-system.md +46 -12
- package/framework/agents/plan/architect.md +40 -20
- package/framework/agents/plan/detail.md +38 -24
- package/framework/agents/plan/phases.md +36 -26
- package/framework/agents/plan/tasks.md +114 -33
- package/framework/agents/plan/ux-brand-architect.md +240 -8
- package/framework/agents/plan/ux-component-engineer.md +28 -13
- package/framework/agents/plan/ux-researcher.md +7 -6
- package/framework/agents/plan/ux.md +55 -22
- package/framework/agents/quality/qa-implementation.md +143 -74
- package/framework/agents/quality/qa-planning.md +115 -42
- package/framework/agents/quality/qa-visual.md +448 -0
- package/framework/agents/shared/visualizer.md +128 -0
- package/framework/config.yaml +7 -6
- package/framework/constitution.md +127 -44
- package/framework/context/governance.md +12 -7
- package/framework/context/quality.md +6 -5
- package/framework/context/root.md +6 -6
- package/framework/data/entity-registry.yaml +377 -4
- package/framework/data/model-limits.json +19 -0
- package/framework/domains/agents/qa-visual.yaml +74 -0
- package/framework/domains/constitution.yaml +46 -2
- package/framework/domains/workflows/greenfield-fullstack.yaml +2 -2
- package/framework/hooks/advance-trigger.js +131 -0
- package/framework/hooks/brief-validator.js +83 -0
- package/framework/hooks/constitution-guard.js +24 -5
- package/framework/hooks/license-guard.js +62 -27
- package/framework/hooks/mode-governance.js +13 -2
- package/framework/hooks/model-governance.js +1 -0
- package/framework/hooks/post-dev.js +207 -0
- package/framework/hooks/prism-engine.js +274 -105
- package/framework/hooks/reasoning-escalator.js +371 -0
- package/framework/hooks/reference-trigger.js +117 -0
- package/framework/hooks/session-digest.js +50 -1
- package/framework/hooks/settings.json +32 -1
- package/framework/hooks/style-guard.js +25 -6
- package/framework/hooks/team-quality-gate.js +19 -12
- package/framework/hooks/undercover-guard.js +4 -2
- package/framework/i18n/en.yaml +3 -3
- package/framework/i18n/es.yaml +3 -3
- package/framework/i18n/fr.yaml +3 -3
- package/framework/i18n/pt.yaml +3 -3
- package/framework/intelligence/context-engine.md +4 -5
- package/framework/intelligence/decision-engine.md +1 -1
- package/framework/intelligence/hooks-performance.md +3 -3
- package/framework/migrations/v1.0-to-v1.1.yaml +1 -1
- package/framework/migrations/v1.4-to-v2.0.yaml +11 -11
- package/framework/migrations/v4.0-to-v4.1.yaml +2 -2
- package/framework/migrations/v4.2-to-v4.3.yaml +29 -0
- package/framework/orchestrator/chati-router.js +441 -0
- package/framework/orchestrator/chati-update.md +40 -40
- package/framework/orchestrator/chati.md +295 -94
- package/framework/rules/human-writing-style.md +47 -0
- package/framework/scaffold/motion-premium/README.md +99 -0
- package/framework/scaffold/motion-premium/app/globals.css.template +400 -0
- package/framework/scaffold/motion-premium/app/layout.tsx.template +110 -0
- package/framework/scaffold/motion-premium/components/animation/BackgroundCrossfadeProvider.tsx.template +170 -0
- package/framework/scaffold/motion-premium/components/animation/LenisProvider.tsx.template +49 -0
- package/framework/scaffold/motion-premium/components/animation/PageTransitionWrapper.tsx.template +83 -0
- package/framework/scaffold/motion-premium/components/animation/Preloader.tsx.template +171 -0
- package/framework/scaffold/motion-premium/components/ui/Container.tsx.template +69 -0
- package/framework/scaffold/motion-premium/components/ui/PageSection.tsx.template +74 -0
- package/framework/scaffold/motion-premium/lib/animations/gsap.ts.template +112 -0
- package/framework/scaffold/motion-premium/lib/animations/refreshCoordinator.ts.template +75 -0
- package/framework/scaffold/motion-premium/lib/animations/tokens.ts.template +119 -0
- package/framework/scaffold/motion-premium/lib/animations/useGsapContext.ts.template +92 -0
- package/framework/scaffold/motion-premium/lib/animations/useScrollSnapStepper.ts.template +265 -0
- package/framework/scaffold/motion-premium/lib/animations/useSmoothScroll.ts.template +67 -0
- package/framework/scaffold/motion-premium/lib/brand.ts.template +43 -0
- package/framework/scaffold/motion-premium/scaffold.yaml +178 -0
- package/framework/scaffold/motion-premium-3d/README.md +90 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoCanvas.tsx.template +81 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/ScrollDemoClient.tsx.template +75 -0
- package/framework/scaffold/motion-premium-3d/app/(3d)/scroll-demo/page.tsx.template +26 -0
- package/framework/scaffold/motion-premium-3d/components/3d/CameraRig.tsx.template +100 -0
- package/framework/scaffold/motion-premium-3d/components/3d/CanvasProvider.tsx.template +85 -0
- package/framework/scaffold/motion-premium-3d/components/3d/InvalidateOnScroll.tsx.template +51 -0
- package/framework/scaffold/motion-premium-3d/components/3d/MeshCrossfade.tsx.template +79 -0
- package/framework/scaffold/motion-premium-3d/components/3d/ScrollCrossfade.tsx.template +88 -0
- package/framework/scaffold/motion-premium-3d/components/3d/ScrollScene.tsx.template +121 -0
- package/framework/scaffold/motion-premium-3d/components/webgl/SceneFallback.tsx.template +65 -0
- package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +68 -0
- package/framework/scaffold/motion-premium-3d/lib/webgl/detect.ts.template +69 -0
- package/framework/scaffold/motion-premium-3d/scaffold.yaml +136 -0
- package/framework/schemas/session.schema.json +109 -21
- package/framework/scripts/reference-capture.js +430 -0
- package/framework/scripts/visual-qa.js +686 -0
- package/framework/tasks/orchestrator-handoff.md +1 -1
- package/framework/tasks/orchestrator-resume.md +1 -1
- package/framework/tasks/orchestrator-route.md +1 -1
- package/framework/tasks/orchestrator-status.md +3 -3
- package/framework/tasks/qa-planning-gate-define.md +1 -1
- package/framework/templates/brandbook-html-tmpl.md +2 -2
- package/framework/templates/brandbook-tmpl.yaml +1 -1
- package/framework/templates/component-spec-tmpl.yaml +1 -1
- package/framework/templates/design-token-tmpl.yaml +1 -1
- package/framework/templates/icon-system-tmpl.yaml +1 -1
- package/framework/templates/team-planning-tasks.yaml +6 -5
- package/framework/workflows/brownfield-discovery.yaml +2 -2
- package/framework/workflows/brownfield-fullstack.yaml +15 -11
- package/framework/workflows/brownfield-service.yaml +14 -10
- package/framework/workflows/brownfield-ui.yaml +15 -11
- package/framework/workflows/greenfield-fullstack.yaml +16 -13
- package/framework/workflows/quick-flow.yaml +3 -3
- package/framework/workflows/standard-flow.yaml +12 -9
- package/package.json +12 -6
- package/src/autonomy/autonomous-gate.js +1 -0
- package/src/autonomy/build-state.js +1 -2
- package/src/autonomy/progress-reporter.js +1 -1
- package/src/config/agent-customizer.js +11 -3
- package/src/config/claude-settings-generator.js +27 -7
- package/src/config/context-file-generator.js +41 -21
- package/src/config/framework-adapter.js +1 -0
- package/src/config/gemini-hooks-generator.js +19 -7
- package/src/config/mcp-configs.js +1 -0
- package/src/context/layers/l1-global.js +2 -1
- package/src/dashboard/data-reader.js +4 -3
- package/src/dashboard/layout.js +2 -1
- package/src/decision/analyzer.js +6 -30
- package/src/decision/engine.js +4 -28
- package/src/decision/registry-healer.js +3 -2
- package/src/decision/registry-updater.js +23 -14
- package/src/extensions/loader.js +2 -8
- package/src/gates/g1-planning-complete.js +2 -1
- package/src/gates/g2-qa-planning.js +2 -1
- package/src/gates/g3-implementation.js +2 -1
- package/src/gates/g4-qa-implementation.js +3 -2
- package/src/gates/g5-deploy-ready.js +2 -1
- package/src/health/engine.js +4 -3
- package/src/installer/core.js +431 -81
- package/src/installer/preflight.js +131 -0
- package/src/installer/provider-overlay.js +3 -3
- package/src/installer/scaffold-applier.js +358 -0
- package/src/installer/templates.js +46 -29
- package/src/installer/validator.js +17 -12
- package/src/intelligence/registry-manager.js +22 -29
- package/src/intelligence/timeline.js +11 -6
- package/src/license/commands.js +1 -1
- package/src/license/wait.js +102 -0
- package/src/memory/agent-memory.js +81 -0
- package/src/memory/dream.js +32 -1
- package/src/merger/replace-merger.js +28 -15
- package/src/orchestrator/agent-selector.js +2 -1
- package/src/orchestrator/cli.js +1880 -71
- package/src/orchestrator/doctor.js +270 -0
- package/src/orchestrator/handoff-engine.js +4 -3
- package/src/orchestrator/index.js +2 -0
- package/src/orchestrator/pipeline-manager.js +306 -15
- package/src/orchestrator/session-manager.js +339 -6
- package/src/tasks/handoff.js +3 -2
- package/src/telemetry/config.js +4 -3
- package/src/telemetry/schema.js +1 -0
- package/src/terminal/collector.js +3 -2
- package/src/terminal/index.js +1 -2
- package/src/terminal/isolation.js +52 -18
- package/src/terminal/prompt-builder.js +42 -25
- package/src/terminal/run-parallel.js +1 -1
- package/src/terminal/run-team.js +3 -3
- package/src/terminal/team-task-list.js +43 -4
- package/src/upgrade/backup.js +3 -2
- package/src/upgrade/checker.js +3 -2
- package/src/upgrade/migrator.js +65 -7
- package/src/upgrade/tracked-files-detector.js +86 -0
- package/src/upgrade/user-messages.js +94 -0
- package/src/utils/config-parser.js +2 -1
- package/src/utils/feature-flags.js +2 -1
- package/src/utils/flatten-entities.js +69 -0
- package/src/utils/framework-dir.js +16 -0
- package/src/utils/model-id.js +85 -0
- package/src/utils/provider-limits.js +84 -23
- package/src/utils/schema-validator.js +1 -1
- package/src/wizard/i18n.js +5 -4
- package/src/wizard/index.js +14 -0
- package/assets/logo - c/303/263pia.png +0 -0
- package/assets/logo.svg +0 -42
- package/assets/logo2.png +0 -0
- package/assets/social-preview.png +0 -0
- package/scripts/bundle-framework.js +0 -69
- package/scripts/changelog-generator.js +0 -222
- package/scripts/codebase-mapper.js +0 -728
- package/scripts/commit-message-generator.js +0 -167
- package/scripts/coverage-analyzer.js +0 -260
- package/scripts/dependency-analyzer.js +0 -280
- package/scripts/doctor/checks/agents.js +0 -77
- package/scripts/doctor/checks/constitution.js +0 -41
- package/scripts/doctor/checks/domain-alignment.js +0 -58
- package/scripts/doctor/checks/prism-layers.js +0 -84
- package/scripts/doctor/checks/registry.js +0 -55
- package/scripts/doctor/checks/schemas.js +0 -61
- package/scripts/doctor/fixes/reference-fix.js +0 -100
- package/scripts/doctor/fixes/registry-fix.js +0 -56
- package/scripts/doctor/index.js +0 -212
- package/scripts/framework-analyzer.js +0 -308
- package/scripts/generate-constitution-domain.js +0 -253
- package/scripts/generate-signing-key.js +0 -33
- package/scripts/health-check.js +0 -481
- package/scripts/ide-sync.js +0 -326
- package/scripts/performance-analyzer.js +0 -325
- package/scripts/plan-tracker.js +0 -278
- package/scripts/populate-entity-registry.js +0 -481
- package/scripts/pr-review.js +0 -317
- package/scripts/rollback-manager.js +0 -310
- package/scripts/semantic-lint.js +0 -328
- package/scripts/sign-manifest.js +0 -53
- package/scripts/stuck-detector.js +0 -343
- package/scripts/test-quality-assessment.js +0 -257
- package/scripts/validate-agents.js +0 -368
- package/scripts/validate-package.js +0 -505
- package/scripts/validate-tasks.js +0 -465
- package/src/autonomy/worktree-manager.js +0 -250
- package/src/intelligence/decision-engine.js +0 -256
- package/src/intelligence/document-sharder.js +0 -221
- package/src/intelligence/elicitation.js +0 -265
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Human Writing Style — Anti-AI Guidelines
|
|
2
|
+
|
|
3
|
+
**Scope**: Apply to all human-facing outputs: WU reports, Briefs, PRDs, handoff Layer 1 summaries, conversation turns with the user.
|
|
4
|
+
**Exemption**: Tasks lists, JSON, YAML, code blocks, qa-*.md structured tables, Given-When-Then criteria — do NOT apply.
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
### 1. No generic opening phrases
|
|
9
|
+
Do not open with "In today's fast-paced world", "In the ever-evolving landscape", "As we navigate", or any variant. Start with the subject matter directly.
|
|
10
|
+
|
|
11
|
+
### 2. No AI-favored filler verbs
|
|
12
|
+
Avoid: delve, leverage, facilitate, utilize, empower, harness. Use: use, help, run, build, drive, enable — only when the simpler word fits.
|
|
13
|
+
|
|
14
|
+
### 3. No rhetorical tricolons
|
|
15
|
+
Avoid: "not only X, but also Y, and Z", "robust, scalable, and maintainable". State the one thing that matters. Cut the rest.
|
|
16
|
+
|
|
17
|
+
### 4. No unnecessary hedging
|
|
18
|
+
Remove: "it's worth noting", "it's important to mention", "it should be noted", "one could argue", "arguably". If it is worth saying, say it directly.
|
|
19
|
+
|
|
20
|
+
### 5. No meta-closings
|
|
21
|
+
Remove: "In conclusion", "To summarize", "Overall", "Ultimately", "In summary". End on the last substantive point.
|
|
22
|
+
|
|
23
|
+
### 6. No sycophancy
|
|
24
|
+
Never open a response with "Great question!", "Excellent point!", "Absolutely!", or any approval of the user's input.
|
|
25
|
+
|
|
26
|
+
### 7. No performative bold
|
|
27
|
+
Do not bold words that carry no additional weight in context. Bold only genuine warnings, field labels, or terms the reader must not miss.
|
|
28
|
+
|
|
29
|
+
### 8. No robotic bullet parallelism
|
|
30
|
+
Bullet lists must not read as machine-generated triplets of the same syntactic form. Vary sentence length and structure. Mix noun phrases with full sentences where it reads better.
|
|
31
|
+
|
|
32
|
+
### 9. No negation-revelation pattern
|
|
33
|
+
Avoid: "This isn't just a dashboard — it's a command center." State what it is. Do not theatricalize via contrast.
|
|
34
|
+
|
|
35
|
+
### 10. No stacked generic adjectives
|
|
36
|
+
Avoid: "comprehensive, robust, scalable solution". Use the adjective only if it is specific and load-bearing. Remove the rest.
|
|
37
|
+
|
|
38
|
+
## Multilingual application
|
|
39
|
+
|
|
40
|
+
Framework supports en/pt/es/fr (Article VII). The English patterns above are EXEMPLARS, not exhaustive enumeration. When producing output in pt-BR / es / fr, apply the SAME PRINCIPLES to language-equivalent forms:
|
|
41
|
+
|
|
42
|
+
- Filler verbs: pt "elucidar / alavancar / facilitar"; es "profundizar / aprovechar / facilitar"; fr "approfondir / exploiter / faciliter"
|
|
43
|
+
- Generic openings: pt "No mundo atual em constante mudança"; es "En el mundo actual"; fr "Dans le monde d'aujourd'hui"
|
|
44
|
+
- Meta-closings: pt "Em conclusão / Em resumo"; es "En conclusión"; fr "En conclusion / Pour conclure"
|
|
45
|
+
- Sycophancy: pt "Ótima pergunta!"; es "¡Excelente pregunta!"; fr "Excellente question !"
|
|
46
|
+
|
|
47
|
+
Agent applies the principle to the target language; do not require literal translation of English examples.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Motion Premium Scaffold — v1.0.0
|
|
2
|
+
|
|
3
|
+
Opinionated premium animation infrastructure for Next.js / React 18+ / Tailwind v4 projects. Ships the 13 non-negotiable sauce patterns + 12 responsive principles proven on reference implementations (reference-website).
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
After `npm install`, run once to download the chromium browser binary used by QA-Visual screenshots:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx playwright install chromium
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Without this step, QA-Visual falls back to source-code analysis (gateway: WEAK) and skips screenshot-based gates.
|
|
14
|
+
|
|
15
|
+
## What this scaffold gives you
|
|
16
|
+
|
|
17
|
+
**Phase 1 (foundation) — shipped in v1.0.0:**
|
|
18
|
+
- `app/globals.css` — fluid type scale (Utopia-based), 4px-base spacing, radius/shadow tokens, `--breakpoint-xl: 75rem` override, reduced-motion safety net, brand placeholders.
|
|
19
|
+
- `lib/brand.ts` — typed brand token source of truth. Single place to edit project colors.
|
|
20
|
+
|
|
21
|
+
**Phase 2–4 (coming in v1.0.0 full ship):**
|
|
22
|
+
- `lib/animations/*` — gsap glue, tokens, scoped hooks (Phase 2)
|
|
23
|
+
- `components/animation/*` — Lenis, crossfade, transition, preloader providers (Phase 3)
|
|
24
|
+
- `components/ui/Container.tsx`, `PageSection.tsx` — UI contract (Phase 4)
|
|
25
|
+
|
|
26
|
+
## When NOT to use this scaffold
|
|
27
|
+
|
|
28
|
+
- Static landing pages without scroll-driven animation — overkill.
|
|
29
|
+
- Non-Tailwind projects — this scaffold is tightly coupled to Tailwind v4 syntax.
|
|
30
|
+
- Projects already using Framer Motion exclusively (no GSAP/Lenis) — import conflicts.
|
|
31
|
+
|
|
32
|
+
## How customization works (Decision 3)
|
|
33
|
+
|
|
34
|
+
Brand tokens flow one-way at install time: `brand.ts` → placeholder resolution → `globals.css` (concrete hex values).
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
lib/brand.ts (single source of truth, user-owned)
|
|
38
|
+
↓
|
|
39
|
+
scaffold-applier resolves {{PRIMARY_HEX}}, {{PRIMARY_RGB}}, ...
|
|
40
|
+
↓
|
|
41
|
+
app/globals.css (concrete --color-* vars, editable but expected to stay in sync)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**If you edit `brand.ts` after install**, globals.css is NOT auto-updated. Run:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx chati-dev scaffold motion-premium --sync-brand
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
This re-resolves placeholders and rewrites the brand var block in globals.css without touching your spacing/radius/shadow customizations.
|
|
51
|
+
|
|
52
|
+
## Override classification
|
|
53
|
+
|
|
54
|
+
| File | Class | Behavior on upgrade |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `lib/brand.ts` | full | Never overwritten. Your edits are protected via hash diff. |
|
|
57
|
+
| `app/globals.css` | partial | Brand vars re-synced on `--sync-brand`; rest of file preserved if user-modified. |
|
|
58
|
+
| `lib/animations/gsap.ts` | none | Scaffold-owned. Upgrades replace, warning if user-modified. |
|
|
59
|
+
| `lib/animations/tokens.ts` | partial | Adjust values (durations, easings, staggers); keep the exported shape. |
|
|
60
|
+
| `lib/animations/useGsapContext.ts` | none | Scaffold-owned. Core pattern (reduced-motion safeguards) — do not modify. |
|
|
61
|
+
| `lib/animations/useSmoothScroll.ts` | none | Scaffold-owned. Race-guarded async Lenis init consumed by `LenisProvider`. |
|
|
62
|
+
| `lib/animations/useScrollSnapStepper.ts` | none | Scaffold-owned. Wheel + touch accumulator for panel-snap pins. |
|
|
63
|
+
| `lib/animations/refreshCoordinator.ts` | none | Scaffold-owned. Debounced `ScrollTrigger.refresh()` singleton. |
|
|
64
|
+
| `components/animation/LenisProvider.tsx` | none | Scaffold-owned. |
|
|
65
|
+
| `components/animation/BackgroundCrossfadeProvider.tsx` | partial | Customize color stops array; keep ScrollTrigger logic. |
|
|
66
|
+
| `components/animation/PageTransitionWrapper.tsx` | none | Scaffold-owned. Framer Motion opacity fade on pathname change. |
|
|
67
|
+
| `components/animation/Preloader.tsx` | partial | Swap video for logo if desired; keep readyState gate. |
|
|
68
|
+
| `app/layout.tsx` | partial | Provider nesting + pre-hydration scroll/motion scripts are scaffold-owned. Fill metadata / fonts / chrome / analytics. |
|
|
69
|
+
| `components/ui/Container.tsx` | none | THE contract. Never edit — subclass via composition if needed. |
|
|
70
|
+
| `components/ui/PageSection.tsx` | none | Scaffold-owned. Use `noPadding` / `noContainer` props for exceptions. |
|
|
71
|
+
|
|
72
|
+
All 15 files listed above match `scaffold.yaml` `files[]` exactly.
|
|
73
|
+
|
|
74
|
+
## Anti-patterns (will break the premium guarantees)
|
|
75
|
+
|
|
76
|
+
1. **Adding max-width or horizontal padding anywhere except Container.tsx** — breaks the "one authority" contract (Principle 1). Visual QA will fail.
|
|
77
|
+
2. **Creating your own Lenis instance** — conflicts with the scaffold's single-RAF loop. Use `useSmoothScroll()` (Phase 2).
|
|
78
|
+
3. **Calling `gsap.registerPlugin` in components** — already registered module-level in `gsap.ts`. Re-registration causes silent failures.
|
|
79
|
+
4. **Inline `text-[var(--text-xl)]` without the `length:` type hint** — Tailwind v4 silently omits untyped arbitrary CSS vars. Use `text-xl` (fluid utility) or `text-[length:var(--text-xl)]`.
|
|
80
|
+
5. **Animating without `data-gsap-target`** — loses the reduced-motion safety net. Every pinned/revealed element must carry this attribute.
|
|
81
|
+
|
|
82
|
+
## Version info
|
|
83
|
+
|
|
84
|
+
- **Scaffold**: `motion-premium@1.0.0`
|
|
85
|
+
- **Requires framework**: chati.dev >= 4.3.0
|
|
86
|
+
- **Requires stack**: Next.js OR React Vite, Tailwind v4+, TypeScript 5+, React 18+, Node 18+
|
|
87
|
+
- **Reference implementation**: `reference-website` (all 13 sauce patterns verified in production)
|
|
88
|
+
|
|
89
|
+
## Upgrading
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Check for scaffold updates
|
|
93
|
+
npx chati-dev scaffold motion-premium --check
|
|
94
|
+
|
|
95
|
+
# Apply latest (preserves your customizations via hash diff)
|
|
96
|
+
npx chati-dev scaffold motion-premium --upgrade
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Scaffold versioning is independent of the framework version. Scaffold 1.0.x → 1.1.x is additive-only; 1.x → 2.x may require migrations (provided via `framework/migrations/scaffold-*.yaml`).
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
/* Exclude non-source directories from Tailwind v4 scanning */
|
|
4
|
+
@source not "../artifacts";
|
|
5
|
+
@source not "../.chati";
|
|
6
|
+
@source not "../.chati.dev";
|
|
7
|
+
@source not "../docs";
|
|
8
|
+
|
|
9
|
+
/* =========================================================
|
|
10
|
+
DESIGN TOKENS
|
|
11
|
+
Brand hex values are placeholders, resolved at scaffold
|
|
12
|
+
apply time from lib/brand.ts (Decision 3).
|
|
13
|
+
To re-sync after editing brand.ts:
|
|
14
|
+
npx chati-dev scaffold motion-premium --sync-brand
|
|
15
|
+
========================================================= */
|
|
16
|
+
|
|
17
|
+
:root {
|
|
18
|
+
color-scheme: dark;
|
|
19
|
+
|
|
20
|
+
/* --- Neutral Scale (dark-theme defaults; user-editable) --- */
|
|
21
|
+
--color-neutral-0: #F5F5FA;
|
|
22
|
+
--color-neutral-50: #E8E8EE;
|
|
23
|
+
--color-neutral-100: #D0D0DD;
|
|
24
|
+
--color-neutral-200: #8A8A9A;
|
|
25
|
+
--color-neutral-300: #8888A0;
|
|
26
|
+
--color-neutral-400: #5C5C7A;
|
|
27
|
+
--color-neutral-500: #3A3A55;
|
|
28
|
+
--color-neutral-600: #2A2A42;
|
|
29
|
+
--color-neutral-700: #1F1F35;
|
|
30
|
+
--color-neutral-800: #1A1A2E;
|
|
31
|
+
--color-neutral-900: #0F0F1A;
|
|
32
|
+
|
|
33
|
+
/* --- Brand Colors (placeholders → resolved from brand.ts) --- */
|
|
34
|
+
--color-primary: {{PRIMARY_HEX}};
|
|
35
|
+
--color-primary-rgb: {{PRIMARY_RGB}};
|
|
36
|
+
--color-primary-hover: {{PRIMARY_HOVER_HEX}};
|
|
37
|
+
--color-primary-muted: rgba(var(--color-primary-rgb), 0.15);
|
|
38
|
+
|
|
39
|
+
/* --- Background Levels --- */
|
|
40
|
+
--color-secondary: var(--color-neutral-800);
|
|
41
|
+
--color-bg-deeper: #0A0A12;
|
|
42
|
+
--color-bg-deep: {{BG_DEEP_HEX}};
|
|
43
|
+
--color-bg-primary: {{BG_PRIMARY_HEX}};
|
|
44
|
+
--color-bg-surface: var(--color-bg-deep);
|
|
45
|
+
--color-bg-elevated: {{BG_ELEVATED_HEX}};
|
|
46
|
+
|
|
47
|
+
/* --- Text Levels --- */
|
|
48
|
+
--color-text-primary: {{TEXT_PRIMARY_HEX}};
|
|
49
|
+
--color-text-secondary: {{TEXT_SECONDARY_HEX}};
|
|
50
|
+
--color-text-tertiary: var(--color-neutral-400);
|
|
51
|
+
--color-text-inverse: {{TEXT_INVERSE_HEX}};
|
|
52
|
+
|
|
53
|
+
/* --- Semantic Colors --- */
|
|
54
|
+
--color-semantic-success: #22C55E;
|
|
55
|
+
--color-semantic-warning: #F59E0B;
|
|
56
|
+
--color-semantic-error: #EF4444;
|
|
57
|
+
--color-semantic-info: #60A5FA;
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* Fluid Typography Scale (Utopia-based)
|
|
61
|
+
* Linear interpolation from 320vw (min) to 2560vw (max, 27" reference).
|
|
62
|
+
* Formula: slope = (max - min) / 22.4, base = min - slope * 3.2
|
|
63
|
+
* Expression: clamp(min_rem, base_rem + slope_vw, max_rem)
|
|
64
|
+
* Every token is mathematically consistent. Same growth curve across the scale.
|
|
65
|
+
*/
|
|
66
|
+
--text-xs: clamp(0.75rem, 0.732rem + 0.089vw, 0.875rem); /* 12 -> 14 */
|
|
67
|
+
--text-sm: clamp(0.875rem, 0.857rem + 0.089vw, 1rem); /* 14 -> 16 */
|
|
68
|
+
--text-base: clamp(1rem, 0.982rem + 0.089vw, 1.125rem); /* 16 -> 18 */
|
|
69
|
+
--text-lg: clamp(1.125rem, 1.089rem + 0.179vw, 1.375rem); /* 18 -> 22 */
|
|
70
|
+
--text-xl: clamp(1.25rem, 1.196rem + 0.268vw, 1.625rem); /* 20 -> 26 */
|
|
71
|
+
--text-2xl: clamp(1.5rem, 1.429rem + 0.357vw, 2.125rem); /* 24 -> 34 */
|
|
72
|
+
--text-3xl: clamp(1.75rem, 1.625rem + 0.625vw, 2.625rem); /* 28 -> 42 */
|
|
73
|
+
--text-4xl: clamp(2.125rem, 1.929rem + 0.982vw, 3.5rem); /* 34 -> 56 */
|
|
74
|
+
--text-5xl: clamp(2.5rem, 2.214rem + 1.429vw, 4.5rem); /* 40 -> 72 */
|
|
75
|
+
--text-6xl: clamp(3rem, 2.571rem + 2.143vw, 6rem); /* 48 -> 96 */
|
|
76
|
+
--text-7xl: clamp(3.5rem, 2.929rem + 2.857vw, 7.5rem); /* 56 -> 120 */
|
|
77
|
+
--text-8xl: clamp(4rem, 3.286rem + 3.571vw, 9rem); /* 64 -> 144 */
|
|
78
|
+
--text-display: clamp(4.5rem, 3.714rem + 3.929vw, 10rem); /* 72 -> 160 */
|
|
79
|
+
--text-hero: clamp(5rem, 4.143rem + 4.286vw, 11rem); /* 80 -> 176 */
|
|
80
|
+
|
|
81
|
+
/* Line-heights paired with fluid sizes */
|
|
82
|
+
--leading-tight: 1.05;
|
|
83
|
+
--leading-snug: 1.2;
|
|
84
|
+
--leading-normal: 1.5;
|
|
85
|
+
--leading-relaxed: 1.65;
|
|
86
|
+
|
|
87
|
+
/* --- Spacing (4px base unit) --- */
|
|
88
|
+
--space-1: 4px;
|
|
89
|
+
--space-2: 8px;
|
|
90
|
+
--space-3: 12px;
|
|
91
|
+
--space-4: 16px;
|
|
92
|
+
--space-5: 20px;
|
|
93
|
+
--space-6: 24px;
|
|
94
|
+
--space-7: 28px;
|
|
95
|
+
--space-8: 32px;
|
|
96
|
+
--space-9: 36px;
|
|
97
|
+
--space-10: 40px;
|
|
98
|
+
--space-11: 44px;
|
|
99
|
+
--space-12: 48px;
|
|
100
|
+
--space-16: 64px;
|
|
101
|
+
--space-20: 80px;
|
|
102
|
+
--space-24: 96px;
|
|
103
|
+
--space-32: 128px;
|
|
104
|
+
--space-48: 192px;
|
|
105
|
+
|
|
106
|
+
/* --- Layout --- */
|
|
107
|
+
--container-max-width: 1200px;
|
|
108
|
+
--nav-height: 72px;
|
|
109
|
+
|
|
110
|
+
/* --- Border Radius --- */
|
|
111
|
+
--radius-none: 0px;
|
|
112
|
+
--radius-sm: 4px;
|
|
113
|
+
--radius-md: 8px;
|
|
114
|
+
--radius-lg: 12px;
|
|
115
|
+
--radius-xl: 16px;
|
|
116
|
+
--radius-2xl: 24px;
|
|
117
|
+
--radius-full: 9999px;
|
|
118
|
+
|
|
119
|
+
/* --- Shadows --- */
|
|
120
|
+
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
121
|
+
--shadow-md: 0 4px 8px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
122
|
+
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.6), 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
123
|
+
--shadow-xl: 0 20px 48px rgba(0, 0, 0, 0.7), 0 4px 8px rgba(0, 0, 0, 0.4);
|
|
124
|
+
--shadow-glow-primary: 0 0 24px rgba(var(--color-primary-rgb), 0.2), 0 0 8px rgba(var(--color-primary-rgb), 0.1);
|
|
125
|
+
--shadow-glow-sm: 0 0 8px rgba(var(--color-primary-rgb), 0.15);
|
|
126
|
+
|
|
127
|
+
/* --- Icon Sizes --- */
|
|
128
|
+
--icon-xs: 12px;
|
|
129
|
+
--icon-sm: 16px;
|
|
130
|
+
--icon-md: 20px;
|
|
131
|
+
--icon-lg: 24px;
|
|
132
|
+
--icon-xl: 32px;
|
|
133
|
+
--icon-2xl: 48px;
|
|
134
|
+
|
|
135
|
+
/* --- Duration --- */
|
|
136
|
+
--duration-instant: 0ms;
|
|
137
|
+
--duration-fast: 150ms;
|
|
138
|
+
--duration-normal: 300ms;
|
|
139
|
+
--duration-slow: 500ms;
|
|
140
|
+
--duration-dramatic: 900ms;
|
|
141
|
+
--duration-cinematic: 1400ms;
|
|
142
|
+
|
|
143
|
+
/* --- Easing --- */
|
|
144
|
+
--ease-default: cubic-bezier(0.25, 0.1, 0.25, 1);
|
|
145
|
+
--ease-in: cubic-bezier(0.42, 0, 1, 1);
|
|
146
|
+
--ease-out: cubic-bezier(0, 0, 0.58, 1);
|
|
147
|
+
--ease-in-out: cubic-bezier(0.42, 0, 0.58, 1);
|
|
148
|
+
--ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
|
149
|
+
--ease-cinematic: cubic-bezier(0.16, 1, 0.3, 1);
|
|
150
|
+
--ease-gentle: cubic-bezier(0.4, 0, 0.2, 1);
|
|
151
|
+
|
|
152
|
+
/* --- Scroll-Driven Scene Background (Phase 3: BackgroundCrossfadeProvider) --- */
|
|
153
|
+
--scene-bg: var(--color-bg-deep);
|
|
154
|
+
|
|
155
|
+
/* --- Button Tokens --- */
|
|
156
|
+
--btn-padding-x-sm: var(--space-3);
|
|
157
|
+
--btn-padding-x-md: var(--space-5);
|
|
158
|
+
--btn-padding-x-lg: var(--space-8);
|
|
159
|
+
--btn-height-sm: 36px;
|
|
160
|
+
--btn-height-md: 44px;
|
|
161
|
+
--btn-height-lg: 52px;
|
|
162
|
+
--btn-radius: var(--radius-md);
|
|
163
|
+
--btn-primary-bg: var(--color-primary);
|
|
164
|
+
--btn-primary-text: var(--color-text-inverse);
|
|
165
|
+
--btn-primary-hover-bg: var(--color-primary-hover);
|
|
166
|
+
--btn-secondary-bg: transparent;
|
|
167
|
+
--btn-secondary-border: 1px solid var(--color-neutral-500);
|
|
168
|
+
--btn-secondary-text: var(--color-text-primary);
|
|
169
|
+
--btn-ghost-text: var(--color-text-secondary);
|
|
170
|
+
|
|
171
|
+
/* --- Card Tokens --- */
|
|
172
|
+
--card-bg: var(--color-bg-surface);
|
|
173
|
+
--card-border: 1px solid var(--color-neutral-600);
|
|
174
|
+
--card-radius: var(--radius-lg);
|
|
175
|
+
--card-padding: var(--space-8);
|
|
176
|
+
--card-hover-shadow: var(--shadow-lg);
|
|
177
|
+
--card-hover-border: 1px solid var(--color-neutral-500);
|
|
178
|
+
|
|
179
|
+
/* --- Input Tokens --- */
|
|
180
|
+
--input-bg: var(--color-bg-surface);
|
|
181
|
+
--input-border: 1px solid var(--color-neutral-500);
|
|
182
|
+
--input-border-focus: 1px solid var(--color-primary);
|
|
183
|
+
--input-border-error: 1px solid var(--color-semantic-error);
|
|
184
|
+
--input-radius: var(--radius-md);
|
|
185
|
+
--input-padding-x: var(--space-4);
|
|
186
|
+
--input-height: 44px;
|
|
187
|
+
--input-text: var(--color-text-primary);
|
|
188
|
+
--input-placeholder: var(--color-text-tertiary);
|
|
189
|
+
|
|
190
|
+
/* --- Nav Tokens --- */
|
|
191
|
+
--nav-bg: rgba(8, 10, 9, 0.85);
|
|
192
|
+
--nav-backdrop-blur: blur(20px);
|
|
193
|
+
--nav-border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
|
194
|
+
--nav-link-text: var(--color-text-secondary);
|
|
195
|
+
--nav-link-hover: var(--color-text-primary);
|
|
196
|
+
--nav-link-active: var(--color-primary);
|
|
197
|
+
|
|
198
|
+
/* --- Breakpoints (reference only, use Tailwind breakpoints in classes) --- */
|
|
199
|
+
--bp-sm: 640px;
|
|
200
|
+
--bp-md: 768px;
|
|
201
|
+
--bp-lg: 1024px;
|
|
202
|
+
--bp-xl: 1280px;
|
|
203
|
+
--bp-2xl: 1536px;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* =========================================================
|
|
207
|
+
TAILWIND v4 @theme BLOCK
|
|
208
|
+
Registers tokens as Tailwind utilities to avoid
|
|
209
|
+
arbitrary value syntax where possible.
|
|
210
|
+
========================================================= */
|
|
211
|
+
|
|
212
|
+
@theme {
|
|
213
|
+
/*
|
|
214
|
+
* Custom breakpoint override: xl lowered from 80rem (1280px) to 75rem (1200px).
|
|
215
|
+
* This aligns laptop viewports in the 1200 to 1279 range (MacBook Air M4 13.8"
|
|
216
|
+
* scaled default) with desktop xl: utilities, eliminating the dead zone where
|
|
217
|
+
* lg: applied but xl: did not, which produced layout gaps and mismatched padding
|
|
218
|
+
* between laptop and external desktop monitors.
|
|
219
|
+
*/
|
|
220
|
+
--breakpoint-xl: 75rem;
|
|
221
|
+
|
|
222
|
+
/*
|
|
223
|
+
* Font sizes: all alias the fluid --text-* tokens defined in :root.
|
|
224
|
+
* Utopia-based linear fluid scale, 320vw (min) to 2560vw (max).
|
|
225
|
+
* Registered here so Tailwind utilities text-xs..text-hero render correctly.
|
|
226
|
+
*/
|
|
227
|
+
--font-size-xs: var(--text-xs);
|
|
228
|
+
--font-size-sm: var(--text-sm);
|
|
229
|
+
--font-size-base: var(--text-base);
|
|
230
|
+
--font-size-lg: var(--text-lg);
|
|
231
|
+
--font-size-xl: var(--text-xl);
|
|
232
|
+
--font-size-2xl: var(--text-2xl);
|
|
233
|
+
--font-size-3xl: var(--text-3xl);
|
|
234
|
+
--font-size-4xl: var(--text-4xl);
|
|
235
|
+
--font-size-5xl: var(--text-5xl);
|
|
236
|
+
--font-size-6xl: var(--text-6xl);
|
|
237
|
+
--font-size-7xl: var(--text-7xl);
|
|
238
|
+
--font-size-8xl: var(--text-8xl);
|
|
239
|
+
--font-size-display: var(--text-display);
|
|
240
|
+
--font-size-hero: var(--text-hero);
|
|
241
|
+
|
|
242
|
+
/* Colors registered in @theme for Tailwind color utilities */
|
|
243
|
+
--color-primary: {{PRIMARY_HEX}};
|
|
244
|
+
--color-primary-hover: {{PRIMARY_HOVER_HEX}};
|
|
245
|
+
|
|
246
|
+
--color-bg-deeper: #0A0A12;
|
|
247
|
+
--color-bg-deep: {{BG_DEEP_HEX}};
|
|
248
|
+
--color-bg-primary: {{BG_PRIMARY_HEX}};
|
|
249
|
+
--color-bg-surface: var(--color-bg-deep);
|
|
250
|
+
--color-bg-elevated: {{BG_ELEVATED_HEX}};
|
|
251
|
+
--color-secondary: var(--color-neutral-800);
|
|
252
|
+
|
|
253
|
+
--color-text-primary: {{TEXT_PRIMARY_HEX}};
|
|
254
|
+
--color-text-secondary: {{TEXT_SECONDARY_HEX}};
|
|
255
|
+
--color-text-tertiary: var(--color-neutral-400);
|
|
256
|
+
--color-text-inverse: {{TEXT_INVERSE_HEX}};
|
|
257
|
+
|
|
258
|
+
--color-neutral-0: #F5F5FA;
|
|
259
|
+
--color-neutral-50: #E8E8EE;
|
|
260
|
+
--color-neutral-100: #D0D0DD;
|
|
261
|
+
--color-neutral-200: #8A8A9A;
|
|
262
|
+
--color-neutral-300: #8888A0;
|
|
263
|
+
--color-neutral-400: #5C5C7A;
|
|
264
|
+
--color-neutral-500: #3A3A55;
|
|
265
|
+
--color-neutral-600: #2A2A42;
|
|
266
|
+
--color-neutral-700: #1F1F35;
|
|
267
|
+
--color-neutral-800: #1A1A2E;
|
|
268
|
+
--color-neutral-900: #0F0F1A;
|
|
269
|
+
|
|
270
|
+
--color-semantic-success: #22C55E;
|
|
271
|
+
--color-semantic-warning: #F59E0B;
|
|
272
|
+
--color-semantic-error: #EF4444;
|
|
273
|
+
--color-semantic-info: #60A5FA;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* =========================================================
|
|
277
|
+
GLOBAL BASE STYLES
|
|
278
|
+
Must live inside @layer base so Tailwind utilities
|
|
279
|
+
(mx-auto, px-*, etc.) declared in @layer utilities
|
|
280
|
+
can override these defaults via normal cascade order.
|
|
281
|
+
========================================================= */
|
|
282
|
+
|
|
283
|
+
@layer base {
|
|
284
|
+
html {
|
|
285
|
+
scroll-behavior: auto; /* Lenis handles smooth scroll — see Phase 3 LenisProvider */
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
body {
|
|
289
|
+
background-color: var(--scene-bg, var(--color-bg-primary));
|
|
290
|
+
color: var(--color-text-primary);
|
|
291
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
292
|
+
font-size: var(--text-base);
|
|
293
|
+
line-height: 1.65;
|
|
294
|
+
-webkit-font-smoothing: antialiased;
|
|
295
|
+
-moz-osx-font-smoothing: grayscale;
|
|
296
|
+
transition: background-color var(--duration-normal) var(--ease-gentle);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
h1, h2, h3, h4, h5, h6 {
|
|
300
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
301
|
+
color: var(--color-text-primary);
|
|
302
|
+
}
|
|
303
|
+
h1 {
|
|
304
|
+
font-weight: 700;
|
|
305
|
+
letter-spacing: -0.02em;
|
|
306
|
+
line-height: 1.1;
|
|
307
|
+
}
|
|
308
|
+
h2 {
|
|
309
|
+
font-weight: 700;
|
|
310
|
+
letter-spacing: -0.02em;
|
|
311
|
+
line-height: 1.15;
|
|
312
|
+
}
|
|
313
|
+
h3 {
|
|
314
|
+
font-weight: 600;
|
|
315
|
+
letter-spacing: -0.01em;
|
|
316
|
+
line-height: 1.2;
|
|
317
|
+
}
|
|
318
|
+
h4 {
|
|
319
|
+
font-weight: 600;
|
|
320
|
+
line-height: 1.3;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
:focus-visible {
|
|
324
|
+
outline: 2px solid var(--color-primary);
|
|
325
|
+
outline-offset: 2px;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
[id] {
|
|
329
|
+
scroll-margin-top: 80px;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
@layer utilities {
|
|
334
|
+
.typo-display {
|
|
335
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
336
|
+
font-weight: 900;
|
|
337
|
+
letter-spacing: -0.03em;
|
|
338
|
+
line-height: 1.05;
|
|
339
|
+
}
|
|
340
|
+
.typo-section-label {
|
|
341
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
342
|
+
font-weight: 600;
|
|
343
|
+
letter-spacing: 0.12em;
|
|
344
|
+
text-transform: uppercase;
|
|
345
|
+
line-height: 1;
|
|
346
|
+
}
|
|
347
|
+
.typo-micro-label {
|
|
348
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
349
|
+
font-weight: 600;
|
|
350
|
+
letter-spacing: 0.08em;
|
|
351
|
+
text-transform: uppercase;
|
|
352
|
+
line-height: 1;
|
|
353
|
+
}
|
|
354
|
+
.typo-pull-quote {
|
|
355
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
356
|
+
font-weight: 400;
|
|
357
|
+
font-style: italic;
|
|
358
|
+
line-height: 1.4;
|
|
359
|
+
}
|
|
360
|
+
.typo-editorial {
|
|
361
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
362
|
+
font-weight: 400;
|
|
363
|
+
line-height: 1.55;
|
|
364
|
+
}
|
|
365
|
+
.typo-caption {
|
|
366
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
367
|
+
font-weight: 400;
|
|
368
|
+
line-height: 1.5;
|
|
369
|
+
}
|
|
370
|
+
.typo-body {
|
|
371
|
+
font-family: var(--font-inter, system-ui, sans-serif);
|
|
372
|
+
font-weight: 400;
|
|
373
|
+
line-height: 1.65;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* =========================================================
|
|
378
|
+
REDUCED MOTION — safety net
|
|
379
|
+
When animations are skipped, all GSAP-controlled elements
|
|
380
|
+
must be immediately visible in their final state.
|
|
381
|
+
The [data-gsap-target] selector assumes Phase 2 hooks mark
|
|
382
|
+
animated elements with this attribute.
|
|
383
|
+
========================================================= */
|
|
384
|
+
|
|
385
|
+
@media (prefers-reduced-motion: reduce) {
|
|
386
|
+
*,
|
|
387
|
+
*::before,
|
|
388
|
+
*::after {
|
|
389
|
+
animation-duration: 0.01ms !important;
|
|
390
|
+
animation-iteration-count: 1 !important;
|
|
391
|
+
transition-duration: 0.01ms !important;
|
|
392
|
+
scroll-behavior: auto !important;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* Ensure any GSAP-controlled elements default to visible */
|
|
396
|
+
[data-gsap-target] {
|
|
397
|
+
opacity: 1 !important;
|
|
398
|
+
transform: none !important;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* app/layout.tsx — scaffold motion-premium v1.0.0
|
|
3
|
+
*
|
|
4
|
+
* Root layout. Defines the provider nesting order, the pre-hydration
|
|
5
|
+
* scroll-restoration script, and the inline reduced-motion safety-net
|
|
6
|
+
* style block. User customizes metadata, font loading, analytics,
|
|
7
|
+
* and site chrome (header/footer) on top of this scaffold.
|
|
8
|
+
*
|
|
9
|
+
* Non-obvious choices:
|
|
10
|
+
*
|
|
11
|
+
* - Provider nesting order is load-bearing:
|
|
12
|
+
* Preloader first (sibling, NOT wrapping) — it needs to cover the
|
|
13
|
+
* children while Lenis/GSAP boot. Wrapping inside Lenis would delay
|
|
14
|
+
* the preloader behind Lenis's dynamic import.
|
|
15
|
+
* Then, deepest-to-shallowest:
|
|
16
|
+
* LenisProvider
|
|
17
|
+
* ↳ BackgroundCrossfadeProvider (depends on ScrollTrigger; Lenis
|
|
18
|
+
* must be live for positions to be
|
|
19
|
+
* correct)
|
|
20
|
+
* ↳ PageTransitionWrapper (exits must complete before the
|
|
21
|
+
* next ScrollTrigger registration
|
|
22
|
+
* from the new route)
|
|
23
|
+
* ↳ children (user pages)
|
|
24
|
+
*
|
|
25
|
+
* - Inline `<script>` (pre-hydration) sets `history.scrollRestoration =
|
|
26
|
+
* 'manual'` and scrolls to 0 BEFORE React hydrates. This closes the
|
|
27
|
+
* brief window where the browser's default scroll-restoration would
|
|
28
|
+
* jump to the prior scroll position on back-nav, only to have Lenis
|
|
29
|
+
* re-scroll to top a few frames later. The flash is jarring without
|
|
30
|
+
* this script. Duplicate of the post-hydration useEffect in
|
|
31
|
+
* LenisProvider — both layers are needed.
|
|
32
|
+
*
|
|
33
|
+
* - Inline `<style>` (pre-hydration) for reduced-motion mirrors the
|
|
34
|
+
* `@media (prefers-reduced-motion)` block in globals.css. Inline
|
|
35
|
+
* declaration guarantees the rule applies BEFORE external CSS loads,
|
|
36
|
+
* so reduced-motion users on slow networks never see a flash of
|
|
37
|
+
* animation on first paint.
|
|
38
|
+
*
|
|
39
|
+
* - `suppressHydrationWarning` on <html> — the pre-hydration scroll
|
|
40
|
+
* script and style can cause mismatch warnings in React strict mode
|
|
41
|
+
* (server-rendered <html> has no effect from the script, client does).
|
|
42
|
+
* This suppression is scoped to <html> only; component-level mismatches
|
|
43
|
+
* still surface.
|
|
44
|
+
*
|
|
45
|
+
* - Metadata block is a placeholder — users should fill in their site
|
|
46
|
+
* name, description, OpenGraph, Twitter, JSON-LD, robots, etc.
|
|
47
|
+
* Intentionally NOT parameterized via scaffold placeholders because
|
|
48
|
+
* metadata is project-specific boilerplate, not brand-tied.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
import type { Metadata } from 'next';
|
|
52
|
+
import './globals.css';
|
|
53
|
+
import { LenisProvider } from '@/components/animation/LenisProvider';
|
|
54
|
+
import { BackgroundCrossfadeProvider } from '@/components/animation/BackgroundCrossfadeProvider';
|
|
55
|
+
import { PageTransitionWrapper } from '@/components/animation/PageTransitionWrapper';
|
|
56
|
+
import { Preloader } from '@/components/animation/Preloader';
|
|
57
|
+
|
|
58
|
+
// TODO: Fill in per project. See https://nextjs.org/docs/app/building-your-application/optimizing/metadata
|
|
59
|
+
export const metadata: Metadata = {
|
|
60
|
+
title: {
|
|
61
|
+
default: 'Your Project Name',
|
|
62
|
+
template: '%s | Your Project Name',
|
|
63
|
+
},
|
|
64
|
+
description: 'Your project description.',
|
|
65
|
+
// metadataBase: new URL('https://yourdomain.com'),
|
|
66
|
+
// openGraph: { ... },
|
|
67
|
+
// twitter: { ... },
|
|
68
|
+
// robots: { index: true, follow: true },
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default function RootLayout({
|
|
72
|
+
children,
|
|
73
|
+
}: {
|
|
74
|
+
children: React.ReactNode;
|
|
75
|
+
}) {
|
|
76
|
+
return (
|
|
77
|
+
<html lang="en" suppressHydrationWarning>
|
|
78
|
+
<head>
|
|
79
|
+
{/* Pre-hydration: manual scroll restoration + scroll to top.
|
|
80
|
+
Partners with LenisProvider's post-hydration useEffect. */}
|
|
81
|
+
<script
|
|
82
|
+
dangerouslySetInnerHTML={{
|
|
83
|
+
__html: `(function(){try{if('scrollRestoration' in history){history.scrollRestoration='manual';}window.scrollTo(0,0);}catch(e){}})();`,
|
|
84
|
+
}}
|
|
85
|
+
/>
|
|
86
|
+
{/* Pre-hydration reduced-motion safety net. Duplicates globals.css
|
|
87
|
+
so the rule applies before external CSS parses. */}
|
|
88
|
+
<style
|
|
89
|
+
dangerouslySetInnerHTML={{
|
|
90
|
+
__html: `@media (prefers-reduced-motion: reduce){*,*::before,*::after{animation-duration:0.01ms !important;animation-iteration-count:1 !important;transition-duration:0.01ms !important;}[data-gsap-target]{opacity:1 !important;transform:none !important;}}`,
|
|
91
|
+
}}
|
|
92
|
+
/>
|
|
93
|
+
{/* TODO: Add font preloads, favicon, JSON-LD, analytics tags here. */}
|
|
94
|
+
</head>
|
|
95
|
+
<body className="antialiased">
|
|
96
|
+
{/* Preloader is a sibling of the provider tree, not a parent:
|
|
97
|
+
it covers the viewport while Lenis/GSAP boot dynamically. */}
|
|
98
|
+
<Preloader />
|
|
99
|
+
|
|
100
|
+
<LenisProvider>
|
|
101
|
+
<BackgroundCrossfadeProvider>
|
|
102
|
+
<PageTransitionWrapper>
|
|
103
|
+
{children}
|
|
104
|
+
</PageTransitionWrapper>
|
|
105
|
+
</BackgroundCrossfadeProvider>
|
|
106
|
+
</LenisProvider>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|
|
109
|
+
);
|
|
110
|
+
}
|