# Liquid Glass (절제된 리퀴드 글래스) 디자인 시스템

> Apple iOS 26 / WWDC 2025의 Liquid Glass 머티리얼에서 출발했지만, 특정 브랜드 복제가 아닌 **웹용 범용 콘셉트**로 정리한 문서다.
> 핵심은 "유리는 떠 있는 컨트롤에만, 콘텐츠는 불투명하게 앞에". 유리를 많이 쓰는 스타일이 아니라 **유리를 아껴 쓰는 스타일**이다.
> `anti-slop.md` 규칙을 함께 적용한다. 특히 "효과는 1종만, 이유가 있는 곳에만" 원칙은 이 콘셉트에서 그대로 성립한다. 효과는 유리 하나뿐이다.

---

## 1. 분위기 (Visual Theme & Atmosphere)

사진, 지도, 영상, 앨범 커버처럼 **풍부한 콘텐츠가 화면 전체를 채우고**, 그 위에 얇은 유리판 몇 장이 떠 있는 구성이다. 유리판은 툴바, 탭 바, 시트, 플로팅 버튼 같은 **내비게이션·컨트롤 레이어**이고, 아래 콘텐츠의 색을 살짝 굴절시켜 받아들인다. 사용자가 스크롤하면 유리 아래로 사진이 흘러가고, 유리는 그 색을 은은하게 머금을 뿐 주인공 자리를 넘보지 않는다.

슬로건은 **"UI는 물러서고, 콘텐츠는 앞으로 나온다 (UI recedes, content advances)"**. 컨트롤은 캡슐 모양으로 작게 뭉쳐 화면 가장자리에 떠 있고, 화면 대부분은 콘텐츠에 내준다. 크롬(chrome)이 얇을수록 이 스타일은 성공한다.

2026년에 나온 "안티 리퀴드 글래스" 비판도 받아들인다. 유리 효과를 표·대시보드·긴 본문 위에 깔면 가독성이 무너지고 장식으로 전락한다. 그래서 이 문서는 유리를 **어디에 쓰지 말아야 하는지**를 쓸 곳만큼 자세히 정한다.

**핵심 특징**
- 콘텐츠(사진·지도·미디어)는 불투명하고 풀블리드. 유리는 그 위의 컨트롤 레이어에만 사용
- 유리 2종: **Regular**(블러+틴트, 텍스트가 있는 컨트롤용) / **Clear**(더 투명, 미디어 위 아이콘 컨트롤용)
- 상단 1px 스페큘러 하이라이트(`inset 0 1px 0`)로 유리 모서리에 빛이 맺히는 느낌
- `backdrop-filter: blur(24px) saturate(180%)`로 굴절된 색감
- 틴트 레이어로 텍스트 대비 **4.5:1 이상 항상 보장**
- 캡슐(pill) 모양 컨트롤, **동심원 반경**(inner radius = outer radius − padding)
- `prefers-reduced-transparency` 사용자에게는 불투명 폴백 제공
- 데이터 밀도가 높은 화면(표, 차트, 폼)에는 유리 금지

---

## 2. 컬러 팔레트 & 역할 (Color Palette & Roles)

유리 자체는 색이 없다. 색은 **콘텐츠에서 오고**, 시스템 팔레트는 중성색 + 액센트 1개로 끝난다. 액센트는 일출빛 앰버 한 가지만 쓴다. 인디고·보라 계열은 쓰지 않는다.

