diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..f991fec --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,444 @@ +# DESIGN.md — EAPIM Portal 디자인 시스템 + +제주은행(DJBank) ERP뱅킹 API 개발자 포털의 디자인 토큰·컴포넌트 규약. + +> **출처**: 이 문서는 Figma Design Guide 원본이 아니라 **현재 코드베이스(`src/main/resources/static/sass/`, `templates/`)에서 역추출**한 실사용 기준이다. +> Figma 가이드와 불일치하는 지점은 §9 "알려진 불일치"에 정리했다. 원본 대조가 필요하면 Figma 파일을 Figma로 열고 MCP 경유로 토큰을 추출해 이 문서를 갱신한다. + +--- + +## 1. 소스 구조 / 빌드 + +``` +src/main/resources/static/ +├── sass/ ← 스타일 단일 소스 (여기만 수정) +│ ├── abstracts/ _variables · _mixins · _color-functions +│ ├── base/ _reset · _typography · _animations · _djb-font · _utilities +│ ├── layout/ _header · _footer · _grid · _container +│ ├── components/ 버튼·뱃지·카드·폼·테이블·모달·… (26개) +│ ├── pages/ 페이지별 스타일 (24개) +│ ├── themes/ _dark (현재 비어 있음) +│ ├── vendors/ _overrides +│ └── main.scss 단일 엔트리포인트 +├── css/main.css ← 컴파일 산출물 (직접 수정 금지) +├── font/ shinhan · spoqa-hans · noto-sans +├── img/ logo · icon · favicon · 페이지 이미지 +└── js/ common.js · djb/* · lib/* · 벤더 +``` + +컴파일: + +```bash +sass src/main/resources/static/sass/main.scss src/main/resources/static/css/main.css +``` + +**규칙** +- `css/main.css`는 산출물이다. **직접 수정 금지**, 반드시 SASS를 고치고 재컴파일한다. +- Dart Sass `@use` 기반. 새 파샬은 `main.scss`의 해당 섹션(base → layout → components → pages → themes → utilities → vendors)에 `@use`로 등록한다. **utilities는 항상 뒤쪽**(`!important` 유틸이 컴포넌트를 이겨야 함). +- 파샬 상단은 항상 다음 3줄로 시작한다: + ```scss + @use '../abstracts/variables' as *; + @use '../abstracts/color-functions' as *; + @use '../abstracts/mixins' as *; + ``` +- `darken()` / `lighten()`은 전역 함수가 아니라 `abstracts/_color-functions.scss`의 `color.scale` 래퍼다(Dart Sass 3.0 호환). 새 파샬에서 쓰려면 위 `@use`가 반드시 있어야 한다. +- 빌드 트리(`build/resources/...`)를 서빙 중인 서버가 있을 수 있다. 수정 전 어느 트리를 서빙하는지 확인하고, 필요 시 `src` → `build` 동기화한다. +- 템플릿/CSS/JS는 서버 프로파일에 따라 기동 시점 고정될 수 있다 → 반영 안 되면 재시작. + +--- + +## 2. 컬러 + +정의: `sass/abstracts/_variables.scss` + +### 브랜드 / 주색 + +| 토큰 | 값 | 용도 | +|---|---|---| +| `$primary-color` | `#0049B4` | `$primary-blue`와 동일 값(중복 정의) | +| `$primary-blue` | `#0049b4` | 주 브랜드 블루. 링크·주버튼·포커스링·활성상태 | +| `$secondary-blue` | `#c3dfea` | 연한 블루. hover 보조·링크 hover | +| `$main-bg` | `#EDF9FE` | 페이지 배경 톤 | + +### 액센트 + +| 토큰 | 값 | 의미 | +|---|---|---| +| `$accent-cyan` | `#00D4FF` | 강조 | +| `$accent-yellow` | `#FFD93D` | 경고 / 진행중(processing) / popular | +| `$accent-orange` | `#FF6B6B` | **에러·삭제·필수표시**(실질적 danger 컬러) | +| `$accent-green` | `#6BCF7F` | 성공·완료·신규 | +| `$accent-purple` | `#A78BFA` | beta 뱃지 | + +### 중립 + +| 토큰 | 값 | 용도 | +|---|---|---| +| `$text-dark` | `#1A1A2E` | 본문 기본 | +| `$text-gray` | `#64748B` | 보조 텍스트·테이블 td | +| `$text-light` | `#94A3B8` | placeholder·비활성 | +| `$white` | `#FFFFFF` | | +| `$gray-bg` | `#F8FAFC` | 연한 배경·disabled | +| `$light-bg` | `#EFF6FF` | 블루 틴트 배경·테이블 thead·뱃지 배경 | +| `$border-gray` | `#E2E8F0` | 기본 보더 | +| `$black` `#000000` / `$gray-800` `#1F2937` / `$gray-900` `#111827` | | | + +### 그림자 + +```scss +$shadow-sm: 0 2px 4px rgba(0,0,0,.05); +$shadow-md: 0 4px 12px rgba(75,155,255,.10); +$shadow-lg: 0 8px 24px rgba(75,155,255,.15); +$shadow-xl: 0 16px 40px rgba(75,155,255,.20); +``` +md 이상은 **블루 틴트 그림자**다. 중립 그림자가 필요하면 `$shadow-sm`을 쓴다. + +### 상태색 관용구 + +투명도 배경 + 원색 텍스트 패턴이 표준이다. + +```scss +background: rgba($accent-green, 0.1); +color: $accent-green; +``` + +--- + +## 3. 타이포그래피 + +### 폰트 패밀리 + +| 토큰 | 스택 | 용도 | +|---|---|---| +| `$font-family-heading` | `OneShinhan` → Spoqa Han Sans Neo → SpoqaHanSans → Noto Sans KR → system | **제목 전용** | +| `$font-family-primary` | `Spoqa Han Sans Neo` → SpoqaHanSans → Noto Sans KR → system | 본문 | +| `$font-family-mono` | `Fira Code`, Courier New, monospace | 코드·키값 | + +`@font-face` 선언: `sass/base/_djb-font.scss` +- OneShinhan: 300 / 400 / 500(=Medium 재사용) / 700, `.woff` +- Spoqa Han Sans Neo: 400 / 700, woff2 → woff → ttf +- Noto Sans KR: Variable 100–900, **한글 서브셋 woff2(~1.1MB)**. 원본 9.9MB TTF는 전송 abort 문제로 제거됨. 재생성 절차는 `docs/font-subset.md`. +- 전부 `font-display: swap` + `local()` 우선. + +### 제목 규칙 + +`base/_typography.scss`가 `h1~h6`, `.h1~.h6`에 더해 **`-title`/`__title`로 끝나는 클래스 전체**에 OneShinhan Medium을 자동 적용한다. + +```scss +[class$="-title"], [class*="-title "], +[class$="__title"], [class*="__title "] { font-family: $font-family-heading; font-weight: 500; } +``` +→ 새 제목 요소는 `.xxx-title` / `.xxx__title` 네이밍만 지켜도 제목 서체가 붙는다. + +### 스케일 + +| 토큰 | px | | 토큰 | px | +|---|---|---|---|---| +| `$font-size-xs` | 12 | | `$font-size-xl` | 24 | +| `$font-size-sm` | 14 | | `$font-size-2xl` | 32 | +| `$font-size-base` | 16 | | `$font-size-3xl` | 40 | +| `$font-size-md` | 18 | | `$font-size-4xl` | 48 | +| `$font-size-lg` | 20 | | `$font-size-5xl` | 56 | + +헤딩 매핑(반응형 축소 포함): + +| 태그 | 기본 | ≤768px | ≤480px | +|---|---|---|---| +| h1 | 5xl (56) | 3xl (40) | 2xl (32) | +| h2 | 4xl (48) | 2xl (32) | xl (24) | +| h3 | 3xl (40) | xl (24) | — | +| h4 | 2xl (32) | — | — | +| h5 | xl (24) | — | — | +| h6 | lg (20) | — | — | + +### 굵기 / 행간 + +``` +400 regular · 500 medium · 600 semibold · 700 bold · 800 extrabold +line-height: tight 1.2 · normal 1.6 · loose 1.8 +``` + +### 텍스트 유틸 + +`.text-primary|secondary|dark|gray|light|white`, `.text-left|center|right`, +`.font-regular|medium|semibold|bold|extrabold`, `.text-xs|sm|base|lg|xl`, +`.lead`(20px/1.8/gray), `.caption`(14px/gray), `.code`(mono/gray-bg/6px radius) + +--- + +## 4. 스페이싱 · 반경 · 레이아웃 + +### 스페이싱 (4px 배수 기반, 후반부 비선형) + +| 토큰 | px | | 토큰 | px | +|---|---|---|---|---| +| xs | 4 | | 2xl | 40 | +| sm | 8 | | 3xl | 48 | +| md | 16 | | 4xl | 64 | +| lg | 24 | | 5xl | 80 | +| xl | 32 | | 6xl | 100 | + +### 보더 반경 + +| 토큰 | 값 | 용도 | +|---|---|---| +| sm | 6px | 코드·복사버튼·작은 뱃지 | +| md | 8px | 입력·셀렉트·기본 액션버튼 | +| lg | 12px | `.btn` 기본·테이블·큰 입력 | +| xl | 16px | 아이콘 박스 | +| 2xl | 20px | **카드 기본** | +| full | 50px | pill 뱃지 | +| circle | 50% | 아바타·아이콘버튼·FAB | + +### 레이아웃 + +```scss +$container-max-width: 1280px; +$header-height: 80px; +``` + +`.container` max 1280 / padding 0 20px(≤768px는 16px) +변형: `.container-fluid`(100%), `.container-narrow`(960px), `.container-wide`(1440px) + +`.section` 상하 100px(≤768px 64px) · `.section-sm` 48px · `.section-lg` 150px + +### 브레이크포인트 & respond-to + +```scss +$breakpoint-xs: 480px; $breakpoint-sm: 768px; $breakpoint-md: 1024px; +$breakpoint-lg: 1280px; $breakpoint-xl: 1440px; +``` + +`@include respond-to($key)`: + +| key | 쿼리 | +|---|---| +| `xs` / `sm` / `md` | `max-width` 480 / 768 / 1024 | +| `tablet` | `max-width: 1024px` (= md) | +| `mobile` | `max-width: 1280px` | +| `lg` / `xl` | **`min-width`** 1280 / 1440 | + +⚠️ `lg`·`xl`만 min-width다. 모바일 대응은 `xs/sm/md/tablet/mobile`(max-width)을 쓴다. + +### z-index + +``` +dropdown 100 · sticky 200 · fixed 300 · header 350 +modal-backdrop 1040 · modal 1050 +popover 600 · tooltip 700 · notification 800 +``` +⚠️ `.global-header`는 토큰이 아니라 **`z-index: 1000` 하드코딩**이다. 그래서 모달은 1040/1050으로 그 위에 올린다. `$z-index-header: 350`은 실사용과 어긋나므로 헤더 관련 작업 시 1000을 기준으로 판단한다. 드롭다운 일부는 1100, 특정 오버레이는 9999를 쓴다. + +### 트랜지션 + +```scss +$transition-fast: all .15s ease; +$transition-base: all .3s ease; // 기본 +$transition-slow: all .5s ease; +``` + +--- + +## 5. 믹스인 (`abstracts/_mixins.scss`) + +| 믹스인 | 내용 | +|---|---| +| `respond-to($bp)` | 미디어쿼리 (§4) | +| `flex-center` / `flex-between` | flex 정렬 | +| `button-base` | inline-flex · gap 8 · padding 16/32 · radius 12 · 600 · 16px · hover `translateY(-3px)` | +| `card` | white · radius 20 · padding 32 · hover `$shadow-lg` | +| `gradient-text($g)` | background-clip: text | +| `text-truncate` | 1줄 말줄임 | +| `absolute-center` | top/left 50% + translate(-50%,-50%) | +| `backdrop-blur($n=10px)` | -webkit 프리픽스 포함 | +| `hover-lift` | hover `translateY(-8px)` + `$shadow-xl` | +| `glass-effect` | white 95% + blur 10 + 흰 보더 | +| `pattern-circle($size,$color)` | 장식 원 (opacity .1) | +| `animate-float/bounce/slide-in-down/slide-in-up/fade-in` | 애니메이션 바인딩 | + +### 애니메이션 (`base/_animations.scss`) + +`float · bounce · slideInDown · slideInUp · slideInLeft · slideInRight · fadeIn · fadeInScale · spin · pulse · shimmer · wave · popIn · popupFadeIn · ripple · gradientShift · drawLine · pulseLine` + +⚠️ `float`·`pulse`는 파일 내 **중복 정의**(뒤 선언이 이김). 수정 시 두 곳 모두 확인. + +--- + +## 6. 컴포넌트 + +### 6.1 버튼 (`components/_buttons.scss`) + +**기본 `.btn`** — `button-base` 기반, radius 12, hover `translateY(-3px)` + +크기: `.btn-sm`(8/16, 14px) · `.btn-md`(16/24, 16px) · `.btn-lg`(16/32, 18px) · `.btn-xl`(24/40, 20px) + +변형: `primary`(blue/white/shadow-md) · `secondary`(#E5E7EB / #5F666C) · `success`(green) · `danger`(orange) · `ghost`(투명+blue) · `outline`(투명+border 2px) · `accent` / `warm`(배경 미지정 — §9) + +상태: `:disabled`/`.disabled` opacity .5 + pointer-events none · `.loading`(텍스트 투명 + spin 스피너) + +형태: `.btn-icon`(44×44 원형, sm 32 / lg 56) · `.btn-block`(100%) · `.btn-group` + +**액션 버튼 계열**(목록·상세 화면 표준) — padding 16/40, radius 8, 500 + +- `.action-btn-new` / `.action-btn-primary` — 주 액션 +- `.action-btn-secondary` — 취소·목록 (white + border-gray, hover 시 blue) +- `.action-btn-edit` — primary-blue +- `.action-btn-delete` — accent-orange +- `.action-btn.btn-list / .btn-edit / .btn-delete` — 게시판 변형 + +**특수 버튼** + +| 클래스 | 규격 | +|---|---| +| `.btn-input-action` | 입력 우측 부착. min-w 172 · h 60 · radius 12 · 20px/700. `.btn-change`/`.btn-auth` = `#a4d6ea` / `#A4D6EA`. ≤768px full-width·h 52 | +| `.btn-upload` | h 40 · `#3ba4ed`(hover `#2b94dd`) · radius 8 · 14px/600 | +| `.btn-action-primary` | CTA. `#2a69de` · 20px/700 · padding 16/48 · radius 10. `.md` 변형 14px/11·45 | +| `.btn-copy` | primary-blue 10% 배경 · 12px | +| `.btn-action` / `.btn-cancel` | 8/24 · radius 8 · 14px | +| `.btn-cta-primary` / `.btn-cta-secondary` | 짙은 배경 위 CTA (white 배경 / 흰 보더 고스트) | +| `.fab` | 60×60 고정 원형, 우하단, 라벨 툴팁 동반 | + +### 6.2 뱃지 (`components/_badges.scss`) + +`.status-badge` — inline-flex · padding 4/16 · radius full · 12px/600 + +상태 클래스(배경 = 원색 10%, 글자 = 원색): + +| 클래스 | 색 | +|---|---| +| `.status-pending` / `.status-failed` | accent-orange | +| `.status-completed` / `.status-success` | accent-green | +| `.status-active` | primary-blue | +| `.status-inactive` | text-gray | +| `.status-processing` | accent-yellow(글자는 30% darken) | + +변형: `.status-badge-header`(하단 여백 포함) · `.badge-sm`(10px) · `.badge-lg`(14px) · `.badge-outline`(currentColor 보더) · `.badge-icon` +`.notification-badge` — 카운트용 20×20 원형, `.badge-primary|success|warning|danger` + +### 6.3 카드 (`components/_cards.scss`) + +전부 `@include card`(white · radius 20 · padding 32 · hover shadow-lg) 기반. + +- `.card` — 기본 +- `.api-card` — 보더 2px, hover 시 primary-blue. 하위 `.api-badge`(`.new`/`.beta`) · `.api-icon`(60×60, radius 16) · `.api-name` · `.api-description` · `.api-features > .feature-tag` · `.api-link`. 변형 `.api-card-popular`(yellow) / `.api-card-new`(green) +- `.experience-card` — 중앙정렬, `.card-icon`(56×56) + `.card-metric`(`.metric-value` 24px/800 blue) +- `.feature-card` — 가로형, `.feature-icon`(48×48 radius 12) + `.feature-content` +- `.testimonial-card` — `::before` 큰 따옴표 장식, `.testimonial-author`(아바타 48 원형) +- `.pricing-card` — `.featured` 시 blue 2px + scale(1.05), `.pricing-badge`/`.pricing-header .price`/`.pricing-features`(✓·× 프리픽스) + +### 6.4 폼 (`components/_forms.scss`) + +**레거시 계열** — `.form-group`(label 14px/600 + `.required`(orange) + `.form-hint` + `.form-error`), `.form-control`(**보더 2px** · radius 8 · padding 12/16 · focus 시 blue + 3px 링 `rgba(primary,.1)`), `.is-valid`/`.is-invalid`, `.form-control-sm|lg` +`textarea.form-control` min-h 120 · `select.form-control` 커스텀 SVG 화살표(`#64748B`) + +**DJB 계열**(신규 화면 표준) — `.djb-label` · `.djb-input` · `.djb-textarea` · `.form-label-wrapper`/`.form-label-text`/`.required-badge` · `.form-field-wrapper` · `.form-input` · `.form-select` · `.form-row` · `.section-divider` + +**조합 위젯** — `.input-group`(+`.input-group-append`) · `.compound-input` · `.input-with-button` · `.auth-input-group` · `.char-counter-wrapper` · `.search-field` · `.file-upload-wrapper` · `.form-check` / `.form-switch` · `.form-actions`(`--between` `--no-border` `--compact` `--with-withdrawal`) / `.form-actions-center` + +> 신규 폼은 **DJB 계열**을 쓴다. `.form-control` 계열은 기존 화면 유지용. + +### 6.5 테이블 (`components/_tables.scss`) + +- `.data-table` — white · radius 12 · shadow-sm. `thead` 배경 `$light-bg` + 하단 2px 보더, `th` 14px/600 dark, `td` 14px gray, `tr:hover` 시 `rgba(primary,.02)`. 래퍼 `.data-table-wrapper`가 `overflow-x: auto` 담당 → **가로 스크롤은 항상 래퍼에 건다**. +- `.notice-table` — 게시판형. `.table-header`가 grid(`80px 1fr 120px`). +- ≤768px에서 padding·font 한 단계 축소. + +### 6.6 기타 컴포넌트 + +| 파일 | 내용 | +|---|---| +| `_alerts.scss` | `.alert` + `.alert-warning`(yellow/글자 `#B89900`) `.alert-error`(orange) `.alert-success`(green) `.alert-info`(blue). 공통 패턴: 배경 10% + 보더 30% | +| `_modals.scss` | 모달 (backdrop 1040 / modal 1050) | +| `_toast.scss` | 토스트. JS는 `js/djb/toast.js` | +| `_pagination.scss` · `_breadcrumb.scss` | 목록/내비 | +| `_accordion.scss` · `_navigation.scss` · `_partners.scss` · `_cta.scss` | 섹션 컴포넌트 | +| `_page-title-banner.scss` | `.page-title-banner` — 배경 `#E9F8FF` · h 110px(모바일 120) · `.title-image`(220px, 모바일 120) · h1 40px/700 letter-spacing -.5px | +| `_apikey-common.scss` · `_board-common.scss` | 도메인 공통 | +| `_password-popup.scss` · `_password-policy.scss` | 비밀번호 UI | +| `_session-timer.scss` · `_two-factor.scss` · `_header-auth.scss` | 인증/세션 | +| `_test-env-notice.scss` | 테스트 환경 배너 | +| `_djb-inquiry-comments.scss` | 문의 댓글 | + +--- + +## 7. 레이아웃 / 템플릿 + +### 헤더 (`layout/_header.scss`) + +`.global-header` — fixed · **h 80px** · **z-index 1000(하드코딩)** +`.header-content`(내부 flex) / `.header-left`(로고 h 32px) / `.header-center`(GNB) / `.header-right`(h 40px 유틸) +모바일: `clamp(44px, 11.73vw, 60px)`로 높이 가변. 햄버거 → 전체화면 오버레이(z-index 9999). +본문은 `.content-wrapper .main-content { padding-top: $header-height }`로 헤더 높이를 보정한다. + +### 그리드 (`layout/_grid.scss`) + +범용: `.grid` + `.grid-cols-1|2|3|4|5|6|12` · `.grid-auto`(minmax 280) `.grid-auto-sm`(200) `.grid-auto-lg`(350) · `.gap-0|sm|md|lg|xl` · `.grid-md-cols-*` `.grid-sm-cols-*` · `.col-span-1~6|full` · `.row-span-1~3` + +도메인 그리드: `.api-grid` · `.experience-grid` · `.partners-grid` · `.feature-grid` · `.demo-wrapper` · `.footer-grid`(2fr 3fr) · `.pricing-grid` · `.testimonial-grid` · `.stats-grid` · `.two-column`(`.reverse` 지원) · `.three-column` +대부분 ≤1024px에서 1~2열, ≤768px에서 1열로 접힌다. + +### Thymeleaf 레이아웃 + +``` +templates/views/ +├── layout/ djbank_base_layout · djbank_index_layout · djbank_title_layout +│ djbank_nohead_layout · base_layout · index_layout · side_menu_layout +├── fragment/djbank/ head · header_container · header_nav · menu +│ footer · service_sidebar · terms_agreements +├── fragment/ 검증 UI 조각 (email/phone/password/auth-number/…) +└── apps/ · djb/ · samples/ 페이지 본문 +``` + +`fragment/djbank/head.html`의 CSS 로드 순서: + +``` +all.min.css → main.css → editor-content.css → slick.css → daterangepicker.css +→ codemirror(+monokai) → summernote-lite → jquery-ui +``` +`main.css`가 벤더보다 앞이므로 **벤더 위젯 커스터마이즈는 `sass/vendors/_overrides.scss`** 에서 한다. + +메타/전역: `` + `_csrf_header`(JS는 쿠키 대신 이 meta를 읽는다), `window.PORTAL_CONFIG`(파일 업로드 제한), `window.__PASSWORD_POLICY__`, `window.__PASSWORD_CRYPTO__`, `window.__CLIENT_GUARD__`. + +### 정적 자산 + +- 로고: `img/logo/logo-djb.png` · `logo-jjb.png` · `logo-jjb-color.png` · `logo-jjb-white.png` · `logo_box.png` (어두운 배경에는 `-white`) +- 파비콘: `img/favicon/` (16·32·apple-touch 180) +- 아이콘: `img/icon/` PNG 세트(`icon_*`, `arrow_*`, `checkbox_on/off` …). 인라인 SVG·data URI도 혼용. +- JS: 공통 `js/common.js`, 커스텀은 `js/djb/*`(`toast.js` · `client-guard.js` · `api-status.js` · `inquiry-*.js` · `notitest.js`), 벤더는 `js/lib/`·`plugins/`. +- `djb/` 네임스페이스는 **커스텀 전용**. 공통 성격은 `common/` 또는 `js/` 루트에 둔다. + +--- + +## 8. 작성 규칙 요약 + +1. **CSS 직접 수정 금지.** SASS만 고치고 컴파일한다. +2. **하드코딩 색 금지.** 토큰이 없으면 `_variables.scss`에 추가한다. +3. 간격·폰트·반경은 토큰 스케일에서 고른다. 임의 px는 컴포넌트 고유 규격(입력 높이 60, 아이콘 44 등)에 한정. +4. 제목 요소는 `-title` / `__title` 네이밍 → 헤딩 서체 자동 적용. +5. 새 파샬은 `main.scss`의 올바른 섹션에 `@use` 등록. 유틸은 마지막. +6. 가로로 넘치는 콘텐츠(테이블·코드)는 **래퍼에 `overflow-x: auto`**, body에 가로 스크롤을 만들지 않는다. +7. 반응형은 `@include respond-to('sm'|'md'|…)` 사용. 직접 `@media`는 기존 코드 관례(`@media (max-width: $breakpoint-sm)`)를 따르는 곳에서만. +8. 상태 표현은 `.status-badge` + `.status-*`, 메시지는 `.alert-*`를 재사용한다. 새 상태색을 만들지 않는다. +9. 신규 폼은 DJB 계열(`.djb-input` · `.form-field-wrapper` …), 신규 액션 버튼은 `.action-btn-*` 계열. +10. 메뉴 추가는 `menu.yml`(GNB) + `page.home` 트리(브레드크럼) 양쪽. 스타일만 고쳐선 메뉴가 안 나온다. + +--- + +## 9. 알려진 불일치 / 부채 + +코드에서 실제로 확인된 항목. 손댈 때 함께 정리한다. + +| # | 내용 | +|---|---| +| 1 | **`#2a69de`가 92회 하드코딩** — `$primary-blue`(`#0049b4`, 91회)와 병존하는 사실상 제2 브랜드 블루인데 토큰이 없다. Figma 원본과 대조해 어느 쪽이 정본인지 확정 후 토큰화 필요. | +| 2 | `$primary-color`와 `$primary-blue`가 같은 값 중복 정의. `$primary-blue`로 일원화 권장. | +| 3 | `.btn-accent` / `.btn-warm`, `.action-btn-new`, `.action-btn .btn-edit`, `.btn-action`, `.experience-card .card-icon`, `.feature-icon`, `.pricing-badge` 등에 **`background` 선언이 비어 있다**(그라디언트 제거 흔적). 흰 글자만 남아 사실상 보이지 않는 상태. | +| 4 | `$z-index-header: 350` vs `.global-header { z-index: 1000 }` 하드코딩 불일치. 드롭다운 1100, 모바일 오버레이 9999도 토큰 밖. | +| 5 | `_animations.scss`에 `float`·`pulse` **중복 @keyframes**. | +| 6 | `.btn-group { gap: -1px }` — 음수 gap은 무효. | +| 7 | `themes/_dark.scss`는 **빈 파일**. 다크 테마 미구현. | +| 8 | `main.scss`에서 `components/password-policy`를 **두 번 `@use`**. | +| 9 | `#a4d6ea` / `#A4D6EA`(대소문자만 다른 동일 색), `#dfdfdf`·`#dadada`·`#e5e7eb`·`#e3e8f0` 등 **회색 계열 난립**. 토큰 정리 대상. | +| 10 | `css/api-statistics.css`가 별도로 존재하나 템플릿에서 링크가 **주석 처리**됨. 통계 스타일은 현재 `main.css` 경유. 파일 정리 여부 확인 필요. | +| 11 | `#f4253c`(17회) — 에러 레드가 `$accent-orange`(`#FF6B6B`)와 별개로 쓰인다. danger 색 이원화. | +| 12 | 이 문서는 코드 역추출본이다. **Figma Design Guide와의 공식 대조는 미수행.** | diff --git a/src/main/resources/templates/views/apps/service/intro.html b/src/main/resources/templates/views/apps/service/intro.html index 90ab677..802f4bf 100644 --- a/src/main/resources/templates/views/apps/service/intro.html +++ b/src/main/resources/templates/views/apps/service/intro.html @@ -155,7 +155,7 @@ HTTPS / OAuth2 - JEJU BANK API PORTAL + [[${brandName}]] API PORTAL 인증 서버 API Gateway 유량 · IP 제어