# Design System — Frutiger Aero (프루티거 에어로)

> 2004~2013년 무렵의 글로시한 UI 감성. Windows Vista·7의 Aero, 초기 아이팟·와이 광고, 휴대폰 대기화면에서 보던 하늘색·아쿠아·연초록, 유리구슬 같은 광택 버튼, 물방울과 비눗방울. 2020년대 들어 "Y2K 다음의 향수"로 다시 쓰이기 시작했다.
> 공통 규칙은 `anti-slop.md`를 함께 적용한다. 미리보기: `preview/frutiger-aero.html` (사내 복지 포털 예시)

> **장식 제한 완화 범위** — 이 묶음(트렌디 · 감성)은 anti-slop.md의 "그라디언트 금지 · 효과 1종 · 그림자 토큰 최소화"를 **이 문서 5장이 정한 범위 안에서만** 풀어 준다. 허용되는 것은 ① 하늘→연초록 배경 그라디언트 1장 ② 광택(gloss) 버튼 레시피 ③ 반투명 패널 1종(`--glass`) ④ 물방울·비눗방울 SVG 장식(화면당 상한 있음)이다. 그 밖의 anti-slop 원칙(이모지 금지, 현실적인 한국어 더미 데이터, 아이콘 카드 3개 나열 금지, 빈 상태·로딩·에러 디자인)은 그대로 지킨다.

---

## 1. 분위기

맑은 날 아침이다. 하늘은 위로 갈수록 진한 파랑, 아래로 갈수록 거의 흰색에 가깝고, 화면 아래쪽에는 연초록 풀밭 기운이 깔린다. 그 위에 **물에 젖은 유리판** 같은 반투명 패널이 떠 있고, 버튼은 손톱만 한 유리구슬처럼 **위쪽 절반에 하얀 광택이 맺혀** 있다. 모서리 근처에는 비눗방울 몇 개가 떠 있다.

이 스타일의 정서는 **낙관**이다. 기술이 자연과 어울려 삶을 밝게 만든다는 2000년대 중반의 믿음. 그래서 어둡거나 날카로운 요소가 없다. 색은 맑고, 빛은 위에서 아래로 떨어지며, 모든 표면이 촉촉하다.

요즘의 "리퀴드 글래스"와 다른 점: 리퀴드 글래스는 유리를 아껴 쓰고 콘텐츠를 앞세운다. 프루티거 에어로는 **광택 자체가 표정**이다. 버튼·헤더·패널 테두리에 빛이 맺히는 것을 숨기지 않는다. 대신 그 광택을 정해진 레시피로만 쓴다.

**어울리는 곳**
- 사내 복지 포털(휴가·복지 포인트·동호회), 건강검진·걷기 챌린지 같은 웰빙 캠페인
- 여름 휴가철 안내, 친환경(ESG) 캠페인, 사내 체육대회 페이지
- 사내 라디오·뉴스레터 아카이브처럼 "가볍게 둘러보는" 화면

**쓰면 안 되는 곳**
- 품질·규제·법무 문서, 의약품 허가 정보 — 장식이 내용의 무게를 깎는다
- 데이터 밀도가 높은 업무 화면(ERP, 구매, 재무). 반투명 위 숫자 표는 가독성이 떨어진다
- 다크 테마가 기본이어야 하는 화면(관제, 야간 모니터링)
- 경영진 보고 자료, 외부 고객용 공식 안내문

**핵심 특징**
- 배경: 하늘색 → 아쿠아 → 연초록 세로 그라디언트 1장 + 아래쪽 부드러운 풀밭 곡선(SVG)
- 패널: 흰색 62% 반투명 + `backdrop-filter: blur(14px)` + 위쪽 1px 하이라이트 + 흰 테두리
- 버튼: 진한 파랑 바탕 + 위쪽 48%에만 흰 광택 타원 (유리구슬)
- 장식: 물방울·비눗방울 SVG, 화면당 6개 이하, 패널 뒤에만
- 반경 2단계: 패널 18px, 버튼·입력·배지 999px(알약)
- 글자는 진한 남색. 반투명 위라도 대비 4.5:1 이상 보장

