Tailwind CSS

Typography, Colors & Backgrounds

Tailwind CSS v4 — font, text, color (OKLCH), background, gradient, border, outline. Bài tập thiết kế typography system và color palette.

1. Font Family (font-sans, font-serif, font-mono, custom fonts trong @theme)

Tailwind CSS cung cấp sẵn 3 font stack mặc định:

ClassCSSMô tả
font-sansui-sans-serif, system-ui, sans-serif, ...Font không chân, tối ưu cho UI
font-serifui-serif, Georgia, Cambria, ...Font có chân, dùng cho bài viết dài
font-monoui-monospace, SFMono-Regular, ...Font monospace, dùng cho code

Trong Tailwind CSS v4, bạn có thể thêm custom font family thông qua @theme directive trong CSS:

/* app/assets/css/main.css */
@import "tailwindcss";

@theme {
  --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-display: 'Clash Display', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;
}

Sau khi định nghĩa trong @theme, bạn dùng class tương ứng:

<h1 class="font-sans">Heading với Inter</h1>
<h2 class="font-display">Display heading</h2>
<code class="font-mono">console.log('hello')</code>
Key concept: Tailwind v4 dùng CSS-based configuration thay vì tailwind.config.js. Mọi custom đều định nghĩa trong @theme block — gọn hơn, type-safe hơn, và tận dụng CSS cascade tự nhiên.

Bài tập 1: Setup custom Google Font (Inter) trong @theme

Yêu cầu: Import Google Font Inter vào project Nuxt, định nghĩa --font-sans trong @theme, và áp dụng cho toàn bộ body.

Bước 1 — Import font trong nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      link: [
        {
          rel: 'stylesheet',
          href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'
        }
      ]
    }
  }
})

Bước 2 — Khai báo trong CSS:

/* app/assets/css/main.css */
@import "tailwindcss";

@theme {
  --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
}

Bước 3 — Áp dụng cho body trong layout:

<!-- app/layouts/default.vue -->
<template>
  <body class="font-sans antialiased">
    <slot />
  </body>
</template>

Bài tập 2: Typography scale cho headings + body text

Yêu cầu: Tạo một typography system gồm:

  • h1: font-display, 48px, bold
  • h2: font-display, 36px, semibold
  • h3: font-sans, 24px, semibold
  • body: font-sans, 16px, leading-relaxed
  • small: font-sans, 14px, text-gray-500
<template>
  <article class="max-w-3xl mx-auto px-6 py-12">
    <h1 class="font-display text-5xl font-bold tracking-tight text-gray-900">
      Tiêu đề bài viết chính
    </h1>

    <h2 class="font-display text-4xl font-semibold tracking-tight text-gray-800 mt-12">
      Section heading cấp 2
    </h2>

    <h3 class="font-sans text-2xl font-semibold text-gray-800 mt-8">
      Sub-section cấp 3
    </h3>

    <p class="text-base leading-relaxed text-gray-700 mt-4">
      Nội dung body text với leading-relaxed để đọc thoải mái hơn.
      Khoảng cách dòng 1.625 giúp mắt không bị mỏi khi đọc đoạn văn dài.
    </p>

    <small class="block text-sm text-gray-500 mt-2">
      Caption hoặc ghi chú nhỏ đi kèm
    </small>
  </article>
</template>

2. Font Size & Weight (text-xs -> text-9xl, font-thin -> font-black)

Tailwind cung cấp scale từ text-xs (12px) đến text-9xl (128px). Mỗi level đi kèm line-height tối ưu.

<p class="text-xs">Extra small — 12px / line-height 1rem</p>
<p class="text-sm">Small — 14px / line-height 1.25rem</p>
<p class="text-base">Base — 16px / line-height 1.5rem</p>
<p class="text-lg">Large — 18px / line-height 1.75rem</p>
<p class="text-xl">Extra large — 20px / line-height 1.75rem</p>
<p class="text-2xl">2XL — 24px / line-height 2rem</p>
<p class="text-3xl">3XL — 30px / line-height 2.25rem</p>
<p class="text-4xl">4XL — 36px / line-height 2.5rem</p>
<p class="text-5xl">5XL — 48px / line-height 1</p>
<p class="text-6xl">6XL — 60px / line-height 1</p>
<p class="text-7xl">7XL — 72px / line-height 1</p>
<p class="text-8xl">8XL — 96px / line-height 1</p>
<p class="text-9xl">9XL — 128px / line-height 1</p>

Font Weight

ClassWeightMô tả
font-thin100Mỏng nhất, dùng cho display text lớn
font-extralight200Rất nhẹ
font-light300Nhẹ
font-normal400Bình thường (default)
font-medium500Vừa phải, phổ biến cho UI text
font-semibold600Hơi đậm, heading phụ
font-bold700Đậm, heading chính
font-extrabold800Rất đậm
font-black900Đậm nhất, hero text

Responsive modifiers

Mọi utility text-*font-* đều có thể kết hợp với responsive prefix:

<!-- Nhỏ hơn trên mobile, lớn dần theo breakpoint -->
<h1 class="text-3xl md:text-4xl lg:text-5xl xl:text-6xl">
  Responsive heading
</h1>

Bài tập 3: Responsive heading sizes (nhỏ hơn trên mobile)

Yêu cầu: Tạo hero section với heading và subheading có kích thước responsive theo từng breakpoint.

<template>
  <section class="bg-gradient-to-br from-indigo-50 to-white py-20 px-6">
    <div class="max-w-4xl mx-auto text-center">
      <h1 class="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-black tracking-tight text-gray-900">
        Xây dựng sản phẩm
        <span class="text-indigo-600">nhanh hơn</span>
      </h1>

      <p class="mt-6 text-base sm:text-lg md:text-xl text-gray-600 max-w-2xl mx-auto leading-relaxed">
        Nền tảng giúp team của bạn ship code nhanh gấp 3 lần.
        Không cần config phức tạp, chỉ cần code.
      </p>

      <div class="mt-10 flex flex-col sm:flex-row gap-4 justify-center">
        <button class="px-6 py-3 bg-indigo-600 text-white font-semibold rounded-lg text-sm sm:text-base hover:bg-indigo-700 transition-colors">
          Bắt đầu miễn phí
        </button>
        <button class="px-6 py-3 border border-gray-300 text-gray-700 font-semibold rounded-lg text-sm sm:text-base hover:bg-gray-50 transition-colors">
          Xem demo
        </button>
      </div>
    </div>
  </section>
</template>

3. Line Height, Letter Spacing, Text Align, Vertical Align

Line Height (leading-*)

<p class="leading-none">line-height: 1 — tiêu đề lớn</p>
<p class="leading-tight">line-height: 1.25 — heading</p>
<p class="leading-snug">line-height: 1.375 — subheading</p>
<p class="leading-normal">line-height: 1.5 — body text tiêu chuẩn</p>
<p class="leading-relaxed">line-height: 1.625 — bài viết dài</p>
<p class="leading-loose">line-height: 2 — text thoáng</p>

Letter Spacing (tracking-*)

<p class="tracking-tighter">-0.05em — heading lớn</p>
<p class="tracking-tight">-0.025em — heading vừa</p>
<p class="tracking-normal">0 — body text</p>
<p class="tracking-wide">0.025em — subheading</p>
<p class="tracking-wider">0.05em — label nhỏ</p>
<p class="tracking-widest">0.1em — uppercase label</p>

