From cdd0d38480d1e471a4c4f72a0757dd16984274e2 Mon Sep 17 00:00:00 2001 From: borja Date: Mon, 13 Oct 2025 18:09:15 +0200 Subject: [PATCH] feat: base de UI con tokens.css, base.css, AppShell y layout /app Co-authored-by: aider (openrouter/openai/gpt-5) --- apps/web/src/lib/styles/base.css | 63 +++++++++++++++++++ apps/web/src/lib/styles/tokens.css | 39 ++++++++++++ apps/web/src/lib/ui/layout/AppShell.svelte | 70 ++++++++++++++++++++++ apps/web/src/routes/+layout.svelte | 3 + apps/web/src/routes/app/+layout.server.ts | 2 +- apps/web/src/routes/app/+layout.svelte | 8 +++ 6 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/lib/styles/base.css create mode 100644 apps/web/src/lib/styles/tokens.css create mode 100644 apps/web/src/lib/ui/layout/AppShell.svelte create mode 100644 apps/web/src/routes/app/+layout.svelte diff --git a/apps/web/src/lib/styles/base.css b/apps/web/src/lib/styles/base.css new file mode 100644 index 0000000..5481929 --- /dev/null +++ b/apps/web/src/lib/styles/base.css @@ -0,0 +1,63 @@ +/* Reset/normalización ligera */ +*, +*::before, +*::after { box-sizing: border-box; } +html, body { height: 100%; } +body { + margin: 0; + font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, Arial, "Apple Color Emoji", "Segoe UI Emoji"; + font-size: 16px; + line-height: 1.5; + background: var(--color-bg); + color: var(--color-text); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +img, svg, video { display: block; max-width: 100%; } +a { color: inherit; text-decoration: none; } +button { font: inherit; } + +/* Accesibilidad: foco visible */ +:focus-visible { + outline: 2px solid var(--color-primary); + outline-offset: 2px; +} + +/* Utilidades */ +.container { + max-width: 960px; + margin: 0 auto; + padding: 0 var(--space-4); +} + +.sr-only { + position: absolute !important; + width: 1px; height: 1px; + padding: 0; margin: -1px; + overflow: hidden; clip: rect(0,0,0,0); + white-space: nowrap; border: 0; +} + +/* Controles base */ +button, +input[type="submit"] { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 44px; + padding: 0 12px; + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + background: var(--color-surface); + color: var(--color-text); + cursor: pointer; +} +button.primary { + background: var(--color-primary); + border-color: var(--color-primary); + color: white; +} +button:disabled { + opacity: 0.6; + cursor: not-allowed; +} diff --git a/apps/web/src/lib/styles/tokens.css b/apps/web/src/lib/styles/tokens.css new file mode 100644 index 0000000..07209a8 --- /dev/null +++ b/apps/web/src/lib/styles/tokens.css @@ -0,0 +1,39 @@ +:root { + --color-bg: #ffffff; + --color-surface: #f7f7f8; + --color-text: #111111; + --color-text-muted: #555555; + --color-border: #e5e7eb; + + --color-primary: #2563eb; /* azul */ + --color-danger: #dc2626; /* rojo */ + --color-warning: #d97706; /* ámbar */ + --color-success: #16a34a; /* verde */ + + --radius-sm: 6px; + --radius-md: 8px; + + --shadow-sm: 0 1px 2px rgba(0,0,0,0.06); + --shadow-md: 0 4px 12px rgba(0,0,0,0.08); + + --space-1: 4px; + --space-2: 8px; + --space-3: 12px; + --space-4: 16px; + --space-5: 24px; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-bg: #0b0c0f; + --color-surface: #14161a; + --color-text: #e6e7eb; + --color-text-muted: #a1a1aa; + --color-border: #26272b; + + --color-primary: #60a5fa; + --color-danger: #f87171; + --color-warning: #fbbf24; + --color-success: #34d399; + } +} diff --git a/apps/web/src/lib/ui/layout/AppShell.svelte b/apps/web/src/lib/ui/layout/AppShell.svelte new file mode 100644 index 0000000..d1e38ae --- /dev/null +++ b/apps/web/src/lib/ui/layout/AppShell.svelte @@ -0,0 +1,70 @@ + + +
+
+ Tareas + +
+ +
+
+
+ +
+ {@render children?.()} +
+ + diff --git a/apps/web/src/routes/+layout.svelte b/apps/web/src/routes/+layout.svelte index 20f8d04..f4b1d6d 100644 --- a/apps/web/src/routes/+layout.svelte +++ b/apps/web/src/routes/+layout.svelte @@ -1,11 +1,14 @@ + {@render children?.()} diff --git a/apps/web/src/routes/app/+layout.server.ts b/apps/web/src/routes/app/+layout.server.ts index 7164642..79628c5 100644 --- a/apps/web/src/routes/app/+layout.server.ts +++ b/apps/web/src/routes/app/+layout.server.ts @@ -4,7 +4,7 @@ import { redirect } from '@sveltejs/kit'; export const load: LayoutServerLoad = async (event) => { const userId = event.locals.userId ?? null; if (!userId) { - throw redirect(303, '/'); + throw redirect(303, '/login'); } return { userId }; }; diff --git a/apps/web/src/routes/app/+layout.svelte b/apps/web/src/routes/app/+layout.svelte new file mode 100644 index 0000000..87f6323 --- /dev/null +++ b/apps/web/src/routes/app/+layout.svelte @@ -0,0 +1,8 @@ + + + + {@render children?.()} +