```css
:root {
  /* ── 캔버스 (콘텐츠가 없을 때의 바탕) ── */
  --lg-canvas:        oklch(0.17 0.012 240);   /* #101418 사진 뒤 기본 바탕 */
  --lg-canvas-raised: oklch(0.22 0.012 240);   /* #1a1f25 불투명 카드/폴백 표면 */

  /* ── 유리 틴트 (Regular / Clear) ── */
  --lg-tint-regular:  oklch(0.22 0.015 240 / 0.58);  /* rgba(26,31,37,.58) 텍스트 컨트롤 */
  --lg-tint-clear:    oklch(0.98 0 0 / 0.10);        /* rgba(255,255,255,.10) 미디어 위 아이콘 */
  --lg-tint-light:    oklch(0.98 0.004 90 / 0.66);   /* rgba(250,249,245,.66) 밝은 콘텐츠 위 Regular */
  --lg-dim-clear:     oklch(0 0 0 / 0.22);           /* Clear 아래 깔리는 디밍 */

  /* ── 하이라이트 & 테두리 ── */
  --lg-specular:      oklch(1 0 0 / 0.38);    /* 상단 1px 하이라이트 */
  --lg-edge:          oklch(1 0 0 / 0.14);    /* 유리 외곽 헤어라인 */
  --lg-edge-dark:     oklch(0 0 0 / 0.20);    /* 밝은 배경 위 외곽선 */

  /* ── 텍스트 (유리 위) ── */
  --lg-text:          oklch(0.97 0.003 90);   /* #f6f5f1 주 텍스트 */
  --lg-text-2:        oklch(0.82 0.008 240);  /* #c3c8ce 보조 텍스트 (Regular 위 4.5:1 이상) */
  --lg-text-3:        oklch(0.68 0.010 240);  /* #9aa1a9 메타 정보, 큰 글씨에만 */
  --lg-ink:           oklch(0.20 0.012 240);  /* #15191e 밝은 유리 위 텍스트 */

  /* ── 액센트 (화면당 1곳) ── */
  --lg-accent:        oklch(0.76 0.14 62);    /* #f2a04a 일출 앰버 */
  --lg-accent-ink:    oklch(0.24 0.04 60);    /* #2e2214 액센트 위 텍스트 */

  /* ── 주 버튼 (불투명 캡슐) ── */
  --lg-primary:       oklch(0.97 0.003 90);   /* #f6f5f1 */
  --lg-primary-ink:   oklch(0.20 0.012 240);  /* #15191e */

  /* ── 상태 ── */
  --lg-danger:        oklch(0.66 0.19 25);    /* #e5534b */
  --lg-success:       oklch(0.74 0.14 155);   /* #4fbf86 */

  /* ── 머티리얼 파라미터 ── */
  --lg-blur:          24px;
  --lg-saturate:      180%;
}
```

### 역할 정리

| 토큰 | 역할 | 쓰는 곳 |
|---|---|---|
| `--lg-canvas` | 콘텐츠 로딩 전/빈 영역 바탕 | 페이지 배경, 이미지 placeholder |
| `--lg-tint-regular` | Regular 유리의 틴트 | 툴바, 탭 바, 시트, 메뉴 |
| `--lg-tint-clear` + `--lg-dim-clear` | Clear 유리 | 사진·영상 위 아이콘 버튼, 필름스트립 |
| `--lg-specular` | 상단 하이라이트 | 모든 유리 표면의 `inset 0 1px 0` |
| `--lg-accent` | 현재 위치·진행 상태·좋아요 등 단 하나의 강조 | 탭 바 활성 점, 재생 진행 바 |
| `--lg-primary` | 주 액션 버튼 (유리 아님, 불투명) | "편집", "공유" 같은 최종 액션 |

**대비 규칙**: 유리 위 텍스트 대비는 **가장 밝은 배경을 기준으로** 계산한다. 밝은 하늘이나 흰 모래사장 위에서도 `--lg-tint-regular` + `--lg-text`가 4.5:1을 넘는지 확인하고, 넘지 못하면 틴트 알파를 0.58 → 0.70으로 올린다. 블러는 대비를 보장하지 못한다. 대비는 **틴트**가 책임진다.

---

## 3. 타이포그래피 (Typography)

### 폰트
- **한글/UI**: `Pretendard Variable`. 유리 위 작은 글씨에서도 획이 무너지지 않는다.
  `https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css`
