@hjmds/design-contracts 0.10.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAC1D,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AAE/D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AA2CF,eAAO,MAAM,MAAM,EAAE,QAAQ,CAC3B,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAC3B,CAAC;AAEpB,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtE,eAAO,MAAM,OAAO,EAAE,QAAQ,CAC5B,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAc5D,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAK3D,CAAC;AAEF,eAAO,MAAM,YAAY,YAAY,CAAC;AAEtC,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;CAKhB,CAAC;AAEX,eAAO,MAAM,eAAe,YAAY,CAAC;AAEzC,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAc5D"}
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAC1D,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AAE/D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAE1E;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AA4CF,eAAO,MAAM,MAAM,EAAE,QAAQ,CAC3B,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAC3B,CAAC;AAEpB,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtE,eAAO,MAAM,OAAO,EAAE,QAAQ,CAC5B,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAc5D,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAK3D,CAAC;AAEF,eAAO,MAAM,YAAY,YAAY,CAAC;AAEtC,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;CAKhB,CAAC;AAEX,eAAO,MAAM,eAAe,YAAY,CAAC;AAEzC,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAc5D"}
package/dist/colors.js CHANGED
@@ -21,20 +21,21 @@ const light = {
21
21
  dangerFill: "#b91c1c",
22
22
  onDanger: "#ffffff",
23
23
  };