Text Align

<p class="text-left">Căn trái (default)</p>
<p class="text-center">Căn giữa</p>
<p class="text-right">Căn phải</p>
<p class="text-justify">Căn đều hai bên</p>
<p class="text-start">Theo hướng viết (LTR = left)</p>
<p class="text-end">Ngược hướng viết (LTR = right)</p>

Line Clamp (truncate nhiều dòng) — line-clamp-*

<!-- Giới hạn 3 dòng, thêm "..." ở cuối -->
<p class="line-clamp-3">
  Đoạn văn rất dài sẽ bị cắt sau 3 dòng và thêm dấu ba chấm ở cuối...
</p>

<!-- Có sẵn: line-clamp-1 đến line-clamp-6 -->
<!-- Hoặc line-clamp-none để bỏ giới hạn -->

Bài tập 4: Blog card với 3-line title truncation

Yêu cầu: Thiết kế blog card với:

  • Title bị giới hạn 2 dòng
  • Description bị giới hạn 3 dòng
  • Ảnh thumbnail, category tag, date
<template>
  <article class="group bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden hover:shadow-md transition-shadow">
    <div class="aspect-[16/9] overflow-hidden">
      <img
        src="https://images.unsplash.com/photo-1498050108023-c5249f4df085"
        alt="Blog thumbnail"
        class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
      />
    </div>

    <div class="p-5">
      <div class="flex items-center gap-2 mb-3">
        <span class="px-2.5 py-0.5 bg-indigo-50 text-indigo-700 text-xs font-medium rounded-full">
          Nuxt 4
        </span>
        <span class="text-xs text-gray-400">12 Tháng 7, 2026</span>
      </div>

      <!-- Title — giới hạn 2 dòng -->
      <h3 class="text-lg font-semibold text-gray-900 line-clamp-2 leading-snug group-hover:text-indigo-600 transition-colors">
        Hướng dẫn tối ưu SEO cho Nuxt 4 với useSeoMeta, Server Routes và Dynamic Rendering
      </h3>

      <!-- Description — giới hạn 3 dòng -->
      <p class="mt-2 text-sm text-gray-600 line-clamp-3 leading-relaxed">
        Tìm hiểu cách tận dụng useSeoMeta để tạo meta tags động,
        kết hợp Server Routes để generate sitemap XML, và dùng
        Hybrid Rendering để tối ưu tốc độ tải trang blog.
        Hướng dẫn chi tiết từ cơ bản đến nâng cao.
      </p>

      <div class="mt-4 flex items-center gap-3">
        <img
          src="https://i.pravatar.cc/40?img=1"
          alt="Author"
          class="w-8 h-8 rounded-full"
        />
        <span class="text-sm font-medium text-gray-700">Nguyen Van A</span>
        <span class="text-xs text-gray-400 ml-auto">8 phút đọc</span>
      </div>
    </div>
  </article>
</template>

Bài tập 5: Centered hero text với proper line-height

Yêu cầu: Hero section với heading lớn, subheading, mỗi loại có line-height và letter-spacing riêng.

<template>
  <section class="min-h-[80vh] flex items-center justify-center bg-slate-900 px-6">
    <div class="text-center max-w-3xl">
      <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-black text-white leading-none tracking-tighter">
        Design that
        <span class="bg-gradient-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent">
          speaks
        </span>
        for itself
      </h1>

      <p class="mt-8 text-lg sm:text-xl text-slate-400 leading-relaxed max-w-xl mx-auto">
        Ship beautiful interfaces faster with a utility-first CSS framework
        that lets you stay in your HTML and never leave your flow.
      </p>

      <div class="mt-10">
        <button class="px-8 py-3.5 bg-white text-slate-900 font-semibold rounded-xl text-base tracking-wide hover:bg-slate-200 transition-colors">
          Get started
        </button>
      </div>
    </div>
  </section>
</template>

4. Text Decoration, Transform, Overflow

Decoration

<p class="underline">Gạch chân</p>
<p class="line-through">Gạch ngang</p>
<p class="overline">Gạch trên</p>
<p class="no-underline">Bỏ gạch chân (hữu ích cho link)</p>

<!-- Kiểm soát style, color, thickness, offset -->
<a href="#" class="underline decoration-indigo-500 decoration-2 underline-offset-4">
  Link với gạch chân tùy chỉnh
</a>

<a href="#" class="underline decoration-wavy decoration-amber-400 underline-offset-2">
  Link với gạch chân lượn sóng
</a>

<a href="#" class="underline decoration-dotted decoration-pink-400">
  Link với gạch chân chấm chấm
</a>

Text Transform

<p class="uppercase">CHỮ IN HOA — label, badge</p>
<p class="lowercase">chữ thường</p>
<p class="capitalize">Mỗi Từ Viết Hoa Chữ Cái Đầu</p>
<p class="normal-case">Bỏ transform — revert về mặc định</p>

Text Overflow

<!-- truncate = text-ellipsis + overflow-hidden + whitespace-nowrap -->
<p class="truncate w-64">
  Đoạn text rất dài chỉ hiển thị 1 dòng và bị cắt với dấu ba chấm...
</p>

<!-- text-ellipsis: thêm "..." ở cuối -->
<p class="text-ellipsis overflow-hidden whitespace-nowrap w-64">
  Đoạn text bị cắt và thêm dấu ...
</p>

<!-- text-clip: cắt cứng không thêm dấu -->
<p class="text-clip overflow-hidden whitespace-nowrap w-64">
  Đoạn text bị cắt cứng không dấu
</p>

Yêu cầu: Tạo link có hiệu ứng gạch chân trượt từ trái qua phải khi hover.

<template>
  <div class="max-w-2xl mx-auto p-12 space-y-8">
    <h2 class="text-2xl font-bold text-gray-900">Link Hover Effects</h2>

    <!-- Effect 1: Gạch chân mở rộng từ giữa -->
    <a href="#"
      class="relative inline-block text-lg font-medium text-indigo-600
             after:absolute after:bottom-0 after:left-1/2 after:-translate-x-1/2
             after:h-[2px] after:w-0 after:bg-indigo-600
             after:transition-all after:duration-300
             hover:after:w-full pb-1">
      Underline mở rộng từ giữa
    </a>

    <!-- Effect 2: Gạch chân trượt từ trái -->
    <div>
      <a href="#"
        class="relative inline-block text-lg font-medium text-emerald-600
               after:absolute after:bottom-0 after:left-0
               after:h-[2px] after:w-0 after:bg-emerald-600
               after:transition-all after:duration-300
               hover:after:w-full pb-1">
        Underline trượt từ trái
      </a>
    </div>

    <!-- Effect 3: Đổi màu + gạch chân đứt đoạn -->
    <div>
      <a href="#"
        class="text-lg font-medium text-gray-500 no-underline
               hover:text-rose-500 hover:underline hover:decoration-dashed
               hover:decoration-rose-400 hover:underline-offset-4
               transition-all duration-200">
        Dashed underline + đổi màu
      </a>
    </div>

    <!-- Effect 4: Highlight background khi hover -->
    <div>
      <a href="#"
        class="relative inline-block text-lg font-medium text-gray-900
               before:absolute before:bottom-1 before:left-0 before:w-full
               before:h-2 before:bg-amber-200/50 before:-z-10
               before:transition-all before:duration-300
               hover:before:h-full hover:before:bottom-0 px-1">
        Highlight nền lan từ dưới lên
      </a>
    </div>
  </div>
