Entre na sua conta
Acesse a memória institucional da sua equipe.
{notice &&{notice}
} diff --git a/frontend/src/index.css b/frontend/src/index.css index 1e05fa4..44e0ce7 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,39 +1,13 @@ -:root { - --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - --font-mono: 'JetBrains Mono', monospace; +/* ============================================================ + Sinapse — base e componentes + ------------------------------------------------------------ + Os tokens vivem em styles/tokens.css, que é a fonte única. + Este arquivo só define o reset, a base do documento e as classes + de componente. Não redefina cor aqui. + ============================================================ */ - /* Color Palette - Deep Slate / Indigo Cyber */ - --bg-primary: #0a0d14; - --bg-secondary: #111622; - --bg-tertiary: #182030; - --bg-card: rgba(19, 26, 42, 0.7); - --bg-card-hover: rgba(26, 35, 58, 0.85); - - --border-subtle: rgba(255, 255, 255, 0.08); - --border-active: rgba(99, 102, 241, 0.4); - - --text-primary: #f8fafc; - --text-secondary: #94a3b8; - --text-muted: #64748b; - - --accent-primary: #6366f1; - --accent-glow: rgba(99, 102, 241, 0.25); - --accent-secondary: #06b6d4; - --accent-emerald: #10b981; - --accent-amber: #f59e0b; - - --radius-sm: 8px; - --radius-md: 12px; - --radius-lg: 16px; - --radius-full: 9999px; - - --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2); - --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.35); - --shadow-glow: 0 0 24px var(--accent-glow); - - --transition-fast: 0.15s ease; - --transition-normal: 0.25s cubic-bezier(0.4, 0, 0.2, 1); -} +@import './styles/tokens.css'; +@import './styles/components.css'; .auth-shell { min-height: 100vh; display: grid; place-items: center; padding: 24px; } .auth-card { width: 100%; max-width: 440px; padding: 32px; display: grid; gap: 18px; } @@ -41,7 +15,7 @@ .auth-card p { color: var(--text-secondary); } .auth-card form { display: grid; gap: 12px; } .auth-card input { width: 100%; padding: 12px; border-radius: var(--radius-sm); border: 1px solid var(--border-subtle); background: var(--bg-secondary); color: var(--text-primary); font: inherit; } -.auth-card [role="alert"] { color: #fca5a5; } +.auth-card [role="alert"] { color: var(--ds-danger-fg); } button:focus-visible, input:focus-visible { outline: 2px solid var(--accent-secondary); outline-offset: 3px; } button:disabled { opacity: .6; cursor: wait; } @media (max-width: 900px) { header { flex-wrap: wrap; gap: 16px; } } @@ -54,20 +28,32 @@ button:disabled { opacity: .6; cursor: wait; } body { font-family: var(--font-sans); - background-color: var(--bg-primary); - color: var(--text-primary); + background-color: var(--ds-bg-app); + color: var(--ds-text); line-height: 1.6; -webkit-font-smoothing: antialiased; min-height: 100vh; + /* Gradiente da PRO4TECH (--gradient1 na folha deles). */ background-image: - radial-gradient(circle at 15% 15%, rgba(99, 102, 241, 0.12) 0%, transparent 40%), - radial-gradient(circle at 85% 85%, rgba(6, 182, 212, 0.08) 0%, transparent 45%); + radial-gradient(circle at 10% 0%, rgba(237, 106, 50, 0.08), transparent 28%), + linear-gradient(180deg, var(--ds-surface-800) 0%, var(--ds-surface-900) 100%); background-attachment: fixed; } +h1, h2, h3 { + font-family: var(--ds-font-display); + letter-spacing: -0.01em; + line-height: 1.2; +} + a { - color: inherit; + color: var(--ds-brand-500); text-decoration: none; + transition: color var(--transition-fast); +} + +a:hover { + color: var(--ds-brand-400); } button { @@ -77,87 +63,206 @@ button { outline: none; } -/* Glassmorphic Container */ +/* Foco visível em qualquer elemento navegável por teclado. */ +:focus-visible { + outline: none; + box-shadow: var(--ds-ring-focus); + border-radius: var(--ds-radius); +} + +/* --- Superfície elevada ---------------------------------- */ +/* Nome mantido por compatibilidade: a PRO4TECH não usa vidro, + então isto é um cartão opaco. */ .glass-panel { - background: var(--bg-card); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid var(--border-subtle); - border-radius: var(--radius-md); - box-shadow: var(--shadow-md); - transition: transform var(--transition-normal), border-color var(--transition-normal); + background: var(--ds-bg-subtle); + border: 1px solid var(--ds-border); + border-radius: var(--ds-radius); + box-shadow: var(--ds-shadow-sm); + transition: border-color var(--transition-normal), background var(--transition-normal); } .glass-panel:hover { - border-color: var(--border-active); + border-color: var(--ds-border-strong); } -/* Badges */ +/* --- Etiquetas ------------------------------------------- */ .badge { display: inline-flex; align-items: center; + justify-self: start; + width: fit-content; gap: 6px; - padding: 4px 10px; - border-radius: var(--radius-full); - font-size: 0.75rem; - font-weight: 600; + height: 24px; + padding: 0 12px; + border-radius: var(--ds-radius-pill); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.06em; text-transform: uppercase; - letter-spacing: 0.05em; } .badge-success { - background: rgba(16, 185, 129, 0.15); - color: #34d399; - border: 1px solid rgba(16, 185, 129, 0.3); + background: var(--ds-success-bg); + color: var(--ds-success-fg); + border: 1px solid rgba(34, 180, 88, 0.42); } .badge-info { - background: rgba(99, 102, 241, 0.15); - color: #818cf8; - border: 1px solid rgba(99, 102, 241, 0.3); + background: var(--ds-info-bg); + color: var(--ds-info-fg); + border: 1px solid rgba(64, 151, 255, 0.42); } .badge-warning { - background: rgba(245, 158, 11, 0.15); - color: #fbbf24; - border: 1px solid rgba(245, 158, 11, 0.3); + background: var(--ds-warning-bg); + color: var(--ds-warning-fg); + border: 1px solid rgba(200, 139, 0, 0.42); +} + +.badge-brand { + background: var(--ds-ai-bg); + color: var(--ds-brand-400); + border: 1px solid var(--border-active); } -/* Buttons */ +.badge-danger { + background: var(--ds-danger-bg); + color: var(--ds-danger-fg); + border: 1px solid rgba(240, 99, 93, 0.42); +} + +/* --- Botões ---------------------------------------------- */ +/* Um só primário por tela. O gradiente é exclusivo dele. */ .btn-primary { - background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%); - color: #fff; - padding: 10px 20px; - border-radius: var(--radius-sm); - font-weight: 500; + background: var(--ds-brand-gradient); + color: var(--ds-on-brand); + height: var(--ds-control-h); + padding: 0 18px; + border-radius: var(--ds-radius); + font-size: 14px; + font-weight: 600; display: inline-flex; align-items: center; + justify-content: center; gap: 8px; - box-shadow: var(--shadow-sm); transition: all var(--transition-normal); } .btn-primary:hover { - background: linear-gradient(135deg, #818cf8 0%, #6366f1 100%); - box-shadow: var(--shadow-glow); - transform: translateY(-1px); + background: linear-gradient(135deg, var(--ds-brand-300) 0%, var(--ds-brand-400) 100%); + box-shadow: var(--ds-shadow-sm); +} + +.btn-primary:disabled { + background: var(--ds-bg-subtle); + color: var(--ds-text-muted); + border: 1px solid var(--ds-border); + cursor: not-allowed; } .btn-secondary { - background: var(--bg-tertiary); - color: var(--text-secondary); - border: 1px solid var(--border-subtle); - padding: 10px 18px; - border-radius: var(--radius-sm); + background: var(--ds-bg-subtle); + color: var(--ds-text); + border: 1px solid var(--ds-border-strong); + height: var(--ds-control-h); + padding: 0 18px; + border-radius: var(--ds-radius); + font-size: 14px; font-weight: 500; display: inline-flex; align-items: center; + justify-content: center; gap: 8px; transition: all var(--transition-normal); } .btn-secondary:hover { - background: var(--bg-card-hover); - color: var(--text-primary); - border-color: var(--border-active); + background: var(--ds-bg-hover); + color: var(--ds-text-strong); + border-color: rgba(196, 199, 204, 0.38); +} + +.btn-ghost { + background: transparent; + color: var(--ds-text-secondary); + height: var(--ds-control-h); + padding: 0 14px; + border-radius: var(--ds-radius); + font-size: 14px; + font-weight: 500; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + transition: all var(--transition-normal); +} + +.btn-ghost:hover { + background: rgba(196, 199, 204, 0.07); + color: var(--ds-text-strong); +} + +.btn-danger { + background: var(--ds-danger-bg); + color: var(--ds-danger-fg); + border: 1px solid rgba(240, 99, 93, 0.42); + height: var(--ds-control-h); + padding: 0 18px; + border-radius: var(--ds-radius); + font-size: 14px; + font-weight: 600; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + transition: all var(--transition-normal); +} + +.btn-danger:hover { + background: #5E2321; /* danger-bg elevado */ + color: var(--ds-text-strong); + border-color: rgba(240, 99, 93, 0.62); +} + +/* --- Campos ---------------------------------------------- */ +.campo { + height: var(--ds-control-h); + width: 100%; + padding: 0 14px; + border-radius: var(--ds-radius); + background: var(--ds-bg-app); + border: 1px solid var(--ds-border-strong); + color: var(--ds-text); + font-family: inherit; + font-size: 14px; + transition: border-color var(--transition-fast), box-shadow var(--transition-fast); +} + +.campo::placeholder { + color: var(--ds-text-disabled); +} + +.campo:focus { + outline: none; + border-color: var(--ds-brand-500); + box-shadow: var(--ds-ring-focus); + color: var(--ds-text-strong); +} + +.campo[aria-invalid='true'] { + border-color: var(--ds-danger-fg); +} + +.campo:disabled { + background: var(--ds-bg-app); + border-color: rgba(196, 199, 204, 0.09); + color: var(--ds-text-disabled); + cursor: not-allowed; +} + +@media (prefers-reduced-motion: reduce) { + * { + transition-duration: 0.01ms !important; + animation-duration: 0.01ms !important; + } } diff --git a/frontend/src/projects/projects.css b/frontend/src/projects/projects.css index 212d147..6cde710 100644 --- a/frontend/src/projects/projects.css +++ b/frontend/src/projects/projects.css @@ -2,7 +2,7 @@ .projects-heading { display: flex; align-items: center; justify-content: space-between; gap: 20px; } .projects-heading h2 { font-size: 1.8rem; } .projects-heading p, .project-card p, .projects-state p, .project-form > p { color: var(--text-secondary); } -.projects-eyebrow { color: var(--accent-secondary) !important; font-size: .8rem; } +.projects-eyebrow { color: var(--ds-text-muted) !important; font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; } .projects-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr)); gap: 20px; } .project-card { padding: 24px; display: grid; gap: 12px; align-content: start; overflow-wrap: anywhere; } .project-card .badge, .project-card button { justify-self: start; } @@ -16,7 +16,7 @@ .project-field input, .project-field textarea { width: 100%; background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: 12px; font: inherit; } .project-field textarea { resize: vertical; } .project-field textarea:focus-visible { outline: 2px solid var(--accent-secondary); outline-offset: 3px; } -.project-field [aria-invalid="true"] { border-color: #fca5a5; } -.projects-page [role="alert"] { color: #fca5a5; } +.project-field [aria-invalid="true"] { border-color: var(--ds-danger-fg); } +.projects-page [role="alert"] { color: var(--ds-danger-fg); } .project-actions { display: flex; flex-wrap: wrap; gap: 12px; } @media (max-width: 900px) { .projects-heading { align-items: flex-start; flex-direction: column; } header > div { flex-wrap: wrap; } } diff --git a/frontend/src/styles/components.css b/frontend/src/styles/components.css index e92b47f..551d545 100644 --- a/frontend/src/styles/components.css +++ b/frontend/src/styles/components.css @@ -3,7 +3,7 @@ .ds-button { min-height: 40px; padding: 0 var(--ds-space-4); - border-radius: var(--ds-radius-sm); + border-radius: var(--ds-radius); border: 1px solid transparent; font: 600 14px/20px var(--ds-font-sans); display: inline-flex; @@ -23,7 +23,7 @@ .ds-button--primary { background: var(--ds-action); - color: var(--ds-neutral-0); + color: var(--ds-on-brand); } .ds-button--primary:hover { background: var(--ds-action-hover); } @@ -69,7 +69,7 @@ .ds-textarea { width: 100%; border: 1px solid var(--ds-border-strong); - border-radius: var(--ds-radius-sm); + border-radius: var(--ds-radius); background: var(--ds-bg-surface); color: var(--ds-text); padding: 10px 12px; @@ -84,7 +84,7 @@ background: var(--ds-bg-surface); color: var(--ds-text); border: 1px solid var(--ds-border); - border-radius: var(--ds-radius-md); + border-radius: var(--ds-radius); box-shadow: var(--ds-shadow-sm); } @@ -111,7 +111,7 @@ height: 8px; overflow: hidden; border-radius: var(--ds-radius-pill); - background: var(--ds-neutral-200); + background: var(--ds-track); } .ds-progress > span { display: block; @@ -123,9 +123,9 @@ .ds-ai-suggestion { border: 1px solid color-mix(in srgb, var(--ds-ai-fg) 25%, transparent); border-left: 4px solid var(--ds-ai-fg); - border-radius: var(--ds-radius-md); + border-radius: var(--ds-radius); background: var(--ds-ai-bg); - color: var(--ds-neutral-900); + color: var(--ds-text); padding: var(--ds-space-4); } diff --git a/frontend/src/styles/tokens.css b/frontend/src/styles/tokens.css index b1bf139..4d1beaf 100644 --- a/frontend/src/styles/tokens.css +++ b/frontend/src/styles/tokens.css @@ -1,52 +1,81 @@ +/* ============================================================ + Sinapse — tokens de interface + ------------------------------------------------------------ + Origem: identidade visual da PRO4TECH. Cor, tipografia, raio e + sombra foram lidos da folha de estilo do site do cliente + (assets/css/main.css), não aproximados a partir de captura de tela. + + As quatro cores semânticas são a única exceção: a marca não + publica cores de estado. Foram derivadas do laranja #ED6A32 em + oklch — mesma luminosidade (0.676) e croma (0.176), variando só o + matiz — para conviverem com o acento sem competir com ele. + + Design system e protótipo: docs/design/ + ============================================================ */ + :root { - /* PRO4TECH / Sinapse product palette */ - --ds-brand-950: #07111f; - --ds-brand-900: #0b1626; - --ds-brand-800: #102238; - --ds-brand-700: #173653; - --ds-brand-500: #0aa7c8; - --ds-brand-400: #24bedb; - --ds-brand-300: #71d7e8; - --ds-brand-100: #ddf7fb; + /* --- Marca ---------------------------------------------- */ + --ds-brand-600: #D3754D; + --ds-brand-500: #ED6A32; /* o acento; usar com parcimônia */ + --ds-brand-400: #F1885B; + --ds-brand-300: #F4A684; + --ds-brand-200: #F8C3AD; + --ds-brand-100: #FBE1D6; + --ds-brand-gradient: linear-gradient(135deg, #F1885B 0%, #ED6A32 100%); + /* Branco sobre o laranja dá 3,13:1 e reprova na WCAG AA. Texto escuro + sobre o mesmo laranja dá 5,67:1, então a marca fica intacta. */ + --ds-on-brand: #16181D; + + /* --- Superfícies, do fundo da página ao cartão elevado --- */ + --ds-surface-900: #0B0D10; + --ds-surface-800: #111827; + --ds-surface-700: #171A21; + --ds-surface-600: #1D212A; - --ds-neutral-0: #ffffff; - --ds-neutral-50: #f8fafc; - --ds-neutral-100: #f1f5f9; - --ds-neutral-200: #e2e8f0; - --ds-neutral-300: #cbd5e1; - --ds-neutral-400: #94a3b8; - --ds-neutral-500: #64748b; - --ds-neutral-600: #475569; - --ds-neutral-700: #334155; - --ds-neutral-800: #1e293b; - --ds-neutral-900: #0f172a; + /* --- Rampa neutra da marca ------------------------------ */ + --ds-neutral-0: #FFFFFF; + --ds-neutral-100: #E5E7EB; + --ds-neutral-300: #C4C7CC; + --ds-neutral-400: #A6AAB3; + --ds-neutral-500: #898E99; + --ds-neutral-600: #6B7280; + --ds-neutral-700: #4B4F57; - --ds-success-bg: #e8f7ef; - --ds-success-fg: #157347; - --ds-info-bg: #e8f6fa; - --ds-info-fg: #087e99; - --ds-warning-bg: #fff7e6; - --ds-warning-fg: #9a6700; - --ds-danger-bg: #fdecec; - --ds-danger-fg: #b42318; - --ds-ai-bg: #eef2ff; - --ds-ai-fg: #4f46e5; + /* --- Semânticas (derivadas, ver cabeçalho) --------------- */ + --ds-success-fg: #22B458; + --ds-success-bg: #0D371A; + --ds-warning-fg: #C88B00; + --ds-warning-bg: #3E2A00; + --ds-danger-fg: #F0635D; + --ds-danger-bg: #4B1D1B; + --ds-info-fg: #4097FF; + --ds-info-bg: #132E50; + --ds-ai-fg: var(--ds-brand-400); + --ds-ai-bg: #4A200F; - --ds-bg-app: var(--ds-neutral-50); - --ds-bg-surface: var(--ds-neutral-0); - --ds-bg-subtle: var(--ds-neutral-100); - --ds-border: var(--ds-neutral-200); - --ds-border-strong: var(--ds-neutral-300); - --ds-text: var(--ds-neutral-900); - --ds-text-secondary: var(--ds-neutral-600); - --ds-text-muted: var(--ds-neutral-500); + /* --- Papéis --------------------------------------------- */ + --ds-bg-app: var(--ds-surface-900); + --ds-bg-surface: var(--ds-surface-800); + --ds-bg-subtle: var(--ds-surface-700); + --ds-bg-hover: var(--ds-surface-600); + --ds-border: rgba(196, 199, 204, 0.14); + --ds-border-strong: rgba(196, 199, 204, 0.22); + --ds-track: rgba(196, 199, 204, 0.12); + --ds-text-strong: var(--ds-neutral-0); + --ds-text: var(--ds-neutral-100); + --ds-text-secondary: var(--ds-neutral-400); + --ds-text-muted: var(--ds-neutral-600); + --ds-text-disabled: var(--ds-neutral-700); --ds-action: var(--ds-brand-500); --ds-action-hover: var(--ds-brand-400); - --ds-focus: var(--ds-brand-300); + --ds-focus: rgba(237, 106, 50, 0.22); + /* --- Tipografia ----------------------------------------- */ + --ds-font-display: 'Public Sans', Inter, ui-sans-serif, system-ui, sans-serif; --ds-font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --ds-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace; + /* --- Espaçamento ---------------------------------------- */ --ds-space-1: 4px; --ds-space-2: 8px; --ds-space-3: 12px; @@ -58,49 +87,52 @@ --ds-space-12: 48px; --ds-space-16: 64px; - --ds-radius-sm: 8px; - --ds-radius-md: 12px; - --ds-radius-lg: 16px; - --ds-radius-pill: 999px; + /* --- Forma ---------------------------------------------- */ + /* A marca tem um raio só. Pílula apenas em etiqueta. */ + --ds-radius: 10px; + --ds-radius-pill: 9999px; - --ds-shadow-sm: 0 1px 2px rgba(15, 23, 42, .06); - --ds-shadow-md: 0 8px 24px rgba(15, 23, 42, .08); + /* --- Profundidade --------------------------------------- */ + --ds-shadow-sm: 0px 1px 14px 0px rgba(0, 0, 0, 0.13); + --ds-shadow-md: 0px 1px 14px 0px rgba(0, 0, 0, 0.13); + --ds-ring-focus: 0 0 0 3px var(--ds-focus); + + /* --- Altura de controle --------------------------------- */ + --ds-control-h: 40px; + --ds-touch-h: 44px; --ds-transition-fast: 120ms ease; --ds-transition-normal: 180ms ease; - /* aliases for the current frontend */ + /* ------------------------------------------------------------ + Compatibilidade — nomes consumidos por Auth.tsx, Projects.tsx e + App.tsx. Novo código usa os --ds-* acima. Remover quando as telas + forem migradas. + ------------------------------------------------------------ */ + --font-sans: var(--ds-font-sans); + --font-mono: var(--ds-font-mono); --bg-primary: var(--ds-bg-app); --bg-secondary: var(--ds-bg-surface); --bg-tertiary: var(--ds-bg-subtle); - --bg-card: var(--ds-bg-surface); - --bg-card-hover: var(--ds-neutral-50); + --bg-card: var(--ds-bg-subtle); + --bg-card-hover: var(--ds-bg-hover); --border-subtle: var(--ds-border); - --border-active: var(--ds-brand-300); + --border-active: rgba(237, 106, 50, 0.42); --text-primary: var(--ds-text); --text-secondary: var(--ds-text-secondary); --text-muted: var(--ds-text-muted); --accent-primary: var(--ds-action); - --accent-secondary: var(--ds-brand-400); + --accent-secondary: var(--ds-action-hover); + --accent-glow: var(--ds-focus); --accent-emerald: var(--ds-success-fg); --accent-amber: var(--ds-warning-fg); - --radius-sm: var(--ds-radius-sm); - --radius-md: var(--ds-radius-md); - --radius-lg: var(--ds-radius-lg); + --radius-sm: var(--ds-radius); + --radius-md: var(--ds-radius); + --radius-lg: var(--ds-radius); --radius-full: var(--ds-radius-pill); --shadow-sm: var(--ds-shadow-sm); --shadow-md: var(--ds-shadow-md); + --shadow-glow: var(--ds-ring-focus); --transition-fast: var(--ds-transition-fast); --transition-normal: var(--ds-transition-normal); } - -[data-theme="dark"] { - --ds-bg-app: var(--ds-brand-950); - --ds-bg-surface: var(--ds-brand-900); - --ds-bg-subtle: var(--ds-brand-800); - --ds-border: #22364c; - --ds-border-strong: #31506f; - --ds-text: var(--ds-neutral-50); - --ds-text-secondary: var(--ds-neutral-300); - --ds-text-muted: var(--ds-neutral-400); -}