🎨 Fase 0 — HTML & CSS

Bem-vindo ao DevTrail! Aqui começa sua jornada. Nesta fase você vai revisar e solidificar HTML e CSS — a estrutura e o estilo de tudo que existe na web. Ao final, você terá uma página de portfólio publicada no GitHub Pages.

⏱ 2 semanas · 10 dias 📅 14:30–17:30 teoria 🌙 21:00–23:00 prática 📁 Repo: html-css-review 🎯 Meta: portfólio no GitHub Pages
🐙 GIT
GitHub — Setup e Fluxo Diário
Faça isso uma vez antes de começar o Dia 1

1. Crie sua conta e o repositório

  1. Acesse github.com e crie sua conta (gratuita)
  2. Clique em New repository
  3. Nome: html-css-review
  4. Marque Add a README file e clique em Create repository

2. Instale o Git no seu computador

Baixe em git-scm.com e instale com as opções padrão.

3. Configure sua identidade (uma vez só)

bash
git config --global user.name "Seu Nome"
git config --global user.email "seu@email.com"

4. Clone o repositório no seu computador

bash
# Abra o terminal, navegue até onde quer salvar os projetos
cd Documentos   # ou qualquer pasta

# Clone o repositório (substitua SEU-USUARIO pelo seu usuário do GitHub)
git clone https://github.com/SEU-USUARIO/html-css-review.git

# Entre na pasta
cd html-css-review

5. Fluxo que você vai repetir todo dia

bash
# APÓS cada sessão de prática (noite):

git status                            # ver o que mudou
git add .                             # adicionar todos os arquivos
git commit -m "tipo: o que foi feito" # registrar com mensagem
git push origin main                  # enviar para o GitHub

6. Tipos de mensagem de commit

Tipo Quando usar Exemplo
study Exercícios e anotações de aprendizado study: estrutura html da pagina
feat Nova funcionalidade ou seção criada feat: secao de projetos com grid
style CSS, layout, cores, espaçamento style: flexbox no header
fix Correção de algo que estava errado fix: alinhamento do menu mobile
chore Setup, configuração, estrutura de pastas chore: cria estrutura inicial
Regra de ouro: Um commit por sessão de estudo no mínimo. Prefira commits pequenos e frequentes. O histórico de commits é parte do seu portfólio.

7. Estrutura de pastas para esta fase

estrutura
html-css-review/
├── README.md
├── portfolio/          ← projeto principal (cresce ao longo dos 10 dias)
│   ├── index.html
│   └── style.css
└── exercicios/         ← exercícios diários
    ├── dia-01/
    ├── dia-02/
    └── ...
Crie estas pastas agora antes de começar o Dia 1. Você pode criar pelo próprio explorador de arquivos do sistema.
Dia 1
HTML Semântico
Segunda-feira · Semana 1 · HTML
📖 Tarde — Teoria (14:30–17:30)

O que é HTML?

HTML (HyperText Markup Language) é a linguagem de estrutura da web. Ele descreve o conteúdo e o significado de uma página — títulos, parágrafos, imagens, listas, links. O navegador lê o HTML e exibe o resultado na tela.

Analogia: Se uma página fosse uma casa, o HTML seria a estrutura — paredes, cômodos, portas, janelas. O CSS seria a pintura e decoração.

Estrutura básica de um documento HTML

Todo arquivo HTML começa com esta estrutura. Salve sempre com extensão .html.

index.html
<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Minha Página</title>
</head>
<body>
  <!-- Todo o conteúdo visível vai aqui -->
  <h1>Olá, mundo!</h1>
  <p>Meu primeiro parágrafo.</p>
</body>
</html>

Cada parte explicada

  • <!DOCTYPE html> — diz ao navegador que é HTML5 (versão atual)
  • <html lang="pt-BR"> — raiz da página; lang ajuda leitores de tela e buscadores
  • <head> — configurações invisíveis: charset, viewport, título, link para CSS
  • <meta charset="UTF-8"> — garante que acentos e ç funcionem
  • <meta name="viewport"> — essencial para o site funcionar bem em celular
  • <title> — texto que aparece na aba do navegador
  • <body> — tudo que o usuário vê fica aqui

Tags semânticas vs <div>

Uma <div> é uma caixa genérica sem significado. Tags semânticas comunicam o propósito do conteúdo para o navegador, leitores de tela e motores de busca.

❌ sem semântica
<div class="cabecalho">
  <div class="navegacao">...</div>
</div>
<div class="conteudo-principal">
  <div class="artigo">...</div>
  <div class="lateral">...</div>
</div>
<div class="rodape">...</div>
✅ com semântica
<header>
  <nav>...</nav>
</header>
<main>
  <article>...</article>
  <aside>...</aside>
</main>
<footer>...</footer>

Tags semânticas principais

Tag Uso
<header> Cabeçalho da página ou de uma seção
<nav> Menu de navegação
<main> Conteúdo principal (único por página)
<section> Seção temática com título
<article> Conteúdo independente (post, card, produto)
<aside> Conteúdo relacionado mas secundário (sidebar)
<footer> Rodapé da página ou seção

Tags de texto e conteúdo

html
<!-- Hierarquia de títulos: use h1 uma vez por página -->
<h1>Título principal da página</h1>
<h2>Seção</h2>
<h3>Subseção</h3>

<!-- Parágrafo -->
<p>Texto comum. <strong>Negrito importante.</strong> <em>Itálico ênfase.</em></p>

<!-- Links -->
<a href="https://github.com">Texto do link</a>
<a href="sobre.html">Link para outra página</a>
<a href="#contato">Link para âncora na mesma página</a>

<!-- Imagem -->
<img src="foto.jpg" alt="Descrição da imagem">

<!-- Listas -->
<ul>  <!-- não ordenada -->
  <li>Item 1</li>
  <li>Item 2</li>
</ul>

<ol>  <!-- ordenada (numerada) -->
  <li>Primeiro</li>
  <li>Segundo</li>
</ol>

Estrutura do projeto portfólio — Dia 1

Esta é a estrutura HTML do portfólio que vamos construir. Hoje criamos o esqueleto. Nos próximos dias vamos adicionar CSS, Flexbox, Grid e muito mais.

portfolio/index.html
<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Portfólio | Seu Nome</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <header>
    <nav>
      <a href="#" class="logo">SeuNome</a>
      <ul>
        <li><a href="#sobre">Sobre</a></li>
        <li><a href="#projetos">Projetos</a></li>
        <li><a href="#contato">Contato</a></li>
      </ul>
    </nav>
  </header>

  <main>

    <!-- SEÇÃO HERO -->
    <section id="hero">
      <h1>Olá, sou <span>Seu Nome</span> 👋</h1>
      <p>Desenvolvedor Front-end em formação. Apaixonado por criar experiências web incríveis.</p>
      <a href="#projetos" class="btn">Ver meus projetos</a>
    </section>

    <!-- SEÇÃO SOBRE -->
    <section id="sobre">
      <h2>Sobre mim</h2>
      <p>Escreva aqui um parágrafo sobre você, seus objetivos e o que está estudando.</p>
    </section>

    <!-- SEÇÃO PROJETOS -->
    <section id="projetos">
      <h2>Projetos</h2>
      <article class="card">
        <h3>TaskFlow</h3>
        <p>Gerenciador de tarefas em JavaScript puro.</p>
        <a href="#">Ver projeto</a>
      </article>
      <article class="card">
        <h3>Busca de CEP</h3>
        <p>Consulta de endereços usando a API ViaCEP.</p>
        <a href="#">Ver projeto</a>
      </article>
      <article class="card">
        <h3>App de Clima</h3>
        <p>Previsão do tempo com dados em tempo real.</p>
        <a href="#">Ver projeto</a>
      </article>
    </section>

    <!-- SEÇÃO CONTATO -->
    <section id="contato">
      <h2>Contato</h2>
      <form>
        <label for="nome">Nome</label>
        <input type="text" id="nome" name="nome" placeholder="Seu nome">
        <label for="email">E-mail</label>
        <input type="email" id="email" name="email" placeholder="seu@email.com">
        <label for="mensagem">Mensagem</label>
        <textarea id="mensagem" name="mensagem" rows="5"></textarea>
        <button type="submit">Enviar mensagem</button>
      </form>
    </section>

  </main>

  <footer>
    <p>Feito com 💙 por Seu Nome &mdash; <a href="https://github.com/seu-usuario">GitHub</a></p>
  </footer>