</template>

5. List Style

<!-- Danh sách có dấu chấm (default) -->
<ul class="list-disc list-inside space-y-2">
  <li>Item thứ nhất</li>
  <li>Item thứ hai</li>
  <li>Item thứ ba</li>
</ul>

<!-- Danh sách đánh số -->
<ol class="list-decimal list-inside space-y-2">
  <li>Bước 1: Cài đặt</li>
  <li>Bước 2: Cấu hình</li>
  <li>Bước 3: Deploy</li>
</ol>

<!-- Bỏ marker -->
<ul class="list-none space-y-2">
  <li>Item không có marker — thường dùng custom marker</li>
</ul>

<!-- list-inside: marker nằm trong flow text -->
<!-- list-outside: marker nằm ngoài (default) -->
<ul class="list-disc list-outside ml-5 space-y-2">
  <li>Marker nằm bên trái, text thẳng hàng</li>
  <li>Phù hợp cho nội dung dài nhiều dòng</li>
</ul>
list-image-* cho phép dùng ảnh tùy chỉnh làm marker: list-image-[url('/check.svg')] hoặc list-image-none.

Bài tập 7: Styled unordered list với custom markers

Yêu cầu: Tạo danh sách với custom marker sử dụng pseudo-element hoặc icon.

<template>
  <div class="max-w-xl mx-auto p-8">
    <h2 class="text-xl font-bold text-gray-900 mb-6">Lợi ích khi dùng Tailwind CSS</h2>

    <!-- Custom marker với custom class -->
    <ul class="space-y-4">
      <li class="flex items-start gap-3">
        <span class="flex-shrink-0 w-6 h-6 rounded-full bg-emerald-100 text-emerald-600 flex items-center justify-center text-sm font-bold mt-0.5">
          &#10003;
        </span>
        <span class="text-gray-700">
          <strong class="text-gray-900">Utility-first:</strong> Không cần đặt tên class, code nhanh hơn 3x.
        </span>
      </li>

      <li class="flex items-start gap-3">
        <span class="flex-shrink-0 w-6 h-6 rounded-full bg-emerald-100 text-emerald-600 flex items-center justify-center text-sm font-bold mt-0.5">
          &#10003;
        </span>
        <span class="text-gray-700">
          <strong class="text-gray-900">Bundle size:</strong> Chỉ giữ CSS bạn dùng — production thường vài KB.
        </span>
      </li>

      <li class="flex items-start gap-3">
        <span class="flex-shrink-0 w-6 h-6 rounded-full bg-emerald-100 text-emerald-600 flex items-center justify-center text-sm font-bold mt-0.5">
          &#10003;
        </span>
        <span class="text-gray-700">
          <strong class="text-gray-900">Responsive:</strong> Prefix `sm:` `md:` `lg:` giúp responsive ngay trong HTML.
        </span>
      </li>

      <li class="flex items-start gap-3">
        <span class="flex-shrink-0 w-6 h-6 rounded-full bg-emerald-100 text-emerald-600 flex items-center justify-center text-sm font-bold mt-0.5">
          &#10003;
        </span>
        <span class="text-gray-700">
          <strong class="text-gray-900">Design system:</strong> Scale có sẵn (spacing, color, typography) giúp consistent.
        </span>
      </li>
    </ul>
  </div>
</template>

6. Text Shadow (v4.1 NEW)

Tailwind CSS v4.1 giới thiệu utility text-shadow — thay thế hoàn toàn cho việc phải dùng custom CSS.

<h1 class="text-shadow">Text shadow mặc định</h1>
<h1 class="text-shadow-sm">Shadow nhỏ</h1>
<h1 class="text-shadow-md">Shadow vừa</h1>
<h1 class="text-shadow-lg">Shadow lớn</h1>
<h1 class="text-shadow-none">Không shadow</h1>

Custom text shadow qua @theme:

@theme {
  --text-shadow-glow: 0 0 10px rgba(59, 130, 246, 0.5);
  --text-shadow-neon: 0 0 5px #0ff, 0 0 10px #0ff;
}
<h1 class="text-shadow-glow">Glow effect</h1>
<h1 class="text-shadow-neon">Neon text</h1>

Bài tập 8: Hero text với text shadow để dễ đọc trên ảnh

Yêu cầu: Hero section có background image, text đọc được nhờ text-shadow.

<template>
  <section class="relative min-h-[70vh] flex items-center justify-center overflow-hidden">
    <!-- Background image -->
    <img
      src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4"
      alt="Mountain landscape"
      class="absolute inset-0 w-full h-full object-cover"
    />

    <!-- Overlay tối -->
    <div class="absolute inset-0 bg-black/40"></div>

    <!-- Nội dung -->
    <div class="relative z-10 text-center px-6 max-w-4xl">
      <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-black text-white leading-none tracking-tighter text-shadow-lg">
        Khám phá thế giới
      </h1>

      <p class="mt-6 text-lg sm:text-xl text-white/90 leading-relaxed max-w-2xl mx-auto text-shadow-sm">
        Những chuyến phiêu lưu đáng nhớ bắt đầu từ một bước chân.
        Cùng chúng tôi khám phá những vùng đất mới.
      </p>

      <button class="mt-10 px-8 py-3.5 bg-white text-gray-900 font-semibold rounded-xl text-base hover:bg-gray-100 transition-colors text-shadow-none">
        Bắt đầu hành trình
      </button>
    </div>
  </section>
</template>

7. Colors -- OKLCH System (v4.0 NEW)

Tailwind CSS v4 chuyển hoàn toàn sang OKLCH color space — một cuộc cách mạng về màu sắc.

OKLCH là gì? OKLCH là không gian màu perceptually uniform (đồng nhất về cảm nhận) — 2 màu có cùng "khoảng cách số" sẽ trông giống nhau về độ khác biệt với mắt người. Hỗ trợ P3 wide gamut — hiển thị được nhiều màu hơn sRGB trên màn hình hiện đại.

Full default color palette

Tailwind cung cấp 22 họ màu, mỗi họ có scale từ 50 -> 950:

Neutral / Gray tones

slate, gray, zinc, neutral, stone — dùng cho text, background, border. Mỗi loại có undertone khác nhau (slate hơi xanh, stone hơi ấm).

Warm colors

red, orange, amber, yellow — cảnh báo, CTA, nhấn mạnh.

Cool colors

lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose — brand, link, accent.

NEW v4.2

mauve, olive, mist, taupe — 4 họ màu mới, tinh tế hơn cho thiết kế hiện đại.

Cú pháp sử dụng

<!-- Text color -->
<p class="text-red-500">Chữ đỏ</p>
<p class="text-blue-600">Chữ xanh dương</p>

<!-- Background color -->
<div class="bg-emerald-500">Nền xanh lá</div>
<div class="bg-slate-100">Nền xám nhạt</div>

