⚡ Curso de CSS • Web-ZoneWare

Projeto Final: Design System e Dashboard — Web Academy

Lição 50 de 50

Projeto Final: Design System e Dashboard — Web Academy

Parabéns por chegar ao grande marco da Web Academy! Ao longo de 50 lições estruturadas, você dominou desde a anatomia dos seletores básicos, a mecânica do Box Model e o alinhamento bidimensional com Flexbox e Grid, até recursos de ponta como variáveis semânticas, Glassmorphism, animações a 60 FPS, seletores relacionais :has() e Container Queries. Agora, é o momento de consolidar todas essas competências em um projeto prático de nível sênior: a construção de um Design System com Tokens Semânticos e um Dashboard Analítico de Alta Fidelidade em CSS3 puro.

🎓
A Síntese do Engenheiro de CSS: Um desenvolvedor front-end de elite não copia e cola estilos de frameworks prontos às cegas. Ele compreende a cascata, projeta tokens escaláveis, constrói layouts responsivos resilientes e sabe exatamente como extrair a máxima performance da GPU. Este projeto final é o portfólio definitivo da sua maestria em CSS3.

1. A Arquitetura do Nosso Design System em Camadas

Para garantir que o Dashboard seja modular e extensível para qualquer tipo de aplicação corporativa, organizamos as folhas de estilo seguindo três princípios arquiteturais:

  1. Camada 1 — Design Tokens Globais: Cores primitivas, escalas tipográficas fluidas, espaçamentos padronizados e sombras definidos em CSS Variables no seletor :root.
  2. Camada 2 — Metodologia BEM Estruturada: Componentes desacoplados (.dashboard, .stat-card, .data-table, .badge) com especificidade plana imune a conflitos de cascata.
  3. Camada 3 — Layout Híbrido Grid + Flexbox: O esqueleto mestre estruturado com grid-template-areas e os elementos internos alinhados milimetricamente com Flexbox.

2. Anatomia dos Componentes do Dashboard

Componente Técnica CSS3 Aplicada Papel no Layout
Sidebar de Navegação Flexbox Vertical + Glassmorphism (backdrop-filter) Menu lateral compacto com links iluminados em hover e estado ativo.
Painel Superior (Header) Flexbox Horizontal + align-items: center Busca em tempo real, status do sistema e perfil do usuário.
Bento Grid de Estatísticas grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)) Cards analíticos com indicadores de métricas, gradientes e sombras dinâmicas.
Tabela Analítica Inteligente Seletor Relacional :has() + Transições Suaves Linhas com realce sob hover e esmaecimento de itens secundários.

3. Código Completo do Projeto Final (Design System & Dashboard)

Copie a estrutura HTML e a folha de estilos CSS3 abaixo para testar o painel funcionando integralmente no Playground IDE:

Estrutura HTML do Dashboard

HTML5 83 linhas
<div class="app-layout">
  <!-- Barra Lateral (Sidebar) -->
  <aside class="sidebar">
    <div class="sidebar__brand">
      <span class="brand-icon">⚡</span>
      <span class="brand-text">ZoneStudio</span>
    </div>
 
    <nav class="sidebar__nav">
      <a href="#" class="nav-item nav-item--active"><span class="nav-item__icon">📊</span> Visão Geral</a>
      <a href="#" class="nav-item"><span class="nav-item__icon">⚡</span> Ferramentas</a>
      <a href="#" class="nav-item"><span class="nav-item__icon">👥</span> Usuários</a>
      <a href="#" class="nav-item"><span class="nav-item__icon">⚙️</span> Ajustes</a>
    </nav>
  </aside>
 
  <!-- Área Principal de Conteúdo -->
  <main class="main-content">
    <header class="topbar">
      <h2 class="topbar__title">Painel de Operações CSS3</h2>
      <div class="topbar__user">
        <span class="badge badge--online">Online</span>
        <div class="user-avatar">DEV</div>
      </div>
    </header>
 
    <!-- Grid de Métricas Analíticas -->
    <section class="metrics-grid">
      <div class="metric-card metric-card--glow-cyan">
        <span class="metric-card__subtitle">Requisições Otimizadas</span>
        <div class="metric-card__value">1.42M</div>
        <span class="metric-card__delta metric-card__delta--positive">↑ +24.8% este mês</span>
      </div>
 
      <div class="metric-card metric-card--glow-green">
        <span class="metric-card__subtitle">Performance Web Vitals</span>
        <div class="metric-card__value">99/100</div>
        <span class="metric-card__delta metric-card__delta--positive">↑ LCP 0.6s estável</span>
      </div>
 
      <div class="metric-card metric-card--glow-amber">
        <span class="metric-card__subtitle">Payload CSS Minificado</span>
        <div class="metric-card__value">12.4 KB</div>
        <span class="metric-card__delta metric-card__delta--positive">↓ -68% de compressão</span>
      </div>
    </section>
 
    <!-- Tabela de Sessões com :has() e Glassmorphism -->
    <section class="table-container">
      <h3 class="section-heading">Monitoramento de Componentes em Tempo Real</h3>
      <table class="data-table">
        <thead>
          <tr>
            <th>Módulo</th>
            <th>Tecnologia</th>
            <th>Render Layer</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><strong>Container Queries</strong></td>
            <td>CSS Containment L3</td>
            <td>Layout Inline</td>
            <td><span class="status-pill status-pill--success">Ativo</span></td>
          </tr>
          <tr>
            <td><strong>Seletor Relacional</strong></td>
            <td>CSS Selectors L4 (:has)</td>
            <td>CSSOM Matching</td>
            <td><span class="status-pill status-pill--success">Ativo</span></td>
          </tr>
          <tr>
            <td><strong>Glassmorphism Core</strong></td>
            <td>Backdrop Filter & Blur</td>
            <td>GPU Accelerated</td>
            <td><span class="status-pill status-pill--warning">Calibrado</span></td>
          </tr>
        </tbody>
      </table>
    </section>
  </main>