24
+ /** Mirrors light's neutrals; see docs/theme-palette.md before editing a value. */
24
25
  const dark = {
25
- bg: "#0b1026",
26
- surface: "#131a36",
27
- surfaceAlt: "#1e293b",
28
- surfaceAccent: "#1e3a5f",
29
- border: "#64748b",
30
- borderControl: "#94a3b8",
31
- text: "#f1f5f9",
32
- textBody: "#e2e8f0",
33
- textMuted: "#cbd5e1",
34
- textSub: "#94a3b8",
35
- textWeak: "#8292a9",
36
- primary: "#075985",
37
- contentBrand: "#38bdf8",
26
+ bg: "#0d1116",
27
+ surface: "#161b22",
28
+ surfaceAlt: "#1e232a",
29
+ surfaceAccent: "#224159",
30
+ border: "#6a788a",
31
+ borderControl: "#929faf",
32
+ text: "#f3f5f7",
33
+ textBody: "#e1e5ea",
34
+ textMuted: "#cad0d8",
35
+ textSub: "#9ba5b0",
36
+ textWeak: "#8b96a2",
37
+ primary: "#0476b4",
38
+ contentBrand: "#51bff6",
38
39
  danger: "#f87171",
39
40
  onPrimary: "#ffffff",
40
41
  dangerFill: "#b91c1c",
@@ -1 +1 @@
1
- {"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"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","sourcesContent":["/** A persisted preference is an application concern; this package only defines valid values. */\nexport type ThemePreference = \"system\" | \"light\" | \"dark\";\nexport type ResolvedTheme = Exclude<ThemePreference, \"system\">;\n\nexport function isThemePreference(value: unknown): value is ThemePreference {\n return value === \"system\" || value === \"light\" || value === \"dark\";\n}\n\n/**\n * Product code chooses colors by meaning, never by a raw palette name.\n * Both themes deliberately expose exactly the same keys.\n */\nexport type ThemeColors = {\n bg: string;\n surface: string;\n surfaceAlt: string;\n surfaceAccent: string;\n border: string;\n /**\n * Outline of an interactive control that must read stronger than the shared\n * hairline. Separate from `border` because a resting control needs to be\n * findable while a surface edge should stay quiet, and separate from\n * `textSub` because a text-strength outline makes an unselected control read\n * heavier than the selected one beside it.\n */\n borderControl: string;\n text: string;\n textBody: string;\n textMuted: string;\n textSub: string;\n textWeak: string;\n primary: string;\n contentBrand: string;\n danger: string;\n onPrimary: string;\n dangerFill: string;\n onDanger: string;\n};\n\nconst light = {\n bg: \"#ffffff\",\n surface: \"#f2f4f6\",\n surfaceAlt: \"#e5e8eb\",\n surfaceAccent: \"#c9e2ff\",\n border: \"#e5e8eb\",\n // Keeps the value the secondary control outline already resolved to.\n borderControl: \"#6b7684\",\n text: \"#191f28\",\n textBody: \"#333d4b\",\n textMuted: \"#4e5968\",\n textSub: \"#6b7684\",\n textWeak: \"#8b95a1\",\n primary: \"#0369a1\",\n contentBrand: \"#075985\",\n danger: \"#b71919\",\n onPrimary: \"#ffffff\",\n dangerFill: \"#b91c1c\",\n onDanger: \"#ffffff\",\n} as const satisfies ThemeColors;\n\nconst dark = {\n bg: \"#0b1026\",\n surface: \"#131a36\",\n surfaceAlt: \"#1e293b\",\n surfaceAccent: \"#1e3a5f\",\n border: \"#64748b\",\n borderControl: \"#94a3b8\",\n text: \"#f1f5f9\",\n textBody: \"#e2e8f0\",\n textMuted: \"#cbd5e1\",\n textSub: \"#94a3b8\",\n textWeak: \"#8292a9\",\n primary: \"#075985\",\n contentBrand: \"#38bdf8\",\n danger: \"#f87171\",\n onPrimary: \"#ffffff\",\n dangerFill: \"#b91c1c\",\n onDanger: \"#ffffff\",\n} as const satisfies ThemeColors;\n\nexport const THEMES: Readonly<\n Record<ResolvedTheme, Readonly<ThemeColors>>\n> = { light, dark };\n\n/** Generic emphasis roles. Product-specific meanings are mapped by each consumer. */\nexport type AccentTone = \"info\" | \"success\" | \"warning\" | \"attention\";\n\nexport const ACCENTS: Readonly<\n Record<ResolvedTheme, Readonly<Record<AccentTone, string>>>\n> = {\n light: {\n info: \"#6d28d9\",\n success: \"#065f46\",\n warning: \"#92400e\",\n attention: \"#9a3412\",\n },\n dark: {\n info: \"#a78bfa\",\n success: \"#34d399\",\n warning: \"#fbbf24\",\n attention: \"#fb923c\",\n },\n};\n\n/** Solid emphasis fills always pair with `onAccentFill`. */\nexport const accentFill: Readonly<Record<AccentTone, string>> = {\n info: \"#6d28d9\",\n success: \"#065f46\",\n warning: \"#92400e\",\n attention: \"#9a3412\",\n};\n\nexport const onAccentFill = \"#ffffff\";\n\nexport const accentTint = {\n weak: 0.1,\n base: 0.15,\n strong: 0.2,\n border: 0.3,\n} as const;\n\n/**\n * HJM organization surfaces' default signature. Renderers translate the\n * normalized coordinates. Product identity is owned by each product adapter;\n * consumers must not treat this value as every product's automatic brand.\n */\nexport const brandGradient = {\n from: \"#0369a1\",\n to: \"#155dfc\",\n start: { x: 0, y: 0 },\n end: { x: 1, y: 1 },\n} as const;\n\nexport const onBrandGradient = \"#ffffff\";\n\n/** Add an alpha channel without coupling callers to a CSS or React Native helper. */\nexport function withAlpha(hex: string, alpha: number): string {\n const match = /^#([0-9a-fA-F]{6})$/.exec(hex);\n if (!match) {\n throw new TypeError(\"A six-digit hex color is required\");\n }\n if (!Number.isFinite(alpha) || alpha < 0 || alpha > 1) {\n throw new RangeError(\"Alpha must be a finite number between 0 and 1\");\n }\n\n const source = match[1]!;\n const channels = [0, 2, 4].map((offset) =>\n Number.parseInt(source.slice(offset, offset + 2), 16),\n );\n return `rgba(${channels[0]}, ${channels[1]}, ${channels[2]}, ${alpha})`;\n}\n"]}
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"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","sourcesContent":["/** A persisted preference is an application concern; this package only defines valid values. */\nexport type ThemePreference = \"system\" | \"light\" | \"dark\";\nexport type ResolvedTheme = Exclude<ThemePreference, \"system\">;\n\nexport function isThemePreference(value: unknown): value is ThemePreference {\n return value === \"system\" || value === \"light\" || value === \"dark\";\n}\n\n/**\n * Product code chooses colors by meaning, never by a raw palette name.\n * Both themes deliberately expose exactly the same keys.\n */\nexport type ThemeColors = {\n bg: string;\n surface: string;\n surfaceAlt: string;\n surfaceAccent: string;\n border: string;\n /**\n * Outline of an interactive control that must read stronger than the shared\n * hairline. Separate from `border` because a resting control needs to be\n * findable while a surface edge should stay quiet, and separate from\n * `textSub` because a text-strength outline makes an unselected control read\n * heavier than the selected one beside it.\n */\n borderControl: string;\n text: string;\n textBody: string;\n textMuted: string;\n textSub: string;\n textWeak: string;\n primary: string;\n contentBrand: string;\n danger: string;\n onPrimary: string;\n dangerFill: string;\n onDanger: string;\n};\n\nconst light = {\n bg: \"#ffffff\",\n surface: \"#f2f4f6\",\n surfaceAlt: \"#e5e8eb\",\n surfaceAccent: \"#c9e2ff\",\n border: \"#e5e8eb\",\n // Keeps the value the secondary control outline already resolved to.\n borderControl: \"#6b7684\",\n text: \"#191f28\",\n textBody: \"#333d4b\",\n textMuted: \"#4e5968\",\n textSub: \"#6b7684\",\n textWeak: \"#8b95a1\",\n primary: \"#0369a1\",\n contentBrand: \"#075985\",\n danger: \"#b71919\",\n onPrimary: \"#ffffff\",\n dangerFill: \"#b91c1c\",\n onDanger: \"#ffffff\",\n} as const satisfies ThemeColors;\n\n/** Mirrors light's neutrals; see docs/theme-palette.md before editing a value. */\nconst dark = {\n bg: \"#0d1116\",\n surface: \"#161b22\",\n surfaceAlt: \"#1e232a\",\n surfaceAccent: \"#224159\",\n border: \"#6a788a\",\n borderControl: \"#929faf\",\n text: \"#f3f5f7\",\n textBody: \"#e1e5ea\",\n textMuted: \"#cad0d8\",\n textSub: \"#9ba5b0\",\n textWeak: \"#8b96a2\",\n primary: \"#0476b4\",\n contentBrand: \"#51bff6\",\n danger: \"#f87171\",\n onPrimary: \"#ffffff\",\n dangerFill: \"#b91c1c\",\n onDanger: \"#ffffff\",\n} as const satisfies ThemeColors;\n\nexport const THEMES: Readonly<\n Record<ResolvedTheme, Readonly<ThemeColors>>\n> = { light, dark };\n\n/** Generic emphasis roles. Product-specific meanings are mapped by each consumer. */\nexport type AccentTone = \"info\" | \"success\" | \"warning\" | \"attention\";\n\nexport const ACCENTS: Readonly<\n Record<ResolvedTheme, Readonly<Record<AccentTone, string>>>\n> = {\n light: {\n info: \"#6d28d9\",\n success: \"#065f46\",\n warning: \"#92400e\",\n attention: \"#9a3412\",\n },\n dark: {\n info: \"#a78bfa\",\n success: \"#34d399\",\n warning: \"#fbbf24\",\n attention: \"#fb923c\",\n },\n};\n\n/** Solid emphasis fills always pair with `onAccentFill`. */\nexport const accentFill: Readonly<Record<AccentTone, string>> = {\n info: \"#6d28d9\",\n success: \"#065f46\",\n warning: \"#92400e\",\n attention: \"#9a3412\",\n};\n\nexport const onAccentFill = \"#ffffff\";\n\nexport const accentTint = {\n weak: 0.1,\n base: 0.15,\n strong: 0.2,\n border: 0.3,\n} as const;\n\n/**\n * HJM organization surfaces' default signature. Renderers translate the\n * normalized coordinates. Product identity is owned by each product adapter;\n * consumers must not treat this value as every product's automatic brand.\n */\nexport const brandGradient = {\n from: \"#0369a1\",\n to: \"#155dfc\",\n start: { x: 0, y: 0 },\n end: { x: 1, y: 1 },\n} as const;\n\nexport const onBrandGradient = \"#ffffff\";\n\n/** Add an alpha channel without coupling callers to a CSS or React Native helper. */\nexport function withAlpha(hex: string, alpha: number): string {\n const match = /^#([0-9a-fA-F]{6})$/.exec(hex);\n if (!match) {\n throw new TypeError(\"A six-digit hex color is required\");\n }\n if (!Number.isFinite(alpha) || alpha < 0 || alpha > 1) {\n throw new RangeError(\"Alpha must be a finite number between 0 and 1\");\n }\n\n const source = match[1]!;\n const channels = [0, 2, 4].map((offset) =>\n Number.parseInt(source.slice(offset, offset + 2), 16),\n );\n return `rgba(${channels[0]}, ${channels[1]}, ${channels[2]}, ${alpha})`;\n}\n"]}
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Package release shown by documentation surfaces. Kept in sync by a test. */
2
- export declare const designSystemVersion: "0.10.0";
2
+ export declare const designSystemVersion: "1.0.0";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAG,QAAiB,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAG,OAAgB,CAAC"}
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Package release shown by documentation surfaces. Kept in sync by a test. */
2
- export const designSystemVersion = "0.10.0";
2
+ export const designSystemVersion = "1.0.0";
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,QAAiB,CAAC","sourcesContent":["/** Package release shown by documentation surfaces. Kept in sync by a test. */\nexport const designSystemVersion = \"0.10.0\" as const;\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAgB,CAAC","sourcesContent":["/** Package release shown by documentation surfaces. Kept in sync by a test. */\nexport const designSystemVersion = \"1.0.0\" as const;\n"]}
@@ -1,6 +1,6 @@
1
1
  # Component maturity and evidence manifest