<!-- Border color -->
<div class="border border-indigo-400">Viền tím</div>

Opacity modifier (cú pháp /)

Thay vì dùng bg-opacity-* riêng, Tailwind v4 dùng cú pháp / gọn hơn:

<!-- Opacity 75% -->
<div class="bg-red-500/75">Nền đỏ 75% opacity</div>

<!-- Opacity 50% -->
<p class="text-blue-600/50">Chữ xanh 50% opacity</p>

<!-- Opacity 25% -->
<div class="border-purple-400/25">Viền tím 25% opacity</div>

<!-- Opacity 10% cho overlay nhẹ -->
<div class="bg-black/10">Overlay đen 10%</div>

Bài tập 9: Color palette cho 1 landing page (primary/secondary/accent)

Yêu cầu: Định nghĩa color system trong @theme cho landing page SaaS với:

  • Primary: Indigo
  • Secondary: Teal
  • Accent: Amber
  • Neutral: Slate
/* app/assets/css/main.css */
@import "tailwindcss";

@theme {
  --color-primary-50: var(--color-indigo-50);
  --color-primary-100: var(--color-indigo-100);
  --color-primary-200: var(--color-indigo-200);
  --color-primary-300: var(--color-indigo-300);
  --color-primary-400: var(--color-indigo-400);
  --color-primary-500: var(--color-indigo-500);
  --color-primary-600: var(--color-indigo-600);
  --color-primary-700: var(--color-indigo-700);
  --color-primary-800: var(--color-indigo-800);
  --color-primary-900: var(--color-indigo-900);
  --color-primary-950: var(--color-indigo-950);

  --color-secondary-500: var(--color-teal-500);
  --color-secondary-600: var(--color-teal-600);

  --color-accent-400: var(--color-amber-400);
  --color-accent-500: var(--color-amber-500);
}
<!-- Sử dụng trong component -->
<template>
  <div class="max-w-4xl mx-auto p-8 space-y-6">
    <!-- Primary button -->
    <button class="px-6 py-3 bg-primary-600 text-white font-semibold rounded-lg hover:bg-primary-700 transition-colors">
      CTA chinh — Primary
    </button>

    <!-- Secondary button -->
    <button class="px-6 py-3 bg-secondary-500 text-white font-semibold rounded-lg hover:bg-secondary-600 transition-colors">
      Hành động phụ — Secondary
    </button>

    <!-- Accent badge -->
    <span class="inline-flex px-3 py-1 bg-accent-400/20 text-accent-500 text-sm font-medium rounded-full">
      Mới ra mắt
    </span>

    <!-- Section với nền primary nhạt -->
    <section class="bg-primary-50 rounded-2xl p-8">
      <h2 class="text-primary-900 text-2xl font-bold">Tính năng nổi bật</h2>
      <p class="text-primary-700 mt-2">Mô tả ngắn gọn về tính năng.</p>
    </section>
  </div>
</template>

Bài tập 10: Accessible color contrast checker concept

Yêu cầu: Tạo component minh họa các cặp màu đạt chuẩn WCAG AA/AAA.

<template>
  <div class="max-w-3xl mx-auto p-8 space-y-8">
    <h2 class="text-2xl font-bold text-gray-900">Kiểm tra độ tương phản màu (WCAG)</h2>

    <p class="text-gray-600">
      WCAG yêu cầu contrast ratio tối thiểu <strong>4.5:1</strong> cho text thường và <strong>3:1</strong> cho text lớn (>=18px bold hoặc >=24px).
    </p>

    <!-- Pass AA: text-gray-900 trên bg-white = ratio ~15:1 -->
    <div class="p-6 bg-white border rounded-xl">
      <p class="text-sm text-gray-500 mb-2">Pass AA (ratio ~15:1)</p>
      <p class="text-gray-900 text-lg font-medium">Text đen chuẩn trên nền trắng — luôn đạt AA/AAA</p>
    </div>

    <!-- Pass AA: text-white trên bg-indigo-600 = ratio ~6.2:1 -->
    <div class="p-6 bg-indigo-600 rounded-xl">
      <p class="text-sm text-indigo-200 mb-2">Pass AA (ratio ~6.2:1)</p>
      <p class="text-white text-lg font-medium">Chữ trắng trên nền indigo-600 — đạt AA</p>
    </div>

    <!-- Fail: text-gray-400 trên bg-white = ratio ~2.6:1 -->
    <div class="p-6 bg-white border rounded-xl">
      <p class="text-sm text-red-500 mb-2">Fail AA (ratio ~2.6:1) — Không nên dùng!</p>
      <p class="text-gray-400 text-lg">Chữ xám nhạt trên nền trắng — khó đọc</p>
    </div>

    <!-- Pass AA: text-gray-600 trên bg-white = ratio ~5.4:1 -->
    <div class="p-6 bg-white border rounded-xl">
      <p class="text-sm text-emerald-600 mb-2">Pass AA (ratio ~5.4:1) — Tối thiểu cho body text</p>
      <p class="text-gray-600 text-base">Nên dùng text-gray-600 trở lên cho body text trên nền trắng.</p>
    </div>

    <!-- Bảng tham khảo nhanh -->
    <div class="overflow-x-auto">
      <table class="w-full text-sm border-collapse">
        <thead>
          <tr class="bg-gray-50">
            <th class="border px-4 py-2 text-left">Text Color</th>
            <th class="border px-4 py-2 text-left">Background</th>
            <th class="border px-4 py-2 text-left">Ratio (xấp xỉ)</th>
            <th class="border px-4 py-2 text-left">WCAG AA</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td class="border px-4 py-2"><code>text-gray-900</code></td>
            <td class="border px-4 py-2"><code>bg-white</code></td>
            <td class="border px-4 py-2">15:1</td>
            <td class="border px-4 py-2 text-emerald-600 font-medium">Pass AAA</td>
          </tr>
          <tr>
            <td class="border px-4 py-2"><code>text-gray-600</code></td>
            <td class="border px-4 py-2"><code>bg-white</code></td>
            <td class="border px-4 py-2">5.4:1</td>
            <td class="border px-4 py-2 text-emerald-600 font-medium">Pass AA</td>
          </tr>
          <tr>
            <td class="border px-4 py-2"><code>text-white</code></td>
            <td class="border px-4 py-2"><code>bg-blue-600</code></td>
            <td class="border px-4 py-2">5.1:1</td>
            <td class="border px-4 py-2 text-emerald-600 font-medium">Pass AA</td>
          </tr>
          <tr>
            <td class="border px-4 py-2"><code>text-gray-500</code></td>
            <td class="border px-4 py-2"><code>bg-white</code></td>
            <td class="border px-4 py-2">3.5:1</td>
            <td class="border px-4 py-2 text-red-500 font-medium">Fail</td>
          </tr>
          <tr>
            <td class="border px-4 py-2"><code>text-gray-400</code></td>
            <td class="border px-4 py-2"><code>bg-white</code></td>
            <td class="border px-4 py-2">2.6:1</td>
            <td class="border px-4 py-2 text-red-500 font-medium">Fail</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

Bài tập 11: Gradient text sử dụng bg-gradient-to-r + bg-clip-text

Yêu cầu: Tạo heading với chữ gradient, sử dụng bg-clip-text + text-transparent.