---

## 2. 컬러 팔레트 & 역할

### Light (기본)

```css
:root {
  /* 하늘 */
  --sky-top:      #7FC8F8;  /* 그라디언트 맨 위 */
  --sky-mid:      #CDEBFF;
  --sky-low:      #EEF9FF;
  --grass:        #CDEFC4;  /* 그라디언트 맨 아래 */
  --grass-deep:   #8ED17E;  /* 풀밭 곡선 SVG */

  /* 표면 */
  --glass:        rgba(255, 255, 255, .62);  /* 반투명 패널 */
  --glass-strong: rgba(255, 255, 255, .86);  /* 표·긴 본문을 담는 패널 */
  --glass-edge:   rgba(255, 255, 255, .90);  /* 패널 테두리 */

  /* 글자 */
  --text:         #0B3556;  /* 진한 남색 본문 */
  --muted:        #3B627E;  /* 보조 — glass-strong 위 6.1:1 */
  --border:       #B9DCF0;

  /* 동작 */
  --primary:      #1477BD;  /* 광택 버튼 바탕 위쪽 (흰 글자 4.9:1) */
  --primary-deep: #0A5E9C;  /* 광택 버튼 바탕 아래쪽 (흰 글자 7.0:1) */
  --aqua:         #23B5D3;  /* 진행 바 채움, 차트 */
  --accent:       #3BAA3F;  /* 잎사귀 초록 — '새로움·여유' 한 곳 */
  --accent-text:  #1F6B24;  /* 초록 의미를 글자로 쓸 때 (흰 패널 대비 6.4:1) */
  --danger:       #B8323F;

  --btn-text:     #FFFFFF;
}
```

### Dark — "밤바다 에어로"

다크는 하늘 대신 **밤바다**다. 남색 그라디언트에 패널은 흰색 8%, 광택은 그대로 두되 세기를 절반으로 줄인다.

```css
:root[data-theme="dark"] {
  --sky-top:      #04263F;
  --sky-mid:      #073A57;
  --sky-low:      #0A4A63;
  --grass:        #0B4B47;
  --grass-deep:   #12665A;
  --glass:        rgba(255, 255, 255, .08);
  --glass-strong: rgba(8, 40, 64, .82);
  --glass-edge:   rgba(255, 255, 255, .18);
  --text:         #E8F6FF;
  --muted:        #A9CDE3;  /* glass-strong 위 8.0:1 */
  --border:       #1D5675;
  --primary:      #2B95DE;
  --primary-deep: #126FB4;
  --aqua:         #48D2EC;
  --accent:       #6FD36A;
  --accent-text:  #A6EBA0;
  --danger:       #FF8C95;
  --btn-text:     #FFFFFF;
}
```

### 역할 규칙

| 토큰 | 쓰는 곳 | 쓰지 않는 곳 |
|---|---|---|
| 광택 버튼(`--primary`) | 주 동작 1개 ("휴가 신청") | 카드 전체, 제목 배경 |
| `--aqua` | 진행 바, 차트 막대, 날씨 아이콘 | 글자 (흰 패널 위 2.6:1 — 금지) |
| `--accent` | "신규"·"오늘" 점 하나, 잔여 여유 강조 | 큰 면, 버튼 |
| `--glass` | 장식성 패널(날씨, 인사) | 표·긴 본문 → `--glass-strong` |
| `--glass-strong` | 표, 목록, 폼이 들어간 패널 | — |

---

## 3. 타이포그래피

| 역할 | 서체 | 불러오기 |
|---|---|---|
| 한글 본문·UI·제목 | **Pretendard Variable** | `cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css` |
| 영문·숫자 포인트 | **Ubuntu** 400·500·700 | Google Fonts `family=Ubuntu:wght@400;500;700` |

Frutiger(원래 서체)는 웹폰트로 자유롭게 쓸 수 없다. 같은 시대의 둥글고 인간적인 산세리프인 Ubuntu가 그 분위기를 가장 잘 낸다. 숫자(휴가 잔여일, 포인트)는 Ubuntu로.