2
2
 
3
- > Generated from `@hjmds/design-contracts` 0.10.0. Do not edit this file directly; run `pnpm contracts:sync`.
3
+ > Generated from `@hjmds/design-contracts` 1.0.0. Do not edit this file directly; run `pnpm contracts:sync`.
4
4
 
5
5
  This document is the human-readable projection of the same catalog and Showcase manifest consumed by product CI.
6
6
 
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "designSystemVersion": "0.10.0",
3
+ "designSystemVersion": "1.0.0",
4
4
  "source": "packages/design-contracts/docs/generated/showcase-manifest.json",
5
5
  "surfaces": {
6
6
  "web": {
7
7
  "packageName": "@hjmds/react",
8
- "packageVersion": "0.10.0",
8
+ "packageVersion": "1.0.0",
9
9
  "activeComponents": 63,
10
10
  "claimedComponents": 63,
11
11
  "completeScenarioComponents": 33,
@@ -2918,7 +2918,7 @@
2918
2918
  },
2919
2919
  "native": {
2920
2920
  "packageName": "@hjmds/react-native",
2921
- "packageVersion": "0.10.0",
2921
+ "packageVersion": "1.0.0",
2922
2922
  "activeComponents": 63,
2923
2923
  "claimedComponents": 63,
2924
2924
  "completeScenarioComponents": 34,
@@ -1,6 +1,6 @@
1
1
  # Renderer evidence coverage
2
2
 
3
- > Generated for HJM 0.10.0. Do not edit directly; run `pnpm evidence:sync`.
3
+ > Generated for HJM 1.0.0. Do not edit directly; run `pnpm evidence:sync`.
4
4
 
5
5
  This projection joins the canonical surface maturity manifest with first-party renderer claims. Missing scenarios are explicit beta promotion debt; stable surfaces are blocked by CI until none remain.
6
6
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "designSystemVersion": "0.10.0",
3
+ "designSystemVersion": "1.0.0",
4
4
  "packageName": "@hjmds/design-contracts",
5
5
  "components": [
6
6
  {
@@ -0,0 +1,52 @@
1
+ # 테마 팔레트 결정 기록
2
+
3
+ `src/colors.ts`의 `THEMES` 값이 왜 지금 값인지를 적는다. 소스에는 포인터만 두는데,
4
+ `tsc`가 JSDoc을 `dist`에 그대로 실어서 긴 주석이 `./colors` 번들 예산을 넘기기 때문이다
5
+ (2026-09-14 실측: 주석만으로 raw 3.0 kB → 4.2 kB, colors를 재수출하는 tokens·recipes·
6
+ contracts·tree-select까지 연쇄로 초과).
7
+
8
+ ## 다크는 라이트의 짝이어야 한다
9
+
10
+ 2026-09-14 제품 보고: "다크 모드 색감이 탁하고, 포인트 색이 안 어울린다."
11
+
12
+ 원인은 다크가 **두 색 계열을 섞어 쓴 것**이었다.
13
+
14
+ | 역할 | 종전 값 | 계열 |
15
+ | --- | --- | --- |
16
+ | `bg` | `#0b1026` | hsl 229° / 채도 55% — 채도 높은 인디고 |
17
+ | `surface` | `#131a36` | hsl 228° / 48% — 인디고 |
18
+ | `surfaceAlt` | `#1e293b` | hsl 217° / 33% — 슬레이트 |
19
+ | `border` | `#64748b` | hsl 215° / 16% — 슬레이트 |
20
+ | 텍스트 램프 | `#f1f5f9`…`#8292a9` | hsl 210-215° / 18-40% — 슬레이트 |
21
+
22
+ 채도 높은 인디고 위에 채도 낮은 회청색 판을 얹으면 탁하게 읽힌다. 그리고 이 구조는
23
+ 라이트에 짝이 없었다 — 라이트의 표면은 거의 중성 회색(hsl ~210°, 채도 9-23%)이고
24
+ 채도가 높은 것은 강조색뿐이다. 즉 다크는 라이트의 다크 버전이 아니라 **다른 색 시스템**이었다.
25
+
26
+ 그래서 표면과 중성 램프를 라이트와 같은 중성 계열(hsl 210-215°, 채도 11-26%)로 내렸다.
27
+ 화면에서 채도가 높은 것은 강조색 하나뿐이 되고, 이것이 "포인트 색이 안 어울린다"의 답이기도
28
+ 하다 — 강조색이 겉돈 이유는 주변이 이미 전부 물들어 있었기 때문이다.
29
+
30
+ **버린 대안:** 소비 제품(번뚝)의 표면만 손보기. 탁함의 원인이 이 공용 토큰이라 모든 소비자가
31
+ 같은 교정을 각자 반복해야 했다.
32
+
33
+ ## `primary`의 밝기 역전
34
+
35
+ 다크 `primary`는 hsl 201° 90% **27%** 로, 라이트의 32%보다 **어두웠다**. 그래서 주요 동작이
36
+ 배경으로 가라앉았다 — 세 표면 대비 1.93:1~2.49:1로, UI 요소가 형태로 식별되기 위한
37
+ **3:1에 미달**했다. WCAG의 텍스트 규칙은 버튼 위의 글자만 보기 때문에 이 결함을 잡지 못한다.
38
+
39
+ 새 값 hsl 201° 96% 36%(`#0476b4`)는 라이트보다 밝고 세 표면 모두에서 3.20:1~3.84:1이다.
40
+ 대신 흰 글자 대비가 7.56:1 → 4.93:1로 줄지만 AA는 유지한다.
41
+
42
+ **창이 좁다.** 이 색상에서 36% 미만이면 `surfaceAlt` 위에서 3:1이 깨지고, 37%를 넘으면
43
+ 흰 라벨이 AA를 놓친다. 값을 조정할 때 두 경계를 함께 본다.
44
+
45
+ ## 회귀 게이트
46
+
47
+ `test/contracts.test.ts`가 두 결정을 고정한다.
48
+
49
+ - `keeps the primary fill discernible against the surfaces it sits on` — 채운 컨트롤이
50
+ 형태로 보이는지(3:1). 기존 AA 검사가 못 잡던 축이다.
51
+ - `keeps neutral surfaces and text in one low-saturation family per theme` — 중성 역할의
52
+ 채도 상한 30%. 강조 역할(`primary`·`contentBrand`·`danger`·`surfaceAccent`)은 제외한다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hjmds/design-contracts",
3
- "version": "0.10.0",
3
+ "version": "1.0.0",
4
4
  "description": "Renderer-neutral design contracts, tokens, recipes, and behaviors shared by HJM products.",
5
5
  "license": "MIT",
6
6
  "repository": {