<template>
  <div class="max-w-3xl mx-auto p-12 space-y-12 bg-slate-900 rounded-2xl">
    <!-- Gradient text cơ bản: xanh -> tím -->
    <h2 class="text-4xl font-black bg-gradient-to-r from-blue-400 to-purple-500 bg-clip-text text-transparent">
      Gradient từ xanh sang tím
    </h2>

    <!-- Gradient text 3 màu -->
    <h2 class="text-4xl font-black bg-gradient-to-r from-rose-400 via-fuchsia-400 to-indigo-400 bg-clip-text text-transparent">
      Gradient 3 màu qua fuchsia
    </h2>

    <!-- Gradient text với hướng khác -->
    <h2 class="text-4xl font-black bg-gradient-to-br from-emerald-300 to-teal-500 bg-clip-text text-transparent">
      Gradient chéo xuống phải
    </h2>

    <!-- Gradient text kết hợp animation (concept) -->
    <h2 class="text-4xl font-black bg-gradient-to-r from-amber-400 via-orange-500 to-red-500 bg-clip-text text-transparent bg-[length:200%_auto] animate-gradient">
      Gradient có animation
    </h2>
  </div>
</template>

<style scoped>
@keyframes gradient-shift {
  0% { background-position: 0% center; }
  100% { background-position: 200% center; }
}

.animate-gradient {
  animation: gradient-shift 3s linear infinite;
}
</style>

8. Background (bg-*, bg-gradient-*, bg-opacity)

Background cơ bản

<div class="bg-red-500">Màu nền đơn</div>
<div class="bg-white">Nền trắng</div>
<div class="bg-transparent">Nền trong suốt</div>
<div class="bg-current">Dùng màu text hiện tại</div>

Gradient (Linear, Radial, Conic)

<!-- Linear gradient -->
<div class="bg-gradient-to-r from-cyan-500 to-blue-500">
  Gradient trái -> phải
</div>

<div class="bg-gradient-to-b from-white to-gray-100">
  Gradient trên -> dưới
</div>

<div class="bg-gradient-to-tr from-pink-500 via-red-500 to-yellow-500">
  Gradient chéo với via (middle stop)
</div>
NEW v4.0 — Radial và Conic gradients: Tailwind v4 hỗ trợ bg-radial-*bg-conic-* mà không cần custom CSS.
<!-- Radial gradient -->
<div class="bg-radial from-white to-slate-300">
  Radial gradient từ tâm
</div>

<div class="bg-radial from-blue-100 via-blue-200 to-blue-400">
  Radial gradient 3 stops
</div>

<div class="bg-radial-[at_25%_25%] from-white to-slate-300">
  Radial gradient với tâm tại 25% 25%
</div>

<!-- Conic gradient -->
<div class="bg-conic from-red-500 via-yellow-500 to-red-500">
  Conic gradient — hiệu ứng vòng tròn
</div>

<div class="bg-conic/[at_50%] from-sky-400 via-indigo-400 to-sky-400">
  Conic với tâm xác định
</div>

Background Clip, Origin, Position

<!-- bg-clip: kiểm soát vùng background chiếm -->
<div class="bg-clip-border">Background đến border (default)</div>
<div class="bg-clip-padding">Background đến padding</div>
<div class="bg-clip-content">Background chỉ trong content box</div>
<div class="bg-clip-text">Background chỉ hiển thị trên text</div>

<!-- bg-origin: kiểm soát gốc tọa độ background -->
<div class="bg-origin-border">Gốc từ border</div>
<div class="bg-origin-padding">Gốc từ padding (default)</div>
<div class="bg-origin-content">Gốc từ content</div>

<!-- bg-position -->
<div class="bg-center">Căn giữa</div>
<div class="bg-top">Căn trên</div>
<div class="bg-right-bottom">Góc phải dưới</div>

<!-- bg-repeat -->
<div class="bg-repeat">Lặp</div>
<div class="bg-no-repeat">Không lặp</div>
<div class="bg-repeat-x">Lặp ngang</div>
<div class="bg-repeat-y">Lặp dọc</div>

Bài tập 12: Hero section với gradient overlay trên ảnh

Yêu cầu: Hero section có background image + gradient overlay + nội dung text.

<template>
  <section class="relative min-h-[80vh] flex items-center bg-cover bg-center"
    style="background-image: url('https://images.unsplash.com/photo-1522071820081-009f0129c71c')">
    <!-- Gradient overlay: tối dần từ trái sang phải -->
    <div class="absolute inset-0 bg-gradient-to-r from-slate-900/90 via-slate-900/50 to-transparent"></div>

    <!-- Nội dung nằm trên overlay -->
    <div class="relative z-10 max-w-2xl px-8 lg:px-16 py-20">
      <span class="inline-block px-3 py-1 bg-indigo-500/20 text-indigo-300 text-sm font-medium rounded-full mb-6">
        Ra mắt tháng 7/2026
      </span>

      <h1 class="text-4xl sm:text-5xl lg:text-6xl font-black text-white leading-none tracking-tight">
        Làm việc nhóm
        <br/>
        <span class="bg-gradient-to-r from-indigo-400 to-cyan-400 bg-clip-text text-transparent">
          hiệu quả hơn
        </span>
      </h1>

      <p class="mt-6 text-lg text-slate-300 leading-relaxed max-w-lg">
        Nền tảng collaboration thế hệ mới — real-time editing,
        video call tích hợp, và AI assistant trong cùng một workspace.
      </p>

      <div class="mt-8 flex gap-4">
        <button class="px-6 py-3 bg-indigo-500 text-white font-semibold rounded-lg hover:bg-indigo-600 transition-colors">
          Dùng thử miễn phí
        </button>
        <button class="px-6 py-3 border border-white/30 text-white font-semibold rounded-lg hover:bg-white/10 transition-colors">
          Xem video
        </button>
      </div>
    </div>
  </section>
</template>

Bài tập 13: Card với radial gradient background

Yêu cầu: Thiết kế pricing card với radial gradient nền tạo điểm nhấn.

<template>
  <div class="max-w-sm mx-auto">
    <div class="relative overflow-hidden rounded-2xl border border-slate-200 bg-white p-8">
      <!-- Radial gradient accent ở góc trên phải -->
      <div class="absolute -top-20 -right-20 w-60 h-60 bg-radial from-indigo-100 to-transparent rounded-full"></div>

      <!-- Nội dung -->
      <div class="relative z-10">
        <span class="text-sm font-semibold text-indigo-600 uppercase tracking-wider">Pro Plan</span>

        <div class="mt-4">
          <span class="text-5xl font-black text-gray-900">$29</span>
          <span class="text-gray-500 text-lg">/tháng</span>
        </div>

        <p class="mt-4 text-gray-600 text-sm leading-relaxed">
          Dành cho freelancer và team nhỏ cần đầy đủ tính năng.
        </p>

        <ul class="mt-6 space-y-3">
          <li class="flex items-center gap-2 text-sm text-gray-700">
            <span class="text-emerald-500 font-bold">&#10003;</span>
            Unlimited projects
          </li>
          <li class="flex items-center gap-2 text-sm text-gray-700">
            <span class="text-emerald-500 font-bold">&#10003;</span>
            50GB storage
          </li>
          <li class="flex items-center gap-2 text-sm text-gray-700">
            <span class="text-emerald-500 font-bold">&#10003;</span>
            Priority support
          </li>
          <li class="flex items-center gap-2 text-sm text-gray-700">
            <span class="text-emerald-500 font-bold">&#10003;</span>
            API access
          </li>
        </ul>

        <button class="mt-8 w-full py-3 bg-indigo-600 text-white font-semibold rounded-lg hover:bg-indigo-700 transition-colors">
          Bắt đầu dùng thử
        </button>
      </div>
    </div>
  </div>