</body>
</html>

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 1

Crie um arquivo exercicios/dia-01/index.html com a estrutura de uma página de receita culinária usando tags semânticas corretas. Inclua:

  • Um <header> com o nome da receita em <h1>
  • Um <main> com dois <section>: ingredientes (lista <ul>) e modo de preparo (lista <ol>)
  • Um <footer> com seu nome como autor
  • Uma imagem com alt descritivo
solução
<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Bolo de Chocolate</title>
</head>
<body>
  <header>
    <h1>Bolo de Chocolate</h1>
    <p>Receita clássica e fofinha</p>
  </header>

  <main>
    <section>
      <h2>Ingredientes</h2>
      <img src="bolo.jpg" alt="Bolo de chocolate com cobertura e fatia cortada">
      <ul>
        <li>3 ovos</li>
        <li>2 xícaras de farinha de trigo</li>
        <li>1 xícara de achocolatado</li>
        <li>1 xícara de açúcar</li>
        <li>1 xícara de leite</li>
        <li>1/2 xícara de óleo</li>
        <li>1 colher de sopa de fermento</li>
      </ul>
    </section>

    <section>
      <h2>Modo de Preparo</h2>
      <ol>
        <li>Preaqueça o forno a 180°C</li>
        <li>Bata os ovos com o açúcar até dobrar de volume</li>
        <li>Adicione o leite e o óleo, misture bem</li>
        <li>Peneire a farinha e o achocolatado e incorpore à mistura</li>
        <li>Adicione o fermento por último, mexendo delicadamente</li>
        <li>Despeje em forma untada e asse por 35 minutos</li>
      </ol>
    </section>
  </main>

  <footer>
    <p>Receita por Seu Nome</p>
  </footer>
</body>
</html>
🏗️ Projeto do Dia — Portfólio: Estrutura HTML

Copie o código do portfólio (seção acima) para o arquivo portfolio/index.html. Personalize com seu nome, e abra no navegador para ver o resultado (sem CSS ainda, estará sem estilo — isso é normal!).

Não esqueça de criar também o arquivo portfolio/style.css vazio — vamos preenchê-lo amanhã.

🐙
Commit do dia
study: estrutura html semantica do portfolio
Cole no terminal após concluir a prática da noite e envie com git push origin main
✅ Checklist do Dia 1
Dia 2
CSS Básico
Terça-feira · Semana 1 · CSS
📖 Tarde — Teoria (14:30–17:30)

O que é CSS?

CSS (Cascading Style Sheets) controla a aparência visual do HTML — cores, fontes, espaçamentos, tamanhos, posicionamento. Sem CSS, toda página seria texto preto em fundo branco.

Como conectar o CSS ao HTML

index.html (dentro do <head>)
<!-- Método correto: arquivo externo -->
<link rel="stylesheet" href="style.css">
Evite: CSS inline (style="color:red") e a tag <style> no HTML. Use sempre um arquivo .css separado — é mais organizado e reutilizável.

Seletores CSS

Um seletor define a quem a regra se aplica. O bloco { } define o que vai mudar.

style.css
/* Seletor de elemento — aplica a TODAS as tags desse tipo */
p { color: gray; }
h1 { font-size: 32px; }

/* Seletor de classe — aplica a qualquer elemento com class="nome" */
.card { background: white; }
.btn { padding: 10px 20px; }

/* Seletor de ID — aplica a UM elemento com id="nome" (use com moderação) */
#hero { background: #0d1117; }

/* Seletor descendente — p dentro de .card */
.card p { color: #666; }

/* Múltiplos seletores — mesma regra para vários */
h1, h2, h3 { font-family: sans-serif; }

Box Model — o modelo de caixa

Todo elemento HTML é uma caixa com 4 camadas:

As 4 camadas (de dentro para fora)

  • content — o conteúdo em si (texto, imagem)
  • padding — espaço interno entre o conteúdo e a borda
  • border — a borda da caixa
  • margin — espaço externo entre elementos
css
.card {
  /* padding: dentro da borda */
  padding: 20px;           /* todos os lados */
  padding: 10px 20px;      /* vertical horizontal */
  padding: 10px 20px 10px 20px; /* top right bottom left */

  /* margin: fora da borda */
  margin: 0 auto;          /* centraliza horizontalmente */
  margin-bottom: 16px;

  /* border */
  border: 1px solid #ccc;
  border-radius: 8px;      /* arredonda os cantos */

  /* width & height */
  width: 300px;
  max-width: 100%;         /* nunca ultrapassa o container pai */
}
Sempre adicione isso no início do seu CSS:
* { box-sizing: border-box; } — faz o padding e border serem incluídos na largura total do elemento, evitando surpresas.

Unidades de medida

Unidade O que é Quando usar
px Pixels — valor fixo Bordas, sombras, valores pequenos e precisos
rem Relativo ao tamanho base do documento (padrão: 16px) Fontes, espaçamentos — escala com acessibilidade
em Relativo ao tamanho do elemento pai Espaçamentos internos do componente
% Percentual do elemento pai Larguras fluidas e responsivas
vh/vw Percentual da altura/largura da viewport Seções full-screen, hero

Cores

css
/* Hexadecimal: #RRGGBB ou #RGB */
color: #e34c26;
color: #fff;   /* branco */
color: #000;   /* preto */

/* RGB e RGBA (a = transparência 0-1) */
color: rgb(30, 30, 30);
color: rgba(0, 0, 0, 0.5);   /* 50% transparente */

/* HSL: hue saturation lightness (mais intuitivo para criar paletas) */
color: hsl(220, 80%, 60%);
background: hsl(220, 80%, 10%);  /* escurece mantendo o tom */

Tipografia

css
body {
  font-family: 'Segoe UI', system-ui, sans-serif; /* pilha de fontes */
  font-size: 16px;        /* tamanho base */
  line-height: 1.6;       /* espaço entre linhas (sem unidade = relativo) */
  color: #333;
}

h1 {
  font-size: 2.5rem;      /* 40px se base = 16px */
  font-weight: 700;       /* 400=normal, 700=bold */
  letter-spacing: -0.5px; /* espaço entre letras */
  color: #0d1117;
}

/* Google Fonts: adicione no <head> do HTML */
/* <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet"> */

body { font-family: 'Inter', sans-serif; }

CSS do Portfólio — Dia 2

Adicione este CSS no arquivo portfolio/style.css:

portfolio/style.css
/* ===== RESET & BASE ===== */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Segoe UI', system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.7;
  color: #1a1a2e;
  background: #ffffff;
}

