# Public Runtime Theme Contract 계약 Source of Truth: `packages/ui/src/theme/contract.ts`. 모든 입력은 선택적이며 외부 override 가능. Component/derived 변수는 공개 입력이 아니다. | Runtime JSON Token | CSS Token | Default | 의미 | 외부 override | 주요 영향 | |---|---|---|---|---|---| | `color.bg.content` | `--hm-sem-bg-content` | `#f5f0e5` | 콘텐츠 면 | Yes | gnb, lnb | | `color.bg.surface` | `--hm-sem-bg-surface` | `#ffffff` | 기본/카드/입력 면 | Yes | checkbox, radio, switch, slider, badge, table, input, select, button, gnb | | `color.fg.primary` | `--hm-sem-fg-primary` | `#0a221d` | 주요 텍스트 | Yes | calendar, pagination, badge, table, input, select, gnb | | `color.fg.secondary` | `--hm-sem-fg-secondary` | `#6e6759` | 보조 텍스트 | Yes | calendar, pagination, badge, table, gnb | | `color.fg.placeholder` | `--hm-sem-fg-placeholder` | `#999999` | Placeholder | Yes | input, select | | `color.action.primary` | `--hm-sem-action-primary` | `#123328` | Strong / Primary ink | Yes | checkbox/radio hover, slider Hover/Drag halo, pagination current, badge default, button outline, navigation current ink | | `color.action.cancel` | `--hm-sem-action-cancel` | `#6e6759` | 공개 취소 역할 | Yes | Button `variant="cancel"` + `appearance="outline"` | | `color.action.destructive` | `--hm-sem-action-destructive` | `#d32f2f` | 오류/위험 역할 | Yes | checkbox, radio, badge, input, button | | `color.status.error` | `--hm-sem-status-error` | `#b3261e` | Generic Status Error · 일반 상태 오류 · Provisional | Yes | Foundation Color / 선택적 Theme 입력; 기존 Component 자동 연결 없음 | | `color.stroke.default` | `--hm-sem-stroke-default` | `#9a9284` | 기본 border | Yes | checkbox, radio, switch, badge | | `color.stroke.input.default` | `--hm-sem-stroke-input-default` | `#dedbd2` | 입력/패널 divider border | Yes | table, input, select, GNB 콘텐츠 LNB divider | | `color.stroke.input.focus` | `--hm-sem-stroke-input-focus` | `#266651` | 공통 Focus border/ring | Yes | input, select, button, checkbox, calendar, slider Keyboard Focus halo 등; GNB/LNB는 contextual 예외 | | `color.bg.brand.stop.0` | `--hm-sem-brand-bg-stop-0` | `#0a221d` | 기존 gradient stop: color.bg.brand.stop.0 | Yes | Theme palette / adapter | | `color.bg.brand.stop.12` | `--hm-sem-brand-bg-stop-12` | `#071e18` | 기존 gradient stop: color.bg.brand.stop.12 | Yes | Theme palette / adapter | | `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 | | `surface.action.primary.stop.100` | `--hm-sem-action-surface-stop-100` | `#08241c` | 기존 gradient stop: surface.action.primary.stop.100 | Yes | button, gnb | | `surface.action.primary.border.stop.0` | `--hm-sem-action-border-stop-0` | `#0a221d` | 기존 gradient stop: surface.action.primary.border.stop.0 | Yes | button | | `surface.action.primary.border.stop.50` | `--hm-sem-action-border-stop-50` | `#34daaa` | 기존 gradient stop: surface.action.primary.border.stop.50 | Yes | button | | `surface.action.primary.border.stop.100` | `--hm-sem-action-border-stop-100` | `#08241c` | 기존 gradient stop: surface.action.primary.border.stop.100 | Yes | button | | `radius.input.default` | `--hm-radius-input` | `4px` | Input/Select radius | Yes | input, select | | `radius.container.default` | `--hm-radius-container` | `4px` | Container radius | Yes | Theme palette / adapter | | `color.state.active` | `--hm-sem-state-active` | `#266651` | Checked / Selected / ON fill | Yes | checkbox, radio, switch, slider, progress, calendar | | `color.on.state.active` | `--hm-sem-on-state-active` | `#ffffff` | Active 위 텍스트/indicator | Yes | checkbox, calendar | | `color.fg.inverse` | `--hm-sem-on-action-primary` | `#ffffff` | 반전 텍스트 | Yes | pagination, badge, button, gnb, lnb | | `color.bg.subtle` | `--hm-sem-bg-subtle` | `#f4f1ea` | 은은한 면 | Yes | calendar, badge, table | | `color.accent` | `--hm-sem-accent` | `#bddfd4` | Soft Highlight 45%, Table 행 20% / Selected·Open surface 100% 원색 | Yes | select, combobox, menu item, table, calendar, pagination hover / toggle, menubar, navigation-menu trigger | | `color.on.accent` | `--hm-sem-on-accent` | `#123328` | Accent 위 텍스트; Primary와 독립 sibling | Yes | select, combobox, menu item, calendar, pagination hover, toggle, menubar, navigation-menu | | `color.palette.green-light-4` | `--hm-sem-palette-green-light-4` | `#34daaa` | 선택적 Theme 팔레트: green-light-4 | Yes | button | | `color.palette.green-light-3` | `--hm-sem-palette-green-light-3` | `#249473` | 선택적 Theme 팔레트: green-light-3 | Yes | data-table Sort Direction Accent, tabs 장식, lnb gradient | | `color.palette.green-light-2` | `--hm-sem-palette-green-light-2` | `#266651` | 선택적 Theme 팔레트: green-light-2 | Yes | checkbox, radio, switch, slider, progress, calendar, table, input, select, gnb, lnb | | `color.palette.green-light-1` | `--hm-sem-palette-green-light-1` | `#205241` | 선택적 Theme 팔레트: green-light-1 | Yes | table, button, lnb | | `color.palette.green-default` | `--hm-sem-palette-green-default` | `#123328` | 선택적 Theme 팔레트: green-default | Yes | checkbox, radio, slider, calendar, pagination, badge, select, button, gnb, lnb | | `color.palette.green-dark-1` | `--hm-sem-palette-green-dark-1` | `#0a221d` | 선택적 Theme 팔레트: green-dark-1 | Yes | calendar, pagination, badge, table, input, select, button, gnb | | `color.palette.green-dark-2` | `--hm-sem-palette-green-dark-2` | `#071e18` | 선택적 Theme 팔레트: green-dark-2 | Yes | Theme palette / adapter | | `color.palette.brown-light-2` | `--hm-sem-palette-brown-light-2` | `#897445` | 선택적 Theme 팔레트: brown-light-2 | Yes | button | | `color.palette.brown-light-1` | `--hm-sem-palette-brown-light-1` | `#604f32` | 선택적 Theme 팔레트: brown-light-1 | Yes | button | | `color.palette.brown-default` | `--hm-sem-palette-brown-default` | `#3e3523` | 선택적 Theme 팔레트: brown-default | Yes | button | | `color.palette.brown-dark-1` | `--hm-sem-palette-brown-dark-1` | `#352d1d` | 선택적 Theme 팔레트: brown-dark-1 | Yes | button | | `color.palette.brown-light-4` | `--hm-sem-palette-brown-light-4` | `#ecd4a2` | 선택적 Theme 팔레트: brown-light-4 | Yes | Theme palette / adapter | | `color.palette.orange-light-4` | `--hm-sem-palette-orange-light-4` | `#feba88` | 선택적 Theme 팔레트: orange-light-4 | Yes | button | | `color.palette.orange-default` | `--hm-sem-palette-orange-default` | `#cc5200` | 선택적 Theme 팔레트: orange-default | Yes | button | | `color.palette.warm-neutral-light` | `--hm-sem-palette-warm-neutral-light` | `#e0dace` | 선택적 Theme 팔레트: warm-neutral-light | Yes | slider, progress | | `color.palette.warm-neutral-mid` | `--hm-sem-palette-warm-neutral-mid` | `#9a9284` | 선택적 Theme 팔레트: warm-neutral-mid | Yes | checkbox, radio, switch, badge | | `color.palette.warm-neutral-dark` | `--hm-sem-palette-warm-neutral-dark` | `#6e6759` | 선택적 Theme 팔레트: warm-neutral-dark | Yes | calendar, pagination, badge, table, gnb | | `color.palette.beige-light` | `--hm-sem-palette-beige-light` | `#f5f0e5` | 선택적 Theme 팔레트: beige-light | Yes | gnb, lnb | | `color.palette.red-danger` | `--hm-sem-palette-red-danger` | `#d32f2f` | 선택적 Theme 팔레트: red-danger | Yes | checkbox, radio, badge, input, button | | `color.palette.white` | `--hm-sem-palette-white` | `#ffffff` | 선택적 Theme 팔레트: white | Yes | checkbox, radio, switch, slider, calendar, pagination, badge, table, input, select, button, gnb, lnb | | `color.palette.black` | `--hm-sem-palette-black` | `#000000` | 선택적 Theme 팔레트: black | Yes | checkbox, switch, select, button, gnb, lnb | | `color.palette.neutral-gray-500` | `--hm-sem-palette-neutral-gray-500` | `#999999` | 선택적 Theme 팔레트: neutral-gray-500 | Yes | input, select | | `color.palette.green-tone-1` | `--hm-sem-palette-green-tone-1` | `#1f8265` | 선택적 Theme 팔레트: green-tone-1 | Yes | button, gnb | | `color.palette.green-tone-2` | `--hm-sem-palette-green-tone-2` | `#165c47` | 선택적 Theme 팔레트: green-tone-2 | Yes | button, gnb | | `color.palette.green-tone-3` | `--hm-sem-palette-green-tone-3` | `#114838` | 선택적 Theme 팔레트: green-tone-3 | Yes | button, gnb | | `color.palette.green-tone-4` | `--hm-sem-palette-green-tone-4` | `#08241c` | 선택적 Theme 팔레트: green-tone-4 | Yes | button, gnb | | `color.palette.warm-neutral-pale` | `--hm-sem-palette-warm-neutral-pale` | `#dedbd2` | 선택적 Theme 팔레트: warm-neutral-pale | Yes | table, input, select | | `color.palette.warm-neutral-secondary` | `--hm-sem-palette-warm-neutral-secondary` | `#ede8db` | 선택적 Theme 팔레트: warm-neutral-secondary | Yes | Theme palette / adapter | | `color.palette.warm-neutral-muted` | `--hm-sem-palette-warm-neutral-muted` | `#f4f1ea` | 선택적 Theme 팔레트: warm-neutral-muted | Yes | calendar, badge, table | | `color.palette.green-tint` | `--hm-sem-palette-green-tint` | `#bddfd4` | 선택적 Theme 팔레트: green-tint | Yes | calendar, pagination, table, select, gnb, lnb | | `color.palette.yellow-accent` | `--hm-sem-palette-yellow-accent` | `#ffc600` | 선택적 Theme 팔레트: yellow-accent | Yes | lnb | | `color.palette.brown-deep` | `--hm-sem-palette-brown-deep` | `#221d13` | 선택적 Theme 팔레트: brown-deep | Yes | button | | `color.palette.brown-highlight` | `--hm-sem-palette-brown-highlight` | `#a98d53` | 선택적 Theme 팔레트: brown-highlight | Yes | button | | `color.palette.orange-light` | `--hm-sem-palette-orange-light` | `#d35a00` | 선택적 Theme 팔레트: orange-light | Yes | button | | `color.palette.orange-mid` | `--hm-sem-palette-orange-mid` | `#ce5600` | 선택적 Theme 팔레트: orange-mid | Yes | button | | `color.palette.orange-dark` | `--hm-sem-palette-orange-dark` | `#b44b00` | 선택적 Theme 팔레트: orange-dark | Yes | button | | `color.palette.orange-deep` | `--hm-sem-palette-orange-deep` | `#783402` | 선택적 Theme 팔레트: orange-deep | Yes | button | | `color.palette.orange-border` | `--hm-sem-palette-orange-border` | `#bc4c00` | 선택적 Theme 팔레트: orange-border | Yes | button | | `color.palette.orange-border-deep` | `--hm-sem-palette-orange-border-deep` | `#5e2902` | 선택적 Theme 팔레트: orange-border-deep | Yes | button | | `color.palette.gray` | `--hm-sem-palette-gray` | `#767676` | 선택적 Theme 팔레트: gray | Yes | button | | `color.palette.gray-dark` | `--hm-sem-palette-gray-dark` | `#5a5a5a` | 선택적 Theme 팔레트: gray-dark | Yes | button | | `color.palette.indicator` | `--hm-sem-palette-indicator` | `#2d2d2d` | 선택적 Theme 팔레트: indicator | Yes | select | | `color.palette.green-dark-3` | `--hm-sem-palette-green-dark-3` | `#020a07` | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `color.palette.brown-light-3` | `--hm-sem-palette-brown-light-3` | `#c1a770` | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `color.palette.brown-dark-2` | `--hm-sem-palette-brown-dark-2` | `#2f281c` | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `color.palette.brown-dark-3` | `--hm-sem-palette-brown-dark-3` | `#1d1810` | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `color.palette.orange-light-3` | `--hm-sem-palette-orange-light-3` | `#ec8f53` | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `color.palette.orange-light-2` | `--hm-sem-palette-orange-light-2` | `#f87725` | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `color.palette.orange-light-1` | `--hm-sem-palette-orange-light-1` | `#eb5f00` | ui_viz 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `color.palette.orange-dark-1` | `--hm-sem-palette-orange-dark-1` | `#bc4c00` | 2026-10-11 사용자 확정 브랜드 단계 | Yes | Color Reference / 선택적 Theme palette | | `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 | 총 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 `color.status.error` → `--hm-sem-status-error` → Default `#B3261E`는 일반 상태 오류의 독립 Semantic Token이다. 사용 가능 상태만 승인되었으며 Confirmed 승격이나 Component 적용은 별도 사용자 결정이다. [Foundation Color](../../src/foundation/color.stories.tsx)는 기존 Semantic 카드와 Computed Property Hook으로 실제 Swatch·HEX·Canonical·CSS Variable·Provisional을 표시한다. [추가 및 선택 검증 기록](../reports/generic-status-error-token-2026-10-11.md). Input Error와 Generic Status Error는 별도 역할이다. Input / Alert destructive / Toast Error / Badge destructive 및 `color.action.destructive`의 기존 `#D32F2F` 값·Alias 체인, Dashboard issue `#FF4D4F`는 유지한다. 새 Token을 기존 Component에 자동 연결하지 않는다. `color.action.cancel`의 공개 key·기본값은 보존한다. 2026-10-10 Gray 통일 요청에 따라 기본 Outline 취소 ink는 기존 Gray palette `#767676`을 사용한다. 기본값과 다른 명시적 취소 컬러 override는 내부 Button mapping에 전달하고 Reset 시 복원한다. 전체 Default preset을 주입해도 기본 Gray와 동일하다. Solid 취소는 기존 Gray mapping을 유지한다. [Runtime Theme](runtime-theme.md). # 디자인팀 Runtime 운영 결정 — 2026-10-06, 팔레트 보강 2026-10-11 기존 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`(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 계약은 유지한다. 추가 Production API는 `fetchRuntimeTheme(url, request?)`, `resolveRuntimeTheme(theme, defaults?)`, `loadRuntimeTheme(root,url,options?)`다. fetch는 DOM과 분리되며 validation은 기존 `isRuntimeTheme`을 재사용한다. Loader 실패는 HM package fallback, partial은 같은 계약으로 교체/병합하며 superseded 요청은 새 Theme를 덮거나 reset하지 않는다. 회사 CDN URL은 하드코딩하지 않는다. 사용법: [디자인팀 Theme 가이드](designer-theme-guide.md), [Theme 운영/배포](theme-delivery.md). 적용·fallback·scope 정책: [Runtime Theme](runtime-theme.md). ## 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--`를 참조한다. 명시적 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 전용 미리보기도 보존한다. 과거 미정의 검증 보고서는 당시 이력으로 유지한다.