```css
--font-sans: "Pretendard Variable", Pretendard, -apple-system, "Malgun Gothic", sans-serif;
--font-num:  "Ubuntu", "Pretendard Variable", sans-serif;
.num { font-family: var(--font-num); font-variant-numeric: tabular-nums; }
```

### 스케일 (6단계)

| 토큰 | 크기 / 굵기 / 자간 | 용도 |
|---|---|---|
| `display` | 30px / 700 / -0.02em | 페이지 인사말 |
| `metric` | 44px / 500 (Ubuntu) | 휴가 잔여일, 포인트 |
| `h2` | 18px / 700 | 패널 제목 |
| `h3` | 15px / 600 | 목록 항목 제목 |
| `body` | 14px / 500, 행간 1.55 | 설명 |
| `label` | 12px / 600, `--muted` | 라벨, 시간 |

제목에 `text-shadow: 0 1px 0 rgba(255,255,255,.7)`를 줘 "새겨진" 느낌을 낼 수 있다(라이트 모드, 제목 한정).

---

## 4. 컴포넌트

### 패널 (반투명 유리판)

```css
.panel {
  position: relative;
  background: var(--glass);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid var(--glass-edge);
  border-radius: 18px;
  padding: 20px 22px;
  box-shadow: var(--aero-panel);
}
.panel--solid { background: var(--glass-strong); }   /* 표·목록·폼 */
.panel-title { font: 700 18px/1.3 var(--font-sans); color: var(--text); }
```

### 광택 버튼 (유리구슬)

```css
.btn-gloss {
  position: relative; overflow: hidden; isolation: isolate;
  height: 44px; padding: 0 24px;
  border: 1px solid #08507F;
  border-radius: 999px;
  color: var(--btn-text);
  font: 700 15px/1 var(--font-sans);
  text-shadow: 0 1px 1px rgba(0, 40, 80, .55);
  background: linear-gradient(180deg, var(--primary) 0%, var(--primary-deep) 100%);
  box-shadow: var(--aero-btn);
  cursor: pointer;
  transition: filter 180ms ease, transform 180ms ease;
}
.btn-gloss::before {                 /* 위쪽 광택 */
  content: ""; position: absolute; z-index: -1;
  left: 6%; right: 6%; top: 2px; height: 48%;
  border-radius: 999px 999px 40% 40% / 999px 999px 100% 100%;
  background: linear-gradient(180deg, rgba(255,255,255,.80) 0%, rgba(255,255,255,.10) 100%);
}
.btn-gloss:hover  { filter: brightness(1.08); }
.btn-gloss:active { transform: translateY(1px); filter: brightness(.94); }
.btn-gloss:focus-visible { outline: 3px solid #F5B400; outline-offset: 3px; }

.btn-glass {                         /* 보조 버튼: 흰 유리구슬 */
  position: relative; overflow: hidden; isolation: isolate;
  height: 40px; padding: 0 18px; border-radius: 999px;
  color: var(--text); font: 600 14px/1 var(--font-sans);
  background: linear-gradient(180deg, #FFFFFF 0%, #E3F2FB 100%);
  border: 1px solid var(--border);
  box-shadow: 0 2px 6px rgba(11, 53, 86, .14), inset 0 1px 0 #fff;
}
```

### 배지

```css
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 10px; border-radius: 999px;
  font: 700 12px/1 var(--font-sans);
  background: linear-gradient(180deg, #FFFFFF 0%, #DCEFFA 100%);
  border: 1px solid var(--border); color: var(--text);
}
.badge--new { background: linear-gradient(180deg, #E9F8E4 0%, #C9EEC0 100%); border-color: #A9DC9C; color: var(--accent-text); }
```

### 입력

