diff --git a/CHANGELOG.md b/CHANGELOG.md index b79ecf0..d07650e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ Notable changes to this project are recorded here. The format follows ## [Unreleased] +### Changed + +- The theme is a thin layer over the VitePress default theme: one + `style.css`, Lucide icons in the sidebar, and the same header geometry on + every page. `ApiCard` is a plain key/description list. +- Each home page is the stock VitePress hero with a pointer-following + `HomeSpotlight` behind it and a screenshot of the portal below. + +### Removed + +- `HeroSection` and `SpotlightBackground`, and the `theme.css`, `sidebar.css` + and `api-docs-responsive.css` stylesheets. + ## [0.1.0] - 2026-11-05 ### Added diff --git a/README.md b/README.md index 167b610..6a8aee3 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ raw spec ──► hydrate ► fix ► validate ──► docs/public/openapi./index.md`, with `HomeSpotlight` (a glow that follows the pointer) behind it. - **Language routing**: `/` (`docs/index.md`) sends the browser to `/pt/`, `/es/` or `/fr/` based on its language, and to `/en/` otherwise. Without JavaScript it shows a list of the four languages. ## Project structure @@ -53,12 +53,13 @@ raw spec ──► hydrate ► fix ► validate ──► docs/public/openapi./` and adjust the sidebars in `docs/.vitepress/config.ts`. -3. Change the brand block in `docs/.vitepress/theme/theme.css` and the logos in `docs/public/`. -4. Take a new `docs/public/preview.png` (the hero shows it inside a MacBook frame: screenshot at 1440×932 and composite it into the screen area). +3. Change the brand block in `docs/.vitepress/theme/style.css` and the logos in `docs/public/`. +4. Replace `docs/public/preview.png` and the two `preview-*.webp` files that the home pages show (1761×1075, a laptop frame with a 1440×932 screenshot composited into the screen). 5. Deploy: any static host works. The live demo runs on Cloudflare Workers Static Assets: `pnpm run deploy` builds the site and runs `wrangler deploy` (config in `wrangler.jsonc`). ## Contributing diff --git a/README.pt-br.md b/README.pt-br.md index 385deee..7d04c34 100644 --- a/README.pt-br.md +++ b/README.pt-br.md @@ -44,8 +44,8 @@ spec crua ──► hydrate ► fix ► validate ──► docs/public/openapi.< - **Guias** são Markdown em `docs/{en,pt,es,fr}/`. Cada idioma tem nav e sidebar próprios em `docs/.vitepress/config.ts`. - **Referência da API**: `docs/.vitepress/components/ScalarApi.vue` embute o Scalar e escolhe a spec pelo idioma da página (`pt` → `openapi.pt-BR.json`, `en` → `openapi.en.json`, ...). Use `spec-url` para sobrescrever. -- **Tema**: o Scalar roda com `theme: 'none'` e suas variáveis CSS são mapeadas para as do VitePress, então a referência segue cores, fontes e modo escuro do site. A paleta fica em `docs/.vitepress/theme/theme.css`. -- **Componentes**: `ApiCard` (tabelas chave/descrição dos guias), `HeroSection` + `SpotlightBackground` (página inicial). +- **Tema**: o Scalar roda com `theme: 'none'` e suas variáveis CSS são mapeadas para as do VitePress, então a referência segue cores, fontes e modo escuro do site. A cor da marca e as fontes ficam em `docs/.vitepress/theme/style.css`, uma camada fina sobre o tema padrão do VitePress. +- **Componentes**: `ApiCard` (tabelas chave/descrição dos guias), A página inicial de cada idioma é o hero padrão do VitePress, configurado em `docs//index.md`, com o `HomeSpotlight` (um brilho que segue o ponteiro) por trás. - **Idioma**: `/` (`docs/index.md`) leva o navegador para `/pt/`, `/es/` ou `/fr/` conforme o idioma dele, e para `/en/` nos demais casos. Sem JavaScript, mostra a lista dos quatro idiomas. ## Estrutura do projeto @@ -53,12 +53,13 @@ spec crua ──► hydrate ► fix ► validate ──► docs/public/openapi.< ```text docs/ ├── .vitepress/ -│ ├── components/ ApiCard, HeroSection, ScalarApi, SpotlightBackground -│ ├── theme/ theme.css (paleta), style.css, api-docs-responsive.css, sidebar.css, fonts.css +│ ├── components/ ApiCard, HomeSpotlight, ScalarApi +│ ├── theme/ style.css (marca, fontes, superfícies), fonts.css │ └── config.ts idiomas, nav, sidebars ├── public/ │ ├── openapi.{en,pt-BR,es,fr}.json uma spec por idioma -│ ├── preview.png imagem da página inicial (também usada acima) +│ ├── preview.png screenshot usado acima +│ ├── preview-{1080,1761}.webp a mesma imagem nas páginas iniciais │ └── favicon.svg, logo-{light,dark}.svg ├── en/ pt/ es/ fr/ intro, authentication, rate-limits, examples, pagination, errors, api-reference └── index.md redirecionamento de idioma @@ -68,8 +69,8 @@ docs/ 1. Substitua `docs/public/openapi.*.json` pelas suas specs (uma por idioma, ou aponte todos os idiomas para o mesmo arquivo em `SPEC_BY_LANG`, dentro de `ScalarApi.vue`). 2. Reescreva os guias em `docs//` e ajuste as sidebars em `docs/.vitepress/config.ts`. -3. Troque o bloco de marca em `docs/.vitepress/theme/theme.css` e os logos em `docs/public/`. -4. Gere um novo `docs/public/preview.png` (a página inicial mostra a imagem dentro de um MacBook: print em 1440×932 composto na área da tela). +3. Troque o bloco de marca em `docs/.vitepress/theme/style.css` e os logos em `docs/public/`. +4. Troque o `docs/public/preview.png` e os dois `preview-*.webp` das páginas iniciais (1761×1075, um notebook com um print de 1440×932 composto na tela). 5. Publique em qualquer host estático. A demo roda no Cloudflare Workers Static Assets: `pnpm run deploy` gera o site e roda `wrangler deploy` (configuração em `wrangler.jsonc`). ## Contribuindo diff --git a/docs/.vitepress/components/ApiCard.vue b/docs/.vitepress/components/ApiCard.vue index 268d357..c347941 100644 --- a/docs/.vitepress/components/ApiCard.vue +++ b/docs/.vitepress/components/ApiCard.vue @@ -1,199 +1,74 @@ + + - - diff --git a/docs/.vitepress/components/HeroSection.vue b/docs/.vitepress/components/HeroSection.vue deleted file mode 100644 index e008393..0000000 --- a/docs/.vitepress/components/HeroSection.vue +++ /dev/null @@ -1,408 +0,0 @@ - - - - - diff --git a/docs/.vitepress/components/HomeSpotlight.vue b/docs/.vitepress/components/HomeSpotlight.vue new file mode 100644 index 0000000..f066080 --- /dev/null +++ b/docs/.vitepress/components/HomeSpotlight.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/docs/.vitepress/components/ScalarApi.vue b/docs/.vitepress/components/ScalarApi.vue index 8bad8d8..1f2f5f3 100644 --- a/docs/.vitepress/components/ScalarApi.vue +++ b/docs/.vitepress/components/ScalarApi.vue @@ -1,20 +1,11 @@ - - - diff --git a/docs/.vitepress/components/SpotlightBackground.vue b/docs/.vitepress/components/SpotlightBackground.vue deleted file mode 100644 index 27f3b30..0000000 --- a/docs/.vitepress/components/SpotlightBackground.vue +++ /dev/null @@ -1,255 +0,0 @@ - - - - - diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 2ddf5fe..49d2876 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -1,258 +1,194 @@ -import { defineConfig } from 'vitepress' +import { BookOpen, Gauge, KeyRound, ListOrdered, SquareCode, TriangleAlert } from 'lucide-static' +import { defineConfig, type DefaultTheme, type LocaleSpecificConfig } from 'vitepress' -// Theme options that are the same in every locale. -const shared = { - siteTitle: false as const, - logo: { - light: '/logo-light.svg', - dark: '/logo-dark.svg', - alt: 'API Docs Starter Logo' +// Every string that changes per language. Adding a locale means adding an +// entry here, its docs// pages and docs/public/openapi..json. +const LOCALES = { + en: { + label: 'English', + lang: 'en', + description: 'Multilingual API documentation portal with VitePress and Scalar', + nav: { home: 'Home', guide: 'API guide', reference: 'API reference' }, + sidebar: { + guide: 'API guide', + intro: 'Introduction', + auth: 'Authentication', + limits: 'Rate limits', + examples: 'Examples', + reference: 'Reference', + pagination: 'Pagination & links', + errors: 'Errors' + }, + outline: 'On this page', + prev: 'Previous page', + next: 'Next page', + search: null }, - footer: { - copyright: ` - API Docs Starter © 2025 · by - - rafactx - - - - ` + pt: { + label: 'Português (Brasil)', + lang: 'pt-BR', + description: 'Portal de documentação de API multilíngue com VitePress e Scalar', + nav: { home: 'Início', guide: 'Guia da API', reference: 'Referência da API' }, + sidebar: { + guide: 'Guia da API', + intro: 'Introdução', + auth: 'Autenticação', + limits: 'Limites', + examples: 'Exemplos', + reference: 'Referência', + pagination: 'Paginação e links', + errors: 'Erros' + }, + outline: 'Nesta página', + prev: 'Página anterior', + next: 'Próxima página', + search: ['Buscar', 'Nenhum resultado para', 'Limpar busca', 'selecionar', 'navegar', 'fechar'] }, - socialLinks: [{ icon: 'github' as const, link: 'https://github.com/rafactx/api-docs-starter' }] + es: { + label: 'Español', + lang: 'es', + description: 'Portal de documentación de API multilingüe con VitePress y Scalar', + nav: { home: 'Inicio', guide: 'Guía de la API', reference: 'Referencia de la API' }, + sidebar: { + guide: 'Guía de la API', + intro: 'Introducción', + auth: 'Autenticación', + limits: 'Límites', + examples: 'Ejemplos', + reference: 'Referencia', + pagination: 'Paginación y enlaces', + errors: 'Errores' + }, + outline: 'En esta página', + prev: 'Página anterior', + next: 'Página siguiente', + search: ['Buscar', 'Sin resultados para', 'Borrar búsqueda', 'seleccionar', 'navegar', 'cerrar'] + }, + fr: { + label: 'Français', + lang: 'fr', + description: "Portail de documentation d'API multilingue avec VitePress et Scalar", + nav: { home: 'Accueil', guide: "Guide de l'API", reference: "Référence de l'API" }, + sidebar: { + guide: "Guide de l'API", + intro: 'Introduction', + auth: 'Authentification', + limits: 'Limites', + examples: 'Exemples', + reference: 'Référence', + pagination: 'Pagination et liens', + errors: 'Erreurs' + }, + outline: 'Sur cette page', + prev: 'Page précédente', + next: 'Page suivante', + search: ['Rechercher', 'Aucun résultat pour', 'Effacer la recherche', 'sélectionner', 'naviguer', 'fermer'] + } +} as const + +type Strings = (typeof LOCALES)[keyof typeof LOCALES] + +// Icons are inlined into the sidebar labels; style.css sizes them. +const icon = (svg: string) => svg.replace('