- **수치/메타**: `IBM Plex Mono`. 촬영 정보(EXIF), 시간, 좌표처럼 자릿수가 맞아야 하는 값에만
- **디스플레이(선택)**: `Instrument Serif`. 콘텐츠 위 큰 장소명·앨범 제목에 한정. UI 컨트롤에는 쓰지 않는다.

```css
--lg-font-ui:      "Pretendard Variable", Pretendard, system-ui, sans-serif;
--lg-font-mono:    "IBM Plex Mono", ui-monospace, monospace;
--lg-font-display: "Instrument Serif", "Pretendard Variable", serif;
```

### 스케일 (5단계)

| 역할 | 폰트 | 크기 | 굵기 | 행간 | 자간 | 비고 |
|---|---|---|---|---|---|---|
| Display | Instrument Serif / Pretendard 600 | `clamp(40px, 5vw, 64px)` | 400 / 600 | 1.05 | -0.02em | 콘텐츠 위 장소명. 유리 위 금지 |
| Title | Pretendard | 20px | 650 | 1.3 | -0.01em | 시트 제목 |
| Body | Pretendard | 15px | 450 | 1.5 | -0.005em | 시트 본문, 리스트 |
| Label | Pretendard | 13px | 550 | 1.3 | 0 | 탭 바 라벨, 버튼 |
| Meta | IBM Plex Mono | 12px | 450 | 1.4 | 0 | EXIF, 시간, 좌표 |

### 원칙
- **유리 위 글씨는 한 단계 굵게**: 같은 크기라도 불투명 배경보다 굵기를 50~100 올린다(450 → 550). 블러 배경은 얇은 획을 먹는다.
- **12px 미만 금지**: 유리 위에서 11px 이하 텍스트는 대비를 맞춰도 읽히지 않는다.
- **콘텐츠 위 직접 텍스트**(장소명 등)는 유리 대신 아래쪽 그라데이션 스크림(`linear-gradient(transparent, rgba(0,0,0,.45))`)으로 대비를 확보한다.

---

## 4. 컴포넌트 (Components)

### 4.1 유리 머티리얼 베이스

```css
.glass {
  position: relative;
  background: var(--lg-tint-regular);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
          backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-saturate));
  border: 1px solid var(--lg-edge);
  box-shadow:
    inset 0 1px 0 var(--lg-specular),          /* 스페큘러 하이라이트 */
    inset 0 -1px 0 oklch(1 0 0 / 0.04),        /* 아랫면 반사 */
    0 8px 32px oklch(0 0 0 / 0.28);            /* 떠 있는 그림자 (1종만) */
  color: var(--lg-text);
}
.glass--clear {
  background: linear-gradient(var(--lg-dim-clear), var(--lg-dim-clear)), var(--lg-tint-clear);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
          backdrop-filter: blur(12px) saturate(160%);
}
.glass--light { background: var(--lg-tint-light); color: var(--lg-ink); border-color: var(--lg-edge-dark); }

/* 투명도 줄이기 폴백: 불투명 표면으로 */
@media (prefers-reduced-transparency: reduce) {
  .glass, .glass--clear {
    background: var(--lg-canvas-raised);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
}
/* backdrop-filter 미지원 브라우저 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: oklch(0.22 0.015 240 / 0.92); }
}
```

### 4.2 버튼

| 종류 | 머티리얼 | 모양 | 용도 |
|---|---|---|---|
| Primary | 불투명 `--lg-primary` | 캡슐, 높이 40 | 화면의 최종 액션 1개 |
| Glass | Regular 유리 | 캡슐, 높이 40 | 툴바 텍스트 버튼 |
| Icon (Clear) | Clear 유리 | 원형 40×40 | 미디어 위 닫기·공유·좋아요 |

```css
.btn {
  height: 40px; padding: 0 16px; border-radius: 999px;
  font: 550 13px/1 var(--lg-font-ui);
  display: inline-flex; align-items: center; gap: 6px;
  transition: transform 160ms ease, background 160ms ease;
}
.btn--primary { background: var(--lg-primary); color: var(--lg-primary-ink); }
.btn--primary:active { transform: scale(0.97); }
.btn-icon { width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; }
.btn-icon:hover { background: oklch(1 0 0 / 0.10); }
:focus-visible { outline: 2px solid var(--lg-accent); outline-offset: 2px; }
```