```css
.field {
  height: 42px; width: 100%; padding: 0 16px;
  border-radius: 999px; border: 1px solid var(--border);
  background: linear-gradient(180deg, #F2F9FD 0%, #FFFFFF 60%);
  box-shadow: inset 0 2px 3px rgba(11, 53, 86, .12);
  color: var(--text); font: 500 14px var(--font-sans);
}
.field::placeholder { color: var(--muted); }
.field:focus { outline: none; border-color: var(--primary); box-shadow: inset 0 2px 3px rgba(11,53,86,.12), 0 0 0 3px rgba(35,181,211,.35); }
.field[aria-invalid="true"] { border-color: var(--danger); }
```

### 진행 바 (유리관 안의 물)

```css
.meter { height: 14px; border-radius: 999px; background: rgba(11, 53, 86, .10);
         box-shadow: inset 0 1px 2px rgba(11,53,86,.20); overflow: hidden; }
.meter > i { display: block; height: 100%; border-radius: 999px;
             background: linear-gradient(180deg, #7BE0F2 0%, var(--aqua) 50%, #1593AD 100%);
             box-shadow: inset 0 1px 0 rgba(255,255,255,.7); }
```

### 내비게이션

상단 가로 바 하나. 반투명 패널(`--glass-strong`) 위에 알약형 메뉴, 현재 메뉴만 흰 유리구슬(`.btn-glass` 스타일) + 아래 아쿠아 2px 선.

```css
.topnav { display: flex; align-items: center; gap: 6px; padding: 8px; border-radius: 999px;
          background: var(--glass-strong); border: 1px solid var(--glass-edge); box-shadow: var(--aero-panel); }
.topnav a { height: 38px; padding: 0 16px; border-radius: 999px; display: flex; align-items: center;
            font-weight: 600; color: var(--muted); }
.topnav a[aria-current="page"] { color: var(--text); background: linear-gradient(180deg,#fff,#E3F2FB);
            box-shadow: 0 2px 6px rgba(11,53,86,.14), inset 0 1px 0 #fff; }
```

---

## 5. 효과 레시피

### 배경 (1장)

```css
body {
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(255,255,255,.55) 0%, rgba(255,255,255,0) 60%),  /* 햇살 */
    linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 38%, var(--sky-low) 68%, var(--grass) 100%);
  background-attachment: fixed;
}
```

아래쪽 풀밭은 `position: fixed; bottom: 0` SVG 곡선 2겹(`--grass-deep` 40%, 25% 불투명도). 화면 높이의 18% 이하.

### 그림자 토큰 (2개만)

```css
:root {
  --aero-panel:
    0 8px 24px rgba(11, 53, 86, .14),       /* 바깥 그림자 */
    inset 0 1px 0 rgba(255, 255, 255, .95), /* 위쪽 하이라이트 1px */
    inset 0 -1px 0 rgba(11, 53, 86, .06);   /* 아래쪽 미세 경계 */
  --aero-btn:
    0 3px 8px rgba(8, 80, 127, .35),
    inset 0 -2px 4px rgba(0, 30, 70, .30),  /* 바닥 쪽 깊이 */
    inset 0 1px 0 rgba(255, 255, 255, .45);
}
```

### 물방울 · 비눗방울 (SVG)

```html
<!-- 비눗방울: 테두리 무지갯빛 + 위쪽 광택 점 -->
<svg width="90" height="90" viewBox="0 0 90 90" aria-hidden="true">
  <defs>
    <radialGradient id="bub" cx="35%" cy="30%" r="70%">
      <stop offset="0" stop-color="#fff" stop-opacity=".9"/>
      <stop offset=".25" stop-color="#fff" stop-opacity=".15"/>
      <stop offset=".85" stop-color="#9FE7F5" stop-opacity=".25"/>
      <stop offset="1" stop-color="#B9F0C5" stop-opacity=".7"/>
    </radialGradient>
  </defs>
  <circle cx="45" cy="45" r="42" fill="url(#bub)" stroke="#fff" stroke-opacity=".7"/>
  <ellipse cx="31" cy="26" rx="10" ry="6" fill="#fff" opacity=".85" transform="rotate(-30 31 26)"/>
</svg>
```

