← Back to course

Финальный Мини-Проект: Responsive Landing Page

Финальный Мини-Проект: Responsive Landing Page

Добро пожаловать в последний урок этого CSS course.

Ты дошёл сюда.

Твой browser выжил.

Твой CSS выжил.

Наверное.

В этом уроке мы объединим всё, что ты изучил, в один mini project.

Мы построим responsive landing page.

Она будет включать:

Здесь CSS перестаёт быть набором случайных properties и начинает становиться настоящим website.

Маленькие CSS pieces наконец встречаются вместе.

Как frontend family dinner.

Надеемся, с меньшим количеством ссор.

Что Ты Построишь

Ты создашь landing page для вымышленного web service под названием FastSite Studio.

Page будет иметь:

Этот project использует много вещей из предыдущих уроков:

Сегодня нет нового монстра.

Только собираем tools вместе.

Как сборка мебели, но с меньшим количеством загадочных винтов.

Создай Проект

Создай folder для final project:

mkdir css-lesson10
cd css-lesson10
touch index.html
touch style.css

Ты должен получить:

css-lesson10/
  index.html
  style.css

Открой folder в своём editor.

Это наш final CSS playground.

Без страха.

Только semicolons.

И, возможно, один dramatic refresh.

Напиши HTML

Открой index.html и добавь это:

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>FastSite Studio</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header class="hero">
    <nav class="navbar">
      <h1 class="logo">FastSite Studio</h1>

      <div class="nav-links">
        <a href="#">Главная</a>
        <a href="#">Функции</a>
        <a href="#">Цены</a>
        <a href="#">Контакт</a>
      </div>
    </nav>

    <section class="hero-content">
      <p class="eyebrow">Modern CSS Project</p>
      <h2>Построй Быстрый, Чистый и Responsive Website</h2>
      <p>
        Практикуй CSS layout, responsive design, cards, buttons, shadows и transitions в одном полном mini project.
      </p>

      <div class="hero-actions">
        <a href="#" class="button primary-button">Начать Строить</a>
        <a href="#" class="button secondary-button">Посмотреть Функции</a>
      </div>
    </section>
  </header>

  <main>
    <section class="section intro-section">
      <div class="section-header">
        <p class="eyebrow dark">Что Ты Практикуешь</p>
        <h2>Здесь Всё Объединяется</h2>
        <p>
          Этот project объединяет самые важные beginner CSS skills в layout, который можно использовать для реальных websites.
        </p>
      </div>

      <div class="feature-grid">
        <article class="feature-card">
          <div class="icon">⚡</div>
          <h3>Быстрый Layout</h3>
          <p>Используй Grid и Flexbox, чтобы создавать sections, которые чистые, структурированные и легко изменяются.</p>
        </article>

        <article class="feature-card">
          <div class="icon">📱</div>
          <h3>Responsive Design</h3>
          <p>Сделай page адаптивной для laptops, tablets и phones без horizontal scrolling chaos.</p>
        </article>

        <article class="feature-card">
          <div class="icon">🎨</div>
          <h3>Polished Styling</h3>
          <p>Добавь colors, borders, shadows, spacing и hover effects, чтобы page выглядела завершённой.</p>
        </article>
      </div>
    </section>

    <section class="section pricing-section">
      <div class="section-header">
        <p class="eyebrow dark">Цены</p>
        <h2>Выбери Своё CSS Приключение</h2>
        <p>
          Эти pricing cards — только практика, но этот layout pattern используется на реальных landing pages везде.
        </p>
      </div>

      <div class="pricing-grid">
        <article class="pricing-card">
          <h3>Basic</h3>
          <p class="price">€99</p>
          <p>Идеально для практики layout basics.</p>
          <ul>
            <li>One-page layout</li>
            <li>Simple cards</li>
            <li>Basic responsive design</li>
          </ul>
          <a href="#" class="button card-button">Выбрать Basic</a>
        </article>

        <article class="pricing-card featured-card">
          <p class="badge">Популярное</p>
          <h3>Standard</h3>
          <p class="price">€199</p>
          <p>Лучший вариант для построения polished responsive page.</p>
          <ul>
            <li>Responsive sections</li>
            <li>Cards и buttons</li>
            <li>Hover transitions</li>
          </ul>
          <a href="#" class="button card-button">Выбрать Standard</a>
        </article>

        <article class="pricing-card">
          <h3>Premium</h3>
          <p class="price">€299</p>
          <p>Для момента, когда твой CSS уже готов надеть костюм.</p>
          <ul>
            <li>Advanced layout</li>
            <li>Polished visual style</li>
            <li>Reusable structure</li>
          </ul>
          <a href="#" class="button card-button">Выбрать Premium</a>
        </article>
      </div>
    </section>
  </main>

  <footer class="site-footer">
    <p>Создано с HTML, CSS, patience и несколькими храбрыми semicolons.</p>
  </footer>
