@orioncactuscorp/ui 1.9.2 → 1.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.
Files changed (99) hide show
  1. package/README.md +119 -54
  2. package/dist/components/Accordion/Accordion.css +1 -1
  3. package/dist/components/Accordion/Accordion.js +169 -177
  4. package/dist/components/ActionArea/ActionAreaLayout.js +20 -24
  5. package/dist/components/Cell/Cell.css +1 -1
  6. package/dist/components/Cell/Cell.js +57 -58
  7. package/dist/components/CheckMark/CheckMark.css +1 -1
  8. package/dist/components/Checkbox/Checkbox.css +1 -1
  9. package/dist/components/Checkbox/Checkbox.js +50 -51
  10. package/dist/components/Menu/Menu.css +1 -1
  11. package/dist/components/Menu/Menu.module.scss.js +20 -22
  12. package/dist/components/Modal/Modal.css +1 -1
  13. package/dist/components/Modal/Modal.js +585 -575
  14. package/dist/components/Modal/bottomSheetGeometry.js +46 -33
  15. package/dist/components/Modal/modalScrollArbitration.js +71 -49
  16. package/dist/components/Modal/snapPoints.js +42 -38
  17. package/dist/components/Modal/useModalContentBlockTransition.js +49 -44
  18. package/dist/components/Modal/useModalDrag.js +937 -854
  19. package/dist/components/Radio/Radio.css +1 -1
  20. package/dist/components/ScrollArea/ScrollArea.js +197 -200
  21. package/dist/components/Select/Select.js +31 -34
  22. package/dist/components/Switch/Switch.css +1 -1
  23. package/dist/components/Tabs/Tabs.css +1 -0
  24. package/dist/components/Tabs/Tabs.js +208 -0
  25. package/dist/components/Tabs/Tabs.module.scss.js +27 -0
  26. package/dist/components/Tabs.d.ts +6 -0
  27. package/dist/components/Tabs.js +8 -0
  28. package/dist/components/TextArea/TextArea.js +57 -58
  29. package/dist/components/TextInput/TextInput.js +30 -33
  30. package/dist/components/Tooltip/Tooltip.css +1 -1
  31. package/dist/foundations/color.theme.dark.css +1 -1
  32. package/dist/foundations/color.theme.light.css +1 -1
  33. package/dist/foundations/focus.css +1 -0
  34. package/dist/foundations/reset.css +1 -1
  35. package/dist/foundations.css +4 -3
  36. package/dist/index.js +69 -64
  37. package/dist/react/motion.js +31 -35
  38. package/dist/reset.css +1 -1
  39. package/dist/styles.css +14 -12
  40. package/dist/ui/src/components/Accordion/Accordion.d.ts.map +1 -1
  41. package/dist/ui/src/components/ActionArea/ActionAreaLayout.d.ts.map +1 -1
  42. package/dist/ui/src/components/Cell/Cell.d.ts.map +1 -1
  43. package/dist/ui/src/components/CheckMark/types.d.ts +10 -0
  44. package/dist/ui/src/components/CheckMark/types.d.ts.map +1 -1
  45. package/dist/ui/src/components/Checkbox/Checkbox.d.ts.map +1 -1
  46. package/dist/ui/src/components/Checkbox/types.d.ts +16 -0
  47. package/dist/ui/src/components/Checkbox/types.d.ts.map +1 -1
  48. package/dist/ui/src/components/Modal/Modal.d.ts +1 -1
  49. package/dist/ui/src/components/Modal/Modal.d.ts.map +1 -1
  50. package/dist/ui/src/components/Modal/bottomSheetGeometry.d.ts +13 -0
  51. package/dist/ui/src/components/Modal/bottomSheetGeometry.d.ts.map +1 -1
  52. package/dist/ui/src/components/Modal/modalScrollArbitration.d.ts.map +1 -1
  53. package/dist/ui/src/components/Modal/snapPoints.d.ts +3 -1
  54. package/dist/ui/src/components/Modal/snapPoints.d.ts.map +1 -1
  55. package/dist/ui/src/components/Modal/types.d.ts +8 -0
  56. package/dist/ui/src/components/Modal/types.d.ts.map +1 -1
  57. package/dist/ui/src/components/Modal/useModalContentBlockTransition.d.ts.map +1 -1
  58. package/dist/ui/src/components/Modal/useModalDrag.d.ts +27 -10
  59. package/dist/ui/src/components/Modal/useModalDrag.d.ts.map +1 -1
  60. package/dist/ui/src/components/Radio/types.d.ts +16 -0
  61. package/dist/ui/src/components/Radio/types.d.ts.map +1 -1
  62. package/dist/ui/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
  63. package/dist/ui/src/components/Select/Select.d.ts.map +1 -1
  64. package/dist/ui/src/components/Switch/types.d.ts +10 -0
  65. package/dist/ui/src/components/Switch/types.d.ts.map +1 -1
  66. package/dist/ui/src/components/Tabs/Tabs.d.ts +7 -0
  67. package/dist/ui/src/components/Tabs/Tabs.d.ts.map +1 -0
  68. package/dist/ui/src/components/Tabs/index.d.ts +3 -0
  69. package/dist/ui/src/components/Tabs/index.d.ts.map +1 -0
  70. package/dist/ui/src/components/Tabs/types.d.ts +26 -0
  71. package/dist/ui/src/components/Tabs/types.d.ts.map +1 -0
  72. package/dist/ui/src/components/TextArea/TextArea.d.ts.map +1 -1
  73. package/dist/ui/src/components/TextInput/TextInput.d.ts.map +1 -1
  74. package/dist/ui/src/index.d.ts +2 -0
  75. package/dist/ui/src/index.d.ts.map +1 -1
  76. package/dist/ui/src/react/motion/index.d.ts.map +1 -1
  77. package/dist/ui/src/utils/mergeRefs.d.ts +13 -0
  78. package/dist/ui/src/utils/mergeRefs.d.ts.map +1 -0
  79. package/dist/utils/mergeRefs.js +24 -0
  80. package/dist/vscode/oc-ui-vars.css +13 -0
  81. package/docs/editor-setup.md +42 -0
  82. package/docs/motion.md +665 -0
  83. package/docs/responsive-foundation-profile.md +230 -0
  84. package/docs/scss-helpers.md +189 -0
  85. package/docs/selector-contract.md +260 -0
  86. package/docs/spring.md +382 -0
  87. package/docs/stability.md +62 -0
  88. package/docs/tokens.md +559 -0
  89. package/package.json +9 -4
  90. package/src/scss/foundations/color-theme.test.ts +14 -0
  91. package/src/scss/foundations/color.theme.dark.scss +1 -0
  92. package/src/scss/foundations/color.theme.light.scss +1 -0
  93. package/src/scss/foundations/focus.scss +4 -0
  94. package/src/scss/foundations/focus.test.ts +48 -0
  95. package/src/scss/foundations/reset.scss +9 -4
  96. package/src/scss/foundations/reset.test.ts +32 -0
  97. package/src/scss/index.scss +2 -0
  98. package/src/scss/mixins/_focus.scss +11 -0
  99. package/src/scss/mixins/_focus.test.ts +58 -0