Primary 버튼은 **유리로 만들지 않는다**. 주 액션은 반드시 불투명해야 눈에 확실히 들어온다.

### 4.3 툴바 (상단 플로팅)

- 화면 끝에 붙이지 않고 `top: 16px`에 띄운다. 좌·우 그룹을 **서로 다른 캡슐**로 나눠 가운데 콘텐츠가 비쳐 보이게 한다.
- 높이 52px, 반경 26px(완전 캡슐), 내부 버튼 높이 40px, 패딩 6px → 내부 반경 20px (동심원).

```css
.toolbar { position: fixed; inset: 16px 16px auto; display: flex; justify-content: space-between; pointer-events: none; }
.toolbar > .glass { pointer-events: auto; height: 52px; padding: 6px; border-radius: 26px; display: flex; gap: 2px; }
.toolbar .btn-icon { border-radius: 20px; } /* 26 - 6 = 20 */
```

### 4.4 탭 바 (하단 플로팅 캡슐)

- 화면 하단 중앙, `bottom: 20px`. 폭은 탭 개수 × 88px 정도로 짧게.
- 활성 탭은 안쪽에 한 겹 더 밝은 "렌즈" 캡슐로 표시하고, 작은 액센트 점 하나만 둔다.
- 스크롤을 내리면 탭 바를 아이콘만 남는 크기로 줄여(`minimize on scroll`) 콘텐츠에 공간을 돌려준다.

```css
.tabbar { position: fixed; left: 50%; bottom: 20px; translate: -50% 0;
  height: 64px; padding: 6px; border-radius: 32px; display: flex; }
.tab { width: 84px; border-radius: 26px; /* 32 - 6 */ display: grid; place-items: center; gap: 2px;
  font: 550 11.5px/1 var(--lg-font-ui); color: var(--lg-text-2); }
.tab[aria-selected="true"] { background: oklch(1 0 0 / 0.14); color: var(--lg-text);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.25); }
```

### 4.5 시트 (사이드/바텀 시트)

- 정보 시트는 Regular 유리. 반경 28px, 패딩 12px → 내부 카드 반경 16px.
- 시트 **안쪽의 카드는 유리를 겹치지 않는다**. 유리 위 유리는 금지이며, 내부 구획은 `oklch(1 0 0 / 0.06)` 반투명 면이나 헤어라인으로 나눈다.
- 시트 내용이 길어 스크롤되면, 그 영역만 틴트를 0.58 → 0.78로 올려 읽기 모드로 만든다.

```css
.sheet { border-radius: 28px; padding: 12px; }
.sheet__section { border-radius: 16px; /* 28 - 12 */ background: oklch(1 0 0 / 0.06); padding: 14px 16px; }
.sheet__divider { height: 1px; background: oklch(1 0 0 / 0.10); }
```

### 4.6 입력 필드 (검색)

- 검색은 유리 캡슐 안에 들어가지만, 포커스되면 틴트를 높여(0.78) 입력 중인 글자의 대비를 키운다.
- 높이 44px, 반경 22px, 왼쪽 검색 아이콘 18px.

```css
.search { height: 44px; border-radius: 22px; padding: 0 16px 0 40px; font: 450 15px var(--lg-font-ui); }
.search:focus { background: oklch(0.22 0.015 240 / 0.78); outline: 2px solid var(--lg-accent); outline-offset: 0; }
.search::placeholder { color: var(--lg-text-2); }
```

### 4.7 콘텐츠 카드 (불투명)

콘텐츠 카드는 **유리가 아니다**. 사진 썸네일, 앨범 커버, 지도 타일은 불투명한 사각형이며 반경 12~16px. 그림자 없이 콘텐츠 자체의 색으로 구분한다.