</template>

Bài tập 14: Striped table rows với even:bg-gray-50

Yêu cầu: Bảng dữ liệu với hàng xen kẽ màu, header nổi bật.

<template>
  <div class="max-w-3xl mx-auto p-8">
    <div class="overflow-hidden rounded-xl border border-gray-200">
      <table class="w-full text-sm">
        <thead>
          <tr class="bg-gray-900 text-white">
            <th class="px-6 py-3.5 text-left font-semibold">Tên dự án</th>
            <th class="px-6 py-3.5 text-left font-semibold">Trạng thái</th>
            <th class="px-6 py-3.5 text-left font-semibold">Thành viên</th>
            <th class="px-6 py-3.5 text-right font-semibold">Tiến độ</th>
          </tr>
        </thead>
        <tbody class="divide-y divide-gray-200">
          <tr class="even:bg-gray-50 hover:bg-indigo-50/50 transition-colors">
            <td class="px-6 py-4 font-medium text-gray-900">Redesign Website</td>
            <td class="px-6 py-4">
              <span class="px-2.5 py-0.5 bg-emerald-100 text-emerald-700 text-xs font-medium rounded-full">Active</span>
            </td>
            <td class="px-6 py-4 text-gray-600">8 người</td>
            <td class="px-6 py-4 text-right font-medium text-gray-900">75%</td>
          </tr>
          <tr class="even:bg-gray-50 hover:bg-indigo-50/50 transition-colors">
            <td class="px-6 py-4 font-medium text-gray-900">Mobile App v2</td>
            <td class="px-6 py-4">
              <span class="px-2.5 py-0.5 bg-amber-100 text-amber-700 text-xs font-medium rounded-full">Review</span>
            </td>
            <td class="px-6 py-4 text-gray-600">5 người</td>
            <td class="px-6 py-4 text-right font-medium text-gray-900">90%</td>
          </tr>
          <tr class="even:bg-gray-50 hover:bg-indigo-50/50 transition-colors">
            <td class="px-6 py-4 font-medium text-gray-900">API Integration</td>
            <td class="px-6 py-4">
              <span class="px-2.5 py-0.5 bg-blue-100 text-blue-700 text-xs font-medium rounded-full">In Progress</span>
            </td>
            <td class="px-6 py-4 text-gray-600">3 người</td>
            <td class="px-6 py-4 text-right font-medium text-gray-900">45%</td>
          </tr>
          <tr class="even:bg-gray-50 hover:bg-indigo-50/50 transition-colors">
            <td class="px-6 py-4 font-medium text-gray-900">Documentation</td>
            <td class="px-6 py-4">
              <span class="px-2.5 py-0.5 bg-gray-100 text-gray-600 text-xs font-medium rounded-full">Draft</span>
            </td>
            <td class="px-6 py-4 text-gray-600">2 người</td>
            <td class="px-6 py-4 text-right font-medium text-gray-900">20%</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>

9. Border & Outline

Border

<!-- Border cơ bản -->
<div class="border">Border 1px solid (default)</div>
<div class="border-2">Border 2px</div>
<div class="border-4">Border 4px</div>
<div class="border-0">Không border</div>

<!-- Border color -->
<div class="border border-red-500">Border đỏ</div>
<div class="border border-slate-200">Border xám nhạt</div>

<!-- Border style -->
<div class="border border-dashed">Border đứt đoạn</div>
<div class="border border-dotted">Border chấm</div>
<div class="border border-double">Border đôi</div>

<!-- Border từng cạnh -->
<div class="border-t-2 border-b border-l-4 border-r-0">
  Mỗi cạnh độ dày khác nhau
</div>

Border Radius

<div class="rounded-sm">Bo góc nhỏ (2px)</div>
<div class="rounded">Bo góc vừa (4px)</div>
<div class="rounded-md">Bo góc trung bình (6px)</div>
<div class="rounded-lg">Bo góc lớn (8px)</div>
<div class="rounded-xl">Bo góc XL (12px)</div>
<div class="rounded-2xl">Bo góc 2XL (16px)</div>
<div class="rounded-3xl">Bo góc 3XL (24px)</div>
<div class="rounded-full">Bo tròn hoàn toàn (circle/pill)</div>

<!-- Bo góc từng góc -->
<div class="rounded-t-xl rounded-b-sm">Bo góc riêng biệt</div>
<div class="rounded-tl-lg rounded-br-lg">Chỉ bo 2 góc chéo</div>

Outline & Ring

<!-- Outline (không chiếm không gian, nằm ngoài border) -->
<button class="outline outline-2 outline-offset-2 outline-blue-500">
  Outline style
</button>

<!-- Ring (thay thế outline với box-shadow — đẹp hơn) -->
<input class="ring-2 ring-blue-500 focus:ring-4" placeholder="Ring focus" />

<!-- Ring inset -->
<div class="ring-2 ring-inset ring-indigo-500">Ring inset</div>
NEW v4.0 — inset-shadow-*inset-ring-*: Thay thế hoàn toàn cho shadow-innerring-inset cũ. Cú pháp độc lập, rõ ràng hơn.
<div class="inset-shadow-sm">Inner shadow nhỏ</div>
<div class="inset-shadow-md">Inner shadow vừa</div>
<div class="inset-ring-2 inset-ring-indigo-500">Inner ring</div>

Bài tập 15: Input field với focus ring styling

Yêu cầu: Form input field với trạng thái mặc định, focus, error.

<template>
  <div class="max-w-md mx-auto p-8 space-y-6">
    <h2 class="text-xl font-bold text-gray-900">Form đăng nhập</h2>

    <!-- Input mặc định -->
    <div>
      <label class="block text-sm font-medium text-gray-700 mb-1.5">Email</label>
      <input
        type="email"
        placeholder="you@example.com"
        class="w-full px-4 py-2.5 border border-gray-300 rounded-lg text-sm
               placeholder:text-gray-400
               focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500
               transition-shadow duration-200"
      />
    </div>

    <!-- Input với error state -->
    <div>
      <label class="block text-sm font-medium text-gray-700 mb-1.5">Mật khẩu</label>
      <input
        type="password"
        placeholder="Nhập mật khẩu"
        class="w-full px-4 py-2.5 border border-red-300 rounded-lg text-sm
               placeholder:text-gray-400
               focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-red-500
               transition-shadow duration-200"
      />
      <p class="mt-1 text-xs text-red-600">Mật khẩu phải có ít nhất 8 ký tự</p>
    </div>

    <!-- Input disabled -->
    <div>
      <label class="block text-sm font-medium text-gray-400 mb-1.5">Username (khóa)</label>
      <input
        type="text"
        value="nguyenvana"
        disabled
        class="w-full px-4 py-2.5 border border-gray-200 rounded-lg text-sm
               bg-gray-50 text-gray-400 cursor-not-allowed"
      />
    </div>

    <button class="w-full py-2.5 bg-indigo-600 text-white font-semibold rounded-lg
                   hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2
                   transition-colors duration-200">
      Đăng nhập
    </button>
  </div>
