@ihabdevteam/core 0.9.11 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/dist/components.cjs.js +45 -45
- package/dist/components.esm.css +1 -1
- package/dist/ihabdevteam-core-tokens.css +1 -1
- package/dist/ihabdevteam-core.cjs.js +182 -182
- package/dist/ihabdevteam-core.css +1 -1
- package/dist/ihabdevteam-core.d.ts +154 -0
- package/dist/packages/core/src/components/Report/ReportDocument.css +127 -0
- package/dist/packages/core/src/components/Report/ReportDocument.d.ts +77 -0
- package/dist/packages/core/src/components/Report/ReportDocument.js +0 -0
- package/dist/packages/core/src/components/Report/ReportInfoPanel.css +42 -0
- package/dist/packages/core/src/components/Report/ReportInfoPanel.d.ts +26 -0
- package/dist/packages/core/src/components/Report/ReportInfoPanel.js +14 -0
- package/dist/packages/core/src/components/SummaryStrip.css +69 -0
- package/dist/packages/core/src/components/SummaryStrip.d.ts +48 -0
- package/dist/packages/core/src/components/SummaryStrip.js +31 -0
- package/dist/packages/core/src/components.d.ts +6 -0
- package/dist/packages/core/src/components.js +3 -0
- package/dist/packages/core/src/styles.css +118 -31
- package/dist/packages/core/src/tokens.css +25 -1
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from '../utils/cx';
|
|
3
|
+
import './SummaryStrip.css';
|
|
4
|
+
/**
|
|
5
|
+
* 화면 위쪽에 놓이는 한 줄 요약 — "지금 다루고 있는 대상"을 이름표와 값으로 늘어놓는다.
|
|
6
|
+
*
|
|
7
|
+
* 값 길이가 제각각이라 균등 그리드에 앉힌다. 긴 값은 칸을 밀어내지 않고 말줄임된다.
|
|
8
|
+
*
|
|
9
|
+
* 값의 서식은 부르는 쪽이 정해 넘긴다 — 빈 값을 `-` 로 적을지, 날짜를 어떻게 쓸지,
|
|
10
|
+
* 여러 값을 한 칸에 묶을지(`오른손 / NC / 연구실 내`)는 화면마다 다르다.
|
|
11
|
+
*
|
|
12
|
+
* 붙박이(sticky)로 두려면 감싸는 쪽에서 건다 — 이 컴포넌트는 자리를 정하지 않는다.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <SummaryStrip
|
|
17
|
+
* items={[
|
|
18
|
+
* { label: '이름', value: patient.name },
|
|
19
|
+
* { label: '생년월일', value: patient.birthDate },
|
|
20
|
+
* { label: '환자번호', value: patient.chartNo ?? '-' },
|
|
21
|
+
* ]}
|
|
22
|
+
* actions={<Button size={32} type="dot" icon="pencil" ariaLabel="정보 수정" onClick={onEdit} />}
|
|
23
|
+
* />
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export default function SummaryStrip({ items, actions, columns, className, style, }) {
|
|
29
|
+
const cols = columns ?? items.length;
|
|
30
|
+
return (_jsx("section", { className: cx('summary-strip', className), style: { ['--summary-strip-cols']: String(cols), ...style }, children: _jsxs("div", { className: "summary-strip__row", children: [_jsx("div", { className: "summary-strip__items", children: items.map((item, i) => (_jsxs("div", { className: "summary-strip__item", children: [_jsx("p", { className: "summary-strip__label caption-1", children: item.label }), _jsx("p", { className: "summary-strip__value body-3b", children: item.value })] }, i))) }), actions && _jsx("div", { className: "summary-strip__actions", children: actions })] }) }));
|
|
31
|
+
}
|
|
@@ -295,6 +295,12 @@ export type { PanelRowToggle, PanelRowSegmented, DropdownItem, PanelRowDropdown,
|
|
|
295
295
|
export { default as Section } from './components/Section';
|
|
296
296
|
export type { SectionProps, SectionType } from './components/Section';
|
|
297
297
|
export { default as Pagination } from './components/Pagination';
|
|
298
|
+
export { default as SummaryStrip } from './components/SummaryStrip';
|
|
299
|
+
export type { SummaryStripProps, SummaryStripItem } from './components/SummaryStrip';
|
|
300
|
+
export { default as ReportDocument } from './components/Report/ReportDocument';
|
|
301
|
+
export type { ReportDocumentProps, ReportBlock } from './components/Report/ReportDocument';
|
|
302
|
+
export { default as ReportInfoPanel } from './components/Report/ReportInfoPanel';
|
|
303
|
+
export type { ReportInfoPanelProps, ReportInfoField } from './components/Report/ReportInfoPanel';
|
|
298
304
|
export { default as UpdateAlert } from './components/UpdateAlert';
|
|
299
305
|
export { default as TrainingCard } from './components/Training/TrainingCard';
|
|
300
306
|
export type { TrainingCardProps } from './components/Training/TrainingCard';
|
|
@@ -230,6 +230,9 @@ export { default as Popup } from './components/Popup/Popup';
|
|
|
230
230
|
export { default as Panel, PanelRow, PanelGrid, PanelRowDevice } from './components/Panel';
|
|
231
231
|
export { default as Section } from './components/Section';
|
|
232
232
|
export { default as Pagination } from './components/Pagination';
|
|
233
|
+
export { default as SummaryStrip } from './components/SummaryStrip';
|
|
234
|
+
export { default as ReportDocument } from './components/Report/ReportDocument';
|
|
235
|
+
export { default as ReportInfoPanel } from './components/Report/ReportInfoPanel';
|
|
233
236
|
export { default as UpdateAlert } from './components/UpdateAlert';
|
|
234
237
|
export { default as TrainingCard } from './components/Training/TrainingCard';
|
|
235
238
|
export { default as TrainingCardGroup } from './components/Training/TrainingCardGroup';
|
|
@@ -54,47 +54,134 @@ textarea {
|
|
|
54
54
|
|
|
55
55
|
/* ── 타이포그래피 헬퍼 (전역) ────────────────────────────── */
|
|
56
56
|
/* 값은 전부 tokens.css의 --text-* 변수에서 온다(반응형·글자 크기 스케일 포함).
|
|
57
|
-
여기서는 "어떤 변수를 쓰는지"만 정의한다 — 수치를 바꾸려면 tokens.css를 고친다.
|
|
57
|
+
여기서는 "어떤 변수를 쓰는지"만 정의한다 — 수치를 바꾸려면 tokens.css를 고친다.
|
|
58
|
+
|
|
59
|
+
**왜 전부 :where() 로 감쌌나 — 이것은 기본값이지 강제가 아니다.**
|
|
60
|
+
이 번들은 소비자 앱과 섞이지 않게 모든 셀렉터에 `.ihabdevteam-core-scope` 를
|
|
61
|
+
붙여 내보낸다. 그러면 `.h0` 이 `.ihabdevteam-core-scope .h0`(특이도 0-2-0)이
|
|
62
|
+
되어, 앱이 `.lp-hero-sub`(0-1-0) 한 겹으로 적은 여백·크기를 **통째로 눌러
|
|
63
|
+
이긴다.** 바로 아래 "margin은 0 기본, 필요 시 컴포넌트에서 override" 라고 적어
|
|
64
|
+
두고도 그 override 가 성립하지 않았다.
|
|
65
|
+
|
|
66
|
+
실측으로 확인한 피해 — 회원앱 랜딩 한 화면에서 다섯 자리가 눌렸고, 그중 셋은
|
|
67
|
+
**코어 자신의 컴포넌트**였다(payment-plan__quote · payment-plan__subtitle ·
|
|
68
|
+
site-footer__copyright). 히어로에서는 `margin-bottom: 32px` 가 0px 이 되어 제목·
|
|
69
|
+
본문·단추가 맞붙었고, 모바일에서 앱이 정한 26px 제목이 h0 의 28px 로 되돌아갔다.
|
|
70
|
+
|
|
71
|
+
`:where()` 는 안에 무엇이 들어 있든 특이도가 0 이다. postcss 설정이 프리픽스도
|
|
72
|
+
`:where(.ihabdevteam-core-scope)` 로 감싸므로(postcss.config.cjs 참고) 최종
|
|
73
|
+
특이도가 0-0-0 이 되어, 앱의 어떤 클래스 규칙이든 이 기본값을 덮을 수 있다.
|
|
74
|
+
타이포 헬퍼는 **바탕**이고 화면이 그 위에 자기 판단을 얹는다 — 그것이 원래
|
|
75
|
+
의도였고, 이제 실제로 그렇게 된다. */
|
|
76
|
+
|
|
77
|
+
/* Display — h0 위의 세 단. 랜딩·히어로처럼 크게 외치는 자리 전용이다.
|
|
78
|
+
h 단과 달리 크기가 뷰포트를 따라 연속으로 변한다(tokens.css 의 clamp) — 까닭은
|
|
79
|
+
그쪽 주석에 적어 두었다. 앱 화면 제목에는 h0~h5 를 쓴다. */
|
|
80
|
+
:where(.display-1), :where(.display-1b) { font-size: var(--text-display-1-size); line-height: var(--text-display-1-line); letter-spacing: var(--text-display-1-spacing); margin: 0; }
|
|
81
|
+
:where(.display-2), :where(.display-2b) { font-size: var(--text-display-2-size); line-height: var(--text-display-2-line); letter-spacing: var(--text-display-2-spacing); margin: 0; }
|
|
82
|
+
:where(.display-3), :where(.display-3b) { font-size: var(--text-display-3-size); line-height: var(--text-display-3-line); letter-spacing: var(--text-display-3-spacing); margin: 0; }
|
|
83
|
+
|
|
84
|
+
:where(.display-1) { font-weight: var(--text-display-1-weight); }
|
|
85
|
+
:where(.display-2) { font-weight: var(--text-display-2-weight); }
|
|
86
|
+
:where(.display-3) { font-weight: var(--text-display-3-weight); }
|
|
87
|
+
:where(.display-1b) { font-weight: var(--text-display-1-weight-bold); }
|
|
88
|
+
:where(.display-2b) { font-weight: var(--text-display-2-weight-bold); }
|
|
89
|
+
:where(.display-3b) { font-weight: var(--text-display-3-weight-bold); }
|
|
58
90
|
|
|
59
91
|
/* Heading — margin은 0 기본, 필요 시 컴포넌트에서 override */
|
|
60
|
-
.h0, .h0b { font-size: var(--text-h0-size); line-height: var(--text-h0-line); letter-spacing: var(--text-h0-spacing); margin: 0; }
|
|
61
|
-
.h1, .h1b { font-size: var(--text-h1-size); line-height: var(--text-h1-line); letter-spacing: var(--text-h1-spacing); margin: 0; }
|
|
62
|
-
.h2, .h2b { font-size: var(--text-h2-size); line-height: var(--text-h2-line); letter-spacing: var(--text-h2-spacing); margin: 0; }
|
|
63
|
-
.h3, .h3b { font-size: var(--text-h3-size); line-height: var(--text-h3-line); letter-spacing: var(--text-h3-spacing); margin: 0; }
|
|
64
|
-
.h4, .h4b { font-size: var(--text-h4-size); line-height: var(--text-h4-line); letter-spacing: var(--text-h4-spacing); margin: 0; }
|
|
65
|
-
.h5, .h5b { font-size: var(--text-h5-size); line-height: var(--text-h5-line); letter-spacing: var(--text-h5-spacing); margin: 0; }
|
|
92
|
+
:where(.h0), :where(.h0b) { font-size: var(--text-h0-size); line-height: var(--text-h0-line); letter-spacing: var(--text-h0-spacing); margin: 0; }
|
|
93
|
+
:where(.h1), :where(.h1b) { font-size: var(--text-h1-size); line-height: var(--text-h1-line); letter-spacing: var(--text-h1-spacing); margin: 0; }
|
|
94
|
+
:where(.h2), :where(.h2b) { font-size: var(--text-h2-size); line-height: var(--text-h2-line); letter-spacing: var(--text-h2-spacing); margin: 0; }
|
|
95
|
+
:where(.h3), :where(.h3b) { font-size: var(--text-h3-size); line-height: var(--text-h3-line); letter-spacing: var(--text-h3-spacing); margin: 0; }
|
|
96
|
+
:where(.h4), :where(.h4b) { font-size: var(--text-h4-size); line-height: var(--text-h4-line); letter-spacing: var(--text-h4-spacing); margin: 0; }
|
|
97
|
+
:where(.h5), :where(.h5b) { font-size: var(--text-h5-size); line-height: var(--text-h5-line); letter-spacing: var(--text-h5-spacing); margin: 0; }
|
|
66
98
|
|
|
67
99
|
/* Weight */
|
|
68
|
-
.h0 { font-weight: var(--text-h0-weight); }
|
|
69
|
-
.h1 { font-weight: var(--text-h1-weight); }
|
|
70
|
-
.h2 { font-weight: var(--text-h2-weight); }
|
|
71
|
-
.h3 { font-weight: var(--text-h3-weight); }
|
|
72
|
-
.h4 { font-weight: var(--text-h4-weight); }
|
|
73
|
-
.h5 { font-weight: var(--text-h5-weight); }
|
|
74
|
-
.h0b { font-weight: var(--text-h0-weight-bold); }
|
|
75
|
-
.h1b { font-weight: var(--text-h1-weight-bold); }
|
|
76
|
-
.h2b { font-weight: var(--text-h2-weight-bold); }
|
|
77
|
-
.h3b { font-weight: var(--text-h3-weight-bold); }
|
|
78
|
-
.h4b { font-weight: var(--text-h4-weight-bold); }
|
|
79
|
-
.h5b { font-weight: var(--text-h5-weight-bold); }
|
|
100
|
+
:where(.h0) { font-weight: var(--text-h0-weight); }
|
|
101
|
+
:where(.h1) { font-weight: var(--text-h1-weight); }
|
|
102
|
+
:where(.h2) { font-weight: var(--text-h2-weight); }
|
|
103
|
+
:where(.h3) { font-weight: var(--text-h3-weight); }
|
|
104
|
+
:where(.h4) { font-weight: var(--text-h4-weight); }
|
|
105
|
+
:where(.h5) { font-weight: var(--text-h5-weight); }
|
|
106
|
+
:where(.h0b) { font-weight: var(--text-h0-weight-bold); }
|
|
107
|
+
:where(.h1b) { font-weight: var(--text-h1-weight-bold); }
|
|
108
|
+
:where(.h2b) { font-weight: var(--text-h2-weight-bold); }
|
|
109
|
+
:where(.h3b) { font-weight: var(--text-h3-weight-bold); }
|
|
110
|
+
:where(.h4b) { font-weight: var(--text-h4-weight-bold); }
|
|
111
|
+
:where(.h5b) { font-weight: var(--text-h5-weight-bold); }
|
|
80
112
|
|
|
81
113
|
/* Body — weight 명시 */
|
|
82
|
-
.body-1,
|
|
83
|
-
.body-2,
|
|
84
|
-
.body-3,
|
|
114
|
+
:where(.body-1), :where(.body-1b) { font-size: var(--text-body-1-size); line-height: var(--text-body-1-line); margin: 0; font-weight: var(--text-body-1-weight); }
|
|
115
|
+
:where(.body-2), :where(.body-2b) { font-size: var(--text-body-2-size); line-height: var(--text-body-2-line); margin: 0; font-weight: var(--text-body-2-weight); }
|
|
116
|
+
:where(.body-3), :where(.body-3b) { font-size: var(--text-body-3-size); line-height: var(--text-body-3-line); margin: 0; font-weight: var(--text-body-3-weight); }
|
|
85
117
|
|
|
86
|
-
.body-1b { font-weight: var(--text-body-1-weight-bold); }
|
|
87
|
-
.body-2b { font-weight: var(--text-body-2-weight-bold); }
|
|
88
|
-
.body-3b { font-weight: var(--text-body-3-weight-bold); }
|
|
118
|
+
:where(.body-1b) { font-weight: var(--text-body-1-weight-bold); }
|
|
119
|
+
:where(.body-2b) { font-weight: var(--text-body-2-weight-bold); }
|
|
120
|
+
:where(.body-3b) { font-weight: var(--text-body-3-weight-bold); }
|
|
89
121
|
|
|
90
122
|
/* Button / Caption — button에 weight 추가, caption과 크기 차별화 */
|
|
91
|
-
.button-1 { font-size: var(--text-button-1-size); line-height: var(--text-button-1-line); font-weight: var(--text-button-1-weight); margin: 0; }
|
|
92
|
-
.button-2 { font-size: var(--text-button-2-size); line-height: var(--text-button-2-line); font-weight: var(--text-button-2-weight); margin: 0; }
|
|
93
|
-
.caption-1, .caption-1b { font-size: var(--text-caption-1-size); line-height: var(--text-caption-1-line); font-weight: var(--text-caption-1-weight); margin: 0; }
|
|
94
|
-
.caption-2, .caption-2b { font-size: var(--text-caption-2-size); line-height: var(--text-caption-2-line); font-weight: var(--text-caption-2-weight); margin: 0; }
|
|
123
|
+
:where(.button-1) { font-size: var(--text-button-1-size); line-height: var(--text-button-1-line); font-weight: var(--text-button-1-weight); margin: 0; }
|
|
124
|
+
:where(.button-2) { font-size: var(--text-button-2-size); line-height: var(--text-button-2-line); font-weight: var(--text-button-2-weight); margin: 0; }
|
|
125
|
+
:where(.caption-1), :where(.caption-1b) { font-size: var(--text-caption-1-size); line-height: var(--text-caption-1-line); font-weight: var(--text-caption-1-weight); margin: 0; }
|
|
126
|
+
:where(.caption-2), :where(.caption-2b) { font-size: var(--text-caption-2-size); line-height: var(--text-caption-2-line); font-weight: var(--text-caption-2-weight); margin: 0; }
|
|
95
127
|
/* b 계열 — 크기·행간은 같고 굵기만 다르다(body-*b와 동일한 규칙) */
|
|
96
|
-
.caption-1b { font-weight: var(--text-caption-1-weight-bold); }
|
|
97
|
-
.caption-2b { font-weight: var(--text-caption-2-weight-bold); }
|
|
128
|
+
:where(.caption-1b) { font-weight: var(--text-caption-1-weight-bold); }
|
|
129
|
+
:where(.caption-2b) { font-weight: var(--text-caption-2-weight-bold); }
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
/* ── 제목 태그 보호 (리셋이 지우는 두 속성만 되돌린다) ────────
|
|
133
|
+
위 헬퍼는 특이도 0 이라 **태그 선택자에도 진다.** Tailwind preflight 가
|
|
134
|
+
`h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit }` (0-0-1)
|
|
135
|
+
를 깔면, `<h1 class="h1">` 이 32px/700 이 아니라 본문값(16px/400)으로 나온다.
|
|
136
|
+
preflight 가 건드리지 않는 line-height 만 헬퍼 값이 남아 "작고 안 굵은데
|
|
137
|
+
행간만 큰" 제목이 된다 — kscan 의 모든 화면 제목이 그랬다(PageTitle 이 h1 을
|
|
138
|
+
그린다).
|
|
139
|
+
|
|
140
|
+
그래서 **제목 태그일 때만** 클래스의 :where() 를 벗어 0-1-0 으로 올린다.
|
|
141
|
+
|
|
142
|
+
0-0-1 리셋의 h1 → 진다
|
|
143
|
+
0-1-0 여기 → 이긴다
|
|
144
|
+
0-1-0 앱의 `.lp-hero-title` → 동점, 나중에 선언된 쪽이 이긴다
|
|
145
|
+
|
|
146
|
+
앱 CSS 는 디자인 시스템 뒤에 실리므로 앱이 계속 이긴다. 한 겹으로 덮을 수
|
|
147
|
+
있다는 원래 성질이 제목에서도 유지된다 — 다만 순서에 기대므로, 앱 CSS 를
|
|
148
|
+
코어보다 **먼저** 싣는 곳이라면 두 겹으로 적어야 한다.
|
|
149
|
+
|
|
150
|
+
되돌리는 것은 리셋이 지우는 font-size·font-weight 둘뿐이다. margin·
|
|
151
|
+
line-height·letter-spacing 은 특이도 0 그대로 둔다 — 회원앱 히어로의
|
|
152
|
+
`margin-bottom: 32px` 이 눌리던 문제는 그대로 고쳐진 채로 남는다.
|
|
153
|
+
|
|
154
|
+
제목 태그가 아닌 곳(p·div·span)은 이 블록에 걸리지 않아 완전히 예전과 같다. */
|
|
155
|
+
:where(h1, h2, h3, h4, h5, h6).display-1 { font-size: var(--text-display-1-size); font-weight: var(--text-display-1-weight); }
|
|
156
|
+
:where(h1, h2, h3, h4, h5, h6).display-1b { font-size: var(--text-display-1-size); font-weight: var(--text-display-1-weight-bold); }
|
|
157
|
+
:where(h1, h2, h3, h4, h5, h6).display-2 { font-size: var(--text-display-2-size); font-weight: var(--text-display-2-weight); }
|
|
158
|
+
:where(h1, h2, h3, h4, h5, h6).display-2b { font-size: var(--text-display-2-size); font-weight: var(--text-display-2-weight-bold); }
|
|
159
|
+
:where(h1, h2, h3, h4, h5, h6).display-3 { font-size: var(--text-display-3-size); font-weight: var(--text-display-3-weight); }
|
|
160
|
+
:where(h1, h2, h3, h4, h5, h6).display-3b { font-size: var(--text-display-3-size); font-weight: var(--text-display-3-weight-bold); }
|
|
161
|
+
:where(h1, h2, h3, h4, h5, h6).h0 { font-size: var(--text-h0-size); font-weight: var(--text-h0-weight); }
|
|
162
|
+
:where(h1, h2, h3, h4, h5, h6).h0b { font-size: var(--text-h0-size); font-weight: var(--text-h0-weight-bold); }
|
|
163
|
+
:where(h1, h2, h3, h4, h5, h6).h1 { font-size: var(--text-h1-size); font-weight: var(--text-h1-weight); }
|
|
164
|
+
:where(h1, h2, h3, h4, h5, h6).h1b { font-size: var(--text-h1-size); font-weight: var(--text-h1-weight-bold); }
|
|
165
|
+
:where(h1, h2, h3, h4, h5, h6).h2 { font-size: var(--text-h2-size); font-weight: var(--text-h2-weight); }
|
|
166
|
+
:where(h1, h2, h3, h4, h5, h6).h2b { font-size: var(--text-h2-size); font-weight: var(--text-h2-weight-bold); }
|
|
167
|
+
:where(h1, h2, h3, h4, h5, h6).h3 { font-size: var(--text-h3-size); font-weight: var(--text-h3-weight); }
|
|
168
|
+
:where(h1, h2, h3, h4, h5, h6).h3b { font-size: var(--text-h3-size); font-weight: var(--text-h3-weight-bold); }
|
|
169
|
+
:where(h1, h2, h3, h4, h5, h6).h4 { font-size: var(--text-h4-size); font-weight: var(--text-h4-weight); }
|
|
170
|
+
:where(h1, h2, h3, h4, h5, h6).h4b { font-size: var(--text-h4-size); font-weight: var(--text-h4-weight-bold); }
|
|
171
|
+
:where(h1, h2, h3, h4, h5, h6).h5 { font-size: var(--text-h5-size); font-weight: var(--text-h5-weight); }
|
|
172
|
+
:where(h1, h2, h3, h4, h5, h6).h5b { font-size: var(--text-h5-size); font-weight: var(--text-h5-weight-bold); }
|
|
173
|
+
:where(h1, h2, h3, h4, h5, h6).body-1 { font-size: var(--text-body-1-size); font-weight: var(--text-body-1-weight); }
|
|
174
|
+
:where(h1, h2, h3, h4, h5, h6).body-1b { font-size: var(--text-body-1-size); font-weight: var(--text-body-1-weight-bold); }
|
|
175
|
+
:where(h1, h2, h3, h4, h5, h6).body-2 { font-size: var(--text-body-2-size); font-weight: var(--text-body-2-weight); }
|
|
176
|
+
:where(h1, h2, h3, h4, h5, h6).body-2b { font-size: var(--text-body-2-size); font-weight: var(--text-body-2-weight-bold); }
|
|
177
|
+
:where(h1, h2, h3, h4, h5, h6).body-3 { font-size: var(--text-body-3-size); font-weight: var(--text-body-3-weight); }
|
|
178
|
+
:where(h1, h2, h3, h4, h5, h6).body-3b { font-size: var(--text-body-3-size); font-weight: var(--text-body-3-weight-bold); }
|
|
179
|
+
:where(h1, h2, h3, h4, h5, h6).caption-1 { font-size: var(--text-caption-1-size); font-weight: var(--text-caption-1-weight); }
|
|
180
|
+
:where(h1, h2, h3, h4, h5, h6).caption-1b { font-size: var(--text-caption-1-size); font-weight: var(--text-caption-1-weight-bold); }
|
|
181
|
+
:where(h1, h2, h3, h4, h5, h6).caption-2 { font-size: var(--text-caption-2-size); font-weight: var(--text-caption-2-weight); }
|
|
182
|
+
:where(h1, h2, h3, h4, h5, h6).caption-2b { font-size: var(--text-caption-2-size); font-weight: var(--text-caption-2-weight-bold); }
|
|
183
|
+
:where(h1, h2, h3, h4, h5, h6).button-1 { font-size: var(--text-button-1-size); font-weight: var(--text-button-1-weight); }
|
|
184
|
+
:where(h1, h2, h3, h4, h5, h6).button-2 { font-size: var(--text-button-2-size); font-weight: var(--text-button-2-weight); }
|
|
98
185
|
|
|
99
186
|
/* ── 전역 스크롤바 ──────────────────────────────────────── */
|
|
100
187
|
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
@@ -133,10 +133,34 @@
|
|
|
133
133
|
--font-family: 'Pretendard Variable', 'Pretendard', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
|
|
134
134
|
|
|
135
135
|
/* ── 타입 스케일 ──────────────────────────────────────────
|
|
136
|
-
클래스(.h0~.h5 / .body-* / .button-* / .caption-*)는 styles.css에 있고 값은 전부
|
|
136
|
+
클래스(.display-1~3 / .h0~.h5 / .body-* / .button-* / .caption-*)는 styles.css에 있고 값은 전부
|
|
137
137
|
여기서 온다. 아래 반응형·글자 크기 스케일 블록이 같은 변수를 재정의하므로,
|
|
138
138
|
다른 프레임워크(Tailwind @theme 등)에서도 이 변수만 읽으면 동일한 스케일을 얻는다.
|
|
139
139
|
`-weight`는 기본, `-weight-bold`는 클래스명에 b가 붙은 변형(.h0b, .body-1b …)이다. */
|
|
140
|
+
/* ── 디스플레이 단 (display-1~3) ─────────────────────────
|
|
141
|
+
h0 **위**의 세 단. 앱 화면 제목이 아니라 **랜딩·히어로처럼 크게 외치는 자리** 전용이다.
|
|
142
|
+
그래서 아래 h0~h5 와 규약이 셋 다르다 —
|
|
143
|
+
|
|
144
|
+
· **크기는 clamp(뷰포트 연속 보간)** 이다. h 단은 미디어쿼리로 세 계단을 뛰는데,
|
|
145
|
+
히어로 글자가 계단으로 뛰면 그 폭 근처에서 줄바꿈이 툭툭 달라진다. 아래
|
|
146
|
+
반응형 블록에 display 를 **다시 적지 않는 것은 그 때문**이다(적으면 계단이
|
|
147
|
+
되살아난다).
|
|
148
|
+
· **행간은 배수, 자간은 em** 이다. 크기가 연속으로 변하는데 px 로 박으면 큰 화면
|
|
149
|
+
에서 행간이 붙고 작은 화면에서 벌어진다.
|
|
150
|
+
· **글자 크기 스케일([data-font-scale])에서 뺀다.** h0~h3 도 같은 이유로 빠져
|
|
151
|
+
있다 — 이미 충분히 크고, 키우면 히어로 한 줄이 화면을 넘긴다.
|
|
152
|
+
|
|
153
|
+
h0(40px) 과 겹치지 않게 잡았다. 어느 폭에서도 h0 < display-3 < display-2 < display-1:
|
|
154
|
+
375px h0 28 · d3 34 · d2 38 · d1 44
|
|
155
|
+
768px h0 32 · d3 34 · d2 40 · d1 51
|
|
156
|
+
1024px h0 40 · d3 42 · d2 53 · d1 68
|
|
157
|
+
1440px h0 40 · d3 44 · d2 56 · d1 72 (셋 다 최댓값 도달)
|
|
158
|
+
특히 1024px 은 h0 가 32→40 으로 뛰는 지점이라, display-3 의 vw 계수(4.1)는
|
|
159
|
+
그 자리에서 40 을 넘도록 잡은 값이다. 낮추면 그 폭에서만 h0 보다 작아진다. */
|
|
160
|
+
--text-display-1-size: clamp(44px, 6.6vw, 72px); --text-display-1-line: 1.05; --text-display-1-spacing: -0.04em; --text-display-1-weight: 800; --text-display-1-weight-bold: 900;
|
|
161
|
+
--text-display-2-size: clamp(38px, 5.2vw, 56px); --text-display-2-line: 1.12; --text-display-2-spacing: -0.03em; --text-display-2-weight: 700; --text-display-2-weight-bold: 800;
|
|
162
|
+
--text-display-3-size: clamp(34px, 4.1vw, 44px); --text-display-3-line: 1.2; --text-display-3-spacing: -0.02em; --text-display-3-weight: 700; --text-display-3-weight-bold: 800;
|
|
163
|
+
|
|
140
164
|
--text-h0-size: 40px; --text-h0-line: 52px; --text-h0-spacing: -1px; --text-h0-weight: 700; --text-h0-weight-bold: 800;
|
|
141
165
|
--text-h1-size: 32px; --text-h1-line: 44px; --text-h1-spacing: -0.5px; --text-h1-weight: 700; --text-h1-weight-bold: 800;
|
|
142
166
|
--text-h2-size: 24px; --text-h2-line: 34px; --text-h2-spacing: -0.25px; --text-h2-weight: 500; --text-h2-weight-bold: 600;
|