### 4.8 필름스트립 (Clear 유리)

사진 위에 떠 있는 썸네일 줄. Clear 유리 캡슐 안에 불투명 썸네일을 담는다. 선택된 썸네일만 2px 흰 링으로 표시한다.

---

## 5. 레이아웃 원칙 (Layout Principles)

### 레이어 구조 (z축 3층)
```
Layer 2  컨트롤 (유리)     툴바 · 탭 바 · 시트 · 플로팅 버튼
Layer 1  스크림           콘텐츠 위 텍스트용 그라데이션 (필요할 때만)
Layer 0  콘텐츠 (불투명)   사진 · 지도 · 영상 · 앨범 그리드  ← 화면의 80% 이상
```

### 간격
- 기본 단위 4px. 스케일: 4 / 6 / 8 / 12 / 16 / 20 / 24 / 32
- 유리 컨트롤과 화면 가장자리 사이 간격: 16px(모바일 12px)
- 플로팅 요소끼리는 최소 12px 띄워 각각 독립된 유리판으로 읽히게 한다.

### 동심원 반경 (Concentric Radii)
바깥 반경 − 패딩 = 안쪽 반경. 이 공식을 지키면 겹친 캡슐의 곡선이 평행하게 흐른다.

| 컨테이너 | 바깥 반경 | 패딩 | 안쪽 반경 |
|---|---|---|---|
| 탭 바 | 32px | 6px | 26px |
| 툴바 | 26px | 6px | 20px |
| 시트 | 28px | 12px | 16px |
| 필름스트립 | 22px | 6px | 16px → 썸네일 12px |

### 반경 체계
**캡슐(999px)** + **동심원 계산값** 두 가지만 쓴다. 임의의 `rounded-xl`을 섞지 않는다.

### 데스크톱 구성
- 콘텐츠는 풀블리드. 정보 시트는 오른쪽에 `width: 340px`로 떠 있고, 시트가 열려도 콘텐츠는 **밀려나지 않고 그대로 아래에 남는다**.
- 유리 레이어는 화면 면적의 25%를 넘기지 않는다.

---

## 6. 깊이 & 엘리베이션 (Depth & Elevation)

| 레벨 | 처리 | 용도 |
|---|---|---|
| 0 콘텐츠 | 불투명, 그림자 없음 | 사진, 지도, 썸네일 |
| 1 스크림 | `linear-gradient(transparent, oklch(0 0 0 / .45))` | 콘텐츠 위 텍스트 바탕 |
| 2 Clear 유리 | blur 12px + 디밍 0.22 + 하이라이트 | 미디어 위 아이콘 버튼, 필름스트립 |
| 3 Regular 유리 | blur 24px saturate 180% + 틴트 0.58 + 하이라이트 + `0 8px 32px` 그림자 | 툴바, 탭 바, 시트 |
| 4 모달 | Regular 유리 + 뒤 콘텐츠 디밍 `oklch(0 0 0 / .35)` | 확인 시트, 공유 시트 |

**그림자 철학**: 그림자는 `0 8px 32px oklch(0 0 0 / .28)` **한 종류만**. 깊이감은 그림자보다 **스페큘러 하이라이트**(위쪽 1px 빛)와 블러 강도 차이에서 나온다. 유리 위에 또 유리를 올리지 않으므로 3중 그림자가 생길 일이 없다.

**모션**: 유리판이 나타날 때는 `scale(.96) → 1` + 불투명도 0 → 1, 220ms `cubic-bezier(.2,.8,.2,1)`. 탭 렌즈 이동은 180ms. `prefers-reduced-motion`이면 페이드만 남긴다.

---

## 7. Do / Don't

