@conscience-technology/ctds 0.0.0-stage → 0.1.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 (289) hide show
  1. package/README.md +128 -2
  2. package/assets/components/AppFrame/AppFrame.module.css +177 -0
  3. package/assets/components/AppFrame/AppFrame.tsx +93 -0
  4. package/assets/components/AppFrame/index.ts +6 -0
  5. package/assets/components/AttachmentChip/AttachmentChip.module.css +71 -0
  6. package/assets/components/AttachmentChip/AttachmentChip.tsx +74 -0
  7. package/assets/components/AttachmentChip/index.ts +2 -0
  8. package/assets/components/AttachmentThumb/AttachmentThumb.module.css +107 -0
  9. package/assets/components/AttachmentThumb/AttachmentThumb.tsx +91 -0
  10. package/assets/components/AttachmentThumb/index.ts +2 -0
  11. package/assets/components/Avatar/Avatar.module.css +167 -0
  12. package/assets/components/Avatar/Avatar.tsx +228 -0
  13. package/assets/components/Avatar/index.ts +2 -0
  14. package/assets/components/AvatarUpload/AvatarUpload.module.css +130 -0
  15. package/assets/components/AvatarUpload/AvatarUpload.tsx +139 -0
  16. package/assets/components/AvatarUpload/index.ts +2 -0
  17. package/assets/components/Badge/Badge.module.css +76 -0
  18. package/assets/components/Badge/Badge.tsx +68 -0
  19. package/assets/components/Badge/index.ts +2 -0
  20. package/assets/components/Breadcrumb/Breadcrumb.module.css +213 -0
  21. package/assets/components/Breadcrumb/Breadcrumb.tsx +279 -0
  22. package/assets/components/Breadcrumb/index.ts +8 -0
  23. package/assets/components/Button/Button.module.css +216 -0
  24. package/assets/components/Button/Button.tsx +149 -0
  25. package/assets/components/Button/index.ts +2 -0
  26. package/assets/components/Callout/Callout.module.css +146 -0
  27. package/assets/components/Callout/Callout.tsx +138 -0
  28. package/assets/components/Callout/index.ts +2 -0
  29. package/assets/components/ChatInput/ChatInput.module.css +241 -0
  30. package/assets/components/ChatInput/ChatInput.tsx +322 -0
  31. package/assets/components/ChatInput/ModelSelector.tsx +40 -0
  32. package/assets/components/ChatInput/SendButton.tsx +41 -0
  33. package/assets/components/ChatInput/index.ts +10 -0
  34. package/assets/components/Checkbox/Checkbox.module.css +66 -0
  35. package/assets/components/Checkbox/Checkbox.tsx +36 -0
  36. package/assets/components/Checkbox/index.ts +2 -0
  37. package/assets/components/Chip/Chip.module.css +128 -0
  38. package/assets/components/Chip/Chip.tsx +103 -0
  39. package/assets/components/Chip/index.ts +2 -0
  40. package/assets/components/ChoiceCard/ChoiceCard.module.css +142 -0
  41. package/assets/components/ChoiceCard/ChoiceCard.tsx +132 -0
  42. package/assets/components/ChoiceCard/index.ts +2 -0
  43. package/assets/components/ContextMenu/ContextMenu.module.css +102 -0
  44. package/assets/components/ContextMenu/ContextMenu.tsx +392 -0
  45. package/assets/components/ContextMenu/index.ts +9 -0
  46. package/assets/components/DatePicker/Calendar.tsx +234 -0
  47. package/assets/components/DatePicker/DESIGN_NOTES.md +106 -0
  48. package/assets/components/DatePicker/DESIGN_NOTES_TIME.md +125 -0
  49. package/assets/components/DatePicker/DatePicker.module.css +295 -0
  50. package/assets/components/DatePicker/DatePicker.tsx +387 -0
  51. package/assets/components/DatePicker/TimeSelector.tsx +69 -0
  52. package/assets/components/DatePicker/index.ts +8 -0
  53. package/assets/components/DatePicker/presets.ts +80 -0
  54. package/assets/components/DatePicker/utils.ts +148 -0
  55. package/assets/components/Disclosure/Disclosure.module.css +73 -0
  56. package/assets/components/Disclosure/Disclosure.tsx +129 -0
  57. package/assets/components/Disclosure/index.ts +6 -0
  58. package/assets/components/Drawer/Drawer.module.css +257 -0
  59. package/assets/components/Drawer/Drawer.tsx +126 -0
  60. package/assets/components/Drawer/index.ts +7 -0
  61. package/assets/components/EmptyState/EmptyState.module.css +102 -0
  62. package/assets/components/EmptyState/EmptyState.tsx +80 -0
  63. package/assets/components/EmptyState/index.ts +2 -0
  64. package/assets/components/FileIcon/FileIcon.module.css +66 -0
  65. package/assets/components/FileIcon/FileIcon.tsx +84 -0
  66. package/assets/components/FileIcon/fileExtMap.ts +112 -0
  67. package/assets/components/FileIcon/index.ts +9 -0
  68. package/assets/components/FilterButton/FilterButton.module.css +130 -0
  69. package/assets/components/FilterButton/FilterButton.tsx +94 -0
  70. package/assets/components/FilterButton/index.ts +2 -0
  71. package/assets/components/GalleryItem/GalleryItem.module.css +220 -0
  72. package/assets/components/GalleryItem/GalleryItem.tsx +163 -0
  73. package/assets/components/GalleryItem/index.ts +7 -0
  74. package/assets/components/Icon/Icon.tsx +616 -0
  75. package/assets/components/Icon/context.tsx +39 -0
  76. package/assets/components/Icon/index.ts +4 -0
  77. package/assets/components/IconButton/IconButton.module.css +109 -0
  78. package/assets/components/IconButton/IconButton.tsx +110 -0
  79. package/assets/components/IconButton/index.ts +2 -0
  80. package/assets/components/Input/Input.module.css +338 -0
  81. package/assets/components/Input/Input.tsx +371 -0
  82. package/assets/components/Input/index.ts +2 -0
  83. package/assets/components/ListItem/ListItem.module.css +318 -0
  84. package/assets/components/ListItem/ListItem.tsx +262 -0
  85. package/assets/components/ListItem/index.ts +9 -0
  86. package/assets/components/MenuItem/MenuItem.module.css +437 -0
  87. package/assets/components/MenuItem/MenuItem.tsx +529 -0
  88. package/assets/components/MenuItem/index.ts +8 -0
  89. package/assets/components/MetricCard/MetricCard.module.css +153 -0
  90. package/assets/components/MetricCard/MetricCard.tsx +140 -0
  91. package/assets/components/MetricCard/index.ts +2 -0
  92. package/assets/components/Modal/Modal.module.css +175 -0
  93. package/assets/components/Modal/Modal.tsx +98 -0
  94. package/assets/components/Modal/index.ts +2 -0
  95. package/assets/components/Onboarding/DocsIndex.tsx +82 -0
  96. package/assets/components/Onboarding/LayoutBuilder.tsx +160 -0
  97. package/assets/components/Onboarding/Onboarding.module.css +1394 -0
  98. package/assets/components/Onboarding/OnboardingAxisPanel.tsx +515 -0
  99. package/assets/components/Onboarding/OnboardingPage.tsx +1193 -0
  100. package/assets/components/Onboarding/PresetsGallery.tsx +65 -0
  101. package/assets/components/Onboarding/actions.ts +250 -0
  102. package/assets/components/Onboarding/index.ts +8 -0
  103. package/assets/components/Onboarding/palette.css +40 -0
  104. package/assets/components/Onboarding/wizardData.ts +265 -0
  105. package/assets/components/Pagination/Pagination.module.css +82 -0
  106. package/assets/components/Pagination/Pagination.tsx +248 -0
  107. package/assets/components/Pagination/index.ts +6 -0
  108. package/assets/components/ProgressBar/ProgressBar.module.css +64 -0
  109. package/assets/components/ProgressBar/ProgressBar.tsx +54 -0
  110. package/assets/components/ProgressBar/index.ts +2 -0
  111. package/assets/components/QuotationBar/QuotationBar.module.css +61 -0
  112. package/assets/components/QuotationBar/QuotationBar.tsx +48 -0
  113. package/assets/components/QuotationBar/index.ts +2 -0
  114. package/assets/components/Radio/Radio.module.css +63 -0
  115. package/assets/components/Radio/Radio.tsx +33 -0
  116. package/assets/components/Radio/index.ts +2 -0
  117. package/assets/components/Select/Select.module.css +151 -0
  118. package/assets/components/Select/Select.tsx +425 -0
  119. package/assets/components/Select/index.ts +10 -0
  120. package/assets/components/SelectableCard/SelectableCard.module.css +177 -0
  121. package/assets/components/SelectableCard/SelectableCard.tsx +83 -0
  122. package/assets/components/SelectableCard/index.ts +2 -0
  123. package/assets/components/Shortcut/Shortcut.module.css +56 -0
  124. package/assets/components/Shortcut/Shortcut.tsx +156 -0
  125. package/assets/components/Shortcut/index.ts +2 -0
  126. package/assets/components/Sidebar/Sidebar.module.css +242 -0
  127. package/assets/components/Sidebar/Sidebar.tsx +264 -0
  128. package/assets/components/Sidebar/index.ts +7 -0
  129. package/assets/components/SidebarSplit/SidebarSplit.module.css +126 -0
  130. package/assets/components/SidebarSplit/SidebarSplit.tsx +222 -0
  131. package/assets/components/SidebarSplit/index.ts +6 -0
  132. package/assets/components/Slider/Slider.module.css +120 -0
  133. package/assets/components/Slider/Slider.tsx +88 -0
  134. package/assets/components/Slider/index.ts +2 -0
  135. package/assets/components/SplitButton/SplitButton.module.css +190 -0
  136. package/assets/components/SplitButton/SplitButton.tsx +145 -0
  137. package/assets/components/SplitButton/index.ts +6 -0
  138. package/assets/components/Stepper/Stepper.module.css +182 -0
  139. package/assets/components/Stepper/Stepper.tsx +185 -0
  140. package/assets/components/Stepper/index.ts +2 -0
  141. package/assets/components/Switch/Switch.module.css +116 -0
  142. package/assets/components/Switch/Switch.tsx +58 -0
  143. package/assets/components/Switch/index.ts +2 -0
  144. package/assets/components/TableCell/TableCell.module.css +137 -0
  145. package/assets/components/TableCell/TableCellAvatar.tsx +42 -0
  146. package/assets/components/TableCell/TableCellBadge.tsx +23 -0
  147. package/assets/components/TableCell/TableCellIcon.tsx +39 -0
  148. package/assets/components/TableCell/TableCellImage.tsx +49 -0
  149. package/assets/components/TableCell/TableCellLink.tsx +33 -0
  150. package/assets/components/TableCell/TableCellMeter.tsx +55 -0
  151. package/assets/components/TableCell/TableCellNumber.tsx +43 -0
  152. package/assets/components/TableCell/TableCellText.tsx +30 -0
  153. package/assets/components/TableCell/index.ts +23 -0
  154. package/assets/components/TableHeader/TableHeader.module.css +287 -0
  155. package/assets/components/TableHeader/TableHeader.tsx +590 -0
  156. package/assets/components/TableHeader/index.ts +9 -0
  157. package/assets/components/TableRow/TableRow.module.css +290 -0
  158. package/assets/components/TableRow/TableRow.tsx +253 -0
  159. package/assets/components/TableRow/index.ts +8 -0
  160. package/assets/components/TableRowEdit/TableRowEdit.module.css +126 -0
  161. package/assets/components/TableRowEdit/TableRowEdit.tsx +247 -0
  162. package/assets/components/TableRowEdit/index.ts +2 -0
  163. package/assets/components/TableRowSelect/TableRowSelect.module.css +23 -0
  164. package/assets/components/TableRowSelect/TableRowSelect.tsx +175 -0
  165. package/assets/components/TableRowSelect/index.ts +2 -0
  166. package/assets/components/Tabs/Tabs.module.css +234 -0
  167. package/assets/components/Tabs/Tabs.tsx +426 -0
  168. package/assets/components/Tabs/index.ts +9 -0
  169. package/assets/components/Textarea/Textarea.module.css +318 -0
  170. package/assets/components/Textarea/Textarea.tsx +426 -0
  171. package/assets/components/Textarea/index.ts +7 -0
  172. package/assets/components/ThemeController.tsx +271 -0
  173. package/assets/components/TimePicker/TimePicker.module.css +317 -0
  174. package/assets/components/TimePicker/TimePicker.tsx +821 -0
  175. package/assets/components/TimePicker/index.ts +8 -0
  176. package/assets/components/TimePicker/utils.ts +115 -0
  177. package/assets/components/Toast/Toast.module.css +264 -0
  178. package/assets/components/Toast/Toast.tsx +243 -0
  179. package/assets/components/Toast/index.ts +15 -0
  180. package/assets/components/Toolbar/Toolbar.module.css +72 -0
  181. package/assets/components/Toolbar/Toolbar.tsx +75 -0
  182. package/assets/components/Toolbar/index.ts +2 -0
  183. package/assets/components/Tooltip/Tooltip.module.css +42 -0
  184. package/assets/components/Tooltip/Tooltip.tsx +332 -0
  185. package/assets/components/Tooltip/index.ts +2 -0
  186. package/assets/components/Topbar/Topbar.module.css +26 -0
  187. package/assets/components/Topbar/Topbar.tsx +47 -0
  188. package/assets/components/Topbar/index.ts +2 -0
  189. package/assets/components/_cn.ts +3 -0
  190. package/assets/components/_color.ts +48 -0
  191. package/assets/components/_data.ts +659 -0
  192. package/assets/components/_utils.css +19 -0
  193. package/assets/components/axisOptions.ts +24 -0
  194. package/assets/components/tokens.css +742 -0
  195. package/assets/prompts/GUIDE.md +251 -0
  196. package/assets/prompts/OVERRIDE.md +170 -0
  197. package/assets/prompts/PRINCIPLES.md +130 -0
  198. package/assets/prompts/axes/density.md +38 -0
  199. package/assets/prompts/axes/font.md +36 -0
  200. package/assets/prompts/axes/hue.md +36 -0
  201. package/assets/prompts/axes/icon.md +48 -0
  202. package/assets/prompts/axes/mode.md +50 -0
  203. package/assets/prompts/axes/motion.md +77 -0
  204. package/assets/prompts/axes/palette.md +35 -0
  205. package/assets/prompts/axes/shape.md +33 -0
  206. package/assets/prompts/axes/voice.md +54 -0
  207. package/assets/prompts/components/README.md +84 -0
  208. package/assets/prompts/components/app-frame.md +94 -0
  209. package/assets/prompts/components/attachment-chip.md +46 -0
  210. package/assets/prompts/components/attachment-thumb.md +49 -0
  211. package/assets/prompts/components/avatar.md +86 -0
  212. package/assets/prompts/components/badge.md +104 -0
  213. package/assets/prompts/components/breadcrumb.md +77 -0
  214. package/assets/prompts/components/button.md +99 -0
  215. package/assets/prompts/components/callout.md +81 -0
  216. package/assets/prompts/components/chat-input.md +84 -0
  217. package/assets/prompts/components/checkbox.md +46 -0
  218. package/assets/prompts/components/chip.md +84 -0
  219. package/assets/prompts/components/choice-card.md +127 -0
  220. package/assets/prompts/components/context-menu.md +145 -0
  221. package/assets/prompts/components/date-picker.md +104 -0
  222. package/assets/prompts/components/drawer.md +152 -0
  223. package/assets/prompts/components/empty-state.md +69 -0
  224. package/assets/prompts/components/file-icon.md +73 -0
  225. package/assets/prompts/components/filter-button.md +42 -0
  226. package/assets/prompts/components/form-field.md +74 -0
  227. package/assets/prompts/components/gallery-item.md +158 -0
  228. package/assets/prompts/components/icon-button.md +82 -0
  229. package/assets/prompts/components/icon.md +68 -0
  230. package/assets/prompts/components/input.md +95 -0
  231. package/assets/prompts/components/list-item.md +235 -0
  232. package/assets/prompts/components/menu-item.md +234 -0
  233. package/assets/prompts/components/metric-card.md +132 -0
  234. package/assets/prompts/components/modal.md +131 -0
  235. package/assets/prompts/components/pagination.md +92 -0
  236. package/assets/prompts/components/progress-bar.md +61 -0
  237. package/assets/prompts/components/quotation-bar.md +39 -0
  238. package/assets/prompts/components/radio.md +41 -0
  239. package/assets/prompts/components/select.md +104 -0
  240. package/assets/prompts/components/selectable-card.md +67 -0
  241. package/assets/prompts/components/shortcut.md +76 -0
  242. package/assets/prompts/components/sidebar.md +107 -0
  243. package/assets/prompts/components/slider.md +89 -0
  244. package/assets/prompts/components/split-button.md +71 -0
  245. package/assets/prompts/components/stepper.md +93 -0
  246. package/assets/prompts/components/switch.md +86 -0
  247. package/assets/prompts/components/table-cell.md +87 -0
  248. package/assets/prompts/components/table-header.md +157 -0
  249. package/assets/prompts/components/table-row-edit.md +129 -0
  250. package/assets/prompts/components/table-row-select.md +82 -0
  251. package/assets/prompts/components/table-row.md +156 -0
  252. package/assets/prompts/components/tabs.md +122 -0
  253. package/assets/prompts/components/textarea.md +105 -0
  254. package/assets/prompts/components/toast.md +149 -0
  255. package/assets/prompts/components/tooltip.md +71 -0
  256. package/assets/prompts/components/topbar.md +148 -0
  257. package/assets/prompts/primitives/emerge.md +43 -0
  258. package/assets/prompts/primitives/fade.md +31 -0
  259. package/assets/prompts/primitives/scale.md +32 -0
  260. package/assets/prompts/primitives/scroll.md +75 -0
  261. package/assets/prompts/primitives/slide.md +31 -0
  262. package/assets/prompts/themes/_SCHEMA.md +135 -0
  263. package/assets/prompts/themes/_TEMPLATE.md +73 -0
  264. package/assets/prompts/themes/expressive.md +118 -0
  265. package/assets/prompts/themes/pure.md +87 -0
  266. package/assets/prompts/themes/spare.md +73 -0
  267. package/assets/prompts/tokens/breakpoint.md +29 -0
  268. package/assets/prompts/tokens/color.md +78 -0
  269. package/assets/prompts/tokens/radius.md +33 -0
  270. package/assets/prompts/tokens/shadow.md +35 -0
  271. package/assets/prompts/tokens/spacing.md +86 -0
  272. package/assets/prompts/tokens/typography.md +76 -0
  273. package/assets/prompts/tokens/z-index.md +35 -0
  274. package/assets/public/expressive.png +0 -0
  275. package/assets/public/pure.png +0 -0
  276. package/assets/public/spare.png +0 -0
  277. package/assets/skill/SKILL.md +36 -0
  278. package/bin/ctds.js +76 -0
  279. package/package.json +35 -4
  280. package/src/commands/init.js +215 -0
  281. package/src/commands/update.js +275 -0
  282. package/src/utils/assets.js +78 -0
  283. package/src/utils/deps.js +51 -0
  284. package/src/utils/detect.js +47 -0
  285. package/src/utils/diff.js +52 -0
  286. package/src/utils/hash.js +16 -0
  287. package/src/utils/log.js +41 -0
  288. package/src/utils/meta.js +73 -0
  289. package/src/utils/prompt.js +28 -0
