> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# SCSS trong AEM Clientlib

Tổ chức và build SCSS trong dự án AEM, gắn style vào component theo BEM, và load qua clientlib.

## Luồng build

```mermaid
graph LR
  S[".scss trong ui.frontend"] --> W["Webpack + sass-loader"]
  W --> C["main.css"]
  C --> CP["clientlib.config.js copy"]
  CP --> CL["clientlib-site trong ui.apps"]
  CL --> HTL["customheaderlibs.html load CSS"]
```

SCSS viết trong `ui.frontend`, Webpack compile ra CSS, plugin (vd `aem-clientlib-generator`) copy vào clientlib trong `ui.apps`. AEM serve CSS qua clientlib category.

## Cấu trúc thư mục

```
ui.frontend/src/main/webpack/
├── site/
│   ├── main.scss              # entry
│   └── styles/
│       ├── abstracts/         # _variables, _mixins, _breakpoints
│       ├── base/              # _reset, _typography
│       ├── components/        # _hero.scss, _card.scss (mỗi AEM component)
│       └── layout/            # _grid, _header, _footer
```

```scss
// main.scss
@use 'styles/abstracts/variables';
@use 'styles/abstracts/mixins';
@use 'styles/base/reset';
@use 'styles/components/hero';
@use 'styles/components/card';
```

## BEM gắn với AEM component

AEM component nên có một class gốc theo tên component, style scope trong class đó để không rò rỉ sang component khác. Quy ước BEM: Block là component, Element là phần con, Modifier là biến thể.

```scss
// _hero.scss
.cmp-hero {
  padding: 32px;

  &__title {
    font-size: 2rem;
  }

  &__image {
    width: 100%;
  }

  &--centered {
    text-align: center;
  }
}
```

HTL render class khớp:

```html
<div class="cmp-hero cmp-hero--centered">
  <h1 class="cmp-hero__title">${model.title}</h1>
  <img class="cmp-hero__image" src="${model.imageSrc @ context='uri'}"/>
</div>
```

Tiền tố `cmp-` (theo Core Components) giúp tránh trùng class với thư viện ngoài.

## Responsive với breakpoint thống nhất

Đặt breakpoint vào map dùng chung, mixin `respond()` cho mọi component. Tránh viết media query rời rạc với giá trị khác nhau.

```scss
// abstracts/_breakpoints.scss
$breakpoints: (
  'sm': 576px,
  'md': 768px,
  'lg': 992px,
  'xl': 1200px
);

@mixin respond($name) {
  @media (min-width: map-get($breakpoints, $name)) {
    @content;
  }
}
```

```scss
.cmp-hero {
  padding: 16px;

  @include respond('md') {
    padding: 32px;
  }

  @include respond('lg') {
    padding: 48px;
  }
}
```

## Style cho Vue component trong AEM

Khi component là Vue SFC, có thể đặt style trong `<style>` của SFC hoặc trong SCSS chung. Lưu ý:

- `<style scoped>` trong SFC giới hạn style trong component đó bằng data attribute. Tốt cho cô lập nhưng tách rời khỏi clientlib chung.
- Để dùng biến/mixin chung trong SFC, import partial vào block style.

```vue
<style lang="scss" scoped>
@use '@/styles/abstracts/variables' as v;

.product-card {
  border: 1px solid v.$muted;
}
</style>
```

## Tránh xung đột style

- Luôn scope style trong class gốc component, không viết selector trần (`h2 {}`, `.title {}`) ở cấp global.
- Không lồng selector quá sâu, giữ specificity thấp để author dễ override qua style system của AEM nếu cần.
- Author có thể bật nhiều instance cùng component trên một trang, style phải hoạt động độc lập, không dựa vào vị trí DOM tuyệt đối.

## Tích hợp Style System của AEM

AEM Style System cho phép author chọn class CSS định nghĩa sẵn cho component qua policy. Khai báo các class style (vd `cmp-hero--centered`, `cmp-hero--dark`) trong SCSS, rồi map vào policy trong `_cq_design_dialog` hoặc template policy để author bật/tắt.

## Tips

| Việc          | Khuyến nghị                                 |
| ------------- | ------------------------------------------- |
| Biến chung    | `abstracts/_variables.scss`, nạp đầu tiên   |
| Đặt tên class | BEM, tiền tố theo component                 |
| Breakpoint    | Map dùng chung + mixin `respond()`          |
| Scope         | Style trong class gốc component             |
| Modifier      | Khai báo class, map vào Style System policy |
