Files
Mlcavalho1andClaude Sonnet 4.6 acbce4edc0 feat: multi-usuário com autenticação JWT
- Tabela `profiles` + coluna `profile_id` em todas as entidades
  (categories, transactions, recurring_expenses, accounts, player_profile,
   xp_events, player_quests, player_achievements, player_cosmetics)
- Dados existentes migrados para profile_id = 1 (Manoel)
- CLI `./api create-user --name <n> --password <p>` cria perfil com
  seed de categorias e player_profile; faz upsert de senha se já existir
- Auth substituída: cookie+APP_PASSWORD → JWT Bearer 24h (HS256)
- Middleware RequireAuth injeta profile_id no context de todas as rotas
- Todos os repositórios filtram por profile_id do context
- Endpoints: POST /api/auth/login, GET /api/auth/me,
  POST /api/auth/change-password, POST /api/logout
- Frontend: auth store usa localStorage (fc_token/fc_profile),
  api.ts envia Authorization header, LoginView usa campo name
- SettingsView reescrita com troca de senha e logout
- docker-compose.yml: remove APP_USERNAME/APP_PASSWORD, adiciona JWT_SECRET

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-27 20:04:44 -03:00

641 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Financeiro Carvalho · Style Guide
**Direção:** Arcade Neon
**Stack alvo:** Vue 3 + Vite + TypeScript + Pinia
**Princípio:** finanças vestindo roupa de fliperama. Fundo escuro, glow neon nos números que importam, fonte pixel nos labels e mono nos dados. HUD sempre presente.
---
## 1. Tokens
Copie `tokens.css` na raiz do `src/styles/` e importe em `main.ts`. Todas as variáveis CSS abaixo são o contrato — componentes consomem `var(--fc-*)`, nunca hex direto.
### 1.1 Cores
| Token | Valor | Uso |
|---|---|---|
| `--fc-bg` | `#0a0418` | Fundo base do app |
| `--fc-bg-raised` | `#150827` | Card / panel topo do gradiente |
| `--fc-bg-panel` | `#1c0d33` | Card / panel base do gradiente |
| `--fc-panel-edge` | `#2d1857` | Borda padrão de painéis |
| `--fc-line` | `#3a1f6e` | Grid de fundo, dividers internos |
| `--fc-text` | `#f4eaff` | Texto principal (off-white lilás) |
| `--fc-text-dim` | `#8b75b8` | Texto secundário, labels |
| `--fc-accent` | `#ff2d95` | Magenta · destaques quentes, alertas suaves, "diária" |
| `--fc-accent-2` | `#00f0ff` | Ciano · links, navegação, "semanal" |
| `--fc-accent-3` | `#a855f7` | Roxo · CTA padrão, painéis com glow |
| `--fc-gold` | `#ffd84d` | XP, conquistas, "mensal" |
| `--fc-green` | `#39ff7a` | Meta atingida, valores positivos |
| `--fc-red` | `#ff3b6b` | Meta falhou, alerta crítico, recorrência ausente |
**Regra de uso:**
- **Magenta** é a cor do "agora" — botões primários secundários, status do dia.
- **Ciano** é a cor da informação fria — XP, links, navegação ativa.
- **Roxo** é estrutura — painel em destaque, hover, foco. Quase sempre tem `box-shadow: 0 0 24px rgba(168,85,247,.25)`.
- **Dourado** é recompensa — qualquer coisa relacionada a XP, nível, conquista.
- **Verde/vermelho** ficam reservados pro binário "meta sim/meta não".
### 1.2 Tipografia
Importe via Google Fonts no `<head>`:
```html
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=JetBrains+Mono:wght@400;500;700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
```
| Família | Uso | Tamanhos comuns |
|---|---|---|
| `Press Start 2P` | Labels, títulos de painel, números heroicos (47%), nav | 7px, 8px, 9px, 14px, 22px, 40px, 56px |
| `JetBrains Mono` | Valores numéricos (R$), datas, IDs | 10px, 11px, 12px, 16px |
| `Inter` | Fallback para corpo de texto longo (descrições de quest, etc.) | 13px, 14px |
Classes utilitárias:
```css
.fc-pixel { font-family: 'Press Start 2P', monospace; letter-spacing: .02em; }
.fc-mono { font-family: 'JetBrains Mono', monospace; }
.fc-body { font-family: 'Inter', system-ui, sans-serif; }
```
**Regra:** nunca usar Inter pra número. Nunca usar Press Start 2P pra parágrafo (>2 linhas). Press Start 2P em maiúscula sempre.
### 1.3 Tamanhos e espaçamento
| Token | Valor | Uso |
|---|---|---|
| `--fc-radius-sm` | `2px` | Botões, chips |
| `--fc-radius` | `4px` | Painéis |
| `--fc-space-1` | `4px` | Gap minúsculo |
| `--fc-space-2` | `8px` | Gap entre chips |
| `--fc-space-3` | `12px` | Padding interno de card pequeno |
| `--fc-space-4` | `16px` | Padding/gap padrão |
| `--fc-space-5` | `24px` | Padding de painel grande |
Página tem `padding: 24px` nas bordas. Grids usam `gap: 16px` entre cards.
### 1.4 Sombras e glow
Sombra padrão de painel:
```css
box-shadow:
inset 0 1px 0 rgba(255,255,255,.05),
0 0 0 1px rgba(0,0,0,.4),
0 8px 24px rgba(0,0,0,.4);
```
Painel com glow (destaque do hero):
```css
box-shadow:
inset 0 1px 0 rgba(255,255,255,.05),
0 0 0 1px var(--fc-accent-3),
0 0 24px rgba(168,85,247,.25),
0 8px 24px rgba(0,0,0,.5);
border-color: var(--fc-accent-3);
```
Glow em texto (números heroicos):
```css
text-shadow: 0 0 8px rgba(var-rgb, .53);
/* ex: text-shadow: 0 0 8px #39ff7a88; */
```
Glow em ícone/cor:
```css
box-shadow: 0 0 8px <cor>88;
```
Sempre que o app exibir um número grande de "vitória", ele recebe um glow do tom correspondente. Use com parcimônia — só nos pontos focais.
---
## 2. Layout
### 2.1 Estrutura geral
Toda tela do app tem essa estrutura vertical:
```
┌─────────────────────────────────────────┐
│ HUD (Top Bar) │ ← persistente, navegação + stats RPG
├─────────────────────────────────────────┤
│ Sub-header (título da rota + ações) │
├─────────────────────────────────────────┤
│ Conteúdo │ ← grid de painéis
│ │
└─────────────────────────────────────────┘
```
**HUD** é elemento de identidade — não dispensar em nenhuma rota.
### 2.2 Grid de painéis
Dashboard usa grid `1.6fr 1fr` (coluna principal mais larga que a lateral). Cards empilhados com `gap: 16px`.
Personagem usa grid `1fr 1.4fr` (personagem à esquerda, quests/conquistas à direita).
### 2.3 Fundo do app
O fundo tem 3 camadas (em ordem, do mais ao fundo):
1. Cor sólida `#0a0418`
2. Dois gradientes radiais sutis (roxo no topo, magenta no canto inferior direito)
3. Grid pontilhado fino (32×32px linhas, opacidade 12%) sobre tudo
4. Scanlines horizontais finas (CRT vibe) com opacidade 2,5%
CSS do body/root do app:
```css
.fc-app {
background:
radial-gradient(ellipse 80% 50% at 50% 0%, rgba(168,85,247,.18), transparent 70%),
radial-gradient(ellipse 60% 40% at 80% 100%, rgba(255,45,149,.12), transparent 60%),
var(--fc-bg);
position: relative;
min-height: 100vh;
}
.fc-app::before { /* scanlines */
content: '';
position: absolute; inset: 0;
background-image: repeating-linear-gradient(0deg, rgba(255,255,255,.025) 0 1px, transparent 1px 3px);
pointer-events: none;
z-index: 2;
}
.fc-app::after { /* grid */
content: '';
position: absolute; inset: 0;
background-image:
linear-gradient(var(--fc-line) 1px, transparent 1px),
linear-gradient(90deg, var(--fc-line) 1px, transparent 1px);
background-size: 32px 32px;
opacity: .12;
pointer-events: none;
}
.fc-app > * { position: relative; z-index: 1; }
```
---
## 3. Componentes
### 3.1 Panel
Wrapper para qualquer conteúdo. Tem cantos em "L" (corner brackets) opcionais — a estética HUD do Arcade Neon.
```vue
<!-- NeonPanel.vue -->
<template>
<div class="fc-panel" :class="{ 'fc-panel--glow': glow, [`fc-panel--${variant}`]: variant }">
<span v-if="corners" class="fc-corner fc-corner--tl" />
<span v-if="corners" class="fc-corner fc-corner--tr" />
<span v-if="corners" class="fc-corner fc-corner--bl" />
<span v-if="corners" class="fc-corner fc-corner--br" />
<slot />
</div>
</template>
<script setup lang="ts">
defineProps<{
glow?: boolean
corners?: boolean
variant?: 'danger' | 'success'
}>()
</script>
```
CSS:
```css
.fc-panel {
position: relative;
background: linear-gradient(180deg, var(--fc-bg-raised), var(--fc-bg-panel));
border: 2px solid var(--fc-panel-edge);
border-radius: var(--fc-radius);
padding: 16px;
box-shadow:
inset 0 1px 0 rgba(255,255,255,.05),
0 0 0 1px rgba(0,0,0,.4),
0 8px 24px rgba(0,0,0,.4);
}
.fc-panel--glow {
border-color: var(--fc-accent-3);
box-shadow:
inset 0 1px 0 rgba(255,255,255,.05),
0 0 0 1px var(--fc-accent-3),
0 0 24px rgba(168,85,247,.25),
0 8px 24px rgba(0,0,0,.5);
}
.fc-panel--danger { border-color: var(--fc-red); box-shadow: 0 0 0 1px var(--fc-red), 0 0 16px rgba(255,59,107,.3); }
.fc-corner {
position: absolute; width: 8px; height: 8px;
border: 2px solid var(--fc-accent-2);
}
.fc-corner--tl { top: -2px; left: -2px; border-right: none; border-bottom: none; }
.fc-corner--tr { top: -2px; right: -2px; border-left: none; border-bottom: none; }
.fc-corner--bl { bottom: -2px; left: -2px; border-right: none; border-top: none; }
.fc-corner--br { bottom: -2px; right: -2px; border-left: none; border-top: none; }
```
**Quando usar `corners`:** somente no painel principal de cada coluna ou no hero. Eles são "decoração de HUD", não devem aparecer em cada card.
**Quando usar `glow`:** apenas no painel de status mais importante da rota — o de meta de poupança no dashboard, o card do personagem na tela RPG.
### 3.2 Título de painel
Todo painel começa com um título no padrão `:: NOME`:
```html
<div class="fc-panel-title">:: GASTOS · CATEGORIA</div>
```
```css
.fc-panel-title {
font-family: 'Press Start 2P', monospace;
font-size: 9px;
color: var(--fc-accent-2);
margin-bottom: 14px;
letter-spacing: .04em;
}
```
O `::` prefix é assinatura visual da direção. Mantém.
### 3.3 Button
Botão padrão é "neon outline":
```css
.fc-btn {
font-family: 'Press Start 2P', monospace;
font-size: 9px;
padding: 9px 12px;
background: var(--fc-bg-raised);
border: 2px solid var(--fc-accent-3);
color: var(--fc-text);
cursor: pointer;
border-radius: 2px;
letter-spacing: .05em;
text-transform: uppercase;
transition: all .12s;
}
.fc-btn:hover {
background: var(--fc-accent-3);
color: white;
box-shadow: 0 0 16px rgba(168,85,247,.6);
}
.fc-btn--pink { border-color: var(--fc-accent); }
.fc-btn--pink:hover { background: var(--fc-accent); box-shadow: 0 0 16px rgba(255,45,149,.6); }
.fc-btn--cyan { border-color: var(--fc-accent-2); color: var(--fc-accent-2); }
.fc-btn--cyan:hover { background: var(--fc-accent-2); color: var(--fc-bg); box-shadow: 0 0 16px rgba(0,240,255,.6); }
```
Hierarquia:
- **Roxo** (padrão): ação primária genérica.
- **Magenta**: ação destrutiva ou de "agora" (registrar transação, atingir quest).
- **Ciano**: ação secundária, ver detalhes.
### 3.4 Chip
```css
.fc-chip {
display: inline-block;
font-family: 'Press Start 2P', monospace;
font-size: 7px;
padding: 4px 6px;
border-radius: 2px;
letter-spacing: .05em;
text-transform: uppercase;
}
```
Cores dependem do contexto:
- Quest "Diária" → `background: var(--fc-accent)`
- Quest "Semanal" → `background: var(--fc-accent-2)`
- Quest "Mensal" → `background: var(--fc-gold)`
- Categoria de transação → `color: var(--fc-text-dim)` apenas (sem fundo)
### 3.5 Bar (XP, progresso de quest, gauge)
```vue
<template>
<div class="fc-bar" :class="{ 'fc-bar--success': success }">
<div class="fc-bar__fill" :style="{ width: pct + '%' }" />
</div>
</template>
<script setup lang="ts">
defineProps<{ pct: number; success?: boolean }>()
</script>
```
```css
.fc-bar {
height: 14px;
background: var(--fc-bg);
border: 2px solid var(--fc-panel-edge);
position: relative;
overflow: hidden;
}
.fc-bar__fill {
height: 100%;
background: linear-gradient(90deg, var(--fc-accent-2), var(--fc-accent-3), var(--fc-accent));
position: relative;
}
.fc-bar__fill::after {
content:''; position: absolute; inset: 0;
background-image: repeating-linear-gradient(90deg, rgba(0,0,0,.2) 0 2px, transparent 2px 6px);
}
.fc-bar--success { border-color: var(--fc-green); }
.fc-bar--success .fc-bar__fill { background: linear-gradient(90deg, var(--fc-green), var(--fc-accent-2)); }
```
Tamanhos:
- XP geral (dashboard widget): 8px
- Quest mini: 6px
- Hero (poupado %): 14px
- Personagem (XP grande): 14px
### 3.6 HUD (top bar)
Persistente em todas as rotas. Contém: logo, separator, stats RPG (LV/XP/STREAK/META), nav.
Stats são essenciais — mesmo em telas que não são `/personagem`, o usuário tem que ver seu progresso o tempo todo. Esse é o ponto da direção.
```html
<header class="fc-hud">
<div class="fc-hud__logo">
<span class="fc-hud__logo-mark" />
<div>
<div class="fc-pixel" style="font-size: 10px; color: var(--fc-accent-2)">CARVALHO</div>
<div class="fc-pixel" style="font-size: 7px; color: var(--fc-text-dim)">FIN.SYS v1.4</div>
</div>
</div>
<div class="fc-hud__sep" />
<div class="fc-hud__stats">
<HUDStat label="LV" :value="user.level" color="var(--fc-gold)" />
<HUDStat label="XP" :value="user.xp" :sub="`/${user.xpNext}`" color="var(--fc-accent-2)" />
<HUDStat label="STREAK" :value="`${user.streak}d`" color="var(--fc-accent)" />
<HUDStat label="META" value="47%" sub="/40%" color="var(--fc-green)" />
</div>
<nav class="fc-hud__nav">
<!-- chip-shaped buttons, one per route -->
</nav>
</header>
```
```css
.fc-hud {
display: flex; align-items: center; gap: 16px;
padding: 12px 20px;
border-bottom: 2px solid var(--fc-panel-edge);
background: linear-gradient(180deg, var(--fc-bg-panel), var(--fc-bg));
position: relative; z-index: 3;
}
.fc-hud__logo-mark {
display: inline-block;
width: 28px; height: 28px;
background: var(--fc-accent);
box-shadow: 0 0 12px var(--fc-accent);
position: relative;
}
.fc-hud__logo-mark::before, .fc-hud__logo-mark::after { content: ''; position: absolute; }
.fc-hud__logo-mark::before { inset: 5px; background: var(--fc-bg); }
.fc-hud__logo-mark::after { top: 9px; left: 9px; width: 10px; height: 10px; background: var(--fc-accent-2); }
```
Nav items são chips com borda. Item ativo: fundo `--fc-accent-3` + glow.
### 3.7 Link (texto)
```css
.fc-link {
color: var(--fc-accent-2);
font-family: 'Press Start 2P', monospace;
font-size: 8px;
cursor: pointer;
text-decoration: none;
letter-spacing: .04em;
}
.fc-link:hover {
text-decoration: underline;
text-shadow: 0 0 8px var(--fc-accent-2);
}
```
Use sempre `VER+`, `ABRIR &gt;`, `REGISTRAR &gt;` — verbo curto + seta. Toda navegação textual usa esse padrão pra reforçar o "menu de jogo".
### 3.8 Alerta pulsante (recorrência ausente)
```css
@keyframes fc-blink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0.2; } }
.fc-blink { animation: fc-blink 1.2s steps(1) infinite; }
```
Use no triângulo ⚠ que precede o título do alerta. Pisca em vermelho.
---
## 4. Tabelas / listas
Padrão de tabela de transações:
```
[ data ][ descrição ......... ][ CATEGORIA ][ -R$ X,XX ]
mono10 mono11 ellipsis pixel7 dim mono11 right
```
- Linhas usam `border-bottom: 1px dashed var(--fc-panel-edge)` (a última, não).
- Padding vertical de 8px por linha.
- Valor positivo → cor `--fc-green`.
- Valor negativo → cor `--fc-text` (não vermelho — o vermelho é só pra alerta crítico).
---
## 5. Pixel Sprite (Character)
O personagem é desenhado a partir de uma grade 17×24 de células. Cores são parametrizáveis por slot de cosmético.
### 5.1 Slots de cor
| Slot | Token CSS sugerido | Cosmético que altera |
|---|---|---|
| `outline` | `--fc-sprite-outline` (`#10131c`) | nunca muda |
| `skin` | `--fc-sprite-skin` (`#f3c79b`) | nunca muda |
| `skinShade` | `--fc-sprite-skin-shade` (`#c98863`) | nunca muda |
| `hat` | `--fc-sprite-hat` | cosmético `hat` |
| `band` | `--fc-sprite-band` | faixa do chapéu |
| `shirt` | `--fc-sprite-shirt` | cosmético `shirt` |
| `shirtShade` | `--fc-sprite-shirt-shade` | shadow do shirt |
| `pants` | `--fc-sprite-pants` | cosmético `pants` |
| `pantsShade` | `--fc-sprite-pants-shade` | shadow do pants |
| `boots` | `--fc-sprite-boots` | cosmético `shoes` |
### 5.2 Render (Vue)
A grade vem do arquivo `sprites/sprite-data.json` (incluído). Componente:
```vue
<!-- CharacterSprite.vue -->
<template>
<svg :width="cols * scale" :height="rows * scale"
:viewBox="`0 0 ${cols * scale} ${rows * scale}`"
shape-rendering="crispEdges"
:class="['fc-sprite', { 'fc-sprite--bob': bob, 'fc-sprite--celebrate': celebrate }]">
<rect v-for="px in pixels" :key="`${px.x}-${px.y}`"
:x="px.x * scale" :y="px.y * scale" :width="scale" :height="scale"
:fill="colors[px.k]" />
</svg>
</template>
<script setup lang="ts">
import spriteData from '@/assets/sprite-data.json'
import { computed } from 'vue'
const props = withDefaults(defineProps<{
scale?: number
theme?: Partial<Record<string,string>>
bob?: boolean
celebrate?: boolean
}>(), { scale: 4, bob: true })
const rows = spriteData.rows
const cols = spriteData.cols
const defaults: Record<string,string> = {
L: '#10131c', s: '#f3c79b', S: '#c98863', e: '#10131c', m: '#80484b',
h: '#ffd84d', w: '#fde68a',
c: '#00f0ff', C: '#0369a1',
p: '#7c5a2e', P: '#4f3a1e',
b: '#0f172a',
}
const colors = computed(() => ({ ...defaults, ...(props.theme || {}) }))
const pixels = computed(() => {
const out: { x: number, y: number, k: string }[] = []
spriteData.grid.forEach((row: string, y: number) => {
for (let x = 0; x < row.length; x++) {
const k = row[x]
if (k === '.' || !colors.value[k]) continue
out.push({ x, y, k })
}
})
return out
})
</script>
<style scoped>
.fc-sprite { image-rendering: pixelated; line-height: 0; }
@keyframes fc-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
.fc-sprite--bob { animation: fc-bob 2.2s steps(2) infinite; }
@keyframes fc-celebrate { 0%,100% { transform: translateY(0) rotate(0); } 25% { transform: translateY(-6px) rotate(-3deg); } 75% { transform: translateY(-6px) rotate(3deg); } }
.fc-sprite--celebrate { animation: fc-celebrate 1s ease-in-out infinite; }
</style>
```
### 5.3 Tamanhos canônicos
- **Dashboard widget**: `scale={3}` → 51×72px no SVG
- **Mobile inline**: `scale={2}` → 34×48px
- **Personagem hero**: `scale={6}` → 102×144px
Sempre escalas inteiras. Nunca esticar.
### 5.4 Cosméticos (data)
A loja de cosméticos persiste no banco. Cada cosmético tem:
```ts
type Cosmetic = {
id: string
name: string
slot: 'hat' | 'shirt' | 'pants' | 'shoes' | 'cape'
unlockLv: number // nível necessário
colors: Partial<Record<'h'|'w'|'c'|'C'|'p'|'P'|'b', string>>
}
```
O store (Pinia) tem um getter `equippedTheme` que faz o merge das cores dos itens equipados. Esse objeto vai como prop `theme` para `<CharacterSprite>`.
---
## 6. Animações
| Trigger | Comportamento |
|---|---|
| Idle (sempre) | Sprite bobinha verticalmente (`fc-sprite--bob`, 2.2s steps(2) infinite) |
| Quest completa | Sprite vira `fc-sprite--celebrate` por 3s, depois volta |
| Level up | Modal sobrepõe a tela: painel com glow magenta, "+1 LEVEL", som opcional |
| XP ganho | Bar enche com transição `width 0.6s ease-out`. Numero do XP no HUD soma com tween 1s |
| Hover em card | `transform: translateY(-2px)` + shadow um pouco mais profundo |
| Alerta de recorrência | Triângulo ⚠ pisca (`fc-blink`) |
Sem motion gratuito. Cada animação tem um significado.
---
## 7. Iconografia
Esta direção evita ícones de biblioteca (Lucide, etc.). Em vez disso usa:
- **Símbolos unicode pequenos** pra categorias: `⌂` casa, `✚` saúde, `◉` mercado, `⚓` veleiro, `▦` board games, `↦` transporte, `•` outros.
- **Cantos em "L"** (`fc-corner-*`) pra emoldurar painéis especiais.
- **Triângulo `▲`** pra alerta, **estrela `✦` ou `★`** pra conquista, **diamante `◆`** pra equipado.
- **Setas** `` `` `>` pra navegação textual.
Quando precisar de um ícone novo: SVG inline pixel-art (8×8 ou 12×12), nunca importar ícone vetorial moderno.
Os pixels de `PixelHeart` e `PixelCoin` estão em `sprites/icons.json`.
---
## 8. Voz e copywriting
- Labels em maiúscula com Press Start 2P, curtas. `:: GASTOS · CATEGORIA`, `:: TRANSAÇÕES`, `:: PERSONAGEM`.
- Botões em maiúscula, verbo + (seta opcional). `REGISTRAR >`, `VER +`, `ABRIR >`, `IMPORTAR EXTRATO`.
- Mensagens de sucesso em tom de jogo: `QUEST OK`, `META BATIDA`, `+200 XP`.
- Mensagens de aviso em tom direto: `RECORRÊNCIA AUSENTE`, `QUEST FAIL`.
- Nome de seção da vida real ganha "stage": `:: STAGE 05 ::` antes do nome do mês na rota `/`.
Evite tom motivacional vazio ("você consegue!"). O jogo recompensa com XP, não com frase.
---
## 9. Responsivo
- Desktop ≥ 1024px: grid `1.6fr 1fr` (dashboard) ou `1fr 1.4fr` (personagem). HUD horizontal completo.
- Tablet 7681023px: grid colapsa pra 1 coluna. HUD ainda horizontal mas nav vira menu hambúrguer (preserve os stats).
- Mobile <768px:
- HUD compacta. Apenas LV + XP-bar visíveis + streak.
- Nav vira **bottom bar** fixa, 4 itens: HOME / TX / ADD (+) / PERS.
- Painéis empilham com `gap: 12px`, padding interno reduz pra 14px.
- Hero "47%" ocupa toda a largura, centralizado.
---
## 10. Arquivos deste pacote
```
neon-handoff/
├── STYLE_GUIDE.md ← este arquivo
├── tokens.css ← variáveis CSS prontas pra importar
├── preview.html ← referência visual interativa
├── components/
│ ├── NeonPanel.vue
│ ├── XPBar.vue
│ ├── HUDStat.vue
│ └── CharacterSprite.vue
├── sprites/
│ ├── sprite-data.json ← grade raw 17×24 (chave por cor)
│ ├── icons.json ← heart, coin, achievement
│ ├── manoel-default.png ← 1× (17×24px) e 4× (68×96px)
│ ├── manoel-default-4x.png
│ ├── manoel-lv01.png
│ ├── manoel-lv03-bone-verolme.png
│ ├── manoel-lv05-wingspan.png
│ ├── manoel-lv07-chapeu-sol.png
│ ├── manoel-lv10-anti-vento.png
│ ├── manoel-lv15-capitao.png
│ └── manoel-sheet-4x.png ← todos os 7 lado a lado, pra sprite-sheet
└── README.md
```