</template>

Bài tập 16: Card với hover border effect

Yêu cầu: Grid card có border chuyển màu và nổi shadow khi hover.

<template>
  <div class="max-w-5xl mx-auto p-8">
    <h2 class="text-2xl font-bold text-gray-900 mb-8">Dịch vụ của chúng tôi</h2>

    <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
      <!-- Card 1 -->
      <div class="group p-6 bg-white rounded-xl border border-gray-200
                  hover:border-indigo-400 hover:shadow-lg
                  transition-all duration-300 cursor-pointer">
        <div class="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4
                    group-hover:bg-indigo-200 transition-colors">
          <svg class="w-6 h-6 text-indigo-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                  d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
          </svg>
        </div>
        <h3 class="text-lg font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors">
          Web Development
        </h3>
        <p class="mt-2 text-sm text-gray-600 leading-relaxed">
          Xây dựng website chuẩn SEO, tốc độ cao với công nghệ mới nhất.
        </p>
      </div>

      <!-- Card 2 -->
      <div class="group p-6 bg-white rounded-xl border border-gray-200
                  hover:border-emerald-400 hover:shadow-lg
                  transition-all duration-300 cursor-pointer">
        <div class="w-12 h-12 bg-emerald-100 rounded-lg flex items-center justify-center mb-4
                    group-hover:bg-emerald-200 transition-colors">
          <svg class="w-6 h-6 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                  d="M12 18h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
          </svg>
        </div>
        <h3 class="text-lg font-semibold text-gray-900 group-hover:text-emerald-600 transition-colors">
          Mobile Apps
        </h3>
        <p class="mt-2 text-sm text-gray-600 leading-relaxed">
          Ứng dụng iOS và Android native, hiệu năng cao, UX mượt mà.
        </p>
      </div>

      <!-- Card 3 -->
      <div class="group p-6 bg-white rounded-xl border border-gray-200
                  hover:border-purple-400 hover:shadow-lg
                  transition-all duration-300 cursor-pointer">
        <div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center mb-4
                    group-hover:bg-purple-200 transition-colors">
          <svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                  d="M13 10V3L4 14h7v7l9-11h-7z" />
          </svg>
        </div>
        <h3 class="text-lg font-semibold text-gray-900 group-hover:text-purple-600 transition-colors">
          AI Solutions
        </h3>
        <p class="mt-2 text-sm text-gray-600 leading-relaxed">
          Tích hợp AI/ML vào sản phẩm — chatbot, recommendation, automation.
        </p>
      </div>
    </div>
  </div>
</template>

Bài tập 17: Avatar với rounded-full + ring

Yêu cầu: Avatar group với ring, online indicator, và stacked layout.

<template>
  <div class="max-w-md mx-auto p-8 space-y-8">
    <h2 class="text-xl font-bold text-gray-900">Avatar Styles</h2>

    <!-- Avatar đơn với ring -->
    <div class="flex items-center gap-4">
      <img
        src="https://i.pravatar.cc/80?img=1"
        alt="User"
        class="w-12 h-12 rounded-full ring-2 ring-white shadow-sm"
      />
      <div>
        <p class="text-sm font-semibold text-gray-900">Nguyen Van A</p>
        <p class="text-xs text-gray-500">Fullstack Developer</p>
      </div>
    </div>

    <!-- Avatar với online indicator -->
    <div class="flex items-center gap-4">
      <div class="relative">
        <img
          src="https://i.pravatar.cc/80?img=5"
          alt="User"
          class="w-12 h-12 rounded-full ring-2 ring-white"
        />
        <span class="absolute bottom-0 right-0 w-3.5 h-3.5 bg-emerald-500 border-2 border-white rounded-full"></span>
      </div>
      <div>
        <p class="text-sm font-semibold text-gray-900">Tran Thi B</p>
        <p class="text-xs text-emerald-600 font-medium">Online</p>
      </div>
    </div>

    <!-- Avatar với offline indicator -->
    <div class="flex items-center gap-4">
      <div class="relative">
        <img
          src="https://i.pravatar.cc/80?img=8"
          alt="User"
          class="w-12 h-12 rounded-full ring-2 ring-white"
        />
        <span class="absolute bottom-0 right-0 w-3.5 h-3.5 bg-gray-400 border-2 border-white rounded-full"></span>
      </div>
      <div>
        <p class="text-sm font-semibold text-gray-900">Le Van C</p>
        <p class="text-xs text-gray-400">Offline</p>
      </div>
    </div>

    <!-- Stacked avatar group -->
    <div>
      <p class="text-sm text-gray-500 mb-3">12 thành viên trong team</p>
      <div class="flex -space-x-2">
        <img src="https://i.pravatar.cc/40?img=1" class="w-10 h-10 rounded-full ring-2 ring-white" alt="" />
        <img src="https://i.pravatar.cc/40?img=2" class="w-10 h-10 rounded-full ring-2 ring-white" alt="" />
        <img src="https://i.pravatar.cc/40?img=3" class="w-10 h-10 rounded-full ring-2 ring-white" alt="" />
        <img src="https://i.pravatar.cc/40?img=4" class="w-10 h-10 rounded-full ring-2 ring-white" alt="" />
        <div class="w-10 h-10 rounded-full ring-2 ring-white bg-indigo-100 flex items-center justify-center text-xs font-bold text-indigo-600">
          +8
        </div>
      </div>
    </div>

    <!-- Avatar sizes -->
    <div class="flex items-end gap-4">
      <img src="https://i.pravatar.cc/24?img=6" class="w-6 h-6 rounded-full ring-1 ring-white" alt="" />
      <img src="https://i.pravatar.cc/32?img=6" class="w-8 h-8 rounded-full ring-2 ring-white" alt="" />
      <img src="https://i.pravatar.cc/48?img=6" class="w-12 h-12 rounded-full ring-2 ring-white" alt="" />
      <img src="https://i.pravatar.cc/64?img=6" class="w-16 h-16 rounded-full ring-2 ring-white" alt="" />
      <img src="https://i.pravatar.cc/96?img=6" class="w-24 h-24 rounded-full ring-2 ring-white" alt="" />
    </div>
  </div>
</template>

10. Divide & Box Shadow

Divide

<!-- Divide ngang giữa các item -->
<ul class="divide-y divide-gray-200">
  <li class="py-3">Item 1</li>
  <li class="py-3">Item 2</li>
  <li class="py-3">Item 3</li>
</ul>

<!-- Divide dọc giữa các item trong flex row -->
<div class="flex divide-x divide-gray-300">
  <div class="px-4">Column 1</div>
  <div class="px-4">Column 2</div>
  <div class="px-4">Column 3</div>
</div>

<!-- Đảo chiều divide -->
<div class="flex flex-row-reverse divide-x divide-x-reverse">
  <div class="px-4">RTL column</div>
