# 🎨 TASK MANAGER - Design System & Guia de Interface ## 🌈 Paleta de Cores ### Cores Principais - **Primary (Azul)**: `#2563EB` - Ações principais, links, seleção - **Primary Dark**: `#1D4ED8` - Estados hover/ativo - **Primary Light**: `#DBEAFE` - Backgrounds, estados desabilitados - **White**: `#FFFFFF` - Backgrounds principal - **Black**: `#000000` - Texto principal, contrastes fortes - **Gray 50**: `#F9FAFB` - Backgrounds secundários - **Gray 100**: `#F3F4F6` - Borders leves - **Gray 200**: `#E5E7EB` - Borders padrão - **Gray 400**: `#9CA3AF` - Texto secundário, placeholders - **Gray 600**: `#4B5563` - Texto terciário ### Cores de Status - **Success**: `#10B981` - Tarefas concluídas - **Warning**: `#F59E0B` - Alertas - **Error**: `#EF4444` - Erros, deletar - **Info**: `#06B6D4` - Informações --- ## 🔤 Tipografia (Google Fonts) ### Fonte Principal: **Inter** - Link: https://fonts.google.com/specimen/Inter - Uso: Corpo de texto, UI, labels ### Fonte Secundária: **Poppins** - Link: https://fonts.google.com/specimen/Poppins - Uso: Títulos, headings, destaque ### Escala Tipográfica | Nome | Tamanho | Weight | Line Height | Letra-espaçamento | Uso | |------|---------|--------|-------------|------------------|-----| | **H1** | 32px | 700 (Bold) | 40px | -0.5px | Títulos principais | | **H2** | 24px | 700 (Bold) | 32px | -0.3px | Subtítulos | | **H3** | 18px | 600 (SemiBold) | 28px | -0.2px | Seções | | **Body Large** | 16px | 400 (Regular) | 24px | 0px | Texto principal | | **Body Normal** | 14px | 400 (Regular) | 22px | 0px | Descrições | | **Body Small** | 12px | 400 (Regular) | 18px | 0.2px | Ajuda, captions | | **Label** | 12px | 600 (SemiBold) | 18px | 0.5px | Labels de campos | | **Button** | 14px | 600 (SemiBold) | 20px | 0.5px | Texto de botões | ### Importação no CSS/Next.js ```css @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@600;700&display=swap'); :root { --font-inter: 'Inter', sans-serif; --font-poppins: 'Poppins', sans-serif; } ``` --- ## 🎯 Espaçamento (8px Base) Seguindo o padrão Material Design + Tailwind, usando múltiplos de 8px: | Token | Valor | Uso | |-------|-------|-----| | **xs** | 4px | Micro-espaçamentos | | **sm** | 8px | Padding pequeno | | **md** | 12px | Padding padrão | | **lg** | 16px | Espaçamento interno | | **xl** | 24px | Separação entre elementos | | **2xl** | 32px | Separação entre seções | | **3xl** | 48px | Grandes divisores | | **4xl** | 64px | Muito grandes | ### Exemplos de Aplicação - **Padding de Botão**: 12px (vertical) × 16px (horizontal) - **Padding de Card**: 24px - **Gap entre inputs**: 16px - **Margin entre seções**: 32px --- ## 🎨 Componentes - Design System ### 1️⃣ **BOTÕES** #### Botão Primary (Padrão) ``` Tamanho: 48px altura Padding: 12px vertical × 16px horizontal Background: #2563EB Text: White, 14px Bold Border Radius: 8px Font Weight: 600 ``` **Estados:** - **Default**: Background #2563EB - **Hover**: Background #1D4ED8, Sombra leve - **Active**: Background #1D4ED8, sem sombra - **Disabled**: Background #E5E7EB, Text #9CA3AF, sem cursor #### Botão Secondary ``` Background: #F3F4F6 Text: #000000, 14px Bold Border: 1px #E5E7EB Border Radius: 8px ``` #### Botão Tertiary (Text only) ``` Background: transparent Text: #2563EB, 14px Bold Padding: 12px 16px ``` #### Botão Danger ``` Background: #EF4444 Text: White, 14px Bold Sombra: 0px 4px 12px rgba(239, 68, 68, 0.2) ``` #### Botão com Ícone ``` Spacing entre ícone e texto: 8px Ícone tamanho: 20px × 20px ``` --- ### 2️⃣ **CAMPOS DE ENTRADA (Inputs)** #### Input Padrão ``` Altura: 44px Padding: 12px 16px Border: 1px #E5E7EB Border Radius: 8px Font: Inter 14px Background: #FFFFFF ``` **Estados:** - **Default**: Border #E5E7EB, Background #FFFFFF - **Focus**: Border #2563EB (2px), Background #FFFFFF, Box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1) - **Filled**: Border #2563EB - **Error**: Border #EF4444, Background #FEF2F2 - **Disabled**: Border #E5E7EB, Background #F9FAFB, Text #9CA3AF #### Placeholder ``` Color: #9CA3AF Font Style: Regular ``` #### Label ``` Font: Poppins 12px SemiBold Color: #000000 Margin Bottom: 8px Required indicator (*): Color #EF4444 ``` #### Help Text ``` Font: Inter 12px Regular Color: #6B7280 Margin Top: 4px ``` #### Error Message ``` Font: Inter 12px Regular Color: #EF4444 Icon: 16px × 16px (⚠️) Margin Top: 4px ``` --- ### 3️⃣ **CARDS** ``` Background: #FFFFFF Border: 1px #E5E7EB Border Radius: 12px Padding: 24px Box Shadow: 0px 1px 3px rgba(0, 0, 0, 0.1) ``` **Hover (Interactive):** ``` Box Shadow: 0px 4px 12px rgba(0, 0, 0, 0.08) Transition: 150ms ``` #### Task Card ``` Padding: 16px Border Radius: 12px Background: #FFFFFF Border: 1px #E5E7EB Estrutura: ├── Checkbox (20px × 20px) ├── Conteúdo (Flex: 1) │ ├── Título: 14px Bold, #000000 │ └── Descrição: 13px Regular, #6B7280 └── Menu/Delete: 24px × 24px (Right) Spacing: 12px entre elementos ``` --- ### 4️⃣ **CHECKBOX & RADIO** #### Checkbox ``` Tamanho: 20px × 20px Border: 2px #E5E7EB Border Radius: 4px Background: #FFFFFF Padding: 2px (interno) ``` **Estados:** - **Unchecked**: Border #E5E7EB, Background #FFFFFF - **Checked**: Border #2563EB, Background #2563EB, Ícone ✓ branco - **Focus**: Box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1) - **Disabled**: Border #E5E7EB, Background #F3F4F6 --- ### 5️⃣ **TABS** ``` Height: 48px Font: Inter 14px SemiBold Color: #6B7280 (inactive), #2563EB (active) Border Bottom: 2px #2563EB (active) Padding: 16px horizontal ``` --- ### 6️⃣ **MODALS/DIALOGS** ``` Background: #FFFFFF Border Radius: 16px Padding: 32px Width: 90% (mobile), 520px (desktop) Max Height: 90vh Box Shadow: 0px 20px 25px rgba(0, 0, 0, 0.15) Overlay: rgba(0, 0, 0, 0.5) ``` **Estrutura:** ``` ├── Header │ ├── Título: H2 │ └── Close button: 24px (top right) ├── Content │ └── Padding: 24px 0 └── Footer (Actions) ├── Button Secondary (Cancel): Left └── Button Primary (Confirm): Right └── Spacing: 12px entre botões ``` --- ### 7️⃣ **ÍCONES (Google Icons)** Link: https://fonts.google.com/icons **Tamanhos Padrão:** - **Small**: 16px - Lado de inputs, help text - **Normal**: 20px - Ícones em botões, menus - **Large**: 24px - Ícones principais, headers - **XL**: 32px - Ícones de estado vazio, sucesso **Cor Principal**: #2563EB **Cor Secundária**: #6B7280 **Cor Erro**: #EF4444 **Ícones Recomendados:** - check_circle (Concluído) - radio_button_unchecked (Não concluído) - delete (Deletar) - edit (Editar) - close (Fechar) - menu (Menu) - search (Buscar) - add (Adicionar) - logout (Sair) - login (Entrar) - person (Perfil) - error (Erro) - warning (Aviso) - info (Info) --- ## 📱 **NEXT.JS - Estrutura de Componentes** ### Diretório ``` frontend-next/ ├── src/ │ ├── components/ │ │ ├── ui/ │ │ │ ├── Button.tsx │ │ │ ├── Input.tsx │ │ │ ├── Card.tsx │ │ │ ├── Checkbox.tsx │ │ │ ├── Modal.tsx │ │ │ ├── Toast.tsx │ │ │ └── Spinner.tsx │ │ ├── forms/ │ │ │ ├── TaskForm.tsx │ │ │ ├── LoginForm.tsx │ │ │ └── SignupForm.tsx │ │ ├── tasks/ │ │ │ ├── TaskItem.tsx │ │ │ ├── TaskList.tsx │ │ │ └── TaskFilters.tsx │ │ ├── layout/ │ │ │ ├── Header.tsx │ │ │ ├── Sidebar.tsx │ │ │ └── Footer.tsx │ │ └── common/ │ │ ├── EmptyState.tsx │ │ └── LoadingState.tsx │ ├── lib/ │ │ ├── styles/ │ │ │ ├── colors.ts │ │ │ ├── spacing.ts │ │ │ ├── typography.ts │ │ │ └── shadows.ts │ │ └── utils.ts │ ├── app/ │ │ ├── globals.css │ │ ├── layout.tsx │ │ ├── page.tsx │ │ ├── (auth)/ │ │ │ ├── login/page.tsx │ │ │ └── signup/page.tsx │ │ └── (dashboard)/ │ │ └── tasks/page.tsx │ └── styles/ │ └── tailwind.config.ts ``` ### Configuração Tailwind (tailwind.config.ts) ```typescript import type { Config } from 'tailwindcss' export default { content: [ './src/pages/**/*.{js,ts,jsx,tsx,mdx}', './src/components/**/*.{js,ts,jsx,tsx,mdx}', './src/app/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { colors: { primary: { DEFAULT: '#2563EB', dark: '#1D4ED8', light: '#DBEAFE', }, gray: { 50: '#F9FAFB', 100: '#F3F4F6', 200: '#E5E7EB', 400: '#9CA3AF', 600: '#4B5563', }, status: { success: '#10B981', warning: '#F59E0B', error: '#EF4444', info: '#06B6D4', }, }, fontFamily: { inter: ['var(--font-inter)', 'sans-serif'], poppins: ['var(--font-poppins)', 'sans-serif'], }, fontSize: { 'h1': ['32px', { lineHeight: '40px', fontWeight: '700', letterSpacing: '-0.5px' }], 'h2': ['24px', { lineHeight: '32px', fontWeight: '700', letterSpacing: '-0.3px' }], 'h3': ['18px', { lineHeight: '28px', fontWeight: '600', letterSpacing: '-0.2px' }], 'body-lg': ['16px', { lineHeight: '24px', fontWeight: '400' }], 'body': ['14px', { lineHeight: '22px', fontWeight: '400' }], 'body-sm': ['12px', { lineHeight: '18px', fontWeight: '400', letterSpacing: '0.2px' }], 'label': ['12px', { lineHeight: '18px', fontWeight: '600', letterSpacing: '0.5px' }], 'btn': ['14px', { lineHeight: '20px', fontWeight: '600', letterSpacing: '0.5px' }], }, spacing: { 'xs': '4px', 'sm': '8px', 'md': '12px', 'lg': '16px', 'xl': '24px', '2xl': '32px', '3xl': '48px', '4xl': '64px', }, borderRadius: { 'sm': '4px', 'md': '8px', 'lg': '12px', 'xl': '16px', }, boxShadow: { 'sm': '0px 1px 3px rgba(0, 0, 0, 0.1)', 'md': '0px 4px 12px rgba(0, 0, 0, 0.08)', 'lg': '0px 20px 25px rgba(0, 0, 0, 0.15)', 'focus': '0 0 0 3px rgba(37, 99, 235, 0.1)', }, }, }, plugins: [], } satisfies Config ``` --- ## 🚀 **FLUTTER - Design System** ### Diretório ``` mobile/ ├── lib/ │ ├── config/ │ │ ├── theme.dart │ │ ├── colors.dart │ │ ├── typography.dart │ │ └── spacing.dart │ ├── widgets/ │ │ ├── buttons/ │ │ │ ├── primary_button.dart │ │ │ ├── secondary_button.dart │ │ │ └── tertiary_button.dart │ │ ├── inputs/ │ │ │ ├── text_input.dart │ │ │ ├── checkbox_input.dart │ │ │ └── form_field.dart │ │ ├── cards/ │ │ │ ├── task_card.dart │ │ │ └── card.dart │ │ ├── common/ │ │ │ ├── modal.dart │ │ │ ├── empty_state.dart │ │ │ └── loading_state.dart │ │ └── app/ │ │ ├── app_bar.dart │ │ └── bottom_nav.dart │ ├── screens/ │ │ ├── auth/ │ │ │ ├── login_screen.dart │ │ │ └── signup_screen.dart │ │ ├── tasks/ │ │ │ ├── tasks_screen.dart │ │ │ ├── task_detail_screen.dart │ │ │ └── create_task_screen.dart │ │ └── profile/ │ │ └── profile_screen.dart │ └── main.dart ``` ### Colors (colors.dart) ```dart abstract class AppColors { // Primary static const Color primary = Color(0xFF2563EB); static const Color primaryDark = Color(0xFF1D4ED8); static const Color primaryLight = Color(0xFFDBEAFE); // Base static const Color white = Color(0xFFFFFFFF); static const Color black = Color(0xFF000000); // Gray static const Color gray50 = Color(0xFFF9FAFB); static const Color gray100 = Color(0xFFF3F4F6); static const Color gray200 = Color(0xFFE5E7EB); static const Color gray400 = Color(0xFF9CA3AF); static const Color gray600 = Color(0xFF4B5563); // Status static const Color success = Color(0xFF10B981); static const Color warning = Color(0xFFF59E0B); static const Color error = Color(0xFFEF4444); static const Color info = Color(0xFF06B6D4); } ``` ### Theme (theme.dart) ```dart import 'package:flutter/material.dart'; import 'colors.dart'; final ThemeData appTheme = ThemeData( useMaterial3: true, colorScheme: ColorScheme( brightness: Brightness.light, primary: AppColors.primary, onPrimary: AppColors.white, secondary: AppColors.gray600, onSecondary: AppColors.white, error: AppColors.error, onError: AppColors.white, background: AppColors.white, onBackground: AppColors.black, surface: AppColors.white, onSurface: AppColors.black, ), fontFamily: 'Inter', textTheme: TextTheme( displayLarge: TextStyle( fontSize: 32, fontWeight: FontWeight.w700, letterSpacing: -0.5, fontFamily: 'Poppins', ), displayMedium: TextStyle( fontSize: 24, fontWeight: FontWeight.w700, letterSpacing: -0.3, fontFamily: 'Poppins', ), headlineSmall: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, letterSpacing: -0.2, fontFamily: 'Poppins', ), bodyLarge: TextStyle( fontSize: 16, fontWeight: FontWeight.w400, height: 1.5, ), bodyMedium: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, height: 1.57, ), bodySmall: TextStyle( fontSize: 12, fontWeight: FontWeight.w400, letterSpacing: 0.2, height: 1.5, ), labelMedium: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, letterSpacing: 0.5, ), ), ); ``` ### Spacing (spacing.dart) ```dart abstract class AppSpacing { static const double xs = 4.0; static const double sm = 8.0; static const double md = 12.0; static const double lg = 16.0; static const double xl = 24.0; static const double xxl = 32.0; static const double xxxl = 48.0; static const double xxxxl = 64.0; } ``` ### Exemplo de Componente - Primary Button ```dart class PrimaryButton extends StatelessWidget { final String label; final VoidCallback onPressed; final bool isLoading; final bool isEnabled; final IconData? icon; const PrimaryButton({ required this.label, required this.onPressed, this.isLoading = false, this.isEnabled = true, this.icon, }); @override Widget build(BuildContext context) { return ElevatedButton( onPressed: isEnabled && !isLoading ? onPressed : null, style: ElevatedButton.styleFrom( backgroundColor: AppColors.primary, disabledBackgroundColor: AppColors.gray200, padding: EdgeInsets.symmetric( vertical: AppSpacing.md, horizontal: AppSpacing.lg, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 0, ), child: isLoading ? SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( isEnabled ? AppColors.white : AppColors.gray400, ), ), ) : Row( mainAxisSize: MainAxisSize.min, children: [ if (icon != null) ...[ Icon(icon, size: 20), SizedBox(width: AppSpacing.sm), ], Text(label), ], ), ); } } ``` --- ## 🎯 **PADRÕES DE LAYOUT** ### Responsividade Next.js ``` Mobile: < 640px (default) Tablet: 640px - 1024px Desktop: > 1024px ``` ### Breakpoints (Tailwind) ```typescript sm: '640px' md: '768px' lg: '1024px' xl: '1280px' 2xl: '1536px' ``` ### Safe Area (Flutter) ```dart Scaffold( body: SafeArea( child: SingleChildScrollView( padding: EdgeInsets.all(AppSpacing.lg), child: YourContent(), ), ), ) ``` --- ## 📐 **ANIMAÇÕES & TRANSIÇÕES** ### Next.js (Tailwind) ``` Duration padrão: 150ms Easing: cubic-bezier(0.4, 0, 0.2, 1) Propriedades: transform, opacity, color, box-shadow ``` **Exemplo:** ```css .button { @apply transition-all duration-150 ease-in-out; } .button:hover { @apply scale-105 shadow-md; } ``` ### Flutter ```dart Duration animationDuration = Duration(milliseconds: 150); Curve animationCurve = Curves.easeInOut; ``` --- ## ✅ **ACESSIBILIDADE** ### Contraste de Cores (WCAG AA) - Ratio mínimo: 4.5:1 para textos normais - Ratio mínimo: 3:1 para textos grandes ### Next.js - Usar `