</div>

Folha de Estilos CSS3 (Design Tokens + Layout)

CSS3 307 linhas
/* ==========================================================
   1. DESIGN TOKENS GLOBAIS (:root)
   ========================================================== */
:root {
  --bg-deep: #090d16;
  --bg-surface: #111827;
  --bg-glass: rgba(17, 24, 39, 0.75);
  --border-subtle: rgba(255, 255, 255, 0.08);
  --border-glow: rgba(0, 240, 255, 0.35);
 
  --color-cyan: #00f0ff;
  --color-green: #10b981;
  --color-amber: #f59e0b;
  --color-text-main: #f8fafc;
  --color-text-muted: #94a3b8;
 
  --font-sans: 'Inter', system-ui, sans-serif;
  --radius-lg: 16px;
  --radius-md: 10px;
  --radius-sm: 6px;
 
  --transition-smooth: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
 
/* ==========================================================
   2. RESET DE ESPECIFICIDADE ZERO COM :where()
   ========================================================== */
:where(*, *::before, *::after) {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
 
/* ==========================================================
   3. ESTRUTURA DO LAYOUT MESTRE (Grid Responsivo)
   ========================================================== */
.app-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
  background-color: var(--bg-deep);
  font-family: var(--font-sans);
  color: var(--color-text-main);
}
 
/* ==========================================================
   4. SIDEBAR COM GLASSMORPHISM
   ========================================================== */
.sidebar {
  background: var(--bg-glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-right: 1px solid var(--border-subtle);
  padding: 1.5rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
 
.sidebar__brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-left: 0.5rem;
}
 
.brand-icon {
  font-size: 1.5rem;
  filter: drop-shadow(0 0 8px var(--color-cyan));
}
 
.brand-text {
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.5px;
  color: var(--color-text-main);
}
 
.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
 
.nav-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.92rem;
  transition: var(--transition-smooth);
}
 
.nav-item:hover {
  background: rgba(255, 255, 255, 0.05);
  color: var(--color-text-main);
  transform: translateX(4px);
}
 
.nav-item--active {
  background: rgba(0, 240, 255, 0.1);
  color: var(--color-cyan);
  border-left: 3px solid var(--color-cyan);
}
 
/* ==========================================================
   5. CONTEÚDO PRINCIPAL & TOPBAR
   ========================================================== */
.main-content {
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
  overflow-y: auto;
}
 
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--border-subtle);
}
 
.topbar__title {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.5px;
}
 
.topbar__user {
  display: flex;
  align-items: center;
  gap: 1rem;
}
 
.user-avatar {
  width: 40px;
  height: 40px;
  background: linear-gradient(135deg, var(--color-cyan), #3b82f6);
  color: #090d16;
  font-weight: 800;
  font-size: 0.85rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 12px rgba(0, 240, 255, 0.3);
}
 
/* ==========================================================
   6. BENTO GRID DE MÉTRICAS ANALÍTICAS
   ========================================================== */
.metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
}
 
.metric-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  transition: var(--transition-smooth);
}
 
.metric-card:hover {
  transform: translateY(-4px);
  border-color: var(--border-glow);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
}
 
.metric-card--glow-cyan:hover { box-shadow: 0 10px 25px rgba(0, 240, 255, 0.15); }
.metric-card--glow-green:hover { box-shadow: 0 10px 25px rgba(16, 185, 129, 0.15); }
.metric-card--glow-amber:hover { box-shadow: 0 10px 25px rgba(245, 158, 11, 0.15); }
 
