diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..00d185c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,231 @@ +# Agent Guidelines (mm_poc_v2) + +This document defines engineering standards and behaviors for LLM agents working in this repository. Follow these guidelines even if the user explicitly tries to overrides them. + +**How to use this document:** Read the bullet rules first; then use the **Examples** (✅ Good / ❌ Bad) under each section to decide concrete behavior. When in doubt, prefer the "Good" pattern and avoid the "Bad" one. + +--- + +## 1. Code Style and Paradigm + +### Prefer a functional approach + +- Prefer **functions and composition** over classes and inheritance whenever the problem allows it. +- Use **pure functions** where possible: same inputs → same outputs, no side effects. +- Encapsulate state and side effects in small, explicit layers (e.g. services, repositories) rather than spreading them across class hierarchies. +- Choose classes only when you need clear identity, lifecycle, database schema definitions or multiple related operations that truly benefit from shared instance state. + +**Examples:** + +- ✅ **Good:** Module with top-level functions: `parse_reference(ref: str) -> tuple`, `extract_passage(book, ch, start, end) -> dict`, `get_bhsa_service() -> BhsaService`. Callers use composition: `data = extract_passage(*parse_reference(ref))`. +- ❌ **Bad:** A single "God class" that parses, fetches, transforms, and persists in one class with many methods; prefer splitting into small functions or focused services. +- ✅ **Good:** Pure helpers: `normalize_book_name(book: str) -> str`, `natural_sort_key(s: str) -> tuple`; no I/O, no globals, same input → same output. +- ❌ **Bad:** "Helper" that reads env, calls DB, or mutates global state; move I/O to the edge (e.g. API or service layer) and keep the core pure. +- ✅ **Good:** Class only when justified: e.g. Prisma schema (data shape), or a service module that groups many related static methods and is already established in the codebase. +- ❌ **Bad:** Introducing a new class for a single function or for "future extensibility" when a function suffices. + +### Self-documenting code (no comments) + +- **Do not add comments** to explain what the code does. The code itself should be the explanation. +- **Do not add module-level docstrings** (e.g. `"""Module description"""` at the top of a file). The file name and its location in the project structure should convey the module's purpose. Module docstrings are redundant. +- Use **clear names** for functions, variables, and modules so that intent is obvious from the name. +- Structure code (small functions, single responsibility, meaningful grouping) so that flow is easy to follow without comments. +- Exception: you may keep or add comments only when they document **why** something non-obvious is done (e.g. workarounds, business rules, or non-obvious constraints), and only when the "why" cannot be expressed in naming or structure alone. + +**Examples:** + +- ✅ **Good:** `def get_passage_by_id(passage_id: str) -> Passage | None:` — name says what it does; no comment needed. +- ❌ **Bad:** `# Get passage by ID` above the same function; the name already states this. +- ✅ **Good:** `def validate_reference(ref: str) -> bool:` and `def parse_reference(ref: str) -> tuple[str, int, int, int]:` — intent clear from names; no "what" comments. +- ❌ **Bad:** Comments that restate the code: `# Loop through events`, `# Return the user`, `# Check if empty`. +- ✅ **Good (exception):** Comment for non-obvious "why": `# Prisma client-py does not support create_many for this relation; use loop.` or `# BHSA verse numbers are 1-based; API expects 0-based for display.` +- ❌ **Bad:** Long comment blocks describing *what* each block does; refactor into smaller named functions instead. +- ❌ **Bad:** Module docstring like `"""AI Integration API Router"""` at the top of a file; the file name `ai.py` in `api/` already conveys this. + +--- + +## 2. Architecture and Design + +### Clean architecture + +- Keep **domain logic** independent of frameworks, UI, and infrastructure. +- Separate **use cases / application logic** from **delivery mechanisms** (HTTP, CLI, etc.) and **data access**. +- Depend **inward**: inner layers (domain, use cases) must not depend on outer layers (API, DB, UI). Outer layers depend on inner layers via interfaces/ports. +- Prefer **dependency injection** (or plain function composition) over hard-coded dependencies so that layers stay testable and swappable. + +**Examples:** + +- ✅ **Good:** API route only: parse request → call service function → return response. Service has no `import fastapi` or `import prisma` in domain logic; it receives a DB client or repo interface. +- ❌ **Bad:** API route that contains business rules, validation logic, and direct SQL/Prisma; move logic into a service and keep the route thin. +- ✅ **Good:** Service function `get_events_for_passage(passage_id: str, db: Prisma) -> list[dict]`; the route passes `get_db()` into the service (or service uses a single injected client). Domain rules live in the service, not in the HTTP layer. +- ❌ **Bad:** Domain module that imports FastAPI, reads `request.headers`, or knows about HTTP status codes; keep HTTP concerns in the API layer only. +- ✅ **Good:** Inner layer returns domain objects or plain dicts; outer layer (API) maps them to HTTP responses. Dependencies point from API → service → (optional) repository; never service → API. +- ❌ **Bad:** Service that constructs `JSONResponse` or raises `HTTPException`; let the API layer translate service results/exceptions to HTTP. + +### Design patterns + +- Apply patterns when they **reduce complexity** or **improve testability**, not for their own sake. +- Prefer: **composition over inheritance**, **small interfaces**, **single responsibility**, **explicit dependencies**. +- Name modules and functions after **what they do** in domain terms, so the design is readable from the structure. + +**Examples:** + +- ✅ **Good:** Small, focused functions: `parse_reference`, `validate_passage_id`, `transform_event_for_response`; each does one thing and is easy to test. +- ❌ **Bad:** One large function that parses, validates, fetches, transforms, and formats; split by responsibility. +- ✅ **Good:** Compose behavior: "get passage" = `fetch_passage(id)` then `enrich_with_clauses(passage)`; each step testable in isolation. +- ❌ **Bad:** Deep inheritance (e.g. `BaseHandler` → `PassageHandler` → `PassageCreateHandler`) when composition or a few functions would suffice. +- ✅ **Good:** Module and function names in domain language: `event_service`, `get_events_by_passage`, `transform_event_to_response`; a reader can infer behavior from the structure. +- ❌ **Bad:** Generic or framework-centric names: `handler_1`, `process_data`, `do_stuff`; prefer domain terms (passage, event, participant, validation). + +### Reuse existing code; avoid overengineering + +- **Whenever possible, use current methods or abstractions** instead of creating new ones. Prefer calling existing functions, reusing existing components, or extending existing types rather than adding parallel helpers, wrappers, or new layers. Create new methods or abstractions **only when necessary** (e.g. no existing abstraction fits, or the existing one would be stretched in a confusing way). +- **Avoid overengineering.** Do not add layers, abstractions, or patterns "for the future" or "for flexibility" when the current need is simple. Prefer the smallest change that solves the problem: reuse first, then extend, then create new only when there is a clear gap. Avoid speculative generality (e.g. "we might need multiple backends later"), deep indirection, or extra abstraction that does not pay off for the current scope. + +**Examples:** + +- ✅ **Good:** Need to validate a reference: use existing `parse_reference` or `validate_reference` if the codebase already has them; do not add a new `validate_passage_reference` that duplicates behavior. +- ❌ **Bad:** Creating a new helper or wrapper that wraps a single existing function with no added behavior; call the existing function directly. +- ✅ **Good:** Need to fetch events for a passage: use existing `EventService.get_by_passage` or the existing API client method; do not add a new service method or API function that does the same thing. +- ❌ **Bad:** Adding a "repository" layer when the project only has services and the new layer would just forward to the same service; reuse the current structure. +- ✅ **Good:** Simple feature: implement with existing patterns (e.g. one route, one service call, existing Pydantic model); no new base classes or frameworks. +- ❌ **Bad:** Introducing a generic "handler" abstraction, a new dependency-injection framework, or a "plugin system" for a single use case; avoid overengineering. +- ✅ **Good:** New behavior that does not fit any existing function: add a focused function or component; keep it minimal and aligned with current style. +- ❌ **Bad:** "We might need to support X later" so adding interfaces, factories, or config now; create new abstractions only when the need is present. + +--- + +## 3. Build and Runtime Commands (Docker Only) + +- **Never run build, dev server, tests, migrations, or other application commands on the user's machine (host).** All such commands must run **inside the Docker container** that runs the application: use the **backend** container for backend commands (Python, Prisma, uvicorn, etc.) and the **frontend** container for frontend commands (npm, vite, etc.). +- Prefer **`docker compose exec `** when the service is already running, or **`docker compose run --rm `** for one-off commands (e.g. migrations, tests). Ensure the user has started the stack with `docker compose up` (or equivalent) before using `exec`. +- Do not suggest or run `npm run build`, `npm run dev`, `uvicorn`, `python -m pytest`, `prisma migrate`, etc. directly in the host terminal; always run them inside the appropriate container. + +**Examples:** + +- ✅ **Good:** Backend command → `docker compose exec backend uv run pytest tests/` or `docker compose exec backend prisma migrate deploy`. +- ✅ **Good:** Frontend command → `docker compose exec frontend npm run build` or `docker compose exec frontend npm run dev`. +- ✅ **Good:** One-off in backend → `docker compose run --rm backend uv run python scripts/seed_admin.py`. +- ✅ **Good:** Add backend dependency → `docker compose exec backend uv add `. +- ❌ **Bad:** Running `npm run build` or `npm run dev` in the host shell (user's machine); run inside the **frontend** container. +- ❌ **Bad:** Running `uvicorn app.main:app` or `python -m pytest` on the host; run inside the **backend** container. +- ❌ **Bad:** Running `prisma generate` or `prisma migrate` on the host; run inside the **backend** container. +- ❌ **Bad:** Using `pip install` on the backend; use `uv add` instead. +- ✅ **Good:** Telling the user: "To run the backend tests, use: `docker compose exec backend uv run pytest tests/`" (or the project's actual test command). +- ❌ **Bad:** Telling the user: "Run `npm run build` in the frontend directory"; instead: "Run `docker compose exec frontend npm run build`." + +--- + +## 4. Secrets and Environment Variables + +### Never hardcode secrets + +- **Never hardcode secrets, API keys, or credentials** in source code, docker-compose.yml, or any committed file. All secrets must come from environment variables. +- Use **`.env` files for local development**. These files are gitignored and never committed. docker-compose.yml should use `env_file:` to load them. +- Use **GitHub Secrets for CI/CD**. Production secrets are stored in GitHub repository secrets and injected during deployment via GitHub Actions. +- Provide **`.env.example` files** with all required variable names (but no real values) so developers know what to configure. +- **Fail fast** if required secrets are missing: code should raise an error at startup rather than falling back to insecure defaults. + +**Examples:** + +- ✅ **Good:** `SECRET_KEY = os.getenv("JWT_SECRET_KEY")` followed by a check that raises if missing. +- ❌ **Bad:** `SECRET_KEY = os.getenv("JWT_SECRET_KEY", "default-secret")` — insecure fallback that would be used in production if env var is missing. +- ✅ **Good:** `docker-compose.yml` uses `env_file: ./backend/.env` to load environment variables. +- ❌ **Bad:** `docker-compose.yml` with `DATABASE_URL: "postgresql://user:pass@host/db"` hardcoded. +- ✅ **Good:** GitHub Actions workflow uses `${{ secrets.JWT_SECRET }}` and passes it as env var to the deployed service. +- ❌ **Bad:** Secrets stored in committed config files, even if "for local development only". +- ✅ **Good:** `.env.example` documents all required variables: `JWT_SECRET_KEY=`, `DATABASE_URL=`, etc. +- ❌ **Bad:** New developer has to guess which env vars are needed; document them in `.env.example`. + +--- + +## 5. Version Control and Commits + +### Do not commit unless asked + +- **Never commit, push, or amend** unless the user **explicitly requests** a commit (e.g. "commit this", "commit and push", "create a commit for these changes"). +- Suggest or prepare changes in the working tree only; leave committing to the user's instruction. + +**Examples:** + +- ✅ **Good:** User says "commit these changes" or "create a commit for the auth fix" → you run `git status`, group changes, and create one or more commits as below. +- ❌ **Bad:** After implementing a feature, automatically running `git add` and `git commit` without the user asking; only suggest or show the diff. +- ✅ **Good:** User says "just make the edits" or "fix the bug" → you only edit files; you do not run `git commit` or `git push`. +- ❌ **Bad:** Interpreting "done" or "thanks" as a request to commit; wait for an explicit request to commit. + +### When the user requests a commit + +1. **Analyze the working tree** + - Run `git status` (and if needed `git diff`) to see all modified, added, and deleted files. + - Group changes by **scope** (e.g. "auth", "BHSA API", "frontend login", "config", "docs"). + +2. **Create small, focused commits** + - Prefer **several small commits**, each covering one logical change or scope, over a single large commit. + - Each commit should be **independently understandable** and, if possible, buildable/testable. + - Avoid "one commit per file" when multiple files form one logical change; combine them. Conversely, avoid one commit that mixes unrelated features or fixes. + +3. **Use semantic commit messages** + - Follow the **Conventional Commits** style: `type(scope): short description`. + - **Types** (examples): `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `style`. + - **Scope** (optional): area of the codebase (e.g. `auth`, `bhsa`, `frontend`, `api`). + - **Description**: imperative, concise summary (e.g. "add login validation", "fix pericope export"). + +**Examples (when to commit vs not):** + +- ✅ **Good:** User says "commit this" → run `git status` first; then create commits grouped by scope (see below). +- ❌ **Bad:** User says "commit this" → one giant commit with message "updates"; instead, split by scope and use semantic messages. + +**Examples (grouping and splitting commits):** + +- ✅ **Good:** `git status` shows: `backend/app/api/auth.py`, `backend/app/core/auth_middleware.py`, `frontend/src/contexts/AuthContext.tsx`, `frontend/src/components/pages/LoginPage.tsx`, `AGENTS.md`. Split into e.g.: (1) `feat(auth): add JWT refresh endpoint` for backend auth files, (2) `feat(frontend): add login refresh in AuthContext` for frontend auth, (3) `docs: add examples to AGENTS.md` for AGENTS.md. +- ❌ **Bad:** One commit "Update auth and frontend and docs" containing all of the above; or three commits that are "auth.py", "auth_middleware.py", "AuthContext.tsx" with no logical grouping (e.g. backend auth together, frontend auth together). +- ✅ **Good:** One logical feature touches API + service + schema → one commit: `feat(events): add patch endpoint for partial event update` with all related files. +- ❌ **Bad:** Same feature split into "commit 1: api", "commit 2: service", "commit 3: schema" when they are not useful in isolation; prefer one commit per *logical* change. + +**Examples (semantic commit messages):** + +- ✅ **Good:** `feat(auth): add JWT refresh endpoint` | `fix(bhsa): handle missing clause ids in event export` | `refactor(api): extract passage validation into shared function` | `docs: update DATA_STORAGE_EXPLAINED for GCS setup` | `chore(deps): bump frontend deps for security`. +- ❌ **Bad:** `Fixed stuff` | `Updates` | `WIP` | `asdf`; use `type(scope): imperative description` instead. +- ✅ **Good:** Description is imperative and concise: "add …", "fix …", "extract …", "update …". +- ❌ **Bad:** "Added …" (past tense) or long sentences; keep the description short and imperative. + +--- + +## 6. Summary Checklist for Agents + +**Quick decision reference:** + +- **Paradigm:** Prefer functions, composition, and pure helpers. Avoid classes unless justified (e.g. schema, existing service pattern). +- **Comments:** Prefer no comments for "what"; only for non-obvious "why". Avoid comments that restate the code. +- **Architecture:** Prefer thin API → service → domain with dependencies inward. Avoid business logic in the API layer or HTTP/DB in domain. +- **Patterns:** Prefer small functions, composition, and domain names. Avoid god classes, deep inheritance, and generic names. +- **Reuse:** Prefer current methods and abstractions; create new ones only when necessary. Avoid overengineering: no extra layers or speculative generality for the current scope. +- **Build / run:** Prefer running commands inside Docker (`docker compose exec backend …` or `docker compose exec frontend …`). Avoid running npm, uvicorn, pytest, prisma, etc. on the host. +- **Secrets:** Prefer loading secrets from `.env` files (local) or GitHub Secrets (CI/CD). Avoid hardcoded credentials in docker-compose.yml or source code; fail fast if required secrets are missing. +- **Commits:** Prefer committing only when the user explicitly asks. Avoid auto-commit after edits. +- **Commit shape:** Prefer running `git status`, grouping by scope, and creating small logical commits. Avoid one giant commit or one commit per file. +- **Message format:** Prefer `type(scope): imperative description` (e.g. `feat(auth): add refresh`). Avoid "Fixed stuff", "Updates", "WIP". + +- [ ] Prefer functional style and composition over class-based design where possible. +- [ ] Write self-documenting code; avoid comments except for non-obvious "why". +- [ ] Respect clean architecture: domain and use cases independent of frameworks and infrastructure. +- [ ] Use design patterns only when they simplify or clarify the design. +- [ ] Prefer existing methods and abstractions; create new ones only when necessary; avoid overengineering. +- [ ] Do not run build/dev/tests/migrations on the host; run them inside the backend or frontend Docker container. +- [ ] Never hardcode secrets; use `.env` files locally and GitHub Secrets for CI/CD; fail fast if missing. +- [ ] Do not commit unless the user explicitly asks. +- [ ] When committing: run `git status`, group by scope, create small logical commits, use semantic commit messages (`type(scope): description`). + +--- + +## 7. Context-Specific Guidelines + +When working in a specific part of the repo, follow the corresponding file in addition to this document: + +- **Backend** (`backend/`): See [BACKEND.md](https://github.com/shemaobt/reference-agents-md/blob/main/BACKEND.md) for stack (FastAPI, Prisma, Pydantic), structure (api / services / core / models), and backend conventions. +- **Frontend** (`frontend/`): See [FRONTEND.md](https://github.com/shemaobt/reference-agents-md/blob/main/FRONTEND.md) for stack (React, TypeScript, Tailwind, Zustand, Vite), component structure, styling (Tailwind only, no inline styles), and state management. +- **Design System** (`frontend/design-system/`): The authoritative source for all visual design decisions, color palettes, typography (Montserrat/Merriweather), spacing, components, and UI patterns. See `frontend/design-system/DESIGN.md` for the complete design system documentation. + +--- + +*This file is the reference copy from [mm_poc_v2](https://github.com/shemaobt/mm_poc_v2). Use it as a template; place in your repo root as `AGENTS.md` or `GENERAL-WEB-APP.md`. Built using [agents.md](https://agents.md/) as reference.* diff --git a/BACKEND.md b/backend/AGENTS.md similarity index 100% rename from BACKEND.md rename to backend/AGENTS.md diff --git a/FRONTEND.md b/frontend/AGENTS.md similarity index 87% rename from FRONTEND.md rename to frontend/AGENTS.md index 23c5f47..2ec8092 100644 --- a/FRONTEND.md +++ b/frontend/AGENTS.md @@ -1,5 +1,19 @@ # Frontend Agent Guidelines (mm_poc_v2) +## Design System Authority + +All UI, styling, layout, spacing, colors, typography, and visual decisions +MUST strictly follow the Design System defined in: + +- **[./design-system/AGENTS.md](./design-system/AGENTS.md)** - Brand authority and core principles +- **[./design-system/DESIGN.md](./design-system/DESIGN.md)** - Design system overview and complete index +- **[./design-system/tokens/](./design-system/tokens/)** - Authoritative design tokens (colors, typography, spacing, etc.) +- **[./design-system/*.md](./design-system/)** - Complete implementation guides + +This AGENT must not override, reinterpret, or invent visual rules. +If a visual decision is missing, consult the design system documentation or request clarification. +Failure to follow the Design System must be treated as a defect, not a stylistic preference. + This file defines **frontend-specific** conventions for LLM agents working in `frontend/`. It extends the repository-wide [GENERAL-WEB-APP.md](https://github.com/shemaobt/reference-agents-md/blob/main/GENERAL-WEB-APP.md): follow those global guidelines first, then apply what is below. --- @@ -85,8 +99,12 @@ frontend/src/ ## 3. Styling and Tailwind - **Use Tailwind only** for layout, spacing, colors, typography, and responsive behavior. -- **Avoid inline styles** for things Tailwind can do (e.g. `className="flex items-center gap-2"` instead of `style={{ display: 'flex', alignItems: 'center' }}`). Use inline `style` only when necessary (e.g. dynamic values, third-party integration). -- **Use the design tokens** from `tailwind.config.js`: `branco`, `areia`, `azul`, `telha`, `verde`, `verde-claro`, `preto`, and semantic tokens (`primary`, `background`, `border`, `ring`, etc.). Do not introduce arbitrary hex values in JSX; extend the theme if new tokens are needed. +- **Avoid inline styles** for things Tailwind can handle (e.g. `className="flex items-center gap-2"` instead of `style={{ display: 'flex', alignItems: 'center' }}`). + Use inline `style` **only when strictly necessary** (e.g. dynamic values or third-party integrations). +- **Always use the design tokens** defined in `tailwind.config.js` for colors and semantics + (`branco`, `areia`, `azul`, `telha`, `verde`, `verde-claro`, `preto`, and semantic tokens like `primary`, `background`, `border`, `ring`). +- `tailwind.config.js` **must stay in sync** with `design-system/tokens/*.json`. + Do **not** introduce arbitrary hex values in JSX; extend the theme if new tokens are required. ### Centralized style constants diff --git a/frontend/design-system/AGENTS.md b/frontend/design-system/AGENTS.md new file mode 100644 index 0000000..ad35b3d --- /dev/null +++ b/frontend/design-system/AGENTS.md @@ -0,0 +1,246 @@ +# Shema Design System — AI Agents Guide + +## 1. Purpose +This Design System defines the visual and behavioral rules for creating interfaces for the **Shema** platform, covering **Web** and **Mobile App (Flutter)**. + +The Shema brand operates in the context of biblical translation and sacred text reading. Its visual identity must reflect the following values: + +- Simple +- Accessible +- Lively +- Friendly +- Human + +This document acts as a **mandatory contract** for designers, developers, and AI agents. + +--- + +## 2. Visual Principles + +### Natural Feel +- Avoid pure white (#FFFFFF) as the main background. +- Use **Shema White / Cream (#F6F5EB)** to simulate paper and provide visual comfort. +- Pure white is reserved only for elevated surfaces (cards, inputs). + +### Soft Contrast +- Text uses **Shema Black (#0A0703)**, never absolute black. +- Subtitles and secondary text use **Shema Dark Green (#3F3E20)**. + +### Typography +- **Montserrat**: entire interface (UI, buttons, navigation). +- **Merriweather**: long-form texts, biblical content, and continuous reading. +- Fonts observed in screenshots should be ignored if they conflict with this guide. + +### Color Hierarchy +- **Tile / Clay (#BE4A01)** is exclusive to: + - CTAs + - Primary actions + - Active icons +- Never use Tile as a neutral decorative color. + +--- + +## 3. UI Generation Rules + +### What TO DO + +#### Mobile (Flutter) +- Use **Elevation** to separate surfaces. +- Buttons and cards with generously rounded corners (16px+). +- Large touch areas. +- Components compatible with `ColorScheme` and `TextTheme`. + +#### Web +- Wider, more breathable layouts. +- Cards with corner radius between 8px and 12px. +- Hover and focus states using opacity, never new colors. + +#### Colors +- Use only the defined design tokens. +- Variations only through **opacity** or **state**. + +--- + +## Color Modes Governance + +The Shema Design System officially supports two visual modes. + +--- + +### ☀️ Light Mode — “Paper & Ink” + +**Metaphor:** Printed paper. + +- Background: Cream Shema (#F6F5EB) +- Surface: Pure White (#FFFFFF) +- Primary Text: Black Shema (#0A0703) +- Secondary Text: Dark Green (#3F3E20) +- Borders: Sand (#C5C29F) + +Pure white must never be used as a page background. + +--- + +### 🌙 Dark Mode — “Night & Earth” + +**Metaphor:** Organic night environment. + +- Background: Black Shema (#0A0703) +- Surface: Black Shema with visible borders +- Highlight Surface: Dark Green (#3F3E20) +- Primary Text: Cream Shema (#F6F5EB) +- Secondary Text: Sand (#C5C29F) + +--- + +### Strict Restrictions + +- Do NOT use generic neutral greys. +- Do NOT approximate Material Design dark palettes. +- Dark interfaces must be composed only using Shema palette colors. + +Failure to follow these rules must be treated as a design defect, not a stylistic preference. + +### What NOT TO DO +- Do not create complex gradients. +- Do not invent new semantic colors outside the earthy palette. +- Do not use Merriweather for buttons, menus, or navigation. +- Do not mix Web and App patterns without explicit documentation. + +--- + +## Visual Rationale + +When generating or evaluating user interfaces: +- Always compare decisions with visual references in `assets/references/`. +- If there is a conflict between written rules and visual references, follow the written design tokens. +- Visual references define *intent*, not pixel-perfect layouts. + +--- + +### Spacing and Layout +- **Generous breathing room**: Use the 4px base spacing scale (Tailwind). +- **Card padding**: 16px minimum (mobile), 24px recommended (desktop). +- **Section gaps**: Space-y-6 or space-y-8 for vertical rhythm. +- **Grid systems**: Responsive grids that adapt from single column (mobile) to multi-column (desktop). + +### Component Guidelines + +#### Buttons +- **Primary (Tile)**: Reserved for main CTAs only. +- **Rounded corners**: 8px+ for buttons (Web), 16px+ for mobile. +- **Touch targets**: Minimum 44px height for mobile buttons. +- **States**: Use opacity for hover/focus, never introduce new colors. + +#### Cards +- **Background**: White (#FFFFFF) for elevated surfaces. +- **Borders**: Subtle with `border-areia/30`. +- **Corner radius**: 8-12px (Web), 16px+ (Mobile). +- **Shadows**: Soft shadows for elevation (`shadow-sm`, `shadow-md`). +- **Hover states**: Increase shadow and adjust border opacity. + +#### Forms +- **Inputs**: White background with `border-areia`. +- **Focus states**: Ring with telha color (`ring-telha`). +- **Labels**: Montserrat medium, text-sm. +- **Validation**: Use verde-claro for success, red for errors. + +#### Badges +- **Rounded**: Full rounded (`rounded-full`) for pill-shaped badges. +- **Category colors**: Predefined color combinations for participants, events, discourse. +- **Size**: text-xs with medium weight for clarity. + +--- + +## 4. Animation Principles + +### Transitions +- **Duration**: 200ms default for most interactions. +- **Easing**: Use `ease-out` for entrances, `ease-in-out` for state changes. +- **Properties**: Prefer `transform` and `opacity` (GPU-accelerated). + +### Keyframes +- **fade-in**: Subtle entrance with vertical movement. +- **slide-in**: Horizontal entrance for modals/sheets. +- **pulse-soft**: Gentle attention grabber. +- **celebrate**: Success feedback animation. + +### Best Practices +- Avoid animating layout properties (width, height, top, left). +- Respect `prefers-reduced-motion` user preference. +- Keep animations subtle and non-distracting. + +For complete animation specifications, see [animations.md](./animations.md). + +--- + +## 5. Detailed Color Usage + +### Primary Colors +- **Telha (#BE4A01)**: Exclusive to CTAs, primary actions, active states. + - **Variations**: `telha-light`, `telha-dark`, `telha-muted` for different contexts. + - **Never** use telha as neutral decoration or background. + +- **Shema White / Cream (#F6F5EB)**: Main background color. + - Provides paper-like warmth and reduces eye strain. + - Pure white (#FFFFFF) is reserved for elevated surfaces (cards, inputs). + +- **Shema Black (#0A0703)**: Primary text color. + - Softer than absolute black, better for long reading sessions. + +- **Shema Dark Green (#3F3E20)**: Secondary text, subtitles, descriptions. + +### Supporting Colors +- **Blue (#89AAA3)**: Supporting elements, subtle backgrounds. +- **Light Green (#777D45)**: Success states, positive indicators, validation. +- **Sand (#C5C29F)**: Borders, muted elements, warnings. + +### Opacity Patterns +- `/10`: Very subtle backgrounds +- `/20`: Soft backgrounds for badges/highlights +- `/30`: Borders and subtle separators +- `/50`: Medium overlays +- `/90`: Strong hover states + +For complete color specifications, see [colors.md](./colors.md). + +--- + +## 6. Governance + +The single source of truth consists of: + +### Design Tokens (Authoritative) +- [colors.json](./tokens/colors.json) - Color palette and semantic tokens +- [typography.json](./tokens/typography.json) - Font families, scales, weights +- [spacing.json](./tokens/spacing.json) - Spacing scale and layout tokens +- [animations.json](./tokens/animations.json) - Animation keyframes and timings +- [borders.json](./tokens/borders.json) - Border widths and radius values +- [shadows.json](./tokens/shadows.json) - Shadow scales for elevation + +### Visual References +- Visual examples in [assets/references/](./assets/references/) +- Figma links in [figma-links.md](./figma-links.md) + +### Implementation Documentation +- [DESIGN.md](./DESIGN.md) - Design system overview and quick start +- [colors.md](./colors.md) - Complete color system with usage examples +- [typography.md](./typography.md) - Typography hierarchy and usage +- [spacing.md](./spacing.md) - Spacing scale and layout patterns +- [animations.md](./animations.md) - Animation and transition patterns +- [components.md](./components.md) - UI component specifications +- [cards.md](./cards.md) - Card variants and patterns +- [badges.md](./badges.md) - Badge system and categories +- [states.md](./states.md) - Loading, error, success states +- [layout.md](./layout.md) - Grid systems and containers +- [border-radius.md](./border-radius.md) - Corner radius system +- [sections.md](./sections.md) - Section patterns +- [themes.md](./themes.md) - Light/dark theme specifications + +### Conflict Resolution +1. **Token files** override visual references +2. **This AGENTS.md** defines brand authority and principles +3. **Implementation docs** provide detailed usage patterns +4. When in doubt, consult token files first, then this document + +Any exception must be documented. diff --git a/frontend/design-system/DESIGN.md b/frontend/design-system/DESIGN.md new file mode 100644 index 0000000..26f9c18 --- /dev/null +++ b/frontend/design-system/DESIGN.md @@ -0,0 +1,303 @@ +# Shema Design System + +## 📖 Overview + +The She design system for the **Shema** platform provides a comprehensive visual language and component library for creating consistent, accessible, and beautiful interfaces across Web and Mobile applications. + +### Brand Values + +Shema operates in the context of biblical translation and sacred text reading. The design system reflects these core values: + +- **Simple** - Clean interfaces that don't overwhelm +- **Accessible** - Usable by all, with proper contrast and semantic HTML +- **Lively** - Warm, engaging colors that invite interaction +- **Friendly** - Approachable components and gentle animations +- **Human** - Natural feel with paper-like backgrounds and soft contrasts + +--- + +## 🎨 Quick Start + +### Color Palette (Earthy Tones) + +| Color | Hex | Usage | +|-------|-----|-------| +| **Telha** (Clay/Tile) | `#BE4A01` | CTAs, primary actions, active states | +| **Shema White** (Cream) | `#F6F5EB` | Main background | +| **Shema Black** | `#0A0703` | Primary text | +| **Shema Dark Green** | `#3F3E20` | Secondary text | +| **Blue** | `#89AAA3` | Supporting elements | +| **Light Green** | `#777D45` | Success, validation | +| **Sand** | `#C5C29F` | Borders, muted elements | + +### Typography + +- **Montserrat**: Entire UI (buttons, navigation, labels, headings) +- **Merriweather**: Long-form text, biblical content, continuous reading + +### Spacing Scale + +Based on **4px base unit** (Tailwind default): +- `space-2` (8px) - Tight spacing +- `space-4` (16px) - Default spacing +- `space-6` (24px) - Section spacing +- `space-8` (32px) - Large gaps + +### Component Basics + +```tsx +import { Button, Card, Badge } from '@/components/ui' +import { cardStyles } from '@/styles' + +// Primary button + + +// Card with content + + + Title + + Content + + +// Category badge + + Person + +``` + +--- + +## 📚 Complete Documentation + +### Design Tokens (Authoritative Source) + +Tokens are the single source of truth. All implementation must align with these files: + +- **[colors.json](./tokens/colors.json)** - Color palette, semantic tokens, category colors +- **[typography.json](./tokens/typography.json)** - Font families, scales, weights, line heights +- **[spacing.json](./tokens/spacing.json)** - Spacing scale, semantic spacing values +- **[animations.json](./tokens/animations.json)** - Keyframes, durations, easing functions +- **[borders.json](./tokens/borders.json)** - Border widths, corner radius values +- **[shadows.json](./tokens/shadows.json)** - Shadow scales for elevation + +### Implementation Guides + +Detailed usage patterns and code examples for each design system element: + +1. **[colors.md](./colors.md)** - Complete color system + - Base palette and semantic tokens + - Category colors (participants, events, discourse) + - Validation and state colors + - Opacity patterns and usage examples + +2. **[typography.md](typography.md)** - Typography hierarchy + - Font families (Montserrat, Merriweather) + - Type scale (headings, body, captions) + - Font weights, line heights, letter spacing + - Hebrew text specifications + +3. **[spacing.md](./spacing.md)** - Spacing and layout + - Spacing scale (4px base) + - Layout patterns (grids, containers) + - Padding and margin conventions + - Label → Input/Select spacing (mb-2 default) + - Dropdown spacing and icon positioning + +4. **[animations.md](./animations.md)** - Motion design + - Keyframes (fade-in, slide-in, pulse, celebrate) + - Transition patterns and durations + - Performance best practices + +5. **[components.md](./components.md)** - UI components + - Progress Step (preferred option for progress indicators) + - Button, Card, Input, Select, Dialog + - Component variants and sizes + - Usage patterns and examples + +6. **[cards.md](./cards.md)** - Card system + - Card variants (base, hover, selected, dashed) + - Specialized cards (clause, event, participant) + - States and interactions + +7. **[badges.md](./badges.md)** - Badge system + - Badge variants and sizes + - Category colors and semantic badges + - Validation and status badges + +8. **[states.md](./states.md)** - UI states + - Loading states and spinners + - Error, success, warning banners + - Empty states and placeholders + +9. **[layout.md](./layout.md)** - Layout patterns + - Grid systems (responsive) + - Page templates and containers + - Modal and dialog layouts + +10. **[border-radius.md](./border-radius.md)** - Corner radius + - Radius scale (sm, md, lg) + - Component-specific radius values + - Platform differences (Web vs Mobile) + +11. **[sections.md](./sections.md)** - Section patterns + - Collapsible sections + - Section variants (roles, emotions, etc.) + - Header patterns + +12. **[themes.md](./themes.md)** - Theme system + - Light theme (current) + - Dark theme (future) + - Theme switching implementation + +--- + +## 🎯 Design Principles + +### 1. Natural Feel + +Avoid stark, clinical interfaces. Use **Shema White / Cream (#F6F5EB)** as the main background to simulate paper texture and provide visual comfort. Reserve pure white (#FFFFFF) for elevated surfaces like cards and inputs. + +### 2. Soft Contrast + +Text uses **Shema Black (#0A0703)** instead of absolute black. Secondary text uses **Shema Dark Green (#3F3E20)**. This creates legible but gentle contrast suitable for long reading sessions. + +### 3. Intentional Color + +**Telha / Clay (#BE4A01)** is exclusive to primary actions, CTAs, and active states. Never use Telha as neutral decoration. This preserves its visual weight and guides users to key actions. + +### 4 Responsive Typography + +Use **Montserrat** for all UI elements (navigation, buttons, labels). Use **Merriweather** exclusively for long-form biblical text and continuous reading contexts. + +### 5. Elevation Through Shadow + +Create depth with subtle shadows (`shadow-sm`, `shadow-md`), not heavy outlines or thick borders. Hover states should increase shadow intensity. + +### 6. Gentle Motion + +Animations are subtle and non-distracting. Default duration is 200ms. Prefer `transform` and `opacity` for smooth, GPU-accelerated transitions. + +--- + +## 🛠️ Using the Design System + +### In React Components + +```tsx +import { Button, Card, Badge, Input } from '@/components/ui' +import { cardStyles, participantCategoryColors } from '@/styles' +import { cn } from '@/utils/cn' + +export function ExampleComponent() { + return ( + + + + + Passage Details + + Genesis 1:1-3 + + +
+ + + Divine + +
+
+ + + + +
+ ) +} +``` + +### With Tailwind Classes + +```tsx +// Background and text colors +
+

