feat(design): alinha com o sistema de design Descomplicar v1.2.0 (gold-fill #b07a00 com texto branco, Roboto/Montserrat); corrige error.issues (Zod v4) no build

This commit is contained in:
2026-10-30 19:34:39 +00:00
parent ab8bf1d9be
commit 746049ceea
10 changed files with 75 additions and 36 deletions
+1 -1
View File
@@ -208,7 +208,7 @@ export async function GET(
{
success: false,
error: 'Invalid input',
details: error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')
details: error.issues.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')
},
{ status: 400 }
)
Binary file not shown.
Binary file not shown.
+38 -2
View File
@@ -4,8 +4,26 @@
--background: #ffffff;
--foreground: #000000;
/* Descomplicar Design System v1.2.0 */
/* Dourado de marca: logótipo, gráficos, destaques decorativos. Nunca como fundo com texto nem em texto/ícones sobre claro. */
--gold: #cc8d00;
/* Acento de interface: fundos preenchidos (botões, badges) com texto --on-accent por cima; ícones de destaque sobre claro */
--gold-fill: #b07a00;
--accent-hover: #9a6a00;
--on-accent: #ffffff;
/* Texto dourado sobre fundo claro */
--accent-text: #7a5400;
--orange: #dd7500;
--ink: #111111;
--ink-muted: #5c5750;
--line: #e6e0d4;
--line-strong: #8f877a;
--success: #1d7a4f;
--danger: #b3261e;
--focus: #7a5400;
/* Brand Descomplicar */
--brand-dourado: #cc8d00;
--brand-dourado: var(--gold);
--brand-bege: #f2d9a2;
--brand-verde: #27a50e;
--brand-preto: #000000;
@@ -22,8 +40,18 @@
--color-brand-verde: var(--brand-verde);
--color-brand-preto: var(--brand-preto);
/* Interface accent (design system v1.2.0) */
--color-gold-fill: var(--gold-fill);
--color-accent-hover: var(--accent-hover);
--color-on-accent: var(--on-accent);
--color-accent-text: var(--accent-text);
--color-primary: var(--gold-fill);
--color-primary-foreground: var(--on-accent);
--color-success: var(--success);
--color-danger: var(--danger);
/* Typography */
--font-sans: 'Inter', system-ui, -apple-system, sans-serif;
--font-sans: 'Roboto', system-ui, -apple-system, 'Segoe UI', sans-serif;
--font-display: 'Montserrat', system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
@@ -49,3 +77,11 @@ body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4 {
font-family: var(--font-display);
}
:focus-visible {
outline-color: var(--focus);
}
+9 -7
View File
@@ -1,16 +1,18 @@
import type { Metadata } from 'next'
import { Inter, Montserrat } from 'next/font/google'
import localFont from 'next/font/local'
import './globals.css'
import { cn } from '@/lib/utils'
const inter = Inter({
subsets: ['latin'],
const roboto = localFont({
src: './fonts/Roboto-latin-wght-normal.woff2',
weight: '100 900',
variable: '--font-sans',
display: 'swap',
})
const montserrat = Montserrat({
subsets: ['latin'],
const montserrat = localFont({
src: './fonts/Montserrat-latin-wght-normal.woff2',
weight: '100 900',
variable: '--font-display',
display: 'swap',
})
@@ -31,7 +33,7 @@ export default function RootLayout({
return (
<html lang="pt">
<body className={cn(
inter.variable,
roboto.variable,
montserrat.variable,
'font-sans antialiased bg-gray-50'
)}>
@@ -40,7 +42,7 @@ export default function RootLayout({
<div className="container mx-auto px-md py-md">
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-display font-bold text-brand-dourado">
<h1 className="text-2xl font-display font-bold text-accent-text">
BI Descomplicar®
</h1>
<p className="text-sm text-gray-600 mt-0.5">
+17 -16
View File
@@ -27,7 +27,8 @@ interface ChartCardProps {
loading?: boolean
}
const COLORS = ['#cc8d00', '#27a50e', '#f2d9a2', '#6e6e6e', '#000000']
// Design system: uma série em dourado de marca; restantes em ink, line-strong, laranja
const COLORS = ['var(--gold)', 'var(--ink)', 'var(--line-strong)', 'var(--orange)', 'var(--line)']
export function ChartCard({
title,
@@ -80,16 +81,16 @@ export function ChartCard({
<ResponsiveContainer width="100%" height={300}>
{type === 'line' && (
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" stroke="#f2d9a2" opacity={0.5} />
<CartesianGrid strokeDasharray="3 3" stroke="var(--line)" />
<XAxis
dataKey={xAxisKey}
stroke="#6e6e6e"
stroke="var(--ink-muted)"
fontSize={12}
tickLine={false}
axisLine={false}
/>
<YAxis
stroke="#6e6e6e"
stroke="var(--ink-muted)"
fontSize={12}
tickLine={false}
axisLine={false}
@@ -98,7 +99,7 @@ export function ChartCard({
<Tooltip
contentStyle={{
backgroundColor: '#fff',
border: '1px solid #f2d9a2',
border: '1px solid var(--line)',
borderRadius: '8px',
fontSize: '12px'
}}
@@ -106,9 +107,9 @@ export function ChartCard({
<Line
type="monotone"
dataKey={dataKey}
stroke="#cc8d00"
stroke="var(--gold)"
strokeWidth={2}
dot={{ fill: '#cc8d00', r: 4 }}
dot={{ fill: 'var(--gold)', r: 4 }}
activeDot={{ r: 6 }}
/>
</LineChart>
@@ -118,20 +119,20 @@ export function ChartCard({
<AreaChart data={data}>
<defs>
<linearGradient id="colorValue" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#cc8d00" stopOpacity={0.8}/>
<stop offset="95%" stopColor="#cc8d00" stopOpacity={0}/>
<stop offset="5%" stopColor="var(--gold)" stopOpacity={0.8}/>
<stop offset="95%" stopColor="var(--gold)" stopOpacity={0}/>
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" stroke="#f2d9a2" opacity={0.5} />
<CartesianGrid strokeDasharray="3 3" stroke="var(--line)" />
<XAxis
dataKey={xAxisKey}
stroke="#6e6e6e"
stroke="var(--ink-muted)"
fontSize={12}
tickLine={false}
axisLine={false}
/>
<YAxis
stroke="#6e6e6e"
stroke="var(--ink-muted)"
fontSize={12}
tickLine={false}
axisLine={false}
@@ -140,7 +141,7 @@ export function ChartCard({
<Tooltip
contentStyle={{
backgroundColor: '#fff',
border: '1px solid #f2d9a2',
border: '1px solid var(--line)',
borderRadius: '8px',
fontSize: '12px'
}}
@@ -148,7 +149,7 @@ export function ChartCard({
<Area
type="monotone"
dataKey={dataKey}
stroke="#cc8d00"
stroke="var(--gold)"
strokeWidth={2}
fillOpacity={1}
fill="url(#colorValue)"
@@ -165,7 +166,7 @@ export function ChartCard({
labelLine={false}
label={({ name, percent }) => `${name} (${((percent || 0) * 100).toFixed(0)}%)`}
outerRadius={100}
fill="#8884d8"
fill="var(--gold)"
dataKey={dataKey}
>
{data.map((entry, index) => (
@@ -175,7 +176,7 @@ export function ChartCard({
<Tooltip
contentStyle={{
backgroundColor: '#fff',
border: '1px solid #f2d9a2',
border: '1px solid var(--line)',
borderRadius: '8px',
fontSize: '12px'
}}
+3 -3
View File
@@ -31,7 +31,7 @@ export function MetricCard({
<CardTitle className="text-sm font-medium text-gray-600">
{title}
</CardTitle>
<Icon className="h-4 w-4 text-brand-dourado" />
<Icon className="h-4 w-4 text-gold-fill" />
</CardHeader>
<CardContent>
{loading ? (
@@ -47,8 +47,8 @@ export function MetricCard({
{change !== undefined && (
<p className={cn(
"text-xs mt-1 font-medium",
detectedTrend === 'up' && "text-brand-verde",
detectedTrend === 'down' && "text-red-500",
detectedTrend === 'up' && "text-success",
detectedTrend === 'down' && "text-danger",
detectedTrend === 'neutral' && "text-gray-500"
)}>
{change > 0 ? '+' : ''}{formatPercent(change / 100, 1)} vs. período anterior
+2 -2
View File
@@ -4,12 +4,12 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
"border-transparent bg-primary text-primary-foreground shadow hover:bg-accent-hover",
secondary:
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive:
+4 -4
View File
@@ -5,12 +5,12 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-display font-bold transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
"bg-primary text-primary-foreground shadow hover:bg-accent-hover",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
@@ -22,8 +22,8 @@ const buttonVariants = cva(
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
sm: "h-8 rounded-full px-3 text-xs",
lg: "h-10 rounded-full px-8",
icon: "h-9 w-9",
},
},
+1 -1
View File
@@ -35,7 +35,7 @@ const CardTitle = React.forwardRef<
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("font-semibold leading-none tracking-tight", className)}
className={cn("font-display font-semibold leading-none tracking-tight", className)}
{...props}
/>
))