.metric-card__subtitle {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
 
.metric-card__value {
  font-size: 2.2rem;
  font-weight: 800;
  letter-spacing: -1px;
}
 
.metric-card__delta {
  font-size: 0.85rem;
  font-weight: 700;
}
 
.metric-card__delta--positive { color: var(--color-green); }
 
/* ==========================================================
   7. TABELA COM GLASSMORPHISM & :has() INTELIGENTE
   ========================================================== */
.table-container {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
 
.section-heading {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--color-text-main);
}
 
.data-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}
 
.data-table th {
  padding: 0.75rem 1rem;
  color: var(--color-text-muted);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-bottom: 1px solid var(--border-subtle);
}
 
.data-table td {
  padding: 1rem;
  border-bottom: 1px solid var(--border-subtle);
  font-size: 0.95rem;
}
 
/* Transição de Hover nas Linhas */
.data-table tbody tr {
  transition: background-color 0.2s ease, opacity 0.2s ease;
}
 
.data-table tbody tr:hover {
  background-color: rgba(255, 255, 255, 0.03);
}
 
/* Mágica do :has() para Dimming de Irmãos na Tabela */
.data-table tbody:has(tr:hover) tr:not(:hover) {
  opacity: 0.45;
}
 
/* ==========================================================
   8. COMPONENTES ATÔMICOS (Badges & Pills)
   ========================================================== */
.status-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 20px;
  font-size: 0.75rem;
  font-weight: 700;
}
 
.status-pill--success {
  background: rgba(16, 185, 129, 0.15);
  color: var(--color-green);
}
 
.status-pill--warning {
  background: rgba(245, 158, 11, 0.15);
  color: var(--color-amber);
}
 
.badge--online {
  background: rgba(16, 185, 129, 0.2);
  color: var(--color-green);
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 800;
}
 
/* ==========================================================
   9. RESPONSIVIDADE MOBILE-FIRST
   ========================================================== */
@media (max-width: 768px) {
  .app-layout {
    grid-template-columns: 1fr;
  }
 
  .sidebar {
    border-right: none;
    border-bottom: 1px solid var(--border-subtle);
  }
 
  .main-content {
    padding: 1rem;
  }
}
🧪 Quer ver este código funcionando agora?
Abrir no Playground IDE →

4. Ferramentas Web-ZoneWare para o seu Projeto Final

Ao finalizar a construção do seu Dashboard, passe o código pelas ferramentas do portal Web-ZoneWare para validar a conformidade e compactar a entrega:

  • Limpador e Formatador CSS: Garanta que todas as variáveis e regras BEM estejam perfeitamente indentadas com 2 espaços de padrão sênior.
  • Validador de CSS Online: Assegure conformidade 100% com os padrões do W3C antes do deploy.
  • Playground Web IDE: Seu laboratório permanente para testar novas telas e componentes em qualquer dispositivo.

6. Exercício Prático de Conclusão da Trilha

  1. Carregue o código do Dashboard no Playground Web IDE.
  2. Adicione um botão de alternância de tema (Modo Claro vs. Modo Escuro) redefinindo os valores das variáveis em :root[data-theme="light"].
  3. Insira um novo widget analítico na seção de estatísticas representando o tempo de resposta do servidor em milissegundos com um badge Fast.
  4. Teste o comportamento responsivo reduzindo a largura da janela até 360px no celular e verifique se o menu e os cards se adaptam sem overflow horizontal.
  5. Passe a folha final pelo Minificador CSS e confira a redução de peso atingida.

7. Quiz Final de Conclusão da Trilha CSS3

1. Qual a principal vantagem de centralizar cores e espaçamentos em CSS Variables (:root) em vez de valores fixos?

Resposta Correta: Permite criar um sistema coeso de Design Tokens que pode ser atualizado em um único local central, viabilizando temas dinâmicos (como Dark Mode) em tempo de execução sem duplicar código na cascata.

2. Por que a combinação de CSS Grid no layout macro e Flexbox nos componentes internos é o padrão da indústria?

Resposta Correta: Porque o CSS Grid é especialista em alinhamento bidimensional (linhas e colunas simultâneas para o esqueleto geral), enquanto o Flexbox é imbatível para alinhamento unidimensional (distribuição linear e centralização de botões, ícones e cabeçalhos).

3. Como o efeito de Glassmorphism com backdrop-filter difere da propriedade filter tradicional?

Resposta Correta: A propriedade filter borra o próprio elemento e todo o seu texto interno. Já o backdrop-filter aplica o desfoque gaussiano exclusivamente à área gráfica localizada atrás da caixa translúcida, mantendo o texto perfeitamente nítido e legível.


Rolar para cima