feat(system,ui): message-template admin (V48) + empty-table demo seed (V49) + Nifty design/token alignment & public card visuals
- system/message: sys_message template CRUD + {key} render API (ADMIN-gated, render for authed)
- V48: sys_message table + 36 seeded templates (9 codes x ko/en/zh/ja), idempotent upsert
- V49: backfill 12 empty domain tables (render_job, cms_media, logistics_*, mail_log,
edm_followup, webhook_*, login_history, sys_role_menu, audit_log); idempotent guards.
followup ON CONFLICT targets business key (event_id, lead_id) to skip pre-seeded rows
- frontend: Nifty token/typography sweep (--fs-*/--fw-*), public e-card 3:4 media + cover fit,
footer copy update across ko/en/zh/ja
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3077cb04f5
commit
276293ebe7
@ -82,6 +82,8 @@ GUARDiA 표준 프레임워크(Spring Boot 3.5 + React 19 + MyBatis + PostgreSQL
|
|||||||
| 2026-07-11 | 구현 하네스 초기 구성 — 전문 에이전트 6종 + kintex-impl-orchestrator + 구현 백로그 | 전체 | 범용 에이전트만 존재 → 스택 확정 후 실제 구현 조율 팀 구성 |
|
| 2026-07-11 | 구현 하네스 초기 구성 — 전문 에이전트 6종 + kintex-impl-orchestrator + 구현 백로그 | 전체 | 범용 에이전트만 존재 → 스택 확정 후 실제 구현 조율 팀 구성 |
|
||||||
| 2026-07-11 | **v2.0 재구성** — 자동전시시스템 확장(PLANNING v2.0). 신규 에이전트 11종(아키텍트 5·공통 1·도메인 5·AI 1) + 오케스트레이터·백로그 v2.0(Phase A 아키텍처→B 공통레이어→C 부스코어→D 도메인→E 배포) | 전체 | 스코프 확장(전시 전기능·경영분석·CMS·관리자·역할분리·공사 옥션·WISE 공통레이어·AI Claude 전환) |
|
| 2026-07-11 | **v2.0 재구성** — 자동전시시스템 확장(PLANNING v2.0). 신규 에이전트 11종(아키텍트 5·공통 1·도메인 5·AI 1) + 오케스트레이터·백로그 v2.0(Phase A 아키텍처→B 공통레이어→C 부스코어→D 도메인→E 배포) | 전체 | 스코프 확장(전시 전기능·경영분석·CMS·관리자·역할분리·공사 옥션·WISE 공통레이어·AI Claude 전환) |
|
||||||
| 2026-07-11 | WISE 웹 기능 레퍼런스 강화 — kintex-frontend-dev에 uiws frontend(pages 공통 업무기능) 차용 원칙, 오케스트레이터에 웹 기능 화면 WISE 패턴·Stitch 디자인 경유·모바일 경계 명시 + 로스터에 kintex-mobile-dev(경계) 추가 | kintex-frontend-dev·kintex-impl-orchestrator | "웹도 wise 기능 참고" 요청 |
|
| 2026-07-11 | WISE 웹 기능 레퍼런스 강화 — kintex-frontend-dev에 uiws frontend(pages 공통 업무기능) 차용 원칙, 오케스트레이터에 웹 기능 화면 WISE 패턴·Stitch 디자인 경유·모바일 경계 명시 + 로스터에 kintex-mobile-dev(경계) 추가 | kintex-frontend-dev·kintex-impl-orchestrator | "웹도 wise 기능 참고" 요청 |
|
||||||
|
| 2026-07-12 | **세션 대량 구현·배포** — visitor 메인(AI 관람 도우미 홈·기능타일·연월 브리핑, 근거=크롤 적재 DB)·3-트랙 관문/서브홈·역할별 랜딩+메뉴 게이트(plan_role_routing)·공개 AI/캘린더 API(V43)·정산 데이터 정렬(V47)·포스터 이미지 빌드내장(V46)·성능 인덱스(V44)·아바타 API(V45). AI 토큰최소화 기획(PLANNING v3.4 §8A)·데이터표준(FK최소화·공통코드·view/mview·배치, data.md)·Open SSO+HR 연동 설계(sso-hr-integration.md). 배포 커밋 214b6df→3077cb0, health 게이트 통과 | 전체 | 소유자 라이브 피드백 연속 반영. **전 지시 로그: `docs/OWNER_FEEDBACK.md`(권위)** |
|
||||||
|
| 2026-07-12 | **선행 게이트 해소·검증 교훈** — G1 나노바나나 Gemini 라이브·G2 kintex.zioinfo.co.kr:8021 CI/CD 라이브. 배포 전 필수: **Flyway 마이그레이션 라이브 dry-run(BEGIN…ROLLBACK)**·시크릿 fail-fast 프로파일 확인·파일단위 커밋(공유 트리 교차 방지)·health 게이트. Stitch 불안정 시 design.md 스펙 직접 구현(문서화 폴백) | 전체·kintex-devops-dev | 다수 배포 롤백/캐시/교차커밋 사고 후 표준화 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -95,6 +97,7 @@ GUARDiA 표준 프레임워크(Spring Boot 3.5 + React 19 + MyBatis + PostgreSQL
|
|||||||
| 날짜 | 변경 내용 | 대상 | 사유 |
|
| 날짜 | 변경 내용 | 대상 | 사유 |
|
||||||
|------|----------|------|------|
|
|------|----------|------|------|
|
||||||
| 2026-07-12 | 초기 구성(analyst·crawler 에이전트 + 오케스트레이터) | 전체 | "크롤링/벤치마킹 하네스 생성" 요청 — COEX 3-트랙 재구성·행사 크롤 정례화 |
|
| 2026-07-12 | 초기 구성(analyst·crawler 에이전트 + 오케스트레이터) | 전체 | "크롤링/벤치마킹 하네스 생성" 요청 — COEX 3-트랙 재구성·행사 크롤 정례화 |
|
||||||
|
| 2026-07-12 | **모바일 앱 벤치마킹**(전시·공연 앱 다운로드·평점 상위순) → `docs/analysis/mobile-benchmark-exhibition-performance.md` + 백로그 12항목. 핵심: 다운로드↔만족도 상반(티켓팅 빅3 저평점) → MMCA·Eventbrite·DICE·Fever 롤모델. **관람객 정보 크롤→DB 적재**(V43 visitor_guide·transport, 포스터 34장 V46) | kintex-benchmark-analyst·kintex-crawler-dev | "모바일은 전시·공연 앱 벤치마킹 다운로드·좋아요순" + "크롤링해서 db 저장" |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -108,6 +111,7 @@ GUARDiA 표준 프레임워크(Spring Boot 3.5 + React 19 + MyBatis + PostgreSQL
|
|||||||
| 날짜 | 변경 내용 | 대상 | 사유 |
|
| 날짜 | 변경 내용 | 대상 | 사유 |
|
||||||
|------|----------|------|------|
|
|------|----------|------|------|
|
||||||
| 2026-07-12 | 초기 구성(kintex-testdata-dev 신규 + wise-ui/menu-ia/qa 재사용 + 오케스트레이터) | 전체 | 소유자 지시 — 상세→메인 복귀 부재·전면 리뉴얼·테스트 데이터/공통코드/프로그램 채움 |
|
| 2026-07-12 | 초기 구성(kintex-testdata-dev 신규 + wise-ui/menu-ia/qa 재사용 + 오케스트레이터) | 전체 | 소유자 지시 — 상세→메인 복귀 부재·전면 리뉴얼·테스트 데이터/공통코드/프로그램 채움 |
|
||||||
|
| 2026-07-12 | **코엑스풍 공개사이트 리뉴얼**(design.md v2.4 §3C-V 비주얼·모션 — 시네마틱 히어로·스크롤 리빌·카운트업·포스터 카드 리프트/줌·오토스크롤, prefers-reduced-motion·CLS 0) + **행사스코프 데이터 정렬**(V47 e-2026-live 폐루프·V49 잔여 보강). ★교훈: 화면이 비는 진짜 원인=시드가 데모 해소행사(workspaces[0]=start_date 최소)에 안 묶임 | kintex-frontend-dev·kintex-testdata-dev·designer | "코엑스처럼 지금 착수"·"정산 데이터 없음"·"모든 테이블 데이터" |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -122,6 +126,7 @@ GUARDiA 표준 프레임워크(Spring Boot 3.5 + React 19 + MyBatis + PostgreSQL
|
|||||||
|------|----------|------|------|
|
|------|----------|------|------|
|
||||||
| 2026-07-12 | 초기 구성(에이전트 2 신규 + kintex-qa 재사용 + 오케스트레이터) | 전체 | 소유자 강한 피드백("전부 WISE대로 안 되어 있다" — 시스템관리 메뉴 실종·햄버거/아코디언 부재·캘린더·대시보드·로고) |
|
| 2026-07-12 | 초기 구성(에이전트 2 신규 + kintex-qa 재사용 + 오케스트레이터) | 전체 | 소유자 강한 피드백("전부 WISE대로 안 되어 있다" — 시스템관리 메뉴 실종·햄버거/아코디언 부재·캘린더·대시보드·로고) |
|
||||||
| 2026-07-12 | 메뉴 IA 전담 추가 — kintex-menu-ia-dev + kintex-menu-recompose 스킬(표준 카테고리 v1·라우트↔메뉴 정합 절차), 오케스트레이터 Phase 2.5 편입 | agents·skills | "카테고리별 메뉴 재구성 하네스" 요청 — 별도 오케스트레이터 대신 중복 회피 확장 |
|
| 2026-07-12 | 메뉴 IA 전담 추가 — kintex-menu-ia-dev + kintex-menu-recompose 스킬(표준 카테고리 v1·라우트↔메뉴 정합 절차), 오케스트레이터 Phase 2.5 편입 | agents·skills | "카테고리별 메뉴 재구성 하네스" 요청 — 별도 오케스트레이터 대신 중복 회피 확장 |
|
||||||
|
| 2026-07-12 | **Nifty 디자인 시스템 전면 정렬** — 카드 Nifty 타입(`.kx-card` subtle 그림자·hover·`--flush`/`__media`/`__header`/`__body`/`__footer` 구조)·타이포(`--fs-micro`/`--fs-nano`·`--fw-*` 토큰·공용 `.kx-page__title`/`.kx-section__title`·font-size 179+weight 415 토큰화)·그리드(`.kx-table` Nifty Advanced header로 6화면 수렴). **캘린더 Nifty**(옅은 격자·연노랑 today·소프트 이벤트칩)·**파란버튼 흰글자**(`--color-on-accent` 다크대응)·favicon 정정. 기준: `docs/DESIGN_SYSTEM_NIFTY.md`·`_workspace/audit_typography_grid.md` | kintex-frontend-dev·kintex-qa | 소유자 반복 강피드백("Nifty 카드/그리드/폰트 안 맞음"·"파란버튼 흰글자"·"달력 Nifty") |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -138,3 +143,4 @@ GUARDiA 표준 프레임워크(Spring Boot 3.5 + React 19 + MyBatis + PostgreSQL
|
|||||||
|------|----------|------|------|
|
|------|----------|------|------|
|
||||||
| 2026-07-11 | 초기 구성 — kintex-mobile-dev 신규 + 오케스트레이터(재사용: designer·backend-dev·qa·devops-dev·reviewer). WISE 모바일 레퍼런스·Stitch 디자인 경유 반영 | 전체 | 모바일 앱 트랙 전담 하네스 부재("하네스 생성" + "wise 모바일 참고" + "디자인은 스티치" 요청) |
|
| 2026-07-11 | 초기 구성 — kintex-mobile-dev 신규 + 오케스트레이터(재사용: designer·backend-dev·qa·devops-dev·reviewer). WISE 모바일 레퍼런스·Stitch 디자인 경유 반영 | 전체 | 모바일 앱 트랙 전담 하네스 부재("하네스 생성" + "wise 모바일 참고" + "디자인은 스티치" 요청) |
|
||||||
| 2026-07-11 | **앱 타깃 2개 확정 반영** — 코드베이스 1(mobile/) + 배포 타깃 2(①운영 B2B: 2FA 필수·사내 QR ②관람객 B2C: 스토어 공개·간편가입·게스트). 계정은 단일 통합+가입 트랙 분리(PLANNING v3.1) | kintex-mobile-dev·오케스트레이터 | 소유자 확정 — 회원가입 관람객 포함 질의 → 하이브리드(계정 통합·앱 분리) 채택 |
|
| 2026-07-11 | **앱 타깃 2개 확정 반영** — 코드베이스 1(mobile/) + 배포 타깃 2(①운영 B2B: 2FA 필수·사내 QR ②관람객 B2C: 스토어 공개·간편가입·게스트). 계정은 단일 통합+가입 트랙 분리(PLANNING v3.1) | kintex-mobile-dev·오케스트레이터 | 소유자 확정 — 회원가입 관람객 포함 질의 → 하이브리드(계정 통합·앱 분리) 채택 |
|
||||||
|
| 2026-07-12 | **내정보(WISE)+생체인식(expo-local-authentication)+프로필 사진(expo-image-picker)** + **앱 위변조 방지·시큐어코딩 보안 체크리스트**(루트/탈옥·무결성·Hermes+R8·화면캡처·cleartext·권한최소, `docs/security/mobile-security-*.md`) + **다국어(react-i18next)·역할별 랜딩 패리티** 착수 | kintex-mobile-dev·kintex-qa | "모바일 내정보 WISE+생체+사진"·"앱 위변조방지·시큐어코딩·보안체크"·"모바일도 동일 로직"·"웹 4개국어인데 모바일은?" |
|
||||||
|
|||||||
184
docs/OWNER_FEEDBACK.md
Normal file
184
docs/OWNER_FEEDBACK.md
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# 소유자 피드백·지시 로그 (KINTEX AI 전시·행사시스템)
|
||||||
|
|
||||||
|
> 이번 세션에서 소유자가 지시한 모든 항목을 전수 기록한다. 상태: ✅완료(배포) · 🚚배포중 · ⏳작업중 · 📋대기.
|
||||||
|
> 이 파일을 기준으로 누락 없이 처리한다. 새 지시는 여기에 추가한다.
|
||||||
|
> 최종 갱신: 2026-07-12
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 디자인 시스템 (Nifty / WISE) — 최우선 반복 지시
|
||||||
|
|
||||||
|
| # | 지시 | 상태 | 비고 |
|
||||||
|
|---|------|------|------|
|
||||||
|
| 1.1 | **Nifty 카드 타입** 적용 (https://preview.themeon.net/nifty/ui-elements/cards/) — 라운딩·그림자·헤더/바디/푸터 구조·보더 톤 | 📋대기 | `.kxp-ecard`는 8px 라운딩 있으나 Nifty 카드 구조 전면 정렬 필요. 다음 패스 |
|
||||||
|
| 1.2 | **그리드는 Nifty Advanced table headers**로 통일 (tables/static-tables) | ⏳작업중 | 정본 `.kx-table` 존재, 미준수 6화면 수렴 (감사완료) |
|
||||||
|
| 1.3 | **Tabulator 기능** 추가 (tables/tabulator — 정렬·필터·페이지·CSV) | 📋대기 | task #32 |
|
||||||
|
| 1.4 | **상세페이지 = Nifty blog** 스타일 (blog-apps/blog) | 📋대기 | task #33 |
|
||||||
|
| 1.5 | **버튼 = Nifty buttons**, **Dropdowns**, **컴포넌트**, **List Group**, **Typography/Modals/Offcanvas** = ui-elements 전체 채택 | ⏳부분 | Offcanvas 완료, 나머지 정렬 진행 |
|
||||||
|
| 1.6 | **Nifty 스타일 학습 md 생성** | ✅완료 | `docs/DESIGN_SYSTEM_NIFTY.md`·`docs/analysis/nifty-design-refs.md` |
|
||||||
|
| 1.7 | **아이콘은 선(line/stroke) SVG**로 직접 (이모지 금지) | ✅원칙 | 전 신규화면 준수 |
|
||||||
|
| 1.8 | **UI는 WISE(UIWS) 문자 그대로** — 셸·메뉴·캘린더 자체 재해석 금지 | ✅원칙 | 메모리 [[ui-follow-wise-strictly]] |
|
||||||
|
| 1.9 | **폰트를 페이지마다 안 맞춤** — 전 화면 타이포 일관화 | ⏳작업중 | 감사완료(하드코딩 262건/36파일). `--fs-micro`·공용 `.kx-page__title`·weight 토큰 신설로 정렬. 다음 패스 |
|
||||||
|
| 1.10 | **모든 경계선 엷은 회색** | ⏳부분 | 구조 보더는 neutral-200(#e4e7ec) 사용 중. 의미색·hover는 유지, 지정화면 정렬 |
|
||||||
|
| 1.11 | **좌우 2단 폭 50:50**, 전 화면 **공백 없는 반응형**(풀블리드) | ✅원칙 | task #39 스윕 대기 |
|
||||||
|
| 1.12 | **top 설정 아이콘** 추가 + **설정 레이아웃 커스터마이저**(offcanvas 테마/레이아웃/색상) | ⏳부분 | 설정 아이콘 완료, 커스터마이저 task #43 |
|
||||||
|
|
||||||
|
## 2. 캘린더
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 2.1 | 캘린더를 **Nifty app-views/calendar**처럼 (옅은 회색 격자·연한 today·가벼운 이벤트 칩) | 🚚배포중 | 큰 캘린더 재스타일 완료(격자 neutral-100·today 연노랑·소프트 칩), 배포 중 |
|
||||||
|
| 2.2 | **공휴일 붉은색 + 일자 옆 공휴일명** (2050년까지 데이터) | 🚚배포중 | 큰 캘린더+미니 달력 배선. 7월은 공휴일 없음(8/15·9월 추석 표시) |
|
||||||
|
| 2.3 | **달력 경계선 모두 회색** | 🚚배포중 | 미니 달력 셀 회색 테두리 추가 |
|
||||||
|
| 2.4 | 일정 **월/주/일** 뷰 (WISE CalendarView) | ✅완료 |
|
||||||
|
| 2.5 | 전시 일정 50:50 비율·달력 날짜 위로(하단 공백 제거) | ✅완료 |
|
||||||
|
|
||||||
|
## 3. 공개사이트 / 메인 / visitor
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 3.1 | **첫 화면 = 제품 소개** (미인증 루트는 히어로 랜딩, 로그인 폼만 노출 금지) | ✅완료 | 메모리 [[product-identity-first]] |
|
||||||
|
| 3.2 | 제품명 **'KINTEX AI 전시·행사시스템'** | ✅완료 |
|
||||||
|
| 3.3 | **visitor 메인 = 세련된 홈페이지** (AI 관람 도우미 중심) | 🚚배포중 | AiAssistant·기능타일·연월 브리핑·쇼케이스 구현 |
|
||||||
|
| 3.4 | 메인에 **AI 기능 전면 노출** (AI가 뭘 하는지 한눈에) | 🚚배포중 | AI 기능 쇼케이스 6타일 |
|
||||||
|
| 3.5 | AI가 답하는 정보는 **크롤링해서 DB 저장** (실시간 외부호출 X) | ✅완료 | V43 visitor_guide·transport, 공개 AI API 근거응답 |
|
||||||
|
| 3.6 | **AI는 전시·행사정보 학습** (근거 기반) | ✅완료 | grounding + 인용, 환각 차단 |
|
||||||
|
| 3.7 | **AI가 연간·월간 전시·행사 기획정보 제시** | 🚚배포중 | AiPlanningBriefing(연/월 토글) |
|
||||||
|
| 3.8 | 비지터가 **가장 알고 싶은 정보를 AI로 쉽게** | ✅설계 | 관람 도우미 예시칩·구조화 카드 |
|
||||||
|
| 3.9 | 코엑스 분석 → **visitor/business/agency 3-트랙** 분리 | ✅완료 | 관문 + 3 서브홈 + TrackSwitcher |
|
||||||
|
| 3.10 | **"코엑스처럼" 전면 리뉴얼** (히어로 배경·애니메이션·비주얼) | 🚚배포중 | design.md v2.4 §3C-V, 코엑스풍 비주얼·모션 구현 |
|
||||||
|
| 3.11 | 메인 카드가 **밋밋한 파란 placeholder** (포스터 이미지 없음) | ✅완료 | V46 실제 포스터 이미지로 교체(배포됨) |
|
||||||
|
| 3.12 | **메인 카드 이미지 크기 안 맞음**(세로 포스터가 16:11 가로 프레임에 늘어남/잘림) | ⏳수정됨 | 포스터 실측 세로 0.67~0.8 → 카드 미디어 3:4 프레임 + `.kxp-ecard__poster` `object-fit:cover`(왜곡 제거). 다음 배포 |
|
||||||
|
| 3.13 | **메인 히어로 이미지 5장 회전(슬라이드)** | ⏳착수 | 크롤러가 KINTEX 전시장/시설 히어로 이미지 5장 `public/media/hero/` 확보 → 프론트 히어로 회전 UI(배포 후) |
|
||||||
|
|
||||||
|
## 4. 역할 · 네비게이션
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 4.1 | **로그인 사용자 구분으로 메인페이지 + 메뉴 그룹 결정** (디폴트 visitor, 로그인 후 business/admin/agency) | 🚚배포중 | plan_role_routing 구현(admin→/admin·agency→/contractor·visitor→/visitor·ops/business→/home) + 역할별 메뉴 게이트 |
|
||||||
|
| 4.2 | **각 트랙 메인페이지 Stitch 디자인 의뢰** | ✅부분 | Stitch 2회 실패 → design.md 스펙 직접 구현(문서화 폴백) |
|
||||||
|
| 4.3 | **모바일 앱도 동일 로직** | 📋대기 | 웹 완료 후 모바일 반영 |
|
||||||
|
| 4.4 | **상세→메인 복귀·브레드크럼·404** 내비게이션 | ⏳ | renewal 하네스 |
|
||||||
|
|
||||||
|
## 5. 데이터 / 시드
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 5.1 | **모든 테이블에 데이터** (50~100건) | ✅완료 | V42 대량시드(40테이블 2,535행) |
|
||||||
|
| 5.2 | **정산·결제 데이터 없음** — 행사스코프 정렬 | 🚚배포중 | V47: 데모 해소행사 `e-2026-live`에 정산 폐루프+옥션+관람객+리드+캠페인 |
|
||||||
|
| 5.3 | 테스트 데이터 **더 현실적으로** | ✅완료 | V39·V42 실감형 |
|
||||||
|
| 5.4 | 행사정보 **크롤링해서 데이터 넣기** | ✅완료 | 크롤 시드 |
|
||||||
|
| 5.5 | **연간·월간 전시 기획정보**도 적재 | ✅완료 | V43 event 생성열·v_event_calendar 뷰 |
|
||||||
|
| 5.6 | 포스터 이미지 **다 다운받아 빌드 내장** | 🚚배포중 | V46 34장 `/media/posters/` |
|
||||||
|
|
||||||
|
## 6. 정산·도메인 화면
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 6.1 | **정산·결제 패딩 없음** | 🚚배포중 | `.kx-settle` 패딩 추가 |
|
||||||
|
| 6.2 | **참가업체 관리가 홈으로 감** — 전용 화면 신설 | 📋대기 | task #41 |
|
||||||
|
| 6.3 | 부서 관리 = **WISE 조직도** | ✅완료 |
|
||||||
|
| 6.4 | 결재관리 **반려·재상신·결재선** (WISE) | ✅완료 |
|
||||||
|
| 6.5 | 통합검색에 **행사·전시 포함** | ✅완료 |
|
||||||
|
| 6.6 | 시스템관리 **메시지 관리**({} 플레이스홀더+샘플) | 📋대기 | task #35 |
|
||||||
|
| 6.7 | 물류허브·서류/마일스톤·CMS·일정 = WISE | ✅완료 |
|
||||||
|
| 6.8 | **그룹권한(역할↔메뉴) 메뉴** 존재 확인 | ✅확인 | RoleAdminPage + RoleMenuAdminPage |
|
||||||
|
|
||||||
|
## 7. 버튼 · 색상 · 대비
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 7.1 | **파란 배경 버튼 = 흰 글자** | ✅완료 | `--color-on-accent`(다크에서도 흰색). 라이브 반영(캐시 새로고침 필요) |
|
||||||
|
| 7.2 | 다크모드 색상배경 위 **흰 글자 어두워지는 버그** 전수 수정 | ✅완료 | 77곳 on-accent. +통계밴드 2곳 추가수정(배포중) |
|
||||||
|
| 7.3 | 회색 버튼은 옅은 ghost — 흰 글자 아님(솔리드 진회색만 흰글자) | ✅확인 |
|
||||||
|
|
||||||
|
## 8. 파비콘 · 브랜드
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 8.1 | **KINTEX favicon** 추가 (홈페이지 크롤) | ✅완료 | 리포 favicon.ico가 톰캣 아이콘이던 것 규명→KINTEX .ico 재생성(v3) |
|
||||||
|
| 8.2 | **브랜드 밑에 영어 병기** | ✅완료 | "AI Exhibition & Event System" |
|
||||||
|
|
||||||
|
## 9. 모바일
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 9.1 | **내정보 (WISE 참조) + 생체인식 + 사진등록** | ✅완료 | app/profile, expo-local-authentication, expo-image-picker. 아바타 API(백엔드) 완료 |
|
||||||
|
| 9.2 | **전시·공연 앱 벤치마킹** (다운로드·좋아요 상위순) | ✅완료 | docs/analysis/mobile-benchmark-exhibition-performance.md + 백로그 12항목 |
|
||||||
|
| 9.3 | **앱 위변조 방지 + 시큐어 코딩 + 보안 체크리스트 통과** | ✅완료 | 루트/탈옥·무결성·Hermes+R8·화면캡처·cleartext·권한최소. 체크리스트/감사 문서 |
|
||||||
|
| 9.4 | **다국어** — 웹 4개국어 완비, 모바일은 한국어(백로그) | ⏳ | 웹 ✅(ko/en/zh/ja), 모바일 i18n 미도입(MB-11) |
|
||||||
|
|
||||||
|
## 10. AI
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 10.1 | **AI 기능 쉽게 사용 + 토큰 최소화** | ✅완료 | PLANNING v3.4 §8A(결정론 라우팅·소형모델 우선·RAG축소·캐싱·집계는 SQL·측정지표) |
|
||||||
|
| 10.2 | AI 기능이 **하나도 구현 안 된 것 같다 → 구현** | ✅완료 | 공개 AI 관람 도우미 라이브(grounded=true, Claude) |
|
||||||
|
| 10.3 | 나노바나나 유료? | ✅답변 | Google Gemini 유료 |
|
||||||
|
|
||||||
|
## 11. 데이터 아키텍처 (표준)
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 11.1 | **FK 최소화, 공통코드로 관리** | ✅표준 | docs/architecture/data.md §10 (소프트참조·공통코드) |
|
||||||
|
| 11.2 | **필요한 인덱스 생성** | 🚚배포중 | V44 성능 인덱스 8건(핫패스) — 이미 배포됨 |
|
||||||
|
| 11.3 | **view/mview/function 고려** | ✅표준 | data.md §11 |
|
||||||
|
| 11.4 | **자동화 배치·프로시저 고려** | ✅표준 | data.md §13 배치 카탈로그 |
|
||||||
|
| 11.5 | **ten_id/tenant_id PK 맨 앞 복합키** | ✅원칙 | 메모리 [[tenant-id-pk-standard]] |
|
||||||
|
|
||||||
|
## 12. 인증 / SSO / HR
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 12.1 | **직원 인사(조직) 정보는 API 방식** | ✅설계 | docs/architecture/sso-hr-integration.md (HrDirectoryClient 어댑터+스냅샷) |
|
||||||
|
| 12.2 | **Open SSO 도입** | ✅설계 | Keycloak OIDC(PKCE)+SAML, 기존 JWT+2FA 공존(브로커) |
|
||||||
|
|
||||||
|
## 13. 평면도 / 기타
|
||||||
|
|
||||||
|
| # | 지시 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| 13.1 | 도면 안 열림 / AI 시각화 어디감 | ✅원인 | 403(행사 미가입) → 데모계정 멤버십 해소. DWG는 SVG캔버스+JPG 렌더(DWG 바이너리는 좌표소스) |
|
||||||
|
| 13.2 | ReRoomAI 기능 (나노바나나 image-to-image) | ⏳ | visualizer 트랙 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 미해결·대기 요약 (다음 우선 처리)
|
||||||
|
|
||||||
|
1. **Nifty 디자인 시스템 전면 정렬** — 카드(ui-elements/cards)·폰트(--fs-micro·공용 제목클래스)·그리드(.kx-table 6화면) 일괄 (1.1·1.2·1.9)
|
||||||
|
2. **참가업체 관리 전용 화면** (6.2 / task #41)
|
||||||
|
3. **메시지 관리** (6.6 / task #35)
|
||||||
|
4. **Tabulator**·**상세 Nifty blog**·**설정 커스터마이저** (1.3·1.4·1.12 / task #32·33·43)
|
||||||
|
5. **전 화면 공백없는 반응형 스윕** (1.11 / task #39)
|
||||||
|
6. **모바일 역할 랜딩·다국어** (4.3·9.4)
|
||||||
|
7. **상세→메인 내비게이션** (4.4)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 처리 로그 (내가 처리·배포한 것 — 2026-07-12 세션)
|
||||||
|
|
||||||
|
**배포 완료 (라이브):** 커밋 214b6df → 6e95ac6 → 87f310f/55e27b3 → 3077cb0
|
||||||
|
- V42 대량시드(40테이블 2,535행) · V43 관람객 가이드/연월 캘린더 뷰 · V44 성능 인덱스 8건 · V45 아바타 컬럼 · V46 포스터 로컬화(73건) · V47 e-2026-live 정산 폐루프
|
||||||
|
- 공개 AI 관람 도우미 API(grounded·Claude) · 연월 캘린더 API · 3-트랙 관문/서브홈 · 역할별 랜딩+메뉴 게이트
|
||||||
|
- 미니/큰 캘린더 공휴일 표시·회색 테두리·Nifty 톤 · 코엑스풍 공개사이트 비주얼(히어로·모션·통계밴드) · 실제 포스터 이미지
|
||||||
|
- 파란버튼 흰글자(`--color-on-accent`) · 다크모드 흰글자 77곳 · favicon(톰캣→KINTEX v3) · 2FA 방패 아이콘 · 브랜드 영문병기 · 정산 패딩
|
||||||
|
|
||||||
|
**구현 완료 (미배포 — 다음 배포 대기):**
|
||||||
|
- **Nifty 디자인 시스템 정렬**(카드 `.kx-card` Nifty 구조·`--fs-micro`/`--fw-*` 토큰·공용 제목클래스·테이블 `.kx-table` 6화면 수렴, font 179+weight 415 토큰화)
|
||||||
|
- **카드 이미지 3:4 프레임 + object-fit cover**(왜곡/잘림 제거)
|
||||||
|
- **메시지 관리 백엔드**(V48 sys_message + 렌더 API + 36샘플)
|
||||||
|
- **통계밴드 흰글자 2곳** · **푸터 "2026 © KINTEX..."** 4개국어
|
||||||
|
|
||||||
|
**병렬 진행 중:** 모바일 다국어+역할랜딩 · 잔여 데이터 보강(V49) · 산출물 문서
|
||||||
|
|
||||||
|
**설계·표준 문서 산출:** PLANNING v3.4(AI 토큰최소화 §8A) · design.md v2.4(공개 비주얼·모션) · docs/architecture/data.md(FK최소화·공통코드·view/mview·배치) · sso-hr-integration.md(Open SSO+HR) · DESIGN_SYSTEM_NIFTY.md · mobile-security-*.md · mobile-benchmark-*.md
|
||||||
|
|
||||||
|
## 산출물(문서) 상태
|
||||||
|
|
||||||
|
| 산출물 | 타이밍 | 상태 |
|
||||||
|
|--------|--------|------|
|
||||||
|
| 개발계획서 | 개발 전/중 | 📋 생성 착수(PLANNING v3.4 기반) |
|
||||||
|
| 설계서(아키텍처·ERD·화면·API) | 개발 중 | 📋 생성 착수(design.md v2.4·architecture·backend 계약 기반) |
|
||||||
|
| 사용자 지침서 | **완성+QA 후**(최종 메뉴 반영) | ⏳ UI 정렬 안정화 후 — 지금 생성 시 재작업(정책: 최종 1회) |
|
||||||
|
| 운영자 지침서 | **완성+QA 후** | ⏳ 동일 |
|
||||||
|
|
||||||
|
> 정책([[deliverables-update-policy]]): deliverables는 최초 1회 + 최종 1회. 개발계획서·설계서는 지금 생성 가능(내용 안정), 지침서는 현재 UI 정렬 파동이 끝난 뒤 최종 메뉴 기준으로 1회 생성.
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package com.zioinfo.kintex.system.message;
|
||||||
|
|
||||||
|
import com.zioinfo.kintex.auth.EventAccessGuard;
|
||||||
|
import com.zioinfo.kintex.auth.KintexPrincipal;
|
||||||
|
import com.zioinfo.kintex.common.ApiResponse;
|
||||||
|
import com.zioinfo.kintex.common.audit.Audited;
|
||||||
|
import com.zioinfo.kintex.system.SystemAccessGuard;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지 관리 API. 관리(CRUD)는 ADMIN(시스템관리 게이트), 렌더는 인증 사용자 공개.
|
||||||
|
* - GET /api/admin/messages 목록(category/locale 필터) [ADMIN]
|
||||||
|
* - GET /api/admin/messages/{code} 코드별 로케일 목록 [ADMIN]
|
||||||
|
* - POST /api/admin/messages 생성/수정(upsert) [ADMIN]
|
||||||
|
* - PUT /api/admin/messages/{code} 수정(upsert) [ADMIN]
|
||||||
|
* - DELETE /api/admin/messages/{code} 삭제(locale 옵션) [ADMIN]
|
||||||
|
* - POST /api/messages/{code}/render {params:{...}} → 치환 문자열 [인증]
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class MessageController {
|
||||||
|
|
||||||
|
private final MessageService service;
|
||||||
|
private final EventAccessGuard authGuard;
|
||||||
|
private final SystemAccessGuard adminGuard;
|
||||||
|
|
||||||
|
public MessageController(MessageService service, EventAccessGuard authGuard, SystemAccessGuard adminGuard) {
|
||||||
|
this.service = service;
|
||||||
|
this.authGuard = authGuard;
|
||||||
|
this.adminGuard = adminGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/api/admin/messages")
|
||||||
|
public ApiResponse<List<MessageDto>> list(@AuthenticationPrincipal KintexPrincipal principal,
|
||||||
|
@RequestParam(required = false) String category,
|
||||||
|
@RequestParam(required = false) String locale) {
|
||||||
|
adminGuard.requireAdmin(principal);
|
||||||
|
return ApiResponse.ok(service.list(principal.tenantId(), category, locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/api/admin/messages/{code}")
|
||||||
|
public ApiResponse<List<MessageDto>> byCode(@AuthenticationPrincipal KintexPrincipal principal,
|
||||||
|
@PathVariable String code) {
|
||||||
|
adminGuard.requireAdmin(principal);
|
||||||
|
return ApiResponse.ok(service.byCode(principal.tenantId(), code));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Audited(action = "SYS_MESSAGE_SAVE", targetType = "sys_message")
|
||||||
|
@PostMapping("/api/admin/messages")
|
||||||
|
public ApiResponse<Void> create(@AuthenticationPrincipal KintexPrincipal principal,
|
||||||
|
@Valid @RequestBody MessageDto dto) {
|
||||||
|
adminGuard.requireAdmin(principal);
|
||||||
|
service.save(principal.tenantId(), dto);
|
||||||
|
return ApiResponse.ok(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Audited(action = "SYS_MESSAGE_SAVE", targetType = "sys_message")
|
||||||
|
@PutMapping("/api/admin/messages/{code}")
|
||||||
|
public ApiResponse<Void> update(@AuthenticationPrincipal KintexPrincipal principal,
|
||||||
|
@PathVariable String code, @Valid @RequestBody MessageDto dto) {
|
||||||
|
adminGuard.requireAdmin(principal);
|
||||||
|
MessageDto merged = new MessageDto(code, dto.locale(), dto.category(), dto.title(),
|
||||||
|
dto.template(), dto.useYn(), null);
|
||||||
|
service.save(principal.tenantId(), merged);
|
||||||
|
return ApiResponse.ok(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Audited(action = "SYS_MESSAGE_DELETE", targetType = "sys_message")
|
||||||
|
@DeleteMapping("/api/admin/messages/{code}")
|
||||||
|
public ApiResponse<Void> delete(@AuthenticationPrincipal KintexPrincipal principal,
|
||||||
|
@PathVariable String code,
|
||||||
|
@RequestParam(required = false) String locale) {
|
||||||
|
adminGuard.requireAdmin(principal);
|
||||||
|
service.delete(principal.tenantId(), code, locale);
|
||||||
|
return ApiResponse.ok(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 렌더 — {params:{name:..,eventName:..}} 를 받아 template 치환 결과 반환. */
|
||||||
|
@PostMapping("/api/messages/{code}/render")
|
||||||
|
public ApiResponse<RenderResult> render(@AuthenticationPrincipal KintexPrincipal principal,
|
||||||
|
@PathVariable String code,
|
||||||
|
@RequestParam(required = false) String locale,
|
||||||
|
@RequestBody(required = false) RenderRequest body) {
|
||||||
|
authGuard.require(principal);
|
||||||
|
Map<String, Object> params = body == null || body.params() == null ? Map.of() : body.params();
|
||||||
|
String loc = (locale != null && !locale.isBlank()) ? locale
|
||||||
|
: (body != null ? body.locale() : null);
|
||||||
|
String text = service.render(principal.tenantId(), code, loc, params);
|
||||||
|
return ApiResponse.ok(new RenderResult(code, loc, text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 렌더 요청 본문 — params 는 {key}→값 매핑. locale 은 쿼리 우선, 없으면 본문. */
|
||||||
|
public record RenderRequest(String locale, Map<String, Object> params) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 렌더 결과. */
|
||||||
|
public record RenderResult(String code, String locale, String text) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.zioinfo.kintex.system.message;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지 템플릿(sys_message 이식) — 알림/이메일/통지 문구를 코드·로케일별로 관리.
|
||||||
|
* template 은 {name}·{eventName} 등 중괄호 플레이스홀더를 포함하며, 렌더 시 파라미터로 치환된다.
|
||||||
|
*/
|
||||||
|
public record MessageDto(
|
||||||
|
@NotBlank String msgCode,
|
||||||
|
String locale,
|
||||||
|
@NotBlank String category,
|
||||||
|
@NotBlank String title,
|
||||||
|
@NotBlank String template,
|
||||||
|
String useYn,
|
||||||
|
String updatedAt) {
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
package com.zioinfo.kintex.system.message;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지 템플릿 매퍼(sys_message). 필터는 null-safe(값이 없으면 조건 무시) — <script> 미사용.
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface MessageMapper {
|
||||||
|
|
||||||
|
@Select("SELECT msg_code AS \"msgCode\", locale, category, title, template, use_yn AS \"useYn\", "
|
||||||
|
+ "to_char(updated_at,'YYYY-MM-DD\"T\"HH24:MI:SS') AS \"updatedAt\" FROM sys_message "
|
||||||
|
+ "WHERE tenant_id = #{tenantId} "
|
||||||
|
+ "AND (#{category} IS NULL OR category = #{category}) "
|
||||||
|
+ "AND (#{locale} IS NULL OR locale = #{locale}) "
|
||||||
|
+ "ORDER BY category, msg_code, locale")
|
||||||
|
List<Map<String, Object>> findAll(@Param("tenantId") String tenantId,
|
||||||
|
@Param("category") String category,
|
||||||
|
@Param("locale") String locale);
|
||||||
|
|
||||||
|
/** 코드로 로케일 목록 조회(관리 상세). */
|
||||||
|
@Select("SELECT msg_code AS \"msgCode\", locale, category, title, template, use_yn AS \"useYn\", "
|
||||||
|
+ "to_char(updated_at,'YYYY-MM-DD\"T\"HH24:MI:SS') AS \"updatedAt\" FROM sys_message "
|
||||||
|
+ "WHERE tenant_id = #{tenantId} AND msg_code = #{msgCode} ORDER BY locale")
|
||||||
|
List<Map<String, Object>> findByCode(@Param("tenantId") String tenantId,
|
||||||
|
@Param("msgCode") String msgCode);
|
||||||
|
|
||||||
|
/** 렌더용 단건 조회 — 정확 로케일 우선, 없으면 ko 폴백은 서비스에서 처리. */
|
||||||
|
@Select("SELECT msg_code AS \"msgCode\", locale, category, title, template, use_yn AS \"useYn\" "
|
||||||
|
+ "FROM sys_message WHERE tenant_id = #{tenantId} AND msg_code = #{msgCode} "
|
||||||
|
+ "AND locale = #{locale} AND use_yn = 'Y'")
|
||||||
|
Map<String, Object> findOne(@Param("tenantId") String tenantId,
|
||||||
|
@Param("msgCode") String msgCode,
|
||||||
|
@Param("locale") String locale);
|
||||||
|
|
||||||
|
@Insert("INSERT INTO sys_message (tenant_id, msg_code, locale, category, title, template, use_yn) "
|
||||||
|
+ "VALUES (#{tenantId}, #{msgCode}, COALESCE(#{locale},'ko'), #{category}, #{title}, #{template}, "
|
||||||
|
+ "COALESCE(#{useYn},'Y')) "
|
||||||
|
+ "ON CONFLICT (tenant_id, msg_code, locale) DO UPDATE SET category=EXCLUDED.category, "
|
||||||
|
+ "title=EXCLUDED.title, template=EXCLUDED.template, use_yn=EXCLUDED.use_yn, updated_at=now()")
|
||||||
|
int upsert(Map<String, Object> p);
|
||||||
|
|
||||||
|
@Delete("DELETE FROM sys_message WHERE tenant_id = #{tenantId} AND msg_code = #{msgCode} "
|
||||||
|
+ "AND (#{locale} IS NULL OR locale = #{locale})")
|
||||||
|
int delete(@Param("tenantId") String tenantId,
|
||||||
|
@Param("msgCode") String msgCode,
|
||||||
|
@Param("locale") String locale);
|
||||||
|
}
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
package com.zioinfo.kintex.system.message;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지 템플릿 조회/관리 + 렌더링.
|
||||||
|
* <p>렌더: template 의 {key} 를 params[key] 로 치환한다. 파라미터가 없으면 원본 {key} 를 유지하고(안전),
|
||||||
|
* 값이 null 이면 빈 문자열로 치환한다. 알림/이메일(W10)·통지에서 {@link #render}/{@link #renderTemplate} 재사용.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class MessageService {
|
||||||
|
|
||||||
|
/** {key} — 영문/숫자/밑줄/점만 허용(중괄호 오탐 방지). */
|
||||||
|
private static final Pattern PLACEHOLDER = Pattern.compile("\\{([a-zA-Z0-9_.]+)}");
|
||||||
|
private static final String DEFAULT_TENANT = "KINTEX";
|
||||||
|
private static final String DEFAULT_LOCALE = "ko";
|
||||||
|
|
||||||
|
private final MessageMapper mapper;
|
||||||
|
|
||||||
|
public MessageService(MessageMapper mapper) {
|
||||||
|
this.mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MessageDto> list(String tenantId, String category, String locale) {
|
||||||
|
return mapper.findAll(tenant(tenantId), blankToNull(category), blankToNull(locale))
|
||||||
|
.stream().map(MessageService::toDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MessageDto> byCode(String tenantId, String msgCode) {
|
||||||
|
return mapper.findByCode(tenant(tenantId), msgCode).stream().map(MessageService::toDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(String tenantId, MessageDto dto) {
|
||||||
|
Map<String, Object> p = new HashMap<>();
|
||||||
|
p.put("tenantId", tenant(tenantId));
|
||||||
|
p.put("msgCode", dto.msgCode());
|
||||||
|
p.put("locale", blankToNull(dto.locale()));
|
||||||
|
p.put("category", dto.category());
|
||||||
|
p.put("title", dto.title());
|
||||||
|
p.put("template", dto.template());
|
||||||
|
p.put("useYn", dto.useYn());
|
||||||
|
mapper.upsert(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** locale 이 null 이면 해당 코드의 전 로케일 삭제. */
|
||||||
|
public void delete(String tenantId, String msgCode, String locale) {
|
||||||
|
mapper.delete(tenant(tenantId), msgCode, blankToNull(locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 코드+로케일 템플릿을 조회해 파라미터로 치환한 최종 문자열을 반환.
|
||||||
|
* 요청 로케일이 없으면 ko 로 폴백, 그래도 없으면 빈 문자열.
|
||||||
|
*/
|
||||||
|
public String render(String tenantId, String msgCode, String locale, Map<String, Object> params) {
|
||||||
|
String loc = (locale == null || locale.isBlank()) ? DEFAULT_LOCALE : locale;
|
||||||
|
Map<String, Object> row = mapper.findOne(tenant(tenantId), msgCode, loc);
|
||||||
|
if (row == null && !DEFAULT_LOCALE.equals(loc)) {
|
||||||
|
row = mapper.findOne(tenant(tenantId), msgCode, DEFAULT_LOCALE);
|
||||||
|
}
|
||||||
|
if (row == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return renderTemplate(String.valueOf(row.get("template")), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** template 의 {key} 를 params 로 치환(파라미터 없으면 원본 유지, null 이면 빈 문자열). */
|
||||||
|
public String renderTemplate(String template, Map<String, Object> params) {
|
||||||
|
if (template == null || template.isEmpty()) {
|
||||||
|
return template == null ? "" : template;
|
||||||
|
}
|
||||||
|
Map<String, Object> safe = params == null ? Map.of() : params;
|
||||||
|
Matcher m = PLACEHOLDER.matcher(template);
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
while (m.find()) {
|
||||||
|
String key = m.group(1);
|
||||||
|
String replacement;
|
||||||
|
if (safe.containsKey(key)) {
|
||||||
|
Object v = safe.get(key);
|
||||||
|
replacement = v == null ? "" : String.valueOf(v);
|
||||||
|
} else {
|
||||||
|
replacement = m.group(0); // 원본 {key} 유지
|
||||||
|
}
|
||||||
|
m.appendReplacement(sb, Matcher.quoteReplacement(replacement));
|
||||||
|
}
|
||||||
|
m.appendTail(sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String tenant(String tenantId) {
|
||||||
|
return (tenantId == null || tenantId.isBlank()) ? DEFAULT_TENANT : tenantId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String blankToNull(String s) {
|
||||||
|
return (s == null || s.isBlank()) ? null : s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MessageDto toDto(Map<String, Object> r) {
|
||||||
|
return new MessageDto(
|
||||||
|
str(r.get("msgCode")), str(r.get("locale")), str(r.get("category")),
|
||||||
|
str(r.get("title")), str(r.get("template")), str(r.get("useYn")), str(r.get("updatedAt")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String str(Object o) {
|
||||||
|
return o == null ? null : String.valueOf(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
-- V48 시스템관리 '메시지 관리' — 메시지 템플릿 리소스 + 샘플 전량 시드 (#35)
|
||||||
|
-- 목표: 알림/이메일/통지 문구를 코드·로케일별 템플릿({name}·{eventName} 등 중괄호 플레이스홀더)으로 중앙 관리.
|
||||||
|
-- 렌더 API가 template 의 {key} 를 파라미터로 치환해 최종 문자열을 만든다(코드 계층).
|
||||||
|
-- 불변: V1~V47 파일 불변. 본 마이그레이션은 순증(additive)·멱등(ON CONFLICT)만 수행한다.
|
||||||
|
-- 테넌트 표준(V31): tenant_id DEFAULT 'KINTEX', 복합 PK 선두 (tenant_id, msg_code, locale).
|
||||||
|
-- 보안 불변(§0-3): 템플릿은 문구만 저장 — 비밀번호·시크릿·PII 실값 미저장(치환 파라미터는 런타임 전달).
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 1) 테이블 — 메시지 템플릿
|
||||||
|
-- ============================================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_message (
|
||||||
|
tenant_id varchar(40) NOT NULL DEFAULT 'KINTEX',
|
||||||
|
msg_code varchar(60) NOT NULL, -- 메시지 코드(예: AUCTION_INVITE)
|
||||||
|
locale varchar(10) NOT NULL DEFAULT 'ko', -- ko/en/zh/ja
|
||||||
|
category varchar(40) NOT NULL, -- 분류(AUCTION/SETTLEMENT/ACCOUNT/VISITOR/MARKETING)
|
||||||
|
title varchar(300) NOT NULL, -- 제목/요약(플레이스홀더 포함 가능)
|
||||||
|
template text NOT NULL, -- 본문 템플릿({key} 플레이스홀더 포함)
|
||||||
|
use_yn char(1) NOT NULL DEFAULT 'Y',
|
||||||
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||||
|
PRIMARY KEY (tenant_id, msg_code, locale)
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sys_message_cat ON sys_message (tenant_id, category, msg_code);
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 2) 샘플 전량 시드 — 주요 메시지 리소스 전 카테고리 × (ko/en/zh/ja)
|
||||||
|
-- ON CONFLICT DO UPDATE 로 멱등. 플레이스홀더는 중괄호 {key}.
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO sys_message (tenant_id, msg_code, locale, category, title, template) VALUES
|
||||||
|
-- AUCTION: 옥션(입찰) 통지
|
||||||
|
('KINTEX','AUCTION_INVITE','ko','AUCTION','[{eventName}] 장치공사 입찰 안내',
|
||||||
|
'{companyName} 담당자님, {eventName} 부스({boothNo}) 장치공사 입찰에 초대합니다. 마감일: {dueDate}. 킨텍스 AI 전시시스템에서 견적을 제출해 주세요.'),
|
||||||
|
('KINTEX','AUCTION_INVITE','en','AUCTION','[{eventName}] Booth Construction Bid Invitation',
|
||||||
|
'Dear {companyName}, you are invited to bid for booth ({boothNo}) construction of {eventName}. Deadline: {dueDate}. Please submit your quotation on the KINTEX AI system.'),
|
||||||
|
('KINTEX','AUCTION_INVITE','zh','AUCTION','[{eventName}] 展位施工招标邀请',
|
||||||
|
'{companyName} 负责人您好,诚邀您参与 {eventName} 展位({boothNo})施工招标。截止日期:{dueDate}。请在 KINTEX AI 系统提交报价。'),
|
||||||
|
('KINTEX','AUCTION_INVITE','ja','AUCTION','[{eventName}] ブース施工入札のご案内',
|
||||||
|
'{companyName} ご担当者様、{eventName} ブース({boothNo})施工の入札にご招待します。締切: {dueDate}。KINTEX AI システムで見積をご提出ください。'),
|
||||||
|
-- AUCTION: 낙찰
|
||||||
|
('KINTEX','AUCTION_AWARD','ko','AUCTION','[{eventName}] 낙찰 안내',
|
||||||
|
'{companyName} 담당자님, {eventName} 장치공사 입찰에 낙찰되셨습니다. 낙찰 금액: {amount}원. 세부 일정은 시스템에서 확인해 주세요.'),
|
||||||
|
('KINTEX','AUCTION_AWARD','en','AUCTION','[{eventName}] Award Notice',
|
||||||
|
'Dear {companyName}, you have won the construction bid for {eventName}. Award amount: {amount} KRW. Please check the schedule on the system.'),
|
||||||
|
('KINTEX','AUCTION_AWARD','zh','AUCTION','[{eventName}] 中标通知',
|
||||||
|
'{companyName} 负责人您好,恭喜您中标 {eventName} 施工项目。中标金额:{amount} 韩元。请在系统查看详细日程。'),
|
||||||
|
('KINTEX','AUCTION_AWARD','ja','AUCTION','[{eventName}] 落札のご案内',
|
||||||
|
'{companyName} ご担当者様、{eventName} 施工入札に落札されました。落札金額: {amount}ウォン。詳細日程はシステムでご確認ください。'),
|
||||||
|
-- SETTLEMENT: 정산 청구
|
||||||
|
('KINTEX','SETTLE_INVOICE','ko','SETTLEMENT','[정산] 청구서 발행 안내',
|
||||||
|
'{companyName} 담당자님, 청구서({invoiceNo})가 발행되었습니다. 청구 금액: {amount}원, 납부 기한: {dueDate}. 감사합니다.'),
|
||||||
|
('KINTEX','SETTLE_INVOICE','en','SETTLEMENT','[Settlement] Invoice Issued',
|
||||||
|
'Dear {companyName}, invoice ({invoiceNo}) has been issued. Amount: {amount} KRW, due by {dueDate}. Thank you.'),
|
||||||
|
('KINTEX','SETTLE_INVOICE','zh','SETTLEMENT','[结算] 账单已开具',
|
||||||
|
'{companyName} 负责人您好,账单({invoiceNo})已开具。金额:{amount} 韩元,付款期限:{dueDate}。谢谢。'),
|
||||||
|
('KINTEX','SETTLE_INVOICE','ja','SETTLEMENT','[精算] 請求書発行のご案内',
|
||||||
|
'{companyName} ご担当者様、請求書({invoiceNo})が発行されました。金額: {amount}ウォン、支払期限: {dueDate}。ありがとうございます。'),
|
||||||
|
-- SETTLEMENT: 마감임박
|
||||||
|
('KINTEX','SETTLE_DUE','ko','SETTLEMENT','[정산] 납부 마감 임박 안내',
|
||||||
|
'{companyName} 담당자님, 청구서({invoiceNo})의 납부 기한이 {dueDate}로 임박했습니다. 기한 내 납부 부탁드립니다.'),
|
||||||
|
('KINTEX','SETTLE_DUE','en','SETTLEMENT','[Settlement] Payment Due Soon',
|
||||||
|
'Dear {companyName}, payment for invoice ({invoiceNo}) is due on {dueDate}. Please complete payment on time.'),
|
||||||
|
('KINTEX','SETTLE_DUE','zh','SETTLEMENT','[结算] 付款截止临近',
|
||||||
|
'{companyName} 负责人您好,账单({invoiceNo})付款期限 {dueDate} 临近,请按时付款。'),
|
||||||
|
('KINTEX','SETTLE_DUE','ja','SETTLEMENT','[精算] 支払期限が近づいています',
|
||||||
|
'{companyName} ご担当者様、請求書({invoiceNo})の支払期限 {dueDate} が近づいています。期限内のお支払をお願いします。'),
|
||||||
|
-- ACCOUNT: 환영
|
||||||
|
('KINTEX','WELCOME','ko','ACCOUNT','환영합니다, {name}님',
|
||||||
|
'{name}님, KINTEX AI 전시·행사시스템에 오신 것을 환영합니다. {eventName} 준비를 함께 시작해 보세요.'),
|
||||||
|
('KINTEX','WELCOME','en','ACCOUNT','Welcome, {name}',
|
||||||
|
'Hi {name}, welcome to the KINTEX AI Exhibition System. Let us start preparing {eventName} together.'),
|
||||||
|
('KINTEX','WELCOME','zh','ACCOUNT','欢迎您,{name}',
|
||||||
|
'{name} 您好,欢迎使用 KINTEX AI 展览系统。让我们一起开始筹备 {eventName} 吧。'),
|
||||||
|
('KINTEX','WELCOME','ja','ACCOUNT','ようこそ、{name}様',
|
||||||
|
'{name}様、KINTEX AI 展示会システムへようこそ。{eventName} の準備を一緒に始めましょう。'),
|
||||||
|
-- ACCOUNT: 비밀번호 재설정
|
||||||
|
('KINTEX','PASSWORD_RESET','ko','ACCOUNT','[보안] 비밀번호 재설정 안내',
|
||||||
|
'{name}님, 비밀번호 재설정을 요청하셨습니다. 아래 링크는 {expireMin}분간 유효합니다: {resetLink}. 본인이 아니라면 무시하세요.'),
|
||||||
|
('KINTEX','PASSWORD_RESET','en','ACCOUNT','[Security] Reset Your Password',
|
||||||
|
'Hi {name}, you requested a password reset. The link is valid for {expireMin} minutes: {resetLink}. Ignore if this was not you.'),
|
||||||
|
('KINTEX','PASSWORD_RESET','zh','ACCOUNT','[安全] 重置密码',
|
||||||
|
'{name} 您好,您申请了重置密码。链接 {expireMin} 分钟内有效:{resetLink}。若非本人操作请忽略。'),
|
||||||
|
('KINTEX','PASSWORD_RESET','ja','ACCOUNT','[セキュリティ] パスワード再設定のご案内',
|
||||||
|
'{name}様、パスワード再設定のリクエストを受け付けました。リンクは {expireMin} 分間有効です: {resetLink}。心当たりがない場合は無視してください。'),
|
||||||
|
-- VISITOR: 체크인
|
||||||
|
('KINTEX','CHECKIN','ko','VISITOR','[{eventName}] 체크인 완료',
|
||||||
|
'{name}님, {eventName} 체크인이 완료되었습니다. 관심 부스({boothNo})를 둘러보세요. 즐거운 관람 되세요.'),
|
||||||
|
('KINTEX','CHECKIN','en','VISITOR','[{eventName}] Check-in Complete',
|
||||||
|
'Hi {name}, your check-in for {eventName} is complete. Explore booth ({boothNo}). Enjoy the show.'),
|
||||||
|
('KINTEX','CHECKIN','zh','VISITOR','[{eventName}] 签到完成',
|
||||||
|
'{name} 您好,您在 {eventName} 的签到已完成。请参观展位({boothNo})。祝您观展愉快。'),
|
||||||
|
('KINTEX','CHECKIN','ja','VISITOR','[{eventName}] チェックイン完了',
|
||||||
|
'{name}様、{eventName} のチェックインが完了しました。ブース({boothNo})をご覧ください。ごゆっくりお楽しみください。'),
|
||||||
|
-- VISITOR: 배지 발급
|
||||||
|
('KINTEX','BADGE_ISSUE','ko','VISITOR','[{eventName}] 배지 발급 안내',
|
||||||
|
'{name}님, 관람 배지({badgeNo})가 발급되었습니다. 입장 시 QR 코드를 제시해 주세요.'),
|
||||||
|
('KINTEX','BADGE_ISSUE','en','VISITOR','[{eventName}] Badge Issued',
|
||||||
|
'Hi {name}, your badge ({badgeNo}) for {eventName} has been issued. Present the QR code at entry.'),
|
||||||
|
('KINTEX','BADGE_ISSUE','zh','VISITOR','[{eventName}] 参观证已发放',
|
||||||
|
'{name} 您好,您在 {eventName} 的参观证({badgeNo})已发放。入场时请出示二维码。'),
|
||||||
|
('KINTEX','BADGE_ISSUE','ja','VISITOR','[{eventName}] バッジ発行のご案内',
|
||||||
|
'{name}様、{eventName} の入場バッジ({badgeNo})が発行されました。入場時に QR コードをご提示ください。'),
|
||||||
|
-- MARKETING: EDM(홍보 메일)
|
||||||
|
('KINTEX','EDM','ko','MARKETING','[{eventName}] 사전등록 안내',
|
||||||
|
'{name}님, {eventName}이(가) {eventDate}에 열립니다. 지금 사전등록하고 다양한 혜택을 받으세요.'),
|
||||||
|
('KINTEX','EDM','en','MARKETING','[{eventName}] Pre-registration Open',
|
||||||
|
'Hi {name}, {eventName} opens on {eventDate}. Pre-register now to enjoy exclusive benefits.'),
|
||||||
|
('KINTEX','EDM','zh','MARKETING','[{eventName}] 预登记开放',
|
||||||
|
'{name} 您好,{eventName} 将于 {eventDate} 举行。立即预登记,享受专属优惠。'),
|
||||||
|
('KINTEX','EDM','ja','MARKETING','[{eventName}] 事前登録のご案内',
|
||||||
|
'{name}様、{eventName} が {eventDate} に開催されます。今すぐ事前登録して特典をお受け取りください。')
|
||||||
|
ON CONFLICT (tenant_id, msg_code, locale) DO UPDATE
|
||||||
|
SET category = EXCLUDED.category,
|
||||||
|
title = EXCLUDED.title,
|
||||||
|
template = EXCLUDED.template,
|
||||||
|
use_yn = 'Y',
|
||||||
|
updated_at = now();
|
||||||
@ -0,0 +1,220 @@
|
|||||||
|
-- ============================================================================
|
||||||
|
-- V49 — 잔여 빈 테이블 전수 보강 (화면이 쓰나 비어 있던 12개 도메인 테이블)
|
||||||
|
-- ============================================================================
|
||||||
|
-- 배경: V42 대량시드(40테이블)·V47(e-2026-live 폐루프) 이후에도, CREATE 는 되었으나
|
||||||
|
-- INSERT 가 전혀 없던(=화면에서 "빈 상태") 테이블이 다수 남아 있었다(매퍼 감사).
|
||||||
|
-- 대상(전부 매퍼/서비스가 조회):
|
||||||
|
-- render_job · cms_media · logistics_equipment_request · logistics_rental_order ·
|
||||||
|
-- logistics_inbound · mail_log · edm_followup_log(+draft campaign) ·
|
||||||
|
-- webhook_subscription · webhook_delivery · login_history · sys_role_menu · audit_log
|
||||||
|
-- 스코프: 이벤트 종속 도메인은 두 데모 행사(e-2026-live=오늘 · e-2026-smf=8월) 모두 채워
|
||||||
|
-- 행사 전환 시에도 물류/렌탈/입고/렌더/팔로업이 보이게 한다(고아 레코드 금지 — 기존 booth/lead/company/menu 참조).
|
||||||
|
-- 원칙: 멱등(ON CONFLICT DO NOTHING) · tenant_id='KINTEX' · PII 더미(홍길동·010-0000-*·*@kintex.test) ·
|
||||||
|
-- 기존 시드 불변. 서버 최신 V47, 진행 중 V48(메시지관리)과 충돌 회피 → V49 확정.
|
||||||
|
--
|
||||||
|
-- 의도적으로 비워 두는 테이블(보안·운영성):
|
||||||
|
-- error_log(운영 500 요약만 기록) · password_reset(1회용 재설정 토큰) ·
|
||||||
|
-- webhook_inbound_endpoint / webhook_inbound_event(secret_enc AES-256-GCM 봉인은
|
||||||
|
-- 앱 부팅 시더 전용 — SQL 평문 저장 금지, V35 주석 준수).
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 1) render_job — 부스별 나노바나나 렌더 결과(상태 분포: DONE·RUNNING·QUEUED·FAILED)
|
||||||
|
-- ============================================================================
|
||||||
|
-- e-2026-live 부스(booth-live-01..06) + e-2026-smf 부스(booth-smf-a102/b101..b106).
|
||||||
|
INSERT INTO render_job (id, event_id, booth_id, shot_preset, status, image_url, schema_hash, model_version, error_message, created_at, updated_at) VALUES
|
||||||
|
-- e-2026-live
|
||||||
|
('rj-live-01','e-2026-live','booth-live-01','S1','DONE','/uploads/render/rj-live-01.png','sha1-live01a','gemini-3.1-flash-image-preview',NULL, now()-interval '5 hour', now()-interval '5 hour'),
|
||||||
|
('rj-live-02','e-2026-live','booth-live-01','S3','DONE','/uploads/render/rj-live-02.png','sha1-live01b','gemini-3.1-flash-image-preview',NULL, now()-interval '5 hour', now()-interval '4 hour'),
|
||||||
|
('rj-live-03','e-2026-live','booth-live-02','S1','DONE','/uploads/render/rj-live-03.png','sha1-live02a','gemini-3.1-flash-image-preview',NULL, now()-interval '4 hour', now()-interval '3 hour'),
|
||||||
|
('rj-live-04','e-2026-live','booth-live-03','S2','RUNNING',NULL,'sha1-live03a','gemini-3.1-flash-image-preview',NULL, now()-interval '20 minute', now()-interval '2 minute'),
|
||||||
|
('rj-live-05','e-2026-live','booth-live-04','S1','QUEUED',NULL,'sha1-live04a',NULL,NULL, now()-interval '8 minute', now()-interval '8 minute'),
|
||||||
|
('rj-live-06','e-2026-live','booth-live-05','S4','FAILED',NULL,'sha1-live05a','gemini-3.1-flash-image-preview','생성 시간 초과 — 재시도 대기(요약).', now()-interval '2 hour', now()-interval '2 hour'),
|
||||||
|
('rj-live-07','e-2026-live','booth-live-06','S1','DONE','/uploads/render/rj-live-07.png','sha1-live06a','gemini-3.1-flash-image-preview',NULL, now()-interval '6 hour', now()-interval '6 hour'),
|
||||||
|
-- e-2026-smf
|
||||||
|
('rj-smf-01','e-2026-smf','booth-smf-a102','S1','DONE','/uploads/render/rj-smf-01.png','sha1-smfa102','gemini-3.1-flash-image-preview',NULL, TIMESTAMPTZ '2026-07-20 10:00+09', TIMESTAMPTZ '2026-07-20 10:03+09'),
|
||||||
|
('rj-smf-02','e-2026-smf','booth-smf-b101','S2','DONE','/uploads/render/rj-smf-02.png','sha1-smfb101','gemini-3.1-flash-image-preview',NULL, TIMESTAMPTZ '2026-07-21 11:00+09', TIMESTAMPTZ '2026-07-21 11:04+09'),
|
||||||
|
('rj-smf-03','e-2026-smf','booth-smf-b102','S1','DONE','/uploads/render/rj-smf-03.png','sha1-smfb102','gemini-3.1-flash-image-preview',NULL, TIMESTAMPTZ '2026-07-22 09:30+09', TIMESTAMPTZ '2026-07-22 09:33+09'),
|
||||||
|
('rj-smf-04','e-2026-smf','booth-smf-b103','S3','QUEUED',NULL,'sha1-smfb103',NULL,NULL, TIMESTAMPTZ '2026-07-23 14:00+09', TIMESTAMPTZ '2026-07-23 14:00+09'),
|
||||||
|
('rj-smf-05','e-2026-smf','booth-smf-b104','S5','FAILED',NULL,'sha1-smfb104','gemini-3.1-flash-image-preview','입력 평면도 해상도 부족 — 재업로드 요망(요약).', TIMESTAMPTZ '2026-07-23 15:20+09', TIMESTAMPTZ '2026-07-23 15:21+09')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 2) cms_media — 미디어 라이브러리(전역 + 행사별)
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO cms_media (id, event_id, file_name, url, content_type, size_bytes, alt_text, uploader_name, created_at) VALUES
|
||||||
|
('med-global-01', NULL, 'kintex-logo.svg', '/uploads/cms/kintex-logo.svg', 'image/svg+xml', 18240, 'KINTEX AI 전시·행사시스템 로고', '관리자', now()-interval '30 day'),
|
||||||
|
('med-global-02', NULL, 'hero-hall.jpg', '/uploads/cms/hero-hall.jpg', 'image/jpeg', 482113, '킨텍스 전시홀 메인 히어로', '관리자', now()-interval '25 day'),
|
||||||
|
('med-global-03', NULL, 'brochure-cover.png', '/uploads/cms/brochure-cover.png', 'image/png', 231544, '공식 도록 표지', '관리자', now()-interval '20 day'),
|
||||||
|
('med-live-01','e-2026-live', 'smart-auto-poster.jpg', '/uploads/cms/smart-auto-poster.jpg','image/jpeg', 356820, '스마트 물류·자동화 코리아 포스터', '홍길동', now()-interval '10 day'),
|
||||||
|
('med-live-02','e-2026-live', 'floorplan-live.png', '/uploads/cms/floorplan-live.png', 'image/png', 512900, 'e-2026-live 홀 배치도', '홍길동', now()-interval '7 day'),
|
||||||
|
('med-live-03','e-2026-live', 'sponsor-banner.jpg', '/uploads/cms/sponsor-banner.jpg', 'image/jpeg', 198340, '스폰서 배너(다이아몬드)', '홍길동', now()-interval '3 day'),
|
||||||
|
('med-smf-01','e-2026-smf', 'smf-keyvisual.jpg', '/uploads/cms/smf-keyvisual.jpg', 'image/jpeg', 421077, '스마트 팩토리 엑스포 키비주얼', '관리자', TIMESTAMPTZ '2026-07-15 10:00+09'),
|
||||||
|
('med-smf-02','e-2026-smf', 'smf-map.png', '/uploads/cms/smf-map.png', 'image/png', 488213, 'e-2026-smf 전시장 안내도', '관리자', TIMESTAMPTZ '2026-07-16 10:00+09'),
|
||||||
|
('med-smf-03','e-2026-smf', 'smf-speaker.jpg', '/uploads/cms/smf-speaker.jpg', 'image/jpeg', 167902, '기조연설 연사 프로필(더미)', '관리자', TIMESTAMPTZ '2026-07-17 10:00+09')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 3) logistics_equipment_request — 부대장비 신청(마스터 스냅샷, 상태 분포)
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO logistics_equipment_request
|
||||||
|
(id, event_id, equipment_id, equipment_name, unit_price, booth_no, quantity, use_date, days, amount, status, note, reject_reason, requested_by, decided_by, decided_at) VALUES
|
||||||
|
('ler-live-01','e-2026-live','leq-fork-25','지게차 2.5t',180000,'L-101',1, CURRENT_DATE, 1, 180000,'approved','반입일 오전 상차','', 'demo-exhibitor','demo-organizer', now()-interval '1 day'),
|
||||||
|
('ler-live-02','e-2026-live','leq-manp-01','상하차 인력', 90000,'L-102',2, CURRENT_DATE, 1, 180000,'requested','대형 장비 상하차 인력 2인','', 'demo-exhibitor',NULL,NULL),
|
||||||
|
('ler-live-03','e-2026-live','leq-lift-01','고소작업 리프트',150000,'L-103',1, CURRENT_DATE+1, 1, 150000,'done','트러스 설치 완료','', 'demo-exhibitor','demo-organizer', now()-interval '2 day'),
|
||||||
|
('ler-smf-01','e-2026-smf','leq-fork-05','지게차 5t',260000,'A-102',1, DATE '2026-08-04', 1, 260000,'approved','반입일 대형 화물 상차','', 'demo-exhibitor','demo-organizer', TIMESTAMPTZ '2026-07-28 10:00+09'),
|
||||||
|
('ler-smf-02','e-2026-smf','leq-lift-01','고소작업 리프트',150000,'B-101',1, DATE '2026-08-04', 2, 300000,'requested','2일간 사이니지 설치','', 'demo-exhibitor',NULL,NULL),
|
||||||
|
('ler-smf-03','e-2026-smf','leq-crane-5','이동식 크레인 5t',420000,'B-104',1, DATE '2026-08-05', 1, 420000,'rejected','','중량물 크레인은 안전관리계획서 선제출 필요', 'demo-exhibitor','demo-organizer', TIMESTAMPTZ '2026-07-29 14:00+09')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 4) logistics_rental_order — 렌탈 품목 주문(마스터 스냅샷, 상태 분포)
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO logistics_rental_order
|
||||||
|
(id, event_id, item_id, item_name, daily_price, booth_no, quantity, start_date, end_date, days, amount, status, note, ordered_by, decided_by, decided_at) VALUES
|
||||||
|
('lro-live-01','e-2026-live','lri-tv-55','55인치 모니터',60000,'L-101',2, CURRENT_DATE, CURRENT_DATE+2, 3, 360000,'confirmed','부스 시연용 2대','demo-exhibitor','demo-organizer', now()-interval '1 day'),
|
||||||
|
('lro-live-02','e-2026-live','lri-chair-01','상담용 의자',3000,'L-101',10, CURRENT_DATE, CURRENT_DATE+2, 3, 90000,'ordered','상담 부스 의자','demo-exhibitor',NULL,NULL),
|
||||||
|
('lro-live-03','e-2026-live','lri-info-01','인포메이션 데스크',25000,'L-102',1, CURRENT_DATE, CURRENT_DATE+2, 3, 75000,'delivered','안내 데스크 설치 완료','demo-exhibitor','demo-organizer', now()-interval '6 hour'),
|
||||||
|
('lro-smf-01','e-2026-smf','lri-table-01','접이식 테이블',8000,'A-102',5, DATE '2026-08-04', DATE '2026-08-07', 4, 160000,'confirmed','상담존 테이블','demo-exhibitor','demo-organizer', TIMESTAMPTZ '2026-07-28 11:00+09'),
|
||||||
|
('lro-smf-02','e-2026-smf','lri-spot-01','LED 스포트 조명',5000,'B-101',12, DATE '2026-08-04', DATE '2026-08-07', 4, 240000,'ordered','제품 진열 조명','demo-exhibitor',NULL,NULL),
|
||||||
|
('lro-smf-03','e-2026-smf','lri-shelf-01','진열 선반',12000,'B-103',3, DATE '2026-08-04', DATE '2026-08-07', 4, 144000,'cancelled','발주 취소(부스 설계 변경)','demo-exhibitor','demo-organizer', TIMESTAMPTZ '2026-07-30 09:00+09')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 5) logistics_inbound — 반입 화물 추적(운송장, 상태 분포)
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO logistics_inbound
|
||||||
|
(id, event_id, tracking_no, carrier, booth_no, item_desc, quantity, status, eta_date, warehouse_at, delivered_at, note, registered_by, updated_by) VALUES
|
||||||
|
('lib-live-01','e-2026-live','CJ-1000-2201','CJ대한통운','L-101','AMR 시연 장비 3종',3,'delivered_booth', CURRENT_DATE, now()-interval '8 hour', now()-interval '3 hour','부스 전달 완료','demo-exhibitor','demo-organizer'),
|
||||||
|
('lib-live-02','e-2026-live','LO-2200-3310','로젠택배','L-102','비전 검사 모듈 팔레트',1,'arrived_warehouse', CURRENT_DATE, now()-interval '2 hour', NULL,'창고 대기 — 부스 전달 예정','demo-exhibitor','demo-organizer'),
|
||||||
|
('lib-live-03','e-2026-live','HJ-3300-4420','한진택배','L-103','협동로봇 본체',2,'inbound_scheduled', CURRENT_DATE+1, NULL, NULL,'익일 입고 예정','demo-exhibitor',NULL),
|
||||||
|
('lib-smf-01','e-2026-smf','CJ-5000-1102','CJ대한통운','A-102','스마트팩토리 데모 셀',1,'registered', DATE '2026-08-03', NULL, NULL,'반입 신청 등록','demo-exhibitor',NULL),
|
||||||
|
('lib-smf-02','e-2026-smf','LO-5100-2203','로젠택배','B-101','전자 사이니지 패널 6매',6,'inbound_scheduled', DATE '2026-08-03', NULL, NULL,'개막 전일 입고','demo-exhibitor','demo-organizer')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 6) mail_log — 발송 이력(제목/마스킹 수신자만, 본문·원문 미저장)
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO mail_log (tenant_id, id, category, ref_id, subject, recipient_masked, status, detail, created_at) VALUES
|
||||||
|
('KINTEX','ml-0001','AUCTION_OPEN','AUC-LIVE-01','[킨텍스] L-101 아일랜드 부스 장치공사 옥션 초대','han***@kintex.test', 'sent','초대 공사업체 3사 발송', now()-interval '3 day'),
|
||||||
|
('KINTEX','ml-0002','AUCTION_OPEN','AUC-LIVE-02','[킨텍스] 메인 통로 전기·조명 설치 옥션 초대','del***@kintex.test', 'sent','초대 공사업체 3사 발송', now()-interval '2 day'),
|
||||||
|
('KINTEX','ml-0003','EDM','cp-live-001','[스마트 물류·자동화 코리아] 개막 안내','vis***@kintex.test', 'sent','사전등록자 5,400명 대상 발송', now()-interval '1 day'),
|
||||||
|
('KINTEX','ml-0004','EDM','cp-live-002','[VIP 초대] 바이어 상담회 안내','buy***@kintex.test', 'sent','VIP 1,200명 대상 발송 예약', now()-interval '6 hour'),
|
||||||
|
('KINTEX','ml-0005','PASSWORD_RESET',NULL,'[킨텍스] 비밀번호 재설정 안내','dem***@kintex.test','sent','재설정 링크 발송(유효 30분)', now()-interval '5 hour'),
|
||||||
|
('KINTEX','ml-0006','EDM','cp-smf-001','[스마트 팩토리 엑스포] 사전등록 오픈 안내','pre***@kintex.test','sent','사전등록 안내 발송', TIMESTAMPTZ '2026-07-18 10:00+09'),
|
||||||
|
('KINTEX','ml-0007','AUCTION_OPEN','AUC-2026-0511','[킨텍스] D-1 옥외 사이니지 설치 옥션 초대','sec***@kintex.test','failed','수신 도메인 일시 오류 — 재발송 대상', TIMESTAMPTZ '2026-07-25 14:00+09'),
|
||||||
|
('KINTEX','ml-0008','EDM','cp-smf-003','[스마트 팩토리 엑스포] 세미나 프로그램 안내','edu***@kintex.test','skipped','수신거부 목록 필터링', TIMESTAMPTZ '2026-07-27 10:00+09')
|
||||||
|
ON CONFLICT (tenant_id, id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 7) edm_followup_log(+ draft campaign) — 핫리드(score>=80) 팔로업 자동 초안 1회
|
||||||
|
-- ============================================================================
|
||||||
|
-- 리드당 초안 캠페인(draft) 1건 생성 후 followup_log 로 링크(멱등 키: UNIQUE(event_id, lead_id)).
|
||||||
|
INSERT INTO edm_campaign (id, event_id, name, status, audience, meta, open_rate, click_rate) VALUES
|
||||||
|
('cp-fu-live-001','e-2026-live','[팔로업] 스마트 물류 AMR 커스텀 제안','draft', 1, 'AI 자동 초안 · ld-live-001', '-','-'),
|
||||||
|
('cp-fu-live-002','e-2026-live','[팔로업] AI 비전 검사 모듈 파일럿 안내','draft', 1, 'AI 자동 초안 · ld-live-002', '-','-'),
|
||||||
|
('cp-fu-smf-001','e-2026-smf','[팔로업] 협동로봇 HR-A1 도입 제안','draft', 1, 'AI 자동 초안 · ld-smf-006', '-','-'),
|
||||||
|
('cp-fu-smf-002','e-2026-smf','[팔로업] 협동로봇 HR-A1 견적 안내','draft', 1, 'AI 자동 초안 · ld-smf-001', '-','-'),
|
||||||
|
('cp-fu-smf-003','e-2026-smf','[팔로업] AI 비전 검사 모듈 사례집','draft', 1, 'AI 자동 초안 · ld-smf-003', '-','-')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
INSERT INTO edm_followup_log (tenant_id, id, event_id, lead_id, campaign_id, hot_score, body_draft, created_at) VALUES
|
||||||
|
('KINTEX','fu-live-001','e-2026-live','ld-live-001','cp-fu-live-001',92,
|
||||||
|
'안녕하세요, 홍 팀장님. 스마트 물류 AMR 커스텀 제안서를 준비했습니다. 다음 주 미팅 가능하실까요?', now()-interval '3 hour'),
|
||||||
|
('KINTEX','fu-live-002','e-2026-live','ld-live-002','cp-fu-live-002',85,
|
||||||
|
'안녕하세요, 김 님. 요청하신 AI 비전 검사 모듈 견적서와 파일럿 프로그램 안내드립니다.', now()-interval '5 hour'),
|
||||||
|
('KINTEX','fu-smf-006','e-2026-smf','ld-smf-006','cp-fu-smf-001',91,
|
||||||
|
'안녕하세요, 문 팀장님. 협동로봇 HR-A1 도입 제안서를 보내드립니다.', TIMESTAMPTZ '2026-08-01 15:00+09'),
|
||||||
|
('KINTEX','fu-smf-001','e-2026-smf','ld-smf-001','cp-fu-smf-002',87,
|
||||||
|
'안녕하세요, 김 담당자님. 협동로봇 HR-A1 견적서를 준비했습니다.', TIMESTAMPTZ '2026-08-01 15:10+09'),
|
||||||
|
('KINTEX','fu-smf-003','e-2026-smf','ld-smf-003','cp-fu-smf-003',82,
|
||||||
|
'안녕하세요, 박 소장님. AI 비전 검사 모듈 도입 사례집을 보내드립니다.', TIMESTAMPTZ '2026-08-01 15:20+09')
|
||||||
|
-- 멱등 키는 업무 유니크 (event_id, lead_id) — V47/V42 가 동일 리드에 이미 초안을 시드했으면(다른 id) 건너뛴다.
|
||||||
|
-- (id PK 는 신규이므로 실충돌은 항상 (event_id, lead_id) 쪽에서 발생.)
|
||||||
|
ON CONFLICT (event_id, lead_id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 8) webhook_subscription — 아웃바운드 구독(발송 disabled 스텁)
|
||||||
|
-- ============================================================================
|
||||||
|
-- secret_hash = SHA-256(secret) hex 자리(원문 미저장·발송 disabled 이므로 검증 불요). 데모 고정 해시.
|
||||||
|
INSERT INTO webhook_subscription (tenant_id, id, event_type, callback_url, secret_hash, description, active, created_by) VALUES
|
||||||
|
('KINTEX','whs-001','lead.hot', 'https://hooks.example.test/kintex/lead-hot', '3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b','핫리드 발생 시 CRM 연동(스텁)', true, 'system-seed'),
|
||||||
|
('KINTEX','whs-002','invoice.paid', 'https://hooks.example.test/kintex/invoice-paid','5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8','청구 완납 시 회계 연동(스텁)', true, 'system-seed'),
|
||||||
|
('KINTEX','whs-003','auction.awarded','https://hooks.example.test/kintex/award', '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b','옥션 낙찰 시 계약 연동(스텁)', true, 'system-seed'),
|
||||||
|
('KINTEX','whs-004','visitor.checkin','https://hooks.example.test/kintex/checkin', 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35','현장 체크인 실시간 연동(스텁)', false, 'system-seed')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 9) webhook_delivery — 아웃바운드 발송 큐(status=disabled 스텁, 실 HTTP 콜 없음)
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO webhook_delivery (tenant_id, id, subscription_id, event_type, payload_json, status, note, created_at) VALUES
|
||||||
|
('KINTEX','whd-001','whs-001','lead.hot',
|
||||||
|
'{"eventId":"e-2026-live","leadId":"ld-live-001","score":92}'::text,'disabled','스텁 — 실발송 없음', now()-interval '3 hour'),
|
||||||
|
('KINTEX','whd-002','whs-002','invoice.paid',
|
||||||
|
'{"eventId":"e-2026-live","invoiceId":"inv-live-01","total":7187400}'::text,'disabled','스텁 — 실발송 없음', now()-interval '5 day'),
|
||||||
|
('KINTEX','whd-003','whs-003','auction.awarded',
|
||||||
|
'{"eventId":"e-2026-live","auctionId":"AUC-LIVE-01","awardId":"aw-live-01"}'::text,'disabled','스텁 — 실발송 없음', now()-interval '1 day'),
|
||||||
|
('KINTEX','whd-004','whs-001','lead.hot',
|
||||||
|
'{"eventId":"e-2026-smf","leadId":"ld-smf-006","score":91}'::text,'disabled','스텁 — 실발송 없음', TIMESTAMPTZ '2026-08-01 15:00+09')
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 10) login_history — 로그인 이력(마스킹 이메일·IP, 결과 분포)
|
||||||
|
-- ============================================================================
|
||||||
|
-- id 는 bigserial → 명시하지 않고 자동 채번. 재실행 시 중복 방지 위해 NOT EXISTS 가드.
|
||||||
|
INSERT INTO login_history (tenant_id, user_id, email_masked, result, fail_reason, ip_masked, user_agent, created_at)
|
||||||
|
SELECT * FROM (VALUES
|
||||||
|
('KINTEX','demo-organizer', 'org***@kintex.test','SUCCESS',NULL, '203.0.113.*', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126', now()-interval '2 hour'),
|
||||||
|
('KINTEX','demo-exhibitor', 'exh***@kintex.test','SUCCESS',NULL, '203.0.113.*', 'Mozilla/5.0 (Macintosh; Intel Mac OS X) Safari/17', now()-interval '5 hour'),
|
||||||
|
('KINTEX','demo-contractor','con***@kintex.test','FAIL', 'BAD_CREDENTIAL','198.51.100.*','Mozilla/5.0 (Windows NT 10.0; Win64; x64) Edge/126', now()-interval '1 day'),
|
||||||
|
('KINTEX','demo-contractor','con***@kintex.test','SUCCESS',NULL, '198.51.100.*','Mozilla/5.0 (Windows NT 10.0; Win64; x64) Edge/126', now()-interval '23 hour'),
|
||||||
|
('KINTEX','demo-visitor', 'vis***@kintex.test','SUCCESS',NULL, '203.0.113.*', 'Mozilla/5.0 (Linux; Android 14) Chrome/126 Mobile', now()-interval '40 minute'),
|
||||||
|
('KINTEX', NULL, 'unk***@kintex.test','FAIL', 'BAD_CREDENTIAL','198.51.100.*','Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/125',now()-interval '3 day'),
|
||||||
|
('KINTEX','demo-exhibitor', 'exh***@kintex.test','LOCKED', 'LOCKED', '198.51.100.*','Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126',now()-interval '2 day')
|
||||||
|
) AS v(tenant_id, user_id, email_masked, result, fail_reason, ip_masked, user_agent, created_at)
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM login_history WHERE user_agent LIKE 'Mozilla/5.0%' AND ip_masked IN ('203.0.113.*','198.51.100.*') LIMIT 1);
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 11) sys_role_menu — 역할-메뉴 권한 매핑(RBAC 조회 화면 /admin/role-menus)
|
||||||
|
-- ============================================================================
|
||||||
|
-- ADMIN: 전 메뉴 읽기/쓰기. MANAGER: 업무(m-work*) 읽기/쓰기. USER: 업무 읽기전용.
|
||||||
|
INSERT INTO sys_role_menu (role_code, menu_id, read_yn, write_yn)
|
||||||
|
SELECT 'ADMIN', id, 'Y', 'Y' FROM sys_menu
|
||||||
|
ON CONFLICT (role_code, menu_id) DO NOTHING;
|
||||||
|
|
||||||
|
INSERT INTO sys_role_menu (role_code, menu_id, read_yn, write_yn)
|
||||||
|
SELECT 'MANAGER', id, 'Y', 'Y' FROM sys_menu WHERE id LIKE 'm-work%'
|
||||||
|
ON CONFLICT (role_code, menu_id) DO NOTHING;
|
||||||
|
|
||||||
|
INSERT INTO sys_role_menu (role_code, menu_id, read_yn, write_yn)
|
||||||
|
SELECT 'USER', id, 'Y', 'N' FROM sys_menu WHERE id LIKE 'm-work%'
|
||||||
|
ON CONFLICT (role_code, menu_id) DO NOTHING;
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 12) audit_log — 감사 로그(관리 조회 화면 /admin/audit)
|
||||||
|
-- ============================================================================
|
||||||
|
-- id 는 bigserial 자동 채번. 재실행 중복 방지 위해 대표 summary 존재 여부로 가드.
|
||||||
|
INSERT INTO audit_log (actor_id, actor_name, action, target_type, target_id, event_id, summary, ruleset_version, result, ip_hint, created_at)
|
||||||
|
SELECT * FROM (VALUES
|
||||||
|
('demo-organizer','주최자(데모)','AWARD_SELECT','auction','AUC-LIVE-01','e-2026-live','옥션 낙찰 선정 — (주)한빛부스디자인(4,200,000원)', 'auction-v1.0','SUCCESS','203.0.113.*', now()-interval '1 day'),
|
||||||
|
('demo-organizer','주최자(데모)','INVOICE_ISSUE','invoice','inv-live-01','e-2026-live','청구서 발행 — (주)스마트오토메이션 7,187,400원', 'billing-v1.0','SUCCESS','203.0.113.*', now()-interval '18 day'),
|
||||||
|
('demo-organizer','주최자(데모)','PAYMENT_RECORD','invoice','inv-live-01','e-2026-live','수납 등록 — 잔금 4,312,440원', 'billing-v1.0','SUCCESS','203.0.113.*', now()-interval '5 day'),
|
||||||
|
('demo-organizer','주최자(데모)','REFUND_RECORD','invoice','inv-live-08','e-2026-live','환불 산정 — 1,320,000원(개막일 이후 50%)', 'refund-v1.0','SUCCESS','203.0.113.*', now()-interval '2 day'),
|
||||||
|
('demo-exhibitor','참가업체(데모)','LEAD_EXPORT','lead',NULL,'e-2026-live','리드 6건 내보내기(CSV)', NULL,'SUCCESS','203.0.113.*', now()-interval '4 hour'),
|
||||||
|
('demo-contractor','공사업체(데모)','BID_SUBMIT','auction','AUC-LIVE-02','e-2026-live','응찰 제출 — 3,650,000원', 'auction-v1.0','SUCCESS','198.51.100.*', now()-interval '12 hour'),
|
||||||
|
('admin','시스템관리자','ROLE_MENU_UPDATE','sys_role_menu','MANAGER','','역할-메뉴 권한 변경 — MANAGER 업무 메뉴 쓰기 허용', NULL,'SUCCESS','203.0.113.*', now()-interval '10 day'),
|
||||||
|
('demo-organizer','주최자(데모)','AWARD_SELECT','auction','AUC-2026-0210','e-2026-smf','옥션 낙찰 선정 — 세계전기시설(12,000,000원)', 'auction-v1.0','SUCCESS','203.0.113.*', TIMESTAMPTZ '2026-07-30 11:00+09')
|
||||||
|
) AS v(actor_id, actor_name, action, target_type, target_id, event_id, summary, ruleset_version, result, ip_hint, created_at)
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM audit_log WHERE action='AWARD_SELECT' AND target_id='AUC-LIVE-01');
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.zioinfo.kintex.system.message;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지 템플릿 렌더({key} 치환) 단위테스트 — DB/스프링 없이 renderTemplate 순수 로직 검증(#35).
|
||||||
|
*/
|
||||||
|
class MessageRenderTest {
|
||||||
|
|
||||||
|
private final MessageService service = new MessageService(null);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void replacesKnownPlaceholders() {
|
||||||
|
Map<String, Object> p = Map.of("name", "홍길동", "eventName", "스마트팩토리");
|
||||||
|
String out = service.renderTemplate("{name}님, {eventName}에 오신 것을 환영합니다.", p);
|
||||||
|
assertEquals("홍길동님, 스마트팩토리에 오신 것을 환영합니다.", out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void keepsMissingPlaceholderAsOriginal() {
|
||||||
|
String out = service.renderTemplate("{name}님, {eventName} 안내", Map.of("name", "김철수"));
|
||||||
|
assertEquals("김철수님, {eventName} 안내", out, "누락 파라미터는 원본 {key} 유지");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nullValueBecomesEmpty() {
|
||||||
|
Map<String, Object> p = new HashMap<>();
|
||||||
|
p.put("name", null);
|
||||||
|
String out = service.renderTemplate("[{name}] 알림", p);
|
||||||
|
assertEquals("[] 알림", out, "null 값은 빈 문자열로 치환");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nullTemplateAndParamsSafe() {
|
||||||
|
assertEquals("", service.renderTemplate(null, Map.of("a", "b")));
|
||||||
|
assertEquals("고정 문구", service.renderTemplate("고정 문구", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void ignoresNonPlaceholderBraces() {
|
||||||
|
String out = service.renderTemplate("금액 {amount} (단위: {}) 원", Map.of("amount", "1,000"));
|
||||||
|
assertEquals("금액 1,000 (단위: {}) 원", out, "빈 중괄호는 플레이스홀더로 오탐하지 않음");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -53,8 +53,8 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.kx-shell__brand-sub {
|
.kx-shell__brand-sub {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
line-height: 1.15;
|
line-height: 1.15;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -63,7 +63,7 @@
|
|||||||
}
|
}
|
||||||
.kx-shell__brand-sub--en {
|
.kx-shell__brand-sub--en {
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
color: var(--color-neutral-400, var(--color-neutral-500));
|
color: var(--color-neutral-400, var(--color-neutral-500));
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@ -84,7 +84,7 @@
|
|||||||
}
|
}
|
||||||
.kx-shell__event-name {
|
.kx-shell__event-name {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -121,8 +121,8 @@
|
|||||||
.kx-shell__nav-section {
|
.kx-shell__nav-section {
|
||||||
margin: var(--space-2) 0 2px;
|
margin: var(--space-2) 0 2px;
|
||||||
padding: 4px var(--space-4) 3px;
|
padding: 4px var(--space-4) 3px;
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
@ -148,7 +148,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
transition: background 0.15s ease, color 0.15s ease;
|
transition: background 0.15s ease, color 0.15s ease;
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: background 0.15s ease, color 0.15s ease;
|
transition: background 0.15s ease, color 0.15s ease;
|
||||||
}
|
}
|
||||||
@ -193,10 +193,10 @@
|
|||||||
.kx-shell__nav-link.is-active {
|
.kx-shell__nav-link.is-active {
|
||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-shell__nav-link--top {
|
.kx-shell__nav-link--top {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
/* 스코프 진입(button) — nav-link 와 동일 표현. */
|
/* 스코프 진입(button) — nav-link 와 동일 표현. */
|
||||||
.kx-shell__nav-link--btn {
|
.kx-shell__nav-link--btn {
|
||||||
@ -267,14 +267,14 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
.kx-shell__user-name {
|
.kx-shell__user-name {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -376,7 +376,7 @@
|
|||||||
}
|
}
|
||||||
.kx-shell__crumb-cur {
|
.kx-shell__crumb-cur {
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@ -511,12 +511,12 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-mdi__tab.is-active .kx-mdi__tab-btn {
|
.kx-mdi__tab.is-active .kx-mdi__tab-btn {
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-mdi__tab-label {
|
.kx-mdi__tab-label {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@ -71,7 +71,7 @@
|
|||||||
transform: rotate(-24deg);
|
transform: rotate(-24deg);
|
||||||
color: rgba(255, 255, 255, 0.55);
|
color: rgba(255, 255, 255, 0.55);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
||||||
@ -92,16 +92,16 @@
|
|||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-aiimg__sample {
|
.kx-aiimg__sample {
|
||||||
background: rgba(109, 74, 255, 0.9);
|
background: rgba(109, 74, 255, 0.9);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-aiimg__gen {
|
.kx-aiimg__gen {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -116,7 +116,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: var(--shadow-level2);
|
box-shadow: var(--shadow-level2);
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@
|
|||||||
background: var(--color-ai-accent-strong);
|
background: var(--color-ai-accent-strong);
|
||||||
}
|
}
|
||||||
.kx-aiimg__notice {
|
.kx-aiimg__notice {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
line-height: var(--lh-caption);
|
line-height: var(--lh-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,5 +66,5 @@
|
|||||||
border: 1px solid var(--color-ai-accent);
|
border: 1px solid var(--color-ai-accent);
|
||||||
}
|
}
|
||||||
.kx-badge__spark {
|
.kx-badge__spark {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
|
transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: rgba(16, 24, 40, 0.72);
|
background: rgba(16, 24, 40, 0.72);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@ -64,8 +64,8 @@
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: -1px;
|
letter-spacing: -1px;
|
||||||
box-shadow: var(--shadow-level2);
|
box-shadow: var(--shadow-level2);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@
|
|||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
font-size: var(--fs-h3, var(--fs-body));
|
font-size: var(--fs-h3, var(--fs-body));
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
.kx-state__title {
|
.kx-state__title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-state__desc {
|
.kx-state__desc {
|
||||||
|
|||||||
@ -130,7 +130,7 @@
|
|||||||
"contactAddress": "217-60 Kintex-ro, Ilsanseo-gu, Goyang-si, Gyeonggi-do",
|
"contactAddress": "217-60 Kintex-ro, Ilsanseo-gu, Goyang-si, Gyeonggi-do",
|
||||||
"contactTel": "Main line 1899-1001",
|
"contactTel": "Main line 1899-1001",
|
||||||
"contactEmail": "exhibition@kintex.com",
|
"contactEmail": "exhibition@kintex.com",
|
||||||
"bottom": "© KINTEX. All Rights Reserved. (10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
"bottom": "2026 © KINTEX. All Rights Reserved. (10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
||||||
},
|
},
|
||||||
"footerbar": {
|
"footerbar": {
|
||||||
"copyright": "© 2026 KINTEX. All rights reserved.",
|
"copyright": "© 2026 KINTEX. All rights reserved.",
|
||||||
|
|||||||
@ -130,7 +130,7 @@
|
|||||||
"contactAddress": "京畿道高陽市一山西区KINTEXロ217-60",
|
"contactAddress": "京畿道高陽市一山西区KINTEXロ217-60",
|
||||||
"contactTel": "代表番号 1899-1001",
|
"contactTel": "代表番号 1899-1001",
|
||||||
"contactEmail": "exhibition@kintex.com",
|
"contactEmail": "exhibition@kintex.com",
|
||||||
"bottom": "© KINTEX. All Rights Reserved. (10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
"bottom": "2026 © KINTEX. All Rights Reserved. (10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
||||||
},
|
},
|
||||||
"footerbar": {
|
"footerbar": {
|
||||||
"copyright": "© 2026 KINTEX. All rights reserved.",
|
"copyright": "© 2026 KINTEX. All rights reserved.",
|
||||||
|
|||||||
@ -130,7 +130,7 @@
|
|||||||
"contactAddress": "경기도 고양시 일산서구 킨텍스로 217-60",
|
"contactAddress": "경기도 고양시 일산서구 킨텍스로 217-60",
|
||||||
"contactTel": "대표번호 1899-1001",
|
"contactTel": "대표번호 1899-1001",
|
||||||
"contactEmail": "exhibition@kintex.com",
|
"contactEmail": "exhibition@kintex.com",
|
||||||
"bottom": "© KINTEX. All Rights Reserved. (10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
"bottom": "2026 © KINTEX. All Rights Reserved. (10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
||||||
},
|
},
|
||||||
"footerbar": {
|
"footerbar": {
|
||||||
"copyright": "© 2026 KINTEX. All rights reserved.",
|
"copyright": "© 2026 KINTEX. All rights reserved.",
|
||||||
|
|||||||
@ -130,7 +130,7 @@
|
|||||||
"contactAddress": "京畿道高阳市一山西区KINTEX路217-60",
|
"contactAddress": "京畿道高阳市一山西区KINTEX路217-60",
|
||||||
"contactTel": "总机 1899-1001",
|
"contactTel": "总机 1899-1001",
|
||||||
"contactEmail": "exhibition@kintex.com",
|
"contactEmail": "exhibition@kintex.com",
|
||||||
"bottom": "© KINTEX. 版权所有。(10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
"bottom": "2026 © KINTEX. 版权所有。(10390) 217-60, Kintex-ro, Ilsanseo-gu, Goyang-si"
|
||||||
},
|
},
|
||||||
"footerbar": {
|
"footerbar": {
|
||||||
"copyright": "© 2026 KINTEX. 版权所有。",
|
"copyright": "© 2026 KINTEX. 版权所有。",
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
.kx-adm__title {
|
.kx-adm__title {
|
||||||
font-size: var(--fs-h1);
|
font-size: var(--fs-h1);
|
||||||
line-height: var(--lh-h1);
|
line-height: var(--lh-h1);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-adm__subtitle {
|
.kx-adm__subtitle {
|
||||||
@ -34,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
.kx-adm-field__label {
|
.kx-adm-field__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-adm-field__input {
|
.kx-adm-field__input {
|
||||||
@ -60,7 +60,7 @@
|
|||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.kx-adm-pill--success { color: var(--color-success); background: #e6f4ee; }
|
.kx-adm-pill--success { color: var(--color-success); background: #e6f4ee; }
|
||||||
@ -114,7 +114,7 @@
|
|||||||
.kx-adm-audit thead th {
|
.kx-adm-audit thead th {
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
border-bottom: 2px solid var(--color-neutral-200);
|
||||||
@ -132,19 +132,19 @@
|
|||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.kx-adm-actor__body { display: flex; flex-direction: column; }
|
.kx-adm-actor__body { display: flex; flex-direction: column; }
|
||||||
.kx-adm-actor__name { font-weight: 600; color: var(--color-neutral-900); }
|
.kx-adm-actor__name { font-weight: var(--fw-semibold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-actor__id { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-actor__id { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
|
|
||||||
.kx-adm-action {
|
.kx-adm-action {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-adm-summary {
|
.kx-adm-summary {
|
||||||
@ -158,7 +158,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.kx-adm-target { display: flex; flex-direction: column; }
|
.kx-adm-target { display: flex; flex-direction: column; }
|
||||||
.kx-adm-target__type { font-weight: 600; color: var(--color-neutral-700); }
|
.kx-adm-target__type { font-weight: var(--fw-semibold); color: var(--color-neutral-700); }
|
||||||
.kx-adm-target__id { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-target__id { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
|
|
||||||
.kx-adm-pager {
|
.kx-adm-pager {
|
||||||
@ -173,7 +173,7 @@
|
|||||||
}
|
}
|
||||||
.kx-adm-pager__info { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-pager__info { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
.kx-adm-pager__nav { display: flex; align-items: center; gap: var(--space-3); }
|
.kx-adm-pager__nav { display: flex; align-items: center; gap: var(--space-3); }
|
||||||
.kx-adm-pager__page { font-size: var(--fs-body); font-weight: 600; color: var(--color-neutral-700); }
|
.kx-adm-pager__page { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--color-neutral-700); }
|
||||||
.kx-adm-pager__size {
|
.kx-adm-pager__size {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -193,7 +193,7 @@
|
|||||||
.kx-adm-group__body { flex: 1; min-width: 0; padding: var(--space-4); }
|
.kx-adm-group__body { flex: 1; min-width: 0; padding: var(--space-4); }
|
||||||
.kx-adm-group__title {
|
.kx-adm-group__title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin-bottom: var(--space-3);
|
margin-bottom: var(--space-3);
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
@ -211,25 +211,25 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
font-family: ui-monospace, 'JetBrains Mono', monospace;
|
||||||
}
|
}
|
||||||
.kx-adm-setrow__desc { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-setrow__desc { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
.kx-adm-setrow__control { display: flex; align-items: center; gap: var(--space-2); }
|
.kx-adm-setrow__control { display: flex; align-items: center; gap: var(--space-2); }
|
||||||
.kx-adm-setrow__input { flex: 1; min-width: 0; }
|
.kx-adm-setrow__input { flex: 1; min-width: 0; }
|
||||||
.kx-adm-setrow__hint { margin-top: 6px; font-size: 11px; color: var(--color-neutral-500); }
|
.kx-adm-setrow__hint { margin-top: 6px; font-size: var(--fs-micro); color: var(--color-neutral-500); }
|
||||||
.kx-adm-secret {
|
.kx-adm-secret {
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
.kx-adm-typechip {
|
.kx-adm-typechip {
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
@ -265,7 +265,7 @@
|
|||||||
.kx-adm-switch input:focus-visible + .kx-adm-switch__track { outline: 2px solid var(--color-primary-100); }
|
.kx-adm-switch input:focus-visible + .kx-adm-switch__track { outline: 2px solid var(--color-primary-100); }
|
||||||
.kx-adm-switch__label { font-size: var(--fs-caption); color: var(--color-neutral-700); }
|
.kx-adm-switch__label { font-size: var(--fs-caption); color: var(--color-neutral-700); }
|
||||||
|
|
||||||
.kx-adm-add__title { font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900); margin-bottom: var(--space-3); }
|
.kx-adm-add__title { font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900); margin-bottom: var(--space-3); }
|
||||||
.kx-adm-add__grid {
|
.kx-adm-add__grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1.4fr 1.4fr 0.8fr;
|
grid-template-columns: 1.4fr 1.4fr 0.8fr;
|
||||||
@ -286,7 +286,7 @@
|
|||||||
.kx-adm-ruleset { display: grid; grid-template-columns: 300px 1fr; gap: var(--space-4); align-items: start; }
|
.kx-adm-ruleset { display: grid; grid-template-columns: 300px 1fr; gap: var(--space-4); align-items: start; }
|
||||||
.kx-adm-ruleset__versions { display: flex; flex-direction: column; gap: var(--space-3); }
|
.kx-adm-ruleset__versions { display: flex; flex-direction: column; gap: var(--space-3); }
|
||||||
.kx-adm-ruleset__vhead { display: flex; align-items: center; justify-content: space-between; }
|
.kx-adm-ruleset__vhead { display: flex; align-items: center; justify-content: space-between; }
|
||||||
.kx-adm-ruleset__vhead h2 { font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-ruleset__vhead h2 { font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-vlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
|
.kx-adm-vlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
|
||||||
.kx-adm-vitem {
|
.kx-adm-vitem {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -317,13 +317,13 @@
|
|||||||
padding: var(--space-4);
|
padding: var(--space-4);
|
||||||
border-bottom: var(--border-card);
|
border-bottom: var(--border-card);
|
||||||
}
|
}
|
||||||
.kx-adm-ruleset__ehead h2 { font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-ruleset__ehead h2 { font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-rules { width: 100%; border-collapse: collapse; }
|
.kx-adm-rules { width: 100%; border-collapse: collapse; }
|
||||||
.kx-adm-rules th, .kx-adm-rules td { padding: 10px 12px; text-align: left; font-size: var(--fs-body); }
|
.kx-adm-rules th, .kx-adm-rules td { padding: 10px 12px; text-align: left; font-size: var(--fs-body); }
|
||||||
.kx-adm-rules thead th {
|
.kx-adm-rules thead th {
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
border-bottom: 2px solid var(--color-neutral-200);
|
||||||
@ -331,8 +331,8 @@
|
|||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
.kx-adm-rules tbody tr { border-bottom: 1px solid var(--color-neutral-200); }
|
.kx-adm-rules tbody tr { border-bottom: 1px solid var(--color-neutral-200); }
|
||||||
.kx-adm-rulename { display: block; font-weight: 600; color: var(--color-neutral-900); }
|
.kx-adm-rulename { display: block; font-weight: var(--fw-semibold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-rulecode { display: block; font-size: 11px; color: var(--color-neutral-500); font-family: ui-monospace, monospace; }
|
.kx-adm-rulecode { display: block; font-size: var(--fs-micro); color: var(--color-neutral-500); font-family: ui-monospace, monospace; }
|
||||||
.kx-adm-disclaimer { padding: var(--space-3) var(--space-4); font-size: var(--fs-caption); color: var(--color-neutral-500); border-top: var(--border-card); }
|
.kx-adm-disclaimer { padding: var(--space-3) var(--space-4); font-size: var(--fs-caption); color: var(--color-neutral-500); border-top: var(--border-card); }
|
||||||
|
|
||||||
/* ═══════════ SCR-A9 테넌트 ═══════════ */
|
/* ═══════════ SCR-A9 테넌트 ═══════════ */
|
||||||
@ -345,13 +345,13 @@
|
|||||||
padding: var(--space-4);
|
padding: var(--space-4);
|
||||||
border-bottom: var(--border-card);
|
border-bottom: var(--border-card);
|
||||||
}
|
}
|
||||||
.kx-adm-tenant__lhead h2 { font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-tenant__lhead h2 { font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-tenants { width: 100%; border-collapse: collapse; }
|
.kx-adm-tenants { width: 100%; border-collapse: collapse; }
|
||||||
.kx-adm-tenants th, .kx-adm-tenants td { padding: 10px 12px; text-align: left; font-size: var(--fs-body); }
|
.kx-adm-tenants th, .kx-adm-tenants td { padding: 10px 12px; text-align: left; font-size: var(--fs-body); }
|
||||||
.kx-adm-tenants thead th {
|
.kx-adm-tenants thead th {
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
border-bottom: 2px solid var(--color-neutral-200);
|
||||||
@ -361,10 +361,10 @@
|
|||||||
.kx-adm-tenants tbody tr { border-bottom: 1px solid var(--color-neutral-200); }
|
.kx-adm-tenants tbody tr { border-bottom: 1px solid var(--color-neutral-200); }
|
||||||
.kx-adm-tenants tbody tr:hover { background: var(--color-primary-050); }
|
.kx-adm-tenants tbody tr:hover { background: var(--color-primary-050); }
|
||||||
.kx-adm-tenants tbody tr.is-selected { background: var(--color-primary-050); }
|
.kx-adm-tenants tbody tr.is-selected { background: var(--color-primary-050); }
|
||||||
.kx-adm-tenants__name { font-weight: 600; color: var(--color-neutral-900); }
|
.kx-adm-tenants__name { font-weight: var(--fw-semibold); color: var(--color-neutral-900); }
|
||||||
|
|
||||||
.kx-adm-tenant__wizard { display: flex; flex-direction: column; gap: 4px; }
|
.kx-adm-tenant__wizard { display: flex; flex-direction: column; gap: 4px; }
|
||||||
.kx-adm-wiz__title { font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-wiz__title { font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-wiz { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; }
|
.kx-adm-wiz { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; }
|
||||||
.kx-adm-wiz__step { display: flex; gap: var(--space-3); padding-bottom: var(--space-4); position: relative; }
|
.kx-adm-wiz__step { display: flex; gap: var(--space-3); padding-bottom: var(--space-4); position: relative; }
|
||||||
.kx-adm-wiz__step:not(:last-child)::before {
|
.kx-adm-wiz__step:not(:last-child)::before {
|
||||||
@ -385,7 +385,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
@ -393,7 +393,7 @@
|
|||||||
.kx-adm-wiz__step.is-done .kx-adm-wiz__dot { background: var(--color-success); color: var(--color-on-accent); }
|
.kx-adm-wiz__step.is-done .kx-adm-wiz__dot { background: var(--color-success); color: var(--color-on-accent); }
|
||||||
.kx-adm-wiz__step.is-current .kx-adm-wiz__dot { background: var(--color-primary-600); color: var(--color-on-accent); }
|
.kx-adm-wiz__step.is-current .kx-adm-wiz__dot { background: var(--color-primary-600); color: var(--color-on-accent); }
|
||||||
.kx-adm-wiz__body { display: flex; flex-direction: column; gap: 2px; padding-top: 3px; }
|
.kx-adm-wiz__body { display: flex; flex-direction: column; gap: 2px; padding-top: 3px; }
|
||||||
.kx-adm-wiz__label { font-size: var(--fs-body); font-weight: 600; color: var(--color-neutral-900); }
|
.kx-adm-wiz__label { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-wiz__step.is-todo .kx-adm-wiz__label { color: var(--color-neutral-500); }
|
.kx-adm-wiz__step.is-todo .kx-adm-wiz__label { color: var(--color-neutral-500); }
|
||||||
.kx-adm-wiz__desc { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-wiz__desc { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
|
|
||||||
@ -422,7 +422,7 @@
|
|||||||
.kx-adm-tbl thead th {
|
.kx-adm-tbl thead th {
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
border-bottom: 2px solid var(--color-neutral-200);
|
||||||
@ -432,7 +432,7 @@
|
|||||||
.kx-adm-tbl tbody tr { border-bottom: 1px solid var(--color-neutral-200); }
|
.kx-adm-tbl tbody tr { border-bottom: 1px solid var(--color-neutral-200); }
|
||||||
.kx-adm-tbl tbody tr:hover { background: var(--color-primary-050); }
|
.kx-adm-tbl tbody tr:hover { background: var(--color-primary-050); }
|
||||||
.kx-adm-tbl tbody tr.is-selected { background: var(--color-primary-050); }
|
.kx-adm-tbl tbody tr.is-selected { background: var(--color-primary-050); }
|
||||||
.kx-adm-tbl__strong { font-weight: 600; color: var(--color-neutral-900); }
|
.kx-adm-tbl__strong { font-weight: var(--fw-semibold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-tbl__actions { display: flex; gap: var(--space-2); justify-content: flex-end; white-space: nowrap; }
|
.kx-adm-tbl__actions { display: flex; gap: var(--space-2); justify-content: flex-end; white-space: nowrap; }
|
||||||
|
|
||||||
/* 역할 칩 */
|
/* 역할 칩 */
|
||||||
@ -442,7 +442,7 @@
|
|||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-adm-rolechip--admin { color: var(--color-error); background: #fef3f2; }
|
.kx-adm-rolechip--admin { color: var(--color-error); background: #fef3f2; }
|
||||||
.kx-adm-rolechip--manager { color: var(--color-primary-700); background: var(--color-primary-100); }
|
.kx-adm-rolechip--manager { color: var(--color-primary-700); background: var(--color-primary-100); }
|
||||||
@ -475,7 +475,7 @@
|
|||||||
box-shadow: var(--shadow-modal, 0 20px 48px rgba(15, 23, 42, 0.24));
|
box-shadow: var(--shadow-modal, 0 20px 48px rgba(15, 23, 42, 0.24));
|
||||||
padding: var(--space-5, 24px);
|
padding: var(--space-5, 24px);
|
||||||
}
|
}
|
||||||
.kx-adm-modal__title { font-size: var(--fs-h2); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-modal__title { font-size: var(--fs-h2); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-modal__desc { margin-top: 4px; font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-modal__desc { margin-top: 4px; font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
.kx-adm-modal__grid {
|
.kx-adm-modal__grid {
|
||||||
margin-top: var(--space-4);
|
margin-top: var(--space-4);
|
||||||
@ -510,7 +510,7 @@
|
|||||||
}
|
}
|
||||||
.kx-adm-secnote {
|
.kx-adm-secnote {
|
||||||
margin-top: var(--space-3);
|
margin-top: var(--space-3);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,8 +535,8 @@
|
|||||||
}
|
}
|
||||||
.kx-adm-permcheck input { margin-top: 3px; }
|
.kx-adm-permcheck input { margin-top: 3px; }
|
||||||
.kx-adm-permcheck__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
.kx-adm-permcheck__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
||||||
.kx-adm-permcheck__name { font-weight: 600; color: var(--color-neutral-900); font-size: var(--fs-body); }
|
.kx-adm-permcheck__name { font-weight: var(--fw-semibold); color: var(--color-neutral-900); font-size: var(--fs-body); }
|
||||||
.kx-adm-permcheck__code { font-size: 11px; color: var(--color-neutral-500); font-family: ui-monospace, monospace; }
|
.kx-adm-permcheck__code { font-size: var(--fs-micro); color: var(--color-neutral-500); font-family: ui-monospace, monospace; }
|
||||||
.kx-adm-permcheck__desc { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-permcheck__desc { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
|
|
||||||
/* ── 공통코드 2단(그룹 → 코드) ── */
|
/* ── 공통코드 2단(그룹 → 코드) ── */
|
||||||
@ -550,7 +550,7 @@
|
|||||||
padding: var(--space-4);
|
padding: var(--space-4);
|
||||||
border-bottom: var(--border-card);
|
border-bottom: var(--border-card);
|
||||||
}
|
}
|
||||||
.kx-adm-codes__head h2 { font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-codes__head h2 { font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-glist { list-style: none; margin: 0; padding: var(--space-2); display: flex; flex-direction: column; gap: 4px; }
|
.kx-adm-glist { list-style: none; margin: 0; padding: var(--space-2); display: flex; flex-direction: column; gap: 4px; }
|
||||||
.kx-adm-gitem {
|
.kx-adm-gitem {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -567,8 +567,8 @@
|
|||||||
}
|
}
|
||||||
.kx-adm-gitem:hover { background: var(--color-neutral-050); }
|
.kx-adm-gitem:hover { background: var(--color-neutral-050); }
|
||||||
.kx-adm-gitem.is-active { border-left-color: var(--color-primary-600); background: var(--color-primary-050); }
|
.kx-adm-gitem.is-active { border-left-color: var(--color-primary-600); background: var(--color-primary-050); }
|
||||||
.kx-adm-gitem__name { font-weight: 600; color: var(--color-neutral-900); }
|
.kx-adm-gitem__name { font-weight: var(--fw-semibold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-gitem__code { font-size: 11px; color: var(--color-neutral-500); font-family: ui-monospace, monospace; }
|
.kx-adm-gitem__code { font-size: var(--fs-micro); color: var(--color-neutral-500); font-family: ui-monospace, monospace; }
|
||||||
|
|
||||||
/* ── 메뉴 트리 ── */
|
/* ── 메뉴 트리 ── */
|
||||||
.kx-adm-menu__name { display: inline-flex; align-items: center; gap: 6px; }
|
.kx-adm-menu__name { display: inline-flex; align-items: center; gap: 6px; }
|
||||||
@ -586,7 +586,7 @@
|
|||||||
max-width: 480px;
|
max-width: 480px;
|
||||||
}
|
}
|
||||||
.kx-adm-denied__icon { color: var(--color-error); }
|
.kx-adm-denied__icon { color: var(--color-error); }
|
||||||
.kx-adm-denied__title { font-size: var(--fs-h1); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-denied__title { font-size: var(--fs-h1); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-denied__desc { font-size: var(--fs-body); color: var(--color-neutral-500); }
|
.kx-adm-denied__desc { font-size: var(--fs-body); color: var(--color-neutral-500); }
|
||||||
.kx-adm-denied__code { margin-top: var(--space-3); font-size: var(--fs-caption); font-family: ui-monospace, monospace; color: var(--color-neutral-400, #94a3b8); }
|
.kx-adm-denied__code { margin-top: var(--space-3); font-size: var(--fs-caption); font-family: ui-monospace, monospace; color: var(--color-neutral-400, #94a3b8); }
|
||||||
|
|
||||||
@ -632,18 +632,18 @@
|
|||||||
.kx-adm-health-card--error { border-left-color: var(--color-error); }
|
.kx-adm-health-card--error { border-left-color: var(--color-error); }
|
||||||
.kx-adm-health-card--neutral { border-left-color: var(--color-warning); }
|
.kx-adm-health-card--neutral { border-left-color: var(--color-warning); }
|
||||||
.kx-adm-health-card__label { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-health-card__label { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
.kx-adm-health-card__value { font-size: var(--fs-h2); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-health-card__value { font-size: var(--fs-h2); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-health-card__sub { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-health-card__sub { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
.kx-adm-metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
|
.kx-adm-metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
|
||||||
.kx-adm-metric { display: flex; flex-direction: column; gap: 4px; }
|
.kx-adm-metric { display: flex; flex-direction: column; gap: 4px; }
|
||||||
.kx-adm-metric__label { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-metric__label { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
.kx-adm-metric__value { font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-adm-metric__value { font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-adm-metric__sub { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
.kx-adm-metric__sub { font-size: var(--fs-caption); color: var(--color-neutral-500); }
|
||||||
|
|
||||||
/* 폼(인증정책·설정) */
|
/* 폼(인증정책·설정) */
|
||||||
.kx-adm-form { display: grid; gap: var(--space-3); }
|
.kx-adm-form { display: grid; gap: var(--space-3); }
|
||||||
.kx-adm-form__section {
|
.kx-adm-form__section {
|
||||||
font-size: var(--fs-h3); font-weight: 700; color: var(--color-neutral-900);
|
font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--color-neutral-900);
|
||||||
margin: var(--space-2) 0 0; padding-top: var(--space-2); border-top: 1px solid var(--color-neutral-100);
|
margin: var(--space-2) 0 0; padding-top: var(--space-2); border-top: 1px solid var(--color-neutral-100);
|
||||||
}
|
}
|
||||||
.kx-adm-form__section:first-child { border-top: none; padding-top: 0; }
|
.kx-adm-form__section:first-child { border-top: none; padding-top: 0; }
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
}
|
}
|
||||||
.kx-admin__status-dot {
|
.kx-admin__status-dot {
|
||||||
@ -133,14 +133,14 @@
|
|||||||
50% { box-shadow: 0 0 0 5px rgba(217, 45, 32, 0); }
|
50% { box-shadow: 0 0 0 5px rgba(217, 45, 32, 0); }
|
||||||
}
|
}
|
||||||
.kx-livecard__state {
|
.kx-livecard__state {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-livecard__title {
|
.kx-livecard__title {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-livecard__meta {
|
.kx-livecard__meta {
|
||||||
@ -192,7 +192,7 @@
|
|||||||
}
|
}
|
||||||
.kx-slideadm__label {
|
.kx-slideadm__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-slideadm__upload input[type='file'] {
|
.kx-slideadm__upload input[type='file'] {
|
||||||
@ -233,7 +233,7 @@
|
|||||||
}
|
}
|
||||||
.kx-slideadm__count {
|
.kx-slideadm__count {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
margin-left: var(--space-2);
|
margin-left: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -292,8 +292,8 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-slideadm__live-badge {
|
.kx-slideadm__live-badge {
|
||||||
background: rgba(0, 102, 179, 0.1);
|
background: rgba(0, 102, 179, 0.1);
|
||||||
@ -313,7 +313,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.kx-slideadm__row-meta {
|
.kx-slideadm__row-meta {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,10 +134,10 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
}
|
}
|
||||||
.kx-dept-tree__row.is-selected .kx-dept-tree__name {
|
.kx-dept-tree__row.is-selected .kx-dept-tree__name {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-dept-tree__sort {
|
.kx-dept-tree__sort {
|
||||||
@ -188,7 +188,7 @@
|
|||||||
.kx-dept-detail__headMain { min-width: 0; }
|
.kx-dept-detail__headMain { min-width: 0; }
|
||||||
.kx-dept-detail__title {
|
.kx-dept-detail__title {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,7 +81,7 @@
|
|||||||
}
|
}
|
||||||
.kx-aicon__ungrounded {
|
.kx-aicon__ungrounded {
|
||||||
color: #B54708;
|
color: #B54708;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-aicon__degraded {
|
.kx-aicon__degraded {
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
@ -118,7 +118,7 @@
|
|||||||
}
|
}
|
||||||
.kx-aicon__cites-h {
|
.kx-aicon__cites-h {
|
||||||
display: block;
|
display: block;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700, #344054);
|
color: var(--color-neutral-700, #344054);
|
||||||
margin-bottom: var(--space-1, 4px);
|
margin-bottom: var(--space-1, 4px);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,7 +91,7 @@
|
|||||||
}
|
}
|
||||||
.kx-bi__global-title {
|
.kx-bi__global-title {
|
||||||
font-size: var(--fs-h3, 1.125rem);
|
font-size: var(--fs-h3, 1.125rem);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
/* 전역 섹션의 하위 split은 동일 폭 2컬럼 */
|
/* 전역 섹션의 하위 split은 동일 폭 2컬럼 */
|
||||||
|
|||||||
@ -76,12 +76,12 @@
|
|||||||
}
|
}
|
||||||
.kx-appqr__name {
|
.kx-appqr__name {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-appqr__ver {
|
.kx-appqr__ver {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
@ -145,7 +145,7 @@
|
|||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-appqr__step-text {
|
.kx-appqr__step-text {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
|
|||||||
@ -185,7 +185,7 @@ export function ManagerApprovalQueuePage() {
|
|||||||
) : rows.length === 0 ? (
|
) : rows.length === 0 ? (
|
||||||
<EmptyState title={t(`approval.empty.${tab}`)} />
|
<EmptyState title={t(`approval.empty.${tab}`)} />
|
||||||
) : (
|
) : (
|
||||||
<table className="kx-aq__table">
|
<table className="kx-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('approval.colTitle')}</th>
|
<th>{t('approval.colTitle')}</th>
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
}
|
}
|
||||||
.kx-apf__head h1 {
|
.kx-apf__head h1 {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-apf__back {
|
.kx-apf__back {
|
||||||
@ -64,7 +64,7 @@
|
|||||||
.kx-apf__reject-head strong {
|
.kx-apf__reject-head strong {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: #b91c1c;
|
color: #b91c1c;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-apf__reject-body {
|
.kx-apf__reject-body {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
@ -88,7 +88,7 @@
|
|||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
.kx-apf__prev-act {
|
.kx-apf__prev-act {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-800);
|
color: var(--color-neutral-800);
|
||||||
}
|
}
|
||||||
.kx-apf__prev-meta {
|
.kx-apf__prev-meta {
|
||||||
@ -125,7 +125,7 @@
|
|||||||
}
|
}
|
||||||
.kx-apf__label {
|
.kx-apf__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-apf__req {
|
.kx-apf__req {
|
||||||
@ -192,7 +192,7 @@
|
|||||||
min-width: 52px;
|
min-width: 52px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
@ -260,7 +260,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
padding: 6px 14px;
|
padding: 6px 14px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-line-editor__add:hover:not(:disabled) {
|
.kx-line-editor__add:hover:not(:disabled) {
|
||||||
@ -300,7 +300,7 @@
|
|||||||
}
|
}
|
||||||
.kx-apm__head h2 {
|
.kx-apm__head h2 {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-apm__close {
|
.kx-apm__close {
|
||||||
@ -318,7 +318,7 @@
|
|||||||
}
|
}
|
||||||
.kx-apm__label {
|
.kx-apm__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-apm__textarea {
|
.kx-apm__textarea {
|
||||||
@ -334,7 +334,7 @@
|
|||||||
border-color: var(--color-primary-600);
|
border-color: var(--color-primary-600);
|
||||||
}
|
}
|
||||||
.kx-apm__hint {
|
.kx-apm__hint {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-apm__foot {
|
.kx-apm__foot {
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
.kx-aq__title-row h1 {
|
.kx-aq__title-row h1 {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-aq__hall-tabs {
|
.kx-aq__hall-tabs {
|
||||||
@ -45,7 +45,7 @@
|
|||||||
border-color: var(--color-primary-600);
|
border-color: var(--color-primary-600);
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-aq__search {
|
.kx-aq__search {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -123,43 +123,16 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
}
|
}
|
||||||
.kx-aq__table {
|
/* 표는 정본 .kx-table 로 수렴(approval-queue.css 자체 테이블 정의 제거).
|
||||||
width: 100%;
|
* 아래는 셀/컬럼 modifier 만 유지. */
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: var(--fs-body);
|
|
||||||
}
|
|
||||||
.kx-aq__table thead {
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
.kx-aq__table th {
|
|
||||||
text-align: left;
|
|
||||||
padding: 10px 12px;
|
|
||||||
font-size: var(--fs-caption);
|
|
||||||
color: var(--color-neutral-500);
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
background: var(--color-neutral-050);
|
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: bottom;
|
|
||||||
}
|
|
||||||
.kx-aq__col-ai {
|
.kx-aq__col-ai {
|
||||||
color: var(--color-ai-accent) !important;
|
color: var(--color-ai-accent) !important;
|
||||||
}
|
}
|
||||||
.kx-aq__col-act {
|
.kx-aq__col-act {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.kx-aq__table td {
|
|
||||||
padding: 10px 12px;
|
|
||||||
border-bottom: 1px solid var(--color-neutral-200);
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.kx-aq__table tbody tr:hover {
|
|
||||||
background: var(--row-hover);
|
|
||||||
}
|
|
||||||
.kx-aq__event {
|
.kx-aq__event {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-aq__booth {
|
.kx-aq__booth {
|
||||||
@ -173,8 +146,8 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
}
|
}
|
||||||
@ -195,7 +168,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
padding: 5px 14px;
|
padding: 5px 14px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-aq__review:hover {
|
.kx-aq__review:hover {
|
||||||
@ -262,7 +235,7 @@
|
|||||||
.kx-aq__load-scale {
|
.kx-aq__load-scale {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-aq__card--ai {
|
.kx-aq__card--ai {
|
||||||
@ -318,7 +291,7 @@
|
|||||||
}
|
}
|
||||||
.kx-aq__tab.is-active {
|
.kx-aq__tab.is-active {
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
border-bottom-color: var(--color-primary-600);
|
border-bottom-color: var(--color-primary-600);
|
||||||
}
|
}
|
||||||
.kx-aq__notice {
|
.kx-aq__notice {
|
||||||
@ -331,7 +304,7 @@
|
|||||||
}
|
}
|
||||||
.kx-aq__count {
|
.kx-aq__count {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
@ -350,8 +323,8 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
background: rgba(148, 163, 184, 0.16);
|
background: rgba(148, 163, 184, 0.16);
|
||||||
color: #475569;
|
color: #475569;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-rev__meta {
|
.kx-rev__meta {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
border: 1px solid var(--color-neutral-200);
|
border: 1px solid var(--color-neutral-200);
|
||||||
@ -186,7 +186,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||||
@ -244,8 +244,8 @@
|
|||||||
border-bottom: 1px solid var(--color-neutral-200);
|
border-bottom: 1px solid var(--color-neutral-200);
|
||||||
}
|
}
|
||||||
.kx-rev__ai-count {
|
.kx-rev__ai-count {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
background: #fef3f2;
|
background: #fef3f2;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -277,13 +277,13 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.kx-rev__vtitle {
|
.kx-rev__vtitle {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
@ -321,8 +321,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.kx-rev__avatar--con {
|
.kx-rev__avatar--con {
|
||||||
@ -340,7 +340,7 @@
|
|||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-rev__comment-top span {
|
.kx-rev__comment-top span {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-rev__comment p {
|
.kx-rev__comment p {
|
||||||
@ -407,8 +407,8 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
background: rgba(148, 163, 184, 0.2);
|
background: rgba(148, 163, 184, 0.2);
|
||||||
color: #475569;
|
color: #475569;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -425,13 +425,13 @@ function BoqPanel({
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="kx-boq__scroll">
|
<div className="kx-boq__scroll">
|
||||||
<table className="kx-boq__table">
|
<table className="kx-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('auction.boq.colSeq')}</th>
|
<th>{t('auction.boq.colSeq')}</th>
|
||||||
<th>{t('auction.boq.colTrade')}</th>
|
<th>{t('auction.boq.colTrade')}</th>
|
||||||
<th>{t('auction.boq.colItem')}</th>
|
<th>{t('auction.boq.colItem')}</th>
|
||||||
<th className="kx-boq__num">{t('auction.boq.colQty')}</th>
|
<th className="kx-num">{t('auction.boq.colQty')}</th>
|
||||||
<th>{t('auction.boq.colUnit')}</th>
|
<th>{t('auction.boq.colUnit')}</th>
|
||||||
<th>{t('auction.boq.colBasis')}</th>
|
<th>{t('auction.boq.colBasis')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -444,7 +444,7 @@ function BoqPanel({
|
|||||||
<span className="kx-boq__trade">{l.trade}</span>
|
<span className="kx-boq__trade">{l.trade}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>{l.item}</td>
|
<td>{l.item}</td>
|
||||||
<td className="kx-boq__num tnum">{l.qty.toLocaleString()}</td>
|
<td className="kx-num tnum">{l.qty.toLocaleString()}</td>
|
||||||
<td>{l.unit}</td>
|
<td>{l.unit}</td>
|
||||||
<td className="kx-boq__basis">{l.basis}</td>
|
<td className="kx-boq__basis">{l.basis}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
font-size: var(--fs-h1);
|
font-size: var(--fs-h1);
|
||||||
line-height: var(--lh-h1);
|
line-height: var(--lh-h1);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-auc__subtitle {
|
.kx-auc__subtitle {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
@ -35,8 +35,8 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
@ -119,7 +119,7 @@
|
|||||||
.kx-auc-card__name {
|
.kx-auc-card__name {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
line-height: var(--lh-h3);
|
line-height: var(--lh-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-auc-card__status {
|
.kx-auc-card__status {
|
||||||
@ -152,7 +152,7 @@
|
|||||||
}
|
}
|
||||||
.kx-auc-card__metric-value {
|
.kx-auc-card__metric-value {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-auc-card__metric-value--price {
|
.kx-auc-card__metric-value--price {
|
||||||
@ -176,7 +176,7 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 카테고리·유형 태그 */
|
/* 카테고리·유형 태그 */
|
||||||
@ -186,7 +186,7 @@
|
|||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
@ -206,7 +206,7 @@
|
|||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-auc-pill--live {
|
.kx-auc-pill--live {
|
||||||
background: #e6f4ee;
|
background: #e6f4ee;
|
||||||
@ -237,7 +237,7 @@
|
|||||||
}
|
}
|
||||||
.kx-auc-open__head h2 {
|
.kx-auc-open__head h2 {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
@ -265,15 +265,15 @@
|
|||||||
.kx-auc .kx-field__label {
|
.kx-auc .kx-field__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.kx-auc .kx-field__label-note {
|
.kx-auc .kx-field__label-note {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
}
|
}
|
||||||
.kx-auc .kx-input {
|
.kx-auc .kx-input {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
@ -321,7 +321,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
.kx-weight input[type='range'] {
|
.kx-weight input[type='range'] {
|
||||||
@ -343,12 +343,12 @@
|
|||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-auc-attach small {
|
.kx-auc-attach small {
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-weight: 400;
|
font-weight: var(--fw-regular);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 초대 업체 리스트 */
|
/* 초대 업체 리스트 */
|
||||||
@ -374,9 +374,9 @@
|
|||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-invite__blocked-tag {
|
.kx-invite__blocked-tag {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── SCR-27 상세 레이아웃 ── */
|
/* ── SCR-27 상세 레이아웃 ── */
|
||||||
@ -404,7 +404,7 @@
|
|||||||
background: #fef3f2;
|
background: #fef3f2;
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
}
|
}
|
||||||
@ -435,14 +435,14 @@
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
.kx-aucd__metric-label {
|
.kx-aucd__metric-label {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-aucd__metric-value {
|
.kx-aucd__metric-value {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-aucd__metric-value--ok {
|
.kx-aucd__metric-value--ok {
|
||||||
@ -481,7 +481,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -518,7 +518,7 @@
|
|||||||
.kx-viewer__placeholder-title {
|
.kx-viewer__placeholder-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
color: rgba(255, 255, 255, 0.85);
|
color: rgba(255, 255, 255, 0.85);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-viewer__placeholder-desc {
|
.kx-viewer__placeholder-desc {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
@ -529,7 +529,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 16px;
|
right: 16px;
|
||||||
bottom: 12px;
|
bottom: 12px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: rgba(255, 255, 255, 0.4);
|
color: rgba(255, 255, 255, 0.4);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@ -556,7 +556,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-toggle {
|
.kx-toggle {
|
||||||
@ -624,7 +624,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@ -639,7 +639,7 @@
|
|||||||
}
|
}
|
||||||
.kx-rank__alias {
|
.kx-rank__alias {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-rank__row--me .kx-rank__alias {
|
.kx-rank__row--me .kx-rank__alias {
|
||||||
@ -647,21 +647,21 @@
|
|||||||
}
|
}
|
||||||
.kx-rank__price {
|
.kx-rank__price {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-rank__price--masked {
|
.kx-rank__price--masked {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-rank__tag {
|
.kx-rank__tag {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
background: #e6f4ee;
|
background: #e6f4ee;
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,21 +683,21 @@
|
|||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
}
|
}
|
||||||
.kx-countdown__label {
|
.kx-countdown__label {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.16em;
|
letter-spacing: 0.16em;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-countdown__value {
|
.kx-countdown__value {
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: var(--lh-display);
|
line-height: var(--lh-display);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
.kx-rank__note {
|
.kx-rank__note {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@ -723,12 +723,12 @@
|
|||||||
border-left-color: var(--color-success);
|
border-left-color: var(--color-success);
|
||||||
}
|
}
|
||||||
.kx-award__chip-label {
|
.kx-award__chip-label {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-award__chip-value {
|
.kx-award__chip-value {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,14 +764,14 @@
|
|||||||
}
|
}
|
||||||
.kx-compare thead th {
|
.kx-compare thead th {
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-compare thead th.kx-compare__metric-col,
|
.kx-compare thead th.kx-compare__metric-col,
|
||||||
.kx-compare td.kx-compare__metric-col {
|
.kx-compare td.kx-compare__metric-col {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: 22%;
|
width: 22%;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-compare__co {
|
.kx-compare__co {
|
||||||
@ -779,7 +779,7 @@
|
|||||||
}
|
}
|
||||||
.kx-compare__co-name {
|
.kx-compare__co-name {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-compare__co--rec .kx-compare__co-name {
|
.kx-compare__co--rec .kx-compare__co-name {
|
||||||
@ -787,16 +787,16 @@
|
|||||||
}
|
}
|
||||||
.kx-compare__co-sub {
|
.kx-compare__co-sub {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 400;
|
font-weight: var(--fw-regular);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
.kx-compare__rec-tag {
|
.kx-compare__rec-tag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: var(--color-primary-700);
|
background: var(--color-primary-700);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -805,15 +805,15 @@
|
|||||||
.kx-compare__best {
|
.kx-compare__best {
|
||||||
background: #f0fbf6;
|
background: #f0fbf6;
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-compare__val-strong {
|
.kx-compare__val-strong {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-compare__note {
|
.kx-compare__note {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
@ -825,7 +825,7 @@
|
|||||||
}
|
}
|
||||||
.kx-compare__score-val {
|
.kx-compare__score-val {
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
}
|
}
|
||||||
.kx-compare__star {
|
.kx-compare__star {
|
||||||
@ -857,7 +857,7 @@
|
|||||||
}
|
}
|
||||||
.kx-risk__grade-value {
|
.kx-risk__grade-value {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
}
|
}
|
||||||
@ -882,7 +882,7 @@
|
|||||||
}
|
}
|
||||||
.kx-award__panel h2 {
|
.kx-award__panel h2 {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-award__rec {
|
.kx-award__rec {
|
||||||
@ -907,11 +907,11 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-award__rec-name {
|
.kx-award__rec-name {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-award__rec-ai {
|
.kx-award__rec-ai {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -931,12 +931,12 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.kx-award__rec-cell-label {
|
.kx-award__rec-cell-label {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-award__rec-cell-value {
|
.kx-award__rec-cell-value {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-award__textarea {
|
.kx-award__textarea {
|
||||||
@ -955,7 +955,7 @@
|
|||||||
padding: var(--space-3);
|
padding: var(--space-3);
|
||||||
background: #fef3f2;
|
background: #fef3f2;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
}
|
}
|
||||||
@ -965,7 +965,7 @@
|
|||||||
}
|
}
|
||||||
.kx-award__steps-title {
|
.kx-award__steps-title {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
margin-bottom: var(--space-3);
|
margin-bottom: var(--space-3);
|
||||||
}
|
}
|
||||||
@ -992,8 +992,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1036,7 +1036,7 @@
|
|||||||
}
|
}
|
||||||
.kx-boq__title {
|
.kx-boq__title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-text-strong);
|
color: var(--color-text-strong);
|
||||||
}
|
}
|
||||||
.kx-boq__scope {
|
.kx-boq__scope {
|
||||||
@ -1048,46 +1048,22 @@
|
|||||||
border: var(--border-card);
|
border: var(--border-card);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
}
|
}
|
||||||
.kx-boq__table {
|
/* BOQ 표는 정본 .kx-table 로 수렴. 셀 상단정렬(다행 항목)만 스코프 유지. */
|
||||||
width: 100%;
|
.kx-boq__scroll .kx-table td {
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: var(--fs-body);
|
|
||||||
color: var(--color-neutral-700);
|
|
||||||
}
|
|
||||||
.kx-boq__table th,
|
|
||||||
.kx-boq__table td {
|
|
||||||
padding: 10px 12px;
|
|
||||||
border-bottom: 1px solid var(--color-neutral-200);
|
|
||||||
text-align: left;
|
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.kx-boq__table thead th {
|
|
||||||
background: var(--color-neutral-050);
|
|
||||||
font-size: var(--fs-caption);
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
color: var(--color-neutral-500);
|
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: bottom;
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
.kx-boq__num {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.kx-boq__trade {
|
.kx-boq__trade {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: var(--color-primary-surface, #eef2ff);
|
background: var(--color-primary-surface, #eef2ff);
|
||||||
color: var(--color-primary-600, #2f42fc);
|
color: var(--color-primary-600, #2f42fc);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-boq__basis {
|
.kx-boq__basis {
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
}
|
}
|
||||||
.kx-boq__note {
|
.kx-boq__note {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
|
|||||||
@ -16,8 +16,9 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.kx-bsales__title {
|
.kx-bsales__title {
|
||||||
font-size: 20px;
|
font-size: var(--fs-h1);
|
||||||
font-weight: 700;
|
line-height: var(--lh-h1);
|
||||||
|
font-weight: var(--fw-bold);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.kx-bsales__subtitle {
|
.kx-bsales__subtitle {
|
||||||
@ -38,18 +39,18 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
background: var(--kx-surface-2, #f1f5f9);
|
background: var(--kx-surface-2, #f1f5f9);
|
||||||
border: 1px solid var(--kx-border, #e2e8f0);
|
border: 1px solid var(--kx-border, #e2e8f0);
|
||||||
}
|
}
|
||||||
.kx-bsales__stat strong { font-size: 15px; font-weight: 700; }
|
.kx-bsales__stat strong { font-size: 15px; font-weight: var(--fw-bold); }
|
||||||
.kx-bsales__stat.is-available { color: #15803d; background: #f0fdf4; border-color: #bbf7d0; }
|
.kx-bsales__stat.is-available { color: #15803d; background: #f0fdf4; border-color: #bbf7d0; }
|
||||||
.kx-bsales__stat.is-held { color: #b45309; background: #fffbeb; border-color: #fde68a; }
|
.kx-bsales__stat.is-held { color: #b45309; background: #fffbeb; border-color: #fde68a; }
|
||||||
.kx-bsales__stat.is-sold { color: #475569; background: #f1f5f9; border-color: #cbd5e1; }
|
.kx-bsales__stat.is-sold { color: #475569; background: #f1f5f9; border-color: #cbd5e1; }
|
||||||
.kx-bsales__stat.is-blocked { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
|
.kx-bsales__stat.is-blocked { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
|
||||||
.kx-bsales__rate {
|
.kx-bsales__rate {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
color: var(--kx-text-muted, #64748b);
|
color: var(--kx-text-muted, #64748b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,14 +95,14 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
.kx-boothstatus {
|
.kx-boothstatus {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-boothstatus.is-available { color: #15803d; background: #f0fdf4; }
|
.kx-boothstatus.is-available { color: #15803d; background: #f0fdf4; }
|
||||||
.kx-boothstatus.is-held { color: #b45309; background: #fffbeb; }
|
.kx-boothstatus.is-held { color: #b45309; background: #fffbeb; }
|
||||||
@ -110,10 +111,10 @@
|
|||||||
|
|
||||||
.kx-boothcard__price {
|
.kx-boothcard__price {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
}
|
}
|
||||||
.kx-boothcard__won { font-size: 13px; font-weight: 500; color: var(--kx-text-muted, #64748b); margin-left: 2px; }
|
.kx-boothcard__won { font-size: 13px; font-weight: var(--fw-medium); color: var(--kx-text-muted, #64748b); margin-left: 2px; }
|
||||||
|
|
||||||
.kx-boothcard__meta {
|
.kx-boothcard__meta {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@ -122,7 +123,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 3px;
|
gap: 3px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
color: var(--kx-text-muted, #64748b);
|
color: var(--kx-text-muted, #64748b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,5 +135,5 @@
|
|||||||
}
|
}
|
||||||
.kx-boothcard__actions .kx-btn {
|
.kx-boothcard__actions .kx-btn {
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -222,7 +222,7 @@ export function MultilingualCmsPage() {
|
|||||||
) : contents.length === 0 ? (
|
) : contents.length === 0 ? (
|
||||||
<div className="kx-cms-empty">콘텐츠가 없습니다.</div>
|
<div className="kx-cms-empty">콘텐츠가 없습니다.</div>
|
||||||
) : (
|
) : (
|
||||||
<table className="kx-i18n-table">
|
<table className="kx-table kx-i18n-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style={{ width: '30%' }}>콘텐츠 / 원문(KO)</th>
|
<th style={{ width: '30%' }}>콘텐츠 / 원문(KO)</th>
|
||||||
|
|||||||
@ -39,8 +39,8 @@
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
@ -55,8 +55,8 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
padding: 1px 10px;
|
padding: 1px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.kx-cms-pill--draft {
|
.kx-cms-pill--draft {
|
||||||
@ -92,7 +92,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cms-label {
|
.kx-cms-label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-cms-input,
|
.kx-cms-input,
|
||||||
@ -278,7 +278,7 @@
|
|||||||
padding: 0 0 8px;
|
padding: 0 0 8px;
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: var(--lh-display);
|
line-height: var(--lh-display);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
@ -331,8 +331,8 @@
|
|||||||
var(--color-neutral-050) 16px
|
var(--color-neutral-050) 16px
|
||||||
);
|
);
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
@ -375,7 +375,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cms-block__kind {
|
.kx-cms-block__kind {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-cms-block__body {
|
.kx-cms-block__body {
|
||||||
@ -413,7 +413,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
@ -435,8 +435,8 @@
|
|||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
}
|
}
|
||||||
.kx-cms-flow__label {
|
.kx-cms-flow__label {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
@ -474,7 +474,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cms-step.is-current {
|
.kx-cms-step.is-current {
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-cms-step.is-current .kx-cms-step__dot {
|
.kx-cms-step.is-current .kx-cms-step__dot {
|
||||||
border-color: var(--color-primary-600);
|
border-color: var(--color-primary-600);
|
||||||
@ -502,11 +502,11 @@
|
|||||||
}
|
}
|
||||||
.kx-cms-ver__v {
|
.kx-cms-ver__v {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-cms-ver__meta {
|
.kx-cms-ver__meta {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-cms-schedcard {
|
.kx-cms-schedcard {
|
||||||
@ -519,8 +519,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
@ -611,7 +611,7 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
@ -680,7 +680,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-mb-site__logo {
|
.kx-mb-site__logo {
|
||||||
@ -692,7 +692,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
.kx-mb-site__menu {
|
.kx-mb-site__menu {
|
||||||
@ -718,14 +718,14 @@
|
|||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
background: rgba(255, 255, 255, 0.14);
|
background: rgba(255, 255, 255, 0.14);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
margin-bottom: var(--space-3);
|
margin-bottom: var(--space-3);
|
||||||
}
|
}
|
||||||
.kx-mb-hero__title {
|
.kx-mb-hero__title {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
margin-bottom: var(--space-3);
|
margin-bottom: var(--space-3);
|
||||||
max-width: 30ch;
|
max-width: 30ch;
|
||||||
}
|
}
|
||||||
@ -743,7 +743,7 @@
|
|||||||
.kx-mb-btn {
|
.kx-mb-btn {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
cursor: default;
|
cursor: default;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
@ -777,7 +777,7 @@
|
|||||||
}
|
}
|
||||||
.kx-mb-section__title {
|
.kx-mb-section__title {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-mb-cards {
|
.kx-mb-cards {
|
||||||
@ -808,15 +808,15 @@
|
|||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-mb-card__body {
|
.kx-mb-card__body {
|
||||||
padding: var(--space-3);
|
padding: var(--space-3);
|
||||||
border-left: 4px solid var(--color-primary-600);
|
border-left: 4px solid var(--color-primary-600);
|
||||||
}
|
}
|
||||||
.kx-mb-card__title {
|
.kx-mb-card__title {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
@ -868,8 +868,8 @@
|
|||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
background: #e6f4ee;
|
background: #e6f4ee;
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-mb-status__dot {
|
.kx-mb-status__dot {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
@ -890,7 +890,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -917,11 +917,11 @@
|
|||||||
}
|
}
|
||||||
.kx-mb-activity__t {
|
.kx-mb-activity__t {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-mb-activity__m {
|
.kx-mb-activity__m {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,7 +951,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-i18n-covcard__pct {
|
.kx-i18n-covcard__pct {
|
||||||
@ -992,45 +992,22 @@
|
|||||||
margin-bottom: var(--space-3);
|
margin-bottom: var(--space-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 매트릭스 테이블 */
|
/* 매트릭스 테이블 — 기본 그리드는 정본 .kx-table 로 수렴. 아래는 확장만 유지. */
|
||||||
.kx-i18n-table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-size: var(--fs-body);
|
|
||||||
}
|
|
||||||
.kx-i18n-table thead th {
|
|
||||||
text-align: left;
|
|
||||||
padding: 10px 12px;
|
|
||||||
font-size: var(--fs-caption);
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
color: var(--color-neutral-500);
|
|
||||||
background: var(--color-neutral-050);
|
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
|
||||||
white-space: nowrap;
|
|
||||||
vertical-align: bottom;
|
|
||||||
}
|
|
||||||
.kx-i18n-table tbody td {
|
.kx-i18n-table tbody td {
|
||||||
padding: 10px 12px;
|
|
||||||
border-bottom: 1px solid var(--color-neutral-200);
|
|
||||||
color: var(--color-neutral-700);
|
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.kx-i18n-table tbody tr {
|
.kx-i18n-table tbody tr {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-i18n-table tbody tr:hover {
|
|
||||||
background: var(--color-neutral-050);
|
|
||||||
}
|
|
||||||
.kx-i18n-table tbody tr.is-active {
|
.kx-i18n-table tbody tr.is-active {
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
}
|
}
|
||||||
.kx-i18n-row__key {
|
.kx-i18n-row__key {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-i18n-row__id {
|
.kx-i18n-row__id {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
}
|
}
|
||||||
@ -1100,13 +1077,13 @@
|
|||||||
background: var(--color-ai-surface);
|
background: var(--color-ai-surface);
|
||||||
}
|
}
|
||||||
.kx-i18n-tone__t {
|
.kx-i18n-tone__t {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
.kx-i18n-tone__p {
|
.kx-i18n-tone__p {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
@ -1119,8 +1096,8 @@
|
|||||||
|
|
||||||
/* 섹션 라벨(공통 소제목) */
|
/* 섹션 라벨(공통 소제목) */
|
||||||
.kx-cms-sublabel {
|
.kx-cms-sublabel {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
@ -1162,11 +1139,11 @@
|
|||||||
background: color-mix(in srgb, var(--color-success) 10%, transparent);
|
background: color-mix(in srgb, var(--color-success) 10%, transparent);
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-cms-disabled-hint {
|
.kx-cms-disabled-hint {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
border: 1px dashed var(--color-neutral-300);
|
border: 1px dashed var(--color-neutral-300);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
padding: var(--space-3) var(--space-4);
|
padding: var(--space-3) var(--space-4);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-comp__banner.is-block {
|
.kx-comp__banner.is-block {
|
||||||
background: #fef3f2;
|
background: #fef3f2;
|
||||||
@ -30,7 +30,7 @@
|
|||||||
border: 1px solid #a6e0c8;
|
border: 1px solid #a6e0c8;
|
||||||
}
|
}
|
||||||
.kx-comp__banner-note {
|
.kx-comp__banner-note {
|
||||||
font-weight: 400;
|
font-weight: var(--fw-regular);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kx-comp__drop {
|
.kx-comp__drop {
|
||||||
@ -81,8 +81,8 @@
|
|||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
}
|
}
|
||||||
.kx-comp__lg {
|
.kx-comp__lg {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
@ -130,8 +130,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: var(--color-error);
|
background: var(--color-error);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
@ -156,12 +156,12 @@
|
|||||||
}
|
}
|
||||||
.kx-comp__item-label {
|
.kx-comp__item-label {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-comp__sev {
|
.kx-comp__sev {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
@ -182,8 +182,8 @@
|
|||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-comp__doc {
|
.kx-comp__doc {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
background: var(--color-ai-surface);
|
background: var(--color-ai-surface);
|
||||||
border: 1px solid var(--color-ai-accent);
|
border: 1px solid var(--color-ai-accent);
|
||||||
@ -231,8 +231,8 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 12%;
|
top: 12%;
|
||||||
right: 6%;
|
right: 6%;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: var(--color-error);
|
background: var(--color-error);
|
||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
font-size: var(--fs-h1);
|
font-size: var(--fs-h1);
|
||||||
line-height: var(--lh-h1);
|
line-height: var(--lh-h1);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-cbd__subtitle {
|
.kx-cbd__subtitle {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
@ -78,7 +78,7 @@
|
|||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@
|
|||||||
}
|
}
|
||||||
.kx-booth__name {
|
.kx-booth__name {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-booth__meta {
|
.kx-booth__meta {
|
||||||
@ -112,7 +112,7 @@
|
|||||||
}
|
}
|
||||||
.kx-booth__right-value {
|
.kx-booth__right-value {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 시공 스테퍼 */
|
/* 시공 스테퍼 */
|
||||||
@ -148,7 +148,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@
|
|||||||
.kx-step--done .kx-step__label,
|
.kx-step--done .kx-step__label,
|
||||||
.kx-step--current .kx-step__label {
|
.kx-step--current .kx-step__label {
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kx-booth__actions {
|
.kx-booth__actions {
|
||||||
@ -220,7 +220,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cbd-bid__name {
|
.kx-cbd-bid__name {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-cbd-bid__price {
|
.kx-cbd-bid__price {
|
||||||
@ -236,8 +236,8 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
.kx-rankpill {
|
.kx-rankpill {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 히어로 타임라인 */
|
/* 히어로 타임라인 */
|
||||||
@ -78,7 +78,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: var(--color-neutral-200);
|
background: var(--color-neutral-200);
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@
|
|||||||
}
|
}
|
||||||
.kx-timeline__title {
|
.kx-timeline__title {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-timeline__card {
|
.kx-timeline__card {
|
||||||
@ -122,7 +122,7 @@
|
|||||||
}
|
}
|
||||||
.kx-timeline__imminent {
|
.kx-timeline__imminent {
|
||||||
color: var(--color-violation-warn-text);
|
color: var(--color-violation-warn-text);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-timeline__muted {
|
.kx-timeline__muted {
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
@ -150,7 +150,7 @@
|
|||||||
.kx-kpi__value {
|
.kx-kpi__value {
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: var(--lh-display);
|
line-height: var(--lh-display);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-kpi__sub {
|
.kx-kpi__sub {
|
||||||
@ -162,7 +162,7 @@
|
|||||||
}
|
}
|
||||||
.kx-kpi--warn .kx-kpi__sub {
|
.kx-kpi--warn .kx-kpi__sub {
|
||||||
color: var(--color-violation-warn-text);
|
color: var(--color-violation-warn-text);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-kpi--error .kx-kpi__value {
|
.kx-kpi--error .kx-kpi__value {
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
@ -193,7 +193,7 @@
|
|||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-dash__degraded {
|
.kx-dash__degraded {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -222,7 +222,7 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
.kx-studio__ctx h2 {
|
.kx-studio__ctx h2 {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-studio__ctx-sub {
|
.kx-studio__ctx-sub {
|
||||||
@ -36,7 +36,7 @@
|
|||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
font-size: 16px;
|
font-size: var(--fs-h3);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-studio__back:hover {
|
.kx-studio__back:hover {
|
||||||
@ -64,7 +64,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: var(--color-ai-surface);
|
background: var(--color-ai-surface);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
font-size: 20px;
|
font-size: var(--fs-h2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kx-studio__body {
|
.kx-studio__body {
|
||||||
@ -100,7 +100,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-acc__chevron {
|
.kx-acc__chevron {
|
||||||
@ -159,7 +159,7 @@
|
|||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-studio__toggle--req {
|
.kx-studio__toggle--req {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-studio__seg {
|
.kx-studio__seg {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
@ -173,7 +173,7 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 6px 18px;
|
padding: 6px 18px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-studio__seg button.is-active {
|
.kx-studio__seg button.is-active {
|
||||||
@ -208,7 +208,7 @@
|
|||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-studio__tile-label {
|
.kx-studio__tile-label {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-studio__tile-empty button {
|
.kx-studio__tile-empty button {
|
||||||
border: 1px solid var(--color-ai-accent);
|
border: 1px solid var(--color-ai-accent);
|
||||||
@ -217,7 +217,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
padding: 6px 14px;
|
padding: 6px 14px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Before/After */
|
/* Before/After */
|
||||||
@ -244,7 +244,7 @@
|
|||||||
transform: rotate(-24deg);
|
transform: rotate(-24deg);
|
||||||
color: rgba(255, 255, 255, 0.55);
|
color: rgba(255, 255, 255, 0.55);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
||||||
@ -255,7 +255,7 @@
|
|||||||
left: var(--space-2);
|
left: var(--space-2);
|
||||||
}
|
}
|
||||||
.kx-studio__compare-notice {
|
.kx-studio__compare-notice {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@
|
|||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-chip--pass {
|
.kx-chip--pass {
|
||||||
background: #e6f4ee;
|
background: #e6f4ee;
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
}
|
}
|
||||||
.kx-doc__label {
|
.kx-doc__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-doc__input,
|
.kx-doc__input,
|
||||||
@ -153,14 +153,14 @@
|
|||||||
}
|
}
|
||||||
.kx-doc__step-label {
|
.kx-doc__step-label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-doc__step.is-active .kx-doc__step-label {
|
.kx-doc__step.is-active .kx-doc__step-label {
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
}
|
}
|
||||||
.kx-doc__step-sub {
|
.kx-doc__step-sub {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +207,7 @@
|
|||||||
}
|
}
|
||||||
.kx-doc__progress-num {
|
.kx-doc__progress-num {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-doc__progress-track {
|
.kx-doc__progress-track {
|
||||||
@ -254,7 +254,7 @@
|
|||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
}
|
}
|
||||||
.kx-doc__doc-name {
|
.kx-doc__doc-name {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@
|
|||||||
padding: 1px 10px;
|
padding: 1px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -321,7 +321,7 @@
|
|||||||
}
|
}
|
||||||
.kx-doc__issue-title {
|
.kx-doc__issue-title {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-doc__issue-desc {
|
.kx-doc__issue-desc {
|
||||||
@ -340,7 +340,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
@ -366,7 +366,7 @@
|
|||||||
.kx-doc__stat-value {
|
.kx-doc__stat-value {
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
margin: var(--space-2) 0;
|
margin: var(--space-2) 0;
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
@ -474,7 +474,7 @@
|
|||||||
.kx-rep__a4-title h2 {
|
.kx-rep__a4-title h2 {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.3em;
|
letter-spacing: 0.3em;
|
||||||
border-bottom: 3px solid #141b2c;
|
border-bottom: 3px solid #141b2c;
|
||||||
padding: 0 16px 6px;
|
padding: 0 16px 6px;
|
||||||
@ -489,19 +489,19 @@
|
|||||||
.kx-rep__table td {
|
.kx-rep__table td {
|
||||||
border: 1px solid #141b2c;
|
border: 1px solid #141b2c;
|
||||||
padding: 7px 9px;
|
padding: 7px 9px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.kx-rep__table th {
|
.kx-rep__table th {
|
||||||
background: #f2f4f7;
|
background: #f2f4f7;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
width: 22%;
|
width: 22%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.kx-rep__a4 h4 {
|
.kx-rep__a4 h4 {
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
}
|
}
|
||||||
.kx-rep__a4 section {
|
.kx-rep__a4 section {
|
||||||
@ -511,7 +511,7 @@
|
|||||||
border: 1px solid #141b2c;
|
border: 1px solid #141b2c;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
min-height: 90px;
|
min-height: 90px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
.kx-rep__a4 ul {
|
.kx-rep__a4 ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -534,8 +534,8 @@
|
|||||||
gap: 14px;
|
gap: 14px;
|
||||||
}
|
}
|
||||||
.kx-rep__sign-name {
|
.kx-rep__sign-name {
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-rep__stamp {
|
.kx-rep__stamp {
|
||||||
width: 54px;
|
width: 54px;
|
||||||
@ -543,8 +543,8 @@
|
|||||||
border: 2px solid var(--color-error);
|
border: 2px solid var(--color-error);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
.kx-exh__company {
|
.kx-exh__company {
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: var(--lh-display);
|
line-height: var(--lh-display);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
border: 2px solid var(--color-neutral-200);
|
border: 2px solid var(--color-neutral-200);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
@ -125,7 +125,7 @@
|
|||||||
}
|
}
|
||||||
.kx-stepper__label {
|
.kx-stepper__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-stepper__item.is-current .kx-stepper__label {
|
.kx-stepper__item.is-current .kx-stepper__label {
|
||||||
@ -135,7 +135,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 62px;
|
top: 62px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -206,7 +206,7 @@
|
|||||||
background: none;
|
background: none;
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
@ -277,7 +277,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
padding: var(--space-3);
|
padding: var(--space-3);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: rgba(255, 255, 255, 0.85);
|
color: rgba(255, 255, 255, 0.85);
|
||||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
|
background: linear-gradient(to top, rgba(0, 0, 0, 0.7), transparent);
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@
|
|||||||
transform: rotate(-24deg);
|
transform: rotate(-24deg);
|
||||||
color: rgba(255, 255, 255, 0.5);
|
color: rgba(255, 255, 255, 0.5);
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-auto__sub {
|
.kx-auto__sub {
|
||||||
@ -36,7 +36,7 @@
|
|||||||
.kx-auto__close {
|
.kx-auto__close {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 16px;
|
font-size: var(--fs-h3);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@
|
|||||||
}
|
}
|
||||||
.kx-auto__card-title {
|
.kx-auto__card-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-auto__metrics {
|
.kx-auto__metrics {
|
||||||
@ -111,9 +111,9 @@
|
|||||||
}
|
}
|
||||||
.kx-auto__viol-ok {
|
.kx-auto__viol-ok {
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-auto__viol-bad {
|
.kx-auto__viol-bad {
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
}
|
}
|
||||||
.kx-editor__hall {
|
.kx-editor__hall {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-editor__version {
|
.kx-editor__version {
|
||||||
@ -40,8 +40,8 @@
|
|||||||
font-size: 8px;
|
font-size: 8px;
|
||||||
}
|
}
|
||||||
.kx-editor__degraded {
|
.kx-editor__degraded {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -81,8 +81,8 @@
|
|||||||
border-bottom: var(--border-card);
|
border-bottom: var(--border-card);
|
||||||
}
|
}
|
||||||
.kx-tool-group h3 {
|
.kx-tool-group h3 {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
@ -123,7 +123,7 @@
|
|||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
.kx-palette__label {
|
.kx-palette__label {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@
|
|||||||
.kx-editor__zoom span {
|
.kx-editor__zoom span {
|
||||||
width: 44px;
|
width: 44px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
border-bottom: 2px solid transparent;
|
border-bottom: 2px solid transparent;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-editor__tabs button.is-active {
|
.kx-editor__tabs button.is-active {
|
||||||
@ -298,7 +298,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 검증 */
|
/* 검증 */
|
||||||
@ -319,7 +319,7 @@
|
|||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-valid__chip--block {
|
.kx-valid__chip--block {
|
||||||
background: #fef3f2;
|
background: #fef3f2;
|
||||||
@ -332,7 +332,7 @@
|
|||||||
.kx-valid__ok {
|
.kx-valid__ok {
|
||||||
background: #e6f4ee;
|
background: #e6f4ee;
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: var(--space-3);
|
padding: var(--space-3);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
@ -364,8 +364,8 @@
|
|||||||
height: 18px;
|
height: 18px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -389,15 +389,15 @@
|
|||||||
}
|
}
|
||||||
.kx-valid__label {
|
.kx-valid__label {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-valid__locate {
|
.kx-valid__locate {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.kx-valid__measured {
|
.kx-valid__measured {
|
||||||
@ -408,8 +408,8 @@
|
|||||||
.kx-valid__doc {
|
.kx-valid__doc {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: var(--space-2);
|
margin-top: var(--space-2);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
background: var(--color-ai-surface);
|
background: var(--color-ai-surface);
|
||||||
border: 1px solid var(--color-ai-accent);
|
border: 1px solid var(--color-ai-accent);
|
||||||
@ -417,7 +417,7 @@
|
|||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
}
|
}
|
||||||
.kx-valid__disclaimer {
|
.kx-valid__disclaimer {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,8 +75,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-cmp__wm {
|
.kx-cmp__wm {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -87,7 +87,7 @@
|
|||||||
transform: rotate(-24deg);
|
transform: rotate(-24deg);
|
||||||
color: rgba(255, 255, 255, 0.5);
|
color: rgba(255, 255, 255, 0.5);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||||
@ -107,8 +107,8 @@
|
|||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-cmp__reco {
|
.kx-cmp__reco {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -130,7 +130,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cmp__metrics dd {
|
.kx-cmp__metrics dd {
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-cmp__ok {
|
.kx-cmp__ok {
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
border: 1px solid var(--color-ai-accent);
|
border: 1px solid var(--color-ai-accent);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kx-gallery__head {
|
.kx-gallery__head {
|
||||||
@ -58,7 +58,7 @@
|
|||||||
padding: 5px 12px;
|
padding: 5px 12px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-gallery__chip.is-active {
|
.kx-gallery__chip.is-active {
|
||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
@ -90,7 +90,7 @@
|
|||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-gallery__status {
|
.kx-gallery__status {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@
|
|||||||
}
|
}
|
||||||
.kx-lightbox__notice {
|
.kx-lightbox__notice {
|
||||||
margin-top: var(--space-3);
|
margin-top: var(--space-3);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
gap: 2px;
|
gap: 2px;
|
||||||
}
|
}
|
||||||
.kx-hall__hallname {
|
.kx-hall__hallname {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@
|
|||||||
}
|
}
|
||||||
.kx-hall__chiptext em {
|
.kx-hall__chiptext em {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-hall__chip.is-conflict .kx-hall__chiptext em {
|
.kx-hall__chip.is-conflict .kx-hall__chiptext em {
|
||||||
@ -124,7 +124,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 16px;
|
font-size: var(--fs-h3);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
color: var(--color-neutral-400);
|
color: var(--color-neutral-400);
|
||||||
padding: 0 2px;
|
padding: 0 2px;
|
||||||
@ -188,7 +188,7 @@
|
|||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
}
|
}
|
||||||
.kx-hall__total td {
|
.kx-hall__total td {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
border-top: 2px solid var(--color-neutral-200);
|
border-top: 2px solid var(--color-neutral-200);
|
||||||
}
|
}
|
||||||
@ -316,7 +316,7 @@
|
|||||||
}
|
}
|
||||||
.kx-hall__detailsec h3 {
|
.kx-hall__detailsec h3 {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__section-title {
|
.kx-home__section-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__hello {
|
.kx-home__hello {
|
||||||
font-size: var(--fs-h1);
|
font-size: var(--fs-h1);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0 0 4px;
|
margin: 0 0 4px;
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@
|
|||||||
}
|
}
|
||||||
.kx-kpitile__value {
|
.kx-kpitile__value {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
/* Stitch 정합: 임박/경과 타일 값 강조색 */
|
/* Stitch 정합: 임박/경과 타일 값 강조색 */
|
||||||
@ -171,7 +171,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__banner-title {
|
.kx-home__banner-title {
|
||||||
font-size: var(--fs-h1);
|
font-size: var(--fs-h1);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
margin: 0 0 6px;
|
margin: 0 0 6px;
|
||||||
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
@ -295,7 +295,7 @@
|
|||||||
.kx-poster__fallback-text {
|
.kx-poster__fallback-text {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
@ -316,8 +316,8 @@
|
|||||||
border-left-color: var(--color-neutral-500);
|
border-left-color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-poster__hall {
|
.kx-poster__hall {
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
}
|
}
|
||||||
@ -329,7 +329,7 @@
|
|||||||
}
|
}
|
||||||
.kx-poster__name {
|
.kx-poster__name {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 2;
|
||||||
@ -354,7 +354,7 @@
|
|||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-home__chip.is-ongoing {
|
.kx-home__chip.is-ongoing {
|
||||||
background: var(--color-success-bg);
|
background: var(--color-success-bg);
|
||||||
@ -405,7 +405,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__cal-title {
|
.kx-home__cal-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@ -470,7 +470,7 @@
|
|||||||
padding: 6px 0;
|
padding: 6px 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-home__cal-wd.is-sun {
|
.kx-home__cal-wd.is-sun {
|
||||||
@ -528,11 +528,11 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
padding: 1px 7px;
|
padding: 1px 7px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-home__cal-more {
|
.kx-home__cal-more {
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
/* spanning bar 레인 — 셀 위에 절대배치(요일 헤더 아래 24px 오프셋) */
|
/* spanning bar 레인 — 셀 위에 절대배치(요일 헤더 아래 24px 오프셋) */
|
||||||
@ -548,7 +548,7 @@
|
|||||||
height: 18px;
|
height: 18px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -578,7 +578,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__cal-list-title {
|
.kx-home__cal-list-title {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0 0 var(--space-2);
|
margin: 0 0 var(--space-2);
|
||||||
}
|
}
|
||||||
@ -609,7 +609,7 @@
|
|||||||
.kx-home__cal-list-name {
|
.kx-home__cal-list-name {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -701,7 +701,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__widget-head h2 {
|
.kx-home__widget-head h2 {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@ -713,7 +713,7 @@
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -767,7 +767,7 @@
|
|||||||
.kx-home__todo-title {
|
.kx-home__todo-title {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
}
|
}
|
||||||
.kx-home__todo-target {
|
.kx-home__todo-target {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
@ -778,7 +778,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__todo-due {
|
.kx-home__todo-due {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.kx-home__todo-due.is-normal {
|
.kx-home__todo-due.is-normal {
|
||||||
@ -802,7 +802,7 @@
|
|||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
}
|
}
|
||||||
.kx-home__todo-done-title {
|
.kx-home__todo-done-title {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@ -850,8 +850,8 @@
|
|||||||
.kx-home__new {
|
.kx-home__new {
|
||||||
background: var(--color-error);
|
background: var(--color-error);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
padding: 1px 5px;
|
padding: 1px 5px;
|
||||||
}
|
}
|
||||||
@ -951,7 +951,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__ws-card-title {
|
.kx-home__ws-card-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 4px 0 0;
|
margin: 4px 0 0;
|
||||||
}
|
}
|
||||||
@ -969,7 +969,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.kx-home__ws-empty-title {
|
.kx-home__ws-empty-title {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: 0 0 4px;
|
margin: 0 0 4px;
|
||||||
}
|
}
|
||||||
@ -1051,7 +1051,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__chart-cap {
|
.kx-home__chart-cap {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -1084,7 +1084,7 @@
|
|||||||
}
|
}
|
||||||
.kx-home__chart-legend-item b {
|
.kx-home__chart-legend-item b {
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1100px) {
|
@media (max-width: 1100px) {
|
||||||
@ -1145,7 +1145,7 @@
|
|||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent-strong);
|
color: var(--color-ai-accent-strong);
|
||||||
letter-spacing: -0.01em;
|
letter-spacing: -0.01em;
|
||||||
}
|
}
|
||||||
@ -1227,14 +1227,14 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-1);
|
gap: var(--space-1);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
}
|
}
|
||||||
.kx-home__aihub-card-tag {
|
.kx-home__aihub-card-tag {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
padding: 1px 5px;
|
padding: 1px 5px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
|
|||||||
@ -99,14 +99,14 @@
|
|||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
color: #d3c7ff;
|
color: #d3c7ff;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
backdrop-filter: blur(4px);
|
backdrop-filter: blur(4px);
|
||||||
}
|
}
|
||||||
.kx-login__headline {
|
.kx-login__headline {
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: var(--lh-display);
|
line-height: var(--lh-display);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: -0.01em;
|
letter-spacing: -0.01em;
|
||||||
}
|
}
|
||||||
@media (min-width: 1280px) {
|
@media (min-width: 1280px) {
|
||||||
@ -153,12 +153,12 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
.kx-login__logo-text {
|
.kx-login__logo-text {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-login__logo-img {
|
.kx-login__logo-img {
|
||||||
@ -168,7 +168,7 @@
|
|||||||
}
|
}
|
||||||
.kx-login__logo-suffix {
|
.kx-login__logo-suffix {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
border-left: 1px solid var(--color-neutral-200);
|
border-left: 1px solid var(--color-neutral-200);
|
||||||
@ -185,7 +185,7 @@
|
|||||||
.kx-login__title {
|
.kx-login__title {
|
||||||
font-size: var(--fs-h1);
|
font-size: var(--fs-h1);
|
||||||
line-height: var(--lh-h1);
|
line-height: var(--lh-h1);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.kx-login__invite-link:hover {
|
.kx-login__invite-link:hover {
|
||||||
@ -259,7 +259,7 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-login__text-link:hover {
|
.kx-login__text-link:hover {
|
||||||
@ -308,7 +308,7 @@
|
|||||||
background: var(--color-success, #16a34a);
|
background: var(--color-success, #16a34a);
|
||||||
}
|
}
|
||||||
.kx-pw__label {
|
.kx-pw__label {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-pw__label--error {
|
.kx-pw__label--error {
|
||||||
@ -335,7 +335,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: var(--space-5);
|
bottom: var(--space-5);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── 공통 필드 ── */
|
/* ── 공통 필드 ── */
|
||||||
@ -346,7 +346,7 @@
|
|||||||
}
|
}
|
||||||
.kx-field label {
|
.kx-field label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-field input {
|
.kx-field input {
|
||||||
@ -383,7 +383,7 @@
|
|||||||
.kx-ws__header h1 {
|
.kx-ws__header h1 {
|
||||||
font-size: var(--fs-h1);
|
font-size: var(--fs-h1);
|
||||||
line-height: var(--lh-h1);
|
line-height: var(--lh-h1);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-ws__header p {
|
.kx-ws__header p {
|
||||||
@ -419,7 +419,7 @@
|
|||||||
.kx-ws__card-title {
|
.kx-ws__card-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
line-height: var(--lh-h3);
|
line-height: var(--lh-h3);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-ws__card-meta {
|
.kx-ws__card-meta {
|
||||||
@ -464,7 +464,7 @@
|
|||||||
.kx-modal__title {
|
.kx-modal__title {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
line-height: var(--lh-h2);
|
line-height: var(--lh-h2);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -494,7 +494,7 @@
|
|||||||
}
|
}
|
||||||
.kx-modal__blocked h3 {
|
.kx-modal__blocked h3 {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
}
|
}
|
||||||
.kx-modal__blocked p {
|
.kx-modal__blocked p {
|
||||||
@ -567,7 +567,7 @@
|
|||||||
.kx-otp__code-input {
|
.kx-otp__code-input {
|
||||||
letter-spacing: 6px;
|
letter-spacing: 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 20px;
|
font-size: var(--fs-h2);
|
||||||
}
|
}
|
||||||
.kx-otp__ok {
|
.kx-otp__ok {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
|
|||||||
@ -38,8 +38,8 @@
|
|||||||
|
|
||||||
/* 샘플 데이터 배지 */
|
/* 샘플 데이터 배지 */
|
||||||
.kx-sample {
|
.kx-sample {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
border: 1px solid #fcd9a8;
|
border: 1px solid #fcd9a8;
|
||||||
@ -50,8 +50,8 @@
|
|||||||
|
|
||||||
/* 오프라인 강등(폴백) 표시 — 집계 API 미연결 시 시연 데이터 안내 */
|
/* 오프라인 강등(폴백) 표시 — 집계 API 미연결 시 시연 데이터 안내 */
|
||||||
.kx-vis__degraded {
|
.kx-vis__degraded {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
border: 1px solid #fcd9a8;
|
border: 1px solid #fcd9a8;
|
||||||
@ -72,7 +72,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
@ -93,7 +93,7 @@
|
|||||||
}
|
}
|
||||||
.kx-kpi__unit {
|
.kx-kpi__unit {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
background: none;
|
background: none;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@
|
|||||||
}
|
}
|
||||||
.kx-mkt__campaign-top h3 {
|
.kx-mkt__campaign-top h3 {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@ -248,8 +248,8 @@
|
|||||||
/* 캠페인 상태 pill */
|
/* 캠페인 상태 pill */
|
||||||
.kx-mkt__cpill {
|
.kx-mkt__cpill {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
@ -277,7 +277,7 @@
|
|||||||
}
|
}
|
||||||
.kx-mkt__field-label {
|
.kx-mkt__field-label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin: var(--space-4) 0 var(--space-2);
|
margin: var(--space-4) 0 var(--space-2);
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -385,8 +385,8 @@
|
|||||||
.kx-mkt__preview-head {
|
.kx-mkt__preview-head {
|
||||||
padding: var(--space-2);
|
padding: var(--space-2);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
border-bottom: 1px solid var(--color-neutral-200);
|
border-bottom: 1px solid var(--color-neutral-200);
|
||||||
@ -409,7 +409,7 @@
|
|||||||
}
|
}
|
||||||
.kx-mkt__preview-title {
|
.kx-mkt__preview-title {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -422,7 +422,7 @@
|
|||||||
margin-top: var(--space-4);
|
margin-top: var(--space-4);
|
||||||
padding-top: var(--space-3);
|
padding-top: var(--space-3);
|
||||||
border-top: 1px solid var(--color-neutral-100);
|
border-top: 1px solid var(--color-neutral-100);
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-mkt__preview-links {
|
.kx-mkt__preview-links {
|
||||||
@ -463,8 +463,8 @@
|
|||||||
margin-bottom: var(--space-3);
|
margin-bottom: var(--space-3);
|
||||||
}
|
}
|
||||||
.kx-mkt__tier-badge {
|
.kx-mkt__tier-badge {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.08em;
|
letter-spacing: 0.08em;
|
||||||
color: var(--tier-accent, var(--color-primary-700));
|
color: var(--tier-accent, var(--color-primary-700));
|
||||||
background: color-mix(in srgb, var(--tier-accent, #0066b3) 12%, white);
|
background: color-mix(in srgb, var(--tier-accent, #0066b3) 12%, white);
|
||||||
@ -478,7 +478,7 @@
|
|||||||
}
|
}
|
||||||
.kx-mkt__tier-price {
|
.kx-mkt__tier-price {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
margin-bottom: var(--space-4);
|
margin-bottom: var(--space-4);
|
||||||
}
|
}
|
||||||
@ -511,7 +511,7 @@
|
|||||||
}
|
}
|
||||||
.kx-mkt__tier-remain {
|
.kx-mkt__tier-remain {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-mkt__tier-remain strong {
|
.kx-mkt__tier-remain strong {
|
||||||
@ -598,7 +598,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -619,8 +619,8 @@
|
|||||||
}
|
}
|
||||||
.kx-mkt__spill {
|
.kx-mkt__spill {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
@ -678,7 +678,7 @@
|
|||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-mkt__roi-link:hover {
|
.kx-mkt__roi-link:hover {
|
||||||
@ -714,5 +714,5 @@
|
|||||||
background: var(--kx-success-bg, #ecfdf5);
|
background: var(--kx-success-bg, #ecfdf5);
|
||||||
color: var(--kx-success-fg, #065f46);
|
color: var(--kx-success-fg, #065f46);
|
||||||
border: 1px solid var(--kx-success-border, #a7f3d0);
|
border: 1px solid var(--kx-success-border, #a7f3d0);
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,10 +66,10 @@
|
|||||||
}
|
}
|
||||||
.kx-m__accent {
|
.kx-m__accent {
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-m__offline {
|
.kx-m__offline {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
border: 1px solid var(--color-neutral-200);
|
border: 1px solid var(--color-neutral-200);
|
||||||
@ -99,7 +99,7 @@
|
|||||||
padding: 7px;
|
padding: 7px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@
|
|||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
padding: var(--space-3);
|
padding: var(--space-3);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@
|
|||||||
}
|
}
|
||||||
.kx-m__acc-head span:first-child {
|
.kx-m__acc-head span:first-child {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-m__acc-count {
|
.kx-m__acc-count {
|
||||||
@ -209,7 +209,7 @@
|
|||||||
border: 1px solid var(--color-neutral-200);
|
border: 1px solid var(--color-neutral-200);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
font-size: 20px;
|
font-size: var(--fs-h2);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@ -222,7 +222,7 @@
|
|||||||
}
|
}
|
||||||
.kx-m__warn h3 {
|
.kx-m__warn h3 {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@
|
|||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-m__rule {
|
.kx-m__rule {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -269,7 +269,7 @@
|
|||||||
border: 1px solid var(--color-neutral-200);
|
border: 1px solid var(--color-neutral-200);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
}
|
}
|
||||||
.kx-m__unit {
|
.kx-m__unit {
|
||||||
@ -283,7 +283,7 @@
|
|||||||
.kx-m__field-err {
|
.kx-m__field-err {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 하단 */
|
/* 하단 */
|
||||||
@ -302,7 +302,7 @@
|
|||||||
}
|
}
|
||||||
.kx-m__foot-note {
|
.kx-m__foot-note {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@
|
|||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-m__cta:disabled {
|
.kx-m__cta:disabled {
|
||||||
@ -353,12 +353,12 @@
|
|||||||
}
|
}
|
||||||
.kx-m__compare-head h2 {
|
.kx-m__compare-head h2 {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-m__flag {
|
.kx-m__flag {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
background: var(--color-ai-surface);
|
background: var(--color-ai-surface);
|
||||||
border: 1px solid var(--color-ai-accent);
|
border: 1px solid var(--color-ai-accent);
|
||||||
@ -388,7 +388,7 @@
|
|||||||
top: 6px;
|
top: 6px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
background: rgba(255, 255, 255, 0.85);
|
background: rgba(255, 255, 255, 0.85);
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
@ -399,7 +399,7 @@
|
|||||||
.kx-m__compare-div {
|
.kx-m__compare-div {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
}
|
}
|
||||||
.kx-m__dots {
|
.kx-m__dots {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -426,7 +426,7 @@
|
|||||||
}
|
}
|
||||||
.kx-m__ilist h3 {
|
.kx-m__ilist h3 {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
padding: 0 var(--space-1);
|
padding: 0 var(--space-1);
|
||||||
}
|
}
|
||||||
@ -458,9 +458,9 @@
|
|||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-m__icard-label small {
|
.kx-m__icard-label small {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
.kx-m__verdict {
|
.kx-m__verdict {
|
||||||
@ -477,7 +477,7 @@
|
|||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
.kx-dock__label {
|
.kx-dock__label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-dock__filters-spacer {
|
.kx-dock__filters-spacer {
|
||||||
@ -86,7 +86,7 @@
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
border-right: 1px solid var(--color-neutral-100);
|
border-right: 1px solid var(--color-neutral-100);
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -101,8 +101,8 @@
|
|||||||
.kx-dock__time {
|
.kx-dock__time {
|
||||||
padding: 10px 2px;
|
padding: 10px 2px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
border-right: 1px solid var(--color-neutral-100);
|
border-right: 1px solid var(--color-neutral-100);
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
border-right: 1px solid var(--color-neutral-100);
|
border-right: 1px solid var(--color-neutral-100);
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
@ -150,7 +150,7 @@
|
|||||||
margin: 4px 2px;
|
margin: 4px 2px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -164,7 +164,7 @@
|
|||||||
.kx-dock__block--priority {
|
.kx-dock__block--priority {
|
||||||
background: var(--color-violation-warn-bg);
|
background: var(--color-violation-warn-bg);
|
||||||
color: var(--color-violation-warn-text);
|
color: var(--color-violation-warn-text);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
border: 1px solid var(--color-violation-warn);
|
border: 1px solid var(--color-violation-warn);
|
||||||
}
|
}
|
||||||
.kx-dock__block-text {
|
.kx-dock__block-text {
|
||||||
@ -280,11 +280,11 @@
|
|||||||
}
|
}
|
||||||
.kx-dock__qr-title {
|
.kx-dock__qr-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.kx-dock__qr-sub {
|
.kx-dock__qr-sub {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
@ -338,7 +338,7 @@
|
|||||||
.kx-dock__chart-axis {
|
.kx-dock__chart-axis {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
padding: 0 2px;
|
padding: 0 2px;
|
||||||
}
|
}
|
||||||
@ -425,7 +425,7 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
.kx-logi__item-name {
|
.kx-logi__item-name {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-text, #101828);
|
color: var(--color-text, #101828);
|
||||||
}
|
}
|
||||||
.kx-logi__item-meta {
|
.kx-logi__item-meta {
|
||||||
@ -464,8 +464,8 @@
|
|||||||
color: #b42318;
|
color: #b42318;
|
||||||
}
|
}
|
||||||
.kx-logi__pill {
|
.kx-logi__pill {
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
top: var(--space-4);
|
top: var(--space-4);
|
||||||
left: var(--space-4);
|
left: var(--space-4);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
@ -76,7 +76,7 @@
|
|||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
}
|
}
|
||||||
.kx-ops__degraded-badge {
|
.kx-ops__degraded-badge {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -117,15 +117,15 @@
|
|||||||
box-shadow: inset 0 0 0 1px rgba(217, 45, 32, 0.25);
|
box-shadow: inset 0 0 0 1px rgba(217, 45, 32, 0.25);
|
||||||
}
|
}
|
||||||
.kx-ops__hall-label {
|
.kx-ops__hall-label {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
}
|
}
|
||||||
.kx-ops__hall-tag {
|
.kx-ops__hall-tag {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--space-3);
|
top: var(--space-3);
|
||||||
right: var(--space-3);
|
right: var(--space-3);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: var(--color-error);
|
background: var(--color-error);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -133,7 +133,7 @@
|
|||||||
}
|
}
|
||||||
.kx-ops__hall-people {
|
.kx-ops__hall-people {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +233,7 @@
|
|||||||
}
|
}
|
||||||
.kx-ops__pill {
|
.kx-ops__pill {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
@ -294,7 +294,7 @@
|
|||||||
|
|
||||||
/* 주차 */
|
/* 주차 */
|
||||||
.kx-ops__note {
|
.kx-ops__note {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-ops__zones {
|
.kx-ops__zones {
|
||||||
@ -318,12 +318,12 @@
|
|||||||
}
|
}
|
||||||
.kx-ops__zone-label {
|
.kx-ops__zone-label {
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-ops__zone-pct {
|
.kx-ops__zone-pct {
|
||||||
font-size: var(--fs-h2);
|
font-size: var(--fs-h2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-ops__zone-pct.is-success { color: var(--color-success); }
|
.kx-ops__zone-pct.is-success { color: var(--color-success); }
|
||||||
.kx-ops__zone-pct.is-warning { color: var(--color-warning); }
|
.kx-ops__zone-pct.is-warning { color: var(--color-warning); }
|
||||||
|
|||||||
@ -743,7 +743,8 @@
|
|||||||
}
|
}
|
||||||
.kxp-ecard__media {
|
.kxp-ecard__media {
|
||||||
position: relative;
|
position: relative;
|
||||||
aspect-ratio: 16 / 11;
|
/* 전시 포스터는 세로형(실측 0.67~0.8) — 세로 프레임으로 맞춰 왜곡/과다크롭 방지. */
|
||||||
|
aspect-ratio: 3 / 4;
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@ -4186,6 +4187,10 @@ a.kxp-ai__cite:hover {
|
|||||||
.kxp-ecard__poster {
|
.kxp-ecard__poster {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
/* 늘어남(distortion) 방지 — 비율 유지하며 프레임을 채운다. */
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
.kxp-ecard__posterfallback {
|
.kxp-ecard__posterfallback {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cv-title {
|
.kx-cv-title {
|
||||||
font-size: var(--fs-h3);
|
font-size: var(--fs-h3);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -119,7 +119,7 @@
|
|||||||
padding: var(--space-2);
|
padding: var(--space-2);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
border-bottom: 1px solid var(--color-neutral-200);
|
border-bottom: 1px solid var(--color-neutral-200);
|
||||||
@ -170,14 +170,14 @@
|
|||||||
/* 다른 달 날짜 숫자 — 흐린 회색(muted). */
|
/* 다른 달 날짜 숫자 — 흐린 회색(muted). */
|
||||||
.kx-cv-cell.is-out .kx-cv-daynum {
|
.kx-cv-cell.is-out .kx-cv-daynum {
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
}
|
}
|
||||||
/* 오늘 — 진한 아웃라인/알약 제거 → Nifty식 옅은 노랑 셀 틴트 + 숫자 강조. */
|
/* 오늘 — 진한 아웃라인/알약 제거 → Nifty식 옅은 노랑 셀 틴트 + 숫자 강조. */
|
||||||
.kx-cv-cell.is-today {
|
.kx-cv-cell.is-today {
|
||||||
background: var(--kx-cv-today-bg);
|
background: var(--kx-cv-today-bg);
|
||||||
}
|
}
|
||||||
.kx-cv-cell.is-today .kx-cv-daynum {
|
.kx-cv-cell.is-today .kx-cv-daynum {
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-cv-cell.is-selected {
|
.kx-cv-cell.is-selected {
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
@ -188,7 +188,7 @@
|
|||||||
left: var(--space-2);
|
left: var(--space-2);
|
||||||
height: var(--kx-cv-daynum-h);
|
height: var(--kx-cv-daynum-h);
|
||||||
line-height: var(--kx-cv-daynum-h);
|
line-height: var(--kx-cv-daynum-h);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
@ -207,8 +207,8 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
max-width: 72px;
|
max-width: 72px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -257,7 +257,7 @@
|
|||||||
background: color-mix(in srgb, var(--kx-bar-color) 14%, var(--color-white));
|
background: color-mix(in srgb, var(--kx-bar-color) 14%, var(--color-white));
|
||||||
color: color-mix(in srgb, var(--kx-bar-color) 72%, var(--color-neutral-900));
|
color: color-mix(in srgb, var(--kx-bar-color) 72%, var(--color-neutral-900));
|
||||||
border-left: 3px solid var(--kx-bar-color);
|
border-left: 3px solid var(--kx-bar-color);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: var(--kx-cv-bar-h);
|
line-height: var(--kx-cv-bar-h);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -295,7 +295,7 @@
|
|||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: color-mix(in srgb, var(--kx-bar-color, var(--color-primary-600)) 22%, transparent);
|
background: color-mix(in srgb, var(--kx-bar-color, var(--color-primary-600)) 22%, transparent);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-cv-bar:hover .kx-cv-bar-badge {
|
.kx-cv-bar:hover .kx-cv-bar-badge {
|
||||||
background: rgba(255, 255, 255, 0.25);
|
background: rgba(255, 255, 255, 0.25);
|
||||||
@ -312,8 +312,8 @@
|
|||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
@ -382,7 +382,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cv-day-head {
|
.kx-cv-day-head {
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-cv-day-list {
|
.kx-cv-day-list {
|
||||||
@ -405,7 +405,7 @@
|
|||||||
background: color-mix(in srgb, var(--kx-bar-color) 14%, var(--color-white));
|
background: color-mix(in srgb, var(--kx-bar-color) 14%, var(--color-white));
|
||||||
color: color-mix(in srgb, var(--kx-bar-color) 72%, var(--color-neutral-900));
|
color: color-mix(in srgb, var(--kx-bar-color) 72%, var(--color-neutral-900));
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -461,8 +461,8 @@
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
@ -541,11 +541,11 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-cv-more-item-range {
|
.kx-cv-more-item-range {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +562,7 @@
|
|||||||
min-height: 120px;
|
min-height: 120px;
|
||||||
}
|
}
|
||||||
.kx-cv-bar-title {
|
.kx-cv-bar-title {
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
}
|
}
|
||||||
/* 좁은 화면: 툴바 제목 고정폭 해제(가로 오버플로 방지). */
|
/* 좁은 화면: 툴바 제목 고정폭 해제(가로 오버플로 방지). */
|
||||||
.kx-cv-title {
|
.kx-cv-title {
|
||||||
@ -572,6 +572,6 @@
|
|||||||
}
|
}
|
||||||
.kx-cv-dow {
|
.kx-cv-dow {
|
||||||
padding: var(--space-1);
|
padding: var(--space-1);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,7 +125,7 @@
|
|||||||
/* 행사 상태 pill */
|
/* 행사 상태 pill */
|
||||||
.kx-evstatus {
|
.kx-evstatus {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -159,7 +159,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
font-size: 16px;
|
font-size: var(--fs-h3);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.kx-cal__nav:hover {
|
.kx-cal__nav:hover {
|
||||||
@ -172,7 +172,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cal__wd {
|
.kx-cal__wd {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@
|
|||||||
.kx-cal__cell.has-event {
|
.kx-cal__cell.has-event {
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-cal__cell.has-event::after {
|
.kx-cal__cell.has-event::after {
|
||||||
content: '';
|
content: '';
|
||||||
@ -206,13 +206,13 @@
|
|||||||
}
|
}
|
||||||
.kx-cal__cell.is-holiday {
|
.kx-cal__cell.is-holiday {
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
/* today — 진남색 알약 제거 → Nifty식 옅은 노랑 틴트 + 진한 숫자(회색 테두리 유지). */
|
/* today — 진남색 알약 제거 → Nifty식 옅은 노랑 틴트 + 진한 숫자(회색 테두리 유지). */
|
||||||
.kx-cal__cell.is-today {
|
.kx-cal__cell.is-today {
|
||||||
background: var(--color-warning-bg);
|
background: var(--color-warning-bg);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
}
|
}
|
||||||
.kx-cal__cell.is-today.has-event::after {
|
.kx-cal__cell.is-today.has-event::after {
|
||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
@ -263,7 +263,7 @@
|
|||||||
.kx-mcal__dow {
|
.kx-mcal__dow {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
padding: 6px 0;
|
padding: 6px 0;
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
@ -299,11 +299,11 @@
|
|||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
}
|
}
|
||||||
.kx-mcal__cell.is-today .kx-mcal__daynum {
|
.kx-mcal__cell.is-today .kx-mcal__daynum {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-mcal__chip {
|
.kx-mcal__chip {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
@ -329,7 +329,7 @@
|
|||||||
color: #1f7a54;
|
color: #1f7a54;
|
||||||
}
|
}
|
||||||
.kx-mcal__more {
|
.kx-mcal__more {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,15 +363,15 @@
|
|||||||
grid-template-columns: 1fr auto auto;
|
grid-template-columns: 1fr auto auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
.kx-availlist__label { color: var(--kx-text, #0f172a); }
|
.kx-availlist__label { color: var(--kx-text, #0f172a); }
|
||||||
.kx-availlist__meta { color: var(--kx-text-muted, #64748b); }
|
.kx-availlist__meta { color: var(--kx-text-muted, #64748b); }
|
||||||
.kx-availbadge {
|
.kx-availbadge {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-availbadge.is-open { color: #15803d; background: #f0fdf4; }
|
.kx-availbadge.is-open { color: #15803d; background: #f0fdf4; }
|
||||||
.kx-availbadge.is-full { color: #b45309; background: #fffbeb; }
|
.kx-availbadge.is-full { color: #b45309; background: #fffbeb; }
|
||||||
|
|||||||
@ -18,8 +18,9 @@
|
|||||||
}
|
}
|
||||||
.kx-settle__title {
|
.kx-settle__title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 22px;
|
font-size: var(--fs-h1);
|
||||||
font-weight: 700;
|
line-height: var(--lh-h1);
|
||||||
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-settle__subtitle {
|
.kx-settle__subtitle {
|
||||||
@ -63,7 +64,7 @@
|
|||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
}
|
}
|
||||||
.kx-settle__kpi-sub {
|
.kx-settle__kpi-sub {
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-settle__kpi--info {
|
.kx-settle__kpi--info {
|
||||||
@ -115,7 +116,7 @@
|
|||||||
}
|
}
|
||||||
.kx-settle__paynote {
|
.kx-settle__paynote {
|
||||||
margin: 12px 0 0;
|
margin: 12px 0 0;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,8 +162,8 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
.kx-settle__pill--muted {
|
.kx-settle__pill--muted {
|
||||||
@ -210,12 +211,12 @@
|
|||||||
}
|
}
|
||||||
.kx-settle__modal-head h2 {
|
.kx-settle__modal-head h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 16px;
|
font-size: var(--fs-h3);
|
||||||
}
|
}
|
||||||
.kx-settle__close {
|
.kx-settle__close {
|
||||||
border: none;
|
border: none;
|
||||||
background: none;
|
background: none;
|
||||||
font-size: 16px;
|
font-size: var(--fs-h3);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -235,13 +236,13 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
.kx-settle__meta-k {
|
.kx-settle__meta-k {
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-settle__meta-v {
|
.kx-settle__meta-v {
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kx-settle__lines {
|
.kx-settle__lines {
|
||||||
@ -252,14 +253,14 @@
|
|||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-settle__total-row td {
|
.kx-settle__total-row td {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
border-top: 1px solid var(--color-neutral-200);
|
border-top: 1px solid var(--color-neutral-200);
|
||||||
}
|
}
|
||||||
.kx-settle__cat {
|
.kx-settle__cat {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
background: var(--color-primary-050);
|
background: var(--color-primary-050);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
@ -269,7 +270,7 @@
|
|||||||
|
|
||||||
.kx-settle__pay-hist h3 {
|
.kx-settle__pay-hist h3 {
|
||||||
margin: 0 0 8px;
|
margin: 0 0 8px;
|
||||||
font-size: 14px;
|
font-size: var(--fs-body);
|
||||||
}
|
}
|
||||||
.kx-settle__pay-hist ul {
|
.kx-settle__pay-hist ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@ -289,7 +290,7 @@
|
|||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
}
|
}
|
||||||
.kx-settle__pay-method {
|
.kx-settle__pay-method {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
border: 1px solid var(--color-neutral-200);
|
border: 1px solid var(--color-neutral-200);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
@ -328,11 +329,11 @@
|
|||||||
}
|
}
|
||||||
.kx-settle__form-error {
|
.kx-settle__form-error {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
}
|
}
|
||||||
.kx-settle__muted {
|
.kx-settle__muted {
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
@ -343,8 +344,8 @@
|
|||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
padding: 1px 7px;
|
padding: 1px 7px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -368,7 +369,7 @@
|
|||||||
.kx-settle__tax h3 {
|
.kx-settle__tax h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-settle__tax-doc {
|
.kx-settle__tax-doc {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -381,14 +382,14 @@
|
|||||||
.kx-settle__tax-row {
|
.kx-settle__tax-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
.kx-settle__tax-amounts {
|
.kx-settle__tax-amounts {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
.kx-settle__cancel {
|
.kx-settle__cancel {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
@ -404,7 +405,7 @@
|
|||||||
.kx-settle__cancel-box h4 {
|
.kx-settle__cancel-box h4 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-settle__refund {
|
.kx-settle__refund {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -414,7 +415,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
.kx-settle__refund-row--em {
|
.kx-settle__refund-row--em {
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
@ -455,5 +456,5 @@
|
|||||||
.kx-settle__report-group h3 {
|
.kx-settle__report-group h3 {
|
||||||
margin: 0 0 6px;
|
margin: 0 0 6px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,13 +14,23 @@
|
|||||||
gap: var(--space-5);
|
gap: var(--space-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 카드 */
|
/* ══════════════════════════════════════════════════════════
|
||||||
|
* 카드 정본 — Nifty 카드 계보
|
||||||
|
* 라운딩 8px · 1px 중립 테두리 · subtle 그림자 · hover elevation.
|
||||||
|
* 각진/미클립 카드 0 목표: 미디어 카드는 .kx-card--flush + __media 로 모서리 클립.
|
||||||
|
* ══════════════════════════════════════════════════════════ */
|
||||||
.kx-card {
|
.kx-card {
|
||||||
border: var(--border-card);
|
border: var(--border-card);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
padding: var(--space-4);
|
padding: var(--space-4);
|
||||||
|
box-shadow: var(--shadow-card);
|
||||||
|
transition: box-shadow 0.15s ease, border-color 0.15s ease;
|
||||||
}
|
}
|
||||||
|
.kx-card:hover {
|
||||||
|
box-shadow: var(--shadow-level2);
|
||||||
|
}
|
||||||
|
/* 헤더 행(현행) — 제목 + 우측 액션 */
|
||||||
.kx-card__head {
|
.kx-card__head {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -38,6 +48,75 @@
|
|||||||
margin: -4px 0 var(--space-3);
|
margin: -4px 0 var(--space-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Nifty 구조형 카드 (헤더/바디/푸터·미디어 클립) ──
|
||||||
|
* .kx-card--flush 로 카드 자체 패딩 제거 + overflow:hidden(미디어를 라운딩에 클립).
|
||||||
|
* 구획별 패딩·neutral-200 구분선은 각 파트가 담당. */
|
||||||
|
.kx-card--flush {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.kx-card__media {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--color-neutral-100);
|
||||||
|
}
|
||||||
|
.kx-card__media > img,
|
||||||
|
.kx-card__media > video,
|
||||||
|
.kx-card__media > canvas,
|
||||||
|
.kx-card__media > svg {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
.kx-card__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: var(--space-3);
|
||||||
|
padding: var(--space-3) var(--space-4);
|
||||||
|
border-bottom: 1px solid var(--color-neutral-200);
|
||||||
|
}
|
||||||
|
.kx-card__header h2,
|
||||||
|
.kx-card__header h3 {
|
||||||
|
font-size: var(--fs-h3);
|
||||||
|
line-height: var(--lh-h3);
|
||||||
|
color: var(--color-neutral-900);
|
||||||
|
}
|
||||||
|
.kx-card__body {
|
||||||
|
padding: var(--space-4);
|
||||||
|
}
|
||||||
|
.kx-card__footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
padding: var(--space-3) var(--space-4);
|
||||||
|
border-top: 1px solid var(--color-neutral-200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ══════════════════════════════════════════════════════════
|
||||||
|
* 공용 제목 클래스 — 페이지/섹션 제목 편차(20/22/26/30px) 근본 해소.
|
||||||
|
* 역할↔토큰 1:1 고정. 화면별 제목은 이 클래스로 수렴한다.
|
||||||
|
* ══════════════════════════════════════════════════════════ */
|
||||||
|
.kx-page__title {
|
||||||
|
font-size: var(--fs-h1);
|
||||||
|
line-height: var(--lh-h1);
|
||||||
|
font-weight: var(--fw-bold);
|
||||||
|
color: var(--color-neutral-900);
|
||||||
|
}
|
||||||
|
.kx-page__subtitle {
|
||||||
|
font-size: var(--fs-body);
|
||||||
|
line-height: var(--lh-body);
|
||||||
|
color: var(--color-neutral-500);
|
||||||
|
}
|
||||||
|
.kx-section__title {
|
||||||
|
font-size: var(--fs-h2);
|
||||||
|
line-height: var(--lh-h2);
|
||||||
|
font-weight: var(--fw-semibold);
|
||||||
|
color: var(--color-neutral-900);
|
||||||
|
}
|
||||||
|
|
||||||
/* 세그먼트 토글 */
|
/* 세그먼트 토글 */
|
||||||
.kx-seg {
|
.kx-seg {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
@ -52,7 +131,7 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -73,7 +152,7 @@
|
|||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* KPI 카드(공통) */
|
/* KPI 카드(공통) — 카드 정본과 동일 Nifty 엘리베이션 */
|
||||||
.kx-kpi {
|
.kx-kpi {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -82,6 +161,11 @@
|
|||||||
border: var(--border-card);
|
border: var(--border-card);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
|
box-shadow: var(--shadow-card);
|
||||||
|
transition: box-shadow 0.15s ease;
|
||||||
|
}
|
||||||
|
.kx-kpi:hover {
|
||||||
|
box-shadow: var(--shadow-level2);
|
||||||
}
|
}
|
||||||
.kx-kpi__label {
|
.kx-kpi__label {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -92,13 +176,13 @@
|
|||||||
}
|
}
|
||||||
.kx-kpi__ai {
|
.kx-kpi__ai {
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
}
|
}
|
||||||
.kx-kpi__value {
|
.kx-kpi__value {
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: var(--lh-display);
|
line-height: var(--lh-display);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-kpi__sub {
|
.kx-kpi__sub {
|
||||||
@ -116,7 +200,7 @@
|
|||||||
.kx-delta {
|
.kx-delta {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
@ -131,7 +215,7 @@
|
|||||||
|
|
||||||
/* degraded 배지 */
|
/* degraded 배지 */
|
||||||
.kx-bi__degraded {
|
.kx-bi__degraded {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: var(--color-warning-bg);
|
background: var(--color-warning-bg);
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -160,7 +244,7 @@
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
@ -190,6 +274,41 @@
|
|||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── 비교 매트릭스 표준 (.kx-matrix) — 목록 표준과 분리된 의도적 패턴.
|
||||||
|
* 헤더 강조(neutral-900/700)·중앙 정렬·항목별 1px 셀 보더. auction 낙찰 비교 등. */
|
||||||
|
.kx-matrix {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: var(--fs-body);
|
||||||
|
color: var(--color-neutral-700);
|
||||||
|
}
|
||||||
|
.kx-matrix th,
|
||||||
|
.kx-matrix td {
|
||||||
|
padding: var(--space-3) var(--space-4);
|
||||||
|
border: 1px solid var(--color-neutral-200);
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.kx-matrix thead th {
|
||||||
|
font-size: var(--fs-caption);
|
||||||
|
font-weight: var(--fw-bold);
|
||||||
|
color: var(--color-neutral-900);
|
||||||
|
background: var(--color-neutral-050);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.kx-matrix tbody th {
|
||||||
|
font-weight: var(--fw-semibold);
|
||||||
|
color: var(--color-neutral-900);
|
||||||
|
text-align: left;
|
||||||
|
background: var(--color-neutral-050);
|
||||||
|
}
|
||||||
|
.kx-matrix .kx-num {
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 참고: docs 리포트 표(.kx-rep__table)는 A4 종이 시뮬레이션(고정 흰 배경·고정 잉크색)이라
|
||||||
|
* 테마 토큰(다크서 반전) 부적합 + 신규 인쇄색 토큰 금지 → 의도적 테마 독립 예외로 유지한다. */
|
||||||
|
|
||||||
/* 가로 막대 리스트 */
|
/* 가로 막대 리스트 */
|
||||||
.kx-barlist {
|
.kx-barlist {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@ -223,7 +342,7 @@
|
|||||||
.kx-grade {
|
.kx-grade {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
.kx-sg__eyebrow {
|
.kx-sg__eyebrow {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
@ -92,9 +92,9 @@
|
|||||||
border-bottom: var(--border-card);
|
border-bottom: var(--border-card);
|
||||||
margin-bottom: var(--space-4);
|
margin-bottom: var(--space-4);
|
||||||
}
|
}
|
||||||
.kx-sg__t-display { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-sg__t-display { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-sg__t-headline { font-size: var(--fs-h1); line-height: var(--lh-h1); font-weight: 700; color: var(--color-neutral-900); }
|
.kx-sg__t-headline { font-size: var(--fs-h1); line-height: var(--lh-h1); font-weight: var(--fw-bold); color: var(--color-neutral-900); }
|
||||||
.kx-sg__t-title { font-size: var(--fs-h3); font-weight: 600; color: var(--color-neutral-700); }
|
.kx-sg__t-title { font-size: var(--fs-h3); font-weight: var(--fw-semibold); color: var(--color-neutral-700); }
|
||||||
.kx-sg__t-body { font-size: var(--fs-body); color: var(--color-neutral-700); }
|
.kx-sg__t-body { font-size: var(--fs-body); color: var(--color-neutral-700); }
|
||||||
|
|
||||||
.kx-sg__swatches {
|
.kx-sg__swatches {
|
||||||
@ -120,7 +120,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
.kx-sg__swatch-hex {
|
.kx-sg__swatch-hex {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +144,7 @@
|
|||||||
}
|
}
|
||||||
.kx-sg__viol {
|
.kx-sg__viol {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
background: #fef3f2;
|
background: #fef3f2;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
@ -225,7 +225,7 @@
|
|||||||
.kx-sg__err-msg {
|
.kx-sg__err-msg {
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
}
|
}
|
||||||
.kx-sg__check-row {
|
.kx-sg__check-row {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
@ -254,7 +254,7 @@
|
|||||||
background: #fef3f2;
|
background: #fef3f2;
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
padding: 10px var(--space-4);
|
padding: 10px var(--space-4);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
border: 1px solid rgba(217, 45, 32, 0.3);
|
border: 1px solid rgba(217, 45, 32, 0.3);
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 16px;
|
font-size: var(--fs-h3);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-uord__wizard {
|
.kx-uord__wizard {
|
||||||
@ -55,8 +55,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
background: var(--color-neutral-200);
|
background: var(--color-neutral-200);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@
|
|||||||
}
|
}
|
||||||
.kx-uord__wizard li.is-current {
|
.kx-uord__wizard li.is-current {
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-uord__wizard li.is-current::before {
|
.kx-uord__wizard li.is-current::before {
|
||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
@ -119,8 +119,8 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: var(--space-3);
|
bottom: var(--space-3);
|
||||||
right: var(--space-3);
|
right: var(--space-3);
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
background: rgba(255, 255, 255, 0.9);
|
background: rgba(255, 255, 255, 0.9);
|
||||||
border: 1px solid var(--color-primary-100);
|
border: 1px solid var(--color-primary-100);
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-violation-warn-text);
|
color: var(--color-violation-warn-text);
|
||||||
background: var(--color-violation-warn-bg);
|
background: var(--color-violation-warn-bg);
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@
|
|||||||
padding: 6px 14px;
|
padding: 6px 14px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-util__tab.is-active {
|
.kx-util__tab.is-active {
|
||||||
@ -110,7 +110,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
font-size: 12px;
|
font-size: var(--fs-caption);
|
||||||
}
|
}
|
||||||
.kx-devtable__del:hover {
|
.kx-devtable__del:hover {
|
||||||
color: var(--color-error);
|
color: var(--color-error);
|
||||||
@ -123,7 +123,7 @@
|
|||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kx-util__compute {
|
.kx-util__compute {
|
||||||
@ -200,7 +200,7 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
.kx-quote__amount {
|
.kx-quote__amount {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-quote__total {
|
.kx-quote__total {
|
||||||
@ -216,12 +216,12 @@
|
|||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-quote__disclaimer {
|
.kx-quote__disclaimer {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-quote__ruleset {
|
.kx-quote__ruleset {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-quote__empty {
|
.kx-quote__empty {
|
||||||
@ -239,14 +239,14 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
.kx-quote__submitted-title {
|
.kx-quote__submitted-title {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
}
|
}
|
||||||
.kx-quote__relay {
|
.kx-quote__relay {
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-quote__diagram {
|
.kx-quote__diagram {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-util__banner {
|
.kx-util__banner {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: #fde68a;
|
color: #fde68a;
|
||||||
background: rgba(180, 83, 9, 0.28);
|
background: rgba(180, 83, 9, 0.28);
|
||||||
border: 1px solid rgba(253, 224, 71, 0.4);
|
border: 1px solid rgba(253, 224, 71, 0.4);
|
||||||
@ -102,7 +102,7 @@
|
|||||||
.kx-wire__path-label {
|
.kx-wire__path-label {
|
||||||
fill: var(--color-white);
|
fill: var(--color-white);
|
||||||
font-size: 1.4px;
|
font-size: 1.4px;
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
paint-order: stroke;
|
paint-order: stroke;
|
||||||
stroke: rgba(16, 24, 40, 0.85);
|
stroke: rgba(16, 24, 40, 0.85);
|
||||||
|
|||||||
@ -316,5 +316,5 @@
|
|||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-checkin__inside-sub b { color: var(--color-neutral-700); font-weight: 600; }
|
.kx-checkin__inside-sub b { color: var(--color-neutral-700); font-weight: var(--fw-semibold); }
|
||||||
.kx-checkin__hours { min-width: 0; }
|
.kx-checkin__hours { min-width: 0; }
|
||||||
|
|||||||
@ -38,8 +38,8 @@
|
|||||||
|
|
||||||
/* 샘플 데이터 배지 */
|
/* 샘플 데이터 배지 */
|
||||||
.kx-sample {
|
.kx-sample {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
border: 1px solid #fcd9a8;
|
border: 1px solid #fcd9a8;
|
||||||
@ -50,8 +50,8 @@
|
|||||||
|
|
||||||
/* 오프라인 강등(폴백) 표시 — 집계 API 미연결 시 시연 데이터 안내 */
|
/* 오프라인 강등(폴백) 표시 — 집계 API 미연결 시 시연 데이터 안내 */
|
||||||
.kx-vis__degraded {
|
.kx-vis__degraded {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-warning);
|
color: var(--color-warning);
|
||||||
background: #fff4e5;
|
background: #fff4e5;
|
||||||
border: 1px solid #fcd9a8;
|
border: 1px solid #fcd9a8;
|
||||||
@ -139,7 +139,7 @@
|
|||||||
}
|
}
|
||||||
.kx-vis__donut-title {
|
.kx-vis__donut-title {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
@ -202,8 +202,8 @@
|
|||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-vis__form-state {
|
.kx-vis__form-state {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
background: var(--color-neutral-050);
|
background: var(--color-neutral-050);
|
||||||
border: 1px solid var(--color-neutral-200);
|
border: 1px solid var(--color-neutral-200);
|
||||||
@ -250,7 +250,7 @@
|
|||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
font-size: 8px;
|
font-size: 8px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
letter-spacing: 0.14em;
|
letter-spacing: 0.14em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
@ -261,7 +261,7 @@
|
|||||||
}
|
}
|
||||||
.kx-badgecard__name {
|
.kx-badgecard__name {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
}
|
}
|
||||||
.kx-badgecard__org {
|
.kx-badgecard__org {
|
||||||
@ -279,7 +279,7 @@
|
|||||||
}
|
}
|
||||||
.kx-badgecard__tag {
|
.kx-badgecard__tag {
|
||||||
font-size: 7px;
|
font-size: 7px;
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: var(--color-ai-accent);
|
background: var(--color-ai-accent);
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
@ -295,7 +295,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.kx-vis__pii-note {
|
.kx-vis__pii-note {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-vis__person {
|
.kx-vis__person {
|
||||||
@ -303,7 +303,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-3);
|
gap: var(--space-3);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-weight: 500;
|
font-weight: var(--fw-medium);
|
||||||
}
|
}
|
||||||
.kx-vis__avatar {
|
.kx-vis__avatar {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
@ -313,7 +313,7 @@
|
|||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
color: var(--color-primary-700);
|
color: var(--color-primary-700);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -328,8 +328,8 @@
|
|||||||
/* 유형 pill */
|
/* 유형 pill */
|
||||||
.kx-vis__type {
|
.kx-vis__type {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-vis__checkin.is-done {
|
.kx-vis__checkin.is-done {
|
||||||
color: var(--color-success);
|
color: var(--color-success);
|
||||||
@ -379,7 +379,7 @@
|
|||||||
gap: 5px;
|
gap: 5px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
color: var(--color-primary-600);
|
color: var(--color-primary-600);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-vis__badge-none {
|
.kx-vis__badge-none {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
@ -425,7 +425,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
background: var(--color-neutral-100);
|
background: var(--color-neutral-100);
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
@ -450,7 +450,7 @@
|
|||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
.kx-vis__lead-name {
|
.kx-vis__lead-name {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,8 +488,8 @@
|
|||||||
background: var(--color-ai-accent);
|
background: var(--color-ai-accent);
|
||||||
}
|
}
|
||||||
.kx-gauge__num {
|
.kx-gauge__num {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-on-accent);
|
color: var(--color-on-accent);
|
||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
@ -523,8 +523,8 @@
|
|||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-vis__hot {
|
.kx-vis__hot {
|
||||||
font-size: 10px;
|
font-size: var(--fs-nano);
|
||||||
font-weight: 800;
|
font-weight: var(--fw-bold);
|
||||||
color: #4500d8;
|
color: #4500d8;
|
||||||
background: #e9e3ff;
|
background: #e9e3ff;
|
||||||
padding: 2px 7px;
|
padding: 2px 7px;
|
||||||
@ -557,7 +557,7 @@
|
|||||||
.kx-vis__ai-score {
|
.kx-vis__ai-score {
|
||||||
font-size: var(--fs-display);
|
font-size: var(--fs-display);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
}
|
}
|
||||||
.kx-vis__ai-actions {
|
.kx-vis__ai-actions {
|
||||||
@ -588,7 +588,7 @@
|
|||||||
}
|
}
|
||||||
.kx-vis__ai-check {
|
.kx-vis__ai-check {
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +600,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
margin-bottom: var(--space-2);
|
margin-bottom: var(--space-2);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@
|
|||||||
}
|
}
|
||||||
.kx-label {
|
.kx-label {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-input,
|
.kx-input,
|
||||||
@ -104,7 +104,7 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
border-bottom: 2px solid var(--color-neutral-200);
|
border-bottom: 2px solid var(--color-neutral-200);
|
||||||
@ -130,7 +130,7 @@
|
|||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
}
|
}
|
||||||
.kx-list-table__title {
|
.kx-list-table__title {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-list-table__muted {
|
.kx-list-table__muted {
|
||||||
@ -149,7 +149,7 @@
|
|||||||
padding: 1px 10px;
|
padding: 1px 10px;
|
||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.kx-pill--neutral {
|
.kx-pill--neutral {
|
||||||
@ -246,7 +246,7 @@
|
|||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-thread__author {
|
.kx-thread__author {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-thread__text {
|
.kx-thread__text {
|
||||||
@ -297,7 +297,7 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@ -338,7 +338,7 @@
|
|||||||
background: var(--color-primary-100);
|
background: var(--color-primary-100);
|
||||||
}
|
}
|
||||||
.kx-msg__item.is-unread .kx-msg__item-title {
|
.kx-msg__item.is-unread .kx-msg__item-title {
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
}
|
}
|
||||||
.kx-msg__item-top {
|
.kx-msg__item-top {
|
||||||
@ -396,7 +396,7 @@
|
|||||||
border-radius: var(--radius-pill);
|
border-radius: var(--radius-pill);
|
||||||
padding: 2px 6px 2px 10px;
|
padding: 2px 6px 2px 10px;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
}
|
}
|
||||||
.kx-tag button {
|
.kx-tag button {
|
||||||
border: none;
|
border: none;
|
||||||
@ -445,7 +445,7 @@
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-cal__wd--sun {
|
.kx-cal__wd--sun {
|
||||||
@ -474,7 +474,7 @@
|
|||||||
}
|
}
|
||||||
.kx-cal__daynum {
|
.kx-cal__daynum {
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
}
|
}
|
||||||
.kx-cal__cell.is-today .kx-cal__daynum {
|
.kx-cal__cell.is-today .kx-cal__daynum {
|
||||||
@ -488,7 +488,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.kx-cal__event {
|
.kx-cal__event {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -498,7 +498,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.kx-cal__more {
|
.kx-cal__more {
|
||||||
font-size: 11px;
|
font-size: var(--fs-micro);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
}
|
}
|
||||||
.kx-cal__legend {
|
.kx-cal__legend {
|
||||||
@ -575,7 +575,7 @@
|
|||||||
background: var(--color-ai-surface);
|
background: var(--color-ai-surface);
|
||||||
color: var(--color-ai-accent);
|
color: var(--color-ai-accent);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -595,7 +595,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-500);
|
color: var(--color-neutral-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-bottom: 2px solid transparent;
|
border-bottom: 2px solid transparent;
|
||||||
@ -696,7 +696,7 @@
|
|||||||
border: var(--border-card);
|
border: var(--border-card);
|
||||||
background: var(--color-white);
|
background: var(--color-white);
|
||||||
font-size: var(--fs-caption);
|
font-size: var(--fs-caption);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -731,7 +731,7 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
.kx-noti__title {
|
.kx-noti__title {
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-900);
|
color: var(--color-neutral-900);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
}
|
}
|
||||||
@ -782,7 +782,7 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
font-size: var(--fs-body);
|
font-size: var(--fs-body);
|
||||||
font-weight: 600;
|
font-weight: var(--fw-semibold);
|
||||||
color: var(--color-neutral-700);
|
color: var(--color-neutral-700);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -797,7 +797,7 @@
|
|||||||
background: var(--color-primary-600);
|
background: var(--color-primary-600);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
font-weight: 700;
|
font-weight: var(--fw-bold);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@ -75,6 +75,7 @@
|
|||||||
--ai-skeleton-a: var(--dk-ai-skeleton-a);
|
--ai-skeleton-a: var(--dk-ai-skeleton-a);
|
||||||
--ai-skeleton-b: var(--dk-ai-skeleton-b);
|
--ai-skeleton-b: var(--dk-ai-skeleton-b);
|
||||||
--focus-ring: var(--dk-primary-700);
|
--focus-ring: var(--dk-primary-700);
|
||||||
|
--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4);
|
||||||
--shadow-level2: 0 4px 12px rgba(0, 0, 0, 0.5);
|
--shadow-level2: 0 4px 12px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +114,7 @@
|
|||||||
--ai-skeleton-a: var(--dk-ai-skeleton-a);
|
--ai-skeleton-a: var(--dk-ai-skeleton-a);
|
||||||
--ai-skeleton-b: var(--dk-ai-skeleton-b);
|
--ai-skeleton-b: var(--dk-ai-skeleton-b);
|
||||||
--focus-ring: var(--dk-primary-700);
|
--focus-ring: var(--dk-primary-700);
|
||||||
|
--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4);
|
||||||
--shadow-level2: 0 4px 12px rgba(0, 0, 0, 0.5);
|
--shadow-level2: 0 4px 12px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,8 +66,19 @@
|
|||||||
--lh-body: 22px;
|
--lh-body: 22px;
|
||||||
--fs-caption: 12px;
|
--fs-caption: 12px;
|
||||||
--lh-caption: 18px;
|
--lh-caption: 18px;
|
||||||
|
/* 마이크로 라벨(비공식 계층 공식화) — audit: 11px 128건 흡수 */
|
||||||
|
--fs-micro: 11px;
|
||||||
|
--lh-micro: 16px;
|
||||||
|
/* 초소형(배지·QR·범례) — 10/9/8px 수렴 */
|
||||||
|
--fs-nano: 10px;
|
||||||
--fs-mono: 13px;
|
--fs-mono: 13px;
|
||||||
|
|
||||||
|
/* ── 폰트 웨이트 토큰 (audit P0) — 페이지 간 700/600/500/800 혼용 수렴 ── */
|
||||||
|
--fw-regular: 400;
|
||||||
|
--fw-medium: 500;
|
||||||
|
--fw-semibold: 600;
|
||||||
|
--fw-bold: 700; /* 800 남발 → 700 수렴 (display/hero 예외만 인라인) */
|
||||||
|
|
||||||
/* ── 라운드 (§1-4) — 최대 8px, 칩은 pill ── */
|
/* ── 라운드 (§1-4) — 최대 8px, 칩은 pill ── */
|
||||||
--radius-sm: 4px; /* 버튼·인풋·작은 요소 */
|
--radius-sm: 4px; /* 버튼·인풋·작은 요소 */
|
||||||
--radius-lg: 8px; /* 카드·모달·섹션 */
|
--radius-lg: 8px; /* 카드·모달·섹션 */
|
||||||
@ -75,7 +86,8 @@
|
|||||||
|
|
||||||
/* ── 엘리베이션 — 톤 레이어 + 1px 테두리 ── */
|
/* ── 엘리베이션 — 톤 레이어 + 1px 테두리 ── */
|
||||||
--border-card: 1px solid var(--color-neutral-200);
|
--border-card: 1px solid var(--color-neutral-200);
|
||||||
--shadow-level2: 0 4px 12px rgba(16, 24, 40, 0.1);
|
--shadow-card: 0 1px 2px rgba(16, 24, 40, 0.06); /* Nifty 카드 기본(subtle) */
|
||||||
|
--shadow-level2: 0 4px 12px rgba(16, 24, 40, 0.1); /* 카드 hover 상승 */
|
||||||
--accent-ai: 4px solid var(--color-ai-accent); /* AI 카드 좌측 액센트 */
|
--accent-ai: 4px solid var(--color-ai-accent); /* AI 카드 좌측 액센트 */
|
||||||
|
|
||||||
/* ── 그리드·간격 (§1-4) — 4px 베이스 ── */
|
/* ── 그리드·간격 (§1-4) — 4px 베이스 ── */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user