물방울(위쪽이 뾰족한 형태)은 같은 그라디언트에 `path d="M45 4 C62 30 78 46 78 62 a33 33 0 0 1-66 0 C12 46 28 30 45 4z"`.

**쓰는 양의 상한**
- 배경 그라디언트: **1장** (body). 패널마다 그라디언트 배경을 주지 않는다
- 광택 버튼: 주 버튼 **1개** + 아이콘 버튼 광택은 작은 원형만
- `backdrop-filter` 패널: **6개 이하**, 서로 겹치지 않게 (겹치면 블러가 이중으로 걸려 탁해진다)
- 비눗방울·물방울: 화면당 **6개 이하**, 패널 **뒤**(z-index 0)에만, 글자 위에 겹치지 않음
- 렌즈 플레어, 무지개 빔, 별 반짝임 금지 — 2000년대 클립아트로 넘어간다

---

## 6. 레이아웃

| 토큰 | 값 |
|---|---|
| `--gap` | 20px |
| `--pad` | 20~22px (패널), 모바일 16px |
| 반경 | 패널 18px / 패널 안 블록 12px / 알약 999px |
| 최대 폭 | 1200px, 좌우 여백 24px |

상단 내비(알약 바) + 본문 12열. 중요도 순으로 크기를 다르게 한다: 휴가 잔여(5열, 큰 숫자) / 복지 포인트(4열) / 날씨(3열, 가장 장식적인 패널 — 여기만 `--glass`), 아래 줄은 사내 행사 목록(7열, `--glass-strong`) / 신청 내역(5열).

```css
.board { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); gap: 20px; }
```

모바일(≤640px): 1열, 상단 내비는 하단 탭 바(반투명 알약)로, 배경 장식은 3개로 줄인다. `background-attachment: fixed`는 모바일에서 `scroll`로(iOS 성능).

---

## 7. 모션

| 상황 | 처리 | 시간 |
|---|---|---|
| 버튼 호버 | `brightness(1.08)` | 180ms |
| 버튼 누름 | 1px 하강 + `brightness(.94)` | 120ms |
| 진행 바 | 폭 변화 | 400ms ease-out |
| 비눗방울 | 위로 12px 천천히 떠오름, 왕복 | 6~9s ease-in-out infinite |

비눗방울 떠다니는 모션은 이 스타일에서 허용되는 유일한 반복 모션이고, **3개 이하**에만 건다.

```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
```

---

## 8. 접근성

밝은 하늘·반투명 패널은 **글자 대비가 배경에 따라 흔들린다.** 아래를 지킨다.