@@ -0,0 +1,1394 @@
1
+ /* Onboarding — wizard 위저드 레이아웃.
2
+ 좌: dark rail (스텝 리스트) / 우: 밝은 콘텐츠(질문·선택지·요약).
3
+ scroll two-layer padding rule: 스크롤 컨테이너에는 padding 없음, 안쪽 트랙에만 padding. */
4
+
5
+ .shell {
6
+ min-height: 100vh;
7
+ padding: var(--space-6);
8
+ /* Cloud Dancer #F0EEE9 — 온보딩 전용 고정 팔레트 (_components/onboardingPalette.css) */
9
+ background: var(--onb-bg);
10
+ color: var(--onb-fg);
11
+ display: grid;
12
+ grid-template-columns: calc(var(--space-24) * 4) 1fr;
13
+ gap: var(--space-8);
14
+ box-sizing: border-box;
15
+ align-items: start;
16
+ }
17
+
18
+ /* ── Rail (좌측 스텝 리스트) ──────────────────────────── */
19
+
20
+ .rail {
21
+ /* Flat 웜 차콜. 그라데이션 없음. */
22
+ background: var(--onb-rail);
23
+ color: var(--onb-rail-fg);
24
+ padding: var(--space-8);
25
+ display: flex;
26
+ flex-direction: column;
27
+ gap: var(--space-10);
28
+ overflow: hidden;
29
+ border-radius: var(--radius-2xl);
30
+ box-shadow: var(--shadow-lg);
31
+ min-width: 0;
32
+ box-sizing: border-box;
33
+ position: sticky;
34
+ top: var(--space-6);
35
+ /* viewport 높이 - shell padding 양쪽 */
36
+ height: calc(100vh - var(--space-6) * 2);
37
+ }
38
+
39
+ .railBrand {
40
+ display: inline-flex;
41
+ width: var(--space-10);
42
+ height: var(--space-10);
43
+ align-items: center;
44
+ justify-content: center;
45
+ border-radius: var(--radius-md);
46
+ background: var(--onb-rail-surface);
47
+ color: var(--onb-rail-fg);
48
+ flex-shrink: 0;
49
+ }
50
+
51
+ /* Rail의 스텝 리스트 — Stepper 컴포넌트에 온보딩 다크 팔레트 오버라이드 */
52
+ .railSteps {
53
+ flex: 1;
54
+ min-height: 0;
55
+ --stepper-fg: var(--onb-rail-fg);
56
+ --stepper-fg-muted: var(--onb-rail-fg-muted);
57
+ --stepper-fg-subtle: var(--onb-rail-fg-subtle);
58
+ --stepper-line: var(--onb-rail-line);
59
+ --stepper-dot-idle: var(--onb-rail-dot-idle);
60
+ --stepper-marker-fg: var(--onb-rail);
61
+ }
62
+
63
+ .railFoot {
64
+ display: flex;
65
+ justify-content: space-between;
66
+ align-items: center;
67
+ font-size: var(--text-xs);
68
+ color: var(--onb-rail-fg-subtle);
69
+ padding-top: var(--space-4);
70
+ flex-shrink: 0;
71
+ }
72
+ .railFootBtn {
73
+ appearance: none;
74
+ background: transparent;
75
+ border: none;
76
+ padding: 0;
77
+ color: inherit;
78
+ font-size: inherit;
79
+ cursor: pointer;
80
+ transition: var(--transition-colors);
81
+ display: inline-flex;
82
+ align-items: center;
83
+ gap: var(--space-1);
84
+ }
85
+ .railFootBtn:hover { color: var(--onb-rail-fg); }
86
+
87
+ /* ── Content (우측 질문·요약) ─────────────────────────── */
88
+
89
+ .content {
90
+ min-width: 0;
91
+ display: flex;
92
+ justify-content: center;
93
+ }
94
+ .contentInner {
95
+ padding: var(--space-16) var(--space-12) var(--space-8);
96
+ max-width: calc(var(--space-24) * 7);
97
+ display: flex;
98
+ flex-direction: column;
99
+ gap: var(--space-6);
100
+ width: 100%;
101
+ box-sizing: border-box;
102
+ }
103
+ .stepBody {
104
+ display: flex;
105
+ flex-direction: column;
106
+ gap: var(--space-3);
107
+ }
108
+
109
+ .stepHeader {
110
+ display: flex;
111
+ flex-direction: column;
112
+ gap: var(--space-1);
113
+ flex-shrink: 0;
114
+ align-items: flex-start;
115
+ }
116
+ .stepProgress {
117
+ font-size: var(--text-xs);
118
+ color: var(--fg-subtle);
119
+ font-family: var(--font-code);
120
+ letter-spacing: 0.04em;
121
+ margin-bottom: var(--space-1);
122
+ }
123
+ .stepTitle {
124
+ font-size: var(--text-2xl);
125
+ line-height: var(--lh-2xl);
126
+ letter-spacing: -0.025em;
127
+ color: var(--onb-fg);
128
+ font-weight: var(--font-weight-semibold);
129
+ }
130
+ .stepLead {
131
+ color: var(--onb-fg-muted);
132
+ font-size: var(--text-sm);
133
+ line-height: var(--lh-sm);
134
+ max-width: calc(var(--space-24) * 5);
135
+ }
136
+
137
+ /* ── Choice cards ─────────────────────────────────────── */
138
+
139
+ .choiceList {
140
+ display: grid;
141
+ gap: var(--space-2);
142
+ /* SelectableCard hover translateY(-1px) 여백 확보 — 부모 stepBody가 overflow:hidden이라
143
+ 최상단 카드가 hover 시 잘리지 않도록. */
144
+ padding-top: var(--space-1);
145
+ }
146
+
147
+ .choice {
148
+ appearance: none;
149
+ text-align: left;
150
+ background: var(--onb-card-bg);
151
+ border: var(--hairline) solid transparent;
152
+ border-radius: var(--radius-lg);
153
+ padding: var(--space-4) var(--space-5);
154
+ cursor: pointer;
155
+ transition: var(--transition-colors), box-shadow var(--duration-slow) var(--ease-out);
156
+ display: grid;
157
+ grid-template-columns: var(--space-5) 1fr auto;
158
+ gap: var(--space-4);
159
+ align-items: center;
160
+ color: var(--onb-fg);
161
+ box-shadow: var(--shadow-xs);
162
+ }
163
+ .choice:hover {
164
+ box-shadow: var(--shadow-sm);
165
+ }
166
+ .choice[data-active] {
167
+ border-color: var(--onb-rail);
168
+ box-shadow: var(--shadow-sm);
169
+ }
170
+
171
+ .choiceRadio {
172
+ width: var(--space-4);
173
+ height: var(--space-4);
174
+ border-radius: var(--radius-full);
175
+ border: var(--hairline) solid var(--onb-border-strong);
176
+ margin-top: var(--space-0_5);
177
+ display: inline-flex;
178
+ align-items: center;
179
+ justify-content: center;
180
+ flex-shrink: 0;
181
+ }
182
+ .choice[data-active] .choiceRadio {
183
+ border-color: var(--onb-rail);
184
+ border-width: calc(var(--hairline) * 2);
185
+ }
186
+ .choice[data-active] .choiceRadio::after {
187
+ content: "";
188
+ width: var(--space-2);
189
+ height: var(--space-2);
190
+ border-radius: var(--radius-full);
191
+ background: var(--onb-rail);
192
+ }
193
+
194
+ .choiceBody {
195
+ display: flex;
196
+ flex-direction: column;
197
+ gap: var(--space-1);
198
+ min-width: 0;
199
+ }
200
+ .choiceTitle {
201
+ font-size: var(--text-base);
202
+ font-weight: var(--font-weight-semibold);
203
+ color: var(--onb-fg);
204
+ }
205
+ .choiceHint {
206
+ font-size: var(--text-sm);
207
+ color: var(--onb-fg-muted);
208
+ line-height: var(--lh-sm);
209
+ }
210
+ .choiceExamples {
211
+ font-size: var(--text-xs);
212
+ color: var(--onb-fg-muted);
213
+ margin-top: var(--space-1);
214
+ }
215
+
216
+ .choiceThumb {
217
+ width: calc(var(--space-16) * 1);
218
+ height: calc(var(--space-8) * 1);
219
+ border-radius: var(--radius-sm);
220
+ border: var(--hairline) solid var(--border);
221
+ overflow: hidden;
222
+ flex-shrink: 0;
223
+ display: grid;
224
+ }
225
+
226
+ /* Vibe 프리뷰: 미니 UI 스와치.
227
+ Palette 색은 쓰지 않고 fg 톤만 사용해서 vibe 자체의 shape·motion·icon weight에만 집중. */
228
+ .vibePreview {
229
+ display: flex;
230
+ align-items: center;
231
+ justify-content: center;
232
+ gap: var(--space-1_5);
233
+ width: 100%;
234
+ height: 100%;
235
+ background: var(--bg);
236
+ padding: 0 var(--space-2);
237
+ }
238
+ .vibePreviewBtn {
239
+ display: inline-flex;
240
+ align-items: center;
241
+ justify-content: center;
242
+ width: var(--space-5);
243
+ height: var(--space-5);
244
+ color: var(--bg);
245
+ background: var(--fg-strong);
246
+ flex-shrink: 0;
247
+ }
248
+ .vibePreviewBtn[data-shape="crisp"] { border-radius: var(--radius-none); }
249
+ .vibePreviewBtn[data-shape="standard"] { border-radius: var(--radius-xs); }
250
+ .vibePreviewBtn[data-shape="soft"] { border-radius: var(--radius-full); }
251
+
252
+ .vibePreviewChip {
253
+ display: inline-block;
254
+ width: var(--space-5);
255
+ height: var(--space-2);
256
+ background: color-mix(in oklab, var(--fg) 18%, transparent);
257
+ flex-shrink: 0;
258
+ }
259
+ .vibePreviewChip[data-variant="ghost"] {
260
+ background: transparent;
261
+ border: var(--hairline) solid color-mix(in oklab, var(--fg) 22%, transparent);
262
+ }
263
+ .vibePreviewChip[data-shape="crisp"] { border-radius: var(--radius-none); }
264
+ .vibePreviewChip[data-shape="standard"] { border-radius: var(--radius-xs); }
265
+ .vibePreviewChip[data-shape="soft"] { border-radius: var(--radius-full); }
266
+
267
+ .choice[data-active] .vibePreviewBtn { background: var(--primary); }
268
+ .choice[data-active] .vibePreviewChip {
269
+ background: color-mix(in oklab, var(--primary) 55%, transparent);
270
+ }
271
+ .choice[data-active] .vibePreviewChip[data-variant="ghost"] {
272
+ background: transparent;
273
+ border-color: color-mix(in oklab, var(--primary) 55%, transparent);
274
+ }
275
+
276
+ .vibePreviewChip[data-motion="bouncy"] {
277
+ animation: vibeBounce calc(var(--duration-slower) * 5) var(--ease-emphasized) infinite;
278
+ }
279
+ .vibePreviewChip[data-motion="standard"] {
280
+ animation: vibePulse calc(var(--duration-slower) * 7) var(--ease-in-out) infinite;
281
+ }
282
+ .vibePreviewChip[data-motion="calm"] {
283
+ animation: vibeFade calc(var(--duration-slower) * 9) var(--ease-in-out) infinite;
284
+ }
285
+
286
+ @keyframes vibeBounce {
287
+ 0%, 100% { transform: translateY(0); }
288
+ 40% { transform: translateY(calc(var(--space-0_5) * -1)); }
289
+ 60% { transform: translateY(calc(var(--space-0_5) * 0.5)); }
290
+ }
291
+ @keyframes vibePulse {
292
+ 0%, 100% { opacity: 1; }
293
+ 50% { opacity: 0.6; }
294
+ }
295
+ @keyframes vibeFade {
296
+ 0%, 100% { opacity: 0.9; }
297
+ 50% { opacity: 0.65; }
298
+ }
299
+ @media (prefers-reduced-motion: reduce) {
300
+ .vibePreviewChip { animation: none; }
301
+ }
302
+
303
+ /* Layout mini thumbnails inside choice */
304
+ .thumb {
305
+ display: grid;
306
+ width: 100%;
307
+ height: 100%;
308
+ background: var(--bg-subtle);
309
+ }
310
+ .thumb[data-kind="sidebar-only"] {
311
+ grid-template-columns: 30% 1fr;
312
+ }
313
+ .thumb[data-kind="topbar-sidebar"] {
314
+ grid-template-rows: 20% 1fr;
315
+ grid-template-columns: 30% 1fr;
316
+ }
317
+ .thumb[data-kind="topbar-only"] {
318
+ grid-template-rows: 22% 1fr;
319
+ }
320
+ .thumb[data-kind="dual-sidebar"] {
321
+ grid-template-columns: 22% 1fr 22%;
322
+ }
323
+ .thumbCell {
324
+ border-right: var(--hairline) solid var(--border);
325
+ border-bottom: var(--hairline) solid var(--border);
326
+ }
327
+ .thumbCell:last-child { border-right: none; }
328
+ .thumbCell[data-role="rail"] { background: var(--fg-strong); }
329
+ .thumbCell[data-role="bar"] { background: color-mix(in oklab, var(--fg-strong) 8%, var(--bg)); }
330
+
331
+ /* ── Color step ───────────────────────────────────────── */
332
+
333
+ .colorStep {
334
+ display: flex;
335
+ flex-direction: column;
336
+ gap: var(--space-5);
337
+ min-height: 0;
338
+ }
339
+ .colorSection {
340
+ display: flex;
341
+ flex-direction: column;
342
+ gap: var(--space-2);
343
+ }
344
+ .colorSectionTitle {
345
+ font-size: var(--text-sm);
346
+ font-weight: var(--font-weight-medium);
347
+ color: var(--fg-strong);
348
+ }
349
+ .colorSectionHead {
350
+ display: flex;
351
+ align-items: baseline;
352
+ gap: var(--space-3);
353
+ flex-wrap: wrap;
354
+ }
355
+ .colorSectionHint {
356
+ font-size: var(--text-xs);
357
+ color: var(--fg-muted);
358
+ }
359
+ .paletteRow {
360
+ display: flex;
361
+ flex-wrap: wrap;
362
+ gap: var(--space-2);
363
+ }
364
+ .hueSliderBlock {
365
+ display: grid;
366
+ grid-template-columns: auto 1fr auto;
367
+ gap: var(--space-3);
368
+ align-items: center;
369
+ transition: var(--transition-colors);
370
+ }
371
+ .hueSliderBlock[data-locked] > *:not(.hueSliderSwatch) {
372
+ opacity: 0.5;
373
+ pointer-events: none;
374
+ }
375
+ .hueSliderSwatch {
376
+ width: var(--space-8);
377
+ height: var(--space-8);
378
+ border-radius: var(--radius-full);
379
+ border: var(--hairline) solid var(--border);
380
+ }
381
+ .hueSliderValue {
382
+ font-family: var(--font-code);
383
+ font-size: var(--text-sm);
384
+ color: var(--fg-muted);
385
+ min-width: var(--space-10);
386
+ text-align: right;
387
+ }
388
+
389
+ .hexDisclosure {
390
+ display: flex;
391
+ flex-direction: column;
392
+ gap: var(--space-2);
393
+ margin-top: var(--space-2);
394
+ }
395
+ .hexToggle {
396
+ appearance: none;
397
+ background: transparent;
398
+ border: none;
399
+ padding: 0;
400
+ cursor: pointer;
401
+ display: inline-flex;
402
+ align-items: center;
403
+ gap: var(--space-1_5);
404
+ align-self: flex-start;
405
+ font-size: var(--text-xs);
406
+ color: var(--fg-muted);
407
+ transition: var(--transition-colors);
408
+ }
409
+ .hexToggle:hover { color: var(--fg); }
410
+ .hexOptionalTag {
411
+ font-size: var(--text-xs);
412
+ color: var(--fg-subtle);
413
+ padding: 0 var(--space-1_5);
414
+ border: var(--hairline) solid var(--border);
415
+ border-radius: var(--radius-xs);
416
+ }
417
+ .hexBlock {
418
+ display: flex;
419
+ flex-direction: column;
420
+ gap: var(--space-1_5);
421
+ padding-left: var(--space-5);
422
+ }
423
+ .hexBigSwatch {
424
+ width: var(--space-5);
425
+ height: var(--space-5);
426
+ border-radius: var(--radius-sm);
427
+ border: var(--hairline) solid var(--border);
428
+ }
429
+ .hexHelp {
430
+ font-size: var(--text-xs);
431
+ color: var(--fg-muted);
432
+ }
433
+
434
+ /* ── Footer nav (Back/Continue) ───────────────────────── */
435
+
436
+ .stepFoot {
437
+ display: flex;
438
+ flex-direction: column;
439
+ gap: var(--space-3);
440
+ padding-top: var(--space-6);
441
+ flex-shrink: 0;
442
+ }
443
+ .stepFootHint {
444
+ font-size: var(--text-xs);
445
+ color: var(--fg-subtle);
446
+ text-align: center;
447
+ }
448
+ .stepFootActions {
449
+ display: grid;
450
+ grid-template-columns: 1fr 1fr;
451
+ gap: var(--space-3);
452
+ }
453
+ .stepFootActions > * {
454
+ width: 100%;
455
+ height: calc(var(--control-h-lg) * 1.25);
456
+ }
457
+ /* Continue = rail과 같은 charcoal 톤 */
458
+ .stepFootActions > *:nth-child(2) {
459
+ background: var(--onb-rail);
460
+ border-color: transparent;
461
+ color: var(--onb-rail-fg);
462
+ }
463
+ .stepFootActions > *:nth-child(2):hover:not(:disabled) {
464
+ background: var(--onb-rail-deep);
465
+ }
466
+ /* Back = 담백한 웜 회색 fill */
467
+ .stepFootActions > *:nth-child(1) {
468
+ background: var(--onb-back-btn);
469
+ border-color: transparent;
470
+ color: var(--onb-fg);
471
+ }
472
+ .stepFootActions > *:nth-child(1):hover:not(:disabled) {
473
+ background: var(--onb-back-btn-hover);
474
+ }
475
+
476
+ /* ── Summary ──────────────────────────────────────────── */
477
+
478
+ /* 5개 항목 → 3열(2+3) 깔끔한 블록 그리드. 폭 좁아지면 2열 → 1열 */
479
+ .summaryGrid {
480
+ display: grid;
481
+ grid-template-columns: repeat(3, 1fr);
482
+ gap: var(--space-3);
483
+ }
484
+ @media (max-width: 900px) {
485
+ .summaryGrid { grid-template-columns: repeat(2, 1fr); }
486
+ }
487
+ @media (max-width: 560px) {
488
+ .summaryGrid { grid-template-columns: 1fr; }
489
+ }
490
+
491
+ .summaryCard {
492
+ background: var(--onb-card-bg);
493
+ border: var(--hairline) solid var(--onb-border);
494
+ border-radius: var(--radius-lg);
495
+ padding: var(--space-4);
496
+ display: flex;
497
+ flex-direction: column;
498
+ gap: var(--space-3);
499
+ box-shadow: var(--shadow-xs);
500
+ }
501
+ .summaryCardPreview {
502
+ height: calc(var(--space-16) * 1);
503
+ display: flex;
504
+ align-items: center;
505
+ justify-content: center;
506
+ background: var(--onb-bg);
507
+ border-radius: var(--radius-md);
508
+ padding: var(--space-3);
509
+ overflow: hidden;
510
+ }
511
+ .summaryCardText {
512
+ display: flex;
513
+ flex-direction: column;
514
+ gap: var(--space-0_5);
515
+ }
516
+ .summaryLabel {
517
+ font-size: var(--text-xs);
518
+ color: var(--onb-fg-muted);
519
+ }
520
+ .summaryValue {
521
+ font-size: var(--text-sm);
522
+ font-weight: var(--font-weight-medium);
523
+ color: var(--onb-fg);
524
+ line-height: var(--lh-sm);
525
+ }
526
+ /* ── Apply dialog ───────────────────────────────────────
527
+ 확인 → applying → done/error 플로우. Modal 자체는 "진짜 콘텐츠 카드"
528
+ 역할이라 bg + radius OK. 색 border·테두리 박스는 금지. */
529
+ .applyBackdrop {
530
+ position: fixed;
531
+ inset: 0;
532
+ background: color-mix(in oklab, var(--onb-rail) 55%, transparent);
533
+ display: flex;
534
+ align-items: center;
535
+ justify-content: center;
536
+ z-index: var(--z-modal);
537
+ padding: var(--space-6);
538
+ }
539
+ .applyModal {
540
+ background: var(--onb-card-bg);
541
+ color: var(--onb-fg);
542
+ border-radius: var(--radius-xl);
543
+ box-shadow: var(--shadow-xl);
544
+ padding: var(--space-8);
545
+ max-width: calc(var(--space-24) * 5);
546
+ width: 100%;
547
+ display: flex;
548
+ flex-direction: column;
549
+ gap: var(--space-4);
550
+ }
551
+ .applyTitle {
552
+ font-size: var(--text-xl);
553
+ font-weight: var(--font-weight-semibold);
554
+ color: var(--onb-fg);
555
+ line-height: var(--lh-xl);
556
+ margin: 0;
557
+ }
558
+ .applyLead {
559
+ font-size: var(--text-sm);
560
+ color: var(--onb-fg-muted);
561
+ line-height: var(--lh-sm);
562
+ margin: 0;
563
+ }
564
+ .applyFileList {
565
+ list-style: none;
566
+ padding: 0;
567
+ margin: 0;
568
+ display: flex;
569
+ flex-direction: column;
570
+ gap: var(--space-2);
571
+ }
572
+ .applyFileList li {
573
+ display: flex;
574
+ flex-direction: column;
575
+ gap: var(--space-0_5);
576
+ padding-left: var(--space-3);
577
+ border-left: var(--hairline) solid var(--onb-border-strong);
578
+ }
579
+ .applyFileList code {
580
+ font-size: var(--text-sm);
581
+ color: var(--onb-fg);
582
+ font-family: var(--font-code);
583
+ }
584
+ .applyFileHint {
585
+ font-size: var(--text-xs);
586
+ color: var(--onb-fg-muted);
587
+ }
588
+ .applyError {
589
+ font-size: var(--text-xs);
590
+ color: var(--onb-fg-muted);
591
+ font-family: var(--font-code);
592
+ background: color-mix(in oklab, var(--onb-fg) 5%, transparent);
593
+ border-radius: var(--radius-sm);
594
+ padding: var(--space-3);
595
+ margin: 0;
596
+ white-space: pre-wrap;
597
+ word-break: break-word;
598
+ }
599
+ .applyActions {
600
+ display: flex;
601
+ justify-content: flex-end;
602
+ gap: var(--space-2);
603
+ margin-top: var(--space-2);
604
+ }
605
+
606
+ /* 비권장 안내 — Callout 박스 금지. 그냥 muted 한 줄. */
607
+ .summaryHint {
608
+ font-size: var(--text-xs);
609
+ color: var(--onb-fg-muted);
610
+ line-height: var(--lh-sm);
611
+ padding-left: var(--space-1);
612
+ }
613
+
614
+ .summaryPreviewMuted {
615
+ font-size: var(--text-xs);
616
+ color: var(--onb-fg-muted);
617
+ font-family: var(--font-code);
618
+ letter-spacing: 0.04em;
619
+ }
620
+
621
+ /* 컬러 카드 — hue 3톤 스와치 */
622
+ .colorPreview {
623
+ display: inline-flex;
624
+ gap: var(--space-1);
625
+ align-items: center;
626
+ }
627
+ .colorPreviewSwatch {
628
+ width: var(--space-6);
629
+ height: var(--space-6);
630
+ border-radius: var(--radius-full);
631
+ border: var(--hairline) solid var(--onb-border);
632
+ }
633
+ .colorPreviewSwatch[data-tone="soft"],
634
+ .colorPreviewSwatch[data-tone="deep"] {
635
+ width: var(--space-5);
636
+ height: var(--space-5);
637
+ }
638
+
639
+ /* 레이아웃 카드 — 밀도와 같은 연한 wireframe 톤 */
640
+ .layoutPreview {
641
+ display: flex;
642
+ width: 100%;
643
+ height: 100%;
644
+ gap: var(--space-0_5);
645
+ }
646
+ .layoutPreviewRail {
647
+ width: var(--space-4);
648
+ flex-shrink: 0;
649
+ background: color-mix(in oklab, var(--onb-fg) 20%, transparent);
650
+ border-radius: var(--radius-xs);
651
+ }
652
+ .layoutPreviewMain {
653
+ flex: 1;
654
+ display: flex;
655
+ flex-direction: column;
656
+ gap: var(--space-0_5);
657
+ min-width: 0;
658
+ }
659
+ .layoutPreviewBar {
660
+ height: var(--space-2);
661
+ flex-shrink: 0;
662
+ background: color-mix(in oklab, var(--onb-fg) 20%, transparent);
663
+ border-radius: var(--radius-xs);
664
+ }
665
+ .layoutPreviewContent {
666
+ flex: 1;
667
+ background: color-mix(in oklab, var(--onb-fg) 8%, transparent);
668
+ border-radius: var(--radius-xs);
669
+ }
670
+
671
+ /* 밀도 카드 — row 4개로 간격 비주얼 */
672
+ .densityPreview {
673
+ display: flex;
674
+ flex-direction: column;
675
+ width: 100%;
676
+ height: 100%;
677
+ justify-content: center;
678
+ }
679
+ .densityPreview > span {
680
+ display: block;
681
+ background: color-mix(in oklab, var(--onb-fg) 20%, transparent);
682
+ border-radius: var(--radius-xs);
683
+ height: var(--space-1);
684
+ }
685
+ .densityPreview[data-density="compact"] > span { margin-bottom: var(--space-0_5); }
686
+ .densityPreview[data-density="compact"] > span:last-child { margin-bottom: 0; }
687
+ .densityPreview[data-density="default"] > span { margin-bottom: var(--space-1); }
688
+ .densityPreview[data-density="default"] > span:last-child { margin-bottom: 0; }
689
+ .densityPreview[data-density="comfortable"] > span { margin-bottom: var(--space-2); }
690
+ .densityPreview[data-density="comfortable"] > span:last-child { margin-bottom: 0; }
691
+
692
+ /* vibePreview가 summaryCard 안에 있을 때 — 투명 배경(이미 onb-bg 위) */
693
+ .vibePreview[data-summary] {
694
+ background: transparent;
695
+ padding: 0;
696
+ }
697
+
698
+
699
+ /* ── Summary 고급 설정 토글 (OnboardingAxisPanel 접힘) ── */
700
+
701
+ .summaryAdvanced {
702
+ display: flex;
703
+ flex-direction: column;
704
+ gap: var(--space-3);
705
+ }
706
+ /* 토글 — 섹션 헤더 톤. 테두리/배경 박스 금지. */
707
+ .summaryAdvancedToggle {
708
+ display: inline-flex;
709
+ align-items: center;
710
+ gap: var(--space-2);
711
+ padding: var(--space-2) 0;
712
+ background: transparent;
713
+ border: none;
714
+ color: var(--onb-fg);
715
+ font-size: var(--text-base);
716
+ font-weight: var(--font-weight-medium);
717
+ cursor: pointer;
718
+ align-self: flex-start;
719
+ transition: var(--transition-colors);
720
+ }
721
+ .summaryAdvancedToggle:hover { color: var(--onb-fg-muted); }
722
+
723
+ /* Body — 박스 아니고, 위쪽 hairline + 들여쓰기로만 영역 구분 */
724
+ .summaryAdvancedBody {
725
+ padding: var(--space-4) 0 0;
726
+ border-top: var(--hairline) solid var(--onb-border);
727
+ }
728
+
729
+ /* ── Axis panel — Summary 고급설정 전용 wide variant ─────
730
+ Free mode 사이드바(narrow)와 공유되는 OnboardingAxisPanel을
731
+ Summary 안쪽 넓은 폭(≈700px)에선 라벨-컨트롤 가로 2열로 재배치하고
732
+ 각 세그먼트에 미니 프리뷰를 얹는다. narrow(.axis* / .segment*)는 그대로 유지. */
733
+
734
+ .axisAdv {
735
+ display: flex;
736
+ flex-direction: column;
737
+ color: var(--onb-fg);
738
+ }
739
+ .axisAdvHead {
740
+ display: flex;
741
+ justify-content: flex-end;
742
+ padding-bottom: var(--space-2);
743
+ }
744
+ .axisAdvRow {
745
+ display: grid;
746
+ grid-template-columns: calc(var(--space-16) * 1) 1fr;
747
+ gap: var(--space-8);
748
+ align-items: start;
749
+ padding: var(--space-5) 0;
750
+ border-top: var(--hairline) solid var(--onb-border);
751
+ }
752
+ .axisAdvRow:first-of-type { border-top: none; padding-top: var(--space-2); }
753
+ .axisAdvLabel {
754
+ font-size: var(--text-sm);
755
+ color: var(--onb-fg);
756
+ font-weight: var(--font-weight-medium);
757
+ padding-top: var(--space-2);
758
+ line-height: var(--lh-sm);
759
+ display: flex;
760
+ flex-direction: column;
761
+ gap: var(--space-1);
762
+ align-items: flex-start;
763
+ }
764
+
765
+ /* 테마가 잠근 축 뱃지 — "Spare 결정" 같은 코드폰트 소형 라벨.
766
+ 왼쪽 hairline 하나로만 "묶음" 암시, 색/배경 박스 금지. */
767
+ .axisLockBadge {
768
+ font-size: var(--text-xs);
769
+ color: var(--onb-fg-muted);
770
+ font-family: var(--font-code);
771
+ letter-spacing: 0.04em;
772
+ padding-left: var(--space-2);
773
+ border-left: var(--hairline) solid var(--onb-border-strong);
774
+ line-height: var(--lh-xs);
775
+ }
776
+ .axisAdvControl {
777
+ min-width: 0;
778
+ }
779
+
780
+ /* 세그먼트 wide — iOS 스타일. 그룹 전체에 track bg를 깔고,
781
+ 활성 아이템은 "track 위에 올라앉은 흰 카드"로 올라옴.
782
+ 비활성 영역이 보여서 "이게 선택지 세트"로 읽히게. */
783
+ .segmentWide {
784
+ display: grid;
785
+ grid-auto-flow: column;
786
+ grid-auto-columns: minmax(0, 1fr);
787
+ gap: var(--space-0_5);
788
+ width: 100%;
789
+ padding: var(--space-1);
790
+ background: color-mix(in oklab, var(--onb-fg) 5%, transparent);
791
+ border-radius: var(--radius-md);
792
+ }
793
+ .segmentWideItem {
794
+ appearance: none;
795
+ background: transparent;
796
+ border: var(--hairline) solid transparent;
797
+ border-radius: var(--radius-sm);
798
+ padding: var(--space-2);
799
+ cursor: pointer;
800
+ display: flex;
801
+ flex-direction: column;
802
+ align-items: center;
803
+ justify-content: flex-start;
804
+ gap: var(--space-1_5);
805
+ color: var(--onb-fg-muted);
806
+ transition: var(--transition-colors);
807
+ min-width: 0;
808
+ }
809
+ .segmentWideItem:hover {
810
+ color: var(--onb-fg);
811
+ }
812
+ .segmentWideItem[data-active] {
813
+ background: var(--onb-card-bg);
814
+ color: var(--onb-fg);
815
+ box-shadow: var(--shadow-xs);
816
+ }
817
+ /* 테마가 잠근 축 — 비활성 선택지는 흐려지고 클릭 불가 */
818
+ .segmentWideItem[data-disabled] {
819
+ opacity: 0.35;
820
+ cursor: not-allowed;
821
+ }
822
+ .segmentWideItem[data-disabled]:hover {
823
+ background: transparent;
824
+ color: var(--onb-fg-muted);
825
+ }
826
+ .segmentWidePreview {
827
+ display: inline-flex;
828
+ align-items: center;
829
+ justify-content: center;
830
+ width: var(--space-10);
831
+ height: var(--space-8);
832
+ flex-shrink: 0;
833
+ }
834
+ .segmentWideLabel {
835
+ font-size: var(--text-xs);
836
+ color: inherit;
837
+ letter-spacing: 0.01em;
838
+ text-align: center;
839
+ max-width: 100%;
840
+ overflow: hidden;
841
+ text-overflow: ellipsis;
842
+ white-space: nowrap;
843
+ }
844
+ .segmentWideSublabel {
845
+ font-size: var(--text-xs);
846
+ color: var(--onb-fg-muted);
847
+ font-family: var(--font-code);
848
+ letter-spacing: 0.04em;
849
+ opacity: 0.7;
850
+ }
851
+ .segmentWideItem[data-active] .segmentWideSublabel { opacity: 1; }
852
+
853
+ /* Hue 블록 wide — 세그먼트와 동일한 track 리듬 */
854
+ .axisAdvHue {
855
+ display: flex;
856
+ flex-direction: column;
857
+ gap: var(--space-3);
858
+ }
859
+ .axisAdvHue .huePresets {
860
+ gap: var(--space-0_5);
861
+ padding: var(--space-1);
862
+ background: color-mix(in oklab, var(--onb-fg) 5%, transparent);
863
+ border-radius: var(--radius-md);
864
+ }
865
+ .axisAdvHue .hueChip {
866
+ background: transparent;
867
+ border-color: transparent;
868
+ border-radius: var(--radius-sm);
869
+ }
870
+ .axisAdvHue .hueChip:hover {
871
+ background: transparent;
872
+ border-color: transparent;
873
+ }
874
+ .axisAdvHue .hueChip[data-active] {
875
+ background: var(--onb-card-bg);
876
+ border-color: transparent;
877
+ box-shadow: var(--shadow-xs);
878
+ }
879
+ .axisAdvCheck {
880
+ display: inline-flex;
881
+ align-items: center;
882
+ gap: var(--space-2);
883
+ font-size: var(--text-xs);
884
+ color: var(--onb-fg-muted);
885
+ cursor: pointer;
886
+ margin-top: var(--space-1);
887
+ }
888
+
889
+ /* ── Preview atoms ───────────────────────────────────── */
890
+
891
+ /* Mode — 반-반 원형. light/dark 한 눈에 */
892
+ .modeSwatch {
893
+ width: var(--space-6);
894
+ height: var(--space-6);
895
+ border-radius: var(--radius-full);
896
+ border: var(--hairline) solid var(--onb-border-strong);
897
+ display: inline-block;
898
+ position: relative;
899
+ overflow: hidden;
900
+ }
901
+ .modeSwatch[data-mode="light"] { background: var(--onb-mode-light); }
902
+ .modeSwatch[data-mode="dark"] { background: var(--onb-mode-dark); }
903
+
904
+ .paletteSwatch {
905
+ width: var(--space-6);
906
+ height: var(--space-6);
907
+ border-radius: var(--radius-full);
908
+ display: inline-block;
909
+ }
910
+
911
+ .accentPreview {
912
+ display: inline-flex;
913
+ gap: var(--space-1);
914
+ align-items: center;
915
+ }
916
+ .accentDot {
917
+ width: var(--space-2);
918
+ height: var(--space-2);
919
+ border-radius: var(--radius-full);
920
+ }
921
+
922
+ /* Shape — 색 톤 다운, 활성 시 또렷 */
923
+ .shapePreview {
924
+ display: inline-block;
925
+ width: var(--space-6);
926
+ height: var(--space-6);
927
+ background: color-mix(in oklab, var(--onb-fg) 35%, transparent);
928
+ transition: var(--transition-colors);
929
+ }
930
+ .segmentWideItem[data-active] .shapePreview {
931
+ background: var(--onb-fg);
932
+ }
933
+ .shapePreview[data-shape="crisp"] { border-radius: var(--radius-none); }
934
+ .shapePreview[data-shape="standard"] { border-radius: var(--radius-xs); }
935
+ .shapePreview[data-shape="soft"] { border-radius: var(--radius-full); }
936
+
937
+ /* Density — bar 두께·여백 미세 조정 */
938
+ .densityMini {
939
+ display: inline-flex;
940
+ flex-direction: column;
941
+ justify-content: center;
942
+ width: var(--space-8);
943
+ height: var(--space-6);
944
+ }
945
+ .densityMini > span {
946
+ display: block;
947
+ background: color-mix(in oklab, var(--onb-fg) 30%, transparent);
948
+ border-radius: var(--radius-xs);
949
+ height: var(--space-0_5);
950
+ }
951
+ .segmentWideItem[data-active] .densityMini > span {
952
+ background: color-mix(in oklab, var(--onb-fg) 60%, transparent);
953
+ }
954
+ .densityMini[data-density="compact"] > span { margin-bottom: var(--space-1); }
955
+ .densityMini[data-density="default"] > span { margin-bottom: var(--space-1_5); }
956
+ .densityMini[data-density="comfortable"] > span { margin-bottom: var(--space-2); }
957
+ .densityMini > span:last-child { margin-bottom: 0; }
958
+
959
+ .motionPreview {
960
+ display: inline-flex;
961
+ align-items: center;
962
+ justify-content: flex-start;
963
+ width: var(--space-10);
964
+ height: var(--space-6);
965
+ padding-left: var(--space-1);
966
+ }
967
+ .motionDot {
968
+ display: inline-block;
969
+ width: var(--space-2_5);
970
+ height: var(--space-2_5);
971
+ border-radius: var(--radius-full);
972
+ background: var(--onb-fg);
973
+ }
974
+ .motionDot[data-motion="bouncy"] {
975
+ animation: axisAdvBounce calc(var(--duration-slower) * 4) var(--ease-emphasized) infinite;
976
+ }
977
+ .motionDot[data-motion="standard"] {
978
+ animation: axisAdvSlide calc(var(--duration-slower) * 5) var(--ease-in-out) infinite;
979
+ }
980
+ .motionDot[data-motion="calm"] {
981
+ animation: axisAdvFade calc(var(--duration-slower) * 7) var(--ease-in-out) infinite;
982
+ }
983
+ .motionDot[data-motion="none"] {
984
+ opacity: 0.4;
985
+ }
986
+ @keyframes axisAdvBounce {
987
+ 0%, 100% { transform: translateX(0); }
988
+ 50% { transform: translateX(var(--space-5)); }
989
+ }
990
+ @keyframes axisAdvSlide {
991
+ 0%, 100% { transform: translateX(0); }
992
+ 50% { transform: translateX(var(--space-5)); }
993
+ }
994
+ @keyframes axisAdvFade {
995
+ 0%, 100% { opacity: 1; transform: translateX(0); }
996
+ 50% { opacity: 0.5; transform: translateX(var(--space-5)); }
997
+ }
998
+ @media (prefers-reduced-motion: reduce) {
999
+ .motionDot { animation: none; }
1000
+ }
1001
+
1002
+ .iconFamilyPreview {
1003
+ display: inline-flex;
1004
+ align-items: center;
1005
+ justify-content: center;
1006
+ color: var(--onb-fg-muted);
1007
+ }
1008
+ .segmentWideItem[data-active] .iconFamilyPreview { color: var(--onb-fg); }
1009
+
1010
+ /* Icon family/weight 미리보기 — 트리오로 family 특색 체감. preview 박스 밖으로 overflow 허용. */
1011
+ .iconTrio {
1012
+ display: inline-flex;
1013
+ align-items: center;
1014
+ gap: var(--space-1);
1015
+ color: var(--onb-fg-muted);
1016
+ transition: var(--transition-colors);
1017
+ white-space: nowrap;
1018
+ }
1019
+ .segmentWideItem[data-active] .iconTrio { color: var(--onb-fg); }
1020
+ /* 아이콘 트리오를 담은 preview 박스는 더 넓게 */
1021
+ .segmentWidePreview:has(.iconTrio) {
1022
+ width: auto;
1023
+ }
1024
+
1025
+ /* Focus ring — 미니 버튼에 ring on/off */
1026
+ .focusRingPreview {
1027
+ display: inline-flex;
1028
+ align-items: center;
1029
+ justify-content: center;
1030
+ width: var(--space-10);
1031
+ height: var(--space-8);
1032
+ }
1033
+ .focusRingButton {
1034
+ display: inline-block;
1035
+ width: var(--space-6);
1036
+ height: var(--space-4);
1037
+ border-radius: var(--radius-sm);
1038
+ background: var(--onb-fg);
1039
+ }
1040
+ .focusRingButton[data-on] {
1041
+ box-shadow:
1042
+ 0 0 0 calc(var(--hairline) * 1) var(--onb-bg),
1043
+ 0 0 0 calc(var(--hairline) * 3) color-mix(in oklab, var(--onb-rail) 60%, transparent);
1044
+ }
1045
+
1046
+ /* Voice — 세로 스택 샘플 문구. 세그먼트가 아닌 "카드 리스트" 톤으로.
1047
+ 같은 상황을 세 톤으로 보여줘서 체감이 바로 와닿게. */
1048
+ .voiceGroup {
1049
+ display: flex;
1050
+ flex-direction: column;
1051
+ gap: var(--space-0_5);
1052
+ width: 100%;
1053
+ padding: var(--space-1);
1054
+ background: color-mix(in oklab, var(--onb-fg) 5%, transparent);
1055
+ border-radius: var(--radius-md);
1056
+ }
1057
+ .voiceItem {
1058
+ appearance: none;
1059
+ background: transparent;
1060
+ border: none;
1061
+ border-radius: var(--radius-sm);
1062
+ padding: var(--space-2) var(--space-3);
1063
+ cursor: pointer;
1064
+ display: flex;
1065
+ align-items: baseline;
1066
+ gap: var(--space-3);
1067
+ text-align: left;
1068
+ transition: var(--transition-colors);
1069
+ }
1070
+ .voiceItem:hover .voiceSample {
1071
+ color: var(--onb-fg);
1072
+ }
1073
+ .voiceItem[data-active] {
1074
+ background: var(--onb-card-bg);
1075
+ }
1076
+ .voiceItem[data-active] .voiceSample {
1077
+ color: var(--onb-fg);
1078
+ }
1079
+ .voiceItem[data-active] .voiceCode {
1080
+ color: var(--onb-fg);
1081
+ }
1082
+ .voiceSample {
1083
+ font-size: var(--text-sm);
1084
+ color: var(--onb-fg-muted);
1085
+ flex: 1;
1086
+ min-width: 0;
1087
+ transition: var(--transition-colors);
1088
+ }
1089
+ .voiceCode {
1090
+ font-size: var(--text-xs);
1091
+ color: var(--onb-fg-muted);
1092
+ font-family: var(--font-code);
1093
+ letter-spacing: 0.04em;
1094
+ flex-shrink: 0;
1095
+ }
1096
+
1097
+ /* ── Free mode ─────────────────────────────────────────── */
1098
+
1099
+ .freeShell {
1100
+ min-height: 100vh;
1101
+ background: var(--bg);
1102
+ color: var(--fg);
1103
+ display: grid;
1104
+ grid-template-columns: calc(var(--space-24) * 3.4) 1fr;
1105
+ }
1106
+ .freeAxis {
1107
+ position: sticky;
1108
+ top: 0;
1109
+ align-self: start;
1110
+ height: 100vh;
1111
+ overflow: hidden;
1112
+ border-right: var(--hairline) solid var(--border);
1113
+ background: var(--bg-subtle);
1114
+ display: flex;
1115
+ flex-direction: column;
1116
+ }
1117
+ .freeAxisScroll {
1118
+ flex: 1;
1119
+ overflow-y: auto;
1120
+ min-height: 0;
1121
+ }
1122
+ .freeAxisInner {
1123
+ padding: var(--space-5) var(--space-5) var(--space-16);
1124
+ display: flex;
1125
+ flex-direction: column;
1126
+ gap: var(--space-4);
1127
+ }
1128
+ .freeContent {
1129
+ overflow-y: auto;
1130
+ min-height: 0;
1131
+ max-height: 100vh;
1132
+ }
1133
+ .freeContentInner {
1134
+ padding: var(--space-8) var(--space-8) var(--space-24);
1135
+ max-width: var(--content-max);
1136
+ margin: 0 auto;
1137
+ display: flex;
1138
+ flex-direction: column;
1139
+ gap: var(--space-6);
1140
+ }
1141
+ .freeHeader {
1142
+ display: flex;
1143
+ justify-content: space-between;
1144
+ align-items: flex-start;
1145
+ gap: var(--space-4);
1146
+ }
1147
+ .freeTitle {
1148
+ font-size: var(--text-2xl);
1149
+ line-height: var(--lh-2xl);
1150
+ color: var(--fg-strong);
1151
+ letter-spacing: -0.02em;
1152
+ }
1153
+ .freeLead {
1154
+ color: var(--fg-muted);
1155
+ font-size: var(--text-sm);
1156
+ margin-top: var(--space-1);
1157
+ }
1158
+
1159
+ /* 축 컨트롤러 내부 (기존과 동일) */
1160
+ .axisRailHead {
1161
+ display: flex;
1162
+ align-items: center;
1163
+ justify-content: space-between;
1164
+ gap: var(--space-3);
1165
+ padding-bottom: var(--space-2);
1166
+ border-bottom: var(--hairline) solid var(--border);
1167
+ }
1168
+ .axisRailTitle {
1169
+ font-size: var(--text-sm);
1170
+ font-weight: var(--font-weight-semibold);
1171
+ color: var(--fg);
1172
+ }
1173
+ .axisRailReset {
1174
+ appearance: none;
1175
+ background: transparent;
1176
+ border: none;
1177
+ padding: 0;
1178
+ color: var(--fg-muted);
1179
+ font-size: var(--text-xs);
1180
+ cursor: pointer;
1181
+ transition: var(--transition-colors);
1182
+ }
1183
+ .axisRailReset:hover { color: var(--fg); }
1184
+ .axisRow { display: flex; flex-direction: column; gap: var(--space-1_5); }
1185
+ .axisLabel { font-size: var(--text-xs); color: var(--fg-muted); }
1186
+ .segment {
1187
+ display: flex;
1188
+ gap: var(--space-0_5);
1189
+ background: var(--bg-muted);
1190
+ border-radius: var(--radius-sm);
1191
+ padding: var(--space-0_5);
1192
+ }
1193
+ .segmentItem {
1194
+ flex: 1;
1195
+ appearance: none;
1196
+ background: transparent;
1197
+ border: none;
1198
+ padding: var(--space-1) var(--space-2);
1199
+ border-radius: var(--radius-xs);
1200
+ font-size: var(--text-xs);
1201
+ color: var(--fg-muted);
1202
+ cursor: pointer;
1203
+ transition: var(--transition-colors);
1204
+ }
1205
+ .segmentItem:hover { color: var(--fg); }
1206
+ .segmentItem[data-active] {
1207
+ background: var(--bg);
1208
+ color: var(--fg);
1209
+ box-shadow: var(--shadow-xs);
1210
+ }
1211
+ .hueBox { display: flex; flex-direction: column; gap: var(--space-2); }
1212
+ .huePresets { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-1); }
1213
+ .hueChip {
1214
+ appearance: none;
1215
+ border: var(--hairline) solid var(--border);
1216
+ background: var(--bg);
1217
+ border-radius: var(--radius-sm);
1218
+ padding: var(--space-1);
1219
+ display: flex;
1220
+ align-items: center;
1221
+ gap: var(--space-1);
1222
+ cursor: pointer;
1223
+ transition: var(--transition-colors);
1224
+ min-width: 0;
1225
+ }
1226
+ .hueChip:hover { border-color: var(--border-strong); }
1227
+ .hueChip[data-active] { border-color: var(--primary); }
1228
+ .hueSwatch {
1229
+ width: var(--space-3);
1230
+ height: var(--space-3);
1231
+ border-radius: var(--radius-full);
1232
+ background: var(--primary);
1233
+ flex-shrink: 0;
1234
+ }
1235
+ .hueLabel {
1236
+ font-size: var(--text-xs);
1237
+ color: var(--fg-muted);
1238
+ overflow: hidden;
1239
+ text-overflow: ellipsis;
1240
+ white-space: nowrap;
1241
+ }
1242
+ .hueDial { display: flex; align-items: center; gap: var(--space-2); }
1243
+ .hueDial input[type="range"] { flex: 1; min-width: 0; }
1244
+ .hueValue {
1245
+ font-size: var(--text-xs);
1246
+ color: var(--fg-muted);
1247
+ min-width: var(--space-8);
1248
+ text-align: right;
1249
+ }
1250
+ .hexRow { display: flex; align-items: center; gap: var(--space-2); }
1251
+ .hexSwatch {
1252
+ width: var(--space-5);
1253
+ height: var(--space-5);
1254
+ border-radius: var(--radius-xs);
1255
+ border: var(--hairline) solid var(--border-strong);
1256
+ flex-shrink: 0;
1257
+ }
1258
+ .hexInput {
1259
+ flex: 1;
1260
+ min-width: 0;
1261
+ appearance: none;
1262
+ background: var(--bg);
1263
+ border: var(--hairline) solid var(--border);
1264
+ border-radius: var(--radius-xs);
1265
+ padding: var(--space-1) var(--space-2);
1266
+ font-family: var(--font-code);
1267
+ font-size: var(--text-xs);
1268
+ color: var(--fg);
1269
+ }
1270
+ .hexInput:focus { outline: none; border-color: var(--primary); }
1271
+ .iconRow { display: flex; flex-direction: column; gap: var(--space-1); }
1272
+
1273
+ @media (max-width: 900px) {
1274
+ .shell {
1275
+ grid-template-columns: 1fr;
1276
+ height: auto;
1277
+ min-height: 100vh;
1278
+ overflow: visible;
1279
+ }
1280
+ .rail { padding: var(--space-4); height: auto; }
1281
+ .contentInner { padding: var(--space-6); height: auto; }
1282
+ .stepBody { overflow: visible; }
1283
+ .freeShell { grid-template-columns: 1fr; }
1284
+ .freeAxis { position: static; height: auto; }
1285
+ }
1286
+
1287
+ /* ── Theme card title row — 영어 접두 뱃지 + 한국어 제목 ── */
1288
+
1289
+ .themeTitleRow {
1290
+ display: inline-flex;
1291
+ align-items: center;
1292
+ gap: var(--space-2);
1293
+ }
1294
+
1295
+ /* ── Theme hover preview — 커서 따라다니는 둥둥 뜬 이미지 ── */
1296
+
1297
+ .themeHoverLayer {
1298
+ position: fixed;
1299
+ top: 0;
1300
+ left: 0;
1301
+ pointer-events: none;
1302
+ z-index: var(--z-tooltip);
1303
+ width: calc(var(--space-24) * 4);
1304
+ height: calc(var(--space-24) * 2.667);
1305
+ padding: var(--space-1);
1306
+ border-radius: var(--radius-lg);
1307
+ overflow: hidden;
1308
+ box-shadow: var(--shadow-xl);
1309
+ background: var(--bg);
1310
+ border: var(--hairline) solid var(--border);
1311
+ opacity: 0;
1312
+ transform: translate(-9999px, -9999px);
1313
+ transition: opacity var(--duration-base) var(--ease-out);
1314
+ animation: themeHoverFloat var(--duration-slower) var(--ease-in-out) infinite alternate;
1315
+ }
1316
+ .themeHoverLayer[data-visible="true"] {
1317
+ opacity: 1;
1318
+ }
1319
+
1320
+ .themeHoverImg {
1321
+ width: 100%;
1322
+ height: 100%;
1323
+ object-fit: cover;
1324
+ display: block;
1325
+ border-radius: var(--radius-md);
1326
+ }
1327
+
1328
+ .themeHoverPlaceholder {
1329
+ width: 100%;
1330
+ height: 100%;
1331
+ display: flex;
1332
+ flex-direction: column;
1333
+ align-items: center;
1334
+ justify-content: center;
1335
+ gap: var(--space-1);
1336
+ background: var(--bg-subtle);
1337
+ }
1338
+ .themeHoverPlaceholderLabel {
1339
+ font-family: var(--font-code);
1340
+ font-size: var(--text-xs);
1341
+ letter-spacing: 0.08em;
1342
+ color: var(--fg-muted);
1343
+ }
1344
+ .themeHoverPlaceholderHint {
1345
+ font-size: var(--text-xs);
1346
+ color: var(--fg-muted);
1347
+ }
1348
+
1349
+ @keyframes themeHoverFloat {
1350
+ from { translate: 0 0; }
1351
+ to { translate: 0 calc(var(--space-1) * -1); }
1352
+ }
1353
+
1354
+ @media (prefers-reduced-motion: reduce) {
1355
+ .themeHoverLayer { animation: none; transition: none; }
1356
+ }
1357
+
1358
+ /* ── Layout wireframe (호버 미리보기 안쪽) ─────────────── */
1359
+
1360
+ .layoutWire {
1361
+ width: 100%;
1362
+ height: 100%;
1363
+ display: flex;
1364
+ gap: var(--space-2);
1365
+ padding: var(--space-3);
1366
+ background: var(--bg);
1367
+ border-radius: var(--radius-md);
1368
+ }
1369
+ .layoutWireSidebar {
1370
+ width: calc(var(--space-24) * 1);
1371
+ flex-shrink: 0;
1372
+ background: color-mix(in oklab, var(--primary) 80%, var(--fg) 20%);
1373
+ border-radius: var(--radius-sm);
1374
+ }
1375
+ .layoutWireMain {
1376
+ flex: 1;
1377
+ display: flex;
1378
+ flex-direction: column;
1379
+ gap: var(--space-2);
1380
+ min-width: 0;
1381
+ }
1382
+ .layoutWireTopbar {
1383
+ height: var(--space-6);
1384
+ flex-shrink: 0;
1385
+ background: color-mix(in oklab, var(--primary) 50%, var(--bg) 50%);
1386
+ border-radius: var(--radius-sm);
1387
+ }
1388
+ .layoutWireContent {
1389
+ flex: 1;
1390
+ background: var(--bg-subtle);
1391
+ border: var(--hairline) solid var(--border);
1392
+ border-radius: var(--radius-sm);
1393
+ }
1394
+