← 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="uk">
<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 цього заслуговує.