### Do
- 유리는 **떠 있는 컨트롤**(툴바, 탭 바, 시트, 플로팅 버튼)에만 쓴다
- 유리 아래에는 반드시 **풍부한 콘텐츠**(사진, 지도, 영상)가 있어야 한다. 단색 배경 위 유리는 그냥 회색 박스다
- 텍스트가 있는 유리는 Regular, 아이콘만 있는 미디어 위 컨트롤은 Clear
- 대비 4.5:1은 **틴트로** 보장한다. 가장 밝은 콘텐츠 위에서 검증한다
- 상단 1px 스페큘러 하이라이트를 모든 유리 표면에 일관되게 넣는다
- 동심원 반경 공식을 지킨다
- `prefers-reduced-transparency`, `@supports not (backdrop-filter)` 폴백을 항상 작성한다
- 주 액션 버튼은 불투명 캡슐로 만든다

### Don't
- **표, 대시보드, 차트, 긴 본문, 폼 위에 유리를 깔지 않는다** (안티 리퀴드 글래스 원칙)
- 콘텐츠 카드 자체를 유리로 만들지 않는다. 콘텐츠는 불투명하다
- 유리 위에 유리를 겹치지 않는다
- 유리판 테두리에 무지개·네온 글로우, 움직이는 블롭, 보라 그라데이션을 넣지 않는다
- 블러만 믿고 틴트를 0.3 이하로 낮추지 않는다. 밝은 사진 위에서 글자가 사라진다
- 페이지 배경 전체를 블러 처리하거나, 장식용 반투명 카드를 나열하지 않는다
- 12px 미만 텍스트를 유리 위에 두지 않는다
- 반경을 컨트롤마다 다르게 임의로 주지 않는다

---

## 8. 반응형 (Responsive Behavior)

| 구간 | 폭 | 변화 |
|---|---|---|
| 모바일 | < 640px | 툴바 좌우 캡슐 유지, 제목은 숨김. 정보 시트는 **바텀 시트**(detent: 30% / 60% / 100%). 탭 바 폭 = 화면 − 24px |
| 태블릿 | 640–1023px | 정보 시트는 바텀 시트, 최대 폭 560px 중앙. 필름스트립은 썸네일 6개 |
| 데스크톱 | ≥ 1024px | 정보 시트는 오른쪽 사이드 시트 340px. 탭 바는 하단 중앙 캡슐 |

- 터치 타깃은 최소 44×44px. 탭 바 탭은 높이 52px.
- 바텀 시트가 100%까지 올라오면 유리를 불투명(`--lg-canvas-raised`)으로 바꾼다. 꽉 찬 시트는 더 이상 떠 있는 컨트롤이 아니라 읽는 화면이기 때문이다.
- 저사양 기기(`navigator.hardwareConcurrency <= 4`)나 스크롤 성능이 떨어지면 blur를 24px → 12px로 낮춘다.
- `env(safe-area-inset-bottom)`을 탭 바 `bottom`에 더한다.

---

## 9. 에이전트 프롬프트 가이드 (Agent Prompt Guide)

### 빠른 토큰 참조
- 바탕: `--lg-canvas` oklch(0.17 0.012 240) / #101418
- Regular 유리: 틴트 rgba(26,31,37,.58) + `backdrop-filter: blur(24px) saturate(180%)`
- Clear 유리: rgba(255,255,255,.10) + 디밍 rgba(0,0,0,.22) + blur(12px)
- 하이라이트: `inset 0 1px 0 rgba(255,255,255,.38)`
- 텍스트: #f6f5f1 / 보조 #c3c8ce
- 액센트(1곳): 일출 앰버 #f2a04a
- 주 버튼: #f6f5f1 바탕 + #15191e 글자, 캡슐
- 폰트: Pretendard Variable + IBM Plex Mono(수치) + Instrument Serif(콘텐츠 위 장소명만)

### 복사해서 쓰는 프롬프트

