feat(web): design system v2 — tech sophisticated con glass + gradient mesh
Cambios principales: - Agregado violet accent (oklch 0.62 0.20 280) para combo tech con brand cyan - Neutrals con shift sutil hacia hue 250 (slate-violet) - Dark mode con bg oklch(0.135 0.018 252) — no pure black, feel mas tech - Inputs con token --input propio (white en light, elevado en dark) y --input-border mas prominente. Fixea problema de input gris feo - Card soporta variant glass/elevated/default - Multi-layer shadows reales (shadow-sm/md/lg/xl/glow) - Gradient mesh utility (.gradient-mesh + token --gradient-mesh) - Clase .glass para glassmorphism (backdrop-blur 20px + saturate 180%) - Border radius default 10px (era 8px) — mas moderno - Headings con tracking-tight -0.015em LoginPage redesigned: - PublicLayout con gradient mesh + 2 glow blobs (brand+violet) + grid sutil - Card variant glass para el form - Logo mark con bg-gradient-to-br from-brand-500 to-violet-500 - Inputs con bg propio + ring brand glow al focus Tests: 136/136 verde. Doc Obsidian 2.14 actualizado v2.0. Engram sig-cm2/design-system actualizado.
This commit is contained in:
@@ -1,20 +1,34 @@
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
import { cva, type VariantProps } from 'class-variance-authority'
|
||||||
|
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
const Card = React.forwardRef<
|
const cardVariants = cva('rounded-xl text-card-foreground transition-shadow', {
|
||||||
HTMLDivElement,
|
variants: {
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
variant: {
|
||||||
>(({ className, ...props }, ref) => (
|
default: 'border border-border bg-card shadow-sm',
|
||||||
<div
|
elevated: 'border border-border bg-card shadow-lg',
|
||||||
ref={ref}
|
glass: 'glass shadow-xl',
|
||||||
className={cn(
|
},
|
||||||
'rounded-lg border bg-card text-card-foreground shadow-sm',
|
},
|
||||||
className,
|
defaultVariants: {
|
||||||
)}
|
variant: 'default',
|
||||||
{...props}
|
},
|
||||||
/>
|
})
|
||||||
))
|
|
||||||
|
export interface CardProps
|
||||||
|
extends React.HTMLAttributes<HTMLDivElement>,
|
||||||
|
VariantProps<typeof cardVariants> {}
|
||||||
|
|
||||||
|
const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
||||||
|
({ className, variant, ...props }, ref) => (
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={cn(cardVariants({ variant }), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
Card.displayName = 'Card'
|
Card.displayName = 'Card'
|
||||||
|
|
||||||
const CardHeader = React.forwardRef<
|
const CardHeader = React.forwardRef<
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||||||
<input
|
<input
|
||||||
type={type}
|
type={type}
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
|
'flex h-10 w-full rounded-md border border-input-border bg-input px-3 py-2 text-sm text-foreground shadow-sm ring-offset-background transition-colors',
|
||||||
|
'placeholder:text-muted-foreground/70',
|
||||||
|
'file:border-0 file:bg-transparent file:text-sm file:font-medium',
|
||||||
|
'hover:border-border focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:ring-offset-0',
|
||||||
|
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { isAxiosError } from 'axios'
|
import { isAxiosError } from 'axios'
|
||||||
import { AlertCircle } from 'lucide-react'
|
import { AlertCircle, Newspaper } from 'lucide-react'
|
||||||
import { useLogin } from '../hooks/useLogin'
|
import { useLogin } from '../hooks/useLogin'
|
||||||
import { LoginForm } from '../components/LoginForm'
|
import { LoginForm } from '../components/LoginForm'
|
||||||
import {
|
import {
|
||||||
@@ -39,14 +39,18 @@ export function LoginPage() {
|
|||||||
const errorMessage = resolveErrorMessage(error)
|
const errorMessage = resolveErrorMessage(error)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="w-full max-w-sm">
|
<Card variant="glass" className="w-full max-w-md">
|
||||||
<CardHeader className="space-y-1">
|
<CardHeader className="space-y-3 text-center pb-2">
|
||||||
<CardTitle className="text-2xl text-center">SIG-CM 2.0</CardTitle>
|
{/* Brand mark */}
|
||||||
<CardDescription className="text-center">
|
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-brand-500 to-violet-500 shadow-lg shadow-brand-500/30">
|
||||||
Iniciar sesión
|
<Newspaper className="h-6 w-6 text-white" strokeWidth={2.25} />
|
||||||
|
</div>
|
||||||
|
<CardTitle className="text-2xl tracking-tight">SIG-CM 2.0</CardTitle>
|
||||||
|
<CardDescription className="text-sm">
|
||||||
|
Sistema de gestión comercial · El Día
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4 pt-4">
|
||||||
{errorMessage && (
|
{errorMessage && (
|
||||||
<Alert variant="destructive">
|
<Alert variant="destructive">
|
||||||
<AlertCircle className="h-4 w-4" />
|
<AlertCircle className="h-4 w-4" />
|
||||||
|
|||||||
@@ -7,110 +7,155 @@
|
|||||||
@import "@fontsource/jetbrains-mono/400.css";
|
@import "@fontsource/jetbrains-mono/400.css";
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
SIG-CM 2.0 Design System — Tokens
|
SIG-CM 2.0 Design System v2.0 — Tokens
|
||||||
Source of truth: Obsidian/02-ARQUITECTURA-y-TECH-STACK/2.14 🎨 Design System.md
|
Source of truth: Obsidian/02-ARQUITECTURA-y-TECH-STACK/2.14 🎨 Design System.md
|
||||||
Brand color: #008fbe (logo El Día) — escalado OKLCH
|
Brand: #008fbe (logo) + violet accent → tech sophistication
|
||||||
|
Style: dark-first elegante, glassmorphism, multi-layer shadows
|
||||||
================================================================ */
|
================================================================ */
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
/* ── Brand (cyan-blue around logo #008fbe) ─────────────────── */
|
/* ── Brand cyan (logo #008fbe) ──────────────────────────── */
|
||||||
--brand-50: oklch(0.972 0.013 220);
|
--brand-50: oklch(0.972 0.013 220);
|
||||||
--brand-100: oklch(0.935 0.035 220);
|
--brand-100: oklch(0.935 0.035 220);
|
||||||
--brand-200: oklch(0.870 0.072 220);
|
--brand-200: oklch(0.870 0.072 220);
|
||||||
--brand-300: oklch(0.780 0.108 220);
|
--brand-300: oklch(0.780 0.108 220);
|
||||||
--brand-400: oklch(0.690 0.128 220);
|
--brand-400: oklch(0.700 0.135 220);
|
||||||
--brand-500: oklch(0.625 0.130 220); /* logo #008fbe */
|
--brand-500: oklch(0.625 0.130 220); /* logo #008fbe */
|
||||||
--brand-600: oklch(0.550 0.128 222);
|
--brand-600: oklch(0.530 0.135 222);
|
||||||
--brand-700: oklch(0.460 0.110 224);
|
--brand-700: oklch(0.440 0.115 224);
|
||||||
--brand-800: oklch(0.360 0.082 226);
|
--brand-800: oklch(0.350 0.085 226);
|
||||||
--brand-900: oklch(0.280 0.058 228);
|
--brand-900: oklch(0.270 0.060 228);
|
||||||
--brand-950: oklch(0.200 0.040 230);
|
--brand-950: oklch(0.190 0.040 230);
|
||||||
|
|
||||||
/* ── Neutral (cool slate, complementa el blue) ─────────────── */
|
/* ── Violet accent (combo tech con brand cyan) ──────────── */
|
||||||
--neutral-50: oklch(0.985 0.003 240);
|
--accent-violet-400: oklch(0.700 0.180 280);
|
||||||
--neutral-100: oklch(0.965 0.005 240);
|
--accent-violet-500: oklch(0.620 0.200 280);
|
||||||
--neutral-200: oklch(0.918 0.008 240);
|
--accent-violet-600: oklch(0.530 0.205 280);
|
||||||
--neutral-300: oklch(0.850 0.012 240);
|
|
||||||
--neutral-400: oklch(0.690 0.015 240);
|
|
||||||
--neutral-500: oklch(0.550 0.018 240);
|
|
||||||
--neutral-600: oklch(0.450 0.018 240);
|
|
||||||
--neutral-700: oklch(0.360 0.015 240);
|
|
||||||
--neutral-800: oklch(0.270 0.013 240);
|
|
||||||
--neutral-900: oklch(0.210 0.010 240);
|
|
||||||
--neutral-950: oklch(0.150 0.008 240);
|
|
||||||
|
|
||||||
/* ── Semantic ──────────────────────────────────────────────── */
|
/* ── Neutral (slate con shift sutil hacia azul/violeta) ── */
|
||||||
--success: oklch(0.640 0.155 145);
|
--neutral-50: oklch(0.985 0.004 250);
|
||||||
--success-foreground: oklch(0.990 0.000 0);
|
--neutral-100: oklch(0.962 0.007 250);
|
||||||
--warning: oklch(0.760 0.150 75);
|
--neutral-200: oklch(0.910 0.012 250);
|
||||||
--warning-foreground: oklch(0.220 0.050 75);
|
--neutral-300: oklch(0.835 0.018 250);
|
||||||
|
--neutral-400: oklch(0.680 0.022 250);
|
||||||
|
--neutral-500: oklch(0.540 0.025 250);
|
||||||
|
--neutral-600: oklch(0.435 0.025 250);
|
||||||
|
--neutral-700: oklch(0.345 0.022 250);
|
||||||
|
--neutral-800: oklch(0.250 0.020 250);
|
||||||
|
--neutral-900: oklch(0.185 0.015 250);
|
||||||
|
--neutral-950: oklch(0.130 0.013 250);
|
||||||
|
|
||||||
/* ── shadcn semantic mapping (LIGHT) ───────────────────────── */
|
/* ── Semantic ──────────────────────────────────────────── */
|
||||||
--background: oklch(0.992 0.003 220); /* off-white tinted brand */
|
--success: oklch(0.640 0.155 145);
|
||||||
--foreground: var(--neutral-900);
|
--success-foreground: oklch(0.990 0.000 0);
|
||||||
|
--warning: oklch(0.760 0.150 75);
|
||||||
|
--warning-foreground: oklch(0.220 0.050 75);
|
||||||
|
|
||||||
--card: oklch(1 0 0); /* pure white over tinted bg */
|
/* ── shadcn semantic mapping (LIGHT) ─────────────────── */
|
||||||
--card-foreground: var(--neutral-900);
|
--background: oklch(0.988 0.003 250); /* slate barely warm */
|
||||||
|
--foreground: var(--neutral-900);
|
||||||
|
|
||||||
--popover: oklch(1 0 0);
|
--card: oklch(1 0 0); /* pure white */
|
||||||
--popover-foreground: var(--neutral-900);
|
--card-foreground: var(--neutral-900);
|
||||||
|
|
||||||
--primary: var(--brand-600); /* WCAG AA on white */
|
--popover: oklch(1 0 0);
|
||||||
--primary-foreground: oklch(0.990 0.000 0);
|
--popover-foreground: var(--neutral-900);
|
||||||
|
|
||||||
--secondary: var(--neutral-100);
|
--primary: var(--brand-600); /* WCAG AA on white */
|
||||||
--secondary-foreground: var(--neutral-800);
|
--primary-foreground: oklch(0.990 0.000 0);
|
||||||
|
|
||||||
--muted: var(--neutral-100);
|
--secondary: var(--neutral-100);
|
||||||
--muted-foreground: var(--neutral-500);
|
--secondary-foreground: var(--neutral-800);
|
||||||
|
|
||||||
--accent: var(--brand-50); /* hover navigation, subtle brand tint */
|
--muted: var(--neutral-100);
|
||||||
--accent-foreground: var(--brand-700);
|
--muted-foreground: var(--neutral-500);
|
||||||
|
|
||||||
--destructive: oklch(0.600 0.220 25);
|
--accent: var(--brand-50);
|
||||||
|
--accent-foreground: var(--brand-700);
|
||||||
|
|
||||||
|
--destructive: oklch(0.600 0.220 25);
|
||||||
--destructive-foreground: oklch(0.990 0.000 0);
|
--destructive-foreground: oklch(0.990 0.000 0);
|
||||||
|
|
||||||
--border: var(--neutral-200);
|
--border: var(--neutral-200);
|
||||||
--input: var(--neutral-200);
|
--input: oklch(1 0 0); /* WHITE inputs en light, no gris */
|
||||||
--ring: var(--brand-500);
|
--input-border: var(--neutral-300); /* border más prominente */
|
||||||
|
--ring: var(--brand-500);
|
||||||
|
|
||||||
/* ── Spacing & shape ──────────────────────────────────────── */
|
/* ── Glass surfaces (backdrop-blur) ───────────────────── */
|
||||||
--radius: 0.5rem; /* 8px */
|
--glass-bg: oklch(1 0 0 / 0.7);
|
||||||
|
--glass-border: oklch(1 0 0 / 0.4);
|
||||||
|
|
||||||
/* ── Typography ───────────────────────────────────────────── */
|
/* ── Gradient backgrounds (hero, login) ───────────────── */
|
||||||
|
--gradient-mesh:
|
||||||
|
radial-gradient(at 100% 0%, oklch(0.625 0.130 220 / 0.12) 0px, transparent 50%),
|
||||||
|
radial-gradient(at 0% 100%, oklch(0.620 0.200 280 / 0.10) 0px, transparent 50%),
|
||||||
|
radial-gradient(at 50% 50%, oklch(0.700 0.135 220 / 0.05) 0px, transparent 60%);
|
||||||
|
|
||||||
|
/* ── Shadows (multi-layer para depth real) ────────────── */
|
||||||
|
--shadow-sm: 0 1px 2px 0 oklch(0.185 0.015 250 / 0.05);
|
||||||
|
--shadow: 0 1px 3px 0 oklch(0.185 0.015 250 / 0.08), 0 1px 2px -1px oklch(0.185 0.015 250 / 0.06);
|
||||||
|
--shadow-md: 0 4px 8px -2px oklch(0.185 0.015 250 / 0.08), 0 2px 4px -2px oklch(0.185 0.015 250 / 0.04);
|
||||||
|
--shadow-lg: 0 12px 24px -6px oklch(0.185 0.015 250 / 0.12), 0 4px 8px -3px oklch(0.185 0.015 250 / 0.06);
|
||||||
|
--shadow-xl: 0 24px 48px -12px oklch(0.185 0.015 250 / 0.18), 0 8px 16px -8px oklch(0.185 0.015 250 / 0.08);
|
||||||
|
--shadow-glow: 0 0 0 1px oklch(0.625 0.130 220 / 0.10), 0 0 24px -4px oklch(0.625 0.130 220 / 0.20);
|
||||||
|
|
||||||
|
/* ── Spacing & shape ───────────────────────────────────── */
|
||||||
|
--radius: 0.625rem; /* 10px */
|
||||||
|
|
||||||
|
/* ── Typography ────────────────────────────────────────── */
|
||||||
--font-sans: "Inter", system-ui, -apple-system, sans-serif;
|
--font-sans: "Inter", system-ui, -apple-system, sans-serif;
|
||||||
--font-mono: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
|
--font-mono: "JetBrains Mono", "Cascadia Code", Consolas, monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: var(--neutral-950);
|
/* Background con shift sutil hacia violet → "tech" feel */
|
||||||
--foreground: var(--neutral-50);
|
--background: oklch(0.135 0.018 252); /* deep slate-violet */
|
||||||
|
--foreground: var(--neutral-50);
|
||||||
|
|
||||||
--card: var(--neutral-900);
|
--card: oklch(0.180 0.020 252); /* elevación visual */
|
||||||
--card-foreground: var(--neutral-50);
|
--card-foreground: var(--neutral-50);
|
||||||
|
|
||||||
--popover: var(--neutral-900);
|
--popover: oklch(0.200 0.022 252);
|
||||||
--popover-foreground: var(--neutral-50);
|
--popover-foreground: var(--neutral-50);
|
||||||
|
|
||||||
--primary: var(--brand-400); /* lighter on dark */
|
--primary: var(--brand-400); /* brighter en dark, "neon" feel */
|
||||||
--primary-foreground: var(--neutral-950);
|
--primary-foreground: oklch(0.130 0.013 250);
|
||||||
|
|
||||||
--secondary: var(--neutral-800);
|
--secondary: oklch(0.230 0.020 252);
|
||||||
--secondary-foreground: var(--neutral-100);
|
--secondary-foreground: var(--neutral-100);
|
||||||
|
|
||||||
--muted: var(--neutral-800);
|
--muted: oklch(0.220 0.020 252);
|
||||||
--muted-foreground: var(--neutral-400);
|
--muted-foreground: var(--neutral-400);
|
||||||
|
|
||||||
--accent: var(--neutral-800);
|
--accent: oklch(0.250 0.030 252);
|
||||||
--accent-foreground: var(--brand-300);
|
--accent-foreground: var(--brand-300);
|
||||||
|
|
||||||
--destructive: oklch(0.580 0.190 25);
|
--destructive: oklch(0.580 0.190 25);
|
||||||
--destructive-foreground: oklch(0.990 0.000 0);
|
--destructive-foreground: oklch(0.990 0.000 0);
|
||||||
|
|
||||||
--border: var(--neutral-800);
|
--border: oklch(1 0 0 / 0.10); /* sutil glass-style border */
|
||||||
--input: var(--neutral-800);
|
--input: oklch(0.215 0.020 252); /* elevado del bg, contrast con texto */
|
||||||
--ring: var(--brand-400);
|
--input-border: oklch(1 0 0 / 0.14);
|
||||||
|
--ring: var(--brand-400);
|
||||||
|
|
||||||
|
/* Glass para dark */
|
||||||
|
--glass-bg: oklch(0.180 0.020 252 / 0.6);
|
||||||
|
--glass-border: oklch(1 0 0 / 0.10);
|
||||||
|
|
||||||
|
/* Gradient mesh dark mode — más vibrante */
|
||||||
|
--gradient-mesh:
|
||||||
|
radial-gradient(at 100% 0%, oklch(0.625 0.130 220 / 0.20) 0px, transparent 50%),
|
||||||
|
radial-gradient(at 0% 100%, oklch(0.620 0.200 280 / 0.18) 0px, transparent 50%),
|
||||||
|
radial-gradient(at 50% 50%, oklch(0.700 0.135 220 / 0.08) 0px, transparent 60%);
|
||||||
|
|
||||||
|
/* Shadows más intensas en dark */
|
||||||
|
--shadow-sm: 0 1px 2px 0 oklch(0 0 0 / 0.30);
|
||||||
|
--shadow: 0 2px 4px 0 oklch(0 0 0 / 0.40), 0 1px 2px -1px oklch(0 0 0 / 0.30);
|
||||||
|
--shadow-md: 0 4px 8px -2px oklch(0 0 0 / 0.40), 0 2px 4px -2px oklch(0 0 0 / 0.30);
|
||||||
|
--shadow-lg: 0 12px 24px -6px oklch(0 0 0 / 0.50), 0 4px 8px -3px oklch(0 0 0 / 0.30);
|
||||||
|
--shadow-xl: 0 24px 48px -12px oklch(0 0 0 / 0.60), 0 8px 16px -8px oklch(0 0 0 / 0.30);
|
||||||
|
--shadow-glow: 0 0 0 1px oklch(0.700 0.135 220 / 0.30), 0 0 32px -4px oklch(0.700 0.135 220 / 0.40);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +165,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
/* Smooth color transitions when toggling theme */
|
|
||||||
color-scheme: light dark;
|
color-scheme: light dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,17 +181,15 @@
|
|||||||
min-height: 100svh;
|
min-height: 100svh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Selection color uses brand */
|
|
||||||
::selection {
|
::selection {
|
||||||
background-color: var(--brand-200);
|
background-color: var(--brand-200);
|
||||||
color: var(--brand-900);
|
color: var(--brand-900);
|
||||||
}
|
}
|
||||||
.dark ::selection {
|
.dark ::selection {
|
||||||
background-color: var(--brand-800);
|
background-color: var(--brand-700);
|
||||||
color: var(--brand-50);
|
color: var(--brand-50);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Focus visible — accessible ring usando brand */
|
|
||||||
*:focus-visible {
|
*:focus-visible {
|
||||||
outline: 2px solid var(--ring);
|
outline: 2px solid var(--ring);
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
@@ -156,7 +198,7 @@
|
|||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
letter-spacing: -0.01em;
|
letter-spacing: -0.015em;
|
||||||
}
|
}
|
||||||
|
|
||||||
code, pre, kbd, samp {
|
code, pre, kbd, samp {
|
||||||
@@ -165,9 +207,30 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
Tailwind 4 inline theme — expone tokens como utility classes
|
Glass surface utility
|
||||||
Cada token aquí queda disponible como Tailwind utility
|
Uso: <div className="glass">…</div>
|
||||||
(bg-background, text-foreground, border-border, etc.)
|
================================================================ */
|
||||||
|
@layer components {
|
||||||
|
.glass {
|
||||||
|
background-color: var(--glass-bg);
|
||||||
|
backdrop-filter: blur(20px) saturate(180%);
|
||||||
|
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||||
|
border: 1px solid var(--glass-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gradient-mesh {
|
||||||
|
background-image: var(--gradient-mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Brand glow para focus en inputs críticos */
|
||||||
|
.focus-glow:focus-visible {
|
||||||
|
box-shadow: var(--shadow-glow);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
Tailwind 4 inline theme — utilidades disponibles globalmente
|
||||||
================================================================ */
|
================================================================ */
|
||||||
@theme inline {
|
@theme inline {
|
||||||
--color-background: var(--background);
|
--color-background: var(--background);
|
||||||
@@ -188,9 +251,10 @@
|
|||||||
--color-destructive-foreground: var(--destructive-foreground);
|
--color-destructive-foreground: var(--destructive-foreground);
|
||||||
--color-border: var(--border);
|
--color-border: var(--border);
|
||||||
--color-input: var(--input);
|
--color-input: var(--input);
|
||||||
|
--color-input-border: var(--input-border);
|
||||||
--color-ring: var(--ring);
|
--color-ring: var(--ring);
|
||||||
|
|
||||||
/* Brand scale (utilities tipo bg-brand-500, text-brand-700, etc.) */
|
/* Brand */
|
||||||
--color-brand-50: var(--brand-50);
|
--color-brand-50: var(--brand-50);
|
||||||
--color-brand-100: var(--brand-100);
|
--color-brand-100: var(--brand-100);
|
||||||
--color-brand-200: var(--brand-200);
|
--color-brand-200: var(--brand-200);
|
||||||
@@ -203,6 +267,11 @@
|
|||||||
--color-brand-900: var(--brand-900);
|
--color-brand-900: var(--brand-900);
|
||||||
--color-brand-950: var(--brand-950);
|
--color-brand-950: var(--brand-950);
|
||||||
|
|
||||||
|
/* Violet accent */
|
||||||
|
--color-violet-400: var(--accent-violet-400);
|
||||||
|
--color-violet-500: var(--accent-violet-500);
|
||||||
|
--color-violet-600: var(--accent-violet-600);
|
||||||
|
|
||||||
/* Semantic */
|
/* Semantic */
|
||||||
--color-success: var(--success);
|
--color-success: var(--success);
|
||||||
--color-success-foreground: var(--success-foreground);
|
--color-success-foreground: var(--success-foreground);
|
||||||
@@ -212,6 +281,14 @@
|
|||||||
--radius-sm: calc(var(--radius) - 4px);
|
--radius-sm: calc(var(--radius) - 4px);
|
||||||
--radius-md: calc(var(--radius) - 2px);
|
--radius-md: calc(var(--radius) - 2px);
|
||||||
--radius-lg: var(--radius);
|
--radius-lg: var(--radius);
|
||||||
|
--radius-xl: calc(var(--radius) + 4px);
|
||||||
|
|
||||||
|
--shadow-sm: var(--shadow-sm);
|
||||||
|
--shadow: var(--shadow);
|
||||||
|
--shadow-md: var(--shadow-md);
|
||||||
|
--shadow-lg: var(--shadow-lg);
|
||||||
|
--shadow-xl: var(--shadow-xl);
|
||||||
|
--shadow-glow: var(--shadow-glow);
|
||||||
|
|
||||||
--font-sans: var(--font-sans);
|
--font-sans: var(--font-sans);
|
||||||
--font-mono: var(--font-mono);
|
--font-mono: var(--font-mono);
|
||||||
|
|||||||
@@ -6,8 +6,26 @@ interface PublicLayoutProps {
|
|||||||
|
|
||||||
export function PublicLayout({ children }: PublicLayoutProps) {
|
export function PublicLayout({ children }: PublicLayoutProps) {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-svh bg-muted/40 flex items-center justify-center p-4">
|
<div className="relative min-h-svh flex items-center justify-center p-4 overflow-hidden">
|
||||||
{children}
|
{/* Gradient mesh background — subtle radial blobs (brand cyan + violet) */}
|
||||||
|
<div className="absolute inset-0 gradient-mesh pointer-events-none" />
|
||||||
|
|
||||||
|
{/* Subtle grid texture overlay (visible on dark, fades on light) */}
|
||||||
|
<div
|
||||||
|
className="absolute inset-0 opacity-[0.015] dark:opacity-[0.04] pointer-events-none"
|
||||||
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
'linear-gradient(to right, currentColor 1px, transparent 1px), linear-gradient(to bottom, currentColor 1px, transparent 1px)',
|
||||||
|
backgroundSize: '64px 64px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Brand glow accents (positioned blobs) */}
|
||||||
|
<div className="absolute top-[-20%] right-[-10%] w-[500px] h-[500px] rounded-full bg-brand-500/10 dark:bg-brand-500/15 blur-[120px] pointer-events-none" />
|
||||||
|
<div className="absolute bottom-[-20%] left-[-10%] w-[500px] h-[500px] rounded-full bg-violet-500/10 dark:bg-violet-500/12 blur-[120px] pointer-events-none" />
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<div className="relative z-10 w-full flex justify-center">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user