/* ===== TIPOGRAFIA ===== */
h1 { font-size: 2.5rem; font-weight: 700; margin-bottom: 1rem; }
h2 { font-size: 1.75rem; font-weight: 600; margin-bottom: 1rem; }
h3 { font-size: 1.25rem; font-weight: 600; margin-bottom: 0.5rem; }
p  { color: #555; margin-bottom: 1rem; }
a  { color: #264de4; text-decoration: none; }
a:hover { text-decoration: underline; }

/* ===== LAYOUT ===== */
section {
  padding: 80px 0;
  max-width: 1000px;
  margin: 0 auto;
  padding-left: 24px;
  padding-right: 24px;
}

/* ===== HEADER ===== */
header {
  background: #0d1117;
  padding: 0 24px;
  position: sticky;
  top: 0;
  z-index: 100;
}

header nav {
  max-width: 1000px;
  margin: 0 auto;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.logo {
  font-weight: 700;
  font-size: 1.1rem;
  color: #ffffff;
  text-decoration: none;
}

header nav ul {
  list-style: none;
  display: flex;
  gap: 28px;
}

header nav ul a {
  color: #8892a4;
  font-size: 0.9rem;
  transition: color 0.2s;
}

header nav ul a:hover {
  color: #ffffff;
  text-decoration: none;
}

/* ===== HERO ===== */
#hero {
  background: #0d1117;
  color: white;
  text-align: center;
  padding: 100px 24px;
  max-width: 100%;
}

#hero h1 { color: white; font-size: 3rem; }
#hero span { color: #264de4; }
#hero p { color: #8892a4; font-size: 1.1rem; max-width: 500px; margin: 0 auto 2rem; }

/* ===== BOTÃO ===== */
.btn {
  display: inline-block;
  background: #264de4;
  color: white;
  padding: 12px 28px;
  border-radius: 8px;
  font-weight: 600;
  text-decoration: none;
  transition: background 0.2s;
}

.btn:hover {
  background: #1a3ab8;
  text-decoration: none;
}

/* ===== CARDS ===== */
.card {
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 16px;
}

/* ===== FORMULÁRIO ===== */
form { max-width: 560px; }
label { display: block; font-weight: 600; font-size: 0.875rem; margin-bottom: 6px; margin-top: 16px; }
input, textarea {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid #dee2e6;
  border-radius: 8px;
  font-size: 1rem;
  font-family: inherit;
}
input:focus, textarea:focus {
  outline: none;
  border-color: #264de4;
  box-shadow: 0 0 0 3px rgba(38, 77, 228, 0.15);
}
form button {
  margin-top: 20px;
  background: #264de4;
  color: white;
  border: none;
  padding: 12px 28px;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
}

/* ===== FOOTER ===== */
footer {
  background: #0d1117;
  color: #8892a4;
  text-align: center;
  padding: 32px 24px;
  font-size: 0.875rem;
}

footer a { color: #264de4; }

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 2

Crie exercicios/dia-02/style.css para estilizar a página da receita do Dia 1. Use:

  • box-sizing: border-box no *
  • Fonte diferente da padrão com font-family
  • Cor de fundo suave e cor de texto adequada
  • Padding nas seções para não grudar nas bordas
  • Um max-width no body ou em uma classe container
  • Estilo diferente para o h1, h2 e os itens da lista
solução
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: Georgia, serif;
  font-size: 16px;
  line-height: 1.7;
  color: #2d2d2d;
  background: #fdf8f2;
}

.container {
  max-width: 700px;
  margin: 0 auto;
  padding: 0 24px;
}

header {
  background: #8b2500;
  color: white;
  padding: 40px 24px;
  text-align: center;
}

h1 {
  font-size: 2rem;
  margin-bottom: 0.5rem;
  color: white;
}

header p { color: rgba(255,255,255,0.8); }

section {
  padding: 32px 24px;
  max-width: 700px;
  margin: 0 auto;
}

h2 {
  font-size: 1.4rem;
  color: #8b2500;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 2px solid #e9d5c8;
}

ul, ol { padding-left: 20px; }
li {
  margin-bottom: 8px;
  color: #444;
}

footer {
  background: #2d2d2d;
  color: #aaa;
  text-align: center;
  padding: 20px;
  font-size: 0.875rem;
}
🏗️ Projeto do Dia — Portfólio: CSS Base

Cole o CSS do portfólio (código acima) no arquivo portfolio/style.css. Abra o index.html no navegador e veja a transformação! Personalize as cores principais se quiser — troque #264de4 por outra cor de sua preferência.

🐙
Commit do dia
style: css base com tipografia e cores do portfolio
✅ Checklist do Dia 2
Dia 3
Flexbox
Quarta-feira · Semana 1 · CSS
📖 Tarde — Teoria (14:30–17:30)

O que é Flexbox?

Flexbox é um sistema de layout CSS que organiza elementos em uma dimensão (linha ou coluna). É perfeito para alinhar itens dentro de um container, criar navbars, centralizar conteúdo e distribuir espaço entre elementos.

Vocabulário: O elemento com display: flex é o flex container. Os filhos diretos são os flex items.

Propriedades do Container (pai)

css
.container {
  display: flex;                  /* ativa o flexbox */

  /* DIREÇÃO */
  flex-direction: row;            /* → padrão: em linha */
  flex-direction: column;         /* ↓ em coluna */
  flex-direction: row-reverse;    /* ← linha invertida */

  /* ALINHAMENTO NO EIXO PRINCIPAL (horizontal se row) */
  justify-content: flex-start;    /* |●●●_______| */
  justify-content: center;        /* |____●●●____| */
  justify-content: flex-end;      /* |_______●●●| */
  justify-content: space-between; /* |●___●___●| */
  justify-content: space-around;  /* |_●__●__●_| */
  justify-content: space-evenly;  /* |__●__●__●__| */

  /* ALINHAMENTO NO EIXO CRUZADO (vertical se row) */
  align-items: stretch;           /* padrão: estica até a altura do container */
  align-items: center;            /* centraliza verticalmente */
  align-items: flex-start;        /* topo */
  align-items: flex-end;          /* base */

  /* QUEBRA DE LINHA */
  flex-wrap: nowrap;              /* padrão: não quebra */
  flex-wrap: wrap;                /* quebra para a próxima linha */

  /* ESPAÇO ENTRE ITENS */
  gap: 16px;                      /* espaço entre todos os itens */
  gap: 16px 24px;                 /* vertical horizontal */
}

Propriedades do Item (filho)

css
.item {
  /* flex-grow: quanto cresce para ocupar espaço extra */
  flex-grow: 0;   /* padrão: não cresce */
  flex-grow: 1;   /* cresce para ocupar espaço disponível */

  /* flex-shrink: quanto encolhe se faltar espaço */
  flex-shrink: 1; /* padrão: pode encolher */
  flex-shrink: 0; /* não encolhe nunca */

  /* flex-basis: tamanho inicial antes de crescer/encolher */
  flex-basis: 200px;
  flex-basis: auto;   /* padrão */

  /* shorthand: grow shrink basis */
  flex: 1;            /* atalho para flex: 1 1 0 */
  flex: 0 0 200px;    /* largura fixa de 200px */

  /* alinhamento individual (sobrescreve align-items do pai) */
  align-self: center;
}

Padrões mais usados

receitas flexbox
/* Centralizar algo na tela */
.centralizado {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

/* Navbar com logo à esquerda e menu à direita */
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 24px;
}

/* Itens iguais que dividem o espaço */
.cols {
  display: flex;
  gap: 16px;
}
.cols .col {
  flex: 1; /* todos iguais */
}

/* Sidebar + conteúdo */
.layout {
  display: flex;
  gap: 24px;
}
.sidebar { flex: 0 0 240px; }   /* largura fixa */
.content { flex: 1; }           /* ocupa o resto */
Dica de estudo: Acesse flexboxfroggy.com e complete os 24 níveis — é a forma mais rápida de fixar Flexbox na memória.

Aplicando ao Portfólio — navbar com Flexbox

O CSS do Dia 2 já usa Flexbox no nav. Agora vamos melhorar a seção hero e preparar os cards:

portfolio/style.css — adicionar
/* HERO com dois conteúdos lado a lado (texto + imagem futura) */
#hero .hero-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  max-width: 600px;
  margin: 0 auto;
}

/* TAGS de tecnologia abaixo do texto do hero */
.tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
}

