From bafc7953554a57015387e878a83b8e79031c6f9b Mon Sep 17 00:00:00 2001
From: Alberto Andre
Date: Tue, 16 Jun 2026 21:51:53 -0300
Subject: [PATCH 01/25] feat(ui): adopt Seven design system in frontend (phases
1-3)
Foundation: reconcile index.css so @etus/tokens wins (drop colliding
radius/shadow/breakpoint/text tokens, the 88 color palettes, and the
decorative utilities banned by DESIGN.md); load Inter + JetBrains Mono.
Shell: sidebar.tsx becomes AppSidebar built on Seven's Sidebar system
(single mode, collapsible icon, SidebarAvatar); _authenticated.tsx mounts
SidebarProvider + SidebarInset.
Screens: settings/account/team/integrations move to TextInput, Divider,
Switch and Checkbox; main.tsx uses Seven's Toaster; error-boundary uses
Button; loading-skeleton uses SkeletonLoader. The local input, separator,
skeleton and sonner components now have zero consumers.
Validated in the browser. Plan:
docs/plans/2026-06-16-001-migrate-frontend-seven-ds-plan.md
---
...6-16-001-migrate-frontend-seven-ds-plan.md | 314 +++++++++++++++
index.html | 2 +-
src/client/components/error-boundary.tsx | 7 +-
src/client/components/sidebar.tsx | 381 +++++++-----------
src/client/components/ui/loading-skeleton.tsx | 3 +-
src/client/index.css | 291 ++-----------
src/client/main.tsx | 12 +-
src/client/routes/_authenticated.tsx | 92 +++--
src/client/routes/_authenticated/account.tsx | 14 +-
.../routes/_authenticated/integrations.tsx | 30 +-
src/client/routes/_authenticated/settings.tsx | 37 +-
src/client/routes/_authenticated/team.tsx | 6 +-
12 files changed, 590 insertions(+), 599 deletions(-)
create mode 100644 docs/plans/2026-06-16-001-migrate-frontend-seven-ds-plan.md
diff --git a/docs/plans/2026-06-16-001-migrate-frontend-seven-ds-plan.md b/docs/plans/2026-06-16-001-migrate-frontend-seven-ds-plan.md
new file mode 100644
index 0000000..b877030
--- /dev/null
+++ b/docs/plans/2026-06-16-001-migrate-frontend-seven-ds-plan.md
@@ -0,0 +1,314 @@
+---
+title: Implementation Plan — Adotar o Seven (DS) em todo o frontend
+type: migration
+date: 2026-06-16
+status: ready-for-execution — D1–D5 decididos; fases reescritas p/ rewrite guiado por blocks (runtime @etus/seven-react). Pendência: confirmar Geist→JetBrains (D3)
+package_target: "@etus/seven-react@^0.1.0-beta.3 (→ @etus/ui@0.4.0-beta.2 + @etus/tokens@0.4.0-beta.2)"
+scope: src/client/** + src/client/index.css
+---
+
+# Implementation Plan — Adotar o Seven em todo o frontend
+
+Plano tático para fazer o **Seven** (`@etus/seven-react`, umbrella sobre `@etus/ui` + `@etus/tokens`)
+ser a fonte única de todo elemento de UI do `boilerplate-hono`, de modo que o boilerplate sirva
+de base de Design System para os produtos derivados.
+
+## Estado atual (diagnóstico 2026-06-16)
+
+A migração **já começou e está parcial** (≈60% das telas). O que já está correto:
+
+- Pacotes instalados e ligados; `index.css` faz `@import "@etus/seven-react/styles.css"` + `@source` (linha 5/11).
+- Cores semânticas **já neutralizadas** do `@theme` local — o Seven vence em light e dark.
+- Dark mode compatível: `use-theme.tsx` aplica `.dark` no ``, igual à estratégia do `@etus/tokens` (`.dark`, sem `prefers-color-scheme`).
+- Telas já no Seven: `Button`, `Card`, `Avatar`, `Dialog`, `Form`, `Tabs`, `Badge`, `Label` em ~13 rotas + `sidebar`/`error-fallback`/`loading-skeleton`.
+
+**Achado central (o gap mais grave, invisível):** o bloco `@theme` local (`src/client/index.css:17+`)
+roda **depois** do `@import` do Seven e, no Tailwind v4, *last wins* — então tokens locais de
+`radius`/`shadow`/`breakpoint`/tipografia **sobrescrevem os do Seven com valores diferentes**, e os
+componentes do Seven renderizam fora do tom. Esta é a "Etapa 2" que os próprios comentários do arquivo
+prometem mas não executaram.
+
+## Objetivo
+
+Todo elemento de UI vem do `@etus/seven-react`; os tokens do `@etus/tokens` são a fonte da verdade
+(o `@theme` local só guarda o que o Seven comprovadamente não fornece); nenhum HTML cru de controle e
+nenhum componente caseiro de UI sobrevive; e há guard-rails que impedem regressão nos produtos derivados.
+
+## Referências canônicas do Seven (repo `~/Dropbox/aa-projects/Github/seven`)
+
+A composição idiomática NÃO será inventada — será ancorada no repo do Seven:
+- **`DESIGN.md`** — espec de marca (regras de ouro abaixo). Fonte de verdade #3 (após Figma e `tokens.css`).
+- **Showcase `apps/showcase`** (código) — composição canônica. O **shell** vive em `src/routes/__root.tsx` (`SidebarProvider mode="dual"` → Rail 64px + Panel 216px + `SidebarInset` + content `rounded-tl-[24px] border`).
+- **`seven.etus.io`** — o showcase **publicado e renderizado**: referência de **validação visual real**. Toda comparação de UI com o Seven compara screenshots do app contra o showcase publicado (não só código/`.d.ts`/tokens).
+- **209 blocks** em `apps/showcase/src/data/blocks/` (29 categorias) — **copiáveis como ponto de partida** (não distribuídos via CLI). Relevantes: `page-shells` (3), `logins`, `account-and-user-management` (15), `form-layouts` (5), `tables`/`data-table`, `empty-states`, `dialogs`, `dashboard`.
+- **CLI registry** — `npx @etus/seven add ` copia 185 componentes como **source local com token-slicing** (resolve o megabundle de 1.4MB — ver D5).
+- **Skill `seven-design-system`** + pacote `@etus/seven-skill` (plugin Claude Code + `npx seven detect`, 35 regras) — guard-rails automáticos; vale instalar.
+
+### Regras de ouro (DESIGN.md) — guard-rails inegociáveis
+- **Tipografia:** Inter (400/500/600/700, evitar 800/900); **JetBrains Mono** p/ código; **nunca Geist/Space Grotesk**. Sentence case pt-BR; sem ponto final em botões/labels.
+- **Cor:** só **mint** (`--primary #19e699`) + **lime** (`--secondary`) são marca; **fuchsia só em charts**; neutros = cinza puro; status semânticos. Nunca inventar cor, nunca indigo/"AI purple", nunca `#000`/`#fff` puros.
+- **Forma:** dois stacks de radius **não intercambiáveis** — componente (4/8/12 = inputs/botões) vs superfície (16/20/24/32 = cards/dialogs); **pills só** em badges/tags, nunca botões.
+- **Elevação/Motion:** bordas 1px p/ hierarquia, sombras só p/ overlays; micro-press tátil (`translate-y` + inset shadow) em todo clicável; 200ms `--ease-default`, sem bounce/spring.
+- **Tailwind v4:** type hints obrigatórios — `bg-[color:var(--token)]`, `text-[length:var(--token)]`, dimensões sem prefixo; **nunca** `bg-[var(...)]` nem `hsl(var(...))` (Lightning CSS dropa em silêncio).
+- **Ícones:** Lucide, stroke 2px, `currentColor`; sem emoji no chrome.
+
+## Estratégia de branch
+
+- Branch nova a partir de `master` (ex.: `feat/frontend-seven-ds`).
+- Migração incremental por fase — `pnpm build` + `pnpm typecheck:client` verdes ao fim de cada fase.
+- Cada fase de UI é verificável por screenshot/E2E `@visual` antes de seguir.
+
+## Definition of Ready (DoR)
+
+- [x] Diagnóstico do estado atual concluído (este doc)
+- [x] Catálogo do Seven mapeado e **verificado em runtime** (não só `.d.ts`): `TextInput`, `Divider`, `SkeletonLoader`, `Switch`, `Checkbox`, `Toaster` existem em `@etus/ui@0.4.0-beta.2` (1215 exports)
+- [x] Spikes técnicos da Fase 0 (D2 tokens, D4 toast) resolvidos
+- [x] Decisões do usuário: D1 = reescrever efeitos/remover paletas; D3 = Inter variable + Geist Mono + remover serif
+- [ ] Branch nova criada a partir de `master`
+
+---
+
+## Fase 0 — Decisões + de-risking (GATE)
+
+Spikes técnicos resolvidos nesta sessão (D2, D4 ✅). Restam **2 decisões do usuário** (D1, D3).
+
+### D1 — Paletas de cor locais (DECISÃO DO USUÁRIO) — dado corrigido
+As paletas `--color-{green,blue,gray,red,yellow,pink,main1,main2}-*` (88 tokens, `index.css:43–145`)
+**não colidem por nome** com o Seven (que usa `--brand-*` + semânticas). Uso real medido:
+- **0** ocorrências como classe utilitária (`bg-green-500` etc.) em `src/client`.
+- **Mas NÃO são órfãs:** são consumidas via `var(--color-…)` por ~10 utilitários visuais do próprio `index.css`
+ (`.gradient-{primary,accent,warm}`, `.glow-*`, spinner/rainbow, `.skeleton` shimmer — linhas ~514–721).
+- **Decidir:** (a) **remapear** os valores das paletas para as primitivas do Seven (mantém os efeitos, alinha a marca);
+ (b) reescrever os efeitos usando `--brand-*`/semânticas e remover as paletas; (c) manter como estão (dois sistemas).
+- **✅ DECISÃO (2026-06-16): opção (b)** — reescrever os ~10 efeitos (`.gradient-*`, `.glow-*`, spinner/rainbow, `.skeleton`) com tokens `--brand-*`/semânticos do Seven e **remover as 88 paletas locais**. Vocabulário único de cor (boilerplate-base limpo). ⚠️ Nem todo gradiente terá equivalente de marca exato — escolher o token Seven mais próximo por efeito e conferir visual.
+- **Verde:** paletas removidas; nenhum `var(--color-{green,blue,…})` sobra; efeitos conferidos.
+
+### D2 — Set de tokens a remover/manter ✅ RESOLVIDO
+Valores reais do Seven (lidos de `@etus/tokens/dist/tokens.css`):
+- **radius:** none 0 · xs **2** · sm **4** · md **8** · lg **12** · xl **16** · 2xl **20** · 3xl 24 · 4xl 32 · pill 999 · full 9999 (px).
+ Local diverge em toda a escala (xs 1 · sm 2 · md 4 · lg 8 · xl 12 · 2xl 14) → **remover locais**.
+- **shadow:** Seven fornece xs–xl (com variante dark) → **remover** locais xs–xl; **manter** `--shadow-2xl` e `--shadow-inner` (Seven não tem).
+- **breakpoint:** Seven xs 320 · sm **360** · md 768 · lg 1024 · xl 1280 · 2xl **1440** · 3xl 1920 · 4xl 2560.
+ Local diverge em **sm (640)** e **2xl (1536)**; md/lg/xl batem → **remover locais** (⚠️ ver R1).
+- **`--text-*`:** Seven **define** (2xs…9xl) → **remover** local `--text-xs…5xl`.
+- **`--font-{thin…extrabold}`:** o Tailwind v4 lê `--font-weight-*` (Seven fornece 100–900); os `--font-*` locais são redundantes → **remover** (checar refs `var(--font-bold)`).
+- **`--leading-*`:** Seven usa namespace próprio `--font-leading-*` (não toca `--leading-*`) → **manter** local.
+
+### D3 — Fontes ⚠️ CORRIGIDO pelo DESIGN.md do Seven
+O `DESIGN.md` canônico contradiz parte do que foi decidido antes (decisão original feita sem acesso a ele):
+- **Sans = Inter, pesos 400/500/600/700 apenas** ("avoid 800/900"). App já está assim ✓ → **NÃO** carregar variable 100–900 (revertido).
+- **Mono = JetBrains Mono** (oficial). **Geist é PROIBIDO** ("never Geist"). → trocar `--font-mono` de Geist Mono p/ **JetBrains Mono** (Google Fonts). ⚠️ revoga a escolha "Geist Mono" — **confirmar com o usuário**.
+- **Sem Space Grotesk** (DESIGN.md: legacy Figma que não shipou; os tokens `--typography-display-*` são legado). Display usa Inter.
+- **Sem serif na marca** (o Instrument Serif do showcase é o tema próprio dele, não o DS). `--font-serif` órfão → **remover**.
+- **Verde:** Inter 400–700 + JetBrains Mono carregadas; sem Geist/Space Grotesk/serif.
+
+### D4 — Toast ✅ RESOLVIDO
+`@etus/ui` exporta `Toaster` (tipado sobre `sonner`) e depende de `sonner@^2.0.7` (mesma versão do app), mas **não reexporta a função `toast`**.
+- **Padrão:** usar `` de `@etus/seven-react` (com `theme={resolvedTheme}` p/ dark) e manter `import { toast } from 'sonner'` nas 4 chamadas. Deletar `components/ui/sonner.tsx`.
+
+### D5 — Arquitetura de consumo (NOVA — DECISÃO DO USUÁRIO)
+Como o boilerplate consome os componentes do Seven?
+- **(a) Runtime `@etus/seven-react`** (atual) — 1 import, atualiza via `pnpm up`, mas **megabundle ~1.4MB** + CSS ~664KB (R4); rota pública carrega tudo (mitigável com lazy/code-split).
+- **(b) CLI source `npx @etus/seven add`** (modelo shadcn) — copia 185 componentes como **source local** com **token-slicing** (só os tokens usados) → bundle enxuto, controle total; **mas** vira código "seu" (sem update automático; re-rodar `add` p/ acompanhar o DS — relevante porque está em beta).
+- **Trade-off:** (a) acompanha o DS em evolução com menos esforço; (b) resolve o bundle e é mais idiomático p/ um boilerplate-base, ao custo de manutenção manual.
+- **✅ DECISÃO (2026-06-16): (a) Runtime `@etus/seven-react`** — manter alinhamento contínuo ao DS (beta evolui); domar o bundle via lazy-load nas rotas públicas (U4.2).
+
+**Checkpoint Fase 0:** D1/D2/D4/D5 fechados; **D3 corrigido pelo DESIGN.md** (aguarda só o OK sobre Geist→JetBrains Mono). Fases 1–5 reescritas abaixo para "rewrite guiado por blocks".
+
+---
+
+## Fase 1 — Fundação de tokens (P0)
+
+**Objetivo:** o Seven passa a ditar radius/shadow/breakpoint/tipografia; o `@theme` local guarda só os extras.
+**Depende de:** D1, D2.
+
+### U1.1 — Remover tokens colidentes do `@theme`
+Conforme D2 (resolvido):
+
+| Família (local) | Ação | Razão |
+|---|---|---|
+| `--radius-xs…2xl`, `--radius-full` | **Remover** | colide com Seven; escala local ≈ metade (xs 1 vs 2, md 4 vs 8…) |
+| `--shadow-xs…xl` | **Remover** | colide com Seven (`--shadow-xs…xl`) |
+| `--shadow-2xl`, `--shadow-inner` | **Manter** | Seven não fornece |
+| `--breakpoint-sm…2xl` | **Remover** | colide; sm 640→**360**, 2xl 1536→**1440** — ⚠️ validar responsividade (R1) |
+| `--text-xs…5xl` | **Remover** | Seven define `--text-*` (2xs…9xl) |
+| `--font-{thin…extrabold}` | **Remover** | redundante; Tailwind usa `--font-weight-*` (Seven fornece 100–900) |
+| `--leading-*` | **Manter** | Seven usa namespace `--font-leading-*`, não toca `--leading-*` |
+| `--blur-*`, `--container-*`, `--grid-gap-*`, `--content-*` | **Manter** | utilitários locais, não conflitam com Seven |
+| `--spacing-{page,section,group,element,tight,xs}`, `--layout-*`, `--card-padding*` | **Manter** | semântica de layout própria |
+| `--animate-duration-*`, `--animate-ease-*`, `--animate-spring` | **Manter (P2: alinhar)** | Seven usa `--duration-*`/`--ease-*` (nomes diferentes) — alinhar é opcional |
+| `--color-error*`, `--color-*-solid` | **Manter** | Seven usa `destructive`; não tem variantes `*-solid` |
+
+- **Verde:** `pnpm build` ok; `grep -nE "\-\-(radius|breakpoint|shadow-(xs|sm|md|lg|xl))" src/client/index.css` só retorna o que a tabela manda manter; screenshot de uma tela de referência (ex.: dashboard) batendo com o tom do Seven.
+
+### U1.2 — Reescrever efeitos e remover paletas (D1 = opção b)
+- Para cada utilitário em `index.css` que usa `var(--color-{green,blue,gray,red,yellow,pink,main1,main2}-*)`
+ (`.gradient-{primary,accent,warm}`, `.glow-*`, spinner/rainbow, `.skeleton` shimmer — linhas ~514–721),
+ trocar pelos tokens `--brand-*`/semânticos do Seven mais próximos; depois **deletar os 88 tokens de paleta** do `@theme`.
+- **Verde:** `grep -nE "var\(--color-(green|blue|gray|red|yellow|pink|main1|main2)-" src/client` vazio; efeitos conferidos visualmente.
+
+### U1.3 — Fontes (D3 corrigido pelo DESIGN.md)
+- `index.html`: manter **Inter 400/500/600/700** (já presente; NÃO adicionar 800/900); trocar o `` para incluir **JetBrains Mono**.
+- `index.css`: `--font-mono` → JetBrains Mono (era Geist, proibido pelo DESIGN.md); **remover** `--font-serif` (órfão); não introduzir Space Grotesk.
+- **Verde:** `font-mono` (6 usos) renderiza JetBrains Mono; `grep -iE "geist|space grotesk" src/client` vazio; sem `--font-serif`.
+
+**Checkpoint Fase 1:** ✅ executado 2026-06-16 (branch `feat/frontend-seven-ds`) — `pnpm typecheck:client` + `pnpm build` (988ms) verdes; limpeza confirmada (0 paletas, 0 tokens colidentes, JetBrains Mono no lugar de Geist). Revisão visual no browser: **pendente**.
+
+---
+
+## Fase 2 — Shell canônico (rewrite guiado pelo showcase)
+
+**Objetivo:** trocar o shell caseiro (`sidebar.tsx`, 267 linhas) pelo sistema de navegação do Seven, replicando o shell canônico do showcase.
+**Depende de:** Fase 1.
+**Referência:** `seven/apps/showcase/src/routes/__root.tsx` (+ blocks `data/blocks/page-shells/*`; screenshots `showcase-canonical-shell-*`).
+
+### U2.1 — Navegação com o sistema Sidebar do Seven
+- Substituir `components/sidebar.tsx` por `SidebarProvider mode="dual"` → `SidebarRailContent` (rail 64px: logo + ícones de seção + theme toggle + ações) + `SidebarPanelContent` (216px: `SidebarHeader` + `SidebarContent` com `SidebarMenu`/`SidebarMenuItem`/`SidebarMenuButton`). Manter os ícones lucide e o user/account menu.
+- Ligar às rotas autenticadas (TanStack `Link`), preservando `useAuth`/`use-theme`.
+- **Verde:** rail+panel como o canonical; navegação e theme toggle funcionam; nenhum markup de sidebar caseiro resta.
+
+### U2.2 — Layout autenticado com `SidebarInset`
+- `routes/_authenticated.tsx`: `SidebarInset` → header `h-12` (Breadcrumb derivado do pathname + ações) + content `rounded-tl-[24px] border bg-background px-8 py-8` (assinatura do shell). `SidebarTrigger` p/ colapsar; skeletons → `SkeletonLoader`/`SidebarMenuSkeleton`.
+- **Verde:** layout idêntico ao canonical; breadcrumb correto; loading sem CLS; E2E de navegação verde.
+
+**Checkpoint Fase 2:** ✅ executado 2026-06-16 — `sidebar.tsx` reescrito como `AppSidebar` (single mode: `SidebarProvider` + `Sidebar collapsible="icon"` + `SidebarHeader/Content/Footer` + `SidebarInset` com header `h-12` e content `rounded-tl-[24px]`); `_authenticated.tsx` monta o shell. `pnpm typecheck:client` + `pnpm build` verdes. ✅ **validação visual feita** (dev server + `/auth/test-login` + `/dashboard`, viewport 1440×900): shell **expandido e colapsado** conferidos contra o canônico, console **sem erros**. Bug pego só na renderização real (não no build): `SidebarAvatar` não compacta sozinho no modo ícone → ligado ao `useSidebar` (`compact={state==='collapsed'}`). 3 refinamentos aplicados: `SidebarAvatar`+dropdown no rodapé, `aria-current="page"`, `size="lg"` no header.
+
+---
+
+## Fase 3 — Telas guiadas por blocks (rewrite da apresentação, lógica preservada)
+
+**Objetivo:** reescrever a árvore visual de cada tela partindo do block correspondente do showcase, **preservando a lógica** (hooks/rotas/forms RHF+zod/queries/handlers do `@etus/auth`). Nesta fase somem os caseiros e o HTML cru de controle.
+**Depende de:** Fase 1 (+ Fase 2 p/ as telas autenticadas).
+
+> **Regra de execução:** abrir o block no showcase (`seven/apps/showcase/src/data/blocks//` e `routes/layouts/marketing/*`), copiar a composição e religar aos dados/forms existentes. Validar **runtime** dos componentes (`Object.keys(await import('@etus/ui'))`), nunca o `.d.ts` (substring → falso positivo). Props do Seven ≠ shadcn: `TextInput` (`size`/`leadingIcon`), `Divider`, `SkeletonLoader`, `Switch`, `Checkbox` — ajustar call-sites. Seguir as regras de ouro (sentence case pt-BR, type hints `[color:var(...)]`, micro-press, radius stacks, `Badge` `type`+`color` — R5).
+>
+> Primitivos substituídos ao longo das telas: `input.tsx`→`TextInput`, `separator.tsx`→`Divider`, `skeleton.tsx`→`SkeletonLoader`, `sonner.tsx`→`Toaster` (D4), toggles `
)
}
diff --git a/packages/bhono-app/templates/base/src/client/routes/_authenticated/team.tsx b/packages/bhono-app/templates/base/src/client/routes/_authenticated/team.tsx
index f4a6bb1..03ed680 100644
--- a/packages/bhono-app/templates/base/src/client/routes/_authenticated/team.tsx
+++ b/packages/bhono-app/templates/base/src/client/routes/_authenticated/team.tsx
@@ -30,8 +30,8 @@ import {
FormItem,
FormLabel,
FormMessage,
+ TextInput,
} from '@etus/seven-react'
-import { Input } from '@/components/ui/input'
import { Icons } from '@/components/icons'
import { useAuth } from '@/hooks/use-auth'
import type { Account, AuthUser } from '@shared/types'
@@ -237,7 +237,7 @@ function TeamPage() {
Email Address
-
- { setSearchQuery(e.target.value) }}
diff --git a/packages/bhono-app/templates/base/src/client/routes/_authenticated/workspaces.tsx b/packages/bhono-app/templates/base/src/client/routes/_authenticated/workspaces.tsx
index 3adfae3..41837bd 100644
--- a/packages/bhono-app/templates/base/src/client/routes/_authenticated/workspaces.tsx
+++ b/packages/bhono-app/templates/base/src/client/routes/_authenticated/workspaces.tsx
@@ -1,11 +1,17 @@
import { createFileRoute } from '@tanstack/react-router'
import {
Badge,
+ Callout,
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
+ Empty,
+ EmptyDescription,
+ EmptyHeader,
+ EmptyMedia,
+ EmptyTitle,
} from '@etus/seven-react'
import { Icons } from '@/components/icons'
import { useGatewayAccounts, type AccountRole } from '@/hooks/use-gateway-accounts'
@@ -39,17 +45,9 @@ function WorkspacesPage() {
{superAdmin && (
-
-
-
-
- Super admin
-
- You have admin-level access across every workspace, regardless of the list below.
-
-
-
-
+ } title="Super admin" variant="success">
+ You have admin-level access across every workspace, regardless of the list below.
+
)}
{isLoading ? (
@@ -58,17 +56,19 @@ function WorkspacesPage() {
Loading workspaces…
) : accounts.length === 0 ? (
-
-
-
-
No workspaces yet
-
+
+
+
+
+
+ No workspaces yet
+
{superAdmin
? 'You hold no explicit per-workspace role, but super admin grants access everywhere.'
: "You don't belong to any gateway workspace yet. An admin can grant you a role."}
-
-
-
+
+
+
) : (
{accounts.map((account) => {
diff --git a/packages/bhono-app/templates/base/src/client/routes/login.tsx b/packages/bhono-app/templates/base/src/client/routes/login.tsx
index b308da1..2a30787 100644
--- a/packages/bhono-app/templates/base/src/client/routes/login.tsx
+++ b/packages/bhono-app/templates/base/src/client/routes/login.tsx
@@ -1,6 +1,6 @@
import { createFileRoute, Link } from '@tanstack/react-router'
import { useState } from 'react'
-import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle } from '@etus/seven-react'
+import { Button } from '@etus/seven-react'
import { Icons } from '@/components/icons'
export const Route = createFileRoute('/login')({
@@ -16,37 +16,31 @@ function LoginPage() {
}
return (
-
- {/* Simple header */}
-
-
-
- Hono
-
-
+
+ {/* Form panel — primary content */}
+
+
+ {/* Brand mark */}
+
+
+
+
+ Hono
+
- {/* Login form */}
-
-
-
-
- Welcome back
-
-
+