</div>

Box Shadow

<div class="shadow-sm">Shadow nhỏ — card tinh tế</div>
<div class="shadow">Shadow vừa (default)</div>
<div class="shadow-md">Shadow trung bình — card nổi</div>
<div class="shadow-lg">Shadow lớn — modal, dropdown</div>
<div class="shadow-xl">Shadow XL — elevated component</div>
<div class="shadow-2xl">Shadow 2XL — floating element</div>
<div class="shadow-inner">Shadow bên trong</div>
<div class="shadow-none">Không shadow</div>
/* Custom shadow trong @theme */
@theme {
  --shadow-card: 0 2px 15px -3px rgba(0, 0, 0, 0.07),
                 0 10px 20px -2px rgba(0, 0, 0, 0.04);
  --shadow-glow: 0 0 20px rgba(99, 102, 241, 0.3);
}

Bài tập 18: Stacked list với divider lines

Yêu cầu: Danh sách notification với divider giữa các item.

<template>
  <div class="max-w-lg mx-auto p-8">
    <div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
      <!-- Header -->
      <div class="px-5 py-4 border-b border-gray-200">
        <h3 class="text-lg font-semibold text-gray-900">Thông báo</h3>
      </div>

      <!-- List với divide -->
      <ul class="divide-y divide-gray-100">
        <li class="px-5 py-4 hover:bg-gray-50 transition-colors cursor-pointer">
          <div class="flex items-start gap-3">
            <div class="flex-shrink-0 w-9 h-9 bg-blue-100 rounded-full flex items-center justify-center">
              <span class="text-blue-600 text-sm">&#128172;</span>
            </div>
            <div class="flex-1 min-w-0">
              <p class="text-sm font-medium text-gray-900">Bình luận mới</p>
              <p class="text-sm text-gray-600 truncate">Nguyen Van A đã bình luận vào bài viết của bạn</p>
              <p class="text-xs text-gray-400 mt-1">5 phút trước</p>
            </div>
            <span class="flex-shrink-0 w-2 h-2 bg-blue-500 rounded-full mt-2"></span>
          </div>
        </li>

        <li class="px-5 py-4 hover:bg-gray-50 transition-colors cursor-pointer">
          <div class="flex items-start gap-3">
            <div class="flex-shrink-0 w-9 h-9 bg-emerald-100 rounded-full flex items-center justify-center">
              <span class="text-emerald-600 text-sm">&#10003;</span>
            </div>
            <div class="flex-1 min-w-0">
              <p class="text-sm font-medium text-gray-900">Deploy thành công</p>
              <p class="text-sm text-gray-600 truncate">Production build #142 đã deploy thành công</p>
              <p class="text-xs text-gray-400 mt-1">1 giờ trước</p>
            </div>
          </div>
        </li>

        <li class="px-5 py-4 hover:bg-gray-50 transition-colors cursor-pointer">
          <div class="flex items-start gap-3">
            <div class="flex-shrink-0 w-9 h-9 bg-amber-100 rounded-full flex items-center justify-center">
              <span class="text-amber-600 text-sm">&#9888;</span>
            </div>
            <div class="flex-1 min-w-0">
              <p class="text-sm font-medium text-gray-900">Cảnh báo billing</p>
              <p class="text-sm text-gray-600 truncate">Gói Pro của bạn sẽ hết hạn sau 3 ngày</p>
              <p class="text-xs text-gray-400 mt-1">3 giờ trước</p>
            </div>
            <span class="flex-shrink-0 w-2 h-2 bg-amber-500 rounded-full mt-2"></span>
          </div>
        </li>

        <li class="px-5 py-4 hover:bg-gray-50 transition-colors cursor-pointer">
          <div class="flex items-start gap-3">
            <div class="flex-shrink-0 w-9 h-9 bg-purple-100 rounded-full flex items-center justify-center">
              <span class="text-purple-600 text-sm">&#128640;</span>
            </div>
            <div class="flex-1 min-w-0">
              <p class="text-sm font-medium text-gray-900">Tính năng mới</p>
              <p class="text-sm text-gray-600 truncate">AI code review đã sẵn sàng trên workspace của bạn</p>
              <p class="text-xs text-gray-400 mt-1">1 ngày trước</p>
            </div>
          </div>
        </li>
      </ul>

      <!-- Footer -->
      <div class="px-5 py-3 border-t border-gray-200 bg-gray-50">
        <button class="text-sm font-medium text-indigo-600 hover:text-indigo-700 transition-colors">
          Xem tất cả thông báo
        </button>
      </div>
    </div>
  </div>
</template>

Bài tập 19: Card elevation system (sm -> 2xl)

Yêu cầu: Demo toàn bộ 6 level shadow của Tailwind trên card giống hệt nhau.

<template>
  <div class="max-w-5xl mx-auto p-8">
    <h2 class="text-2xl font-bold text-gray-900 mb-8">Card Elevation System</h2>

    <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
      <!-- shadow-sm -->
      <div class="shadow-sm bg-white rounded-xl p-6">
        <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Level 1</span>
        <h3 class="text-lg font-semibold text-gray-900 mt-1">shadow-sm</h3>
        <p class="text-sm text-gray-500 mt-2">Tinh tế, nhẹ nhàng. Dùng cho card trong layout phẳng.</p>
      </div>

      <!-- shadow -->
      <div class="shadow bg-white rounded-xl p-6">
        <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Level 2</span>
        <h3 class="text-lg font-semibold text-gray-900 mt-1">shadow</h3>
        <p class="text-sm text-gray-500 mt-2">Default elevation. Card cơ bản, section container.</p>
      </div>

      <!-- shadow-md -->
      <div class="shadow-md bg-white rounded-xl p-6">
        <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Level 3</span>
        <h3 class="text-lg font-semibold text-gray-900 mt-1">shadow-md</h3>
        <p class="text-sm text-gray-500 mt-2">Card nổi vừa. Dùng cho card tương tác được.</p>
      </div>

      <!-- shadow-lg -->
      <div class="shadow-lg bg-white rounded-xl p-6">
        <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Level 4</span>
        <h3 class="text-lg font-semibold text-gray-900 mt-1">shadow-lg</h3>
        <p class="text-sm text-gray-500 mt-2">Dropdown menu, popover, card hover state.</p>
      </div>

      <!-- shadow-xl -->
      <div class="shadow-xl bg-white rounded-xl p-6">
        <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Level 5</span>
        <h3 class="text-lg font-semibold text-gray-900 mt-1">shadow-xl</h3>
        <p class="text-sm text-gray-500 mt-2">Modal, dialog, sticky header khi scroll.</p>
      </div>

      <!-- shadow-2xl -->
      <div class="shadow-2xl bg-white rounded-xl p-6">
        <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Level 6</span>
        <h3 class="text-lg font-semibold text-gray-900 mt-1">shadow-2xl</h3>
        <p class="text-sm text-gray-500 mt-2">Floating action button, toast notification, tooltip.</p>
      </div>
    </div>
  </div>
</template>

© 2026 .NET Fresher Guide. All rights reserved.

Về Trang Web

Hướng dẫn toàn diện để chuẩn bị phỏng vấn vị trí .NET Fresher với nội dung từ lý thuyết đến thực hành.