From 73ef042c5536ee28ef9d5be4aae6aceec62acc9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=88=98=ED=98=84?= Date: Mon, 9 Nov 2026 19:23:43 +0900 Subject: [PATCH] feat(theme): update Hanmac Green and Brown palette steps Seven shared Hanmac color tokens change: - Green Default #123328 -> #164434, Dark 1 #0a221d -> #11372d, Dark 2 #071e18 -> #0b2b23, Dark 3 #020a07 -> #030e0a - Brown Default #3e3523 -> #4e422d, Dark 1 #352d1d -> #403726, Dark 3 #1d1810 -> #0d0b07 Updates primitives.css, the generated default values, themes/default.json, the verification baseline and the hard-coded Default expectations in the theme Stories and the quality-reference script. --hm-sem-on-accent is intentionally unchanged. check:theme-defaults reports generated outputs match. --- .../ui/src/theme/default-values.generated.ts | 30 +++++++++---------- packages/ui/src/theme/primitives.css | 14 ++++----- scripts/verify-quality-reference.mjs | 6 ++-- src/theme/designer-theme.stories.tsx | 2 +- src/theme/runtime-loader.stories.tsx | 2 +- src/theme/runtime-theme.stories.tsx | 2 +- src/theme/verification-baseline.json | 10 +++---- themes/default.json | 30 +++++++++---------- 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/packages/ui/src/theme/default-values.generated.ts b/packages/ui/src/theme/default-values.generated.ts index 14003bd..512203e 100644 --- a/packages/ui/src/theme/default-values.generated.ts +++ b/packages/ui/src/theme/default-values.generated.ts @@ -3,24 +3,24 @@ export const runtimeThemeDefaults = { "--hm-sem-bg-content": "#f5f0e5", "--hm-sem-bg-surface": "#ffffff", - "--hm-sem-fg-primary": "#0a221d", + "--hm-sem-fg-primary": "#11372d", "--hm-sem-fg-secondary": "#6e6759", "--hm-sem-fg-placeholder": "#999999", - "--hm-sem-action-primary": "#123328", + "--hm-sem-action-primary": "#164434", "--hm-sem-action-cancel": "#6e6759", "--hm-sem-action-destructive": "#d32f2f", "--hm-sem-status-error": "#b3261e", "--hm-sem-stroke-default": "#9a9284", "--hm-sem-stroke-input-default": "#dedbd2", "--hm-sem-stroke-input-focus": "#266651", - "--hm-sem-brand-bg-stop-0": "#0a221d", - "--hm-sem-brand-bg-stop-12": "#071e18", - "--hm-sem-brand-bg-stop-42": "#123328", + "--hm-sem-brand-bg-stop-0": "#11372d", + "--hm-sem-brand-bg-stop-12": "#0b2b23", + "--hm-sem-brand-bg-stop-42": "#164434", "--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-0": "#403726", "--hm-sem-brown-bg-stop-12": "#2f281c", - "--hm-sem-brown-bg-stop-42": "#3e3523", + "--hm-sem-brown-bg-stop-42": "#4e422d", "--hm-sem-brown-bg-stop-78": "#897445", "--hm-sem-brown-bg-stop-100": "#604f32", "--hm-sem-orange-bg-stop-0": "#bc4c00", @@ -32,7 +32,7 @@ export const runtimeThemeDefaults = { "--hm-sem-action-surface-stop-30": "#165c47", "--hm-sem-action-surface-stop-65": "#114838", "--hm-sem-action-surface-stop-100": "#08241c", - "--hm-sem-action-border-stop-0": "#0a221d", + "--hm-sem-action-border-stop-0": "#11372d", "--hm-sem-action-border-stop-50": "#34daaa", "--hm-sem-action-border-stop-100": "#08241c", "--hm-radius-input": "4px", @@ -47,13 +47,13 @@ export const runtimeThemeDefaults = { "--hm-sem-palette-green-light-3": "#249473", "--hm-sem-palette-green-light-2": "#266651", "--hm-sem-palette-green-light-1": "#205241", - "--hm-sem-palette-green-default": "#123328", - "--hm-sem-palette-green-dark-1": "#0a221d", - "--hm-sem-palette-green-dark-2": "#071e18", + "--hm-sem-palette-green-default": "#164434", + "--hm-sem-palette-green-dark-1": "#11372d", + "--hm-sem-palette-green-dark-2": "#0b2b23", "--hm-sem-palette-brown-light-2": "#897445", "--hm-sem-palette-brown-light-1": "#604f32", - "--hm-sem-palette-brown-default": "#3e3523", - "--hm-sem-palette-brown-dark-1": "#352d1d", + "--hm-sem-palette-brown-default": "#4e422d", + "--hm-sem-palette-brown-dark-1": "#403726", "--hm-sem-palette-brown-light-4": "#ecd4a2", "--hm-sem-palette-orange-light-4": "#feba88", "--hm-sem-palette-orange-default": "#cc5200", @@ -85,10 +85,10 @@ export const runtimeThemeDefaults = { "--hm-sem-palette-gray": "#767676", "--hm-sem-palette-gray-dark": "#5a5a5a", "--hm-sem-palette-indicator": "#2d2d2d", - "--hm-sem-palette-green-dark-3": "#020a07", + "--hm-sem-palette-green-dark-3": "#030e0a", "--hm-sem-palette-brown-light-3": "#c1a770", "--hm-sem-palette-brown-dark-2": "#2f281c", - "--hm-sem-palette-brown-dark-3": "#1d1810", + "--hm-sem-palette-brown-dark-3": "#0d0b07", "--hm-sem-palette-orange-light-3": "#ec8f53", "--hm-sem-palette-orange-light-2": "#f87725", "--hm-sem-palette-orange-light-1": "#eb5f00", diff --git a/packages/ui/src/theme/primitives.css b/packages/ui/src/theme/primitives.css index baeca6b..f679180 100644 --- a/packages/ui/src/theme/primitives.css +++ b/packages/ui/src/theme/primitives.css @@ -5,14 +5,14 @@ --hm-green-light-3: #249473; --hm-green-light-2: #266651; --hm-green-light-1: #205241; - --hm-green-default: #123328; - --hm-green-dark-1: #0a221d; - --hm-green-dark-2: #071e18; + --hm-green-default: #164434; + --hm-green-dark-1: #11372d; + --hm-green-dark-2: #0b2b23; --hm-brown-light-2: #897445; --hm-brown-light-1: #604f32; - --hm-brown-default: #3e3523; - --hm-brown-dark-1: #352d1d; + --hm-brown-default: #4e422d; + --hm-brown-dark-1: #403726; --hm-brown-light-4: #ecd4a2; @@ -47,10 +47,10 @@ /* Confirmed brand palette additions (ui_viz Color 4.1; Orange Dark 1/2 confirmed by user 2026-10-11). */ :root { - --hm-green-dark-3: #020a07; + --hm-green-dark-3: #030e0a; --hm-brown-light-3: #c1a770; --hm-brown-dark-2: #2f281c; - --hm-brown-dark-3: #1d1810; + --hm-brown-dark-3: #0d0b07; --hm-orange-light-3: #ec8f53; --hm-orange-light-2: #f87725; --hm-orange-light-1: #eb5f00; diff --git a/scripts/verify-quality-reference.mjs b/scripts/verify-quality-reference.mjs index c342cc3..168d45a 100644 --- a/scripts/verify-quality-reference.mjs +++ b/scripts/verify-quality-reference.mjs @@ -62,11 +62,11 @@ try { const page = await browser.newPage(); await page.goto(`${base}/storybook/iframe.html?id=theme-designer-playground--editor&viewMode=story`, { waitUntil: 'networkidle' }); await page.getByRole('button', { name: 'Load Service Example JSON', exact: true }).click(); - await page.waitForFunction(() => document.querySelector('[aria-label="Primary / Brand HEX"]')?.value !== '#123328'); + await page.waitForFunction(() => document.querySelector('[aria-label="Primary / Brand HEX"]')?.value !== '#164434'); const changed = await page.getByRole('textbox', { name: 'Primary / Brand HEX', exact: true }).inputValue(); await page.getByRole('button', { name: 'Load Default JSON', exact: true }).click(); - await page.waitForFunction(() => document.querySelector('[aria-label="Primary / Brand HEX"]')?.value === '#123328'); - await page.close(); return { servicePrimary: changed, defaultPrimary: '#123328' }; + await page.waitForFunction(() => document.querySelector('[aria-label="Primary / Brand HEX"]')?.value === '#164434'); + await page.close(); return { servicePrimary: changed, defaultPrimary: '#164434' }; }); await task('RUNTIME_THEME_KEYBOARD', async () => { const page = await browser.newPage(); diff --git a/src/theme/designer-theme.stories.tsx b/src/theme/designer-theme.stories.tsx index 045fe2a..a737854 100644 --- a/src/theme/designer-theme.stories.tsx +++ b/src/theme/designer-theme.stories.tsx @@ -240,7 +240,7 @@ export const LiveVerification: Story = { } fillJson('{"schemaVersion":1,"tokens":{"color.state.active":"#345678"}}'); click("Import JSON") await waitForThemeState(() => variable("--hm-sem-state-active") === "#345678", "Designer partial import") - assert(variable("--hm-sem-state-active") === "#345678" && variable("--hm-sem-action-primary") === "#123328" && variable("--hm-sem-stroke-input-focus") === "#266651", "Partial import replaces previous keys; unspecified roles use Default") + assert(variable("--hm-sem-state-active") === "#345678" && variable("--hm-sem-action-primary") === "#164434" && variable("--hm-sem-stroke-input-focus") === "#266651", "Partial import replaces previous keys; unspecified roles use Default") for (const [index, [token, label]] of roles.entries()) { const value = `#3456${(120 + index).toString(16)}` setInput(`${label} HEX`, value) diff --git a/src/theme/runtime-loader.stories.tsx b/src/theme/runtime-loader.stories.tsx index cc017f4..c9a150a 100644 --- a/src/theme/runtime-loader.stories.tsx +++ b/src/theme/runtime-loader.stories.tsx @@ -50,7 +50,7 @@ async function verifyLoader(container: HTMLElement) { assert(checked.dataset.state === "checked" && checked.getAttribute("aria-checked") === "true" && getComputedStyle(checked).backgroundColor === "rgb(0, 127, 115)", "HTTP JSON reaches rendered Checkbox") assert(JSON.stringify(geometry()) === initial, "External JSON preserves component geometry") const resolved = resolveRuntimeTheme({ schemaVersion: 1, tokens: { "color.state.active": "#345678" } }, defaults) - assert(resolved.tokens["color.action.primary"] === "#123328" && resolved.tokens["color.state.active"] === "#345678", "Default JSON + partial service override merge") + assert(resolved.tokens["color.action.primary"] === "#164434" && resolved.tokens["color.state.active"] === "#345678", "Default JSON + partial service override merge") assert(await loadRuntimeTheme(root, "/themes/service-example.json", { defaults }), "Loader accepts separately fetched Default JSON") assert(variable("--hm-sem-action-primary") === "#6837a8", "Service override wins supplied Default") resetRuntimeTheme(root) diff --git a/src/theme/runtime-theme.stories.tsx b/src/theme/runtime-theme.stories.tsx index 79f0207..39fd39a 100644 --- a/src/theme/runtime-theme.stories.tsx +++ b/src/theme/runtime-theme.stories.tsx @@ -190,7 +190,7 @@ async function verifyRuntime(canvasElement: HTMLElement, keyboardFocus = false) applyRuntimeTheme(after, {schemaVersion:1,tokens:{"color.state.active":"#345678"}}) assert(variable("--hm-checkbox-checked-background") === "#345678", "Scoped B overrides global A") assert(getComputedStyle(globalRoot).getPropertyValue("--hm-checkbox-checked-background").trim() === "#007f73", "Global A retains its own mapping") - assert(variable("--hm-badge-default-background") === "#123328", "Explicit isolated scope falls back to HM preset") + assert(variable("--hm-badge-default-background") === "#164434", "Explicit isolated scope falls back to HM preset") } finally { resetRuntimeTheme(globalRoot); resetRuntimeTheme(after) } after.style.setProperty("--hm-sem-state-active", "#112233", "important") applyRuntimeTheme(after, external); resetRuntimeTheme(after) diff --git a/src/theme/verification-baseline.json b/src/theme/verification-baseline.json index c9cf137..600eb16 100644 --- a/src/theme/verification-baseline.json +++ b/src/theme/verification-baseline.json @@ -779,13 +779,13 @@ "--hm-green-light-3": "#249473", "--hm-green-light-2": "#266651", "--hm-green-light-1": "#205241", - "--hm-green-default": "#123328", - "--hm-green-dark-1": "#0a221d", - "--hm-green-dark-2": "#071e18", + "--hm-green-default": "#164434", + "--hm-green-dark-1": "#11372d", + "--hm-green-dark-2": "#0b2b23", "--hm-brown-light-2": "#897445", "--hm-brown-light-1": "#604f32", - "--hm-brown-default": "#3e3523", - "--hm-brown-dark-1": "#352d1d", + "--hm-brown-default": "#4e422d", + "--hm-brown-dark-1": "#403726", "--hm-brown-light-4": "#ecd4a2", "--hm-orange-light-4": "#feba88", "--hm-orange-default": "#cc5200", diff --git a/themes/default.json b/themes/default.json index b97dbf9..fca225e 100644 --- a/themes/default.json +++ b/themes/default.json @@ -3,24 +3,24 @@ "tokens": { "color.bg.content": "#f5f0e5", "color.bg.surface": "#ffffff", - "color.fg.primary": "#0a221d", + "color.fg.primary": "#11372d", "color.fg.secondary": "#6e6759", "color.fg.placeholder": "#999999", - "color.action.primary": "#123328", + "color.action.primary": "#164434", "color.action.cancel": "#6e6759", "color.action.destructive": "#d32f2f", "color.status.error": "#b3261e", "color.stroke.default": "#9a9284", "color.stroke.input.default": "#dedbd2", "color.stroke.input.focus": "#266651", - "color.bg.brand.stop.0": "#0a221d", - "color.bg.brand.stop.12": "#071e18", - "color.bg.brand.stop.42": "#123328", + "color.bg.brand.stop.0": "#11372d", + "color.bg.brand.stop.12": "#0b2b23", + "color.bg.brand.stop.42": "#164434", "color.bg.brand.stop.78": "#266651", "color.bg.brand.stop.100": "#205241", - "color.bg.brown.stop.0": "#352d1d", + "color.bg.brown.stop.0": "#403726", "color.bg.brown.stop.12": "#2f281c", - "color.bg.brown.stop.42": "#3e3523", + "color.bg.brown.stop.42": "#4e422d", "color.bg.brown.stop.78": "#897445", "color.bg.brown.stop.100": "#604f32", "color.bg.orange.stop.0": "#bc4c00", @@ -32,7 +32,7 @@ "surface.action.primary.stop.30": "#165c47", "surface.action.primary.stop.65": "#114838", "surface.action.primary.stop.100": "#08241c", - "surface.action.primary.border.stop.0": "#0a221d", + "surface.action.primary.border.stop.0": "#11372d", "surface.action.primary.border.stop.50": "#34daaa", "surface.action.primary.border.stop.100": "#08241c", "color.state.active": "#266651", @@ -45,13 +45,13 @@ "color.palette.green-light-3": "#249473", "color.palette.green-light-2": "#266651", "color.palette.green-light-1": "#205241", - "color.palette.green-default": "#123328", - "color.palette.green-dark-1": "#0a221d", - "color.palette.green-dark-2": "#071e18", + "color.palette.green-default": "#164434", + "color.palette.green-dark-1": "#11372d", + "color.palette.green-dark-2": "#0b2b23", "color.palette.brown-light-2": "#897445", "color.palette.brown-light-1": "#604f32", - "color.palette.brown-default": "#3e3523", - "color.palette.brown-dark-1": "#352d1d", + "color.palette.brown-default": "#4e422d", + "color.palette.brown-dark-1": "#403726", "color.palette.brown-light-4": "#ecd4a2", "color.palette.orange-light-4": "#feba88", "color.palette.orange-default": "#cc5200", @@ -83,10 +83,10 @@ "color.palette.gray": "#767676", "color.palette.gray-dark": "#5a5a5a", "color.palette.indicator": "#2d2d2d", - "color.palette.green-dark-3": "#020a07", + "color.palette.green-dark-3": "#030e0a", "color.palette.brown-light-3": "#c1a770", "color.palette.brown-dark-2": "#2f281c", - "color.palette.brown-dark-3": "#1d1810", + "color.palette.brown-dark-3": "#0d0b07", "color.palette.orange-light-3": "#ec8f53", "color.palette.orange-light-2": "#f87725", "color.palette.orange-light-1": "#eb5f00",