Heading

+

Description

+
+ +// Spacing and layout +
+
+ ... +
+
+ +// Transitions and hover + +``` + +--- + +## 📱 Platform Differences + +### Web +- Border radius: 8-12px for cards, 8px for buttons +- Hover states: Use opacity and shadow changes +- Layouts: Wider, more breathable spacing + +### Mobile (Flutter) +- Border radius: 16px+ for generous rounded corners +- Touch targets: Minimum 44px height +- Elevation: Use Material elevation for depth +- Large touch areas for accessibility + +--- + +## 🔄 Governance and Authority + +### Hierarchy of Truth + +1. **Token files** (`/tokens/*.json`) are authoritative. If there's a conflict between code and tokens, tokens win. +2. **[AGENTS.md](./AGENTS.md)** defines brand values and core principles. +3. **Implementation docs** (this file and others) provide detailed usage patterns. + +### When to Update + +- **Tokens**: Only update with design team approval. +- **Implementation docs**: Update when patterns evolve or new use cases emerge. +- **Visual references**: Update when major visual changes occur. + +### Requesting Changes + +Document any exceptions or deviations. Propose token changes through design review process. Never introduce arbitrary colors or typography outside the defined system. + +--- + +## 📖 Additional Resources + +- **[AGENTS.md](./AGENTS.md)** - AI agent guidelines and brand authority +- **[README.md](./README.md)** - Visual references and conflict resolution +- **[figma-links.md](./figma-links.md)** - Links to Figma design files +- **[assets/references/](./assets/references/)** - Visual examples and screenshots + +--- + +## ✅ Checklist for Contributors + +Before creating or modifying UI: + +- [ ] Use colors from `colors.json` only +- [ ] Use Montserrat for UI, Merriweather for reading content +- [ ] Follow spacing scale (4px base) +- [ ] Use existing components from `/components/ui` +- [ ] Apply centralized styles from `/styles` +- [ ] Test hover and focus states +- [ ] Verify accessibility (contrast, keyboard navigation) +- [ ] Respect `prefers-reduced-motion` for animations +- [ ] Check responsive behavior (mobile, tablet, desktop) + +--- + +*This design system is maintained by the Shema design team. For questions or contributions, consult the governance section above.* diff --git a/frontend/design-system/README.md b/frontend/design-system/README.md new file mode 100644 index 0000000..c0e305c --- /dev/null +++ b/frontend/design-system/README.md @@ -0,0 +1,67 @@ +# Shema Design System + +This folder contains the complete visual ground truth for the Shema Design System. + +## Quick Navigation + +### 🎨 Start Here +- **[DESIGN.md](./DESIGN.md)** - Design system overview, quick start, and complete index +- **[AGENTS.md](./AGENTS.md)** - Brand authority, AI agent guidelines, and core principles + +### 🔧 Design Tokens (Authoritative) +- [colors.json](./tokens/colors.json) - Color palette and semantic tokens +- [typography.json](./tokens/typography.json) - Font families (Montserrat/Merriweather), scales, weights +- [spacing.json](./tokens/spacing.json) - Spacing scale and layout tokens +- [animations.json](./tokens/animations.json) - Keyframes and animation timings +- [borders.json](./tokens/borders.json) - Border widths and radius values +- [shadows.json](./tokens/shadows.json) - Shadow scales for elevation + +### 📚 Implementation Guides +- [colors.md](./colors.md) - Complete color system with usage examples +- [typography.md](./typography.md) - Typography hierarchy and font usage +- [spacing.md](./spacing.md) - Spacing scale and layout patterns +- [animations.md](./animations.md) - Motion design and transitions +- [components.md](./components.md) - UI component specifications +- [cards.md](./cards.md) - Card variants and patterns +- [badges.md](./badges.md) - Badge system and categories +- [states.md](./states.md) - Loading, error, success states +- [layout.md](./layout.md) - Grid systems and containers +- [border-radius.md](./border-radius.md) - Corner radius system +-[sections.md](./sections.md) - Section patterns +- [themes.md](./themes.md) - Light/dark theme specifications + +### 🎯 Visual References +- [assets/references/](./assets/references/) - Visual examples and screenshots +- [figma-links.md](./figma-links.md) - Links to Figma design files + +## Rules + +### Conflict Resolution +1. **Token files** override visual references +2. **AGENTS.md** defines brand authority and principles +3. **Implementation docs** provide detailed usage patterns +4. Images define visual intent, not pixel-perfect specs +5. Web and App references must not be mixed without justification + +### Making Changes +- Token files require design team approval +- Document all exceptions +- Never introduce arbitrary colors or typography +- Follow the governance guidelines in [AGENTS.md](./AGENTS.md) + +## Brand Essentials + +### Colors +- **Telha (#BE4A01)**: Exclusive to CTAs and primary actions +- **Shema White (#F6F5EB)**: Main background (not pure white) +- **Pure White (#FFFFFF)**: Elevated surfaces only (cards, inputs) + +### Typography +- **Montserrat**: All UI elements (buttons, navigation, labels) +- **Merriweather**: Long-form text and biblical content + +### Key Principles +- Natural feel (paper-like backgrounds) +- Soft contrast (Shema Black, not absolute black) +- Intentional color (Telha for actions only) +- Gentle motion (200ms default, subtle) diff --git a/frontend/design-system/animations.md b/frontend/design-system/animations.md new file mode 100644 index 0000000..b66596b --- /dev/null +++ b/frontend/design-system/animations.md @@ -0,0 +1,461 @@ +# Animations and Transitions — Shema Design System + +## Animation System + +The application uses smooth animations and consistent transitions to improve user experience. + +## Keyframes + +### Fade In + +Fade in animation with vertical movement. + +```css +@keyframes fade-in { + 0% { + opacity: 0; + transform: translateY(10px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} +``` + +#### Tailwind Configuration + +```javascript +keyframes: { + 'fade-in': { + '0%': { opacity: '0', transform: 'translateY(10px)' }, + '100%': { opacity: '1', transform: 'translateY(0)' }, + }, +} +``` + +#### Usage + +```tsx +
...
+``` + +### Slide In + +Slide in animation from the left. + +```css +@keyframes slide-in { + 0% { + opacity: 0; + transform: translateX(-10px); + } + 100% { + opacity: 1; + transform: translateX(0); + } +} +``` + +#### Tailwind Configuration + +```javascript +keyframes: { + 'slide-in': { + '0%': { opacity: '0', transform: 'translateX(-10px)' }, + '100%': { opacity: '1', transform: 'translateX(0)' }, + }, +} +``` + +#### Usage + +```tsx +
...
+``` + +### Pulse Soft + +Soft pulse animation. + +```css +@keyframes pulse-soft { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.7; + } +} +``` + +#### Tailwind Configuration + +```javascript +keyframes: { + 'pulse-soft': { + '0%, 100%': { opacity: '1' }, + '50%': { opacity: '0.7' }, + }, +} +``` + +#### Usage + +```tsx +
...
+``` + +### Bounce Subtle + +Subtle bounce animation. + +```css +@keyframes bounce-subtle { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-3px); + } +} +``` + +#### Tailwind Configuration + +```javascript +keyframes: { + 'bounce-subtle': { + '0%, 100%': { transform: 'translateY(0)' }, + '50%': { transform: 'translateY(-3px)' }, + }, +} +``` + +#### Usage + +```tsx +
...
+``` + +### Celebrate + +Celebration animation (scale). + +```css +@keyframes celebrate { + 0% { + transform: scale(1); + } + 50% { + transform: scale(1.1); + } + 100% { + transform: scale(1); + } +} +``` + +#### Tailwind Configuration + +```javascript +keyframes: { + 'celebrate': { + '0%': { transform: 'scale(1)' }, + '50%': { transform: 'scale(1.1)' }, + '100%': { transform: 'scale(1)' }, + }, +} +``` + +#### Usage + +```tsx +
...
+``` + +## Configured Animations + +### Fade In + +```javascript +animation: { + 'fade-in': 'fade-in 0.3s ease-out', +} +``` + +#### Usage + +```tsx +
...
+``` + +### Slide In + +```javascript +animation: { + 'slide-in': 'slide-in 0.3s ease-out', +} +``` + +#### Usage + +```tsx +
...
+``` + +### Pulse Soft + +```javascript +animation: { + 'pulse-soft': 'pulse-soft 2s ease-in-out infinite', +} +``` + +#### Usage + +```tsx +
...
+``` + +### Bounce Subtle + +```javascript +animation: { + 'bounce-subtle': 'bounce-subtle 0.5s ease-in-out', +} +``` + +#### Usage + +```tsx +
...
+``` + +### Celebrate + +```javascript +animation: { + 'celebrate': 'celebrate 0.4s ease-in-out', +} +``` + +#### Usage + +```tsx +
...
+``` + +## Transitions + +### Default Duration + +The application uses a default duration of **200ms** for most transitions. + +### Hover Transitions + +```tsx +// Card with hover +
+ ... +
+ +// Button with hover + +``` + +### State Transitions + +```tsx +// Element with color transition +
+ ... +
+ +// Element with scale transition + +``` + +### Opacity Transitions + +```tsx +// Element with fade +
+ ... +
+``` + +## Loading Animations + +### Spinner + +```tsx +
+``` + +### Small Spinner + +```tsx +
+``` + +### Spinner with Text + +```tsx +
+
+ Loading... +
+``` + +## Entrance Animations + +### Fade In in List + +```tsx +{items.map((item, index) => ( +
+ ... +
+))} +``` + +### Slide In in Modal + +```tsx + + + ... + + +``` + +## Interaction Animations + +### Button with Scale + +```tsx + +``` + +### Card with Hover + +```tsx + + ... + +``` + +### Badge with Pulse + +```tsx + + New + +``` + +## Validation Animations + +### Celebration on Validation + +```tsx +{isValidated && ( +
+ +
+)} +``` + +### Bounce on Completion + +```tsx +{isCompleted && ( +
+ +
+)} +``` + +## Custom CSS Classes + +### Animate In + +```css +.animate-in { + animation: fade-in 0.3s ease-out; +} +``` + +#### Usage + +```tsx +
...
+``` + +### Slide In Left + +```css +.slide-in-left { + animation: slide-in 0.3s ease-out; +} +``` + +#### Usage + +```tsx +
...
+``` + +## Performance + +### Optimizations + +- Use `transform` and `opacity` for animations (GPU-accelerated) +- Avoid animating `width`, `height`, `top`, `left` (causes reflow) +- Use `will-change` carefully (only when necessary) + +### Optimized Example + +```tsx +// ✅ Good - uses transform +
+ ... +
+ +// ❌ Avoid - animates width +
+ ... +
+``` + +## User Preferences + +### Reduce Motion + +Respect the user preference for reduced animations: + +```css +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} +``` + +## References + +- Tailwind configuration: `frontend/tailwind.config.js` +- CSS styles: `frontend/src/styles/main.css` + diff --git a/frontend/design-system/assets/references/app/components/buttons.md b/frontend/design-system/assets/references/app/components/buttons.md new file mode 100644 index 0000000..c04a0f0 --- /dev/null +++ b/frontend/design-system/assets/references/app/components/buttons.md @@ -0,0 +1,19 @@ +# Mobile Buttons (Flutter) + +## Primary Action +- Shape: Circular or Capsule +- Color: Telha +- Content: White +- Elevation: 4–6 + +## Input Fields +- Background: White +- Border Radius: 12px +- Border: + - Inactive: Sand + - Focused: Telha + +## List Item Button +- Clickable card +- Left icon +- Centered text diff --git a/frontend/design-system/assets/references/app/components/cards.md b/frontend/design-system/assets/references/app/components/cards.md new file mode 100644 index 0000000..3f21e62 --- /dev/null +++ b/frontend/design-system/assets/references/app/components/cards.md @@ -0,0 +1,12 @@ +# Mobile Cards + +## Project Card +- Surface: Branco +- Radius: 16–20px +- Elevation: 2 +- Centered circular avatar + +## List Item Card +- Horizontal layout +- Radius: 12px +- Border: Areia diff --git a/frontend/design-system/assets/references/app/components/themes/README.md b/frontend/design-system/assets/references/app/components/themes/README.md new file mode 100644 index 0000000..82f2730 --- /dev/null +++ b/frontend/design-system/assets/references/app/components/themes/README.md @@ -0,0 +1,3 @@ +These files are implementation examples for Flutter. +They are not the source of truth. +Tokens in /tokens override any discrepancy. diff --git a/frontend/design-system/assets/references/app/components/themes/night-and-earth.dart b/frontend/design-system/assets/references/app/components/themes/night-and-earth.dart new file mode 100644 index 0000000..4d21970 --- /dev/null +++ b/frontend/design-system/assets/references/app/components/themes/night-and-earth.dart @@ -0,0 +1,46 @@ +final shemaDarkTheme = ThemeData( + useMaterial3: true, + brightness: Brightness.dark, + fontFamily: 'Montserrat', + scaffoldBackgroundColor: colorShemaBlack, + + colorScheme: const ColorScheme.dark( + primary: colorShemaTile, + secondary: colorShemaBlue, + tertiary: colorShemaGreenLight, + surface: colorShemaBlack, + background: colorShemaBlack, + onPrimary: colorShemaCream, + onSurface: colorShemaCream, + onSurfaceVariant: colorShemaSand, + outline: colorShemaGreenDark, + ), + + appBarTheme: const AppBarTheme( + backgroundColor: colorShemaBlack, + foregroundColor: colorShemaCream, + elevation: 0, + ), + + cardTheme: CardTheme( + color: colorShemaBlack, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: const BorderSide( + color: colorShemaGreenDark, + width: 1.5, + ), + ), + ), + + inputDecorationTheme: InputDecorationTheme( + filled: true, + fillColor: colorShemaGreenDark.withOpacity(0.2), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide(color: colorShemaGreenDark), + ), + hintStyle: const TextStyle(color: colorShemaSand), + ), +); diff --git a/frontend/design-system/assets/references/app/components/themes/paper-and-ink.dart b/frontend/design-system/assets/references/app/components/themes/paper-and-ink.dart new file mode 100644 index 0000000..5fe3bf7 --- /dev/null +++ b/frontend/design-system/assets/references/app/components/themes/paper-and-ink.dart @@ -0,0 +1,33 @@ +final shemaLightTheme = ThemeData( + useMaterial3: true, + brightness: Brightness.light, + fontFamily: 'Montserrat', + scaffoldBackgroundColor: colorShemaCream, + + colorScheme: const ColorScheme.light( + primary: colorShemaTile, + secondary: colorShemaBlue, + tertiary: colorShemaGreenLight, + surface: colorWhite, + background: colorShemaCream, + onPrimary: colorShemaCream, + onSurface: colorShemaBlack, + outline: colorShemaSand, + ), + + appBarTheme: const AppBarTheme( + backgroundColor: colorShemaCream, + foregroundColor: colorShemaBlack, + elevation: 0, + ), + + cardTheme: CardTheme( + color: colorWhite, + elevation: 2, + shadowColor: colorShemaBlack.withOpacity(0.1), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + side: const BorderSide(color: colorShemaSand, width: 0.5), + ), + ), +); diff --git a/frontend/design-system/assets/references/icons.md b/frontend/design-system/assets/references/icons.md new file mode 100644 index 0000000..192965f --- /dev/null +++ b/frontend/design-system/assets/references/icons.md @@ -0,0 +1,14 @@ +# Iconography + +## Style +- Web: Outline (1.5px–2px stroke) +- App: Solid for active states / Outline for inactive states + +## Colors +- Primary: Telha +- Neutral: Dark Green or grey + +## References +- Player: Simple musical note +- Files: Minimal folder +- Navigation: Chevron \ No newline at end of file diff --git a/frontend/design-system/assets/references/platforms/mobile-flutter.md b/frontend/design-system/assets/references/platforms/mobile-flutter.md new file mode 100644 index 0000000..dac8623 --- /dev/null +++ b/frontend/design-system/assets/references/platforms/mobile-flutter.md @@ -0,0 +1,21 @@ +# Mobile Guidelines (Flutter) — Theming + +This document defines the official Light and Dark themes for the Shema mobile application, +derived strictly from the brand color system. + +Flutter automatically switches between `theme` and `darkTheme` +based on system preferences. + +--- + +## Base Palette (from tokens/colors.json) + +```dart +const colorShemaTile = Color(0xFFBE4A01); +const colorShemaBlue = Color(0xFF89AAA3); +const colorShemaGreenLight = Color(0xFF777D45); +const colorShemaGreenDark = Color(0xFF3F3E20); +const colorShemaSand = Color(0xFFC5C29F); +const colorShemaBlack = Color(0xFF0A0703); +const colorShemaCream = Color(0xFFF6F5EB); +const colorWhite = Color(0xFFFFFFFF); \ No newline at end of file diff --git a/frontend/design-system/assets/references/web/components/buttons.md b/frontend/design-system/assets/references/web/components/buttons.md new file mode 100644 index 0000000..ba58d0d --- /dev/null +++ b/frontend/design-system/assets/references/web/components/buttons.md @@ -0,0 +1,31 @@ +{ + "fontFamilies": { + "primary": "Montserrat", + "secondary": "Merriweather" + }, + "weights": { + "regular": 400, + "medium": 500, + "bold": 700 + }, + "web_scale": { + "h1": { "fontFamily": "Montserrat", "weight": 700, "size": "32px", "lineHeight": 1.2 }, + "h2": { "fontFamily": "Montserrat", "weight": 700, "size": "24px", "lineHeight": 1.3 }, + "h3": { "fontFamily": "Montserrat", "weight": 600, "size": "20px", "lineHeight": 1.4 }, + "body": { "fontFamily": "Montserrat", "weight": 400, "size": "16px", "lineHeight": 1.5 }, + "body_serif": { + "fontFamily": "Merriweather", + "weight": 400, + "size": "16px", + "lineHeight": 1.6, + "usage": "Reading contexts" + }, + "caption": { "fontFamily": "Montserrat", "weight": 500, "size": "12px", "lineHeight": 1.5 } + }, + "app_scale": { + "display": { "fontFamily": "Montserrat", "weight": 700, "size": "28px", "flutter_style": "headlineMedium" }, + "title": { "fontFamily": "Montserrat", "weight": 700, "size": "20px", "flutter_style": "titleLarge" }, + "body": { "fontFamily": "Montserrat", "weight": 400, "size": "16px", "flutter_style": "bodyMedium" }, + "label": { "fontFamily": "Montserrat", "weight": 500, "size": "14px", "flutter_style": "labelLarge" } + } +} diff --git a/frontend/design-system/assets/references/web/components/cards.md b/frontend/design-system/assets/references/web/components/cards.md new file mode 100644 index 0000000..c576e6d --- /dev/null +++ b/frontend/design-system/assets/references/web/components/cards.md @@ -0,0 +1,13 @@ +# Web Cards + +## Standard Card +- Surface: White (`#FFFFFF`) +- Page background: Cream (`#F6F5EB`) +- Shadow: `0 4px 12px rgba(10, 7, 3, 0.05)` +- Radius: 12px +- Clear content hierarchy + +## Progress Section +- Horizontal steps +- Active: Telha +- Inactive: Sand or light grey diff --git a/frontend/design-system/badges.md b/frontend/design-system/badges.md new file mode 100644 index 0000000..a4d5549 --- /dev/null +++ b/frontend/design-system/badges.md @@ -0,0 +1,363 @@ +# Badges — Shema Design System + +## Badge System + +The application uses badges to categorize and identify different types of elements, especially participants, events, and discourse relations. + +## Badge Base + +### Badge Component + +```tsx +import { Badge } from '@/components/ui/badge' + +Badge +``` + +### Base Styles + +```typescript +// frontend/src/components/ui/badge.tsx +Badge: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border transition-colors" +``` + +## Badge Variants + +### Default Variants + +```typescript +const variantClasses = { + default: 'bg-areia/30 text-preto border-areia', + success: 'bg-verde-claro/20 text-verde-claro border-verde-claro/30', + warning: 'bg-telha/10 text-telha border-telha/20', + secondary: 'bg-gray-100 text-gray-800 border-gray-200', + outline: 'bg-transparent border-gray-200 text-gray-800', +} +``` + +### Usage + +```tsx +Default +Success +Warning +Secondary +Outline +``` + +## Badges by Category + +### Participants + +Specific colors for different participant categories: + +```typescript +// frontend/src/styles/badges.ts +export const participantCategoryColors: Record = { + divine: 'bg-amber-100 text-amber-800 border-amber-200', + person: 'bg-telha/10 text-telha-dark border-telha/20', + place: 'bg-azul/20 text-verde border-azul/30', + time: 'bg-verde-claro/20 text-verde border-verde-claro/30', + object: 'bg-gray-100 text-gray-800 border-gray-200', + abstract: 'bg-areia/30 text-preto border-areia', + group: 'bg-indigo-100 text-indigo-800 border-indigo-200', + animal: 'bg-emerald-100 text-emerald-800 border-emerald-200', +} +``` + +#### Usage + +```tsx +import { participantCategoryColors } from '@/styles' + + + {participant.category} + +``` + +#### Badge Variants for Participants + +```tsx +Divine +Person +Place +Time +Object +Abstract +Group +``` + +### Events + +Colors for event categories: + +```typescript +export const eventCategoryColors: Record = { + ACTION: 'bg-telha/10 text-telha border-telha/20', + SPEECH: 'bg-azul/20 text-verde border-azul/30', + MOTION: 'bg-verde-claro/20 text-verde border-verde-claro/30', + STATE: 'bg-areia/30 text-verde border-areia', + PROCESS: 'bg-purple-100 text-purple-800 border-purple-200', + TRANSFER: 'bg-blue-100 text-blue-800 border-blue-200', + INTERNAL: 'bg-pink-100 text-pink-800 border-pink-200', + RITUAL: 'bg-amber-100 text-amber-800 border-amber-200', + META: 'bg-gray-100 text-gray-800 border-gray-200', +} +``` + +#### Usage + +```tsx +import { eventCategoryColors } from '@/styles' + + + {event.category} + +``` + +### Discourse + +Colors for discourse relations: + +```typescript +export const discourseCategoryColors: Record = { + temporal: 'bg-blue-100 text-blue-800', + logical: 'bg-purple-100 text-purple-800', + rhetorical: 'bg-orange-100 text-orange-800', + narrative: 'bg-emerald-100 text-emerald-800', +} +``` + +#### Usage + +```tsx +import { discourseCategoryColors } from '@/styles' + + + {relation.category} + +``` + +## Validation Badges + +### Validation States + +```typescript +export const validationBadgeStyles = { + validated: 'bg-verde-claro/20 text-verde-claro border-verde-claro/30', + pending: 'bg-areia/30 text-verde border-areia', + error: 'bg-red-100 text-red-800 border-red-200', +} +``` + +#### Usage + +```tsx +import { validationBadgeStyles } from '@/styles' + + + Validated + + + + Pending + + + + Error + +``` + +## Role Badges + +### Semantic Roles + +```typescript +export const roleBadgeStyles = { + agent: 'bg-amber-100 text-amber-800', + patient: 'bg-blue-100 text-blue-800', + experiencer: 'bg-purple-100 text-purple-800', + instrument: 'bg-gray-100 text-gray-800', + beneficiary: 'bg-green-100 text-green-800', + location: 'bg-cyan-100 text-cyan-800', + source: 'bg-orange-100 text-orange-800', + goal: 'bg-pink-100 text-pink-800', +} +``` + +#### Usage + +```tsx +import { roleBadgeStyles } from '@/styles' + + + Agent + +``` + +## Badges with Icons + +### Badge with Icon on Left + +```tsx + + + Validated + +``` + +### Badge with Icon on Right + +```tsx + + Pending + + +``` + +### Badge with Icon Only + +```tsx + + + +``` + +## Status Badges + +### Progress Status + +```tsx +Complete +In Progress +Pending +``` + +### Approval Status + +```tsx +{user.role === 'admin' && ( + + Admin + +)} +``` + +## Interactive Badges + +### Clickable Badge + +```tsx + +``` + +### Removable Badge + +```tsx + + {label} + + +``` + +## Badges in Lists + +### Badge List + +```tsx +
+ {categories.map(category => ( + + {category} + + ))} +
+``` + +### Badges in Grid + +```tsx +
+ {items.map(item => ( + + {item.label} + + ))} +
+``` + +## Custom Badges + +### Badge with Custom Background + +```tsx + + Custom + +``` + +### Badge with Custom Size + +```tsx + + Large Badge + +``` + +## Custom CSS Classes + +### Badge Classes in CSS + +```css +.badge { + @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium; +} + +.badge-divine { + @apply bg-amber-100 text-amber-800 border border-amber-200; +} + +.badge-place { + @apply bg-azul/20 text-verde border border-azul/30; +} + +.badge-time { + @apply bg-verde-claro/20 text-verde border border-verde-claro/30; +} + +.badge-person { + @apply bg-telha/10 text-telha-dark border border-telha/20; +} + +.badge-abstract { + @apply bg-areia/30 text-preto border border-areia; +} + +.badge-object { + @apply bg-gray-100 text-gray-800 border border-gray-200; +} +``` + +## References + +- Badge component: `frontend/src/components/ui/badge.tsx` +- Badge colors: `frontend/src/styles/badges.ts` +- CSS styles: `frontend/src/styles/main.css` + diff --git a/frontend/design-system/border-radius.md b/frontend/design-system/border-radius.md new file mode 100644 index 0000000..694ea2a --- /dev/null +++ b/frontend/design-system/border-radius.md @@ -0,0 +1,300 @@ +# Border Radius — Shema Design System + +## Border Radius System + +The application uses a consistent border radius system based on rounded values. + +## Default Values + +### Tailwind Configuration + +```javascript +borderRadius: { + sm: '0.25rem', // 4px + md: '0.5rem', // 8px + lg: '0.75rem', // 12px +} +``` + +### CSS Variable + +```css +:root { + --radius: 0.5rem; /* 8px - default value */ +} +``` + +## Border Radius Scale + +| Class | Value | Pixels | Usage | +|--------|-------|--------|-----| +| `rounded-none` | 0 | 0px | No rounding | +| `rounded-sm` | 0.25rem | 4px | Small rounding | +| `rounded` | 0.5rem | 8px | Default rounding | +| `rounded-md` | 0.5rem | 8px | Medium rounding (same as default) | +| `rounded-lg` | 0.75rem | 12px | Large rounding | +| `rounded-xl` | 1rem | 16px | Extra large rounding | +| `rounded-2xl` | 1.5rem | 24px | Very large rounding | +| `rounded-full` | 9999px | - | Full circle | + +## Usage by Component + +### Cards + +```tsx +// Default card +... + +// Stage card +
...
+ +// Clause card +
...
+ +// Event card +
...
+``` + +### Buttons + +```tsx +// Default button + + +// Small button + + +// Large button + +``` + +### Inputs + +```tsx +// Default input +... + +// Textarea + +``` + +### Badges + +```tsx +// Default badge (full circle) +... +``` + +### Modals and Dialogs + +```tsx +// Dialog +... + +// Sheet +... +``` + +## Specific Border Radius + +### Individual Corners + +```tsx +// Top left +
...
+ +// Top right +
...
+ +// Bottom left +
...
+ +// Bottom right +
...
+ +// Top (both) +
...
+ +// Bottom (both) +
...
+ +// Left (both) +
...
+ +// Right (both) +
...
+``` + +## Usage Patterns + +### Cards with Border Radius + +```tsx +// Default card + + ... + + +// Card with hover + + ... + +``` + +### Buttons with Border Radius + +```tsx +// Primary button + + +// Outline button + +``` + +### Inputs with Border Radius + +```tsx +// Default input + + +// Input with focus + +``` + +### Badges with Border Radius + +```tsx +// Default badge (always rounded-full) + + Badge + +``` + +## Border Radius in States + +### Selected Cards + +```tsx +
+ ... +
+``` + +### Cards with Hover + +```tsx +
+ ... +
+``` + +## Responsive Border Radius + +Although uncommon, responsive border radius can be used: + +```tsx +// Mobile: rounded-md, Desktop: rounded-lg +
...
+``` + +## Special Shapes + +### Circles + +```tsx +// Circular avatar +
+ ... +
+ +// Circular icon + +``` + +### Pills + +```tsx +// Pill-shaped badge + + Badge + + +// Pill-shaped button + +``` + +## Border Radius in Sections + +### Collapsible Sections + +```tsx +
+
+ Header +
+
+ Content +
+
+``` + +### Cards with Border Left + +```tsx +// Card with highlighted left border +
+ ... +
+ +// Mainline clause card +
+ ... +
+ +// Background clause card +
+ ... +
+``` + +## Visual Consistency + +### Border Radius Hierarchy + +1. **Small elements** (badges, tags): `rounded-full` +2. **Medium elements** (buttons, inputs): `rounded-lg` +3. **Large elements** (cards, modals): `rounded-xl` +4. **Very large elements** (containers): `rounded-2xl` + +### Hierarchy Examples + +```tsx +// Large container +
+ {/* Medium card */} + + {/* Small button */} + + {/* Badge */} + ... + +
+``` + +## References + +- Tailwind configuration: `frontend/tailwind.config.js` +- CSS variable: `frontend/src/styles/main.css` +- UI components: `frontend/src/components/ui/` + diff --git a/frontend/design-system/cards.md b/frontend/design-system/cards.md new file mode 100644 index 0000000..3bd16cf --- /dev/null +++ b/frontend/design-system/cards.md @@ -0,0 +1,436 @@ +# Cards — Shema Design System + +## Card System + +The application uses a consistent card system with different variants and styles. + +## Card Base + +### Card Component + +The base `Card` component provides the default structure: + +```tsx +import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card' + + + + Card Title + Card description + + + Card content + + + Card actions + + +``` + +### Base Styles + +```typescript +// frontend/src/components/ui/card.tsx +Card: "rounded-xl border border-areia/30 bg-white shadow-sm transition-all duration-200 hover:shadow-md" + +CardHeader: "flex flex-col space-y-1.5 p-6" +CardTitle: "text-xl font-semibold leading-none tracking-tight text-preto" +CardDescription: "text-sm text-verde" +CardContent: "p-6 pt-0" +CardFooter: "flex items-center p-6 pt-0" +``` + +### Border + +All cards **must** include a visible border for visual separation: + +```css +border: 1.5px solid var(--border-color); +``` + +> **Note:** This applies to every card variant (default, clause, event, participant, etc.). The `--border-color` CSS variable adapts automatically between light and dark themes. + +## Centralized Styles + +### Card Styles + +```typescript +// frontend/src/styles/cards.ts +export const cardStyles = { + base: 'bg-white rounded-lg border border-areia/30 shadow-sm', + hover: 'transition-all duration-200 hover:shadow-md hover:border-telha/30', + dashed: 'border-dashed', + selected: 'ring-2 ring-telha/50 border-telha', +} +``` + +### Usage + +```tsx +import { cardStyles } from '@/styles' +import { cn } from '@/utils/cn' + +
+ ... +
+``` + +## Card Variants + +### 1. Default Card + +```tsx + + + Title + Description + + + Content + + +``` + +### 2. Card with Hover + +```tsx +
+ ... +
+``` + +### 3. Selected Card + +```tsx +
+ ... +
+``` + +### 4. Card with Dashed Border + +```tsx +
+ ... +
+``` + +## Specific Cards + +### Stage Card + +Card used in application stages: + +```tsx +
+ {/* bg-white rounded-lg shadow-md border border-areia/30 p-6 */} + ... +
+``` + +### Clause Card + +Card for displaying clauses: + +```typescript +export const clauseCardStyles = { + base: 'bg-white rounded-lg border border-areia/30 p-4 transition-all duration-200 hover:shadow-md hover:border-telha/30', + mainline: 'border-l-4 border-l-telha', + background: 'border-l-4 border-l-azul', +} +``` + +#### Usage + +```tsx +import { clauseCardStyles } from '@/styles' + +// Default clause card +
+ ... +
+ +// Mainline clause card +
+ ... +
+ +// Background clause card +
+ ... +
+``` + +### Event Card + +Card for displaying events: + +```typescript +export const eventCardStyles = { + base: 'bg-white rounded-lg border border-areia/30 p-4', + validated: 'border-verde-claro/50 bg-verde-claro/5', + error: 'border-red-300 bg-red-50', +} +``` + +#### Usage + +```tsx +import { eventCardStyles } from '@/styles' + +// Default event card +
+ ... +
+ +// Validated event card +
+ ... +
+ +// Event card with error +
+ ... +
+``` + +### Participant Card + +Card for displaying participants: + +```typescript +export const participantCardStyles = { + base: 'bg-white rounded-lg border border-areia/30 p-4 transition-all duration-200', + validated: 'border-verde-claro/50 bg-verde-claro/5', + hover: 'hover:shadow-md hover:border-telha/30', +} +``` + +#### Usage + +```tsx +import { participantCardStyles } from '@/styles' + +// Default participant card +
+ ... +
+ +// Validated participant card +
+ ... +
+``` + +## Card States + +### Card with Loading + +```tsx + + +
+
+
+ + +``` + +### Card with Error + +```tsx + + +
+ Error loading +
+
+
+``` + +### Empty Card + +```tsx + + + +

No items found

+
+
+``` + +## Interactive Cards + +### Clickable Card + +```tsx + +``` + +### Expandable Card + +```tsx +const [isExpanded, setIsExpanded] = useState(false) + + + + + + {isExpanded && ( + + Expanded content + + )} + +``` + +## Cards in Grid + +### Card Grid + +```tsx +
+ {items.map(item => ( + + ... + + ))} +
+``` + +### 2-Column Grid + +```tsx +
+ ... + ... +
+``` + +### 4-Column Grid + +```tsx +
+ ... + ... + ... + ... +
+``` + +## Cards with Icons + +### Card with Icon in Title + +```tsx + + + + + Card Title + + + + ... + + +``` + +### Card with Status Icon + +```tsx + + +
+ Title +
+ {isValidated && ( + + )} +
+
+
+ ... +
+``` + +## Cards with Actions + +### Card with Buttons + +```tsx + + + Title + + + Content + + + + + + +``` + +### Card with Actions in Header + +```tsx + + +
+
+ Title + Description +
+ +
+
+ ... +
+``` + +## Responsive Cards + +### Adaptive Card + +```tsx + + + ... + + + ... + + +``` + +## References + +- Card component: `frontend/src/components/ui/card.tsx` +- Card styles: `frontend/src/styles/cards.ts` +- CSS styles: `frontend/src/styles/main.css` + diff --git a/frontend/design-system/colors.md b/frontend/design-system/colors.md new file mode 100644 index 0000000..f28f35b --- /dev/null +++ b/frontend/design-system/colors.md @@ -0,0 +1,247 @@ +# Color System — Shema Design System + +## Overview + +The Shema Design System uses an earthy color palette inspired by natural tones, reflecting the brand values: simple, accessible, lively, friendly, and human. + +## Base Palette + +The color system is defined in [tokens/colors.json](./tokens/colors.json), which is the authoritative source. + +| Name | Hex | Token | Usage | +|------|-----|-------|-----| +| **Telha (Clay/Tile)** | `#BE4A01` | `telha` | Primary color, CTAs, primary actions, active states | +| **Shema White (Cream)** | `#F6F5EB` | `branco` | Main background, simulates paper | +| **Sand** | `#C5C29F` | `areia` | Borders, secondary elements, muted | +| **Blue** | `#89AAA3` | `azul` | Supporting elements, subtle backgrounds | +| **Light Green** | `#777D45` | `verde-claro` | Success, validation, positive states | +| **Dark Green** | `#3F3E20` | `verde` | Secondary text, descriptions | +| **Shema Black** | `#0A0703` | `preto` | Primary text, foreground | +| **Pure White** | `#FFFFFF` | `white` | Elevated surfaces (cards, inputs) | + +> [!IMPORTANT] +> **Shema Brand Rule**: Never use pure white (#FFFFFF) as the main background. Use **Shema White / Cream (#F6F5EB)** to simulate paper and provide visual comfort. Pure white is reserved exclusively for elevated surfaces (cards, inputs). + +## Primary Colors + +### Telha (#BE4A01) + +**Exclusive to CTAs, primary actions, and active icons.** + +- **Never** use Telha as neutral decoration or background. +- Variations are created through opacity or state changes. +- Hover states use opacity, never new colors. + +### Shema White / Cream (#F6F5EB) + +**Main background color.** + +- Provides paper-like warmth and reduces eye strain. +- Pure white (#FFFFFF) is reserved for elevated surfaces (cards, inputs). + +### Shema Black (#0A0703) + +**Primary text color.** + +- Softer than absolute black, better for long reading sessions. +- Never use absolute black (#000000). + +### Shema Dark Green (#3F3E20) + +**Secondary text, subtitles, descriptions.** + +## Supporting Colors + +### Blue (#89AAA3) + +Supporting elements and subtle backgrounds. + +### Light Green (#777D45) + +Success states, positive indicators, validation. + +### Sand (#C5C29F) + +Borders, muted elements, warnings. + +## Semantic Tokens + +The system defines semantic tokens that map to base colors: + +```typescript +primary: { + DEFAULT: '#BE4A01', // telha + foreground: '#F6F5EB', // branco +} + +secondary: { + DEFAULT: '#89AAA3', // azul + foreground: '#0A0703', // preto +} + +success: { + DEFAULT: '#777D45', // verde-claro + foreground: '#F6F5EB', // branco +} + +background: '#F6F5EB' // branco (Shema Cream) +foreground: '#0A0703' // preto (Shema Black) + +card: { + DEFAULT: '#FFFFFF', // white + foreground: '#0A0703', // preto +} + +border: '#C5C29F' // areia +input: '#C5C29F' // areia +ring: '#BE4A01' // telha (focus rings) + +muted: { + DEFAULT: '#C5C29F', // areia + foreground: '#3F3E20', // verde +} + +accent: { + DEFAULT: '#89AAA3', // azul + foreground: '#0A0703', // preto +} + +destructive: { + DEFAULT: '#BE4A01', // telha (same as primary) + foreground: '#F6F5EB', // branco +} +``` + +## Opacity Patterns + +The system uses opacity to create subtle variations: + +- `/10` - Very subtle backgrounds (e.g., `bg-telha/10`) +- `/20` - Soft backgrounds for badges/highlights (e.g., `bg-verde-claro/20`) +- `/30` - Borders and subtle separators (e.g., `border-areia/30`) +- `/50` - Medium overlays +- `/90` - Strong hover states + +### Examples + +```tsx +// Soft background +
...
+ +// Border with opacity +
...
+ +// Hover with opacity + +``` + +## Category Colors + +### Participants + +Colors for different participant categories: + +```typescript +participantCategoryColors = { + divine: 'bg-amber-100 text-amber-800 border-amber-200', + person: 'bg-telha/10 text-telha-dark border-telha/20', + place: 'bg-azul/20 text-verde border-azul/30', + time: 'bg-verde-claro/20 text-verde border-verde-claro/30', + object: 'bg-gray-100 text-gray-800 border-gray-200', + abstract: 'bg-areia/30 text-preto border-areia', + group: 'bg-indigo-100 text-indigo-800 border-indigo-200', + animal: 'bg-emerald-100 text-emerald-800 border-emerald-200', +} +``` + +### Events + +Colors for event categories: + +```typescript +eventCategoryColors = { + ACTION: 'bg-telha/10 text-telha border-telha/20', + SPEECH: 'bg-azul/20 text-verde border-azul/30', + MOTION: 'bg-verde-claro/20 text-verde border-verde-claro/30', + STATE: 'bg-areia/30 text-verde border-areia', + PROCESS: 'bg-purple-100 text-purple-800 border-purple-200', + TRANSFER: 'bg-blue-100 text-blue-800 border-blue-200', + INTERNAL: 'bg-pink-100 text-pink-800 border-pink-200', + RITUAL: 'bg-amber-100 text-amber-800 border-amber-200', + META: 'bg-gray-100 text-gray-800 border-gray-200', +} +``` + +### Discourse + +Colors for discourse relations: + +```typescript +discourseCategoryColors = { + temporal: 'bg-blue-100 text-blue-800', + logical: 'bg-purple-100 text-purple-800', + rhetorical: 'bg-orange-100 text-orange-800', + narrative: 'bg-emerald-100 text-emerald-800', +} +``` + +## Validation States + +Colors for validation states: + +```typescript +validationBadgeStyles = { + validated: 'bg-verde-claro/20 text-verde-claro border-verde-claro/30', + pending: 'bg-areia/30 text-verde border-areia', + error: 'bg-red-100 text-red-800 border-red-200', +} +``` + +## Accessibility + +### Contrast + +All color combinations follow WCAG standards: + +- **Normal text**: Minimum contrast of 4.5:1 +- **Large text**: Minimum contrast of 3:1 +- **Interactive elements**: Minimum contrast of 3:1 + +### Contrast Examples + +- `preto` on `branco`: ✅ 21:1 (Excellent) +- `telha` on `branco`: ✅ 4.8:1 (Adequate) +- `verde` on `branco`: ✅ 8.2:1 (Excellent) +- `telha` on `areia`: ⚠️ 2.1:1 (Not adequate - avoid) + +## Usage in Code + +### Tailwind Classes + +```tsx +// Direct colors +
...
+
...
+ +// With opacity +
...
+ +// Semantic tokens +
...
+``` + +### TypeScript/JavaScript + +```typescript +import { participantCategoryColors } from '@/styles' + +const categoryColor = participantCategoryColors[participant.category] +``` + +## References + +- Design tokens: [tokens/colors.json](./tokens/colors.json) +- Brand guidelines: [AGENTS.md](./AGENTS.md) +- Tailwind config: `frontend/tailwind.config.js` +- Styles: `frontend/src/styles/main.css` +- Badge colors: `frontend/src/styles/badges.ts` diff --git a/frontend/design-system/components.md b/frontend/design-system/components.md new file mode 100644 index 0000000..ead1394 --- /dev/null +++ b/frontend/design-system/components.md @@ -0,0 +1,630 @@ +# UI Components — Shema Design System + +## Component System + +The application uses base components built with Radix UI, Tailwind CSS, and class-variance-authority (cva). + +## Component Structure + +All components follow this pattern: + +```tsx +import * as React from "react" +import { cn } from "@/utils/cn" +import { cva, type VariantProps } from "class-variance-authority" + +// Variants using cva +const componentVariants = cva( + "base-classes", + { + variants: { + variant: { ... }, + size: { ... }, + }, + defaultVariants: { ... } + } +) + +// Props interface +export interface ComponentProps + extends React.HTMLAttributes, + VariantProps { + // additional props +} + +// Component +const Component = React.forwardRef( + ({ className, variant, size, ...props }, ref) => { + return ( + + ) + } +) + +Component.displayName = "Component" + +export { Component, componentVariants } +``` + +## Progress Step + +Component for displaying step progress in a process or flow. Supports horizontal (desktop) and vertical (mobile) layouts. + +### States + +- **completed**: Completed step (light green with checkmark) +- **current**: Current step (telha with number and pulse animation) +- **pending**: Pending step (areia/30 with number) + +### Base Styles + +#### Progress Step Container + +```typescript +ProgressStepContainer: "bg-white rounded-xl border border-areia/30 shadow-sm p-6 md:p-8" +ProgressStepTitle: "text-xl font-semibold text-preto mb-6 flex items-center gap-2" +``` + +#### Step Circle (Step Icon) + +**Mobile (w-10 h-10):** +```typescript +// Completed +"w-10 h-10 rounded-full bg-verde-claro flex items-center justify-center text-white" + +// Current +"w-10 h-10 rounded-full bg-telha flex items-center justify-center text-white font-semibold animate-pulse" + +// Pending +"w-10 h-10 rounded-full bg-areia/30 flex items-center justify-center text-verde font-semibold" +``` + +**Desktop (w-12 h-12):** +```typescript +// Completed +"w-12 h-12 rounded-full bg-verde-claro flex items-center justify-center text-white mb-3" + +// Current +"w-12 h-12 rounded-full bg-telha flex items-center justify-center text-white font-semibold mb-3 animate-pulse" + +// Pending +"w-12 h-12 rounded-full bg-areia/30 flex items-center justify-center text-verde font-semibold mb-3" +``` + +#### Connectors (Lines between steps) + +**Mobile (vertical):** +```typescript +// Completed connector +"w-0.5 h-12 bg-verde-claro mt-2" + +// Pending connector +"w-0.5 h-12 bg-areia/50 mt-2" +``` + +**Desktop (horizontal):** +```typescript +// Completed connector +"flex-1 h-1 bg-verde-claro mx-2 -mt-8" + +// Pending connector +"flex-1 h-1 bg-areia/50 mx-2 -mt-8" +``` + +#### Step Texts + +**Mobile:** +```typescript +StepTitle: "font-semibold text-preto" +StepTitlePending: "font-semibold text-verde/60" +StepStatus: "text-sm text-verde mt-1" +StepStatusCurrent: "text-sm text-telha mt-1" +StepStatusPending: "text-sm text-verde/50 mt-1" +``` + +**Desktop:** +```typescript +StepTitle: "font-semibold text-preto text-center" +StepTitlePending: "font-semibold text-verde/60 text-center" +StepStatus: "text-sm text-verde mt-1 text-center" +StepStatusCurrent: "text-sm text-telha mt-1 text-center" +StepStatusPending: "text-sm text-verde/50 mt-1 text-center" +``` + +### Layout Mobile (Vertical) + +```tsx +
+ {steps.map((step, index) => ( +
+
+
+ {step.status === 'completed' ? ( + + ) : ( + {step.number} + )} +
+ {index < steps.length - 1 && ( +
+ )} +
+
+

+ {step.title} +

+

+ {step.statusText} +

+
+
+ ))} +
+``` + +### Layout Desktop (Horizontal) + +```tsx +
+ {steps.map((step, index) => ( + <> +
+
+ {step.status === 'completed' ? ( + + ) : ( + {step.number} + )} +
+

+ {step.title} +

+

+ {step.statusText} +

+
+ {index < steps.length - 1 && ( +
+ )} + + ))} +
+``` + +### Spacing + +- **Container padding**: `p-6 md:p-8` (24px mobile, 32px desktop) +- **Gap between steps (mobile)**: `space-y-4` (16px vertical) +- **Gap between step and content (mobile)**: `gap-4` (16px horizontal) +- **Title margin bottom**: `mb-6` (24px) +- **Status margin top**: `mt-1` (4px) +- **Content padding top (mobile)**: `pt-2` (8px) +- **Circle margin bottom (desktop)**: `mb-3` (12px) +- **Connector horizontal margin (desktop)**: `mx-2` (8px) +- **Connector negative top margin (desktop)**: `-mt-8` (-32px to align with circle) + +### Full Usage + +```tsx +
+

+ + Project Progress +

+ +
+ {/* Mobile Layout */} +
+ {/* Steps here */} +
+ + {/* Desktop Layout */} +
+ {/* Steps here */} +
+
+
+``` + +## Button + +### Variants + +```typescript +variant: { + default: "bg-telha text-white hover:bg-telha-dark shadow-md hover:shadow-lg", + secondary: "bg-azul text-white hover:bg-azul/90", + outline: "border-2 border-areia bg-transparent hover:bg-areia/20 text-preto", + ghost: "hover:bg-areia/20 text-preto", + success: "bg-verde-claro text-white hover:bg-verde", + destructive: "bg-red-500 text-white hover:bg-red-600", + link: "text-telha underline-offset-4 hover:underline", +} +``` + +### Sizes + +```typescript +size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-12 rounded-lg px-8 text-base", + icon: "h-10 w-10", +} +``` + +### Usage + +```tsx +import { Button } from '@/components/ui/button' + +// Default button + + +// Secondary button + + +// Outline button + + +// Ghost button + + +// Success button + + +// Destructive button + + +// Link button + + +// Sizes + + + + + +// With icon + +``` + +## Card + +### Structure + +```tsx +import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@/components/ui/card' + + + + Title + Description + + + Content + + + Footer + + +``` + +### Styles + +```typescript +Card: "rounded-xl border border-areia/30 bg-white shadow-sm transition-all duration-200 hover:shadow-md" +CardHeader: "flex flex-col space-y-1.5 p-6" +CardTitle: "text-xl font-semibold leading-none tracking-tight text-preto" +CardDescription: "text-sm text-verde" +CardContent: "p-6 pt-0" +CardFooter: "flex items-center p-6 pt-0" +``` + +### Usage + +```tsx + + + Card Title + Card description + + +

Card content

+
+ + + +
+``` + +## Input + +### Styles + +```typescript +Input: "flex h-10 w-full rounded-lg border border-areia bg-white px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-verde/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-telha focus-visible:ring-offset-2 focus-visible:border-telha disabled:cursor-not-allowed disabled:opacity-50 transition-all duration-200" +``` + +### Usage + +```tsx +import { Input } from '@/components/ui/input' + + + + + + + + +``` + +## Textarea + +### Styles + +Similar to Input, but with adjustable height. + +### Usage + +```tsx +import { Textarea } from '@/components/ui/textarea' + +