@@ -0,0 +1,230 @@
1
+ # Responsive Foundation Profile
2
+
3
+ `responsive.config`는 typography와 spacing foundation의 responsive 출력 방식을 정하는 SCSS compile-time profile이다. `typo`와 `space`는 같은 mode를 공유하며, 소비자는 token 값을 다시 작성하지 않고 공통 stop 또는 foundation별 stop range를 선택한다.
4
+
5
+ 이 profile은 `@orioncactuscorp/ui/foundations.css` 또는 `@orioncactuscorp/ui/styles.css` 같은 prebuilt CSS에는 적용되지 않는다. profile을 바꾸려면 SCSS source foundation을 직접 import해서 consumer build에서 컴파일해야 한다.
6
+
7
+ ## Config
8
+
9
+ ```scss
10
+ @use '@orioncactuscorp/ui/scss/foundations/responsive.config' with (
11
+ $oc-responsive-mode: fluid,
12
+ $oc-responsive-stops: (
13
+ min,
14
+ sm,
15
+ md,
16
+ lg,
17
+ xl,
18
+ hg,
19
+ ),
20
+ $oc-responsive-typo-stops: null,
21
+ $oc-responsive-space-stops: null,
22
+ $oc-responsive-space-profile: null,
23
+ $oc-responsive-static-stop: null
24
+ );
25
+ ```
26
+
27
+ ### `$oc-responsive-mode`
28
+
29
+ - `fluid`: 기본값. 기존 출력과 동일하게 stop 사이를 `fluidClamp()`로 보간한다.
30
+ - `stepped`: `clamp()` 없이 stop 값이 breakpoint에서 계단식으로 바뀐다.
31
+ - `static`: 선택한 stop 하나를 전체 viewport에 고정한다.
32
+
33
+ ### `$oc-responsive-stops`
34
+
35
+ 활성화할 기본 design stop 목록이다.
36
+
37
+ - `fluid`: active range로 사용한다. range 밖은 가까운 active stop 값으로 고정된다.
38
+ - `stepped`: 첫 stop은 base 값으로 출력하고, 이후 stop은 `respond-to(min, stop)` 기준 media에서 출력한다.
39
+ - `static`: foundation별 stops가 없을 때 fallback active range로 사용한다.
40
+
41
+ `sm`, `md`는 design stop 이름이다. 단일 `respond-to(sm/md)` mixin은 max-width 편의 API지만, `stepped` profile의 stop 전환은 `respond-to(min, stop)` 기준이다. 예를 들어 `md` 값은 `min-width: 769px`부터 적용된다.
42
+
43
+ ### `$oc-responsive-typo-stops`
44
+
45
+ `typo` size/height token에만 적용할 design stop 목록이다. `null`이면 `$oc-responsive-stops`를 사용한다.
46
+
47
+ ### `$oc-responsive-space-stops`
48
+
49
+ `space` token에만 적용할 design stop 목록이다. `null`이면 `$oc-responsive-stops`를 사용한다.
50
+
51
+ ### `$oc-responsive-space-profile`
52
+
53
+ `space` token의 stepped 출력 방식을 바꾸는 profile이다. `null`이면 `$oc-responsive-mode: stepped`에서 active stops를 순서대로 출력한다.
54
+
55
+ 현재 지원하는 profile type:
56
+
57
+ - `stepped-points`: named point별 target stop을 출력한다. `points.base`는 base `:root` 값이고, `min-md` 같은 point는 `respond-to(min, md)` 기준 media로 출력한다.
58
+
59
+ `max-active-defined` target은 `$oc-responsive-space-stops` 안에서 해당 token에 실제 값이 있는 마지막 stop을 사용한다. `$oc-space-overrides`에서 stop 값을 `null`로 지정하면 그 stop은 정의되지 않은 것으로 취급한다.
60
+
61
+ ### `$oc-responsive-static-stop`
62
+
63
+ `static` mode에서 전체 foundation에 공통으로 사용할 stop이다. 생략하면 각 foundation의 active stops 첫 번째 stop을 사용한다. foundation별 stops가 없으면 `$oc-responsive-stops`의 첫 번째 stop을 사용한다.
64
+
65
+ ## Examples
66
+
67
+ ### Default Fluid
68
+
69
+ 별도 설정 없이 `typo`와 `space`를 import하면 기본 fluid profile이 적용된다.
70
+
71
+ ```scss
72
+ @use '@orioncactuscorp/ui/scss/foundations/typo';
73
+ @use '@orioncactuscorp/ui/scss/foundations/space';
74
+ ```
75
+
76
+ ### Stepped, sm~md Only
77
+
78
+ `sm` 값을 base로 쓰고, `md` 값은 `769px`부터 적용한다. `lg` 이상 stop은 출력하지 않으므로 `md` 값이 이후 viewport에서도 유지된다.
79
+
80
+ ```scss
81
+ @use '@orioncactuscorp/ui/scss/foundations/responsive.config' with (
82
+ $oc-responsive-mode: stepped,
83
+ $oc-responsive-stops: (
84
+ sm,
85
+ md,
86
+ )
87
+ );
88
+
89
+ @use '@orioncactuscorp/ui/scss/foundations/typo';
90
+ @use '@orioncactuscorp/ui/scss/foundations/space';
91
+ ```
92
+
93
+ 출력 형태:
94
+
95
+ ```css
96
+ :root {
97
+ --oc-typo-size-body1: 1rem;
98
+ }
99
+
100
+ @media screen and (min-width: 769px) {
101
+ :root {
102
+ --oc-typo-size-body1: 1.0625rem;
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Separate Typo and Space Stops
108
+
109
+ mode는 `typo`와 `space`가 공유하되 active stop range만 다르게 지정할 수 있다. 아래 예시는 `typo`를 `sm` 값에 고정하고, `space`는 `sm` 값을 base로 쓰다가 `md` 이상에서 `md` 값으로 전환한다.
110
+
111
+ ```scss
112
+ @use '@orioncactuscorp/ui/scss/foundations/responsive.config' with (
113
+ $oc-responsive-mode: stepped,
114
+ $oc-responsive-typo-stops: (
115
+ sm,
116
+ ),
117
+ $oc-responsive-space-stops: (
118
+ sm,
119
+ md,
120
+ )
121
+ );
122
+
123
+ @use '@orioncactuscorp/ui/scss/foundations/typo';
124
+ @use '@orioncactuscorp/ui/scss/foundations/space';
125
+ ```
126
+
127
+ `$oc-responsive-typo-stops` 또는 `$oc-responsive-space-stops`를 생략하면 기존처럼 `$oc-responsive-stops`를 fallback으로 사용한다. `static` mode에서 `$oc-responsive-static-stop`을 생략한 경우에도 각 foundation의 첫 active stop을 고정값으로 사용한다.
128
+
129
+ ### Two-Mode Figma Viewport
130
+
131
+ Figma `Viewport` collection이 `Mobile(md)`와 `Desktop(min, md)`처럼 두 mode만 갖고, `Desktop(min, md)`가 token별 desktop target 값을 가리킬 때는 `space`에 `stepped-points` profile을 사용한다.
132
+
133
+ ```scss
134
+ @use '@orioncactuscorp/ui/scss/foundations/responsive.config' with (
135
+ $oc-responsive-mode: stepped,
136
+ $oc-responsive-typo-stops: (
137
+ sm,
138
+ ),
139
+ $oc-responsive-space-stops: (
140
+ md,
141
+ lg,
142
+ xl,
143
+ ),
144
+ $oc-responsive-space-profile: (
145
+ type: stepped-points,
146
+ points: (
147
+ base: md,
148
+ min-md: max-active-defined,
149
+ ),
150
+ )
151
+ );
152
+
153
+ @use '@orioncactuscorp/ui/scss/foundations/space' with (
154
+ $oc-space-overrides: (
155
+ section-padding-viewport-x: (
156
+ md: 20,
157
+ xl: 32,
158
+ ),
159
+ section-padding-viewport-y: (
160
+ md: 16,
161
+ xl: 24,
162
+ ),
163
+ item-gap-small: (
164
+ xl: null,
165
+ ),
166
+ )
167
+ );
168
+ ```
169
+
170
+ 이 profile은 `space`의 base 값을 각 token의 `md`로 출력하고, `769px+`부터 `$oc-responsive-space-stops` 안의 마지막 정의값으로 전환한다. 예를 들어 `item-padding-xsmall`은 `md -> xl`, `item-gap-tiny`는 `md -> lg`, `item-gap-small`은 `xl: null` 때문에 `md -> lg`로 출력된다.
171
+
172
+ ### Static md
173
+
174
+ 전체 viewport에서 `md` 값을 사용한다. 한 stop만 쓸 때 `fluid`나 `stepped`도 결과적으로 static처럼 출력되지만, 고정 의도를 드러내려면 `static` mode를 권장한다.
175
+
176
+ ```scss
177
+ @use '@orioncactuscorp/ui/scss/foundations/responsive.config' with (
178
+ $oc-responsive-mode: static,
179
+ $oc-responsive-static-stop: md
180
+ );
181
+
182
+ @use '@orioncactuscorp/ui/scss/foundations/typo';
183
+ @use '@orioncactuscorp/ui/scss/foundations/space';
184
+ ```
185
+
186
+ 출력 형태:
187
+
188
+ ```css
189
+ :root {
190
+ --oc-typo-size-body1: 1.0625rem;
191
+ --oc-space-section-padding-viewport-x: 2rem;
192
+ }
193
+ ```
194
+
195
+ ## Full Foundation Rebuild
196
+
197
+ `foundations.css`를 profile 적용 버전으로 대체하려면 consumer entry에서 foundation SCSS를 직접 import한다.
198
+
199
+ ```scss
200
+ @use '@orioncactuscorp/ui/scss/foundations/responsive.config' with (
201
+ $oc-responsive-mode: static,
202
+ $oc-responsive-static-stop: md
203
+ );
204
+ @use '@orioncactuscorp/ui/scss/foundations/color.global' as *;
205
+ @use '@orioncactuscorp/ui/scss/foundations/color.theme.light' as *;
206
+ @use '@orioncactuscorp/ui/scss/foundations/color.theme.dark' as *;
207
+ @use '@orioncactuscorp/ui/scss/foundations/breakpoint' as *;
208
+ @use '@orioncactuscorp/ui/scss/foundations/typo' as *;
209
+ @use '@orioncactuscorp/ui/scss/foundations/space' as *;
210
+ @use '@orioncactuscorp/ui/scss/foundations/atomic' as *;
211
+ @use '@orioncactuscorp/ui/scss/foundations/focus' as *;
212
+ @use '@orioncactuscorp/ui/scss/foundations/motion' as *;
213
+ @use '@orioncactuscorp/ui/scss/foundations/zindex' as *;
214
+ ```
215
+
216
+ 이 consumer SCSS를 `@orioncactuscorp/ui/foundations.css` 대신 import한다.
217
+
218
+ `reset.css`는 package prebuilt CSS를 그대로 import해도 된다.
219
+
220
+ ```tsx
221
+ import '@orioncactuscorp/ui/reset.css';
222
+ import './foundations.scss';
223
+ ```
224
+
225
+ ## Scope
226
+
227
+ - responsive profile은 현재 `typo` size/height와 `space` token을 제어한다.
228
+ - Typography letter spacing과 weight는 고정 token map을 유지한다.
229
+ - `atomic` radius token은 `responsive.config` 대상이 아니며 기존 foundation 동작을 유지한다.
230
+ - CSS variable runtime override와 SCSS compile-time profile은 서로 다른 customization 경로다.
@@ -0,0 +1,189 @@
1
+ # SCSS Helpers
2
+
3
+ `@orioncactuscorp/ui`가 SCSS source로 제공하는 consumer용 mixin/function입니다. 각 모듈은 `@orioncactuscorp/ui/scss/*` subpath로 import하고, `@use ... as *;` 형태를 사용합니다.
4
+
5
+ ```scss
6
+ @use '@orioncactuscorp/ui/scss/mixins/element' as *;
7
+ @use '@orioncactuscorp/ui/scss/mixins/breakpoint' as *;
8
+ ```
9
+
10
+ > `@orioncactuscorp/ui/scss/index.scss` 통합 entry는 mixin뿐 아니라 **foundation CSS(토큰 + reset)를 함께 방출**합니다. `foundations.css`를 이미 import하고 있다면 토큰이 중복 방출되므로, mixin/function만 필요할 때는 위처럼 개별 mixin 모듈을 import하세요. 통합 entry는 prebuilt `foundations.css` 대신 SCSS foundation source를 직접 compile하는 경로에서만 사용합니다.
11
+
12
+ 이 문서에 있는 helper가 공개 계약입니다. 문서화되지 않은 export는 내부 구현이며 예고 없이 바뀔 수 있습니다([Stability Policy](./stability.md)).
13
+
14
+ ## oc-border — layout에 영향 없는 surface stroke
15
+
16
+ `@orioncactuscorp/ui/scss/mixins/element`
17
+
18
+ 실제 CSS `border` 대신 `box-shadow`로 stroke를 그립니다. 요소의 content/padding/layout 크기를 바꾸지 않습니다.
19
+
20
+ ```scss
21
+ @include oc-border($tokens...);
22
+ ```
23
+
24
+ CSS `border` shorthand와 비슷하게 토큰을 순서 무관하게 나열합니다.
25
+
26
+ | 토큰 | 값 | 기본값 | 비고 |
27
+ | --------- | --------------------------------------------------- | -------------- | ---------------------------------------------------------------------- |
28
+ | width | number (1개) | `1px` | `1.5px` 같은 half-pixel은 WebKit/DPR 보정 출력 포함 |
29
+ | color | color, `var(...)` (1개) | `currentColor` | |
30
+ | side | `top`, `right`, `bottom`, `left` (복수 가능), `all` | `all` | 개별 side는 해당 방향 단일 stroke |
31
+ | placement | `inset`, `outer` | `inset` | `outer`는 요소 바깥에 그림 (역시 layout 무영향) |
32
+ | style | `solid` | - | CSS shorthand 익숙함을 위해 수용만 함 (box-shadow stroke는 항상 solid) |
33
+
34
+ ```scss
35
+ .surface {
36
+ @include oc-border; // 1px currentColor inset
37
+ }
38
+
39
+ .surfaceAccent {
40
+ @include oc-border(var(--oc-color-theme-primary-normal));
41
+ }
42
+
43
+ .surfaceInvalid {
44
+ @include oc-border(1.5px, var(--oc-color-theme-status-negative));
45
+ }
46
+
47
+ .underline {
48
+ @include oc-border(bottom); // 아래쪽만
49
+ }
50
+
51
+ .focusRing {
52
+ @include oc-border(2px, var(--oc-color-theme-primary-normal), outer);
53
+ }
54
+ ```
55
+
56
+ `box-shadow` 한 채널을 사용하므로, 같은 요소에서 다른 `box-shadow`와 함께 쓸 때는 직접 shadow 목록을 조합해야 합니다.
57
+
58
+ ## oc-radius — 전역 radius factor 연동
59
+
60
+ `@orioncactuscorp/ui/scss/mixins/radius`
61
+
62
+ ```scss
63
+ oc-radius($radius, $factor-token: var(--oc-atomic-radius-factor))
64
+ ```
65
+
66
+ `rem`/`em`/`px`/`clamp(...)` 기반 radius 값을 전역 radius factor에 연결합니다. `--oc-atomic-radius-factor`를 `0`으로 두면 이 helper를 거친 컴포넌트 로컬 radius도 함께 각지게 됩니다.
67
+
68
+ ```scss
69
+ @use '@orioncactuscorp/ui/scss/mixins/radius' as *;
70
+
71
+ .badge {
72
+ --oc-badge-radius: #{oc-radius(0.4em)};
73
+ }
74
+ ```
75
+
76
+ ## oc-focus-ring — 키보드 포커스 ring
77
+
78
+ `@orioncactuscorp/ui/scss/mixins/focus`
79
+
80
+ ```scss
81
+ oc-focus-ring($color: var(--oc-color-theme-focus-ring), $width: var(--oc-focus-ring-width), $offset: var(--oc-focus-ring-offset))
82
+ ```
83
+
84
+ `:focus-visible` ring을 foundation 토큰으로 그립니다. `outline` 기반이라 layout에 영향이 없고 요소의 border-radius를 그대로 따라가며 forced-colors 모드에서도 유지됩니다. reset 레이어가 `button`/`a[href]`/`summary`/`[tabindex]`에 같은 ring을 전역 기본값으로 제공하므로, 이 믹스인은 `all: unset`을 쓰는 요소나 ring을 다른 요소로 리다이렉트하는 경우(예: 선택 컨트롤의 wrapper)에 사용합니다.
85
+
86
+ ```scss
87
+ @use '@orioncactuscorp/ui/scss/mixins/focus' as *;
88
+
89
+ .trigger {
90
+ all: unset;
91
+
92
+ &:focus-visible {
93
+ @include oc-focus-ring;
94
+ }
95
+ }
96
+ ```
97
+
98
+ ## oc-alpha — 토큰 기반 알파 색상
99
+
100
+ `@orioncactuscorp/ui/scss/mixins/color`
101
+
102
+ ```scss
103
+ oc-alpha($color, $opacity)
104
+ ```
105
+
106
+ `color-mix(in srgb, ...)`로 알파가 적용된 색을 만듭니다. runtime CSS 변수 색상에도 알파를 적용할 수 있다는 점이 Sass `rgba()`와의 차이입니다.
107
+
108
+ - `$color`: Sass color, `var(...)`, 또는 global color 토큰 suffix (`--oc-color-global-` 뒤 이름)
109
+ - `$opacity`: `0`~`1` 숫자, 또는 global opacity 토큰 suffix (`--oc-color-global-opacity-` 뒤 이름)
110
+
111
+ ```scss
112
+ @use '@orioncactuscorp/ui/scss/mixins/color' as *;
113
+
114
+ .scrim {
115
+ background-color: oc-alpha(var(--oc-color-theme-primary-normal), 0.4);
116
+ }
117
+ ```
118
+
119
+ ## typo — typography 토큰 조합
120
+
121
+ `@orioncactuscorp/ui/scss/mixins/typo`
122
+
123
+ ```scss
124
+ @include typo($variant, $weight: normal);
125
+ ```
126
+
127
+ `font-size`, `line-height`, `letter-spacing`, `font-weight`를 `--oc-typo-*` 토큰에서 한 번에 출력합니다. raw `var(--oc-typo-size-*)` 직접 참조 대신 이 mixin을 사용하세요 — `--oc-typo-size-factor` runtime multiplier가 자동 반영됩니다.
128
+
129
+ - `$variant`: foundation typo variant 이름 (`title1`, `body1` 등 — 전체 목록은 [Token Reference](./tokens.md))
130
+ - `$weight`: `normal` | `medium` | `bold`
131
+
132
+ variant별로 제공되는 weight는 [Token Reference](./tokens.md)의 `--oc-typo-weight-{variant}-*` 토큰 존재 여부를 기준으로 합니다.
133
+
134
+ ```scss
135
+ @use '@orioncactuscorp/ui/scss/mixins/typo' as *;
136
+
137
+ .heading {
138
+ @include typo(title2, bold);
139
+ }
140
+ ```
141
+
142
+ ## respond-to — breakpoint media query
143
+
144
+ `@orioncactuscorp/ui/scss/mixins/breakpoint`
145
+
146
+ ```scss
147
+ @include respond-to($bp1, $bp2: null) { ... }
148
+ ```
149
+
150
+ named breakpoint: `sm`(480px), `md`(768px), `lg`(1280px), `xl`(1600px), `hg`(1920px). `@use ... with ($breakpoint-md: 800px)`로 override할 수 있습니다.
151
+
152
+ | 호출 | 출력 media | 용도 |
153
+ | ---------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------ |
154
+ | `respond-to(sm)`, `respond-to(md)` | `(max-width: bp)` | 좁은 viewport 예외 보정 |
155
+ | `respond-to(lg)`, `respond-to(xl)`, `respond-to(hg)` | `(min-width: bp + 1px)` | 넓은 viewport 확장 |
156
+ | `respond-to(min, $bp)` | `(min-width: bp + 1px)` (named) / `(min-width: 값)` (직접 값) | mobile-first progressive enhancement |
157
+ | `respond-to(max, $bp)` | `(max-width: bp)` | 상한 |
158
+ | `respond-to($bp1, $bp2)` | `(min-width: 작은쪽 + 1px) and (max-width: 큰쪽)` | 구간 |
159
+
160
+ 직접 숫자 값(`respond-to(min, 900px)`)도 받습니다. raw `@media (min-width: ...)` 대신 항상 이 mixin을 사용하세요.
161
+
162
+ oc-ui SCSS는 mobile-first가 기본입니다: base rule은 narrow viewport 기준으로 쓰고, desktop 이상 차이는 `respond-to(min, md)`에서 더합니다. `respond-to(md)`(max-width)는 `Mobile(md)` 전용 예외 보정에만 사용합니다.
163
+
164
+ ## fluidClamp / toRem — fluid 값 유틸
165
+
166
+ `@orioncactuscorp/ui/scss/mixins/utils`
167
+
168
+ ```scss
169
+ fluidClamp($from, $bp, $anchor: to, $to)
170
+ ```
171
+
172
+ `clamp($from, <viewport 비례식>, $to)`를 출력합니다. `$bp`는 기준 breakpoint(px), `$anchor`는 비례식이 어느 끝값에 정렬될지(`to` 기본, `from` 선택)입니다. foundation typo/space 토큰의 fluid 출력에 쓰이는 것과 같은 helper로, 커스텀 fluid 값을 만들 때 사용합니다.
173
+
174
+ ```scss
175
+ @use '@orioncactuscorp/ui/scss/mixins/utils' as *;
176
+
177
+ .hero {
178
+ padding-block: fluidClamp(toRem(24), 1280, to, toRem(64));
179
+ }
180
+ ```
181
+
182
+ `toRem($px)`는 `16px = 1rem` 기준으로 숫자를 rem으로 변환합니다.
183
+
184
+ ## Motion / Spring
185
+
186
+ transition·animation helper(`oc-motion`, `oc-spring`)는 별도 가이드를 참조하세요.
187
+
188
+ - [Semantic Motion](./motion.md) — intent/phase/pace 기반 motion 계약
189
+ - [Spring Motion](./spring.md) — iOS perceptual duration 기반 spring transition