**전체 화면**
```
절제된 리퀴드 글래스 스타일로 여행 사진 앨범 상세 화면을 만들어줘.
- 사진이 화면 전체를 불투명하게 채운다(풀블리드). 콘텐츠가 주인공.
- 유리는 상단 툴바(좌·우 캡슐 2개), 하단 중앙 탭 바(캡슐), 오른쪽 정보 시트(340px)에만 쓴다.
- Regular 유리: rgba(26,31,37,.58) 틴트 + backdrop-filter: blur(24px) saturate(180%) + inset 0 1px 0 rgba(255,255,255,.38) 하이라이트 + 1px rgba(255,255,255,.14) 테두리.
- 사진 위 아이콘 버튼과 썸네일 필름스트립은 Clear 유리(rgba(255,255,255,.10) + 디밍 .22, blur 12px).
- 동심원 반경: 탭 바 32/패딩 6/탭 26, 시트 28/패딩 12/내부 구획 16.
- 유리 위 텍스트 대비 4.5:1 이상, prefers-reduced-transparency 폴백 포함.
- 폰트 Pretendard Variable, 촬영 정보는 IBM Plex Mono. 액센트는 #f2a04a 한 곳만.
- 실제 같은 한국어 더미 데이터(장소, 날짜, 촬영 정보, 동행자 이름).
```

**탭 바만**
```
하단 중앙에 떠 있는 리퀴드 글래스 탭 바를 만들어줘. 높이 64px, 반경 32px, 패딩 6px.
탭 4개(보관함·추억·지도·검색), 각 탭은 lucide 아이콘 22px + 11.5px 라벨.
활성 탭은 안쪽 반경 26px의 밝은 렌즈 캡슐(rgba(255,255,255,.14) + 상단 1px 하이라이트)로 표시하고,
180ms로 미끄러지듯 이동. 비활성 라벨은 #c3c8ce, 활성은 #f6f5f1.
```

**음악 플레이어**
```
앨범 아트가 화면 전체를 채우는 음악 재생 화면. 아트는 불투명.
하단에 Regular 유리 캡슐 미니 플레이어(곡명·아티스트·재생 버튼), 진행 바만 #f2a04a 액센트.
가사 화면으로 전환하면 유리를 쓰지 말고 아트를 어둡게 디밍한 불투명 배경 위에 가사를 표시한다.
```

**지도 앱**
```
지도가 풀스크린인 장소 탐색 화면. 상단 검색 캡슐(Regular 유리, 높이 44, 포커스 시 틴트 .78),
오른쪽 아래 Clear 유리 원형 버튼 2개(현재 위치, 레이어), 하단 바텀 시트(30%/60%/100% detent).
시트가 100%가 되면 유리를 불투명 #1a1f25로 전환. 장소 리스트는 시트 안에서 유리 없이 헤어라인으로 구분.
```

### 프롬프트 끝에 붙이는 제약 블록
```
[리퀴드 글래스 제약]
- 유리는 떠 있는 컨트롤(툴바·탭 바·시트·플로팅 버튼)에만. 콘텐츠·카드·표는 불투명
- 표·차트·대시보드·긴 본문·폼 위에 유리 금지
- 유리 위에 유리 겹치기 금지
- 틴트로 텍스트 대비 4.5:1 보장, 12px 미만 텍스트 금지
- 반경은 캡슐(999px) + 동심원 계산값만
- 그림자 1종(0 8px 32px rgba(0,0,0,.28)), 스페큘러 하이라이트 inset 0 1px 0
- prefers-reduced-transparency / backdrop-filter 미지원 폴백 필수
- 보라·인디고 그라디언트, 글로우, 블롭, 이모지 금지. 아이콘은 lucide
```

### 반복 작업 가이드
1. 먼저 **콘텐츠 레이어**를 완성한다. 사진·지도가 빈약하면 유리는 회색 박스로 보인다.
2. 그다음 컨트롤을 유리로 올린다. "이 요소가 떠 있는 컨트롤인가?"를 요소마다 묻는다.
3. 가장 밝은 콘텐츠 위로 유리를 옮겨 대비를 검증한다.
4. 반경 표를 보고 동심원이 맞는지 확인한다.
5. OS 설정에서 "투명도 줄이기"를 켜고 폴백 화면을 확인한다.
