# Semog Design System (`@semog-tech/tahoe`)

> **Preocupe-se apenas em morar.**
> *(Worry only about living.)*

Semog is the largest condominium administrator in Brazil's Northeast — 35 years on the market, operating in **Pernambuco, Pará e Paraíba**. The brand presents itself as a sophisticated, technology-driven **hub of solutions** for both the building leadership (síndico, conselho) and individual residents (condôminos).

This repo publishes as **`@semog-tech/tahoe`** on GitHub Packages. It contains design tokens, font, kit primitives (admin / sindico / app / web) and the AI skills that teach Claude/Cursor how to use them.

## Install & consume

### 1. Configure the registry (once per machine)

Add to your app's `.npmrc` (in repo root):

```
@semog-tech:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_PACKAGES_TOKEN}
```

Then export the token. Use a **fine-grained PAT** with `read:packages` scope ([create one here](https://github.com/settings/tokens?type=beta)):

**Windows / PowerShell:**
```pwsh
setx GITHUB_PACKAGES_TOKEN "ghp_xxx"
# Close and reopen the terminal, then `pnpm install`.
```

**macOS / Linux:**
```bash
echo 'export GITHUB_PACKAGES_TOKEN=ghp_xxx' >> ~/.zshrc
source ~/.zshrc
```

**Fallback if `${VAR}` interpolation fails on your machine** (rare on Windows + pnpm < 8): write the token directly to your **user-level** `.npmrc` instead (`~/.npmrc` or `$env:USERPROFILE\.npmrc`), so it never gets committed:
```
@semog-tech:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=ghp_xxx
```

**CI (GitHub Actions):** use the built-in `${{ secrets.GITHUB_TOKEN }}` — no extra setup.

### 2. Install

```bash
pnpm add @semog-tech/tahoe
```

### 3. Import in your app entry

```ts
// main.tsx / _app.tsx / +layout.svelte
import '@semog-tech/tahoe/tokens'      // CSS variables only (no element styles)
import '@semog-tech/tahoe/admin'       // OR '@semog-tech/tahoe/sindico' — scoped to .tahoe-shell
```

**Important (v0.2.0+):** the admin/sindico kits are scoped under
`.tahoe-shell`. Wrap the page region you want Tahoe-styled in a
wrapper div:

```html
<body>
  <div class="tahoe-shell">          <!-- gradient wallpaper, flex centering -->
    <div class="window">...</div>    <!-- your Tahoe content -->
  </div>
</body>
```

Apps with mixed shadcn + Tahoe routes can wrap only the Tahoe routes —
shadcn routes outside `.tahoe-shell` stay untouched.

If you only want the design tokens (CSS vars) to use in shadcn
components, skip the kit import entirely:

```ts
import '@semog-tech/tahoe/tokens'   // just gives you var(--blue-600) etc.
```

Greenfield apps can also opt-in to element defaults (h1..h6, p, a):
```ts
import '@semog-tech/tahoe/tokens'
import '@semog-tech/tahoe/base'
```

For Tailwind apps (optional):

**Tailwind v4** (recomendado — usa `@theme` em CSS):
```css
/* src/index.css (ou app.css / global.css) */
@import "tailwindcss";
@import "@semog-tech/tahoe/tokens";
@import "@semog-tech/tahoe/tailwind";
```

**Tailwind v3** (legacy — usa preset JS):
```js
// tailwind.config.js
import semogTahoe from '@semog-tech/tahoe/tailwind/preset';
export default { presets: [semogTahoe], content: [...] };
```

### 4. Wire up AI skills (Cursor + Claude Code)

Add to your app's `package.json`:
```json
"scripts": {
  "postinstall": "node node_modules/@semog-tech/tahoe/scripts/install-skills.mjs"
}
```

And to `.gitignore`:
```
.cursor/rules/semog-*.md
docs/design-system/semog-*.md
```

This copies the relevant `SKILL.md` files into your repo so Cursor (which doesn't index `node_modules`) and Claude Code can both reference them. The script is idempotent — only writes when content changes.

In your `CLAUDE.md` (or `.cursor/rules/main.md`):
```md
# Design system: @semog-tech/tahoe

Antes de tocar UI, leia o SKILL relevante:
- Telas admin/backoffice → .cursor/rules/semog-admin.md
- Telas síndico → .cursor/rules/semog-sindico.md
- App mobile → .cursor/rules/semog-app.md
- Site marketing → .cursor/rules/semog-web.md

Tokens: node_modules/@semog-tech/tahoe/tokens/tokens.css
CSS por kit: node_modules/@semog-tech/tahoe/kits/{kit}/tahoe.css
```

## Token tiers

The `tokens.css` file ships **three tiers** of color tokens. Choosing the
right tier is the single most important decision when consuming the
design system — it determines whether your component survives a brand
update or breaks on it.

| Tier | Exemplos | Pergunta que responde | Uso em componente |
|------|----------|----------------------|-------------------|
| 1 — Primitives | `--blue-600`, `--sky-200`, `--gray-800` | "Qual shade numérica?" | ❌ Nunca direto |
| 2 — Brand aliases | `--semog-blue-world`, `--semog-brand-page`, `--semog-brand-mid` | "Qual cor brand específica?" | ⚠️ Só quando o papel é brand |
| 3 — Semantic surfaces | `--link`, `--bg`, `--fg-muted`, `--border` | "Qual papel funcional?" | ✅ Padrão |

> **Note on Tailwind utility names.** A tabela mostra o **nome de declaração CSS**.
> Tier 1 e Tier 3 mapeiam 1:1 pra utilities Tailwind (`--blue-600` → `bg-blue-600`,
> `--fg-muted` → `text-fg-muted`). **Tier 2 strips the `--semog-` prefix** quando
> exposto via Tailwind: `--semog-brand-page` vira `bg-brand-page`, `--semog-blue-world`
> vira `bg-blue-world`. No JSX, use a utility sem prefixo. O aliasing acontece em
> [`tailwind/theme.css`](tailwind/theme.css) (Tailwind v4 — `@theme inline` block) e
> [`tailwind/preset.js`](tailwind/preset.js) (Tailwind v3 preset).

### Choice rule

When picking a token, ask **"qual papel essa cor exerce?"** — não "qual cor exata?"

- **Default to Tier 3.** A link or accent button isn't "blue 600" — it's "the
  interactive emphasis color". Use `var(--link)` so a brand refresh of
  `--blue-600` flows through every link/accent surface automatically.
- **Drop to Tier 2** only when the role is *explicitly brand*: full-screen
  brand background (Login, BrandPanel), gradient hero, institutional
  surface. `bg-brand-page` says "this is the brand showing up", not
  "this is the dark background".
- **Never consume Tier 1 directly** in JSX or component CSS. They exist
  to back the higher tiers. Reaching for `bg-blue-700` in app code
  means there's a Tier 3 token missing — flag it and ask before
  hardcoding.

### Decision matrix — qual papel → qual tier?

When in doubt, use this lookup:

| Papel da cor | Tier | Token | Exemplo concreto |
|--------------|------|-------|------------------|
| Identidade institucional (página de marca, hero, splash) | T2 brand | `bg-brand-page`, `text-blue-world` | Login split panel, BrandPanel, marketing hero |
| Destaque interativo / link / ação secundária | T3 link | `text-link`, `bg-link/5` | Pill "Saiba mais", link de dado, note pill |
| Botão de ação principal | T2 brand (ou shadcn `bg-primary`) | `bg-blue-world` ou shadcn token | Botão "Nova assembleia" |
| Feedback de status (sucesso/atenção/erro/info) | T3 feedback | `pill-ok`, `text-danger`, `bg-warning-soft` | Banner de erro, pill "Atrasada", banner de sucesso |
| Background de superfície neutra | T3 surface | `bg-bg`, `bg-bg-soft` | Cards, panels, backgrounds default |
| Texto corpo | T3 content | `text-fg`, `text-fg-muted` | Parágrafo, label, hint |
| Borda neutra | T3 surface | `border-border`, `border-border-strong` | Inputs, dividers, separators |

Regra de unwind: se você está prestes a escrever `bg-blue-700` ou `text-emerald-600` direto no JSX (Tier 1 / palette Tailwind crua), **pare e pergunte qual token Tier 3 cobre esse papel.** Se nenhum cobre, é sinal de token faltando — abrir issue em vez de hardcodar.

### Sources of truth

Tiers 1 and 2 are **independent sources of truth**:

- **Tier 1** (`--blue-50..900`, `--sky-50..500`, `--gray-50..800`) was
  extrapolated for UI surfaces. Internal vocabulary.
- **Tier 2** (`--semog-blue-world`, etc.) comes from the **Manual de
  Marca** with Pantone references. External vocabulary.

If the brand updates `--semog-blue-world` to a new hex, Tier 2 changes
without Tier 1 moving. They are parallel, not derived. (Tier 3 currently
references Tier 1 internally — if a brand refresh moves both Tier 1 and
Tier 2 in lockstep, Tier 3 follows automatically. If they diverge, Tier 3
may need to be re-pointed.)

## Index

| File / folder                         | What's inside                                                            |
| ------------------------------------- | ------------------------------------------------------------------------ |
| `README.md`                           | You are here — brand context + content/visual/iconography fundamentals.  |
| `package.json`                        | npm package manifest (`@semog-tech/tahoe`) with subpath exports map.          |
| `tokens/tokens.css`                   | CSS variables only — colors, gradients, type scale, spacing, motion. No element styles. |
| `tokens/base.css`                     | Element defaults (h1..h6, p, a, body) — opt-in via `@semog-tech/tahoe/base`. |
| `fonts/`                              | Inter variable font (licensed).                                          |
| `kits/admin/`                         | Admin Tahoe — `tahoe.css` + `shell.html` + `SKILL.md`.                   |
| `kits/sindico/`                       | Síndico Tahoe — `tahoe.css` + `SKILL.md` (max-width 1320, .ws switcher). |
| `kits/app/`                           | Condômino mobile-app kit (Boleto, Login, Dashboard…) + `SKILL.md`.       |
| `kits/web/`                           | Marketing site kit (Hero, CTA, Footer…) + `SKILL.md`.                    |
| `tailwind/theme.css`                  | Tailwind v4 theme (`@theme inline`) — default for `@semog-tech/tahoe/tailwind`. |
| `tailwind/preset.js`                  | Tailwind v3 JS preset (legacy) — `@semog-tech/tahoe/tailwind/preset`.    |
| `scripts/install-skills.mjs`          | Idempotent copy of SKILL.md files into consuming app's Cursor/docs dirs. |
| `scripts/check-exports.mjs`           | Validates `package.json` exports point to existing files (CI gate).      |
| `.github/workflows/publish.yml`       | Publishes to GitHub Packages on `git tag v*` push.                       |
| `assets/`                             | Logos, gradient backgrounds, photographic references, mockups.           |
| `preview/`                            | Card-sized specimens shown in the Design System tab.                     |
| `Admin Shell Tahoe.html`              | Live dashboard preview (showcase only — not in published tarball).       |
| `Sindico Shell Tahoe.html`            | Live síndico preview (showcase only — not in published tarball).         |
| `SKILL.md`                            | Top-level brand skill (`semog-design`). Kit-specific skills live in `kits/{kit}/SKILL.md`. |

## When to split into multiple packages

Today this is **one package** for simplicity. Quebra em pacotes separados quando **qualquer** condição abaixo for verdade:

- **Bundle weight:** kit individual > 200KB minified (tipicamente quando entrar SVG complexo / framer-motion / vídeos como peer dep só de um kit).
- **Cadência divergente:** admin com release > 2×/semana enquanto outro kit fica > 1 mês parado por > 2 trimestres seguidos.
- **Peer deps incompatíveis:** ex.: `app` precisa React Native, `web` precisa Astro — não cabem no mesmo `package.json`.
- **Consumidor externo isolado:** parceiro/terceirizado que precisa só de um kit e não pode ver o resto (NDA, acoplamento mínimo).
- **≥ 3 apps em produção** consumindo só um kit, nunca os outros.

Quando virar real, migrar para monorepo com [changesets](https://github.com/changesets/changesets).

## Releasing

```bash
# 1. Bump version in package.json
# 2. Update CHANGELOG.md
# 3. Commit
git commit -am "Release v0.1.1"
# 4. Tag and push — GitHub Action publishes
git tag v0.1.1 && git push --tags
```

The workflow verifies tag matches `package.json` and runs `check-exports.mjs` before `npm publish`.

---

## Brand at a glance

| | |
|---|---|
| **Name**          | Semog |
| **Domain**        | semog.com.br (the live site does not yet follow this system) |
| **Tagline**       | Preocupe-se apenas em morar |
| **North-star quote** | *"A simplicidade é o último grau da sofisticação."* — Leonardo da Vinci |
| **Archetype**     | **O Governante** (The Ruler) — authoritative, orderly, custodial. |
| **Three pillars** | **Condomínios · Métricas · Organização** (Venn intersection = Semog). |
| **Values**        | Transparência · Retidão · Dinâmica |
| **Posture**       | Warm but unmistakably professional — we administer other people's money. |
| **Footprint**     | PE · PA · PB · Northeast Brazil market leader. |

## Source materials referenced

This system was built from the brand manual and surrounding assets the user provided. The originals live in `uploads/`:

- `Ativo 1.png` / `Ativo 1.svg` — primary lockup (III + SEMOG wordmark)
- `Ativo 2…16-100.jpg` — pages of the Semog *Manual de Marca* (covers, palette, type, layout grid, archetype card, da Vinci quote, three-pillars Venn, billboard, stationery, business cards, phone hero, social grid, etc.)
- `SCR-20260511-*.png/jpeg` — additional brand-manual pages, mockups (book, billboard, stationery, app login, tote bag, App Store listing, social grid).

Sources are not always publicly accessible to a reader; keep `uploads/` so they can be re-inspected.

---

## Content fundamentals

**Voice.** Calm, custodial, declarative. We speak as a steward who has been doing this for 35 years. Sentences are short and confident. We very rarely shout.

**Tone slider.** Warm 60 / Professional 40. We are friendly to residents but we never forget we are handling other people's money — that earns the right to sound *grown up*.

**Person.** Mostly **"você"** (warm-formal Brazilian Portuguese). Internal-facing copy uses **"nós"** ("Somos uma revolução inovativa…", "Acreditamos…").

**Casing.**
- Headlines often Sentence case ("Preocupe-se apenas em morar").
- Hashtag-style declarations get ALL CAPS, no spaces ("#TODOMUNDONOAZUL").
- Wordmark **SEMOG** is always uppercase, never abbreviated.

**Language.** Brazilian Portuguese is the canonical language. English is reserved for technical labels and internal docs. Never translate "Preocupe-se apenas em morar".

**Emoji.** Never. The brand uses none. If an icon-glyph is required, use the **III monogram** or a thin-stroke geometric icon.

**Sample copy — the bank.**

> *"Preocupe-se apenas em morar."*
> *"Somos uma revolução inovativa, acreditamos que um condomínio saudável é fruto da responsabilidade organizacional."*
> *"Controle, Organização & Respeito."*
> *"Serviço de moradia gerenciada."*
> *"Queremos todo mundo no azul."*
> *"#TODOMUNDONOAZUL — Só a maior administradora de condomínios pode fazer isso."*
> *"Em 12x no boleto."*
> *"Síndicos, nós temos um aplicativo para você."*
> *"Dedicados em resolver para você."*
> *"Peça uma proposta agora em nosso site."*
> *"Deixe seu condomínio no azul."*
> *"Condômino, sua opinião é valiosa."*

**Do**: lean on stillness ("Preocupe-se apenas em morar" is two short clauses, then silence).
**Don't**: stack adjectives, hype, exclamation marks, sales-pitch verbs.

---

## Visual foundations

### Colors

| Token | Hex | Pantone | CMYK | Role |
|---|---|---|---|---|
| **Blue World** (primary) | `#1B2D70` | 103-8 C | C100 M88 Y28 K13 | Hero surfaces, wordmark, headlines on light |
| **Gray Mist** (support) | `#BCBCC7` | 174-1 C | C30 M23 Y16 K1 | Neutral panels, "white space" alternatives, archetype slides |
| **Sky** (support) | `#ADD5EB` | P 116-2 C | C36 M6 Y5 K0 | Light flourishes, gradient highlights, accent surfaces |
| White | `#FFFFFF` | – | – | Primary canvas |

**Rule.** Blue World leads. The other two **support**. They never compete with Blue World for hierarchy — they soften, fade, or wash it.

### Gradients (signature element)

The brand **lives in gradients**. They are the visual fingerprint and appear on covers, phone screens, posters, social tiles and book spines.

Three gradient archetypes are codified, mirroring the three brand values:

1. **Transparência** — a vertical light-to-blue wash (White → Sky → Blue) used on supporting tiles. **Never inside the III monogram itself — the monogram is always solid Blue World.**
2. **Retidão** — flat, dense Blue World fill. Used when authority must dominate.
3. **Dinâmica** — large, organic radial blur of Blue / Sky / White — never repeats, looks like sky reflected on glass (`--grad-cover`).

When in doubt: **soft, foggy, light-from-the-corner**. Gradients are not decorative noise — they are the brand.

### Typography

| Family | Role | Weights |
|---|---|---|
| **Saira** | Titles, hero copy, the wordmark stack | 300 / 400 / 500 |
| **Inter** | Body, UI, captions, legal | 400 / 500 / 600 / 700 |

> **⚠️ Font substitution flag.** We do not have the original licensed `.ttf`/`.otf` files for Saira or Inter. The system loads both from **Google Fonts**, which is the closest open-source match (Saira is the same typeface family; Inter is widely used as the brand's UI text). If the marketing team has the licensed files, drop them in `fonts/` and replace the `@import` at the top of `colors_and_type.css`.

- Saira's slight rectangular geometry mirrors the III monogram — keep generous tracking on small caps.
- Inter handles every interface label, table, form, and dense paragraph.
- The wordmark itself ("SEMOG") is set in a custom **serif-toned** treatment in some applications (see `assets/semog-logo.svg`) — never re-set the wordmark in a system font.

### Spacing & layout

- 8-pt base grid. Multiples of `4 / 8 / 12 / 16 / 24 / 32 / 48 / 64 / 96`.
- Page layouts follow **Etapa 1 / 2 / 3** progression from the manual: two-column → three-column → twelve-column grid. Wider canvases get more columns; the rhythm stays.
- Outer page margin on print/poster output ≈ 1/12 of the long edge.
- Hero copy uses generous left-padding (eyebrow at column 2, headline at column 2, supporting paragraph indented slightly further).

### Corners, borders, shadows

- **Corner radii** intentionally restrained. Hard-edge rectangles (`0px`) for posters, slides and brand surfaces. UI uses **2–14 px** at most. Never large, never "soft tech bubble".
- Borders are **hairline** — 1 px in `--gray-200`, sometimes `--blue-600` at 1 px for accent.
- Shadows are quiet (`shadow-1` for cards, `shadow-3` for floating). The brand prefers **gradient-as-elevation** over drop shadows: a card might be a Blue World rectangle floating on a sky-gradient page.
- **Glassy outline frames** — see the website hero — use a 1-2 px white rounded-corner border over a gradient field, no inner fill.

### Motion

- **Tempo:** slow, steady, never bouncy. Defaults: `--dur-base: 220ms`, `--ease-out` (`cubic-bezier(0.22, 0.61, 0.36, 1)`).
- **Hover:** drop opacity to ~70 %. **Active:** drop to ~50 %. No scale bouncing.
- Background gradients can **slow-drift** (30-60s linear loop) — never spin or pulse.
- Transitions between sections fade or slide; never flip, never confetti.

### Imagery & photography

- Cool palette — navy, sky, white, gray. No warm casts.
- People photos: candid, natural light, modest crops, **business-casual**. The manual ships an example: a young woman in chambray reading docs.
- Architectural photos: blue-painted buildings, blue-stair textures, blue umbrella — the visual gag is **"Todo mundo no azul"**.
- Avoid stock that looks "tech-startup-y" (3D blobs, isometric people, gradient meshes).

### Transparency & blur

Gradients and soft frosted layers are everywhere. The brand's "glass" treatment is a 1 px white border on a Blue → White diagonal, no backdrop blur necessary — the gradient itself does the work.

### Hover / press / focus states

- **Hover:** `opacity: 0.7` (text & icons); on filled buttons darken by one step (`--blue-700`).
- **Press:** `opacity: 0.5` or background → `--blue-800`.
- **Focus-visible:** 2 px outline in `--sky-300` with 2 px offset. Never use the browser default.
- Disabled: `--gray-300` text on `--gray-100` surface, `cursor: not-allowed`.

### Cards

Two card archetypes:

1. **Document card** — White background, hairline `--border`, `radius-md`, `shadow-1`. For data tables, dashboard widgets.
2. **Brand card** — Filled with `--grad-cover` or `--grad-deep`, white text inside, **no border**, `radius-md` or `0`. For hero callouts, marketing tiles.

### Fixed elements

- Top navigation: 72 px tall on web, flush-translucent over hero gradients.
- Footer: dark `--blue-700` slab, white type, large logo, address columns.
- Mobile app: bottom tab bar 64 px, top header 56 px including safe-area inset.

---

## Iconography

Semog's icon vocabulary is **deliberately spartan**. The single most-used "icon" is the **III monogram itself** — it appears as a favicon, app icon, watermark, end-mark, and section divider.

**Rules**

1. **The III monogram comes first.** Whenever you need a generic "Semog mark", use the three vertical bars (see `assets/semog-logo.svg`, plus the favicon-mark file derived from it).
2. **Strokes thin, geometry rectilinear, corners square.** Matches the brand's hard-edge rectangular vocabulary.
3. **Outline-style line icons only.** No filled glyphs in product UI; filled icons read too "consumer-app" for an administrator brand.

**Substitution flag.** The supplied material does not ship a custom icon set. For UI work we substitute **[Lucide](https://lucide.dev)** (loaded via CDN — `https://unpkg.com/lucide-static`). Lucide's 1.5-2 px strokes and rectilinear caps match Semog's spirit. If/when a bespoke set is delivered, drop the SVGs in `assets/icons/` and swap the import.

**Emoji.** Never used.
**Unicode glyphs as icons.** Never. Use Lucide or the III mark.
**Photographic icons.** Never — keep icons purely linework.

---

## Quick-start (HTML preview, no bundler)

```html
<link rel="stylesheet" href="tokens/tokens.css">

<header class="semog-hero">
  <span class="eyebrow">Garante</span>
  <h1>Preocupe-se<br>apenas em morar</h1>
  <p class="lead">Somos uma revolução inovativa…</p>
</header>
```

See `kits/web/index.html`, `kits/app/index.html` and `kits/admin/shell.html` for live, click-thru examples. Full dashboards live at `Admin Shell Tahoe.html` and `Sindico Shell Tahoe.html` (raiz, showcase only).

In an app with a bundler, **don't** use the relative paths above — use the imports from the [Install & consume](#install--consume) section instead.

---

## Roadmap

Open considerations not scheduled yet. Each item is a thought worth
revisiting at a specific moment, not a queued task.

- **Monitor `--link` overload across consumer apps.** The 0.3.0
  release split off `--info` (informational accents) from what was then
  called `--accent`. The 0.4.0 release renamed the remainder to `--link`
  to avoid cascade collision with shadcn's `--accent`. With the role now
  cleaner ("interactive emphasis: links, CTA secundário"), monitor in
  Fase 2 + future apps whether `--link` itself needs further splitting
  (e.g., `--link` for hyperlinks vs `--cta-secondary` for buttons). No
  action until ≥ 2 consumer apps report friction.
