From d9ed29ba3d7e048ff17b854dec019c6f41590820 Mon Sep 17 00:00:00 2001 From: cw2007 Date: Sat, 11 Jul 2026 12:13:15 +0900 Subject: [PATCH] =?UTF-8?q?style(dashboard):=20=EC=B0=B8=EA=B3=A0=20?= =?UTF-8?q?=EB=8C=80=EC=8B=9C=EB=B3=B4=EB=93=9C=20=EB=AF=B8=ED=95=99?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9E=AC=ED=85=8C=EB=A7=88=20=E2=80=94=20?= =?UTF-8?q?=EB=8C=80=ED=98=95=20=EC=88=AB=EC=9E=90=20KPI=C2=B7=ED=94=8C?= =?UTF-8?q?=EB=9E=AB=20=EC=B9=B4=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 참고 이미지(Geckoboard형 KPI / 인디고+골드 애널리틱스) 방향으로 시각 정리. 실제 렌더(브라우저 스크린샷)로 대시보드 4탭 + 공용 login 확인. - KPI 스트립을 '대형 숫자 + 소형 대문자 라벨' 위계로 재구성. 상태는 라벨 앞 상태 dot(도형+색) + 값 색 + 텍스트로 3중 인코딩(상단 그라디언트 스트립 제거). 타일 패딩·높이 확대로 여백 확보. - 카드 상단 3px 그라디언트 스트립 제거(.card·.kpi) → 참고처럼 평평하고 조용한 카드. .card 상태색은 값 색상 + 미묘한 테두리 틴트로 유지(월간보고·보안증적 공용). - 토큰: 라운드(r-lg 16→18) 상향, 그림자를 소프트·확산형으로, 장식 골드 액센트 토큰(--accent-gold) 추가. 공용 7페이지가 토큰으로 일관 이동. 알림 스트립 좌측 액센트 바와 login/status-hero 상단 액센트는 의미있는 알림· 아이덴티티 어포던스로 유지. --- php/assets/app.css | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/php/assets/app.css b/php/assets/app.css index c8cb82c..edc00e9 100644 --- a/php/assets/app.css +++ b/php/assets/app.css @@ -41,10 +41,13 @@ --mono: ui-monospace,SFMono-Regular,Consolas,"D2Coding",monospace; --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; - --r-sm: 6px; --r: 10px; --r-lg: 16px; --r-pill: 999px; - --shadow: 0 1px 2px rgba(0,0,0,.4); - --shadow-lg: 0 12px 32px rgba(0,0,0,.45); + --r-sm: 8px; --r: 12px; --r-lg: 18px; --r-pill: 999px; + /* 소프트·확산형 그림자(참고 대시보드처럼 카드가 표면 위에 살짝 떠 보이게) */ + --shadow: 0 2px 10px rgba(0,0,0,.30); + --shadow-lg: 0 16px 40px rgba(0,0,0,.48); --ring: 0 0 0 3px rgba(108,123,255,.45); + /* 장식 골드 액센트(참고 2.png 인디고+골드) — 상태색 --warn 과 별개의 장식 역할 */ + --accent-gold: #ffc24b; } * { box-sizing: border-box; margin: 0; padding: 0; } @@ -93,8 +96,7 @@ header h1::before { content: ""; width: 10px; height: 10px; border-radius: 50%; .panel { padding: var(--sp-5); } .chart-panel { padding: var(--sp-5); margin-bottom: var(--sp-6); } -.card { padding: var(--sp-5) var(--sp-5) var(--sp-6); position: relative; overflow: hidden; } -.card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: linear-gradient(90deg, var(--primary), var(--chart-hum)); opacity: .9; } +.card { padding: var(--sp-5) var(--sp-5) var(--sp-6); position: relative; } .card > div:first-child { color: var(--ink-2); font-size: .78rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; } .card span { color: var(--ink-2); font-size: .8125rem; } .card .val { font-size: clamp(2.4rem, 4.2vw, 3.4rem); font-weight: 800; line-height: 1.02; margin-top: var(--sp-2); color: var(--ink); letter-spacing: -.02em; } @@ -103,9 +105,10 @@ header h1::before { content: ""; width: 10px; height: 10px; border-radius: 50%; .card .val.ok-color { color: var(--normal-ink); } .card .val.err-color { color: var(--leak-ink); } .card .val.warn-color { color: var(--warn-ink); } -.card:has(.val.ok-color)::before { background: var(--normal); } -.card:has(.val.err-color)::before { background: var(--leak); } -.card:has(.val.warn-color)::before { background: var(--warn); } +/* 상태색은 .val 색상으로 인코딩(상단 스트립 제거 — 참고 대시보드 스타일의 평평한 카드) */ +.card.ok, .card:has(.val.ok-color) { border-color: rgba(53,214,160,.32); } +.card.err, .card:has(.val.err-color) { border-color: rgba(255,84,112,.34); } +.card.warn, .card:has(.val.warn-color) { border-color: rgba(255,178,62,.32); } .card .val.ok-color::before, .card .val.err-color::before, .card .val.warn-color::before { content: none; } .status-hero { border-radius: var(--r-lg); padding: var(--sp-6); margin-bottom: var(--sp-5); display: grid; grid-template-columns: minmax(0,1fr) auto; gap: var(--sp-4); align-items: center; color: var(--ink); background: linear-gradient(180deg, rgba(53,214,160,.08), transparent 70%), var(--surface); border: 1px solid var(--line); position: relative; overflow: hidden; } @@ -536,20 +539,20 @@ tbody tr:hover td { background: var(--surface-2); } margin-bottom: var(--sp-2); } .kpi { - display: flex; flex-direction: column; justify-content: center; gap: 2px; + display: flex; flex-direction: column; justify-content: center; gap: 6px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); - box-shadow: var(--shadow); padding: var(--sp-3) var(--sp-4); min-height: 76px; - text-decoration: none; color: var(--ink); position: relative; overflow: hidden; + box-shadow: var(--shadow); padding: var(--sp-4) var(--sp-5); min-height: 104px; + text-decoration: none; color: var(--ink); transition: border-color .12s ease, transform .12s ease; } -.kpi::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--primary); } -.kpi:hover { border-color: var(--primary); } -.kpi .kpi-lbl { color: var(--ink-2); font-size: .72rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; } -.kpi .kpi-val { font-size: clamp(1.3rem, 2.2vw, 1.7rem); font-weight: 800; line-height: 1.1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; } +.kpi:hover { border-color: var(--primary); transform: translateY(-2px); } +/* 상태 3중 인코딩: 라벨 앞 상태 dot(도형+색) + 값 색 + 텍스트 — 상단 스트립 없이 */ +.kpi .kpi-lbl { display: flex; align-items: center; gap: 7px; color: var(--ink-2); font-size: .72rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; } +.kpi .kpi-lbl::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--normal); flex: none; } +.kpi .kpi-val { font-size: clamp(1.6rem, 2.8vw, 2.15rem); font-weight: 800; line-height: 1.05; letter-spacing: -.025em; font-variant-numeric: tabular-nums; } .kpi .kpi-sub { color: var(--ink-3); font-size: .72rem; font-variant-numeric: tabular-nums; } -.kpi.ok::before { background: var(--normal); } -.kpi.warn::before { background: var(--warn); } -.kpi.err::before { background: var(--leak); } -.kpi.ok .kpi-val { color: var(--normal-ink); } +.kpi.warn .kpi-lbl::before { background: var(--warn); } +.kpi.err .kpi-lbl::before { background: var(--leak); } +.kpi.ok .kpi-val { color: var(--ink); } .kpi.warn .kpi-val { color: var(--warn-ink); } .kpi.err .kpi-val { color: var(--leak-ink); }