.tag-item {
  background: rgba(38, 77, 228, 0.15);
  color: #8aabff;
  padding: 4px 12px;
  border-radius: 99px;
  font-size: 0.8rem;
  font-weight: 500;
}

/* Atualize o HTML do hero para incluir as tags */

Adicione também no index.html, dentro de #hero, após o botão:

portfolio/index.html — atualizar hero
<section id="hero">
  <div class="hero-content">
    <h1>Olá, sou <span>Seu Nome</span> 👋</h1>
    <p>Desenvolvedor Front-end em formação. Apaixonado por criar experiências web incríveis.</p>
    <a href="#projetos" class="btn">Ver meus projetos</a>
    <div class="tags">
      <span class="tag-item">HTML</span>
      <span class="tag-item">CSS</span>
      <span class="tag-item">JavaScript</span>
      <span class="tag-item">React</span>
    </div>
  </div>
</section>

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 3

Crie exercicios/dia-03/index.html com um layout de galeria de fotos usando Flexbox:

  • Um container com display: flex, flex-wrap: wrap e gap: 16px
  • 6 "fotos" (pode usar cores de fundo no lugar de imagens reais)
  • Cada foto com largura de aproximadamente 30% para ficarem 3 por linha
  • Altura fixa de 200px cada uma
  • Um título centralizado acima da galeria
solução — html
<!-- index.html -->
<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <title>Galeria</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Minha Galeria</h1>
  <div class="galeria">
    <div class="foto" style="background:#e34c26"></div>
    <div class="foto" style="background:#264de4"></div>
    <div class="foto" style="background:#f7df1e"></div>
    <div class="foto" style="background:#61dafb"></div>
    <div class="foto" style="background:#3fb950"></div>
    <div class="foto" style="background:#bc8cff"></div>
  </div>
</body>
</html>
solução — css
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; padding: 32px; background: #f5f5f5; }
h1 { text-align: center; margin-bottom: 24px; font-size: 1.8rem; }
.galeria {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.foto {
  flex: 0 0 calc(33.333% - 11px); /* 3 por linha descontando gap */
  height: 200px;
  border-radius: 12px;
}
🏗️ Projeto do Dia — Portfólio: Flexbox no Hero e Nav

Aplique as mudanças do CSS e HTML do portfólio acima. Depois, abra o Flexbox Froggy e tente completar pelo menos os 12 primeiros níveis — é rápido e fixa bem as propriedades na memória.

🐙
Commit do dia
style: flexbox no hero e navbar do portfolio
✅ Checklist do Dia 3
Dia 4
CSS Grid
Quinta-feira · Semana 1 · CSS
📖 Tarde — Teoria (14:30–17:30)

O que é CSS Grid?

CSS Grid é um sistema de layout bidimensional — controla linhas e colunas ao mesmo tempo. Enquanto o Flexbox é ideal para uma linha ou coluna de itens, o Grid é perfeito para layouts de página completos e galerias complexas.

Flexbox vs Grid — quando usar cada um?

  • Flexbox: navbar, lista de tags, botões lado a lado, alinhar um item dentro de outro — uma dimensão
  • Grid: layout da página, galeria de cards, formulários alinhados — duas dimensões
  • Dica: na prática, você usa os dois juntos! Grid para a estrutura geral, Flexbox dentro dos componentes.

Criando colunas e linhas

css
.grid {
  display: grid;

  /* COLUNAS */
  grid-template-columns: 200px 200px 200px; /* 3 colunas fixas */
  grid-template-columns: 1fr 1fr 1fr;       /* 3 colunas iguais */
  grid-template-columns: repeat(3, 1fr);    /* mesmo resultado */
  grid-template-columns: 250px 1fr;         /* sidebar + conteúdo */
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* responsivo! */

  /* LINHAS */
  grid-template-rows: auto; /* padrão: altura do conteúdo */
  grid-template-rows: 100px 1fr auto; /* header fixo, main flexível, footer auto */

  /* ESPAÇAMENTO */
  gap: 24px;
  column-gap: 16px;
  row-gap: 24px;
}

A unidade fr — fração do espaço disponível

css
/* Imagine um container de 900px com gap de 24px */

/* Duas colunas iguais: cada uma fica com ~438px */
grid-template-columns: 1fr 1fr;

/* Sidebar + conteúdo: sidebar=250px, conteúdo=626px */
grid-template-columns: 250px 1fr;

/* Três colunas: 1ª pequena, 2ª grande, 3ª média */
grid-template-columns: 1fr 2fr 1fr;

Posicionando itens no grid

css
/* Um item que ocupa 2 colunas */
.destaque {
  grid-column: span 2;   /* ocupa 2 colunas */
  grid-row: span 2;      /* ocupa 2 linhas */
}

/* Posicionamento preciso (linha inicial / linha final) */
.header { grid-column: 1 / 4; }       /* da coluna 1 até a 4 (3 colunas) */
.sidebar { grid-column: 1 / 2; }      /* apenas coluna 1 */
.main { grid-column: 2 / 4; }         /* colunas 2 e 3 */
.footer { grid-column: 1 / -1; }      /* -1 = até o final */

Grid Template Areas — layout visual

css
.pagina {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main main"
    "footer footer footer";
  grid-template-columns: 250px 1fr 1fr;
  gap: 16px;
  min-height: 100vh;
}

header  { grid-area: header; }
aside   { grid-area: sidebar; }
main    { grid-area: main; }
footer  { grid-area: footer; }

Auto-fill + minmax — grid responsivo automático

Essa é uma das técnicas mais poderosas do Grid: colunas que se adaptam automaticamente ao espaço disponível, sem media queries!

css
.cards {
  display: grid;
  /* cria quantas colunas couberem, com mínimo 250px e máximo 1fr */
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 24px;
}
/* Em tela larga: 3 colunas. Em tablet: 2. No mobile: 1. */

Portfólio — Seção de Projetos com Grid

Substitua o CSS dos cards no style.css:

portfolio/style.css — atualizar
/* GRID DE PROJETOS */
#projetos .grid-projetos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
  margin-top: 32px;
}

.card {
  background: #ffffff;
  border: 1px solid #e9ecef;
  border-radius: 12px;
  padding: 24px;
  transition: transform 0.2s, box-shadow 0.2s;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08);
}

