Nexo UI
OP7Nexo Design System v1.0

Nexo UI

shadcn/ui + Inter · #006EFF ação · Navy estrutura

Cores

Componente

Paleta oficial OP7

Primárias

Primary#006EFF
Navy#00214d
Navy Escuro#000533
Destructive#c80010
Gradiente Primário #006EFF → #000533
Gradiente Urgência #c80010 → #ff6332
/* CSS Variables */
--primary: #006EFF;
--navy: #00214d;
--destructive: #c80010;
--warning: #ff6332;
--success: #0fa856;

/* Tailwind */
bg-primary text-primary-foreground
bg-[#00214d] text-white
border-border bg-card

Tipografia

Componente

Inter — fonte principal do sistema

Micro 11px — timestamps/metadados

Label 12px — help text

Body 14px — padrão do sistema

Base 16px — parágrafos

Subtitle 18px — subtítulo

KPI 20px — valores

Page Title 24px

Section Title 30px

Pesos: 400 corpo · 500 labels/botões · 600 títulos

const inter = Inter({
  subsets: ['latin'],
  variable: '--font-sans',
})

// Uso:
// text-sm → 14px padrão
// text-xl font-medium → KPI
// text-2xl font-semibold → Título de página

Ícones

Componente

lucide-react — sempre

Search
X
ChevronsUpDown
Plus
Ellipsis
Funnel
Calendar
Moon
Sun
import { Search, X, Plus } from "lucide-react"
// size-4 (16px) padrão em botões
// size-5 (20px) avulso
// size-3 (12px) compacto

Botões

Componente

5 variantes × 4 tamanhos

Variantes

Tamanhos

Estados

<Button variant="default" size="default">Salvar</Button>
<Button variant="outline">Cancelar</Button>
<Button variant="destructive">Excluir</Button>
<Button variant="ghost" size="icon-sm"><X /></Button>

Toggle

Componente

Botão liga/desliga

Badges

Componente

Status e destaques

DefaultSecondaryDestructiveOutlineUrgente
<Badge>Ativo</Badge>
<Badge variant="destructive">Bloqueado</Badge>
<Badge variant="outline">Rascunho</Badge>
{/* Badge urgente */}
<Badge className="bg-gradient-urgent text-white">Urgente</Badge>

Cards

Componente

Superfície flat — bg-card + border + shadow-sm

Card Padrão
Com header e footer

Conteúdo do card.

Receita

R$ 45.200

+12% vs mês anterior

Taxa Conversão

3,2%

x
<Card>
  <CardHeader><CardTitle>Título</CardTitle></CardHeader>
  <CardContent>Conteúdo</CardContent>
  <CardFooter>Ações</CardFooter>
</Card>

{/* KPI Card */}
<div className="rounded-xl border bg-card p-4">
  <p className="text-xs uppercase tracking-wider text-muted-foreground">Label</p>
  <p className="text-xl font-medium mt-1">Valor</p>
</div>

Avatar

Componente

Foto ou iniciais

RCRMOP

Tabela

Componente

Data Table shadcn

Usuários

5 registros

NomeEmailFunçãoStatus
Ana Silvaana@op7nexo.comAdminAtivo
Carlos Oliveiracarlos@op7nexo.comEditorAtivo
Mariana Costamariana@op7nexo.comViewerInativo
Pedro Santospedro@op7nexo.comEditorAtivo
Julia Limajulia@op7nexo.comAdminAtivo
<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Nome</TableHead>
      <TableHead>Status</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>Ana Silva</TableCell>
      <TableCell><Badge>Ativo</Badge></TableCell>
    </TableRow>
  </TableBody>
</Table>

Formulários

Componente

Input, Textarea, Switch

Estados

<Input placeholder="Email" />
<Textarea placeholder="Bio" />
<Switch /> {/* ou defaultChecked */}

{/* Estados */}
className="ring-2 ring-primary/20 border-primary" // focus
className="border-destructive ring-2 ring-destructive/20" // erro

Select

Componente

Dropdown de seleção

<Select>
  <SelectTrigger className="w-full">
    <SelectValue placeholder="Selecione" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="1">Opção 1</SelectItem>
  </SelectContent>
</Select>

Combobox

Componente

Dropdown com campo de busca (Command + Popover)

<Popover>
  <PopoverTrigger>
    <Button variant="outline" role="combobox">
      Selecione... <ChevronsUpDown />
    </Button>
  </PopoverTrigger>
  <PopoverContent className="w-[250px] p-0">
    <Command>
      <CommandInput placeholder="Buscar..." />
      <CommandList>
        <CommandEmpty>Nada.</CommandEmpty>
        <CommandGroup heading="Opções">
          <CommandItem value="opt">
            <Check className="size-4" />
            Opção
          </CommandItem>
        </CommandGroup>
      </CommandList>
    </Command>
  </PopoverContent>
</Popover>

Switch

Componente

Toggle on/off

Radio Group

Componente

Seleção única

<RadioGroup defaultValue="opt1">
  <div className="flex items-center gap-3">
    <RadioGroupItem value="opt1" id="opt1" />
    <label htmlFor="opt1">Opção 1</label>
  </div>
</RadioGroup>

Date Picker

Componente

Seleção de data

// Usar Calendar + Popover
import { Calendar } from "@/components/ui/calendar"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"

<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline"><CalendarIcon /> Data</Button>
  </PopoverTrigger>
  <PopoverContent><Calendar mode="single" /></PopoverContent>
</Popover>

Modais (Dialog)

Componente

5 tamanhos: sm→400 · default→500 · lg→700 · xl→900 · full

<Dialog>
  <DialogContent className="sm:max-w-[500px]">
    {/* sm:400 | default:500 | lg:700 | xl:900 | full:<90vw */}
    <DialogHeader><DialogTitle>Título</DialogTitle></DialogHeader>
    <div>Conteúdo</div>
    <DialogFooter>Ações</DialogFooter>
  </DialogContent>
</Dialog>

{/* NUNCA altura fixa. overflow-y-auto + max-h-[85vh] */}

Sheet

Componente

Painel lateral

<Sheet>
  <SheetTrigger asChild><Button>Abrir</Button></SheetTrigger>
  <SheetContent>
    <SheetHeader><SheetTitle>Título</SheetTitle></SheetHeader>
    <div>Conteúdo</div>
  </SheetContent>
</Sheet>
{/* side: "right" | "left" | "top" | "bottom" */}

Progresso

Componente

Barra de progresso

x
x
x

Skeleton

Componente

Loading state

Tooltip

Componente

Dica ao passar o mouse

{/* Envolver em TooltipProvider uma vez no layout */}
<Tooltip>
  <TooltipTrigger asChild><Button>Hover</Button></TooltipTrigger>
  <TooltipContent><p>Dica</p></TooltipContent>
</Tooltip>

Toast

Componente

Notificações (Sonner)

// Toaster no layout
import { Toaster } from "@/components/ui/sonner"
<Toaster />

// Uso
import { toast } from "sonner"
toast.success("Salvo com sucesso!")
toast.error("Falha ao salvar")

Empty State

Componente

Estado vazio padrão

Nenhum resultado encontrado

Tente ajustar os filtros ou criar um novo registro.

<div className="p-12 text-center">
  <h3 className="font-medium">Nenhum resultado</h3>
  <p className="text-sm text-muted-foreground">Ajuste os filtros</p>
  <Button className="mt-4" size="sm"><Plus /> Novo</Button>
</div>

Tabs

Componente

Navegação entre seções

Conteúdo da aba Geral

Pagination

Componente

Paginação de listas

<Pagination>
  <PaginationContent>
    <PaginationItem><PaginationPrevious href="#" /></PaginationItem>
    <PaginationItem><PaginationLink href="#" isActive>1</PaginationLink></PaginationItem>
    <PaginationItem><PaginationNext href="#" /></PaginationItem>
  </PaginationContent>
</Pagination>

Gráfico de Barras

Componente

Receita vs Custos mensal

<div className="h-[300px]">
  <ChartContainer config={config} className="aspect-auto h-full w-full">
    <BarChart data={data}>
      <CartesianGrid vertical={false} />
      <XAxis dataKey="month" />
      <YAxis />
      <ChartTooltip content={<ChartTooltipContent />} />
      <ChartLegend content={<ChartLegendContent />} />
      <Bar dataKey="receita" fill="#006EFF" radius={[4,4,0,0]} />
    </BarChart>
  </ChartContainer>
</div>

Gráfico de Linha

Componente

Usuários ativos e novos ao longo do tempo

<div className="h-[300px]">
  <ChartContainer config={config} className="aspect-auto h-full w-full">
    <LineChart data={data}>
      <CartesianGrid vertical={false} />
      <XAxis dataKey="month" />
      <YAxis />
      <ChartTooltip content={<ChartTooltipContent />} />
      <ChartLegend content={<ChartLegendContent />} />
      <Line dataKey="ativos" stroke="#006EFF" strokeWidth={2} dot={{ r: 3 }} />
    </LineChart>
  </ChartContainer>
</div>

Gráfico de Pizza

Componente

Distribuição por categoria

<div className="h-[300px]">
  <ChartContainer config={{}} className="aspect-auto h-full w-full">
    <PieChart>
      <Pie data={data} dataKey="value" innerRadius={60} outerRadius={110}>
        {data.map((entry, i) => <Cell key={i} fill={entry.color} />)}
      </Pie>
      <ChartTooltip content={<ChartTooltipContent />} />
    </PieChart>
  </ChartContainer>
</div>

Gráfico de Área

Componente

Pedidos acumulados no período

<div className="h-[300px]">
  <ChartContainer config={config} className="aspect-auto h-full w-full">
    <AreaChart data={data}>
      <CartesianGrid vertical={false} />
      <XAxis dataKey="month" />
      <YAxis />
      <ChartTooltip content={<ChartTooltipContent />} />
      <ChartLegend content={<ChartLegendContent />} />
      <Area dataKey="pedidos" stroke="#006EFF" fill="#006EFF" fillOpacity={0.15} />
    </AreaChart>
  </ChartContainer>
</div>

KPI Dashboard

Componente

Painel de indicadores combinado

Visão Geral

Receita

R$ 45.200

+12%

Usuários

12.450

+8%

Conversão

3,2%

-0,5%

Tickets

847

+23%

{/* KPI Grid */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
  <Card className="p-4">
    <p className="text-xs uppercase tracking-wider text-muted-foreground">Label</p>
    <p className="text-xl font-medium">Valor</p>
  </Card>
</div>

Página de Lista

Componente

Filtros + Tabela + Paginação combinados

Usuários

NomeFunçãoStatus
Ana SilvaAdminAtivo
Carlos OliveiraEditorAtivo
Mariana CostaViewerInativo
{/* Template de página de lista */}
<div className="space-y-4">
  <h1 className="text-2xl font-semibold">Título</h1>
  <Card>
    <div className="p-4 border-b flex gap-2"><Input placeholder="Buscar..." /><Select>...</Select></div>
    <Table>...</Table>
    <div className="p-2 border-t"><Pagination>...</Pagination></div>
  </Card>
</div>

Tela de Login

Componente

Com gradiente primário

Bem-vindo
Faça login na plataforma
Esqueci a senha
<div className="bg-gradient-primary">
  <Card className="max-w-sm">
    <CardHeader><CardTitle>Login</CardTitle></CardHeader>
    <CardContent className="space-y-3">
      <Input placeholder="Email" />
      <Input type="password" placeholder="Senha" />
      <Button className="w-full">Entrar</Button>
    </CardContent>
  </Card>
</div>