</body>
</html>

Этот HTML даёт нам полную structure.

Теперь нужен CSS.

Пока что page — это raw HTML.

Полезно, но без шарма.

Как pasta без соуса.

Технически еда.

Эмоционально незавершённая.

Добавь Base Styles

Открой style.css и добавь:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
  background-color: #f3f4f6;
  color: #111827;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  padding-left: 20px;
}

Это даёт нам:

Good foundation.

Final project требует stable foundation.

Иначе CSS начинает вести себя как shopping cart с одним сломанным колесом.

Стилизуй Hero

Добавь:

.hero {
  background: linear-gradient(135deg, #111827, #1e3a8a);
  color: white;
}

Это создаёт dark hero background.

Теперь стилизуй navbar:

.navbar {
  max-width: 1100px;
  margin: 0 auto;
  padding: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.logo {
  margin: 0;
  font-size: 24px;
}

.nav-links {
  display: flex;
  gap: 20px;
  font-weight: 700;
}

Navbar теперь использует Flexbox.

Logo слева.

Links справа.

Clean.

Simple.

Достаточно professional, чтобы CSS попросил LinkedIn profile.

Стилизуй Hero Content

Добавь:

.hero-content {
  max-width: 850px;
  margin: 0 auto;
  padding: 90px 24px 110px;
  text-align: center;
}

.eyebrow {
  margin: 0 0 16px;
  color: #bfdbfe;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.hero-content h2 {
  margin: 0 0 20px;
  font-size: 58px;
  line-height: 1.1;
}

.hero-content p {
  margin: 0 auto;
  max-width: 700px;
  color: #dbeafe;
  font-size: 20px;
  line-height: 1.7;
}

Теперь hero имеет:

Это visual hierarchy.

User видит самое важное первым.

Heading first.

Text second.

Button next.

Good layout не заставляет user искать meaning с фонариком.

Стилизуй Buttons

Добавь:

.hero-actions {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 28px;
}

.button {
  display: inline-block;
  padding: 14px 22px;
  border-radius: 999px;
  font-weight: 700;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.button:hover {
  transform: translateY(-3px);
}

.primary-button {
  background-color: white;
  color: #1e3a8a;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.22);
}

.secondary-button {
  border: 2px solid rgba(255, 255, 255, 0.5);
  color: white;
}

Теперь hero имеет два buttons.

Один primary.

Один secondary.

Primary button сильнее.

Secondary button спокойнее.

Это важно.

Не каждый button должен кричать.

Если каждый button кричит, page становится meeting, где все говорят одновременно.

Ужас.

Создай Reusable Section Styles

Добавь:

.section {
  max-width: 1100px;
  margin: 0 auto;
  padding: 72px 24px;
}

.section-header {
  max-width: 760px;
  margin: 0 auto 36px;
  text-align: center;
}

.eyebrow.dark {
  color: #2563eb;
}

.section-header h2 {
  margin: 0 0 16px;
  font-size: 38px;
  line-height: 1.2;
}

.section-header p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

Теперь sections имеют consistent spacing.

Consistency важна.

Website с random spacing выглядит nervous.

Будто CSS пытается вспомнить, где припарковал car.

Создай Feature Cards

Добавь:

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

.feature-card {
  background-color: white;
  padding: 28px;
  border: 2px solid #e5e7eb;
  border-radius: 24px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.feature-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
}

.icon {
  width: 52px;
  height: 52px;
  border-radius: 18px;
  background-color: #dbeafe;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  margin-bottom: 18px;
}

.feature-card h3 {
  margin: 0 0 12px;
  font-size: 24px;
}

.feature-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

Это использует CSS Grid для cards.

Three columns на desktop.

Nice spacing.

Soft shadows.

Hover movement.

Page начинает выглядеть так, будто знает, что делает.

Опасно professional.

Стилизуй Pricing Section

Додай:

.pricing-section {
  padding-top: 40px;
}

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

.pricing-card {
  position: relative;
  background-color: white;
  padding: 32px;
  border: 2px solid #e5e7eb;
  border-radius: 28px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.pricing-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
  border-color: #2563eb;
}

.pricing-card h3 {
  margin: 0 0 12px;
  font-size: 26px;
}

.price {
  margin: 0 0 16px;
  font-size: 42px;
  font-weight: 800;
  color: #1e3a8a;
}

.pricing-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.6;
}

.pricing-card li {
  margin-bottom: 8px;
  color: #374151;
}

Теперь pricing cards выглядят structured.

Price большой.

Text readable.

Cards имеют depth.

Pricing card должна быть easy to scan.

Users не должны нуждаться в treasure map, чтобы найти price.

Featured Pricing Card

Добавь:

.featured-card {
  border-color: #2563eb;
  background-color: #eff6ff;
}

.badge {
  display: inline-block;
  margin: 0 0 16px;
  background-color: #2563eb;
  color: white !important;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 14px !important;
  font-weight: 700;
}

Middle card теперь выделяется.

Она имеет badge.

Она имеет blue border.

Она имеет soft blue background.

Она говорит:

“Посмотри сюда.”

А не:

“СМОТРИ СЮДА, ИНАЧЕ Я СЕЙЧАС НАЧНУ МИГАТЬ.”

Хорошо.

Card Buttons

Добавь:

.card-button {
  margin-top: 18px;
  background-color: #2563eb;
  color: white;
  text-align: center;
  width: 100%;
}

.card-button:hover {
  box-shadow: 0 12px 25px rgba(37, 99, 235, 0.3);
}

Теперь каждая pricing card имеет full-width button.

Это common pattern в pricing sections.

Easy to click.

Easy to understand.

No mystery.

Mystery — для detective novels.

Не для pricing cards.

Footer

Добавь:

.site-footer {
  text-align: center;
  padding: 36px 24px;
  color: #6b7280;
}

Simple footer.

No drama.

Final projects не требуют dramatic footers.

Footer не main character.

Сделай Это Responsive

Теперь добавь media queries.

Сначала для tablets:

@media (max-width: 850px) {
  .hero-content h2 {
    font-size: 44px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

Теперь cards становятся two columns на medium screens.

Потом для phones:

@media (max-width: 600px) {
  .navbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .nav-links {
    flex-direction: column;
    gap: 12px;
  }

  .hero-content {
    text-align: left;
    padding: 64px 20px 80px;
  }

  .hero-content h2 {
    font-size: 36px;
  }

  .hero-content p {
    font-size: 18px;
  }

  .hero-actions {
    justify-content: flex-start;
  }

  .section {
    padding: 56px 20px;
  }

  .section-header {
    text-align: left;
  }

  .section-header h2 {
    font-size: 30px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: 1fr;
  }
}

Теперь page работает на phones.

Navbar stacks.

Cards становятся one column.

Text gets smaller.

Spacing becomes more compact.

Это responsive design doing its job.

No sideways scrolling.

No tiny unreadable cards.

No user rage.

Excellent.

Добавь Reduced Motion Support

Добавь это в конец:

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none;
  }
}

Это помогает users, которые prefer less motion.

Это маленький detail.

Но good websites care about details.

И users.

Mostly users.

CSS существует для людей, а не только для screenshots.

Полный CSS

Твой style.css должен выглядеть так:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
  background-color: #f3f4f6;
  color: #111827;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  padding-left: 20px;
}

.hero {
  background: linear-gradient(135deg, #111827, #1e3a8a);
  color: white;
}

.navbar {
  max-width: 1100px;
  margin: 0 auto;
  padding: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.logo {
  margin: 0;
  font-size: 24px;
}

.nav-links {
  display: flex;
  gap: 20px;
  font-weight: 700;
}

.hero-content {
  max-width: 850px;
  margin: 0 auto;
  padding: 90px 24px 110px;
  text-align: center;
}

.eyebrow {
  margin: 0 0 16px;
  color: #bfdbfe;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.hero-content h2 {
  margin: 0 0 20px;
  font-size: 58px;
  line-height: 1.1;
}

.hero-content p {
  margin: 0 auto;
  max-width: 700px;
  color: #dbeafe;
  font-size: 20px;
  line-height: 1.7;
}

.hero-actions {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 28px;
}

.button {
  display: inline-block;
  padding: 14px 22px;
  border-radius: 999px;
  font-weight: 700;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.button:hover {
  transform: translateY(-3px);
}

.primary-button {
  background-color: white;
  color: #1e3a8a;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.22);
}

.secondary-button {
  border: 2px solid rgba(255, 255, 255, 0.5);
  color: white;
}

.section {
  max-width: 1100px;
  margin: 0 auto;
  padding: 72px 24px;
}

.section-header {
  max-width: 760px;
  margin: 0 auto 36px;
  text-align: center;
}

.eyebrow.dark {
  color: #2563eb;
}

.section-header h2 {
  margin: 0 0 16px;
  font-size: 38px;
  line-height: 1.2;
}

.section-header p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

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

.feature-card {
  background-color: white;
  padding: 28px;
  border: 2px solid #e5e7eb;
  border-radius: 24px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.feature-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
}

.icon {
  width: 52px;
  height: 52px;
  border-radius: 18px;
  background-color: #dbeafe;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  margin-bottom: 18px;
}

.feature-card h3 {
  margin: 0 0 12px;
  font-size: 24px;
}

.feature-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.7;
}

.pricing-section {
  padding-top: 40px;
}

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

.pricing-card {
  position: relative;
  background-color: white;
  padding: 32px;
  border: 2px solid #e5e7eb;
  border-radius: 28px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.pricing-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.1);
  border-color: #2563eb;
}

.pricing-card h3 {
  margin: 0 0 12px;
  font-size: 26px;
}

.price {
  margin: 0 0 16px;
  font-size: 42px;
  font-weight: 800;
  color: #1e3a8a;
}

.pricing-card p {
  color: #4b5563;
  font-size: 18px;
  line-height: 1.6;
}

.pricing-card li {
  margin-bottom: 8px;
  color: #374151;
}

.featured-card {
  border-color: #2563eb;
  background-color: #eff6ff;
}

.badge {
  display: inline-block;
  margin: 0 0 16px;
  background-color: #2563eb;
  color: white !important;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 14px !important;
  font-weight: 700;
}

.card-button {
  margin-top: 18px;
  background-color: #2563eb;
  color: white;
  text-align: center;
  width: 100%;
}

.card-button:hover {
  box-shadow: 0 12px 25px rgba(37, 99, 235, 0.3);
}

.site-footer {
  text-align: center;
  padding: 36px 24px;
  color: #6b7280;
}

@media (max-width: 850px) {
  .hero-content h2 {
    font-size: 44px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  .navbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .nav-links {
    flex-direction: column;
    gap: 12px;
  }

  .hero-content {
    text-align: left;
    padding: 64px 20px 80px;
  }

  .hero-content h2 {
    font-size: 36px;
  }

  .hero-content p {
    font-size: 18px;
  }

  .hero-actions {
    justify-content: flex-start;
  }

  .section {
    padding: 56px 20px;
  }

  .section-header {
    text-align: left;
  }

  .section-header h2 {
    font-size: 30px;
  }

  .feature-grid,
  .pricing-grid {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none;
  }
}

Сохрани file.

Обнови browser.

Измени размер window.

Наведи mouse на cards и buttons.

Теперь у тебя есть complete responsive landing page.

Поздравляю.

Это уже не просто CSS practice.

Это reusable website structure.

Можно использовать этот pattern для:

Теперь твой CSS имеет работу.

Наконец.

Что Ты Практиковал

В этом final project ты практиковал:

Это много.

Не делай вид, что это ничего.

CSS выглядит simple, пока не начинает спорить с screen size.

Ты это выдержал.

Хорошо.

Частые Ошибки

Пытаться Сделать Всё Идеальным Сразу

Не пытайся сделать page perfect с первой попытки.

Строй этапами:

  1. HTML structure.
  2. Base CSS.
  3. Layout.
  4. Cards.
  5. Responsive design.
  6. Polish.

Если пытаться сделать всё сразу, CSS почувствует страх.

Забыть Mobile

Всегда resize browser.

Всегда test smaller screens.

Page, которая работает только на desktop, не finished.

Она просто pretending.

Добавить Слишком Много Decoration

Clean page лучше, чем noisy page.

Используй:

Тебе не нужны 19 gradients и button, который танцует, будто слышит музыку.

Мини-Задание

Customize этот project.

Измени:

Потом сделай из этого свою landing page.

Она может стать:

Так начинаются real web projects.

Simple structure.

Then customization.

Then improvement.

Then coffee.

Итог

Ты завершил CSS course.

Ты изучил:

CSS — это не только decoration.

CSS — это layout.

Structure.

Readability.

Responsiveness.

User experience.

И иногда emotional damage.

Но теперь ты сильнее.

Последние Слова

Продолжай практиковаться.

Возьми этот project и восстанови его по памяти.

Потом измени его.

Сломай его.

Исправь его.

Сделай следующий.

Так CSS становится natural.

Не через чтение тысячи properties.

А через строительство вещей, пока fingers сами знают, где живёт display: grid.

Поздравляю.

Твоя CSS toolbox готова.

Теперь иди строить что-то fast, clean, responsive и немного менее chaotic, чем internet этого заслуживает.