.card h3 { margin-bottom: 8px; color: #0d1117; }
.card p  { color: #666; font-size: 0.9rem; margin-bottom: 16px; }
.card a  {
  font-size: 0.85rem;
  font-weight: 600;
  color: #264de4;
}

/* Card em destaque (ocupa 2 colunas se houver espaço) */
.card.destaque {
  grid-column: span 2;
}

Atualize o HTML da seção de projetos para usar a classe grid-projetos:

portfolio/index.html — atualizar
<section id="projetos">
  <h2>Projetos</h2>
  <div class="grid-projetos">
    <article class="card destaque">
      <h3>🗂️ TaskFlow</h3>
      <p>Gerenciador de tarefas completo. Desenvolvido em HTML+CSS+JS puro, depois migrado para React e TypeScript.</p>
      <a href="#">Ver projeto →</a>
    </article>
    <article class="card">
      <h3>📍 Busca de CEP</h3>
      <p>Consulta de endereços usando a API ViaCEP com async/await.</p>
      <a href="#">Ver projeto →</a>
    </article>
    <article class="card">
      <h3>🌤️ App de Clima</h3>
      <p>Previsão do tempo com geolocalização e dados em tempo real.</p>
      <a href="#">Ver projeto →</a>
    </article>
  </div>
</section>

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 4

Recrie a galeria do Dia 3 usando CSS Grid em vez de Flexbox. Depois, adicione um elemento que ocupe 2 colunas (destaque). Compare o resultado com a versão Flexbox — qual ficou mais fácil de controlar?

solução — css
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; padding: 32px; background: #f5f5f5; }
h1 { text-align: center; margin-bottom: 24px; font-size: 1.8rem; }

.galeria {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.foto {
  height: 200px;
  border-radius: 12px;
}

/* Elemento em destaque: ocupa 2 colunas */
.foto.destaque {
  grid-column: span 2;
  height: 300px;
}
🏗️ Projeto do Dia — Portfólio: Seção de Projetos com Grid

Aplique as mudanças de CSS e HTML acima. Veja como o card "TaskFlow" ocupa duas colunas. Experimente adicionar mais cards e observe como o grid se adapta.

Opcional: acesse cssgridgarden.com e complete alguns níveis para fixar o grid.

🐙
Commit do dia
style: secao de projetos com css grid
✅ Checklist do Dia 4
Dia 5
Formulários HTML
Sexta-feira · Semana 1 · HTML CSS
📖 Tarde — Teoria (14:30–17:30)

Elementos de formulário

Formulários são como o usuário envia dados para o sistema. Em JavaScript (próxima fase), você vai capturar e processar esses dados. Por enquanto, foco na estrutura e no estilo.

html — elementos principais
<form action="/enviar" method="POST">

  <!-- LABEL sempre vinculado ao input pelo "for" = "id" -->
  <label for="nome">Nome completo</label>
  <input type="text" id="nome" name="nome" placeholder="Ex: João Silva" required>

  <!-- Tipos de input mais comuns -->
  <input type="email"    name="email"    placeholder="seu@email.com">
  <input type="password" name="senha"    placeholder="Mínimo 8 caracteres">
  <input type="number"   name="idade"    min="18" max="100">
  <input type="tel"      name="telefone" placeholder="(11) 99999-9999">
  <input type="date"     name="data">
  <input type="url"      name="site"     placeholder="https://">

  <!-- Checkbox e Radio -->
  <input type="checkbox" id="aceito" name="aceito">
  <label for="aceito">Aceito os termos de uso</label>

  <input type="radio" id="js" name="linguagem" value="js">
  <label for="js">JavaScript</label>
  <input type="radio" id="py" name="linguagem" value="py">
  <label for="py">Python</label>

  <!-- Select (dropdown) -->
  <label for="nivel">Nível</label>
  <select id="nivel" name="nivel">
    <option value="">Selecione...</option>
    <option value="iniciante">Iniciante</option>
    <option value="intermediario">Intermediário</option>
    <option value="avancado">Avançado</option>
  </select>

  <!-- Textarea -->
  <label for="mensagem">Mensagem</label>
  <textarea id="mensagem" name="mensagem" rows="5" placeholder="Escreva aqui..."></textarea>

  <!-- Botões -->
  <button type="submit">Enviar</button>
  <button type="reset">Limpar</button>
  <button type="button">Clique (não envia o form)</button>

</form>

Validação nativa do HTML

html — atributos de validação
<!-- required: campo obrigatório -->
<input type="text" required>

<!-- minlength / maxlength: tamanho do texto -->
<input type="password" minlength="8" maxlength="32">

<!-- min / max: para números e datas -->
<input type="number" min="1" max="10">

<!-- pattern: expressão regular para validar formato -->
<input type="text" pattern="[0-9]{5}-[0-9]{3}" placeholder="00000-000">

<!-- O navegador bloqueia o envio se a validação falhar -->

Estilizando formulários

css — formulário completo
/* Reset de estilos nativos dos inputs */
input, textarea, select, button {
  font-family: inherit;   /* herda a fonte do corpo */
  font-size: 1rem;
}

/* Campo de texto base */
.campo {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid #dee2e6;
  border-radius: 8px;
  background: #fff;
  color: #333;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}

/* Estado de foco — acessibilidade importante! */
.campo:focus {
  border-color: #264de4;
  box-shadow: 0 0 0 3px rgba(38, 77, 228, 0.15);
}

/* Estado inválido após interação */
.campo:invalid:not(:placeholder-shown) {
  border-color: #dc3545;
  box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.15);
}

/* Estado válido */
.campo:valid:not(:placeholder-shown) {
  border-color: #3fb950;
}

/* Label */
label {
  display: block;
  font-weight: 600;
  font-size: 0.875rem;
  color: #333;
  margin-bottom: 6px;
}

/* Grupo de campo */
.form-group {
  margin-bottom: 20px;
}

/* Select */
select.campo {
  cursor: pointer;
  appearance: none;           /* remove estilo nativo */
  background-image: url("data:image/svg+xml,...");  /* seta customizada */
}

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 5

Crie um formulário de cadastro de usuário em exercicios/dia-05/ com os campos: nome, e-mail, senha, data de nascimento, linguagem favorita (radio), nível (select) e um checkbox de termos. Adicione validação nativa e estilize tudo com CSS.

solução
<form>
  <div class="form-group">
    <label for="nome">Nome completo *</label>
    <input class="campo" type="text" id="nome" required minlength="3" placeholder="Seu nome">
  </div>
  <div class="form-group">
    <label for="email">E-mail *</label>
    <input class="campo" type="email" id="email" required placeholder="seu@email.com">
  </div>
  <div class="form-group">
    <label for="senha">Senha *</label>
    <input class="campo" type="password" id="senha" required minlength="8">
  </div>
  <div class="form-group">
    <label for="nascimento">Data de nascimento</label>
    <input class="campo" type="date" id="nascimento">
  </div>
  <div class="form-group">
    <label>Linguagem favorita</label>
    <div class="radio-group">
      <label><input type="radio" name="lang" value="js"> JavaScript</label>
      <label><input type="radio" name="lang" value="py"> Python</label>
      <label><input type="radio" name="lang" value="ts"> TypeScript</label>
    </div>
  </div>
  <div class="form-group">
    <label for="nivel">Nível atual</label>
    <select class="campo" id="nivel">
      <option value="">Selecione...</option>
      <option>Iniciante</option>
      <option>Intermediário</option>
      <option>Avançado</option>
    </select>
  </div>
  <div class="form-group">
    <label style="flex-direction:row;gap:8px;display:flex;align-items:center;font-weight:400">
      <input type="checkbox" required> Aceito os termos de uso
    </label>
  </div>
  <button type="submit" class="btn">Criar conta</button>
</form>
🏗️ Projeto do Dia — Portfólio: Seção de Contato

O formulário de contato já está no HTML desde o Dia 1. Hoje, aplique os estilos CSS da seção de formulários para deixá-lo bonito e com estados de foco visíveis. Adicione também o atributo required nos campos de nome, e-mail e mensagem.

🐙
Commit do dia
feat: formulario de contato estilizado com validacao
✅ Checklist do Dia 5
Dia 6
Responsividade
Segunda-feira · Semana 2 · CSS
📖 Tarde — Teoria (14:30–17:30)

O que é design responsivo?

Um site responsivo adapta seu layout para funcionar bem em qualquer tamanho de tela — do celular ao monitor ultrawide. Em 2024, mais de 60% do tráfego web vem de dispositivos móveis.

1. Viewport meta tag — obrigatório

Sem isso, o navegador mobile simula uma tela desktop e o site fica minúsculo. Já está no nosso HTML desde o Dia 1.

html — <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">

2. Media Queries

Media queries aplicam estilos CSS condicionalmente, dependendo do tamanho da tela.

css
/* Aplica quando a tela tem ATÉ 768px de largura */
@media (max-width: 768px) {
  .nav-menu { display: none; }
  h1 { font-size: 1.8rem; }
}

/* Aplica quando a tela tem PELO MENOS 768px */
@media (min-width: 768px) {
  .container { padding: 0 48px; }
}

/* Aplica ENTRE dois tamanhos */
@media (min-width: 480px) and (max-width: 768px) {
  .grid { grid-template-columns: repeat(2, 1fr); }
}

3. Breakpoints comuns

Nome Tamanho Dispositivos
Mobile até 480px Smartphones pequenos
Mobile L até 768px Smartphones grandes
Tablet 769px – 1024px Tablets, iPad
Desktop 1025px – 1280px Notebooks
Wide 1281px+ Monitores grandes

4. Mobile-first — a abordagem correta

Escreva o CSS base para mobile e use min-width para adicionar estilos em telas maiores. É mais fácil escalar para cima do que comprimir para baixo.

css — mobile-first
/* BASE: mobile (sem media query) */
.grid-projetos {
  display: grid;
  grid-template-columns: 1fr;  /* 1 coluna no mobile */
  gap: 16px;
}

/* TABLET: 2 colunas */
@media (min-width: 640px) {
  .grid-projetos {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* DESKTOP: 3 colunas */
@media (min-width: 1024px) {
  .grid-projetos {
    grid-template-columns: repeat(3, 1fr);
  }
}

5. Imagens responsivas

css
/* Nunca ultrapassa o container pai */
img {
  max-width: 100%;
  height: auto;     /* mantém proporção */
  display: block;
}

Portfólio — Tornando responsivo

Adicione ao final do style.css:

portfolio/style.css — adicionar no final
/* ===== RESPONSIVIDADE ===== */

@media (max-width: 768px) {
  /* Título hero menor */
  #hero h1 { font-size: 2rem; }
  #hero p  { font-size: 1rem; }

  /* Grid de projetos: 1 coluna */
  #projetos .grid-projetos {
    grid-template-columns: 1fr;
  }

  /* Card destaque: sem span no mobile */
  .card.destaque {
    grid-column: span 1;
  }

  /* Seções com menos padding */
  section {
    padding: 48px 16px;
  }

  /* Navbar: ocultar links (voltaremos com JS depois) */
  header nav ul {
    display: none;
  }
}
Como testar responsividade: No Chrome/Firefox, pressione F12 → clique no ícone de dispositivo móvel (ou Ctrl+Shift+M). Você pode simular diferentes tamanhos de tela.

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 6

Pegue o exercício da galeria (Dia 3 ou 4) e torne-a responsiva sem usar auto-fill — use media queries manualmente:

  • Mobile: 1 coluna
  • Tablet (≥ 480px): 2 colunas
  • Desktop (≥ 768px): 3 colunas
solução
.galeria {
  display: grid;
  grid-template-columns: 1fr;   /* mobile: 1 coluna */
  gap: 16px;
}

@media (min-width: 480px) {
  .galeria {
    grid-template-columns: repeat(2, 1fr);  /* tablet: 2 */
  }
}

@media (min-width: 768px) {
  .galeria {
    grid-template-columns: repeat(3, 1fr);  /* desktop: 3 */
  }
}
🏗️ Projeto do Dia — Portfólio: Responsividade

Aplique as media queries ao portfólio. Teste no DevTools (F12) em diferentes tamanhos: 375px (iPhone), 768px (iPad), 1280px (desktop). Corrija qualquer coisa que esteja estranha no mobile.

🐙
Commit do dia
style: responsividade mobile no portfolio
✅ Checklist do Dia 6
Dia 7
Variáveis CSS e Pseudo-classes
Terça-feira · Semana 2 · CSS
📖 Tarde — Teoria (14:30–17:30)

Variáveis CSS (Custom Properties)

Variáveis CSS permitem armazenar valores (cores, tamanhos, fontes) em um lugar e reutilizá-los em todo o código. Trocar uma cor do tema fica trivial.

css
/* Declaração: sempre no :root para acesso global */
:root {
  /* Paleta */
  --cor-primaria: #264de4;
  --cor-primaria-hover: #1a3ab8;
  --cor-fundo: #0d1117;
  --cor-texto: #e6edf3;
  --cor-texto-suave: #8892a4;

  /* Tipografia */
  --fonte-base: 'Segoe UI', system-ui, sans-serif;
  --tamanho-base: 16px;

  /* Espaçamento */
  --espacamento-sm: 8px;
  --espacamento-md: 16px;
  --espacamento-lg: 32px;

  /* Borda */
  --radius: 8px;
  --borda: 1px solid rgba(255,255,255,0.08);
}

/* Uso: var(--nome-da-variavel) */
body {
  font-family: var(--fonte-base);
  color: var(--cor-texto);
  background: var(--cor-fundo);
}

.btn {
  background: var(--cor-primaria);
  border-radius: var(--radius);
  padding: var(--espacamento-sm) var(--espacamento-lg);
}

.btn:hover {
  background: var(--cor-primaria-hover);
}

/* Dark/Light mode com variáveis */
[data-tema="claro"] {
  --cor-fundo: #ffffff;
  --cor-texto: #1a1a2e;
}

Pseudo-classes

Pseudo-classes selecionam elementos em estados específicos ou posições na estrutura.

css
/* Estados de interação */
a:hover   { color: blue; }          /* mouse em cima */
a:visited { color: purple; }        /* link já visitado */
a:active  { color: red; }           /* clicando agora */

input:focus  { border-color: blue; }  /* elemento focado */
input:disabled { opacity: 0.5; }      /* campo desabilitado */

/* Posição na estrutura */
li:first-child { font-weight: bold; }   /* primeiro filho */
li:last-child  { border-bottom: none; } /* último filho */
li:nth-child(2) { color: red; }         /* segundo filho */
li:nth-child(odd)  { background: #f5f5f5; } /* filhos ímpares */
li:nth-child(even) { background: #fff; }    /* filhos pares */
li:nth-child(3n) { color: blue; }      /* a cada 3 filhos */

/* Estado de formulário */
input:valid   { border-color: green; }
input:invalid { border-color: red; }
input:required::after { content: " *"; color: red; }

/* Elemento sem filhos */
p:empty { display: none; }

/* Negação */
li:not(:last-child) { border-bottom: 1px solid #eee; }

Pseudo-elementos

Pseudo-elementos criam elementos virtuais no DOM — úteis para decorações sem poluir o HTML.

css
/* ::before e ::after: inserem conteúdo antes/depois do elemento */
/* Sempre precisam de "content" (pode ser vazio "") */

/* Ícone de asterisco em campos obrigatórios */
label.obrigatorio::after {
  content: " *";
  color: red;
}

/* Linha decorativa abaixo do título */
h2 {
  position: relative;
  padding-bottom: 12px;
}
h2::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 48px;
  height: 3px;
  background: var(--cor-primaria);
  border-radius: 99px;
}

/* Seta decorativa em cards */
.card::before {
  content: "→";
  position: absolute;
  top: 20px;
  right: 20px;
  color: var(--cor-primaria);
  opacity: 0;
  transition: opacity 0.2s;
}
.card:hover::before { opacity: 1; }

/* Selecionar texto */
::selection {
  background: rgba(38, 77, 228, 0.3);
  color: white;
}

Portfólio — Variáveis e efeitos hover

Refatore o início do style.css para usar variáveis CSS:

portfolio/style.css — refatorar topo
:root {
  --primaria: #264de4;
  --primaria-hover: #1a3ab8;
  --fundo-escuro: #0d1117;
  --fundo-card: #ffffff;
  --texto: #1a1a2e;
  --texto-suave: #666;
  --borda: #e9ecef;
  --radius: 12px;
  --sombra: 0 8px 30px rgba(0,0,0,0.08);
}

/* Linha decorativa nos h2 */
h2 {
  position: relative;
  padding-bottom: 14px;
  margin-bottom: 32px;
}
h2::after {
  content: "";
  position: absolute;
  bottom: 0; left: 0;
  width: 40px; height: 3px;
  background: var(--primaria);
  border-radius: 99px;
}

/* Hover nos cards */
.card {
  position: relative;
  overflow: hidden;
}
.card::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 3px; height: 100%;
  background: var(--primaria);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 0.25s ease;
}
.card:hover::before { transform: scaleY(1); }

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 7

Crie uma lista de 10 itens de menu de restaurante estilizando com pseudo-classes e pseudo-elementos:

  • Alternar cor de fundo nos itens pares/ímpares (:nth-child)
  • Negrito no primeiro e último item
  • Remover borda do último item com :not(:last-child)
  • Adicionar um emoji "🍽️" antes de cada item com ::before
  • Efeito hover que muda a cor de fundo e move o item 4px para a direita
solução — css
:root { --primaria: #264de4; }

.menu { list-style: none; max-width: 400px; border: 1px solid #eee; border-radius: 12px; overflow: hidden; }

.menu li {
  position: relative;
  padding: 14px 14px 14px 40px;
  border-bottom: 1px solid #eee;
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
}

.menu li::before {
  content: "🍽️";
  position: absolute;
  left: 12px;
}

.menu li:nth-child(even) { background: #f9f9f9; }
.menu li:first-child, .menu li:last-child { font-weight: 700; }
.menu li:not(:last-child) { border-bottom: 1px solid #eee; }
.menu li:last-child { border-bottom: none; }
.menu li:hover { background: rgba(38,77,228,.08); transform: translateX(4px); }
🏗️ Projeto do Dia — Portfólio: Refatoração com Variáveis

Aplique a refatoração com variáveis CSS e adicione os pseudo-elementos nos h2 e nos cards. Lembre-se de substituir as cores hardcoded por var(--primaria) em todo o arquivo.

🐙
Commit do dia
style: variaveis css e pseudo-elementos no portfolio
✅ Checklist do Dia 7
Dia 8
Transições e Animações
Quarta-feira · Semana 2 · CSS
📖 Tarde — Teoria (14:30–17:30)

transition — animações de estado

A propriedade transition anima a mudança de um valor CSS para outro (por exemplo, ao passar o mouse).

css
.btn {
  background: #264de4;
  /* transition: propriedade duração timing-function delay */
  transition: background 0.2s ease;

  /* Múltiplas propriedades */
  transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.3s ease;

  /* Atalho para animar tudo (cuidado: pode ser lento) */
  transition: all 0.2s ease;
}

.btn:hover {
  background: #1a3ab8;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(38, 77, 228, 0.4);
}

/* Timing functions */
transition: color 0.3s ease;          /* suave (padrão) */
transition: color 0.3s ease-in;       /* começa devagar */
transition: color 0.3s ease-out;      /* termina devagar */
transition: color 0.3s ease-in-out;   /* começa e termina devagar */
transition: color 0.3s linear;        /* velocidade constante */
transition: color 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); /* personalizado (bounce) */

Propriedades mais animadas

Propriedade Para que serve
opacity Aparecer/desaparecer (0 = invisível, 1 = visível)
transform Mover, girar, escalar sem afetar o layout
background-color Mudança de cor de fundo
color Mudança de cor de texto
box-shadow Sombra aparecendo/mudando
border-color Borda mudando de cor

transform — movimentar sem quebrar o layout

css
.elemento {
  /* Mover */
  transform: translateX(20px);    /* horizontal */
  transform: translateY(-10px);   /* vertical (negativo = para cima) */
  transform: translate(10px, -5px); /* ambos */

  /* Escalar */
  transform: scale(1.1);          /* 10% maior */
  transform: scale(0.95);         /* 5% menor */
  transform: scaleX(1.5);         /* só horizontal */

  /* Girar */
  transform: rotate(45deg);       /* 45 graus horário */
  transform: rotate(-90deg);      /* 90 graus anti-horário */

  /* Inclinar */
  transform: skewX(10deg);

  /* Combinar (ordem importa!) */
  transform: translateY(-4px) scale(1.02);
}

@keyframes — animações completas

Para animações mais complexas que não dependem de interação do usuário.

css
/* Definindo a animação */
@keyframes aparecer {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pulsar {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}

@keyframes girar {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Aplicando a animação */
.hero-title {
  /* animation: nome duração timing delay repetições direção */
  animation: aparecer 0.6s ease-out forwards;
}

.loader {
  animation: girar 1s linear infinite;
}

.badge {
  animation: pulsar 2s ease-in-out infinite;
}

Spinner em CSS puro — mini projeto

html + css
<div class="spinner"></div>
css
@keyframes spin {
  to { transform: rotate(360deg); }
}

.spinner {
  width: 40px;
  height: 40px;
  border: 3px solid rgba(38, 77, 228, 0.2);
  border-top-color: #264de4;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

Portfólio — Animações de entrada

portfolio/style.css — adicionar
/* Animação de entrada para o hero */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: translateY(0); }
}

#hero h1 {
  animation: fadeUp 0.7s ease-out forwards;
}
#hero p {
  animation: fadeUp 0.7s 0.15s ease-out both;
}
#hero .btn {
  animation: fadeUp 0.7s 0.3s ease-out both;
}
#hero .tags {
  animation: fadeUp 0.7s 0.45s ease-out both;
}

/* Respeitar preferência do usuário por menos movimento */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 8

Crie uma página com um botão e um card que demonstra 4 tipos de animação:

  • Botão com transition de cor e sombra no hover
  • Card com transform: translateY no hover
  • Um spinner com @keyframes
  • Um elemento que aparece com animação de fade-in ao carregar a página
solução — css
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes spin {
  to { transform: rotate(360deg); }
}

body { font-family: sans-serif; padding: 40px; background: #f5f5f5; display: flex; flex-direction: column; gap: 24px; align-items: flex-start; }

.btn {
  padding: 12px 28px; background: #264de4; color: white; border: none;
  border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer;
  transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
}
.btn:hover {
  background: #1a3ab8; transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(38,77,228,0.4);
}

.card {
  background: white; border: 1px solid #e9ecef; border-radius: 12px;
  padding: 24px; width: 280px;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
  animation: fadeIn 0.8s ease-out forwards;
}
.card:hover { transform: translateY(-6px); box-shadow: 0 12px 32px rgba(0,0,0,0.1); }

.spinner {
  width: 40px; height: 40px; border-radius: 50%;
  border: 3px solid rgba(38,77,228,0.2);
  border-top-color: #264de4;
  animation: spin 0.8s linear infinite;
}
🏗️ Projeto do Dia — Portfólio: Animações de Entrada

Aplique as animações de fadeUp no hero. Recarregue a página e observe o efeito cascata nos elementos do hero aparecendo com delays diferentes. Adicione também transições suaves nos links da navegação.

🐙
Commit do dia
style: transicoes e animacoes de entrada no portfolio
✅ Checklist do Dia 8
Dia 9
Position e z-index
Quinta-feira · Semana 2 · CSS
📖 Tarde — Teoria (14:30–17:30)

Como position funciona

A propriedade position define como um elemento é posicionado no documento. É fundamental para menus dropdown, modais, tooltips, cabeçalhos fixos e overlays.

static — o padrão

css
/* static é o padrão de todos os elementos */
/* top, right, bottom, left e z-index NÃO funcionam com static */
.elemento { position: static; }

relative — relativo a si mesmo

css
.caixa {
  position: relative;
  top: 10px;    /* move 10px para baixo DO LUGAR ORIGINAL */
  left: 20px;   /* move 20px para a direita DO LUGAR ORIGINAL */
  /* O espaço original é preservado no layout */
}

/* Uso mais importante: criar um "âncora" para filhos absolute */
.container {
  position: relative; /* filho absolute se posicionará em relação a este */
}

absolute — relativo ao pai com position

css
/* O elemento sai do fluxo normal — não ocupa espaço */
/* Se posiciona em relação ao pai mais próximo com position != static */

.card {
  position: relative; /* âncora para filhos */
}
.card .badge {
  position: absolute;
  top: 12px;
  right: 12px;
  /* Agora "12px do topo do card" e "12px da direita do card" */
}

fixed — relativo à viewport

css
/* Fica fixo na tela mesmo ao rolar a página */
header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;  /* obrigatório: ocupa a largura total */
  z-index: 100; /* fica acima de outros elementos */
}

/* Botão de "voltar ao topo" */
.btn-top {
  position: fixed;
  bottom: 24px;
  right: 24px;
}

sticky — híbrido de relative e fixed

css
/* Funciona como relative ATÉ chegar no threshold,
   depois funciona como fixed dentro do container pai */
.menu-categoria {
  position: sticky;
  top: 60px;   /* gruda a 60px do topo quando chegar lá */
}

/* Muito usado em: headers de tabela, sidebars, menus de seção */

z-index — controle de camadas

css
/* Só funciona em elementos com position != static */
/* Maior número = mais na frente */

.overlay   { position: fixed; z-index: 400; }
.modal     { position: fixed; z-index: 500; }
.tooltip   { position: absolute; z-index: 600; }

/* Convenção de z-index por camadas */
:root {
  --z-base:    0;
  --z-elevado: 10;
  --z-sticky:  100;
  --z-header:  200;
  --z-overlay: 400;
  --z-modal:   500;
  --z-toast:   700;
}

Dropdown com position — mini projeto

html
<nav>
  <div class="menu-item">
    Projetos ▾
    <ul class="dropdown">
      <li><a href="#">TaskFlow</a></li>
      <li><a href="#">Busca de CEP</a></li>
      <li><a href="#">App de Clima</a></li>
    </ul>
  </div>
</nav>
css
.menu-item {
  position: relative;
  cursor: pointer;
  padding: 8px 16px;
}

.dropdown {
  position: absolute;
  top: 100%;        /* logo abaixo do pai */
  left: 0;
  background: white;
  border: 1px solid #eee;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  list-style: none;
  min-width: 180px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
  z-index: 200;
}

/* Mostrar ao hover */
.menu-item:hover .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.dropdown li a {
  display: block;
  padding: 10px 16px;
  color: #333;
  text-decoration: none;
  transition: background 0.15s;
}
.dropdown li a:hover { background: #f5f5f5; }

💻 Noite — Prática (21:00–23:00)
📝 Exercício — Dia 9

Crie um card de produto com:

  • Um badge "NOVO" no canto superior direito com position: absolute
  • Um overlay de hover que escurece a imagem com position: absolute e opacity
  • Um botão "Ver mais" que aparece sobre o overlay ao hover
solução — html + css
.card-produto {
  position: relative;
  width: 260px;
  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
}
.card-imagem {
  width: 100%; height: 200px;
  background: linear-gradient(135deg, #264de4, #61dafb);
}
.badge-novo {
  position: absolute; top: 12px; right: 12px;
  background: #f0883e; color: white;
  font-size: 11px; font-weight: 700; padding: 4px 10px;
  border-radius: 99px;
}
.overlay {
  position: absolute; inset: 0;  /* shorthand para top right bottom left */
  background: rgba(0,0,0,0.5);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity 0.25s;
}
.card-produto:hover .overlay { opacity: 1; }
.btn-overlay {
  background: white; color: #333;
  padding: 10px 20px; border-radius: 8px;
  font-weight: 600; font-size: 14px;
  transform: translateY(10px);
  transition: transform 0.25s;
}
.card-produto:hover .btn-overlay { transform: translateY(0); }
🏗️ Projeto do Dia — Portfólio: Dropdown na Navbar

Adicione o menu dropdown de projetos na navbar do portfólio. O header já tem position: sticky do CSS do Dia 2. Adicione o dropdown de projetos usando o código acima, adaptando os links para as seções do portfólio.

🐙
Commit do dia
feat: dropdown de projetos na navbar com css position
✅ Checklist do Dia 9
Dia 10
Revisão Final + GitHub Pages
Sexta-feira · Semana 2 · Git Deploy
📖 Tarde — Revisão (14:30–17:30)

Revisão geral — checklist técnico

Antes de publicar, revise o portfólio com este checklist:

📋 Revisão HTML
📋 Revisão CSS

💻 Noite — Deploy (21:00–23:00)

Publicando no GitHub Pages

GitHub Pages permite hospedar sites estáticos gratuitamente diretamente de um repositório.

Passo a passo

  1. Certifique-se que seu código está atualizado no GitHub (git push origin main)
  2. Acesse seu repositório html-css-review no GitHub
  3. Clique em Settings (aba no topo)
  4. No menu lateral, clique em Pages
  5. Em "Source", selecione main e a pasta /root
  6. Clique em Save
  7. Aguarde 2–5 minutos e acesse: https://SEU-USUARIO.github.io/html-css-review/portfolio/
Dica: Coloque um link para o GitHub Pages no README do repositório. Isso facilita muito quando recrutadores acessam seu GitHub.

README do repositório

Um bom README faz diferença. Atualize o README.md com este modelo:

README.md
# HTML & CSS Review — DevTrail Fase 0

Revisão e prática de HTML e CSS como parte da minha trilha de desenvolvimento front-end.

## 🔗 Demo ao vivo
[Ver portfólio no GitHub Pages](https://SEU-USUARIO.github.io/html-css-review/portfolio/)

## 📁 Estrutura
- `portfolio/` — Página de portfólio pessoal (projeto principal da fase)
- `exercicios/` — Exercícios diários de HTML e CSS

## 📚 O que aprendi nesta fase
- HTML5 semântico e acessibilidade
- CSS: seletores, box model, tipografia
- Flexbox e CSS Grid
- Design responsivo com media queries
- Variáveis CSS, pseudo-classes e pseudo-elementos
- Transições e animações CSS
- Position e z-index
- Deploy com GitHub Pages

## 🛠️ Tecnologias
HTML5 · CSS3 · Git · GitHub Pages
🐙
Commit final da fase
feat: portfolio finalizado e publicado no github pages
Este é o último commit desta fase. Parabéns! 🎉
✅ Checklist do Dia 10
🏁
Portfólio Completo — O que você construiu
Fase 0 concluída · Portfólio GitHub Pages

Evolução dia a dia

Dia O que foi adicionado ao portfólio
Dia 1 Estrutura HTML semântica completa (header, main, footer, seções)
Dia 2 CSS base: tipografia, cores, box model, botão, header dark
Dia 3 Flexbox no hero: tags empilhadas, navbar alinhada
Dia 4 Grid na seção de projetos com card em destaque
Dia 5 Formulário de contato estilizado com validação nativa
Dia 6 Responsividade completa testada em mobile, tablet e desktop
Dia 7 Variáveis CSS, linha decorativa nos h2, efeito hover nos cards
Dia 8 Animações de entrada no hero (fadeUp com delays)
Dia 9 Dropdown de projetos na navbar
Dia 10 Revisão, polimento final e deploy no GitHub Pages

Checklist de avanço para a Fase 1 — JavaScript

Você está pronto quando conseguir marcar tudo
🎉 Parabéns por concluir a Fase 0! Você tem agora a base para que o JavaScript faça sentido. Na Fase 1, cada coisa que você aprendeu aqui (estrutura HTML, classes CSS, formulários) vai ser manipulada dinamicamente com código. Vamos começar!