feat(theme): add brown and orange background gradients

This commit is contained in:
shkim4 committed 2026-10-11 13:30:30 +09:00
1 parent 220973cf89
commit 3220b753dd
12 files changed
+206 -20

No files matched your search

+1 -1
View File
@@ -37,7 +37,7 @@ resetRuntimeTheme(document.documentElement)
- 일반 새 탭은 독립 세션입니다. 탭 복제 또는 opener로 연 탭은 브라우저가 초기 sessionStorage를 복사할 수 있으며 이후 편집은 탭별로 독립적입니다.
- 서버/DB/Publish 기능은 없습니다. 같은 브라우저 탭의 Storybook preview origin에 `sessionStorage`로 보관하며, 세션 저장을 사용할 수 없는 환경에서도 현재 화면의 편집/Export는 동작합니다. 장기 보관은 JSON Export를 사용하세요.
- Global Theme는 `document.documentElement`에 적용하며 body Portal도 같은 Theme를 사용합니다. wrapper 밖으로 Portal된 popup은 Scoped Theme를 자동 전달받지 않습니다. 이 제한은 기존 FOLLOW_UP입니다.
- 전체 Runtime Contract는 84개 입력입니다(2026-10-11 기존 확정 브랜드 팔레트 8개 및 사용자 확정 Orange Dark 1·2 추가, 이전 81개 보존 및 Provisional Generic Status Error 1개 추가). 배포하는 Default JSON은 82개 컬러이며 radius/geometry는 package에서 관리합니다. 편집 화면은 상위 컬러 역할 17개만 노출하며 Component Token, radius, palette/gradient 개별 입력 UI를 만들지 않습니다. 기존 컬러 계약의 palette/gradient는 유효 JSON으로 Import할 수 있으며 gradient는 세트 전체를 제공해야 합니다.
- 전체 Runtime Contract는 94개 입력입니다(2026-10-11 기존 확정 브랜드 팔레트 8개 및 사용자 확정 Orange Dark 1·2 추가, 이전 81개 보존 및 Provisional Generic Status Error 1개, 확정 Brown·Orange Background Stop 10개 추가). 배포하는 Default JSON은 92개 컬러이며 radius/geometry는 package에서 관리합니다. 편집 화면은 상위 컬러 역할 17개만 노출하며 Component Token, radius, palette/gradient 개별 입력 UI를 만들지 않습니다. 기존 컬러 계약의 palette/gradient는 유효 JSON으로 Import할 수 있으며 gradient는 세트 전체를 제공해야 합니다.
- 명시적 `[data-hm-theme]` scope는 독립 HM preset이므로 Global Theme를 이어받지 않습니다. Production에서 같은 root는 한 owner가 Apply/Reset을 관리합니다.
- Storybook 편집기 설치는 이번 코드 변경을 적용하는 최초 빌드가 필요합니다. 설치 후 컬러 값을 바꾸는 운영에는 재빌드가 필요 없습니다.
+20 -2
View File
@@ -21,6 +21,16 @@
| `color.bg.brand.stop.42` | `--hm-sem-brand-bg-stop-42` | `#123328` | 기존 gradient stop: color.bg.brand.stop.42 | Yes | Theme palette / adapter |
| `color.bg.brand.stop.78` | `--hm-sem-brand-bg-stop-78` | `#266651` | 기존 gradient stop: color.bg.brand.stop.78 | Yes | Theme palette / adapter |
| `color.bg.brand.stop.100` | `--hm-sem-brand-bg-stop-100` | `#205241` | 기존 gradient stop: color.bg.brand.stop.100 | Yes | Theme palette / adapter |
| `color.bg.brown.stop.0` | `--hm-sem-brown-bg-stop-0` | `#352d1d` | Brown Background · Dark 1 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.brown.stop.12` | `--hm-sem-brown-bg-stop-12` | `#2f281c` | Brown Background · Dark 2 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.brown.stop.42` | `--hm-sem-brown-bg-stop-42` | `#3e3523` | Brown Background · Default | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.brown.stop.78` | `--hm-sem-brown-bg-stop-78` | `#897445` | Brown Background · Light 2 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.brown.stop.100` | `--hm-sem-brown-bg-stop-100` | `#604f32` | Brown Background · Light 1 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.orange.stop.0` | `--hm-sem-orange-bg-stop-0` | `#bc4c00` | Orange Background · Dark 1 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.orange.stop.12` | `--hm-sem-orange-bg-stop-12` | `#883700` | Orange Background · Dark 2 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.orange.stop.42` | `--hm-sem-orange-bg-stop-42` | `#cc5200` | Orange Background · Default | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.orange.stop.78` | `--hm-sem-orange-bg-stop-78` | `#f87725` | Orange Background · Light 2 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `color.bg.orange.stop.100` | `--hm-sem-orange-bg-stop-100` | `#eb5f00` | Orange Background · Light 1 | Yes · 5개 세트 | 공통 Background / Foundation Color |
| `surface.action.primary.stop.0` | `--hm-sem-action-surface-stop-0` | `#1f8265` | 기존 gradient stop: surface.action.primary.stop.0 | Yes | button, gnb |
| `surface.action.primary.stop.30` | `--hm-sem-action-surface-stop-30` | `#165c47` | 기존 gradient stop: surface.action.primary.stop.30 | Yes | button, gnb |
| `surface.action.primary.stop.65` | `--hm-sem-action-surface-stop-65` | `#114838` | 기존 gradient stop: surface.action.primary.stop.65 | Yes | button, gnb |
@@ -90,7 +100,7 @@
| `color.palette.orange-dark-2` | `--hm-sem-palette-orange-dark-2` | `#883700` | 2026-10-11 사용자 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette |
| `color.palette.orange-dark-3` | `--hm-sem-palette-orange-dark-3` | `#4f2000` | 2026-10-11 사용자 재확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette |
총 84개. 기존 25개 + 핵심 역할 6개 + 선택적 팔레트 52개(2026-10-11 ui_viz 확정 단계 8개 및 사용자 확정 Orange Dark 1·2 추가) + Provisional Generic Status Error 1개. 팔레트는 컴포넌트별 계약이 아니며 Primary / Active / Focus를 개별 지정하면 팔레트 alias보다 우선한다. Focus와 Active, Primary와 On Accent는 각각 sibling이며 서로 alias하지 않는다.
총 94개. 기존 25개 + 핵심 역할 6개 + 선택적 팔레트 52개(2026-10-11 ui_viz 확정 단계 8개 및 사용자 확정 Orange Dark 1·2 추가) + Provisional Generic Status Error 1개 + Brown·Orange Background Stop 10개. 팔레트는 컴포넌트별 계약이 아니며 Primary / Active / Focus를 개별 지정하면 팔레트 alias보다 우선한다. Focus와 Active, Primary와 On Accent는 각각 sibling이며 서로 alias하지 않는다.
## Generic Status Error — Provisional · 2026-10-11
@@ -103,7 +113,7 @@ Input Error와 Generic Status Error는 별도 역할이다. Input / Alert destru
기존 v1 입력 73개와 이전 팔레트 보강 이후 81개의 Key·CSS property·type·Default를 유지한다. Orange Dark 1·2는 최신 사용자 확정값으로 공개 입력에 추가하며 Dark 3는 기존 값을 유지한다. 과거 Needs Review 기록은 이력으로 보존하고 현재 기준은 [브랜드 컬러 단계](brand-color-steps.md)를 따른다. 공개 API `isRuntimeTheme(unknown): value is RuntimeTheme`를 제공한다. 이 사전 검증은 DOM을 변경하지 않는다. 기존 `applyRuntimeTheme`의 invalid 입력 시 reset 정책은 유지한다. 편집기는 사전 검증으로 invalid Import를 차단해 마지막 유효 Theme를 보존한다.
Default 컬러의 운영 원본은 `themes/default.json`(82개 컬러)이다. `scripts/theme-defaults.mjs`가 JSON과 컬러 literal 없는 alias/geometry template에서 package `primitives.css`, `default.css`, `default-values.generated.ts`를 생성한다. `contract.ts`의 defaultValue와 `defaultRuntimeTheme`는 생성 데이터를 읽는다. 2개 radius/geometry는 template에서 유지한다. CSS fallback/현재 색을 유지하고 세 가지 최종 명령의 pre hook에서 stale 생성 데이터를 검사한다. Theme-only 산출은 `npm run build:themes`로 분리한다.
Default 컬러의 운영 원본은 `themes/default.json`(92개 컬러)이다. `scripts/theme-defaults.mjs`가 JSON과 컬러 literal 없는 alias/geometry template에서 package `primitives.css`, `default.css`, `default-values.generated.ts`를 생성한다. `contract.ts`의 defaultValue와 `defaultRuntimeTheme`는 생성 데이터를 읽는다. 2개 radius/geometry는 template에서 유지한다. CSS fallback/현재 색을 유지하고 세 가지 최종 명령의 pre hook에서 stale 생성 데이터를 검사한다. Theme-only 산출은 `npm run build:themes`로 분리한다.
Storybook `Theme/Designer Playground/Editor`는 17개 상위 컬러 역할과 JSON URL/파일 Preview를 제공하는 소비자다. Global decorator에서 `resolveRuntimeTheme(theme, defaultJson)` 후 Production `applyRuntimeTheme(document.documentElement, theme)` → CSS Custom Properties → 기존 Mapping으로 적용한다. JSON Export/Import는 동일 v1 계약이다. 컬러 artifact/편집기만 radius를 거부한다. Production API의 기존 radius/gradient 계약은 유지한다.
@@ -114,3 +124,11 @@ Storybook `Theme/Designer Playground/Editor`는 17개 상위 컬러 역할과 JS
## Dashboard 상태 색상 범위
Dashboard의 `active / hold / done / issue` 업무 상태 계약은 `packages/ui/src/patterns/dashboard-status/contract.ts`에서 ID·label·tone을 제공한다. 상태 변수 원본은 `packages/ui/src/patterns/dashboard-status/dashboard-status.css`이며 `@hm-design/ui/dashboard-status.css`로 배포한다. `src/patterns/dashboard-status-contract.css`는 기존 Story/HTML 경로의 호환 import다. Theme CSS 다음에 상태 CSS를 로드하고 `--hm-dashboard-status-active|hold|done|issue`를 화면 요소의 색상에 별도로 연결한다. 상태 CSS 자체는 Badge나 `data-status`를 자동으로 꾸미지 않는다. active/hold/issue는 기존 Story 색상을 보존하는 compatibility mapping이고 done은 `:root` 및 `[data-hm-theme]`에서 해당 scope의 기존 HM white token을 참조한다. 기존 HM Theme 및 Public Runtime Token/JSON에 상태 입력은 추가하지 않으며, 실제 Production 소비처가 반복되어 공통 색상 의미가 확정될 때만 Semantic Token 승격을 검토한다.
## Brown·Orange 공통 Background — Confirmed · 2026-10-11
사용자가 확정한 [브랜드 Palette](brand-color-steps.md)의 Dark 1 / Dark 2 / Default / Light 2 / Light 1을 기본값으로 참조한다. 공개 입력은 각각 `color.bg.brown.stop.*`, `color.bg.orange.stop.*`이며 CSS-only fallback은 대응 `--hm-sem-palette-<brand>-<stage>`를 참조한다. 명시적 Runtime stop 값은 Palette alias보다 우선한다. Green과 같은 `to bottom`, 0 / 12 / 42 / 78 / 100% 구조다.
조합 변수 `--hm-sem-bg-brown` / `--hm-sem-bg-orange`는 내부 Derived CSS이며 전체 Gradient 문자열·방향·위치를 Runtime JSON 입력으로 받지 않는다. Runtime에서 한 stop을 바꾸려면 해당 브랜드의 5개 stop을 모두 전달한다. Brown·Orange 두 그룹은 서로 독립적이며 미지정 그룹은 기존 fallback을 따른다. 부분 그룹은 atomic validation으로 거부한다. Global / Scoped 적용과 Reset은 [Runtime Theme](runtime-theme.md)의 기존 계약을 사용한다.
공통 Background는 기존 Green·Brown/Orange Button·Dashboard 배경에 자동 연결하지 않는다. [Foundation Color](../../src/foundation/color.stories.tsx)의 기존 `foundation-color--all`에서 실제 Gradient, 각 stop Token/CSS 변수·위치·HEX, 미리보기 요소의 computed `background-image`를 표시한다. 기존 Button 전용 미리보기도 보존한다. 과거 미정의 검증 보고서는 당시 이력으로 유지한다.
+3 -3
View File
@@ -14,7 +14,7 @@
React 외 실행 형식으로 변환할 때도 이 문서의 Token·CSS Custom Properties·Runtime 적용 계약을 유지한다. Target Runtime, standalone asset, `file://` 검증 및 AI/도구 독립성 기준은 [Runtime Portability Policy](runtime-portability.md)를 따른다.
소비 CSS는 `tailwindcss` → `@hm-design/ui/tailwind.css` → `@hm-design/ui/theme.css` 순서로 앱 entry에서 로드한다. Dashboard 상태 표시가 있으면 그 뒤에 `@hm-design/ui/dashboard-status.css`와 소비 Badge mapping을 연결한다([상태 예제](../patterns/dashboard-layout.md#dashboard-업무-상태-공통-계약)). Status CSS는 변수만 정의하며 84개 Runtime Theme 계약에 새 상태 Token을 추가하지 않는다. [Tailwind 검색 범위](runtime-portability.md#21-tailwind-v4-소비자-검색-범위)와 [Noto Sans KR·Asset 경로](runtime-portability.md#41-noto-sans-kr-경로-실행-환경별-확인)는 실행 환경별 소비 가이드를 따른다.
소비 CSS는 `tailwindcss` → `@hm-design/ui/tailwind.css` → `@hm-design/ui/theme.css` 순서로 앱 entry에서 로드한다. Dashboard 상태 표시가 있으면 그 뒤에 `@hm-design/ui/dashboard-status.css`와 소비 Badge mapping을 연결한다([상태 예제](../patterns/dashboard-layout.md#dashboard-업무-상태-공통-계약)). Status CSS는 변수만 정의하며 94개 Runtime Theme 계약에 새 상태 Token을 추가하지 않는다. [Tailwind 검색 범위](runtime-portability.md#21-tailwind-v4-소비자-검색-범위)와 [Noto Sans KR·Asset 경로](runtime-portability.md#41-noto-sans-kr-경로-실행-환경별-확인)는 실행 환경별 소비 가이드를 따른다.
Default는 특별한 컴포넌트 내부 상수가 아니라 이 계약을 만족하는 기본 제공 Theme Set이다. 주입이 없으면 패키지 CSS의 Default preset을 사용한다. `defaultRuntimeTheme`는 동일한 값을 가진 JSON 형태 preset이다. Story의 CSS fallback / Default preset 주입 비교와 계약 값 검사로 두 표현의 일치를 검증한다.
@@ -24,7 +24,7 @@ Default는 특별한 컴포넌트 내부 상수가 아니라 이 계약을 만
- **내부 Derived**: `--hm-sem-surface-highlight`(Accent 45%), gradient 조합, shadow/overlay 조합, shadcn adapter(`--primary`, `--ring` 등). 외부 JSON은 이 변수를 직접 쓰지 않는다.
- **내부 Component Mapping**: `--hm-checkbox-*`, `--hm-calendar-*`, `--hm-pagination-*` 등. 기존 이름을 유지한다. Runtime JSON으로 받지 않는다.
- Typography, height, spacing, gradient geometry, shadow geometry, responsive layout은 코드 계약이다. 이번 컬러 구조 변경으로 Runtime 범위를 확대하지 않았다.
- Typography 현황(2026-10-08): 기존 크기와 ui_viz 승인 변경값을 유지한다. `packages/ui/src/theme/*.css`의 font-size는 px이고 shadcn 유래 Tailwind class(`text-sm` 등)는 rem 기반이라 단위가 혼재한다. 소비자가 Tailwind class나 `className`으로 크기를 덮어쓰면 Theme 값보다 우선할 수 있다. Typography Role(heading/body/label 등)은 아직 공통 Token으로 도입하지 않았고 Runtime JSON 84개 계약에도 포함하지 않는다.
- Typography 현황(2026-10-08): 기존 크기와 ui_viz 승인 변경값을 유지한다. `packages/ui/src/theme/*.css`의 font-size는 px이고 shadcn 유래 Tailwind class(`text-sm` 등)는 rem 기반이라 단위가 혼재한다. 소비자가 Tailwind class나 `className`으로 크기를 덮어쓰면 Theme 값보다 우선할 수 있다. Typography Role(heading/body/label 등)은 아직 공통 Token으로 도입하지 않았고 Runtime JSON 94개 계약에도 포함하지 않는다.
기존 25개 allowlist의 JSON 이름과 validation을 유지하고 Active / on Active / Inverse Text / Subtle Surface / Accent / on Accent를 추가했다. 같은 CSS property로 향하는 중복 공개 key는 없다. Component 수백 개의 Token을 요구하는 대신 Theme 팔레트는 선택적 확장이다. 핵심 역할만 지정해도 사용할 수 있다. 팔레트 이름은 색상 계열을 유지하며, 역할 Token은 각각 독립적으로 override할 수 있다.
@@ -69,7 +69,7 @@ resetRuntimeTheme(document.documentElement)
- 부분 Token만 제공: 같은 scope의 미지정 값은 HM Default를 사용한다. Theme A에서 B로 교체할 때 A의 키가 남지 않는다.
- `null`, 단순 `{}`, 잘못된 schemaVersion, 알 수 없는 key, Component Token key, 잘못된 값: false를 반환하고 이 helper의 이전 override를 해제한다. 정상적인 host에서는 Default로 돌아간다. host가 원래 소유한 inline override는 복원한다.
- 불투명 6자리 HEX만 허용한다. radius는 2–12px 정수만 허용한다. `var()`, `url()`, CSS 함수, `!important`, 임의 CSS rule은 입력할 수 없다.
- 기존 3개의 gradient stop 그룹은 각각 전체 또는 미지정만 허용한다. 한 stop만 보내면 문서 전체를 거부한다.
- Green 배경·Primary 면·Primary border·Brown 배경·Orange 배경의 5개 gradient stop 그룹은 각각 전체 또는 미지정만 허용한다. 한 stop만 보내면 문서 전체를 거부한다.
- 입력 전체를 검증한 뒤 DOM에 쓴다. 하나의 잘못된 값 때문에 CSS가 오염되는 대신 마지막 override를 해제한다. 이 atomic fallback은 기존 정책을 유지했다.
- cleanup은 helper가 덮기 전 inline 값과 priority 및 `data-hm-theme` 속성을 복원한다. 같은 scope는 한 owner가 적용/해제를 관리한다. 서로 다른 helper 호출자가 같은 scope를 동시에 소유하는 다중 owner 시스템은 제공하지 않는다.
+2 -2
View File
@@ -12,7 +12,7 @@ HMDesignSystem/
│ ├─ ui/ # @hm-design/ui: logic, contract, mapping, runtime
│ └─ center-graphic/ # 독립 Graphic package
├─ themes/
│ ├─ default.json # 82개 public color 값의 공식 Default 원본
│ ├─ default.json # 92개 public color 값의 공식 Default 원본
│ ├─ service-example.json # 5개 역할만 바꾸는 명시적 예제
│ └─ drafts/ # 과거 초안; Theme 산출 대상 아님
├─ scripts/
@@ -23,7 +23,7 @@ HMDesignSystem/
└─ docs/guidelines/
```
`themes/default.json`은 기존 v1 `{schemaVersion:1,tokens:{...}}` 계약을 사용한다. Component Token은 없다. 84개 Runtime 입력 중 82개 컬러를 포함한다. 나머지 두 radius와 layout은 패키지 template에서 관리한다. 서비스 Theme는 같은 계약의 부분 컬러 override다.
`themes/default.json`은 기존 v1 `{schemaVersion:1,tokens:{...}}` 계약을 사용한다. Component Token은 없다. 94개 Runtime 입력 중 92개 컬러를 포함한다. 나머지 두 radius와 layout은 패키지 template에서 관리한다. 서비스 Theme는 같은 계약의 부분 컬러 override다.
## 단일 Default 원본과 package fallback
@@ -0,0 +1,72 @@
# Brown·Orange 공통 Background Gradient 및 Gitea 작성자 정합성 — 2026-10-11
RESULT: PARTIAL. 승인된 두 Gradient의 구현·빌드·브라우저 검증은 PASS다. Guard의 패키지 범위 및 동적 스타일 NOT VERIFIED는 보존한다. Git Commit/Push 결과와 최종 SHA는 작업 최종 응답에서 기록한다.
## 기준과 범위
- 공식 경로 `D:\디자인시스템\HMDesign-Gitea-Transfer`, `main`, origin `https://gitea.hmac.kr/b25027/HMDesign.git`.
- 시작 Local/Remote HEAD `220973cf89d3f9ae66cb96dab6a66b7859026849`, Working Tree 깨끗함. 시작 시각 2026-10-11 13:19:32 KST, 최초 예상 30~45분.
- 범위: Theme 공개 Stop 입력 + 기존 Foundation Color Story. Runtime: React / Public Runtime Theme v1. 새 업무 화면·Navigation·Control은 없다. Pattern 선택과 키보드/focus/Label 동작 검증은 해당 없음.
- 이전 [Foundation Color 기록](foundation-color-storybook-2026-10-11.md)과 [Generic Status Error 기록](generic-status-error-token-2026-10-11.md)은 당시 상태를 기록한 이력으로 보존한다.
## Gradient와 공개 계약
| Stop | Palette 단계 | Brown | Orange |
|---|---|---|---|
| 0% | Dark 1 | #352D1D | #BC4C00 |
| 12% | Dark 2 | #2F281C | #883700 |
| 42% | Default | #3E3523 | #CC5200 |
| 78% | Light 2 | #897445 | #F87725 |
| 100% | Light 1 | #604F32 | #EB5F00 |
- 방향: 두 Background 모두 `to bottom`, Green과 동일한 5-stop 위치.
- Brown 입력 `color.bg.brown.stop.{0|12|42|78|100}` → `--hm-sem-brown-bg-stop-*` → Derived `--hm-sem-bg-brown`.
- Orange 입력 `color.bg.orange.stop.{0|12|42|78|100}` → `--hm-sem-orange-bg-stop-*` → Derived `--hm-sem-bg-orange`.
- [확정 Palette](../guidelines/brand-color-steps.md)와 모든 HEX가 일치한다. CSS-only 기본값은 대응 Semantic Palette를 참조하며 명시적 Runtime Stop 값이 우선한다. 새 HEX나 전체 Gradient 문자열 입력은 추가하지 않았다.
- 각 브랜드의 5개 Stop은 그룹 전체 또는 미지정만 허용한다. 특정 Stop만 바꾸려면 나머지 네 값도 함께 전달한다. 기존 Green·Primary 면·Primary border의 그룹과 순서를 보존하고 독립 그룹 두 개를 추가했다.
- [공개 계약](../../packages/ui/src/theme/contract.ts), [Default JSON](../../themes/default.json), [CSS Template](../../scripts/theme-templates/default.css)에서 기존 스크립트로 CSS와 TypeScript 기본값을 생성했다. 94개 Runtime 입력 / 92개 Default 컬러 / 기존 radius 2개. [Runtime 계약 문서](../guidelines/runtime-theme-contract.md).
- [Foundation Color](../../src/foundation/color.stories.tsx)의 `foundation-color--all` ID를 유지한다. 실제 공통 Background와 기존 Button 전용 미리보기, Stop 위치·HEX·Token·CSS Variable 및 요소의 computed `background-image`를 표시한다. 새 Stop 카드에만 폭을 보강하여 네 검증 폭에서 Token/변수가 한 줄로 식별된다.
브라우저의 실제 `background-image`는 다음과 같다. 브라우저는 기본 방향 `to bottom`을 직렬화에서 생략하며 방향은 CSS Variable에서도 확인했다.
```css
/* Brown */
linear-gradient(rgb(53, 45, 29) 0%, rgb(47, 40, 28) 12%, rgb(62, 53, 35) 42%, rgb(137, 116, 69) 78%, rgb(96, 79, 50) 100%)
/* Orange */
linear-gradient(rgb(188, 76, 0) 0%, rgb(136, 55, 0) 12%, rgb(204, 82, 0) 42%, rgb(248, 119, 37) 78%, rgb(235, 95, 0) 100%)
```
## 보존과 검증
- 기존 JSON 컬러 82개, Default CSS 선언 141개, UI 소스 123개 보존. 기존 전체 JSON과 service partial JSON 유효성 PASS. 기존 Storybook ID 292개 보존. Foundation Color와 해당 신규 카드용 CSS 외 앱·Story·Storybook 설정 변경 없음.
- 이전 정적 Storybook 빌드와 비교해 기존 HM 계산 변수 1,153개의 값 변화 0. Green Background, Brown/Orange Button, Dashboard Header/Compact 배경·Component API·3종 Palette × 8단계·Generic Status Error `#B3261E`·Destructive `#D32F2F`·Disabled Input Label 60% 보존.
- `npm run generate:theme-defaults`, `npm run build:themes` PASS. 생성 stale 검사, root/UI/CENTER typecheck, UI/CENTER package build PASS. 마지막 Story/CSS 변경 후 root typecheck와 Storybook build만 다시 확인했다.
- 최종 Storybook static build PASS. 기존 큰 chunk 및 bundler callback 성능 경고는 코드 오류가 아니다. 기존 전체 Component 테스트는 반복하지 않았다.
- 브라우저 Foundation Color 실제 React 렌더 PASS. Brown/Orange Stop 순서·HEX·Palette·Canonical/CSS 변수·Swatch·표시 computed 값과 실제 요소 값 일치 PASS. 기존 Green 및 Button 전용 미리보기 유지.
- Runtime: 완전 그룹 적용, 단일 Stop/invalid 값 거부, Brown/Orange 독립성, Theme 전환, invalid fallback, Scoped 적용, Global 불변, 기존 host inline 값/priority 복원, Palette alias 변경, Reset PASS.
- 390 / 768 / 1280 / 1440px에서 문서 및 Gradient panel 가로 overflow 0, 새 Stop ID 줄바꿈 0. 각 문서/panel의 scrollWidth/clientWidth 및 scrollHeight/clientHeight 측정 보관. Foundation은 정상 문서 세로 스크롤이며 신규 숨김 알림·Navigation 없음. 브라우저 console/page error 0.
- Git diff whitespace 검사 PASS. MD 링크 검사 결과는 최종 응답에 기록한다. 실제 스크린리더·실기기 검증 NOT VERIFIED.
## Guard 원본과 실행 증거
변경 범위 STORYBOOK / PARTIAL Guard를 실행했다. 이후 브라우저에서 발견한 Stop ID 줄바꿈을 수정하면서 Story/CSS 소스 해시가 변경되어 최종 상태에 대해 다시 검사했다. 정상 Component 검사 반복이나 Guard 규칙 완화는 하지 않았다.
```sh
node scripts/ai-generation-guard.mjs --target . --profile STORYBOOK --scope PARTIAL --files src/foundation/color.stories.tsx,src/foundation/foundation.css,packages/ui/src/theme/contract.ts,packages/ui/src/theme/default.css,packages/ui/src/theme/default-values.generated.ts,scripts/theme-templates/default.css,themes/default.json --json
```
원본 status / staticStatus: NOT VERIFIED, FAIL 0. CSS styleEvidence: STATIC PASS / RUNTIME NOT VERIFIED / DESIGN_INTENT PASS / FINAL NOT VERIFIED. 원본에 Runtime 증거가 자동 결합되지 않았으므로 결합 styleVerification은 NOT VERIFIED다.
SCOPE-001은 package 계약·생성값·Template이 증명된 소비 Storybook graph 밖이라는 경계이며 별도 package build/API/브라우저 검사로 확인했다. TOKEN-002는 동적 style/property/template 및 StoryPage className의 정적 해석 한계다. 새 Gradient·Stop의 실제 위치·색상·계산값은 별도 실행 증거로 확인했으며 다른 미실행 동적 위치까지 PASS로 확장하지 않았다. 사용자 승인 범위는 두 독립 Background와 Foundation 표시다. 원본 Guard를 덮어쓰지 않았다.
로컬 실행 원본·JSON·스크린샷은 `_local/background-gradients-20261011/` 및 관련 `_local/background-*.log`에 보관한다. 이 디렉터리는 Git 배포 범위 밖이며 Clone 후 확인할 계약과 검증 요약은 이 문서에 남긴다.
## Git Identity와 인증
- 기존 전역 `user.name`과 이전 Commit의 Author/Committer는 Windows PC 이름을 포함했다. 기존 이메일은 PC 호스트명으로 구성된 주소는 아니지만 공식 Gitea 기본 이메일과 달랐다. 기존 이력과 전역 설정을 보존했다.
- 기존 Credential Manager의 HTTPS credential로 공식 Gitea `/api/v1/user` 및 `/api/v1/user/emails`를 조회했다. 인증 계정 `b25027`, 실제 프로필 이름 `김수현`, 기본 이메일 `shkim4@samaneng.com`의 primary/verified 상태를 확인했다. 인증된 Push 사용자와 Commit 작성자는 별도로 확인한다.
- `/api/v1/user/settings`의 `hide_email=false` 확인. 이메일 숨김 옵션은 존재하지만 현재 활성화되지 않았다. 서버의 정확한 noreply 주소는 확인하지 않았으며 임의 생성하지 않았다. 현재 확인된 공개 기본 이메일을 사용한다. Git Commit의 Author/Committer 이메일은 저장소 이력에 기록된다.
- 현재 저장소 `.git/config`에만 `user.name=김수현`, `user.email=shkim4@samaneng.com` 적용. `git var GIT_AUTHOR_IDENT`와 `GIT_COMMITTER_IDENT`도 이 값으로 해석됨을 확인했다.
- 작업 프로세스의 Author/Committer 및 Git config 환경 Override는 없었다. 별도 core.hooksPath/사용자 정의 Git hook도 없었다. 현재 생성하는 Commit의 실제 메타데이터를 Commit 후 다시 확인한다.
- 원격 URL·기존 Credential Manager·인증 방식·전역 config를 변경하지 않았고 재로그인·Token 재발급·GitHub Push·이력 재작성도 하지 않았다. 인증 비밀값은 출력·파일 저장하지 않았다.
- 관련 12개 파일만 Stage, Staged Diff 검토 후 요청된 `feat(theme): add brown and orange background gradients`로 일반 Commit/Push한다. Commit/Push 직전 원격 main이 시작 SHA에서 변경되면 중단한다. 신규 Commit의 Gitea 계정 attribution 및 Local/Remote SHA·Working Tree는 최종 응답에서 기록한다.
+24
View File
@@ -20,6 +20,16 @@ export const runtimeThemeContract = {
"color.bg.brand.stop.42": { property: "--hm-sem-brand-bg-stop-42", defaultValue: runtimeThemeDefaults["--hm-sem-brand-bg-stop-42"], type: "color" },
"color.bg.brand.stop.78": { property: "--hm-sem-brand-bg-stop-78", defaultValue: runtimeThemeDefaults["--hm-sem-brand-bg-stop-78"], type: "color" },
"color.bg.brand.stop.100": { property: "--hm-sem-brand-bg-stop-100", defaultValue: runtimeThemeDefaults["--hm-sem-brand-bg-stop-100"], type: "color" },
"color.bg.brown.stop.0": { property: "--hm-sem-brown-bg-stop-0", defaultValue: runtimeThemeDefaults["--hm-sem-brown-bg-stop-0"], type: "color" },
"color.bg.brown.stop.12": { property: "--hm-sem-brown-bg-stop-12", defaultValue: runtimeThemeDefaults["--hm-sem-brown-bg-stop-12"], type: "color" },
"color.bg.brown.stop.42": { property: "--hm-sem-brown-bg-stop-42", defaultValue: runtimeThemeDefaults["--hm-sem-brown-bg-stop-42"], type: "color" },
"color.bg.brown.stop.78": { property: "--hm-sem-brown-bg-stop-78", defaultValue: runtimeThemeDefaults["--hm-sem-brown-bg-stop-78"], type: "color" },
"color.bg.brown.stop.100": { property: "--hm-sem-brown-bg-stop-100", defaultValue: runtimeThemeDefaults["--hm-sem-brown-bg-stop-100"], type: "color" },
"color.bg.orange.stop.0": { property: "--hm-sem-orange-bg-stop-0", defaultValue: runtimeThemeDefaults["--hm-sem-orange-bg-stop-0"], type: "color" },
"color.bg.orange.stop.12": { property: "--hm-sem-orange-bg-stop-12", defaultValue: runtimeThemeDefaults["--hm-sem-orange-bg-stop-12"], type: "color" },
"color.bg.orange.stop.42": { property: "--hm-sem-orange-bg-stop-42", defaultValue: runtimeThemeDefaults["--hm-sem-orange-bg-stop-42"], type: "color" },
"color.bg.orange.stop.78": { property: "--hm-sem-orange-bg-stop-78", defaultValue: runtimeThemeDefaults["--hm-sem-orange-bg-stop-78"], type: "color" },
"color.bg.orange.stop.100": { property: "--hm-sem-orange-bg-stop-100", defaultValue: runtimeThemeDefaults["--hm-sem-orange-bg-stop-100"], type: "color" },
"surface.action.primary.stop.0": { property: "--hm-sem-action-surface-stop-0", defaultValue: runtimeThemeDefaults["--hm-sem-action-surface-stop-0"], type: "color" },
"surface.action.primary.stop.30": { property: "--hm-sem-action-surface-stop-30", defaultValue: runtimeThemeDefaults["--hm-sem-action-surface-stop-30"], type: "color" },
"surface.action.primary.stop.65": { property: "--hm-sem-action-surface-stop-65", defaultValue: runtimeThemeDefaults["--hm-sem-action-surface-stop-65"], type: "color" },
@@ -115,5 +125,19 @@ export const runtimeGradientGroups = [
"surface.action.primary.border.stop.0",
"surface.action.primary.border.stop.50",
"surface.action.primary.border.stop.100"
],
[
"color.bg.brown.stop.0",
"color.bg.brown.stop.12",
"color.bg.brown.stop.42",
"color.bg.brown.stop.78",
"color.bg.brown.stop.100"
],
[
"color.bg.orange.stop.0",
"color.bg.orange.stop.12",
"color.bg.orange.stop.42",
"color.bg.orange.stop.78",
"color.bg.orange.stop.100"
]
] as const
@@ -18,6 +18,16 @@ export const runtimeThemeDefaults = {
"--hm-sem-brand-bg-stop-42": "#123328",
"--hm-sem-brand-bg-stop-78": "#266651",
"--hm-sem-brand-bg-stop-100": "#205241",
"--hm-sem-brown-bg-stop-0": "#352d1d",
"--hm-sem-brown-bg-stop-12": "#2f281c",
"--hm-sem-brown-bg-stop-42": "#3e3523",
"--hm-sem-brown-bg-stop-78": "#897445",
"--hm-sem-brown-bg-stop-100": "#604f32",
"--hm-sem-orange-bg-stop-0": "#bc4c00",
"--hm-sem-orange-bg-stop-12": "#883700",
"--hm-sem-orange-bg-stop-42": "#cc5200",
"--hm-sem-orange-bg-stop-78": "#f87725",
"--hm-sem-orange-bg-stop-100": "#eb5f00",
"--hm-sem-action-surface-stop-0": "#1f8265",
"--hm-sem-action-surface-stop-30": "#165c47",
"--hm-sem-action-surface-stop-65": "#114838",
+20
View File
@@ -62,6 +62,26 @@
var(--hm-sem-brand-bg-stop-42) 42%, var(--hm-sem-brand-bg-stop-78) 78%,
var(--hm-sem-brand-bg-stop-100) 100%);
/* Independent common backgrounds; Button and Dashboard mappings stay unchanged. */
--hm-sem-brown-bg-stop-0: var(--hm-sem-palette-brown-dark-1);
--hm-sem-brown-bg-stop-12: var(--hm-sem-palette-brown-dark-2);
--hm-sem-brown-bg-stop-42: var(--hm-sem-palette-brown-default);
--hm-sem-brown-bg-stop-78: var(--hm-sem-palette-brown-light-2);
--hm-sem-brown-bg-stop-100: var(--hm-sem-palette-brown-light-1);
--hm-sem-bg-brown: linear-gradient(to bottom,
var(--hm-sem-brown-bg-stop-0) 0%, var(--hm-sem-brown-bg-stop-12) 12%,
var(--hm-sem-brown-bg-stop-42) 42%, var(--hm-sem-brown-bg-stop-78) 78%,
var(--hm-sem-brown-bg-stop-100) 100%);
--hm-sem-orange-bg-stop-0: var(--hm-sem-palette-orange-dark-1);
--hm-sem-orange-bg-stop-12: var(--hm-sem-palette-orange-dark-2);
--hm-sem-orange-bg-stop-42: var(--hm-sem-palette-orange-default);
--hm-sem-orange-bg-stop-78: var(--hm-sem-palette-orange-light-2);
--hm-sem-orange-bg-stop-100: var(--hm-sem-palette-orange-light-1);
--hm-sem-bg-orange: linear-gradient(to bottom,
var(--hm-sem-orange-bg-stop-0) 0%, var(--hm-sem-orange-bg-stop-12) 12%,
var(--hm-sem-orange-bg-stop-42) 42%, var(--hm-sem-orange-bg-stop-78) 78%,
var(--hm-sem-orange-bg-stop-100) 100%);
--hm-sem-action-surface-stop-0: var(--hm-sem-palette-green-tone-1);
--hm-sem-action-surface-stop-30: var(--hm-sem-palette-green-tone-2);
--hm-sem-action-surface-stop-65: var(--hm-sem-palette-green-tone-3);
+20
View File
@@ -61,6 +61,26 @@
var(--hm-sem-brand-bg-stop-42) 42%, var(--hm-sem-brand-bg-stop-78) 78%,
var(--hm-sem-brand-bg-stop-100) 100%);
/* Independent common backgrounds; Button and Dashboard mappings stay unchanged. */
--hm-sem-brown-bg-stop-0: {{color.bg.brown.stop.0|var(--hm-sem-palette-brown-dark-1)}};
--hm-sem-brown-bg-stop-12: {{color.bg.brown.stop.12|var(--hm-sem-palette-brown-dark-2)}};
--hm-sem-brown-bg-stop-42: {{color.bg.brown.stop.42|var(--hm-sem-palette-brown-default)}};
--hm-sem-brown-bg-stop-78: {{color.bg.brown.stop.78|var(--hm-sem-palette-brown-light-2)}};
--hm-sem-brown-bg-stop-100: {{color.bg.brown.stop.100|var(--hm-sem-palette-brown-light-1)}};
--hm-sem-bg-brown: linear-gradient(to bottom,
var(--hm-sem-brown-bg-stop-0) 0%, var(--hm-sem-brown-bg-stop-12) 12%,
var(--hm-sem-brown-bg-stop-42) 42%, var(--hm-sem-brown-bg-stop-78) 78%,
var(--hm-sem-brown-bg-stop-100) 100%);
--hm-sem-orange-bg-stop-0: {{color.bg.orange.stop.0|var(--hm-sem-palette-orange-dark-1)}};
--hm-sem-orange-bg-stop-12: {{color.bg.orange.stop.12|var(--hm-sem-palette-orange-dark-2)}};
--hm-sem-orange-bg-stop-42: {{color.bg.orange.stop.42|var(--hm-sem-palette-orange-default)}};
--hm-sem-orange-bg-stop-78: {{color.bg.orange.stop.78|var(--hm-sem-palette-orange-light-2)}};
--hm-sem-orange-bg-stop-100: {{color.bg.orange.stop.100|var(--hm-sem-palette-orange-light-1)}};
--hm-sem-bg-orange: linear-gradient(to bottom,
var(--hm-sem-orange-bg-stop-0) 0%, var(--hm-sem-orange-bg-stop-12) 12%,
var(--hm-sem-orange-bg-stop-42) 42%, var(--hm-sem-orange-bg-stop-78) 78%,
var(--hm-sem-orange-bg-stop-100) 100%);
--hm-sem-action-surface-stop-0: {{surface.action.primary.stop.0|var(--hm-sem-palette-green-tone-1)}};
--hm-sem-action-surface-stop-30: {{surface.action.primary.stop.30|var(--hm-sem-palette-green-tone-2)}};
--hm-sem-action-surface-stop-65: {{surface.action.primary.stop.65|var(--hm-sem-palette-green-tone-3)}};
+22 -12
View File
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react-vite"
import { useEffect, useRef, useState } from "react"
import { runtimeThemeContract, type RuntimeThemeToken } from "@hm-design/ui/theme"
import { ReferencePage, ReferenceSection, useResolvedProperties } from "./reference"
@@ -32,9 +33,9 @@ const semanticGroups = [
] satisfies { name: string; colors: ColorReference[] }[]
type ColorReference = { name: string; token?: RuntimeThemeToken; property?: string; status: string; note: string; legacy?: string; foreground?: boolean }
const gradients = [
{ name: "HM Green Background", property: "--hm-sem-bg-brand", legacy: "gradient.green.background", note: "현행 공통 브랜드 배경 · Confirmed. 공개 stop 계약은 color.bg.brand.stop.*이며 방향·위치는 현행 CSS에서 읽습니다. Dashboard의 Header / Compact 배경은 별도 정의입니다." },
{ name: "HM Brown Background", legacy: "gradient.brown.background", note: "공통 Brown Background Token / CSS 변수 미정의. 참고 자료의 5-stop 배경을 재구성하지 않습니다.", componentProperty: "--hm-button-brand-brown-background" },
{ name: "Orange Background", legacy: "gradient.orange.background", note: "공통 Orange Background Token / CSS 변수 미정의. 참고 자료의 5-stop 배경을 재구성하지 않습니다.", componentProperty: "--hm-button-brand-orange-background" },
{ name: "HM Green Background", property: "--hm-sem-bg-brand", stopPrefix: undefined, legacy: "gradient.green.background", note: "현행 공통 브랜드 배경 · Confirmed. 공개 stop 계약은 color.bg.brand.stop.*이며 방향·위치는 현행 CSS에서 읽습니다. Dashboard의 Header / Compact 배경은 별도 정의입니다." },
{ name: "HM Brown Background", property: "--hm-sem-bg-brown", stopPrefix: "color.bg.brown.stop", legacy: "gradient.brown.background", note: "공통 Brown Background · Confirmed. 확정 Brown Palette를 참조하는 독립 5-stop 배경입니다. Runtime JSON은 5개 stop 전체를 지정하며 Button·Dashboard와 별도 역할입니다.", componentProperty: "--hm-button-brand-brown-background" },
{ name: "Orange Background", property: "--hm-sem-bg-orange", stopPrefix: "color.bg.orange.stop", legacy: "gradient.orange.background", note: "공통 Orange Background · Confirmed. 확정 Orange Palette를 참조하는 독립 5-stop 배경입니다. Runtime JSON은 5개 stop 전체를 지정하며 Button·Dashboard와 별도 역할입니다.", componentProperty: "--hm-button-brand-orange-background" },
]
const colorProperties = [...new Set([
...Object.values(runtimeThemeContract).filter(definition => definition.type === "color").map(definition => definition.property),
@@ -92,15 +93,25 @@ function SemanticColor({ item, values }: { item: ColorReference; values: Record<
</dl>
</article>
}
function GradientPreview({ name, property, values }: { name: string; property: string; values: Record<string, string> }) {
function GradientPreview({ name, property, stopPrefix, values }: { name: string; property: string; stopPrefix?: string; values: Record<string, string> }) {
const preview = useRef<HTMLDivElement>(null)
const [backgroundImage, setBackgroundImage] = useState<string>()
useEffect(() => {
if (preview.current) setBackgroundImage(getComputedStyle(preview.current).backgroundImage)
}, [property, values])
const value = values[property]
const parts = gradientParts(value)
return <>
<div className="hm-foundation-swatch hm-color-gradient-preview" data-gradient-property={property} style={{ backgroundImage: `var(${property})` }} aria-label={`${name} Gradient 미리보기`} />
<dl><dt>현재 CSS Variable</dt><dd><code>{property}</code></dd><dt>현재 Theme 적용 결과 · Computed CSS</dt><dd><code data-gradient-value>{value ?? "확인 중"}</code></dd><dt>방향</dt><dd>{parts?.direction ?? "NOT VERIFIED"}</dd></dl>
{parts ? <div className="hm-color-gradient-stops">{parts.stops.map((stop, index) => <article className="hm-brand-color-chip" key={index} data-gradient-stop={stop.position}>
<div className="hm-foundation-swatch" style={{ background: stop.color }} /><h3>{stop.position}</h3><p data-stop-value>{colorHex(stop.color)}</p>
</article>)}</div> : <p>{value === undefined ? "Stop 확인 중" : "Stop 미정의 또는 해석 불가 · NOT VERIFIED"}</p>}
<div ref={preview} className="hm-foundation-swatch hm-color-gradient-preview" data-gradient-property={property} style={{ backgroundImage: `var(${property})` }} aria-label={`${name} Gradient 미리보기`} />
<dl><dt>현재 CSS Variable · Derived Gradient</dt><dd><code>{property}</code></dd><dt>현재 Theme 적용 결과 · Computed CSS Variable</dt><dd><code data-gradient-value>{value ?? "확인 중"}</code></dd><dt>실제 Computed background-image</dt><dd><code data-gradient-background-image>{backgroundImage ?? "확인 중"}</code></dd><dt>방향</dt><dd>{parts?.direction ?? "NOT VERIFIED"}</dd></dl>
{parts ? <div className="hm-color-gradient-stops">{parts.stops.map((stop, index) => {
const token = stopPrefix ? `${stopPrefix}.${stop.position.replace("%", "")}` as RuntimeThemeToken : undefined
const definition = token ? runtimeThemeContract[token] : undefined
return <article className="hm-brand-color-chip" key={index} data-gradient-stop={stop.position} data-gradient-stop-token={token}>
<div className="hm-foundation-swatch" style={{ background: stop.color }} /><h3>{stop.position}</h3><p data-stop-value>{colorHex(stop.color)}</p>
{definition && <dl><dt>Canonical Token</dt><dd><code>{token}</code></dd><dt>CSS Variable</dt><dd><code>{definition.property}</code></dd></dl>}
</article>
})}</div> : <p>{value === undefined ? "Stop 확인 중" : "Stop 미정의 또는 해석 불가 · NOT VERIFIED"}</p>}
</>
}
function ColorReferencePage() {
@@ -122,9 +133,8 @@ function ColorReferencePage() {
<ReferenceSection title="Gradients" note="실제 CSS Gradient를 가로형 카드에서 비교합니다. Stop과 방향은 현재 선언의 적용값에서 읽습니다. 공통 배경과 Button 전용 배경은 별도 역할입니다.">
<div className="hm-foundation-specimens">{gradients.map(gradient => <article className="hm-foundation-panel" key={gradient.name}>
<h3>{gradient.name}</h3><p className="hm-foundation-note">{gradient.note}</p><p>기존 참고 명칭: <code>{gradient.legacy}</code></p>
{gradient.property ? <GradientPreview name={gradient.name} property={gradient.property} values={values} /> : <><p>공통 Background: 미정의 · Canonical Token / CSS Variable 없음</p>
{gradient.componentProperty && <div className="hm-foundation-specimen"><h3>기존 Button 전용 Background · Confirmed</h3><p>현행 Component CSS만 표시합니다. 공통 5-stop 배경의 대체 또는 확정이 아닙니다. 전체 Gradient canonical은 없으며 stop 색상은 공개 Palette를 소비합니다.</p><GradientPreview name={`${gradient.name} Button`} property={gradient.componentProperty} values={values} /></div>}
</>}
<GradientPreview name={gradient.name} property={gradient.property} stopPrefix={gradient.stopPrefix} values={values} />
{gradient.componentProperty && <div className="hm-foundation-specimen"><h3>기존 Button 전용 Background · Confirmed</h3><p>현행 Component CSS만 표시합니다. 공통 5-stop 배경과 독립적으로 유지합니다. 전체 Gradient canonical은 없으며 stop 색상은 공개 Palette를 소비합니다.</p><GradientPreview name={`${gradient.name} Button`} property={gradient.componentProperty} values={values} /></div>}
</article>)}</div>
</ReferenceSection>
</ReferencePage>
+2
View File
@@ -35,4 +35,6 @@
.hm-foundation .hm-color-gradient-preview { height: 112px; }
.hm-foundation .hm-color-gradient-stops { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.hm-foundation .hm-color-gradient-stops .hm-brand-color-chip { flex: 1 1 110px; }
/* New common background stop IDs stay on one line at the supported widths. */
.hm-foundation .hm-color-gradient-stops .hm-brand-color-chip[data-gradient-stop-token] { flex-basis: 220px; }
.hm-foundation .hm-color-foreground-sample { padding: 16px; background: var(--hm-sem-bg-surface); }
+10
View File
@@ -18,6 +18,16 @@
"color.bg.brand.stop.42": "#123328",
"color.bg.brand.stop.78": "#266651",
"color.bg.brand.stop.100": "#205241",
"color.bg.brown.stop.0": "#352d1d",
"color.bg.brown.stop.12": "#2f281c",
"color.bg.brown.stop.42": "#3e3523",
"color.bg.brown.stop.78": "#897445",
"color.bg.brown.stop.100": "#604f32",
"color.bg.orange.stop.0": "#bc4c00",
"color.bg.orange.stop.12": "#883700",
"color.bg.orange.stop.42": "#cc5200",
"color.bg.orange.stop.78": "#f87725",
"color.bg.orange.stop.100": "#eb5f00",
"surface.action.primary.stop.0": "#1f8265",
"surface.action.primary.stop.30": "#165c47",
"surface.action.primary.stop.65": "#114838",