From f211ff42a5806a3442d5fb2d50dd6c5dcd1de07e Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 12 Oct 2026 20:52:31 +0900 Subject: [PATCH] =?UTF-8?q?fix(b05,b06):=20=EC=A2=85=EB=8B=A8=EB=8F=84=20?= =?UTF-8?q?=EB=88=84=EA=B0=80=ED=86=A0=EB=9F=89=20=EC=95=8C=EC=95=BD=20?= =?UTF-8?q?=ED=85=8C=EB=91=90=EB=A6=AC=20=C2=B7=20=EA=B8=80=EC=9E=90=20?= =?UTF-8?q?=C2=B7=20=EB=B0=94=ED=83=95=20=EB=B6=89=EC=9D=80=20=EA=B3=84?= =?UTF-8?q?=ED=86=B5=20=C2=B7=20=EC=9D=8C=EC=88=98=EB=8A=94=20=EB=8D=94=20?= =?UTF-8?q?=EC=A7=84=ED=95=98=EA=B2=8C=20(289-2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD --- common_util/common_util_mass_haul.css | 21 +++++-- .../tester/test_289_1_mass_badge_size.py | 55 +++++++++++++++++++ 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/common_util/common_util_mass_haul.css b/common_util/common_util_mass_haul.css index 4ecc1abde..ce334dbb9 100644 --- a/common_util/common_util_mass_haul.css +++ b/common_util/common_util_mass_haul.css @@ -388,10 +388,15 @@ gap: var(--spacing-4, 4px); /* 큰 알약(289) — 글자 · 여백 한 단 위 */ padding: var(--spacing-4, 4px) var(--spacing-12, 12px); - border: 1px solid var(--color-border); + /* 붉은 계통(289-2) — 테두리 · 글자 · 옅은 바탕 = 위험색 섞음(밝음 · 어두움 같이) */ + border: 1px solid color-mix(in srgb, var(--color-danger) 55%, transparent); border-radius: var(--radius-pills, 999px); - background: color-mix(in srgb, var(--color-surface-raised) 88%, transparent); - color: var(--color-text-body); + background: color-mix( + in srgb, + var(--color-danger) 6%, + color-mix(in srgb, var(--color-surface-raised) 88%, transparent) + ); + color: color-mix(in srgb, var(--color-danger) 70%, var(--color-text-body)); font-size: var(--pill-font-size-lg); line-height: var(--leading-body-sm); white-space: nowrap; @@ -399,7 +404,7 @@ } .mass-haul-badge em { - color: var(--color-text-secondary); + color: color-mix(in srgb, var(--color-danger) 55%, var(--color-text-secondary)); font-style: normal; } @@ -407,6 +412,12 @@ font-weight: var(--font-weight-bold, 700); } +/* 음수 = 더 진하게 — 테두리 = 위험색 그대로 · 바탕 짙게 · 값 = 위험색 더 많이(대비 4.5 : 1 지킴) */ +.mass-haul-badge.is-over { + border-color: var(--color-danger); + background: color-mix(in srgb, var(--color-danger) 12%, var(--color-surface-raised)); +} + .mass-haul-badge.is-over strong { - color: var(--color-danger, #f43f5e); + color: color-mix(in srgb, var(--color-danger) 85%, var(--color-text-body)); } diff --git a/resources/tester/test_289_1_mass_badge_size.py b/resources/tester/test_289_1_mass_badge_size.py index 9a9a62861..566ad448e 100644 --- a/resources/tester/test_289_1_mass_badge_size.py +++ b/resources/tester/test_289_1_mass_badge_size.py @@ -37,3 +37,58 @@ def test_badge_below_up_buttons(): overlays = _read("A00_Common/design/design_profile_overlays.ts") m = re.search(r'"--mass-haul-badge-top", "(\d+)px"', overlays) assert m and int(m.group(1)) > 47 # 측점 ▲ 줄 바닥(top 30 + 17) + + +# 289-2 붉은 계통 — 테마 위험색 섞음 · 밝음 · 어두움 대비(글자 4.5 : 1 이상) +THEMES = { + "light": {"danger": "#c0392b", "surface": "#ffffff", "body": "#333333", "secondary": "#615e6e"}, + "dark": {"danger": "#e8695a", "surface": "#251f38", "body": "#e4e0f0", "secondary": "#b3aec6"}, +} + + +def _rgb(hex_: str) -> tuple[float, ...]: + return tuple(int(hex_[i : i + 2], 16) / 255 for i in (1, 3, 5)) + + +def _mix(a: str, pct: int, b: str) -> tuple[float, ...]: + """CSS color-mix(in srgb, a pct%, b) — 불투명 근사.""" + return tuple(x * pct / 100 + y * (100 - pct) / 100 for x, y in zip(_rgb(a), _rgb(b))) + + +def _lum(c: tuple[float, ...]) -> float: + lin = [v / 12.92 if v <= 0.04045 else ((v + 0.055) / 1.055) ** 2.4 for v in c] + return 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2] + + +def _contrast(a: tuple[float, ...], b: tuple[float, ...]) -> float: + hi, lo = sorted((_lum(a), _lum(b)), reverse=True) + return (hi + 0.05) / (lo + 0.05) + + +def test_badge_red_tone_uses_theme_danger(): + css = _read("common_util/common_util_mass_haul.css") + badge = _block(css, ".mass-haul-badge") + assert "border: 1px solid color-mix(in srgb, var(--color-danger) 55%, transparent)" in badge + assert "color: color-mix(in srgb, var(--color-danger) 70%, var(--color-text-body))" in badge + assert "var(--color-danger) 6%" in badge + em = _block(css, ".mass-haul-badge em") + assert "color-mix(in srgb, var(--color-danger) 55%, var(--color-text-secondary))" in em + over = _block(css, ".mass-haul-badge.is-over") + assert "border-color: var(--color-danger)" in over + assert "var(--color-danger) 12%" in over + over_value = _block(css, ".mass-haul-badge.is-over strong") + assert "color-mix(in srgb, var(--color-danger) 85%, var(--color-text-body))" in over_value + assert not re.search(r"#[0-9a-fA-F]{3,6}\b", badge + em + over + over_value) # 하드코딩 색 없음 + + +def test_badge_red_tone_contrast_both_themes(): + for name, t in THEMES.items(): + bg = _mix(t["danger"], 6, t["surface"]) + text = _mix(t["danger"], 70, t["body"]) + caption = _mix(t["danger"], 55, t["secondary"]) + over_bg = _mix(t["danger"], 12, t["surface"]) + over_value = _mix(t["danger"], 85, t["body"]) # 음수 값 = 위험색 더 많이 + assert _contrast(text, bg) >= 4.5, name + assert _contrast(caption, bg) >= 4.5, name + assert _contrast(over_value, over_bg) >= 4.5, name + assert _contrast(caption, over_bg) >= 4.5, name