1. 본문은 진한 남색 `--text`(#0B3556). 가장 밝은 배경(#EEF9FF)에서 12:1, 가장 진한 하늘(#7FC8F8)에서도 7:1
2. 표·목록·폼·긴 본문은 반드시 `--glass-strong`(흰 86%) 패널에. 62% 패널 위에는 제목·큰 숫자·짧은 라벨만
3. `--muted`(#3B627E)는 `--glass-strong` 위에서만 보조 글자로. `--glass` 위 작은 회색 글자 금지
4. `--aqua`(#23B5D3)·`--accent`(#3BAA3F)는 **글자색으로 쓰지 않는다**(흰 바탕 대비 2.6~3.2:1). 초록 의미가 필요한 글자는 `--accent-text`
5. 광택 버튼의 흰 글자: 바탕 위쪽 `#1477BD`가 4.9:1 + `text-shadow`로 광택 영역에서도 윤곽 유지. 광택 `::before`는 높이 48%를 넘기지 않는다(글자 아래 절반은 진한 바탕 위)
6. `prefers-reduced-transparency: reduce`이면 `--glass`·`--glass-strong`을 불투명 `#F4FAFE`로 바꾸고 `backdrop-filter`를 끈다
7. `backdrop-filter` 미지원 브라우저 대비 `@supports not (backdrop-filter: blur(1px))`에서 `--glass-strong`으로 대체
8. 포커스 링은 노란 `#F5B400` 3px — 하늘색 배경에서 가장 잘 보이는 보색
9. 장식 SVG는 모두 `aria-hidden="true"`

```css
@media (prefers-reduced-transparency: reduce) {
  .panel { background: #F4FAFE; -webkit-backdrop-filter: none; backdrop-filter: none; }
}
```

---

## 9. 하지 말 것

- 광택을 모든 카드·배지·제목에 바르기 (버튼과 진행 바에만)
- 패널마다 다른 그라디언트 배경
- 반투명 62% 패널 위에 표나 작은 회색 글자
- 아쿠아·초록을 글자색으로
- 렌즈 플레어, 무지개 빔, 반짝이 별, 돌고래·지구본 클립아트
- 외부 사진(하늘·풀밭 이미지) — 배경은 CSS 그라디언트와 SVG로만
- 비눗방울을 글자 위에 겹치기, 7개 이상 띄우기
- 각진 모서리(반경 0~6px) — 이 시대 UI는 다 둥글다
- 이모지 (날씨도 lucide 아이콘: `sun`, `cloud-sun`, `droplets`)
- 해피 패스만 있는 화면 — 포인트 0점, 신청 내역 없음, 날씨 불러오기 실패 상태도 그린다

---

## 10. 셀프 체크리스트

- [ ] 배경 그라디언트가 body 1장뿐인가?
- [ ] 광택 버튼이 주 동작 1개뿐인가? 광택 높이가 48% 이하인가?
- [ ] 그림자가 `--aero-panel` / `--aero-btn` 두 토큰뿐인가?
- [ ] 표·목록이 `--glass-strong` 패널에 들어 있나?
- [ ] 아쿠아·초록이 글자색으로 쓰이지 않았나?
- [ ] 비눗방울이 6개 이하, 패널 뒤에만 있나? 움직이는 건 3개 이하인가?
- [ ] `prefers-reduced-motion` / `prefers-reduced-transparency` 처리가 있나?
- [ ] 반경이 18 / 12 / 999 외에 없나?
- [ ] 휴가 일수·포인트·행사 날짜가 현실적인가? (예: "연차 15일 중 9.5일 남음", "복지포인트 412,000P")
- [ ] 빈 상태·로딩·에러가 있나?

### 빠른 토큰

```
sky #7FC8F8 → #CDEBFF → #EEF9FF → grass #CDEFC4 (세로 그라디언트 1장)
glass rgba(255,255,255,.62) · glass-strong rgba(255,255,255,.86) · edge rgba(255,255,255,.9)
text #0B3556 · muted #3B627E · border #B9DCF0 · primary #1477BD→#0A5E9C · aqua #23B5D3 · accent #3BAA3F
radius 18 / 12 / 999 · gap 20 · Pretendard + Ubuntu(숫자·영문)
gloss: ::before 위쪽 48%, rgba(255,255,255,.8)→.1 그라디언트
```

### 복사용 프롬프트

```
프루티거 에어로 스타일로 사내 복지 포털 첫 화면을 만들어줘. designs/frutiger-aero.md를 따른다.
- 배경은 body 하나에만 하늘(#7FC8F8)→아쿠아→연초록(#CDEFC4) 세로 그라디언트 + 아래쪽 풀밭 곡선 SVG
- 패널은 흰색 62% 반투명 + blur(14px) + 위쪽 1px 흰 하이라이트, 표·목록은 86% 패널에
- 주 버튼 1개만 유리구슬 광택 버튼 (진한 파랑 #1477BD→#0A5E9C + 위쪽 48% 흰 광택 ::before)
- 구성: 연차 잔여일(큰 숫자 Ubuntu), 복지포인트, 사내 날씨 위젯, 이번 달 사내 행사 목록, 최근 신청 내역
- 비눗방울 SVG 6개 이하, 패널 뒤에만. 이미지 파일·이모지 금지, 아이콘은 lucide SVG
- 글자는 진한 남색 #0B3556, 아쿠아·초록은 글자색으로 쓰지 말 것
- 빈 상태·로딩·에러, prefers-reduced-motion·prefers-reduced-transparency 포함
```
