@yeongseoksong/framework 1.6.2 → 1.7.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/dist/ui/index.cjs DELETED
@@ -1,3136 +0,0 @@
1
- "use client";
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __defProps = Object.defineProperties;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
8
- var __getOwnPropNames = Object.getOwnPropertyNames;
9
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
10
- var __getProtoOf = Object.getPrototypeOf;
11
- var __hasOwnProp = Object.prototype.hasOwnProperty;
12
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
13
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
- var __spreadValues = (a, b) => {
15
- for (var prop in b || (b = {}))
16
- if (__hasOwnProp.call(b, prop))
17
- __defNormalProp(a, prop, b[prop]);
18
- if (__getOwnPropSymbols)
19
- for (var prop of __getOwnPropSymbols(b)) {
20
- if (__propIsEnum.call(b, prop))
21
- __defNormalProp(a, prop, b[prop]);
22
- }
23
- return a;
24
- };
25
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
- var __objRest = (source, exclude) => {
27
- var target = {};
28
- for (var prop in source)
29
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
30
- target[prop] = source[prop];
31
- if (source != null && __getOwnPropSymbols)
32
- for (var prop of __getOwnPropSymbols(source)) {
33
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
34
- target[prop] = source[prop];
35
- }
36
- return target;
37
- };
38
- var __export = (target, all) => {
39
- for (var name in all)
40
- __defProp(target, name, { get: all[name], enumerable: true });
41
- };
42
- var __copyProps = (to, from, except, desc) => {
43
- if (from && typeof from === "object" || typeof from === "function") {
44
- for (let key of __getOwnPropNames(from))
45
- if (!__hasOwnProp.call(to, key) && key !== except)
46
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
47
- }
48
- return to;
49
- };
50
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
51
- // If the importer is in node compatibility mode or this is not an ESM
52
- // file that has been converted to a CommonJS file using a Babel-
53
- // compatible transform (i.e. "__esModule" has not been set), then set
54
- // "default" to the CommonJS "module.exports" for node compatibility.
55
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
56
- mod
57
- ));
58
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
59
-
60
- // ui/index.tsx
61
- var ui_exports = {};
62
- __export(ui_exports, {
63
- HeroCarousel: () => HeroCarousel,
64
- Logo: () => Logo,
65
- MainLayout: () => MainLayout,
66
- NavProvider: () => NavProvider,
67
- PageLayout: () => PageLayout,
68
- PageLayoutBrand: () => PageLayoutBrand,
69
- PageLayoutImage: () => PageLayoutImage,
70
- PageLayoutMinimal: () => PageLayoutMinimal,
71
- PageLayoutPlain: () => PageLayoutPlain,
72
- SdBadge: () => SdBadge,
73
- SdBadgeDefault: () => SdBadgeDefault,
74
- SdBadgePrimary: () => SdBadgePrimary,
75
- SdBadgeSuccess: () => SdBadgeSuccess,
76
- SdBadgeWarning: () => SdBadgeWarning,
77
- SdBreadcrumb: () => SdBreadcrumb,
78
- SdButton: () => SdButton,
79
- SdButtonCancel: () => SdButtonCancel,
80
- SdButtonDelete: () => SdButtonDelete,
81
- SdButtonDownload: () => SdButtonDownload,
82
- SdButtonExcel: () => SdButtonExcel,
83
- SdButtonGhost: () => SdButtonGhost,
84
- SdButtonOutline: () => SdButtonOutline,
85
- SdButtonPrimary: () => SdButtonPrimary,
86
- SdButtonSecondary: () => SdButtonSecondary,
87
- SdButtonSubmit: () => SdButtonSubmit,
88
- SdButtonWhite: () => SdButtonWhite,
89
- SdClients: () => SdClients,
90
- SdClientsGrid: () => SdClientsGrid,
91
- SdClientsMarquee: () => SdClientsMarquee,
92
- SdContainer: () => SdContainer,
93
- SdCta: () => SdCta,
94
- SdCtaBanner: () => SdCtaBanner,
95
- SdCtaInline: () => SdCtaInline,
96
- SdCtaSubtle: () => SdCtaSubtle,
97
- SdErrorView: () => SdErrorView,
98
- SdErrorViewNotFound: () => SdErrorViewNotFound,
99
- SdErrorViewPage: () => SdErrorViewPage,
100
- SdFaq: () => SdFaq,
101
- SdFaqDefault: () => SdFaqDefault,
102
- SdFaqFilled: () => SdFaqFilled,
103
- SdFaqWithHeader: () => SdFaqWithHeader,
104
- SdFeatureSection: () => SdFeatureSection,
105
- SdFeatures: () => SdFeatures,
106
- SdFooter: () => SdFooter,
107
- SdHeader: () => SdHeader,
108
- SdHeaderMega: () => SdHeaderMega,
109
- SdHeaderPanel: () => SdHeaderPanel,
110
- SdHeaderSimple: () => SdHeaderSimple,
111
- SdInput: () => SdInput,
112
- SdInputAutocomplete: () => SdInputAutocomplete,
113
- SdInputCheckbox: () => SdInputCheckbox,
114
- SdInputColor: () => SdInputColor,
115
- SdInputDate: () => SdInputDate,
116
- SdInputDateRange: () => SdInputDateRange,
117
- SdInputEmail: () => SdInputEmail,
118
- SdInputFile: () => SdInputFile,
119
- SdInputJson: () => SdInputJson,
120
- SdInputMultiSelect: () => SdInputMultiSelect,
121
- SdInputNativeSelect: () => SdInputNativeSelect,
122
- SdInputNumber: () => SdInputNumber,
123
- SdInputPassword: () => SdInputPassword,
124
- SdInputPinCode: () => SdInputPinCode,
125
- SdInputRadioGroup: () => SdInputRadioGroup,
126
- SdInputRating: () => SdInputRating,
127
- SdInputSegmented: () => SdInputSegmented,
128
- SdInputSelect: () => SdInputSelect,
129
- SdInputSlider: () => SdInputSlider,
130
- SdInputSwitch: () => SdInputSwitch,
131
- SdInputTags: () => SdInputTags,
132
- SdInputText: () => SdInputText,
133
- SdInputTextarea: () => SdInputTextarea,
134
- SdInputTime: () => SdInputTime,
135
- SdLink: () => SdLink,
136
- SdLinkBody: () => SdLinkBody,
137
- SdLinkHint: () => SdLinkHint,
138
- SdLinkStrong: () => SdLinkStrong,
139
- SdLinkSub: () => SdLinkSub,
140
- SdLoginView: () => SdLoginView,
141
- SdLoginViewCard: () => SdLoginViewCard,
142
- SdLoginViewSplit: () => SdLoginViewSplit,
143
- SdMap: () => SdMap,
144
- SdMapSingle: () => SdMapSingle,
145
- SdMapTabs: () => SdMapTabs,
146
- SdModal: () => SdModal,
147
- SdNumberIcon: () => SdNumberIcon,
148
- SdPricingCard: () => SdPricingCard,
149
- SdPricingCardDefault: () => SdPricingCardDefault,
150
- SdPricingCardFeatured: () => SdPricingCardFeatured,
151
- SdPricingCardGrid: () => SdPricingCardGrid,
152
- SdProvider: () => SdProvider,
153
- SdQuote: () => SdQuote,
154
- SdQuoteCard: () => SdQuoteCard,
155
- SdQuotePlain: () => SdQuotePlain,
156
- SdResult: () => SdResult,
157
- SdResultError: () => SdResultError,
158
- SdResultSuccess: () => SdResultSuccess,
159
- SdSkeleton: () => SdSkeleton,
160
- SdSkeletonAvatar: () => SdSkeletonAvatar,
161
- SdSkeletonCard: () => SdSkeletonCard,
162
- SdSkeletonImage: () => SdSkeletonImage,
163
- SdSkeletonText: () => SdSkeletonText,
164
- SdSkeletonTitle: () => SdSkeletonTitle,
165
- SdSolution: () => SdSolution,
166
- SdSolutionCard: () => SdSolutionCard,
167
- SdSolutionCardGrid: () => SdSolutionCardGrid,
168
- SdSolutionCardItem: () => SdSolutionCardItem,
169
- SdSolutionFiltered: () => SdSolutionFiltered,
170
- SdSolutionList: () => SdSolutionList,
171
- SdSteps: () => SdSteps,
172
- SdStepsBubble: () => SdStepsBubble,
173
- SdStepsCard: () => SdStepsCard,
174
- SdStepsSection: () => SdStepsSection,
175
- SdStepsStrip: () => SdStepsStrip,
176
- SdTable: () => SdTable,
177
- SdTableSpec: () => SdTableSpec,
178
- SdTabs: () => SdTabs,
179
- SdTabsOutline: () => SdTabsOutline,
180
- SdTabsPills: () => SdTabsPills,
181
- SdTabsUnderline: () => SdTabsUnderline,
182
- SdTestimonial: () => SdTestimonial,
183
- SdTestimonialCard: () => SdTestimonialCard,
184
- SdTestimonialGrid: () => SdTestimonialGrid,
185
- SdTestimonialStrip: () => SdTestimonialStrip,
186
- SdText: () => SdText,
187
- SdTextBody: () => SdTextBody,
188
- SdTextBox: () => SdTextBox,
189
- SdTextBoxCard: () => SdTextBoxCard,
190
- SdTextBoxHero: () => SdTextBoxHero,
191
- SdTextBoxSection: () => SdTextBoxSection,
192
- SdTextBoxSub: () => SdTextBoxSub,
193
- SdTextError: () => SdTextError,
194
- SdTextEyebrow: () => SdTextEyebrow,
195
- SdTextHint: () => SdTextHint,
196
- SdTextNumeric: () => SdTextNumeric,
197
- SdTextStrong: () => SdTextStrong,
198
- SdTextSub: () => SdTextSub,
199
- SdTimeline: () => SdTimeline,
200
- SdTimelineSection: () => SdTimelineSection,
201
- SdTitle: () => SdTitle,
202
- SdTitleCard: () => SdTitleCard,
203
- SdTitleDisplay: () => SdTitleDisplay,
204
- SdTitleSection: () => SdTitleSection,
205
- SdTitleSub: () => SdTitleSub,
206
- SdToast: () => SdToast,
207
- SdToastClean: () => SdToastClean,
208
- SdToastError: () => SdToastError,
209
- SdToastHide: () => SdToastHide,
210
- SdToastInfo: () => SdToastInfo,
211
- SdToastLoading: () => SdToastLoading,
212
- SdToastProvider: () => SdToastProvider,
213
- SdToastSuccess: () => SdToastSuccess,
214
- SdToastUpdate: () => SdToastUpdate,
215
- SdToastWarning: () => SdToastWarning,
216
- theme: () => theme,
217
- useNav: () => useNav
218
- });
219
- module.exports = __toCommonJS(ui_exports);
220
-
221
- // ui/atom/Logo.tsx
222
- var import_link = __toESM(require("next/link"));
223
- var import_core = require("@mantine/core");
224
-
225
- // util/env.util.ts
226
- var _a;
227
- var COMPANY_NAME = (_a = process.env.NEXT_PUBLIC_COMPANY_NAME) != null ? _a : "";
228
- var _a2;
229
- var LOGO_SRC = (_a2 = process.env.NEXT_PUBLIC_LOGO_SRC) != null ? _a2 : "/logo.svg";
230
- var _a3;
231
- var LOGO_ALT = (_a3 = process.env.NEXT_PUBLIC_LOGO_ALT) != null ? _a3 : "\uB85C\uACE0";
232
-
233
- // ui/atom/Logo.tsx
234
- var import_jsx_runtime = require("react/jsx-runtime");
235
- function Logo(_props) {
236
- const { size } = (0, import_core.useProps)("Logo", { size: "md" }, _props);
237
- const theme2 = (0, import_core.useMantineTheme)();
238
- const resolved = theme2.other.logoSizes[size];
239
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: "/", style: { display: "inline-flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Image, { src: LOGO_SRC, alt: LOGO_ALT, w: (0, import_core.rem)(resolved.width), h: "auto", fit: "contain", fetchPriority: "high" }) });
240
- }
241
-
242
- // ui/atom/Tabs.tsx
243
- var import_react = require("react");
244
- var import_core3 = require("@mantine/core");
245
-
246
- // ui/atom/Container.tsx
247
- var import_core2 = require("@mantine/core");
248
- var import_jsx_runtime2 = require("react/jsx-runtime");
249
- function SdContainer(_a4) {
250
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
251
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core2.Container, __spreadProps(__spreadValues({ px: { base: "md", sm: "xl" } }, props), { children }));
252
- }
253
-
254
- // ui/atom/Tabs.tsx
255
- var import_jsx_runtime3 = require("react/jsx-runtime");
256
- function SdPanel(_a4) {
257
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
258
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tabs.Panel, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SdContainer, { py: "xl", children }) }));
259
- }
260
- function SdScrollableList(_a4) {
261
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
262
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Box, { style: { overflowX: "auto", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tabs.List, __spreadProps(__spreadValues({}, props), { children })) });
263
- }
264
- function createTabs(defaults, scrollable = false) {
265
- function SdTabsRoot(_a4) {
266
- var _b = _a4, { syncHash, value, onChange } = _b, props = __objRest(_b, ["syncHash", "value", "onChange"]);
267
- const [hashValue, setHashValue] = (0, import_react.useState)(null);
268
- (0, import_react.useEffect)(() => {
269
- if (!syncHash) return;
270
- const apply = () => {
271
- const id = decodeURIComponent(window.location.hash.slice(1));
272
- if (id) setHashValue(id);
273
- };
274
- apply();
275
- window.addEventListener("hashchange", apply);
276
- return () => window.removeEventListener("hashchange", apply);
277
- }, [syncHash]);
278
- if (!syncHash) {
279
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tabs, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { value, onChange }));
280
- }
281
- const handleChange = (next) => {
282
- if (next) {
283
- window.history.replaceState(null, "", `#${next}`);
284
- setHashValue(next);
285
- }
286
- onChange == null ? void 0 : onChange(next);
287
- };
288
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core3.Tabs, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { value: value != null ? value : hashValue, onChange: handleChange }));
289
- }
290
- SdTabsRoot.List = scrollable ? SdScrollableList : import_core3.Tabs.List;
291
- SdTabsRoot.Tab = import_core3.Tabs.Tab;
292
- SdTabsRoot.Panel = SdPanel;
293
- return SdTabsRoot;
294
- }
295
- var SdTabs = {
296
- Pills: createTabs({
297
- variant: "pills",
298
- color: "primary",
299
- radius: "xl",
300
- styles: {
301
- list: {
302
- background: "var(--mantine-color-slate-1)",
303
- padding: "var(--mantine-spacing-xs)",
304
- gap: "var(--mantine-spacing-xs)",
305
- borderRadius: "var(--mantine-radius-xl)",
306
- width: "fit-content",
307
- maxWidth: "100%",
308
- margin: "0 auto",
309
- flexWrap: "wrap",
310
- justifyContent: "center"
311
- },
312
- tab: {
313
- fontWeight: "500",
314
- fontSize: "var(--mantine-h5-font-size)",
315
- paddingInline: "var(--mantine-spacing-lg)"
316
- }
317
- }
318
- }),
319
- Underline: createTabs({
320
- variant: "default",
321
- color: "primary",
322
- styles: {
323
- list: { width: "fit-content", margin: "0 auto", gap: "var(--mantine-spacing-sm)" },
324
- tab: {
325
- fontWeight: "500",
326
- fontSize: "var(--mantine-h5-font-size)",
327
- paddingInline: "var(--mantine-spacing-lg)"
328
- }
329
- }
330
- }),
331
- Outline: createTabs({
332
- variant: "outline",
333
- color: "primary",
334
- radius: "md",
335
- styles: {
336
- list: { width: "fit-content", margin: "0 auto", gap: "var(--mantine-spacing-sm)" },
337
- tab: {
338
- fontWeight: "500",
339
- fontSize: "var(--mantine-h5-font-size)",
340
- paddingInline: "var(--mantine-spacing-lg)"
341
- }
342
- }
343
- })
344
- };
345
- var SdTabsPills = SdTabs.Pills;
346
- var SdTabsUnderline = SdTabs.Underline;
347
- var SdTabsOutline = SdTabs.Outline;
348
-
349
- // ui/atom/Title.tsx
350
- var import_core4 = require("@mantine/core");
351
-
352
- // util/text.util.ts
353
- var COMPANY_TOKEN = "%c";
354
- function t(text) {
355
- return text.replaceAll(COMPANY_TOKEN, COMPANY_NAME);
356
- }
357
-
358
- // ui/atom/Title.tsx
359
- var import_jsx_runtime4 = require("react/jsx-runtime");
360
- function createTitle(defaults) {
361
- return function SdTitle2(_a4) {
362
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
363
- const resolved = typeof children === "string" ? t(children) : children;
364
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.Title, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { children: resolved }));
365
- };
366
- }
367
- var SdTitle = {
368
- /** 히어로 대제목 — h1, clamp 폰트 */
369
- Display: createTitle({ order: 2 }),
370
- /** 섹션 제목 */
371
- Section: createTitle({ order: 3 }),
372
- /** 카드·모달 제목 — */
373
- Card: createTitle({ order: 4 }),
374
- /** 소제목 */
375
- Sub: createTitle({ order: 5 })
376
- };
377
- var SdTitleDisplay = SdTitle.Display;
378
- var SdTitleSection = SdTitle.Section;
379
- var SdTitleCard = SdTitle.Card;
380
- var SdTitleSub = SdTitle.Sub;
381
-
382
- // ui/atom/Text.tsx
383
- var import_core5 = require("@mantine/core");
384
-
385
- // ui/typography.ts
386
- var textStyles = {
387
- /** 최상위 강조 */
388
- Strong: { fw: 700, c: "slate.9", fz: "md", style: { letterSpacing: "-0.04em" } },
389
- /** 기본 본문 */
390
- Body: { fw: 500, c: "slate.7", fz: "sm", lh: 1.7 },
391
- /** 보조 정보 */
392
- Sub: { fw: 400, c: "slate.5", fz: "xs", lh: 1.6 },
393
- /** 최소 강조 — 밀도 높은 목록 */
394
- Hint: { fw: 400, c: "slate.4", fz: "xs", lh: 1.5 },
395
- /** 섹션 라벨 */
396
- Eyebrow: {
397
- fw: 700,
398
- c: "primary.6",
399
- fz: "xs",
400
- style: { letterSpacing: "0.12em", textTransform: "uppercase" }
401
- },
402
- /** 오류 메시지 */
403
- Error: { fw: 400, c: "red.6", fz: "sm" },
404
- /** 숫자 — 자릿수 정렬 */
405
- Numeric: {
406
- fw: 700,
407
- c: "slate.8",
408
- fz: "md",
409
- style: { fontVariantNumeric: "tabular-nums", letterSpacing: "-0.02em" }
410
- }
411
- };
412
-
413
- // ui/atom/Text.tsx
414
- var import_jsx_runtime5 = require("react/jsx-runtime");
415
- function createText(defaults) {
416
- return function SdText2(_a4) {
417
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
418
- const resolved = typeof children === "string" ? t(children) : children;
419
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.Text, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { children: resolved }));
420
- };
421
- }
422
- var SdText = {
423
- Strong: createText(textStyles.Strong),
424
- Body: createText(textStyles.Body),
425
- Sub: createText(textStyles.Sub),
426
- Eyebrow: createText(textStyles.Eyebrow),
427
- Error: createText(textStyles.Error),
428
- Hint: createText(textStyles.Hint),
429
- Numeric: createText(textStyles.Numeric)
430
- };
431
- var SdTextStrong = SdText.Strong;
432
- var SdTextBody = SdText.Body;
433
- var SdTextSub = SdText.Sub;
434
- var SdTextEyebrow = SdText.Eyebrow;
435
- var SdTextError = SdText.Error;
436
- var SdTextHint = SdText.Hint;
437
- var SdTextNumeric = SdText.Numeric;
438
-
439
- // ui/atom/Button.tsx
440
- var import_core6 = require("@mantine/core");
441
- var import_icons_react = require("@tabler/icons-react");
442
- var import_jsx_runtime6 = require("react/jsx-runtime");
443
- function createButton(defaults, defaultLabel) {
444
- return function SdButton2(_a4) {
445
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
446
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core6.Button, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { children: children != null ? children : defaultLabel }));
447
- };
448
- }
449
- var SdButton = {
450
- /** 주요 액션 — filled primary */
451
- Primary: createButton({ color: "primary" }),
452
- /** 보조 액션 — white bg + slate text */
453
- Secondary: createButton({ variant: "white", color: "slate" }),
454
- /** 보조 액션 — outline */
455
- Outline: createButton({ variant: "outline", color: "primary" }),
456
- /** 텍스트 수준 — subtle */
457
- Ghost: createButton({ variant: "subtle", color: "slate" }),
458
- /** 다크 배경 위 — white */
459
- White: createButton({ variant: "white" }),
460
- // ── 표준 액션 버튼: 라벨·색·아이콘이 고정 (children으로 라벨 덮어쓰기 가능) ──
461
- /** 전송 — filled primary + 종이비행기 아이콘, 기본 라벨 "전송" */
462
- Submit: createButton({ color: "primary", leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react.IconSend, { size: 16 }) }, "\uC804\uC1A1"),
463
- /** 삭제 — filled red + 휴지통 아이콘, 기본 라벨 "삭제" */
464
- Delete: createButton({ color: "red", leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react.IconTrash, { size: 16 }) }, "\uC0AD\uC81C"),
465
- /** 취소 — outline slate + X 아이콘, 기본 라벨 "취소" */
466
- Cancel: createButton(
467
- { variant: "outline", color: "slate", leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react.IconX, { size: 16 }) },
468
- "\uCDE8\uC18C"
469
- ),
470
- /** 엑셀 — outline green + 스프레드시트 아이콘, 기본 라벨 "엑셀" */
471
- Excel: createButton(
472
- { variant: "outline", color: "green", leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react.IconFileSpreadsheet, { size: 16 }) },
473
- "\uC5D1\uC140"
474
- ),
475
- /** 다운로드 — light primary + 다운로드 아이콘, 기본 라벨 "다운로드" */
476
- Download: createButton(
477
- { variant: "light", color: "primary", leftSection: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons_react.IconDownload, { size: 16 }) },
478
- "\uB2E4\uC6B4\uB85C\uB4DC"
479
- )
480
- };
481
- var SdButtonPrimary = SdButton.Primary;
482
- var SdButtonSecondary = SdButton.Secondary;
483
- var SdButtonOutline = SdButton.Outline;
484
- var SdButtonGhost = SdButton.Ghost;
485
- var SdButtonWhite = SdButton.White;
486
- var SdButtonSubmit = SdButton.Submit;
487
- var SdButtonDelete = SdButton.Delete;
488
- var SdButtonCancel = SdButton.Cancel;
489
- var SdButtonExcel = SdButton.Excel;
490
- var SdButtonDownload = SdButton.Download;
491
-
492
- // ui/atom/Quote.tsx
493
- var import_core7 = require("@mantine/core");
494
- var import_jsx_runtime7 = require("react/jsx-runtime");
495
- function QuoteInner({ lines, name, role }) {
496
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_core7.Stack, { gap: "lg", children: [
497
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_core7.Stack, { gap: 0, children: [
498
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SdTitle.Display, { c: "primary.6", lh: 0.8, "aria-hidden": true, children: "\u201C" }),
499
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core7.Stack, { gap: "sm", mt: "md", children: lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SdText.Body, { children: line }, i)) })
500
- ] }),
501
- (name || role) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_core7.Group, { gap: "xs", align: "baseline", children: [
502
- name && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SdText.Strong, { children: name }),
503
- role && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SdText.Sub, { children: role })
504
- ] })
505
- ] });
506
- }
507
- function Plain(_a4) {
508
- var _b = _a4, { lines, name, role } = _b, boxProps = __objRest(_b, ["lines", "name", "role"]);
509
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core7.Center, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core7.Box, __spreadProps(__spreadValues({ w: "fit-content" }, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(QuoteInner, { lines, name, role }) })) });
510
- }
511
- function CardQuote(_a4) {
512
- var _b = _a4, { lines, name, role } = _b, boxProps = __objRest(_b, ["lines", "name", "role"]);
513
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core7.Center, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core7.Card, __spreadProps(__spreadValues({ w: "fit-content" }, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(QuoteInner, { lines, name, role }) })) });
514
- }
515
- var SdQuote = {
516
- Plain,
517
- Card: CardQuote
518
- };
519
- var SdQuotePlain = SdQuote.Plain;
520
- var SdQuoteCard = SdQuote.Card;
521
-
522
- // ui/atom/Table.tsx
523
- var import_core8 = require("@mantine/core");
524
- var import_jsx_runtime8 = require("react/jsx-runtime");
525
- function createTable(defaults) {
526
- function SdTableRoot(props) {
527
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_core8.Table, __spreadValues(__spreadValues({}, defaults), props));
528
- }
529
- SdTableRoot.Thead = import_core8.Table.Thead;
530
- SdTableRoot.Tbody = import_core8.Table.Tbody;
531
- SdTableRoot.Tr = import_core8.Table.Tr;
532
- SdTableRoot.Th = import_core8.Table.Th;
533
- SdTableRoot.Td = import_core8.Table.Td;
534
- SdTableRoot.Caption = import_core8.Table.Caption;
535
- return SdTableRoot;
536
- }
537
- var base = {
538
- striped: true,
539
- highlightOnHover: true,
540
- withTableBorder: true,
541
- withColumnBorders: false,
542
- verticalSpacing: "sm",
543
- horizontalSpacing: "md"
544
- };
545
- function SpecTh(_a4) {
546
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
547
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_core8.Table.Th, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SdText.Strong, { c: "white", children }) }));
548
- }
549
- function SpecTd(_a4) {
550
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
551
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_core8.Table.Td, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SdText.Body, { children }) }));
552
- }
553
- var Spec = createTable(__spreadProps(__spreadValues({}, base), {
554
- withColumnBorders: true,
555
- verticalSpacing: "md",
556
- horizontalSpacing: "lg",
557
- styles: {
558
- table: { borderRadius: "var(--mantine-radius-md)", overflow: "hidden" },
559
- th: {
560
- background: "var(--mantine-color-primary-6)",
561
- letterSpacing: "0.01em"
562
- }
563
- }
564
- }));
565
- Spec.Th = SpecTh;
566
- Spec.Td = SpecTd;
567
- var SdTable = Object.assign(createTable(base), { Spec });
568
- var SdTableSpec = Spec;
569
-
570
- // ui/atom/Modal.tsx
571
- var import_core9 = require("@mantine/core");
572
- var import_jsx_runtime9 = require("react/jsx-runtime");
573
- function createModal(defaults) {
574
- function SdModalRoot(props) {
575
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_core9.Modal, __spreadValues(__spreadValues({}, defaults), props));
576
- }
577
- SdModalRoot.Header = import_core9.Modal.Header;
578
- SdModalRoot.Title = import_core9.Modal.Title;
579
- SdModalRoot.Body = import_core9.Modal.Body;
580
- SdModalRoot.CloseButton = import_core9.Modal.CloseButton;
581
- return SdModalRoot;
582
- }
583
- var SdModal = createModal({
584
- size: "md",
585
- overlayProps: { backgroundOpacity: 0.4, blur: 4 }
586
- });
587
-
588
- // ui/atom/NumberIcon.tsx
589
- var import_core10 = require("@mantine/core");
590
- var import_jsx_runtime10 = require("react/jsx-runtime");
591
- function SdNumberIcon(_a4) {
592
- var _b = _a4, {
593
- value,
594
- size = 48,
595
- radius = "xl",
596
- color = "primary"
597
- } = _b, props = __objRest(_b, [
598
- "value",
599
- "size",
600
- "radius",
601
- "color"
602
- ]);
603
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_core10.ThemeIcon, __spreadProps(__spreadValues({ size, radius, color }, props), { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SdText.Strong, { c: "white", children: value }) }));
604
- }
605
-
606
- // ui/atom/Badge.tsx
607
- var import_core11 = require("@mantine/core");
608
- var import_jsx_runtime11 = require("react/jsx-runtime");
609
- function createBadge(defaults) {
610
- return function SdBadge2(_a4) {
611
- var _b = _a4, { children } = _b, props = __objRest(_b, ["children"]);
612
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_core11.Badge, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { children }));
613
- };
614
- }
615
- var SdBadge = {
616
- /** 기본 — outline slate */
617
- Default: createBadge({ variant: "outline", color: "slate" }),
618
- /** 브랜드 강조 — light primary */
619
- Primary: createBadge({ variant: "light", color: "primary" }),
620
- /** 성공/완료 */
621
- Success: createBadge({ variant: "light", color: "green" }),
622
- /** 주의/경고 */
623
- Warning: createBadge({ variant: "light", color: "amber" })
624
- };
625
- var SdBadgeDefault = SdBadge.Default;
626
- var SdBadgePrimary = SdBadge.Primary;
627
- var SdBadgeSuccess = SdBadge.Success;
628
- var SdBadgeWarning = SdBadge.Warning;
629
-
630
- // ui/atom/Input.tsx
631
- var import_core12 = require("@mantine/core");
632
- var import_dates = require("@mantine/dates");
633
- var import_jsx_runtime12 = require("react/jsx-runtime");
634
- function createInput(Component, defaults) {
635
- return function SdInput2(props) {
636
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Component, __spreadValues(__spreadValues({}, defaults), props));
637
- };
638
- }
639
- function createWrappedInput(Component, defaults) {
640
- return function SdWrappedInput(_a4) {
641
- var _b = _a4, {
642
- label,
643
- description,
644
- error,
645
- required,
646
- withAsterisk
647
- } = _b, rest = __objRest(_b, [
648
- "label",
649
- "description",
650
- "error",
651
- "required",
652
- "withAsterisk"
653
- ]);
654
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
655
- import_core12.Input.Wrapper,
656
- {
657
- label,
658
- description,
659
- error,
660
- required,
661
- withAsterisk,
662
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Component, __spreadValues(__spreadValues({}, defaults), rest))
663
- }
664
- );
665
- };
666
- }
667
- function SdInputRadio(_a4) {
668
- var _b = _a4, { data, orientation = "horizontal" } = _b, props = __objRest(_b, ["data", "orientation"]);
669
- const Layout = orientation === "vertical" ? import_core12.Stack : import_core12.Group;
670
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_core12.Radio.Group, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Layout, { gap: "sm", mt: "xs", children: data.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_core12.Radio, { value: item.value, label: item.label, disabled: item.disabled }, item.value)) }) }));
671
- }
672
- var SdInput = {
673
- // ── 텍스트 ──
674
- /** 일반 텍스트 — 이름, 회사명 등 */
675
- Text: createInput(import_core12.TextInput),
676
- /** 이메일 입력 */
677
- Email: createInput(import_core12.TextInput, { type: "email" }),
678
- /** 비밀번호 입력 — 마스킹 토글 포함 */
679
- Password: createInput(import_core12.PasswordInput),
680
- /** 멀티라인 텍스트 — 문의 메시지 등 */
681
- Textarea: createInput(import_core12.Textarea, { autosize: true, minRows: 3 }),
682
- /** JSON 입력 — 포맷·검증 버튼 포함 */
683
- Json: createInput(import_core12.JsonInput, { autosize: true, minRows: 4, formatOnBlur: true }),
684
- // ── 숫자 ──
685
- /** 숫자 입력 — 증감 컨트롤 포함 */
686
- Number: createInput(import_core12.NumberInput),
687
- /** 범위 선택 슬라이더 */
688
- Slider: createWrappedInput(import_core12.Slider),
689
- /** 별점 */
690
- Rating: createWrappedInput(import_core12.Rating),
691
- /** 인증번호 등 자리수가 고정된 코드 */
692
- PinCode: createWrappedInput(import_core12.PinInput),
693
- // ── 선택 ──
694
- /** 드롭다운 선택 */
695
- Select: createInput(import_core12.Select),
696
- /** 브라우저 기본 select — 모바일·간단한 목록 */
697
- NativeSelect: createInput(import_core12.NativeSelect),
698
- /** 다중 선택 */
699
- MultiSelect: createInput(import_core12.MultiSelect),
700
- /** 입력하며 후보를 좁히는 자동완성(자유 입력 허용) */
701
- Autocomplete: createInput(import_core12.Autocomplete),
702
- /** 자유롭게 추가하는 태그 목록 */
703
- Tags: createInput(import_core12.TagsInput),
704
- /** 라디오 그룹 — data로 항목을 넘긴다 */
705
- Radio: SdInputRadio,
706
- /** 두세 개 중 하나 — 탭처럼 보이는 선택 */
707
- Segmented: createWrappedInput(import_core12.SegmentedControl),
708
- // ── 불리언 ──
709
- /** 체크박스 — getInputProps(name, { type: 'checkbox' }) */
710
- Checkbox: createInput(import_core12.Checkbox),
711
- /** 스위치 — 즉시 반영되는 on/off */
712
- Switch: createInput(import_core12.Switch),
713
- // ── 기타 ──
714
- /** 파일 선택 */
715
- File: createInput(import_core12.FileInput, { clearable: true }),
716
- /** 색상 선택 */
717
- Color: createInput(import_core12.ColorInput),
718
- // ── 날짜·시간 (@mantine/dates) ──
719
- /** 날짜 — 직접 입력 + 달력 팝오버. 값은 'YYYY-MM-DD' 문자열 */
720
- Date: createInput(import_dates.DateInput, { valueFormat: "YYYY-MM-DD", clearable: true }),
721
- /** 기간 — 시작·종료 두 날짜 */
722
- DateRange: createInput(import_dates.DatePickerInput, {
723
- type: "range",
724
- valueFormat: "YYYY-MM-DD",
725
- clearable: true
726
- }),
727
- /** 시각 */
728
- Time: createInput(import_dates.TimeInput)
729
- };
730
- var SdInputText = SdInput.Text;
731
- var SdInputEmail = SdInput.Email;
732
- var SdInputPassword = SdInput.Password;
733
- var SdInputTextarea = SdInput.Textarea;
734
- var SdInputJson = SdInput.Json;
735
- var SdInputNumber = SdInput.Number;
736
- var SdInputSlider = SdInput.Slider;
737
- var SdInputRating = SdInput.Rating;
738
- var SdInputPinCode = SdInput.PinCode;
739
- var SdInputSelect = SdInput.Select;
740
- var SdInputNativeSelect = SdInput.NativeSelect;
741
- var SdInputMultiSelect = SdInput.MultiSelect;
742
- var SdInputAutocomplete = SdInput.Autocomplete;
743
- var SdInputTags = SdInput.Tags;
744
- var SdInputRadioGroup = SdInput.Radio;
745
- var SdInputSegmented = SdInput.Segmented;
746
- var SdInputCheckbox = SdInput.Checkbox;
747
- var SdInputSwitch = SdInput.Switch;
748
- var SdInputFile = SdInput.File;
749
- var SdInputColor = SdInput.Color;
750
- var SdInputDate = SdInput.Date;
751
- var SdInputDateRange = SdInput.DateRange;
752
- var SdInputTime = SdInput.Time;
753
-
754
- // ui/atom/Skeleton.tsx
755
- var import_core13 = require("@mantine/core");
756
- var import_jsx_runtime13 = require("react/jsx-runtime");
757
- function SkeletonText(_a4) {
758
- var _b = _a4, { width = "100%" } = _b, props = __objRest(_b, ["width"]);
759
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core13.Skeleton, __spreadValues({ height: 14, width, radius: "sm" }, props));
760
- }
761
- function SkeletonTitle(_a4) {
762
- var _b = _a4, { width = "60%" } = _b, props = __objRest(_b, ["width"]);
763
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core13.Skeleton, __spreadValues({ height: 20, width, radius: "sm" }, props));
764
- }
765
- function SkeletonImage(_a4) {
766
- var _b = _a4, { height = 200 } = _b, props = __objRest(_b, ["height"]);
767
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core13.Skeleton, __spreadValues({ height, radius: "md" }, props));
768
- }
769
- function SkeletonAvatar(_a4) {
770
- var _b = _a4, { size = 40 } = _b, props = __objRest(_b, ["size"]);
771
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core13.Skeleton, __spreadValues({ height: size, width: size, circle: true }, props));
772
- }
773
- function SkeletonCard({ height, lines = 3 }) {
774
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
775
- import_core13.Box,
776
- {
777
- p: "md",
778
- style: {
779
- borderRadius: "var(--mantine-radius-md)",
780
- border: "1px solid var(--mantine-color-gray-3)",
781
- height
782
- },
783
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core13.Stack, { gap: "sm", children: [
784
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core13.Skeleton, { height: 20, width: "50%", radius: "sm" }),
785
- Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
786
- import_core13.Skeleton,
787
- {
788
- height: 14,
789
- width: i === lines - 1 ? "70%" : "100%",
790
- radius: "sm"
791
- },
792
- i
793
- ))
794
- ] })
795
- }
796
- );
797
- }
798
- var SdSkeleton = {
799
- Card: SkeletonCard,
800
- Text: SkeletonText,
801
- Title: SkeletonTitle,
802
- Image: SkeletonImage,
803
- Avatar: SkeletonAvatar
804
- };
805
- var SdSkeletonCard = SkeletonCard;
806
- var SdSkeletonText = SkeletonText;
807
- var SdSkeletonTitle = SkeletonTitle;
808
- var SdSkeletonImage = SkeletonImage;
809
- var SdSkeletonAvatar = SkeletonAvatar;
810
-
811
- // ui/atom/Link.tsx
812
- var import_core14 = require("@mantine/core");
813
-
814
- // ui/style.util.ts
815
- function toCssColor(value) {
816
- if (typeof value !== "string") return "";
817
- return value.includes(".") ? `var(--mantine-color-${value.replace(".", "-")})` : value;
818
- }
819
-
820
- // ui/atom/Link.tsx
821
- var import_jsx_runtime14 = require("react/jsx-runtime");
822
- var HOVER_COLOR = "var(--mantine-color-primary-6)";
823
- function createLink(defaults, Fallback) {
824
- return function SdLink2(_a4) {
825
- var _b = _a4, { children, onMouseEnter, onMouseLeave } = _b, props = __objRest(_b, ["children", "onMouseEnter", "onMouseLeave"]);
826
- var _a5;
827
- const baseColor = toCssColor((_a5 = props.c) != null ? _a5 : defaults.c);
828
- const resolved = typeof children === "string" ? t(children) : children;
829
- if (!props.href) {
830
- const _b2 = props, { href: _href, target: _target, rel: _rel } = _b2, textProps = __objRest(_b2, ["href", "target", "rel"]);
831
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Fallback, __spreadProps(__spreadValues({}, textProps), { children }));
832
- }
833
- const handleEnter = (e) => {
834
- e.currentTarget.style.color = HOVER_COLOR;
835
- onMouseEnter == null ? void 0 : onMouseEnter(e);
836
- };
837
- const handleLeave = (e) => {
838
- e.currentTarget.style.color = baseColor;
839
- onMouseLeave == null ? void 0 : onMouseLeave(e);
840
- };
841
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
842
- import_core14.Anchor,
843
- __spreadProps(__spreadValues(__spreadValues({}, defaults), props), {
844
- style: { transition: "color 0.15s" },
845
- onMouseEnter: handleEnter,
846
- onMouseLeave: handleLeave,
847
- children: resolved
848
- })
849
- );
850
- };
851
- }
852
- function linkStyle(base2, extra) {
853
- return Object.assign({ underline: "never" }, base2, extra);
854
- }
855
- var SdLink = {
856
- /** 최상위 강조 — 눈에 띄어야 하는 단일 링크 */
857
- Strong: createLink(linkStyle(textStyles.Strong), SdText.Strong),
858
- /** 기본 — 본문·네비게이션 수준의 일반 링크 */
859
- Body: createLink(linkStyle(textStyles.Body), SdText.Body),
860
- /** 보조 — 연락처·정책 등 부가 정보 */
861
- Sub: createLink(linkStyle(textStyles.Sub), SdText.Sub),
862
- /** 최소 강조 — 링크 목록처럼 밀도가 높고 톤을 낮춰야 하는 곳 */
863
- Hint: createLink(linkStyle(textStyles.Hint), SdText.Hint)
864
- };
865
- var SdLinkStrong = SdLink.Strong;
866
- var SdLinkBody = SdLink.Body;
867
- var SdLinkSub = SdLink.Sub;
868
- var SdLinkHint = SdLink.Hint;
869
-
870
- // ui/atom/Toast.tsx
871
- var import_notifications = require("@mantine/notifications");
872
- var import_icons_react2 = require("@tabler/icons-react");
873
- var import_jsx_runtime15 = require("react/jsx-runtime");
874
- var toastStyles = {
875
- /** 성공 — 저장·전송 완료 */
876
- Success: { color: "green", icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons_react2.IconCheck, { size: 18 }), title: "\uC644\uB8CC" },
877
- /** 실패 — 요청 오류·검증 실패 */
878
- Error: { color: "red", icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons_react2.IconX, { size: 18 }), title: "\uC624\uB958" },
879
- /** 주의 — 되돌릴 수 없는 동작 안내 등 */
880
- Warning: { color: "amber", icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons_react2.IconAlertTriangle, { size: 18 }), title: "\uC8FC\uC758" },
881
- /** 안내 — 중립 정보 */
882
- Info: { color: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons_react2.IconInfoCircle, { size: 18 }), title: "\uC548\uB0B4" },
883
- /** 진행 중 — 스피너 + 자동 닫힘 없음. Update로 결과 변형으로 바꾼다. */
884
- Loading: { loading: true, autoClose: false, withCloseButton: false, title: "\uCC98\uB9AC \uC911" }
885
- };
886
- function createToast(defaults) {
887
- return function SdToast2(message, options) {
888
- return import_notifications.notifications.show(__spreadValues(__spreadProps(__spreadValues({}, defaults), { message }), options));
889
- };
890
- }
891
- var SdToast = {
892
- Success: createToast(toastStyles.Success),
893
- Error: createToast(toastStyles.Error),
894
- Warning: createToast(toastStyles.Warning),
895
- Info: createToast(toastStyles.Info),
896
- Loading: createToast(toastStyles.Loading),
897
- /**
898
- * 이미 떠 있는 알림을 다른 변형으로 교체한다 — `Loading` → `Success`/`Error` 전환용.
899
- * `loading: false`·`autoClose`를 먼저 깔아 두므로 스피너가 그대로 남지 않는다.
900
- */
901
- Update: (id, variant, message, options) => import_notifications.notifications.update(__spreadValues(__spreadProps(__spreadValues({
902
- id,
903
- loading: false,
904
- autoClose: 4e3,
905
- withCloseButton: true
906
- }, toastStyles[variant]), {
907
- message
908
- }), options)),
909
- /** 특정 알림 닫기 */
910
- Hide: (id) => import_notifications.notifications.hide(id),
911
- /** 떠 있는 알림 전부 닫기 */
912
- Clean: () => import_notifications.notifications.clean()
913
- };
914
- function SdToastProvider(props) {
915
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_notifications.Notifications, __spreadValues({ position: "top-right", autoClose: 4e3, limit: 3 }, props));
916
- }
917
- var SdToastSuccess = SdToast.Success;
918
- var SdToastError = SdToast.Error;
919
- var SdToastWarning = SdToast.Warning;
920
- var SdToastInfo = SdToast.Info;
921
- var SdToastLoading = SdToast.Loading;
922
- var SdToastUpdate = SdToast.Update;
923
- var SdToastHide = SdToast.Hide;
924
- var SdToastClean = SdToast.Clean;
925
-
926
- // ui/molecule/TextBox.tsx
927
- var import_core15 = require("@mantine/core");
928
- var import_jsx_runtime16 = require("react/jsx-runtime");
929
- function createTextBox(titleVariant, defaultGap = "xs", descVariant = "Body", color_ = void 0) {
930
- return function SdTextBox2(_a4) {
931
- var _b = _a4, {
932
- label,
933
- title,
934
- description,
935
- titleVariant: variantOverride,
936
- maxDescWidth,
937
- children,
938
- color
939
- } = _b, stackProps = __objRest(_b, [
940
- "label",
941
- "title",
942
- "description",
943
- "titleVariant",
944
- "maxDescWidth",
945
- "children",
946
- "color"
947
- ]);
948
- const colorRes = color != null ? color : color_;
949
- const variant = variantOverride != null ? variantOverride : titleVariant;
950
- const TitleComponent = SdTitle[variant];
951
- const DescComponent = SdText[descVariant];
952
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_core15.Stack, __spreadProps(__spreadValues({ gap: defaultGap }, stackProps), { children: [
953
- label && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SdText.Eyebrow, { children: label }),
954
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TitleComponent, { c: colorRes, children: title }),
955
- description && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DescComponent, { c: colorRes, maw: maxDescWidth, mt: 4, children: description }),
956
- children
957
- ] }));
958
- };
959
- }
960
- var SdTextBox = {
961
- Hero: createTextBox("Display", "lg", "Body", "slate.0"),
962
- Section: createTextBox("Section", "xs", "Body"),
963
- Card: createTextBox("Card", "xs", "Body"),
964
- Sub: createTextBox("Sub", "xs", "Sub")
965
- };
966
- var SdTextBoxHero = SdTextBox.Hero;
967
- var SdTextBoxSection = SdTextBox.Section;
968
- var SdTextBoxCard = SdTextBox.Card;
969
- var SdTextBoxSub = SdTextBox.Sub;
970
-
971
- // ui/molecule/Features.tsx
972
- var import_core16 = require("@mantine/core");
973
-
974
- // util/sort.util.ts
975
- function filterAndSort(items, direction = "asc") {
976
- const sign = direction === "asc" ? 1 : -1;
977
- return (items != null ? items : []).filter((item) => item.isShow).sort((a, b) => (a.order - b.order) * sign);
978
- }
979
-
980
- // ui/molecule/Features.tsx
981
- var import_jsx_runtime17 = require("react/jsx-runtime");
982
- function SdFeatures({ items, cols = { base: 1, sm: 2, md: 3 } }) {
983
- const visible = filterAndSort(items);
984
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_core16.SimpleGrid, { cols, spacing: "xl", children: visible.map((item) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_core16.Card, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_core16.Stack, { gap: "sm", children: [
985
- item.icon,
986
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SdTextBox.Card, { label: item.label, title: item.title, description: item.description })
987
- ] }, item.id) }, item.id)) });
988
- }
989
-
990
- // ui/molecule/Timeline.tsx
991
- var import_core17 = require("@mantine/core");
992
- var import_jsx_runtime18 = require("react/jsx-runtime");
993
- function SdTimeline({ items }) {
994
- const grouped = items.filter((item) => item.isShow).sort((a, b) => b.year - a.year || b.month - a.month).reduce((acc, item) => {
995
- var _a4, _b;
996
- ;
997
- ((_b = acc[_a4 = item.year]) != null ? _b : acc[_a4] = []).push(item);
998
- return acc;
999
- }, {});
1000
- const years = Object.keys(grouped).map(Number).sort((a, b) => b - a);
1001
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_core17.Timeline, { active: items.length, bulletSize: 24, lineWidth: 2, children: years.map((year) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_core17.Timeline.Item, { title: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(SdTitle.Sub, { children: [
1002
- year,
1003
- "\uB144"
1004
- ] }), children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_core17.Stack, { gap: 6, mt: "xs", children: grouped[year].map((event) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_core17.Group, { gap: "md", align: "center", wrap: "nowrap", children: [
1005
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(SdText.Eyebrow, { miw: 28, children: [
1006
- event.month,
1007
- "\uC6D4"
1008
- ] }),
1009
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SdText.Sub, { style: { flex: 1 }, children: event.description })
1010
- ] }, event.id)) }) }, year)) });
1011
- }
1012
-
1013
- // ui/molecule/Steps.tsx
1014
- var import_core18 = require("@mantine/core");
1015
- var import_icons_react3 = require("@tabler/icons-react");
1016
- var import_jsx_runtime19 = require("react/jsx-runtime");
1017
- var import_jsx_runtime20 = require("react/jsx-runtime");
1018
- function BubbleStep({ item, index, isLast }) {
1019
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_core18.Group, { align: "flex-start", gap: "lg", wrap: "nowrap", children: [
1020
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1021
- import_core18.Box,
1022
- {
1023
- style: { display: "flex", flexDirection: "column", alignItems: "center", flexShrink: 0 },
1024
- children: [
1025
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SdNumberIcon, { value: String(index + 1).padStart(2, "0"), color: "primary" }),
1026
- !isLast && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1027
- import_core18.Box,
1028
- {
1029
- style: {
1030
- width: 2,
1031
- flex: 1,
1032
- minHeight: 32,
1033
- marginTop: 8,
1034
- background: "var(--mantine-color-primary-2)"
1035
- }
1036
- }
1037
- )
1038
- ]
1039
- }
1040
- ),
1041
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1042
- SdTextBox.Card,
1043
- {
1044
- title: item.title,
1045
- description: item.description,
1046
- pb: !isLast ? "xl" : 0,
1047
- pt: 4
1048
- }
1049
- )
1050
- ] });
1051
- }
1052
- function Bubble({ items }) {
1053
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Box, { children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BubbleStep, { item, index: i, isLast: i === items.length - 1 }, i)) });
1054
- }
1055
- function CardStep({ item, index }) {
1056
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_core18.Card, { withBorder: true, radius: "md", p: 0, style: { height: "100%", overflow: "hidden" }, children: [
1057
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1058
- import_core18.Box,
1059
- {
1060
- py: "lg",
1061
- style: {
1062
- display: "flex",
1063
- justifyContent: "center",
1064
- background: "var(--mantine-color-primary-0)"
1065
- },
1066
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(SdText.Eyebrow, { children: [
1067
- "STEP ",
1068
- String(index + 1).padStart(2, "0")
1069
- ] })
1070
- }
1071
- ),
1072
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Box, { p: "lg", style: { textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SdTextBox.Card, { title: item.title, description: item.description }) })
1073
- ] });
1074
- }
1075
- function CardArrow({ direction }) {
1076
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.ThemeIcon, { size: 36, radius: "xl", variant: "light", color: "primary", children: direction === "right" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons_react3.IconArrowRight, { size: 20, stroke: 2.5 }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons_react3.IconArrowDown, { size: 20, stroke: 2.5 }) });
1077
- }
1078
- function CardVariant({ items }) {
1079
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
1080
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Stack, { gap: "sm", hiddenFrom: "sm", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime19.Fragment, { children: [
1081
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStep, { item, index: i }),
1082
- i < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Box, { style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardArrow, { direction: "down" }) })
1083
- ] }, i)) }),
1084
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Group, { wrap: "nowrap", align: "stretch", gap: 0, visibleFrom: "sm", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime19.Fragment, { children: [
1085
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Box, { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStep, { item, index: i }) }),
1086
- i < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Box, { style: { display: "flex", alignItems: "center", padding: "0 8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardArrow, { direction: "right" }) })
1087
- ] }, i)) })
1088
- ] });
1089
- }
1090
- function StripStep({ item, index }) {
1091
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Box, { pl: "md", style: { borderLeft: "3px solid var(--mantine-color-primary-6)" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_core18.Stack, { gap: 4, children: [
1092
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(SdText.Eyebrow, { children: [
1093
- "STEP ",
1094
- String(index + 1).padStart(2, "0")
1095
- ] }),
1096
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SdTextBox.Card, { title: item.title, description: item.description })
1097
- ] }) });
1098
- }
1099
- function Strip({ items }) {
1100
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core18.Stack, { gap: "xl", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StripStep, { item, index: i }, i)) });
1101
- }
1102
- var SdSteps = { Bubble, Card: CardVariant, Strip };
1103
- var SdStepsBubble = SdSteps.Bubble;
1104
- var SdStepsCard = SdSteps.Card;
1105
- var SdStepsStrip = SdSteps.Strip;
1106
-
1107
- // ui/molecule/Testimonial.tsx
1108
- var import_core19 = require("@mantine/core");
1109
- var import_jsx_runtime21 = require("react/jsx-runtime");
1110
- function AuthorRow({ item }) {
1111
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_core19.Group, { gap: "sm", wrap: "nowrap", children: [
1112
- item.avatar && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.Avatar, { src: item.avatar, size: "md", radius: "xl" }),
1113
- !item.avatar && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.Avatar, { size: "md", radius: "xl", color: "primary", children: item.name.charAt(0) }),
1114
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_core19.Stack, { gap: 0, children: [
1115
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SdText.Strong, { fz: "sm", children: item.name }),
1116
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(SdText.Sub, { children: [
1117
- item.role,
1118
- item.company ? ` \xB7 ${item.company}` : ""
1119
- ] })
1120
- ] })
1121
- ] });
1122
- }
1123
- function CardTestimonial(_a4) {
1124
- var _b = _a4, { item } = _b, boxProps = __objRest(_b, ["item"]);
1125
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.Card, __spreadProps(__spreadValues({ h: "100%" }, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_core19.Stack, { gap: "md", h: "100%", children: [
1126
- item.rating && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.Rating, { value: item.rating, readOnly: true, size: "sm", color: "primary" }),
1127
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_core19.Stack, { gap: "xs", style: { flex: 1 }, children: [
1128
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SdTitle.Display, { c: "primary.6", lh: 0.8, "aria-hidden": true, children: "\u201C" }),
1129
- item.lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SdText.Body, { children: line }, i))
1130
- ] }),
1131
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AuthorRow, { item })
1132
- ] }) }));
1133
- }
1134
- function Strip2(_a4) {
1135
- var _b = _a4, { item } = _b, boxProps = __objRest(_b, ["item"]);
1136
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.Box, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_core19.Stack, { gap: "md", children: [
1137
- item.rating && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.Rating, { value: item.rating, readOnly: true, size: "sm", color: "primary" }),
1138
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_core19.Group, { gap: 4, align: "flex-start", children: [
1139
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SdTitle.Display, { c: "primary.6", lh: 0.8, "aria-hidden": true, children: "\u201C" }),
1140
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.Stack, { gap: "xs", style: { flex: 1 }, children: item.lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SdText.Body, { children: line }, i)) })
1141
- ] }),
1142
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AuthorRow, { item })
1143
- ] }) }));
1144
- }
1145
- function Grid({ items, cols = { base: 1, sm: 2, md: 3 } }) {
1146
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core19.SimpleGrid, { cols, spacing: "xl", style: { alignItems: "stretch" }, children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardTestimonial, { item }, i)) });
1147
- }
1148
- var SdTestimonial = {
1149
- /** 카드형 — 그리드 배치용 */
1150
- Card: CardTestimonial,
1151
- /** 스트립형 — 단일 강조 후기 */
1152
- Strip: Strip2,
1153
- /** 카드 그리드 — 여러 후기 목록 */
1154
- Grid
1155
- };
1156
- var SdTestimonialCard = SdTestimonial.Card;
1157
- var SdTestimonialStrip = SdTestimonial.Strip;
1158
- var SdTestimonialGrid = SdTestimonial.Grid;
1159
-
1160
- // ui/molecule/PricingCard.tsx
1161
- var import_core20 = require("@mantine/core");
1162
- var import_icons_react4 = require("@tabler/icons-react");
1163
- var import_jsx_runtime22 = require("react/jsx-runtime");
1164
- function Default(_a4) {
1165
- var _b = _a4, { item, onSelect } = _b, cardProps = __objRest(_b, ["item", "onSelect"]);
1166
- var _a5;
1167
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_core20.Card, __spreadProps(__spreadValues({ withBorder: true, style: { position: "relative" } }, cardProps), { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Stack, { gap: "xl", children: [
1168
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Stack, { gap: "xs", children: [
1169
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Group, { justify: "space-between", align: "flex-start", children: [
1170
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdTitle.Card, { children: item.name }),
1171
- item.isPopular && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdBadge.Primary, { children: "\uCD94\uCC9C" })
1172
- ] }),
1173
- item.description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdText.Sub, { children: item.description })
1174
- ] }),
1175
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Group, { gap: 4, align: "baseline", children: [
1176
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdTitle.Display, { children: item.price }),
1177
- item.period && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(SdText.Sub, { children: [
1178
- "/ ",
1179
- item.period
1180
- ] })
1181
- ] }),
1182
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_core20.Divider, {}),
1183
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_core20.Stack, { gap: "sm", children: item.features.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Group, { gap: "sm", wrap: "nowrap", children: [
1184
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1185
- import_core20.ThemeIcon,
1186
- {
1187
- size: "xs",
1188
- radius: "xl",
1189
- color: f.included ? "primary" : "slate",
1190
- variant: f.included ? "filled" : "subtle",
1191
- children: f.included ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_react4.IconCheck, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_react4.IconX, { size: 12 })
1192
- }
1193
- ),
1194
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdText.Body, { fz: "sm", c: f.included ? "slate.7" : "slate.4", children: f.text })
1195
- ] }, i)) }),
1196
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdButton.Outline, { fullWidth: true, onClick: () => onSelect == null ? void 0 : onSelect(item), children: (_a5 = item.ctaLabel) != null ? _a5 : "\uC2DC\uC791\uD558\uAE30" })
1197
- ] }) }));
1198
- }
1199
- function Featured(_a4) {
1200
- var _b = _a4, { item, onSelect } = _b, cardProps = __objRest(_b, ["item", "onSelect"]);
1201
- var _a5;
1202
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_core20.Card, __spreadProps(__spreadValues({ bg: "primary.6", style: { position: "relative" } }, cardProps), { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Stack, { gap: "xl", children: [
1203
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Stack, { gap: "xs", children: [
1204
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Group, { justify: "space-between", align: "flex-start", children: [
1205
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdTitle.Card, { c: "white", children: item.name }),
1206
- item.isPopular && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdBadge.Default, { c: "white", style: { borderColor: "rgba(255,255,255,0.5)" }, children: "\uCD94\uCC9C" })
1207
- ] }),
1208
- item.description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdText.Body, { c: "primary.1", children: item.description })
1209
- ] }),
1210
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Group, { gap: 4, align: "baseline", children: [
1211
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdTitle.Display, { c: "white", children: item.price }),
1212
- item.period && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(SdText.Body, { c: "primary.2", children: [
1213
- "/ ",
1214
- item.period
1215
- ] })
1216
- ] }),
1217
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_core20.Divider, { color: "primary.4" }),
1218
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_core20.Stack, { gap: "sm", children: item.features.map((f, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_core20.Group, { gap: "sm", wrap: "nowrap", children: [
1219
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1220
- import_core20.ThemeIcon,
1221
- {
1222
- size: "xs",
1223
- radius: "xl",
1224
- color: "white",
1225
- variant: f.included ? "filled" : "subtle",
1226
- children: f.included ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_react4.IconCheck, { size: 12, color: "var(--mantine-color-primary-6)" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_react4.IconX, { size: 12, color: "rgba(255,255,255,0.4)" })
1227
- }
1228
- ),
1229
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdText.Body, { fz: "sm", c: f.included ? "white" : "primary.3", children: f.text })
1230
- ] }, i)) }),
1231
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SdButton.White, { fullWidth: true, onClick: () => onSelect == null ? void 0 : onSelect(item), children: (_a5 = item.ctaLabel) != null ? _a5 : "\uC2DC\uC791\uD558\uAE30" })
1232
- ] }) }));
1233
- }
1234
- function Grid2({ items, cols = { base: 1, sm: 2, md: 3 }, onSelect }) {
1235
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_core20.SimpleGrid, { cols, spacing: "xl", style: { alignItems: "stretch" }, children: items.map(
1236
- (item, i) => item.isPopular ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Featured, { item, onSelect }, i) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Default, { item, onSelect }, i)
1237
- ) });
1238
- }
1239
- var SdPricingCard = {
1240
- /** 기본 outlined 카드 */
1241
- Default,
1242
- /** 강조 — primary 배경 */
1243
- Featured,
1244
- /** 가격 그리드 (isPopular 항목은 자동으로 Featured 처리) */
1245
- Grid: Grid2
1246
- };
1247
- var SdPricingCardDefault = SdPricingCard.Default;
1248
- var SdPricingCardFeatured = SdPricingCard.Featured;
1249
- var SdPricingCardGrid = SdPricingCard.Grid;
1250
-
1251
- // ui/molecule/Faq.tsx
1252
- var import_core21 = require("@mantine/core");
1253
- var import_jsx_runtime23 = require("react/jsx-runtime");
1254
- function Default2(_a4) {
1255
- var _b = _a4, { items } = _b, boxProps = __objRest(_b, ["items"]);
1256
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Box, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Accordion, { variant: "separated", radius: "md", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Accordion.Item, { value: String(i), children: [
1257
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Accordion.Control, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SdText.Strong, { fz: "sm", children: item.question }) }),
1258
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Accordion.Panel, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SdText.Body, { fz: "sm", children: item.answer }) })
1259
- ] }, i)) }) }));
1260
- }
1261
- function Filled(_a4) {
1262
- var _b = _a4, { items } = _b, boxProps = __objRest(_b, ["items"]);
1263
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Box, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Accordion, { variant: "filled", radius: "md", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Accordion.Item, { value: String(i), children: [
1264
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Accordion.Control, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SdText.Strong, { fz: "sm", children: item.question }) }),
1265
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_core21.Accordion.Panel, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SdText.Body, { fz: "sm", children: item.answer }) })
1266
- ] }, i)) }) }));
1267
- }
1268
- function WithHeader(_a4) {
1269
- var _b = _a4, { label, title, description, items } = _b, boxProps = __objRest(_b, ["label", "title", "description", "items"]);
1270
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Stack, __spreadProps(__spreadValues({ gap: "xl" }, boxProps), { children: [
1271
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_core21.Stack, { gap: "xs", children: [
1272
- label && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SdText.Eyebrow, { children: label }),
1273
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SdTitle.Section, { children: title }),
1274
- description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SdText.Body, { children: description })
1275
- ] }),
1276
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Default2, { items })
1277
- ] }));
1278
- }
1279
- var SdFaq = {
1280
- /** separated 스타일 아코디언 */
1281
- Default: Default2,
1282
- /** filled 배경 아코디언 */
1283
- Filled,
1284
- /** 헤더 + 아코디언 조합 */
1285
- WithHeader
1286
- };
1287
- var SdFaqDefault = SdFaq.Default;
1288
- var SdFaqFilled = SdFaq.Filled;
1289
- var SdFaqWithHeader = SdFaq.WithHeader;
1290
-
1291
- // ui/molecule/Cta.tsx
1292
- var import_core22 = require("@mantine/core");
1293
- var import_jsx_runtime24 = require("react/jsx-runtime");
1294
- function Banner(_a4) {
1295
- var _b = _a4, {
1296
- label,
1297
- title,
1298
- description,
1299
- primaryLabel = "\uC2DC\uC791\uD558\uAE30",
1300
- secondaryLabel,
1301
- onPrimary,
1302
- onSecondary
1303
- } = _b, boxProps = __objRest(_b, [
1304
- "label",
1305
- "title",
1306
- "description",
1307
- "primaryLabel",
1308
- "secondaryLabel",
1309
- "onPrimary",
1310
- "onSecondary"
1311
- ]);
1312
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Box, __spreadProps(__spreadValues({ bg: "primary.7", py: { base: "xl", md: 80 }, px: { base: "md", md: "xl" } }, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Center, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: "xl", align: "center", maw: 600, children: [
1313
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: "sm", align: "center", children: [
1314
- label && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdText.Eyebrow, { c: "primary.3", children: label }),
1315
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdTitle.Section, { c: "white", ta: "center", children: title }),
1316
- description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdText.Body, { c: "primary.2", ta: "center", children: description })
1317
- ] }),
1318
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Group, { gap: "sm", children: [
1319
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdButton.White, { size: "md", onClick: onPrimary, children: primaryLabel }),
1320
- secondaryLabel && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdButton.Ghost, { size: "md", c: "primary.2", onClick: onSecondary, children: secondaryLabel })
1321
- ] })
1322
- ] }) }) }));
1323
- }
1324
- function Subtle(_a4) {
1325
- var _b = _a4, {
1326
- label,
1327
- title,
1328
- description,
1329
- primaryLabel = "\uC2DC\uC791\uD558\uAE30",
1330
- secondaryLabel,
1331
- onPrimary,
1332
- onSecondary
1333
- } = _b, boxProps = __objRest(_b, [
1334
- "label",
1335
- "title",
1336
- "description",
1337
- "primaryLabel",
1338
- "secondaryLabel",
1339
- "onPrimary",
1340
- "onSecondary"
1341
- ]);
1342
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1343
- import_core22.Box,
1344
- __spreadProps(__spreadValues({
1345
- bg: "primary.0",
1346
- py: { base: "xl", md: 60 },
1347
- px: { base: "md", md: "xl" },
1348
- style: { borderRadius: "var(--mantine-radius-lg)" }
1349
- }, boxProps), {
1350
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_core22.Center, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: "lg", align: "center", maw: 560, children: [
1351
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: "sm", align: "center", children: [
1352
- label && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdText.Eyebrow, { children: label }),
1353
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdTitle.Section, { ta: "center", children: title }),
1354
- description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdText.Body, { ta: "center", children: description })
1355
- ] }),
1356
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Group, { gap: "sm", children: [
1357
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdButton.Primary, { size: "md", onClick: onPrimary, children: primaryLabel }),
1358
- secondaryLabel && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdButton.Outline, { size: "md", onClick: onSecondary, children: secondaryLabel })
1359
- ] })
1360
- ] }) })
1361
- })
1362
- );
1363
- }
1364
- function Inline(_a4) {
1365
- var _b = _a4, {
1366
- label,
1367
- title,
1368
- description,
1369
- primaryLabel = "\uC2DC\uC791\uD558\uAE30",
1370
- secondaryLabel,
1371
- onPrimary,
1372
- onSecondary
1373
- } = _b, boxProps = __objRest(_b, [
1374
- "label",
1375
- "title",
1376
- "description",
1377
- "primaryLabel",
1378
- "secondaryLabel",
1379
- "onPrimary",
1380
- "onSecondary"
1381
- ]);
1382
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1383
- import_core22.Box,
1384
- __spreadProps(__spreadValues({
1385
- py: { base: "xl", md: 48 },
1386
- px: { base: "md", md: "xl" },
1387
- style: {
1388
- borderTop: "1px solid var(--mantine-color-slate-2)",
1389
- borderBottom: "1px solid var(--mantine-color-slate-2)"
1390
- }
1391
- }, boxProps), {
1392
- children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Group, { justify: "space-between", align: "center", gap: "xl", children: [
1393
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Stack, { gap: "xs", style: { flex: 1 }, children: [
1394
- label && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdText.Eyebrow, { children: label }),
1395
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdTitle.Card, { children: title }),
1396
- description && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdText.Sub, { children: description })
1397
- ] }),
1398
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_core22.Group, { gap: "sm", wrap: "nowrap", children: [
1399
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdButton.Primary, { size: "md", onClick: onPrimary, children: primaryLabel }),
1400
- secondaryLabel && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SdButton.Outline, { size: "md", onClick: onSecondary, children: secondaryLabel })
1401
- ] })
1402
- ] })
1403
- })
1404
- );
1405
- }
1406
- var SdCta = {
1407
- /** 다크 배경 전체폭 CTA */
1408
- Banner,
1409
- /** 라이트 박스형 CTA */
1410
- Subtle,
1411
- /** 좌우 분할 인라인 CTA */
1412
- Inline
1413
- };
1414
- var SdCtaBanner = SdCta.Banner;
1415
- var SdCtaSubtle = SdCta.Subtle;
1416
- var SdCtaInline = SdCta.Inline;
1417
-
1418
- // ui/molecule/Solution.tsx
1419
- var import_react2 = require("react");
1420
- var import_core24 = require("@mantine/core");
1421
- var import_link3 = __toESM(require("next/link"));
1422
-
1423
- // ui/molecule/SolutionCard.tsx
1424
- var import_core23 = require("@mantine/core");
1425
- var import_link2 = __toESM(require("next/link"));
1426
- var import_jsx_runtime25 = require("react/jsx-runtime");
1427
- function SolutionCardItem(_a4) {
1428
- var _b = _a4, { item, onSelect } = _b, cardProps = __objRest(_b, ["item", "onSelect"]);
1429
- var _a5, _b2;
1430
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_core23.Card, __spreadProps(__spreadValues({ withBorder: true, h: "100%", style: { display: "flex", flexDirection: "column" } }, cardProps), { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_core23.Stack, { gap: "md", style: { flex: 1 }, children: [
1431
- item.icon,
1432
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SdBadge.Primary, { children: item.category }),
1433
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SdTitle.Card, { children: item.title }),
1434
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SdText.Body, { children: item.description }),
1435
- item.href ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_core23.Button, { variant: "subtle", color: "slate", component: import_link2.default, href: item.href, mt: "auto", children: [
1436
- (_a5 = item.ctaLabel) != null ? _a5 : "\uC790\uC138\uD788 \uBCF4\uAE30",
1437
- " \u2192"
1438
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(SdButton.Ghost, { onClick: () => onSelect == null ? void 0 : onSelect(item), mt: "auto", children: [
1439
- (_b2 = item.ctaLabel) != null ? _b2 : "\uC790\uC138\uD788 \uBCF4\uAE30",
1440
- " \u2192"
1441
- ] })
1442
- ] }) }));
1443
- }
1444
- function Grid3({ items, cols = { base: 1, sm: 2, md: 3 }, onSelect }) {
1445
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_core23.SimpleGrid, { cols, spacing: "xl", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SolutionCardItem, { item, onSelect }, i)) });
1446
- }
1447
- var SdSolutionCard = {
1448
- /** 단일 compact 카드 */
1449
- Item: SolutionCardItem,
1450
- /** 카드 그리드 */
1451
- Grid: Grid3
1452
- };
1453
- var SdSolutionCardItem = SdSolutionCard.Item;
1454
- var SdSolutionCardGrid = SdSolutionCard.Grid;
1455
-
1456
- // ui/molecule/Solution.tsx
1457
- var import_jsx_runtime26 = require("react/jsx-runtime");
1458
- function Filtered({ items, allLabel = "\uC804\uCCB4", cols, onSelect }) {
1459
- const categories = ["all", ...Array.from(new Set(items.map((i) => i.category)))];
1460
- const [active, setActive] = (0, import_react2.useState)("all");
1461
- const filtered = active === "all" ? items : items.filter((i) => i.category === active);
1462
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_core24.Stack, { gap: "xl", children: [
1463
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SdTabs.Pills, { value: active, onChange: (v) => setActive(v != null ? v : "all"), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SdTabs.Pills.List, { children: categories.map((cat) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SdTabs.Pills.Tab, { value: cat, children: cat === "all" ? allLabel : cat }, cat)) }) }),
1464
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SdSolutionCard.Grid, { items: filtered, cols, onSelect })
1465
- ] });
1466
- }
1467
- function List({ items, onSelect }) {
1468
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_core24.Stack, { gap: 0, children: items.map((item, i) => {
1469
- var _a4, _b;
1470
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
1471
- i > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_core24.Divider, {}),
1472
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_core24.Group, { align: "flex-start", py: "lg", gap: "lg", children: [
1473
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_core24.ThemeIcon, { variant: "light", color: "primary", size: "xl", radius: "md", children: item.icon }),
1474
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_core24.Stack, { gap: "xs", style: { flex: 1 }, children: [
1475
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SdBadge.Primary, { children: item.category }),
1476
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SdTitle.Card, { children: item.title }),
1477
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SdText.Body, { children: item.description }),
1478
- item.href ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1479
- import_core24.Button,
1480
- {
1481
- variant: "subtle",
1482
- color: "slate",
1483
- component: import_link3.default,
1484
- href: item.href,
1485
- style: { alignSelf: "flex-start", paddingInline: 0 },
1486
- children: [
1487
- (_a4 = item.ctaLabel) != null ? _a4 : "\uC790\uC138\uD788 \uBCF4\uAE30",
1488
- " \u2192"
1489
- ]
1490
- }
1491
- ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1492
- SdButton.Ghost,
1493
- {
1494
- onClick: () => onSelect == null ? void 0 : onSelect(item),
1495
- style: { alignSelf: "flex-start" },
1496
- children: [
1497
- (_b = item.ctaLabel) != null ? _b : "\uC790\uC138\uD788 \uBCF4\uAE30",
1498
- " \u2192"
1499
- ]
1500
- }
1501
- )
1502
- ] })
1503
- ] })
1504
- ] }, i);
1505
- }) });
1506
- }
1507
- var SdSolution = {
1508
- /** 카테고리 탭 필터 + 카드 그리드 (솔루션 페이지 메인) */
1509
- Filtered,
1510
- /** 수평 리스트 레이아웃 (상세 탐색용) */
1511
- List
1512
- };
1513
- var SdSolutionFiltered = SdSolution.Filtered;
1514
- var SdSolutionList = SdSolution.List;
1515
-
1516
- // ui/molecule/Clients.tsx
1517
- var import_core25 = require("@mantine/core");
1518
- var import_jsx_runtime27 = require("react/jsx-runtime");
1519
- var grayStyle = {
1520
- filter: "grayscale(1) opacity(0.5)",
1521
- transition: "filter 0.25s"
1522
- };
1523
- var colorStyle = {
1524
- filter: "grayscale(0) opacity(1)"
1525
- };
1526
- function LogoImage({ client, height }) {
1527
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Tooltip, { label: client.name, withArrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Anchor, { href: client.url, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1528
- "img",
1529
- {
1530
- src: client.logo,
1531
- alt: client.name,
1532
- style: __spreadValues({
1533
- height,
1534
- width: "auto",
1535
- maxWidth: "100%",
1536
- objectFit: "contain",
1537
- display: "block"
1538
- }, grayStyle),
1539
- onMouseEnter: (e) => Object.assign(e.currentTarget.style, colorStyle),
1540
- onMouseLeave: (e) => Object.assign(e.currentTarget.style, grayStyle)
1541
- }
1542
- ) }) });
1543
- }
1544
- function Grid4({
1545
- items,
1546
- cols = { base: 2, sm: 3, md: 4, lg: 6 },
1547
- logoHeight = 40
1548
- }) {
1549
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.SimpleGrid, { cols, spacing: "xl", children: items.map((client, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1550
- import_core25.Box,
1551
- {
1552
- style: {
1553
- display: "flex",
1554
- alignItems: "center",
1555
- justifyContent: "center",
1556
- padding: "12px 8px",
1557
- minWidth: 0,
1558
- // 그리드 트랙이 이미지 intrinsic width로 밀려 깨지는 것 방지
1559
- overflow: "hidden"
1560
- },
1561
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LogoImage, { client, height: logoHeight })
1562
- },
1563
- i
1564
- )) });
1565
- }
1566
- var KEYFRAME = `@keyframes sd-clients-marquee { from { transform: translateX(0) } to { transform: translateX(-50%) } }`;
1567
- function Marquee({ items, speed = 40, logoHeight = 36, gap = 64 }) {
1568
- const doubled = [...items, ...items];
1569
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_core25.Box, { style: { overflow: "hidden" }, children: [
1570
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("style", { children: KEYFRAME }),
1571
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1572
- import_core25.Box,
1573
- {
1574
- style: {
1575
- display: "flex",
1576
- alignItems: "center",
1577
- gap,
1578
- width: "max-content",
1579
- animation: `sd-clients-marquee ${speed}s linear infinite`
1580
- },
1581
- onMouseEnter: (e) => {
1582
- ;
1583
- e.currentTarget.style.animationPlayState = "paused";
1584
- },
1585
- onMouseLeave: (e) => {
1586
- ;
1587
- e.currentTarget.style.animationPlayState = "running";
1588
- },
1589
- children: doubled.map((client, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LogoImage, { client, height: logoHeight }, i))
1590
- }
1591
- )
1592
- ] });
1593
- }
1594
- var SdClients = {
1595
- /** 반응형 로고 그리드 */
1596
- Grid: Grid4,
1597
- /** 무한 수평 스크롤 띠 — 호버 시 일시정지 */
1598
- Marquee
1599
- };
1600
- var SdClientsGrid = Grid4;
1601
- var SdClientsMarquee = Marquee;
1602
-
1603
- // ui/molecule/Map.tsx
1604
- var import_react3 = require("react");
1605
- var import_core26 = require("@mantine/core");
1606
- var import_jsx_runtime28 = require("react/jsx-runtime");
1607
- function MapFrame({ address, height }) {
1608
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_core26.Stack, { gap: "xs", children: [
1609
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Box, { style: { borderRadius: "var(--mantine-radius-md)", overflow: "hidden", height }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1610
- "iframe",
1611
- {
1612
- src: address.embbedUrl,
1613
- width: "100%",
1614
- height: "100%",
1615
- style: { border: 0, display: "block" },
1616
- allowFullScreen: true,
1617
- loading: "lazy",
1618
- referrerPolicy: "no-referrer-when-downgrade",
1619
- title: address.label
1620
- }
1621
- ) }),
1622
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(SdText.Sub, { children: [
1623
- "[",
1624
- address.label,
1625
- "] ",
1626
- address.address
1627
- ] })
1628
- ] });
1629
- }
1630
- function Single(_a4) {
1631
- var _b = _a4, { address, height = 400 } = _b, boxProps = __objRest(_b, ["address", "height"]);
1632
- if (!address.embbedUrl) return null;
1633
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Box, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MapFrame, { address, height }) }));
1634
- }
1635
- function Tabs2({ addresses, height = 400 }) {
1636
- var _a4, _b, _c;
1637
- const mapped = addresses.filter((a) => a.embbedUrl);
1638
- const [active, setActive] = (0, import_react3.useState)((_b = (_a4 = mapped[0]) == null ? void 0 : _a4.label) != null ? _b : "");
1639
- if (mapped.length === 0) return null;
1640
- if (mapped.length === 1) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MapFrame, { address: mapped[0], height });
1641
- const current = (_c = mapped.find((a) => a.label === active)) != null ? _c : mapped[0];
1642
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_core26.Stack, { gap: "md", children: [
1643
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SdTabs.Pills, { value: active, onChange: (v) => setActive(v != null ? v : mapped[0].label), children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SdTabs.Pills.List, { children: mapped.map((addr) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SdTabs.Pills.Tab, { value: addr.label, children: addr.label }, addr.label)) }) }),
1644
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(MapFrame, { address: current, height })
1645
- ] });
1646
- }
1647
- var SdMap = {
1648
- /** 단일 주소 지도 — embbedUrl 없으면 null 반환 */
1649
- Single,
1650
- /** 여러 주소 탭 전환 지도 — embbedUrl 있는 항목만 표시 */
1651
- Tabs: Tabs2
1652
- };
1653
- var SdMapSingle = Single;
1654
- var SdMapTabs = Tabs2;
1655
-
1656
- // ui/molecule/Breadcrumb.tsx
1657
- var import_core27 = require("@mantine/core");
1658
- var import_navigation = require("next/navigation");
1659
- var import_icons_react5 = require("@tabler/icons-react");
1660
-
1661
- // ui/template/NavProvider.tsx
1662
- var import_react4 = require("react");
1663
- var import_jsx_runtime29 = require("react/jsx-runtime");
1664
- var NavContext = (0, import_react4.createContext)([]);
1665
- function NavProvider({
1666
- children,
1667
- navItems
1668
- }) {
1669
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(NavContext.Provider, { value: navItems, children });
1670
- }
1671
- function useNav() {
1672
- return (0, import_react4.useContext)(NavContext);
1673
- }
1674
-
1675
- // ui/molecule/Breadcrumb.tsx
1676
- var import_jsx_runtime30 = require("react/jsx-runtime");
1677
- function normalizePath(href) {
1678
- if (!href) return "";
1679
- const trimmed = href.replace(/\/+$/, "");
1680
- return trimmed === "" ? "/" : trimmed;
1681
- }
1682
- function buildTrail(navItems, currentHref) {
1683
- const target = normalizePath(currentHref);
1684
- const byId = new Map(navItems.map((item) => [item.id, item]));
1685
- let current = navItems.find((item) => normalizePath(item.href) === target);
1686
- if (!current) {
1687
- current = navItems.filter((item) => item.href && target.startsWith(normalizePath(item.href) + "/")).sort((a, b) => normalizePath(b.href).length - normalizePath(a.href).length)[0];
1688
- }
1689
- if (!current) return [];
1690
- const trail = [];
1691
- const seen = /* @__PURE__ */ new Set();
1692
- let node = current;
1693
- while (node && !seen.has(node.id)) {
1694
- seen.add(node.id);
1695
- trail.unshift(node);
1696
- node = node.parentId != null ? byId.get(node.parentId) : void 0;
1697
- }
1698
- return trail;
1699
- }
1700
- function SdBreadcrumb(_a4) {
1701
- var _b = _a4, {
1702
- navItems: navItemsProp,
1703
- currentHref,
1704
- homeHref = "/",
1705
- homeLabel = "\uD648"
1706
- } = _b, boxProps = __objRest(_b, [
1707
- "navItems",
1708
- "currentHref",
1709
- "homeHref",
1710
- "homeLabel"
1711
- ]);
1712
- var _a5;
1713
- const navFromContext = useNav();
1714
- const navItems = navItemsProp != null ? navItemsProp : navFromContext;
1715
- const pathname = (0, import_navigation.usePathname)();
1716
- const trail = buildTrail(navItems, (_a5 = currentHref != null ? currentHref : pathname) != null ? _a5 : "");
1717
- if (navItems.length === 0) return;
1718
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_core27.Box, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
1719
- import_core27.Breadcrumbs,
1720
- {
1721
- separator: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_icons_react5.IconChevronRight, { size: 14, stroke: 2, color: "var(--mantine-color-slate-4)" }),
1722
- separatorMargin: "xs",
1723
- children: [
1724
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1725
- SdLink.Sub,
1726
- {
1727
- href: homeHref,
1728
- "aria-label": homeLabel,
1729
- style: { display: "inline-flex", alignItems: "center" },
1730
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_icons_react5.IconHome, { size: 16, stroke: 2 })
1731
- }
1732
- ),
1733
- trail.map((item, i) => {
1734
- const isLast = i === trail.length - 1;
1735
- return isLast ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SdLink.Body, { children: item.label }, item.id) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SdLink.Sub, { href: item.href, children: item.label }, item.id);
1736
- })
1737
- ]
1738
- }
1739
- ) }));
1740
- }
1741
-
1742
- // ui/organism/HeroCarousel.tsx
1743
- var import_carousel = require("@mantine/carousel");
1744
- var import_core28 = require("@mantine/core");
1745
- var import_icons_react6 = require("@tabler/icons-react");
1746
- var import_jsx_runtime31 = require("react/jsx-runtime");
1747
- var variantMap = {
1748
- primary: SdButton.Primary,
1749
- secondary: SdButton.Secondary,
1750
- outline: SdButton.Outline,
1751
- white: SdButton.White
1752
- };
1753
- function CtaButton({ cta }) {
1754
- var _a4;
1755
- const Button3 = variantMap[(_a4 = cta.variant) != null ? _a4 : "primary"];
1756
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core28.Anchor, { href: cta.href, underline: "never", children: cta.icon ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button3, { size: "md", rightSection: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_icons_react6.IconArrowNarrowRight, {}), children: cta.label }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button3, { size: "md", children: cta.label }) });
1757
- }
1758
- function HeroCarousel({ slides, children }) {
1759
- if (children) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_jsx_runtime31.Fragment, { children });
1760
- const filterdSlides = filterAndSort(slides);
1761
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_carousel.Carousel, { withIndicators: true, height: "60svh", children: filterdSlides.map((slide, i) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_carousel.Carousel.Slide, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1762
- import_core28.Box,
1763
- {
1764
- style: {
1765
- height: "100%",
1766
- backgroundImage: `linear-gradient(rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.45)), url(${slide.image})`,
1767
- backgroundSize: "cover",
1768
- backgroundPosition: "center",
1769
- display: "flex",
1770
- alignItems: "center",
1771
- justifyContent: "center"
1772
- },
1773
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_core28.Stack, { align: "center", style: { textAlign: "center", maxWidth: 780 }, px: "xl", children: [
1774
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1775
- SdTextBox.Hero,
1776
- {
1777
- title: slide.title,
1778
- description: slide.description,
1779
- ta: "center",
1780
- align: "center"
1781
- }
1782
- ),
1783
- slide.ctas && slide.ctas.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_core28.Group, { gap: "sm", mt: "md", children: slide.ctas.map((cta, i2) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(CtaButton, { cta }, cta.href)) })
1784
- ] })
1785
- }
1786
- ) }, i)) });
1787
- }
1788
-
1789
- // ui/organism/Header.tsx
1790
- var import_core29 = require("@mantine/core");
1791
- var import_icons_react7 = require("@tabler/icons-react");
1792
- var import_hooks = require("@mantine/hooks");
1793
- var import_jsx_runtime32 = require("react/jsx-runtime");
1794
- var BAR_HEIGHT = 60;
1795
- var MAX_DEPTH = 3;
1796
- var NAV_LINK_STYLES = {
1797
- label: {
1798
- fontWeight: textStyles.Body.fw,
1799
- fontSize: `var(--mantine-font-size-${textStyles.Body.fz})`,
1800
- color: toCssColor(textStyles.Body.c),
1801
- lineHeight: textStyles.Body.lh
1802
- }
1803
- };
1804
- function useNavTree(navItems) {
1805
- const visibleItems = filterAndSort(navItems);
1806
- return {
1807
- topItems: visibleItems.filter((item) => !item.parentId),
1808
- childrenOf: (parentId) => visibleItems.filter((item) => item.parentId === parentId),
1809
- hasAnyChildren: visibleItems.some((item) => item.parentId)
1810
- };
1811
- }
1812
- function MobileNavNode({ item, depth, childrenOf, close }) {
1813
- const kids = depth < MAX_DEPTH ? childrenOf(item.id) : [];
1814
- if (kids.length === 0) {
1815
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Box, { px: "sm", py: 8, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: item.href, onClick: close, children: item.label }) });
1816
- }
1817
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1818
- import_core29.NavLink,
1819
- {
1820
- label: item.label,
1821
- styles: NAV_LINK_STYLES,
1822
- component: item.href ? "a" : "button",
1823
- href: item.href,
1824
- childrenOffset: 28,
1825
- children: kids.map((kid) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1826
- MobileNavNode,
1827
- {
1828
- item: kid,
1829
- depth: depth + 1,
1830
- childrenOf,
1831
- close
1832
- },
1833
- kid.id
1834
- ))
1835
- }
1836
- );
1837
- }
1838
- function MobileNav({ opened, close, topItems, childrenOf, loginFlag }) {
1839
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Drawer, { opened, onClose: close, hiddenFrom: "sm", size: "xs", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Stack, { gap: 0, children: [
1840
- topItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(MobileNavNode, { item, depth: 1, childrenOf, close }, item.id)),
1841
- loginFlag && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Stack, { gap: "xs", mt: "md", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1842
- ] }) });
1843
- }
1844
- function MegaHeader({ navItems, loginFlag, logoSize }) {
1845
- const [opened, { toggle, close }] = (0, import_hooks.useDisclosure)();
1846
- const { topItems, childrenOf, hasAnyChildren } = useNavTree(navItems);
1847
- const { hovered, ref: hoverRef } = (0, import_hooks.useHover)();
1848
- const { focused, ref: focusRef } = (0, import_hooks.useFocusWithin)();
1849
- const rootRef = (0, import_hooks.useMergedRef)(hoverRef, focusRef);
1850
- const expanded = hasAnyChildren && (hovered || focused);
1851
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
1852
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1853
- import_core29.Box,
1854
- {
1855
- ref: rootRef,
1856
- pos: "relative",
1857
- bg: "var(--mantine-color-body)",
1858
- style: {
1859
- boxShadow: expanded ? "var(--mantine-shadow-md)" : void 0,
1860
- borderBottom: expanded ? "1px solid var(--mantine-color-slate-2)" : void 0,
1861
- transition: "box-shadow 0.15s"
1862
- },
1863
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { justify: "space-between", align: "flex-start", wrap: "nowrap", children: [
1864
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { h: BAR_HEIGHT, align: "center", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Logo, { size: logoSize }) }),
1865
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { gap: "xl", align: "flex-start", wrap: "nowrap", visibleFrom: "sm", children: topItems.map((item) => {
1866
- const kids = childrenOf(item.id);
1867
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Stack, { gap: 0, align: "center", children: [
1868
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { h: BAR_HEIGHT, align: "center", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: item.href, children: item.label }) }),
1869
- kids.length > 0 && /*
1870
- Mantine Collapse를 쓰지 않는다 — 접힐 때 display:none이 되어
1871
- 하위 링크가 폭 계산에서 빠졌다가 펼칠 때 다시 들어오면서
1872
- 컬럼 폭(=상단 nav 간격)이 튄다.
1873
- height 0 + overflow hidden은 폭 기여를 유지하므로 간격이 고정된다.
1874
- visibility:hidden이 접힌 상태의 링크를 탭 순서에서도 빼준다.
1875
- */
1876
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1877
- import_core29.Box,
1878
- {
1879
- "aria-hidden": !expanded,
1880
- style: {
1881
- height: expanded ? "auto" : 0,
1882
- overflow: "hidden",
1883
- opacity: expanded ? 1 : 0,
1884
- visibility: expanded ? "visible" : "hidden",
1885
- transition: "opacity 0.15s ease"
1886
- },
1887
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Stack, { gap: "xs", pt: 4, pb: "lg", align: "center", children: kids.map((kid) => {
1888
- const grandkids = childrenOf(kid.id);
1889
- if (grandkids.length === 0) {
1890
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: kid.href, children: kid.label }, kid.id);
1891
- }
1892
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Stack, { gap: 2, align: "center", children: [
1893
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: kid.href, children: kid.label }),
1894
- grandkids.map((gk) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Sub, { href: gk.href, children: gk.label }, gk.id))
1895
- ] }, kid.id);
1896
- }) })
1897
- }
1898
- )
1899
- ] }, item.id);
1900
- }) }),
1901
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { h: BAR_HEIGHT, align: "center", gap: "sm", wrap: "nowrap", children: [
1902
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Burger, { hiddenFrom: "sm", opened, onClick: toggle }),
1903
- loginFlag && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { gap: "sm", visibleFrom: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1904
- ] })
1905
- ] }) })
1906
- }
1907
- ),
1908
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1909
- MobileNav,
1910
- {
1911
- opened,
1912
- close,
1913
- topItems,
1914
- childrenOf,
1915
- loginFlag
1916
- }
1917
- )
1918
- ] });
1919
- }
1920
- function renderMenuLeaf(item) {
1921
- return item.href ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Item, { component: "a", href: item.href, children: item.label }, item.id) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Label, { children: item.label }, item.id);
1922
- }
1923
- function SimpleHeader({ navItems, loginFlag, logoSize }) {
1924
- const [opened, { toggle, close }] = (0, import_hooks.useDisclosure)();
1925
- const { topItems, childrenOf } = useNavTree(navItems);
1926
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
1927
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Box, { bg: "var(--mantine-color-body)", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { h: BAR_HEIGHT, justify: "space-between", align: "center", wrap: "nowrap", children: [
1928
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Logo, { size: logoSize }),
1929
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { gap: "xl", align: "center", wrap: "nowrap", visibleFrom: "sm", children: topItems.map((item) => {
1930
- const kids = childrenOf(item.id);
1931
- if (kids.length === 0) {
1932
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: item.href, children: item.label }, item.id);
1933
- }
1934
- return (
1935
- /*
1936
- trigger="click-hover" — 마우스는 hover로, 키보드/터치는 click으로 연다.
1937
- Menu.Target은 ref를 받을 수 있는 단일 엘리먼트여야 하므로
1938
- SdLink/SdText가 아니라 Box를 타깃으로 두고 라벨을 그 안에 넣는다.
1939
- */
1940
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1941
- import_core29.Menu,
1942
- {
1943
- trigger: "click-hover",
1944
- openDelay: 50,
1945
- closeDelay: 120,
1946
- position: "bottom",
1947
- offset: 12,
1948
- shadow: "md",
1949
- radius: "md",
1950
- withinPortal: true,
1951
- children: [
1952
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Target, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Box, { style: { cursor: "pointer" }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { gap: 4, align: "center", wrap: "nowrap", children: [
1953
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: item.href, children: item.label }),
1954
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_icons_react7.IconChevronDown, { size: 14, stroke: 2 })
1955
- ] }) }) }),
1956
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Dropdown, { children: kids.map((kid) => {
1957
- const grandkids = childrenOf(kid.id);
1958
- if (grandkids.length > 0) {
1959
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Menu.Sub, { children: [
1960
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Sub.Target, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Sub.Item, { children: kid.label }) }),
1961
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Sub.Dropdown, { children: grandkids.map(renderMenuLeaf) })
1962
- ] }, kid.id);
1963
- }
1964
- return renderMenuLeaf(kid);
1965
- }) })
1966
- ]
1967
- },
1968
- item.id
1969
- )
1970
- );
1971
- }) }),
1972
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { align: "center", gap: "sm", wrap: "nowrap", children: [
1973
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Burger, { hiddenFrom: "sm", opened, onClick: toggle }),
1974
- loginFlag && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { gap: "sm", visibleFrom: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1975
- ] })
1976
- ] }) }) }),
1977
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1978
- MobileNav,
1979
- {
1980
- opened,
1981
- close,
1982
- topItems,
1983
- childrenOf,
1984
- loginFlag
1985
- }
1986
- )
1987
- ] });
1988
- }
1989
- function PanelHeader({ navItems, loginFlag, logoSize }) {
1990
- const [opened, { toggle, close }] = (0, import_hooks.useDisclosure)();
1991
- const { topItems, childrenOf } = useNavTree(navItems);
1992
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
1993
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Box, { bg: "var(--mantine-color-body)", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { h: BAR_HEIGHT, justify: "space-between", align: "center", wrap: "nowrap", children: [
1994
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Logo, { size: logoSize }),
1995
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { gap: "xl", align: "center", wrap: "nowrap", visibleFrom: "sm", children: topItems.map((item) => {
1996
- const kids = childrenOf(item.id);
1997
- if (kids.length === 0) {
1998
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: item.href, children: item.label }, item.id);
1999
- }
2000
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
2001
- import_core29.Menu,
2002
- {
2003
- trigger: "click-hover",
2004
- openDelay: 50,
2005
- closeDelay: 120,
2006
- position: "bottom",
2007
- offset: 12,
2008
- shadow: "md",
2009
- radius: "md",
2010
- withinPortal: true,
2011
- children: [
2012
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Target, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Box, { style: { cursor: "pointer" }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { gap: 4, align: "center", wrap: "nowrap", children: [
2013
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: item.href, children: item.label }),
2014
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_icons_react7.IconChevronDown, { size: 14, stroke: 2 })
2015
- ] }) }) }),
2016
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Menu.Dropdown, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Stack, { gap: "xs", p: "xs", children: kids.map((kid) => {
2017
- const grandkids = childrenOf(kid.id);
2018
- if (grandkids.length === 0) {
2019
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: kid.href, children: kid.label }, kid.id);
2020
- }
2021
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Stack, { gap: 2, children: [
2022
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Body, { href: kid.href, children: kid.label }),
2023
- grandkids.map((gk) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdLink.Sub, { href: gk.href, pl: "sm", children: gk.label }, gk.id))
2024
- ] }, kid.id);
2025
- }) }) })
2026
- ]
2027
- },
2028
- item.id
2029
- );
2030
- }) }),
2031
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_core29.Group, { align: "center", gap: "sm", wrap: "nowrap", children: [
2032
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Burger, { hiddenFrom: "sm", opened, onClick: toggle }),
2033
- loginFlag && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core29.Group, { gap: "sm", visibleFrom: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
2034
- ] })
2035
- ] }) }) }),
2036
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2037
- MobileNav,
2038
- {
2039
- opened,
2040
- close,
2041
- topItems,
2042
- childrenOf,
2043
- loginFlag
2044
- }
2045
- )
2046
- ] });
2047
- }
2048
- var SdHeader = Object.assign(MegaHeader, {
2049
- Mega: MegaHeader,
2050
- Simple: SimpleHeader,
2051
- Panel: PanelHeader
2052
- });
2053
- var SdHeaderMega = MegaHeader;
2054
- var SdHeaderSimple = SimpleHeader;
2055
- var SdHeaderPanel = PanelHeader;
2056
-
2057
- // ui/organism/Footer.tsx
2058
- var import_core30 = require("@mantine/core");
2059
- var import_icons_react8 = require("@tabler/icons-react");
2060
- var import_jsx_runtime33 = require("react/jsx-runtime");
2061
- function FooterNavColumns({ items }) {
2062
- const topLevel = items.filter((item) => !item.parentId);
2063
- const getChildren = (parentId) => items.filter((item) => item.parentId === parentId);
2064
- const CHILD_THRESH = 4;
2065
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, { children: topLevel.map((group) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Grid.Col, { span: { base: 6, sm: 4, md: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core30.Stack, { gap: "xs", children: [
2066
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdLink.Sub, { href: group.href, children: group.label }, group.id),
2067
- getChildren(group.id).map((link, id) => {
2068
- if (id >= CHILD_THRESH) return;
2069
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdLink.Hint, { href: link.href, children: link.label }, link.id);
2070
- })
2071
- ] }) }, group.id)) });
2072
- }
2073
- var SOCIAL_ICONS = {
2074
- x: import_icons_react8.IconBrandX,
2075
- youtube: import_icons_react8.IconBrandYoutube,
2076
- instagram: import_icons_react8.IconBrandInstagram,
2077
- facebook: import_icons_react8.IconBrandFacebook,
2078
- linkedin: import_icons_react8.IconBrandLinkedin,
2079
- github: import_icons_react8.IconBrandGithub,
2080
- blog: import_icons_react8.IconWorld
2081
- };
2082
- function FooterSocials({ items }) {
2083
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Group, { gap: 0, wrap: "nowrap", children: items.map((item) => {
2084
- var _a4, _b;
2085
- const Icon = (_a4 = SOCIAL_ICONS[item.platform]) != null ? _a4 : import_icons_react8.IconWorld;
2086
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2087
- import_core30.ActionIcon,
2088
- {
2089
- component: "a",
2090
- href: item.url,
2091
- target: "_blank",
2092
- rel: "noreferrer",
2093
- size: "lg",
2094
- color: "gray",
2095
- variant: "subtle",
2096
- "aria-label": (_b = item.label) != null ? _b : item.platform,
2097
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Icon, { size: 18, stroke: 1.5 })
2098
- },
2099
- item.url
2100
- );
2101
- }) });
2102
- }
2103
- function InfoCell({ label, children }) {
2104
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core30.Group, { gap: 6, wrap: "nowrap", align: "baseline", children: [
2105
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdText.Sub, { c: "slate.4", style: { whiteSpace: "nowrap" }, children: label }),
2106
- typeof children === "string" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdText.Sub, { children }) : children
2107
- ] });
2108
- }
2109
- function FooterCompanyInfo({ company }) {
2110
- const sortedAddresses = [...company.addresses].sort((a, b) => a.order - b.order);
2111
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core30.SimpleGrid, { cols: { base: 2, sm: 2, md: 1 }, spacing: "md", verticalSpacing: 0, children: [
2112
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(InfoCell, { label: "\uC0C1\uD638", children: company.name }),
2113
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(InfoCell, { label: "\uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638", children: company.registrationNumber }),
2114
- sortedAddresses.map((addr) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(InfoCell, { label: addr.label, children: addr.address }, addr.label)),
2115
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(InfoCell, { label: "Tel", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdLink.Sub, { href: `tel:${company.tel}`, children: company.tel }) }),
2116
- company.fax && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(InfoCell, { label: "Fax", children: company.fax }),
2117
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(InfoCell, { label: "Email", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdLink.Sub, { href: `mailto:${company.email}`, children: company.email }) })
2118
- ] });
2119
- }
2120
- function SdFooter({ company, navItems, policyLinks, description, logoSize = "sm" }) {
2121
- const visibleNav = filterAndSort(navItems);
2122
- const visiblePolicy = filterAndSort(policyLinks);
2123
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Box, { component: "footer", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdContainer, { py: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core30.Stack, { children: [
2124
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Logo, { size: logoSize }),
2125
- description && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(SdText.Sub, { children: description }),
2126
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core30.Flex, { direction: { base: "column", md: "row" }, gap: 48, align: "flex-start", children: [
2127
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Box, { flex: { base: "0 0 auto", md: "1 1 0" }, w: { base: "100%", md: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FooterCompanyInfo, { company }) }),
2128
- visibleNav.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Box, { flex: { base: "0 0 auto", md: "2 1 0" }, w: { base: "100%", md: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Grid, { style: { "--grid-gutter": "24px" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FooterNavColumns, { items: visibleNav }) }) })
2129
- ] }),
2130
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Divider, {}),
2131
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core30.Group, { justify: "space-between", wrap: "wrap", gap: "xs", children: [
2132
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(SdText.Sub, { children: [
2133
- "\xA9 ",
2134
- company.copyrightYear,
2135
- " ",
2136
- t(company.name),
2137
- ". All rights reserved."
2138
- ] }),
2139
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_core30.Group, { gap: "lg", wrap: "wrap", children: [
2140
- visiblePolicy.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_core30.Group, { gap: "lg", children: visiblePolicy.map((item) => {
2141
- const Link4 = item.highlight ? SdLink.Body : SdLink.Sub;
2142
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Link4, { href: item.href, children: item.label }, item.id);
2143
- }) }),
2144
- company.socials && company.socials.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FooterSocials, { items: company.socials })
2145
- ] })
2146
- ] })
2147
- ] }) }) });
2148
- }
2149
-
2150
- // ui/organism/FeatureSection.tsx
2151
- var import_core31 = require("@mantine/core");
2152
- var import_jsx_runtime34 = require("react/jsx-runtime");
2153
- function SdFeatureSection(_a4) {
2154
- var _b = _a4, {
2155
- label,
2156
- title,
2157
- description,
2158
- items,
2159
- cols,
2160
- py = 0
2161
- } = _b, boxProps = __objRest(_b, [
2162
- "label",
2163
- "title",
2164
- "description",
2165
- "items",
2166
- "cols",
2167
- "py"
2168
- ]);
2169
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SdContainer, __spreadProps(__spreadValues({ py }, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_core31.Stack, { gap: "xl", children: [
2170
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2171
- SdTextBox.Section,
2172
- {
2173
- label,
2174
- title,
2175
- description,
2176
- maxDescWidth: 520,
2177
- ta: "center",
2178
- align: "center"
2179
- }
2180
- ),
2181
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SdFeatures, { items, cols })
2182
- ] }) }));
2183
- }
2184
-
2185
- // ui/organism/TimelineSection.tsx
2186
- var import_core32 = require("@mantine/core");
2187
- var import_jsx_runtime35 = require("react/jsx-runtime");
2188
- function SdTimelineSection(_a4) {
2189
- var _b = _a4, {
2190
- label,
2191
- title,
2192
- description,
2193
- items,
2194
- py = 0
2195
- } = _b, boxProps = __objRest(_b, [
2196
- "label",
2197
- "title",
2198
- "description",
2199
- "items",
2200
- "py"
2201
- ]);
2202
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core32.Center, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_core32.Stack, __spreadProps(__spreadValues({ py, gap: "md" }, boxProps), { children: [
2203
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(SdTextBox.Section, { label, title, description }),
2204
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_core32.Center, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(SdTimeline, { items }) })
2205
- ] })) });
2206
- }
2207
-
2208
- // ui/organism/StepsSection.tsx
2209
- var import_core33 = require("@mantine/core");
2210
- var import_jsx_runtime36 = require("react/jsx-runtime");
2211
- function SdStepsSection(_a4) {
2212
- var _b = _a4, {
2213
- label,
2214
- title,
2215
- description,
2216
- items,
2217
- py = 0
2218
- } = _b, boxProps = __objRest(_b, [
2219
- "label",
2220
- "title",
2221
- "description",
2222
- "items",
2223
- "py"
2224
- ]);
2225
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SdContainer, __spreadProps(__spreadValues({ py }, boxProps), { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_core33.Stack, { gap: "xl", children: [
2226
- (label || title || description) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SdTextBox.Section, { label, title, description }),
2227
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SdSteps.Bubble, { items })
2228
- ] }) }));
2229
- }
2230
-
2231
- // ui/organism/ErrorView.tsx
2232
- var import_core34 = require("@mantine/core");
2233
- var import_jsx_runtime37 = require("react/jsx-runtime");
2234
- function StatusCode({ code }) {
2235
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2236
- import_core34.Text,
2237
- {
2238
- fz: 160,
2239
- fw: 900,
2240
- c: "slate.1",
2241
- lh: 1,
2242
- style: { userSelect: "none", letterSpacing: "-0.04em" },
2243
- "aria-hidden": true,
2244
- children: code
2245
- }
2246
- );
2247
- }
2248
- function Page({ error, onReset, onHome }) {
2249
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core34.Center, { mih: "60vh", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core34.Stack, { align: "center", gap: "lg", ta: "center", children: [
2250
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(StatusCode, { code: "500" }),
2251
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core34.Stack, { gap: "sm", align: "center", children: [
2252
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdTitle.Section, { children: "\uC11C\uBC84\uC5D0\uC11C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4" }),
2253
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdText.Body, { maw: 480, children: "\uC608\uAE30\uCE58 \uC54A\uC740 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694." })
2254
- ] }),
2255
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core34.Group, { gap: "sm", justify: "center", children: [
2256
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdButton.Primary, { onClick: onReset, children: "\uB2E4\uC2DC \uC2DC\uB3C4" }),
2257
- onHome && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdButton.Ghost, { onClick: onHome, children: "\uD648\uC73C\uB85C" })
2258
- ] })
2259
- ] }) }) });
2260
- }
2261
- function NotFound({
2262
- title = "\uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",
2263
- description = "\uC694\uCCAD\uD558\uC2E0 \uD398\uC774\uC9C0\uAC00 \uC874\uC7AC\uD558\uC9C0 \uC54A\uAC70\uB098 \uC774\uB3D9\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
2264
- onHome = () => {
2265
- window.location.href = "/";
2266
- },
2267
- onBack = () => window.history.back()
2268
- }) {
2269
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_core34.Center, { mih: "60vh", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core34.Stack, { align: "center", gap: "lg", ta: "center", children: [
2270
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(StatusCode, { code: "404" }),
2271
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core34.Stack, { gap: "sm", align: "center", children: [
2272
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdTitle.Section, { children: title }),
2273
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdText.Body, { maw: 480, children: description })
2274
- ] }),
2275
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_core34.Group, { gap: "sm", justify: "center", children: [
2276
- onHome && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdButton.Primary, { onClick: onHome, children: "\uD648\uC73C\uB85C" }),
2277
- onBack && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(SdButton.Ghost, { onClick: onBack, children: "\uB4A4\uB85C \uAC00\uAE30" })
2278
- ] })
2279
- ] }) }) });
2280
- }
2281
- var SdErrorView = {
2282
- /** app/error.tsx — 서버/렌더링 오류 + 재시도 버튼 */
2283
- Page,
2284
- /** app/not-found.tsx — 404 Not Found */
2285
- NotFound
2286
- };
2287
- var SdErrorViewPage = SdErrorView.Page;
2288
- var SdErrorViewNotFound = SdErrorView.NotFound;
2289
-
2290
- // ui/organism/LoginView.tsx
2291
- var import_core35 = require("@mantine/core");
2292
- var import_icons_react9 = require("@tabler/icons-react");
2293
-
2294
- // ui/surface.ts
2295
- var brandSurface = {
2296
- background: `
2297
- radial-gradient(90% 120% at 12% 0%, var(--mantine-color-primary-7) 0%, transparent 58%),
2298
- radial-gradient(70% 100% at 100% 100%, var(--mantine-color-primary-9) 0%, transparent 55%),
2299
- var(--mantine-color-slate-9)`
2300
- };
2301
- var brandDotTexture = {
2302
- backgroundImage: "radial-gradient(rgba(255,255,255,0.10) 1px, transparent 1px)",
2303
- backgroundSize: "18px 18px",
2304
- maskImage: "linear-gradient(180deg, rgba(0,0,0,0.9) 0%, transparent 70%)",
2305
- WebkitMaskImage: "linear-gradient(180deg, rgba(0,0,0,0.9) 0%, transparent 70%)",
2306
- pointerEvents: "none"
2307
- };
2308
-
2309
- // ui/organism/LoginView.tsx
2310
- var import_jsx_runtime38 = require("react/jsx-runtime");
2311
- var SOCIAL_META = {
2312
- google: { Icon: import_icons_react9.IconBrandGoogle, label: "\uAD6C\uAE00\uB85C \uB85C\uADF8\uC778" },
2313
- kakao: { Icon: import_icons_react9.IconBrandKakaoTalk, label: "\uCE74\uCE74\uC624\uB85C \uB85C\uADF8\uC778" },
2314
- naver: { Icon: import_icons_react9.IconCircleLetterN, label: "\uB124\uC774\uBC84\uB85C \uB85C\uADF8\uC778" },
2315
- apple: { Icon: import_icons_react9.IconBrandApple, label: "\uC560\uD50C\uB85C \uB85C\uADF8\uC778" },
2316
- github: { Icon: import_icons_react9.IconBrandGithub, label: "\uAE43\uD5C8\uBE0C\uB85C \uB85C\uADF8\uC778" }
2317
- };
2318
- function LoginForm({
2319
- onSubmit,
2320
- loading,
2321
- error,
2322
- submitLabel = "\uB85C\uADF8\uC778",
2323
- withRemember = true,
2324
- findPasswordHref,
2325
- signUpHref,
2326
- socials,
2327
- children
2328
- }) {
2329
- function handleSubmit(event) {
2330
- var _a4, _b;
2331
- event.preventDefault();
2332
- const data = new FormData(event.currentTarget);
2333
- onSubmit == null ? void 0 : onSubmit({
2334
- email: String((_a4 = data.get("email")) != null ? _a4 : ""),
2335
- password: String((_b = data.get("password")) != null ? _b : ""),
2336
- remember: data.get("remember") === "on"
2337
- });
2338
- }
2339
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("form", { onSubmit: handleSubmit, noValidate: true, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core35.Stack, { gap: "md", children: [
2340
- error && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SdText.Error, { children: error }),
2341
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2342
- SdInput.Email,
2343
- {
2344
- name: "email",
2345
- label: "\uC774\uBA54\uC77C",
2346
- placeholder: "name@example.com",
2347
- autoComplete: "email",
2348
- required: true
2349
- }
2350
- ),
2351
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2352
- SdInput.Password,
2353
- {
2354
- name: "password",
2355
- label: "\uBE44\uBC00\uBC88\uD638",
2356
- placeholder: "\uBE44\uBC00\uBC88\uD638\uB97C \uC785\uB825\uD558\uC138\uC694",
2357
- autoComplete: "current-password",
2358
- required: true
2359
- }
2360
- ),
2361
- (withRemember || findPasswordHref) && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core35.Group, { justify: "space-between", align: "center", wrap: "nowrap", children: [
2362
- withRemember ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Checkbox, { name: "remember", size: "xs", label: "\uC790\uB3D9 \uB85C\uADF8\uC778" }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", {}),
2363
- findPasswordHref && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SdLink.Sub, { href: findPasswordHref, children: "\uBE44\uBC00\uBC88\uD638\uB97C \uC78A\uC73C\uC168\uB098\uC694?" })
2364
- ] }),
2365
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2366
- SdButton.Primary,
2367
- {
2368
- type: "submit",
2369
- fullWidth: true,
2370
- loading,
2371
- leftSection: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_icons_react9.IconLogin2, { size: 16 }),
2372
- children: submitLabel
2373
- }
2374
- ),
2375
- socials && socials.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
2376
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Divider, { label: "\uB610\uB294", labelPosition: "center" }),
2377
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Stack, { gap: "xs", children: socials.map((social) => {
2378
- var _a4;
2379
- const { Icon, label } = SOCIAL_META[social.provider];
2380
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2381
- SdButton.Outline,
2382
- {
2383
- color: "slate",
2384
- fullWidth: true,
2385
- type: "button",
2386
- onClick: social.onClick,
2387
- leftSection: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { size: 16 }),
2388
- children: (_a4 = social.label) != null ? _a4 : label
2389
- },
2390
- social.provider
2391
- );
2392
- }) })
2393
- ] }),
2394
- signUpHref && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core35.Group, { gap: 6, justify: "center", children: [
2395
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SdText.Sub, { children: "\uC544\uC9C1 \uACC4\uC815\uC774 \uC5C6\uC73C\uC2E0\uAC00\uC694?" }),
2396
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SdLink.Sub, { href: signUpHref, c: "primary.6", children: "\uD68C\uC6D0\uAC00\uC785" })
2397
- ] }),
2398
- children
2399
- ] }) });
2400
- }
2401
- function FormHeader({
2402
- title,
2403
- description,
2404
- logoSize = "sm"
2405
- }) {
2406
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core35.Stack, { gap: "lg", children: [
2407
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Logo, { size: logoSize }),
2408
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SdTextBox.Card, { title, description: description != null ? description : "" })
2409
- ] });
2410
- }
2411
- function Card7(_a4) {
2412
- var _b = _a4, {
2413
- title = "\uB85C\uADF8\uC778",
2414
- description = "%c \uC11C\uBE44\uC2A4\uB97C \uC774\uC6A9\uD558\uB824\uBA74 \uB85C\uADF8\uC778\uD574 \uC8FC\uC138\uC694.",
2415
- mih = "100svh",
2416
- logoSize
2417
- } = _b, formProps = __objRest(_b, [
2418
- "title",
2419
- "description",
2420
- "mih",
2421
- "logoSize"
2422
- ]);
2423
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Center, { mih, bg: "slate.0", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Paper, { w: "100%", maw: 420, p: { base: "lg", sm: "xl" }, radius: "lg", withBorder: true, shadow: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core35.Stack, { gap: "xl", children: [
2424
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FormHeader, { title, description, logoSize }),
2425
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(LoginForm, __spreadValues({}, formProps))
2426
- ] }) }) });
2427
- }
2428
- function Split(_a4) {
2429
- var _b = _a4, {
2430
- title = "\uB85C\uADF8\uC778",
2431
- description = "\uACC4\uC815 \uC815\uBCF4\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.",
2432
- brandTitle = "%c",
2433
- brandDescription = "\uD558\uB098\uC758 \uACC4\uC815\uC73C\uB85C \uBAA8\uB4E0 \uC11C\uBE44\uC2A4\uB97C \uC774\uC6A9\uD558\uC138\uC694.",
2434
- mih = "100svh",
2435
- logoSize
2436
- } = _b, formProps = __objRest(_b, [
2437
- "title",
2438
- "description",
2439
- "brandTitle",
2440
- "brandDescription",
2441
- "mih",
2442
- "logoSize"
2443
- ]);
2444
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core35.SimpleGrid, { cols: { base: 1, md: 2 }, spacing: 0, mih, children: [
2445
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2446
- import_core35.Box,
2447
- {
2448
- visibleFrom: "md",
2449
- pos: "relative",
2450
- style: __spreadValues({ overflow: "hidden", display: "flex", alignItems: "flex-end" }, brandSurface),
2451
- children: [
2452
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Box, { "aria-hidden": true, pos: "absolute", inset: 0, style: brandDotTexture }),
2453
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Box, { pos: "relative", p: 48, style: { zIndex: 1, width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2454
- SdTextBox.Hero,
2455
- {
2456
- title: brandTitle,
2457
- description: brandDescription,
2458
- gap: "sm",
2459
- maxDescWidth: 420,
2460
- ta: "left",
2461
- align: "flex-start"
2462
- }
2463
- ) })
2464
- ]
2465
- }
2466
- ),
2467
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_core35.Center, { p: { base: "md", sm: "xl" }, bg: "white", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_core35.Stack, { gap: "xl", w: "100%", maw: 400, children: [
2468
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FormHeader, { title, description, logoSize }),
2469
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(LoginForm, __spreadValues({}, formProps))
2470
- ] }) })
2471
- ] });
2472
- }
2473
- var SdLoginView = {
2474
- /** 중앙 정렬 카드 — 기본 로그인 화면 */
2475
- Card: Card7,
2476
- /** 좌측 브랜드 패널 + 우측 폼 — 넓은 화면용 */
2477
- Split
2478
- };
2479
- var SdLoginViewCard = SdLoginView.Card;
2480
- var SdLoginViewSplit = SdLoginView.Split;
2481
-
2482
- // ui/organism/Result.tsx
2483
- var import_core36 = require("@mantine/core");
2484
- var import_icons_react10 = require("@tabler/icons-react");
2485
- var import_jsx_runtime39 = require("react/jsx-runtime");
2486
- function ResultIcon({ color, Icon }) {
2487
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core36.Center, { w: 88, h: 88, bg: `${color}.0`, style: { borderRadius: "50%" }, "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { size: 48, stroke: 1.5, color: `var(--mantine-color-${color}-6)` }) });
2488
- }
2489
- function createResult(defaults) {
2490
- return function SdResult2({
2491
- title = defaults.title,
2492
- description,
2493
- primaryAction,
2494
- secondaryAction,
2495
- children,
2496
- mih = "60vh"
2497
- }) {
2498
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core36.Center, { mih, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SdContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core36.Stack, { align: "center", gap: "lg", ta: "center", children: [
2499
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ResultIcon, { color: defaults.color, Icon: defaults.Icon }),
2500
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core36.Stack, { gap: "sm", align: "center", children: [
2501
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SdTitle.Section, { children: title }),
2502
- description && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SdText.Body, { maw: 480, children: description })
2503
- ] }),
2504
- children && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_core36.Box, { children }),
2505
- (primaryAction || secondaryAction) && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_core36.Group, { gap: "sm", justify: "center", children: [
2506
- primaryAction && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SdButton.Primary, { onClick: primaryAction.onClick, children: primaryAction.label }),
2507
- secondaryAction && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(SdButton.Ghost, { onClick: secondaryAction.onClick, children: secondaryAction.label })
2508
- ] })
2509
- ] }) }) });
2510
- };
2511
- }
2512
- var SdResult = {
2513
- /** 성공 — 가입 완료·결제 완료 등 */
2514
- Success: createResult({
2515
- color: "green",
2516
- Icon: import_icons_react10.IconCircleCheck,
2517
- title: "\uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4"
2518
- }),
2519
- /** 실패 — 결제 실패·처리 중 오류 등. 서버 오류·404는 SdErrorView를 쓴다. */
2520
- Error: createResult({
2521
- color: "red",
2522
- Icon: import_icons_react10.IconCircleX,
2523
- title: "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4"
2524
- })
2525
- };
2526
- var SdResultSuccess = SdResult.Success;
2527
- var SdResultError = SdResult.Error;
2528
-
2529
- // ui/template/MainLayout.tsx
2530
- var import_core37 = require("@mantine/core");
2531
- var import_jsx_runtime40 = require("react/jsx-runtime");
2532
- var headers = {
2533
- mega: SdHeader.Mega,
2534
- simple: SdHeader.Simple,
2535
- panel: SdHeader.Panel
2536
- };
2537
- function MainLayout({
2538
- children,
2539
- navItems,
2540
- companyInfo,
2541
- loginFlag,
2542
- headerVariant = "mega",
2543
- headerLogoSize,
2544
- footerLogoSize
2545
- }) {
2546
- const Header = headers[headerVariant];
2547
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core37.AppShell, { header: { height: 60 }, children: [
2548
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core37.AppShell.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Header, { navItems, loginFlag, logoSize: headerLogoSize }) }),
2549
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core37.AppShell.Main, { children }),
2550
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(SdFooter, { company: companyInfo, navItems, logoSize: footerLogoSize })
2551
- ] });
2552
- }
2553
-
2554
- // ui/template/PageLayout.tsx
2555
- var import_core38 = require("@mantine/core");
2556
- var import_jsx_runtime41 = require("react/jsx-runtime");
2557
- var HERO_MIN_H = "38svh";
2558
- var HERO_PY = { base: 56, sm: 88 };
2559
- var HERO_MAW = 680;
2560
- function Content({
2561
- children,
2562
- navItems,
2563
- breadcrumb = true,
2564
- currentHref
2565
- }) {
2566
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(SdContainer, { py: "xl", children: [
2567
- breadcrumb && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SdBreadcrumb, { navItems, currentHref, mb: "lg" }),
2568
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core38.Stack, { gap: "xl", children })
2569
- ] });
2570
- }
2571
- function LayoutGap() {
2572
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core38.Space, {});
2573
- }
2574
- function Minimal({
2575
- label,
2576
- title,
2577
- description,
2578
- children,
2579
- navItems,
2580
- breadcrumb,
2581
- currentHref
2582
- }) {
2583
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(Plain2, { navItems, breadcrumb, currentHref, children: [
2584
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(LayoutGap, {}),
2585
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SdTextBox.Section, { label, title, description: description != null ? description : "" }),
2586
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core38.Divider, {}),
2587
- children
2588
- ] });
2589
- }
2590
- function Plain2({
2591
- children,
2592
- navItems,
2593
- breadcrumb,
2594
- currentHref
2595
- }) {
2596
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_jsx_runtime41.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Content, { navItems, breadcrumb, currentHref, children }) });
2597
- }
2598
- function HeroCopy({ label, title, description }) {
2599
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_core38.Stack, { gap: "md", maw: HERO_MAW, children: [
2600
- label && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_core38.Group, { gap: "sm", align: "center", wrap: "nowrap", children: [
2601
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core38.Box, { w: 28, h: 2, bg: "primary.3", style: { borderRadius: 2 } }),
2602
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SdText.Eyebrow, { c: "primary.1", children: label })
2603
- ] }),
2604
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2605
- SdTextBox.Hero,
2606
- {
2607
- title,
2608
- description,
2609
- gap: "sm",
2610
- maxDescWidth: 560,
2611
- ta: "left",
2612
- align: "flex-start"
2613
- }
2614
- )
2615
- ] });
2616
- }
2617
- function Image2({
2618
- image,
2619
- label,
2620
- title,
2621
- description,
2622
- children,
2623
- navItems,
2624
- breadcrumb,
2625
- currentHref
2626
- }) {
2627
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
2628
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
2629
- import_core38.Box,
2630
- {
2631
- pos: "relative",
2632
- style: {
2633
- minHeight: HERO_MIN_H,
2634
- display: "flex",
2635
- alignItems: "flex-end",
2636
- backgroundImage: image ? `url(${image})` : void 0,
2637
- backgroundSize: "cover",
2638
- backgroundPosition: "center",
2639
- backgroundColor: "var(--mantine-color-slate-9)"
2640
- },
2641
- children: [
2642
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2643
- import_core38.Box,
2644
- {
2645
- "aria-hidden": true,
2646
- pos: "absolute",
2647
- inset: 0,
2648
- style: {
2649
- background: "linear-gradient(180deg, rgba(15,23,42,0.25) 0%, rgba(15,23,42,0.72) 62%, rgba(15,23,42,0.94) 100%)"
2650
- }
2651
- }
2652
- ),
2653
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SdContainer, { pos: "relative", py: HERO_PY, style: { zIndex: 1, width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(HeroCopy, { label, title, description }) })
2654
- ]
2655
- }
2656
- ),
2657
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Content, { navItems, breadcrumb, currentHref, children })
2658
- ] });
2659
- }
2660
- function Brand({
2661
- label,
2662
- title,
2663
- description,
2664
- children,
2665
- navItems,
2666
- breadcrumb,
2667
- currentHref
2668
- }) {
2669
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
2670
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
2671
- import_core38.Box,
2672
- {
2673
- pos: "relative",
2674
- style: __spreadValues({
2675
- minHeight: HERO_MIN_H,
2676
- display: "flex",
2677
- alignItems: "flex-end",
2678
- overflow: "hidden",
2679
- borderBottom: "1px solid var(--mantine-color-slate-8)"
2680
- }, brandSurface),
2681
- children: [
2682
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_core38.Box, { "aria-hidden": true, pos: "absolute", inset: 0, style: brandDotTexture }),
2683
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SdContainer, { pos: "relative", py: HERO_PY, style: { zIndex: 1, width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(HeroCopy, { label, title, description }) })
2684
- ]
2685
- }
2686
- ),
2687
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Content, { navItems, breadcrumb, currentHref, children })
2688
- ] });
2689
- }
2690
- var PageLayout = {
2691
- /** 사진 배경 + 하단 스크림 + 좌측 정렬 텍스트 */
2692
- Image: Image2,
2693
- /** SdTextBox.Section 타이틀 + Plain 컨테이너 */
2694
- Minimal,
2695
- /** slate 바탕 + primary 라이트 + 도트 텍스처 */
2696
- Brand,
2697
- /** 히어로 없이 SdContainer + py="xl" 만 */
2698
- Plain: Plain2
2699
- };
2700
- var PageLayoutImage = PageLayout.Image;
2701
- var PageLayoutMinimal = PageLayout.Minimal;
2702
- var PageLayoutBrand = PageLayout.Brand;
2703
- var PageLayoutPlain = PageLayout.Plain;
2704
-
2705
- // ui/template/SdProvider.tsx
2706
- var import_core40 = require("@mantine/core");
2707
-
2708
- // ui/theme.ts
2709
- var import_core39 = require("@mantine/core");
2710
- var primary = [
2711
- "#e7f0fb",
2712
- "#c8dcf4",
2713
- "#a3c3ec",
2714
- "#7aa8e3",
2715
- "#4f8ddb",
2716
- "#2374d4",
2717
- "#0b5ed7",
2718
- // 6 ← brand anchor
2719
- "#094db1",
2720
- "#073d8c",
2721
- "#052d68"
2722
- ];
2723
- var secondary = [
2724
- "#fef6e7",
2725
- "#fde9c4",
2726
- "#fbd79a",
2727
- "#fac470",
2728
- "#f8ab47",
2729
- "#f7931e",
2730
- // 5
2731
- "#de7c12",
2732
- // 6
2733
- "#b5640e",
2734
- "#8a4c0b",
2735
- "#5e3307"
2736
- ];
2737
- var slate = [
2738
- "#f8fafc",
2739
- // 0 slate-50
2740
- "#f1f5f9",
2741
- // 1 slate-100
2742
- "#e2e8f0",
2743
- // 2 slate-200
2744
- "#cbd5e1",
2745
- // 3 slate-300
2746
- "#94a3b8",
2747
- // 4 slate-400
2748
- "#64748b",
2749
- // 5 slate-500
2750
- "#475569",
2751
- // 6 slate-600
2752
- "#334155",
2753
- // 7 slate-700
2754
- "#1e293b",
2755
- // 8 slate-800
2756
- "#0f172a"
2757
- // 9 slate-900
2758
- ];
2759
- var red = [
2760
- "#fef2f2",
2761
- // 0 red-50
2762
- "#fee2e2",
2763
- // 1 red-100
2764
- "#fecaca",
2765
- // 2 red-200
2766
- "#fca5a5",
2767
- // 3 red-300
2768
- "#f87171",
2769
- // 4 red-400
2770
- "#ef4444",
2771
- // 5 red-500
2772
- "#dc2626",
2773
- // 6 red-600
2774
- "#b91c1c",
2775
- // 7 red-700
2776
- "#991b1b",
2777
- // 8 red-800
2778
- "#7f1d1d"
2779
- // 9 red-900
2780
- ];
2781
- var green = [
2782
- "#f0fdf4",
2783
- // 0 green-50
2784
- "#dcfce7",
2785
- // 1 green-100
2786
- "#bbf7d0",
2787
- // 2 green-200
2788
- "#86efac",
2789
- // 3 green-300
2790
- "#4ade80",
2791
- // 4 green-400
2792
- "#22c55e",
2793
- // 5 green-500
2794
- "#16a34a",
2795
- // 6 green-600
2796
- "#15803d",
2797
- // 7 green-700
2798
- "#166534",
2799
- // 8 green-800
2800
- "#14532d"
2801
- // 9 green-900
2802
- ];
2803
- var amber = [
2804
- "#fffbeb",
2805
- // 0 amber-50
2806
- "#fef3c7",
2807
- // 1 amber-100
2808
- "#fde68a",
2809
- // 2 amber-200
2810
- "#fcd34d",
2811
- // 3 amber-300
2812
- "#fbbf24",
2813
- // 4 amber-400
2814
- "#f59e0b",
2815
- // 5 amber-500
2816
- "#d97706",
2817
- // 6 amber-600
2818
- "#b45309",
2819
- // 7 amber-700
2820
- "#92400e",
2821
- // 8 amber-800
2822
- "#78350f"
2823
- // 9 amber-900
2824
- ];
2825
- var theme = (0, import_core39.createTheme)({
2826
- /* ---- Color ---- */
2827
- colors: { primary, secondary, slate, red, green, amber, dark: slate },
2828
- primaryColor: "primary",
2829
- primaryShade: { light: 6, dark: 5 },
2830
- /* ---- Type ---- */
2831
- fontFamily: "'Noto Sans KR', ui-sans-serif, system-ui, -apple-system, sans-serif",
2832
- fontFamilyMonospace: "'Noto Sans KR', ui-monospace, monospace",
2833
- headings: {
2834
- fontFamily: "'Noto Sans KR', ui-sans-serif, system-ui, sans-serif",
2835
- fontWeight: "700",
2836
- sizes: {
2837
- h1: { fontSize: (0, import_core39.rem)(48), lineHeight: "1.1", fontWeight: "900" },
2838
- h2: { fontSize: (0, import_core39.rem)(36), lineHeight: "1.1", fontWeight: "900" },
2839
- h3: { fontSize: (0, import_core39.rem)(28), lineHeight: "1.15", fontWeight: "700" },
2840
- h4: { fontSize: (0, import_core39.rem)(20), lineHeight: "1.3", fontWeight: "700" },
2841
- h5: { fontSize: (0, import_core39.rem)(16), lineHeight: "1.4", fontWeight: "700" },
2842
- h6: { fontSize: (0, import_core39.rem)(14), lineHeight: "1.4", fontWeight: "700" }
2843
- }
2844
- },
2845
- fontSizes: {
2846
- xs: (0, import_core39.rem)(14),
2847
- sm: (0, import_core39.rem)(16),
2848
- md: (0, import_core39.rem)(18),
2849
- lg: (0, import_core39.rem)(20),
2850
- xl: (0, import_core39.rem)(22)
2851
- },
2852
- lineHeights: {
2853
- xs: "1.4",
2854
- sm: "1.45",
2855
- md: "1.5",
2856
- lg: "1.55",
2857
- xl: "1.6"
2858
- },
2859
- defaultRadius: "md",
2860
- radius: {
2861
- xs: (0, import_core39.rem)(6),
2862
- sm: (0, import_core39.rem)(8),
2863
- md: (0, import_core39.rem)(10),
2864
- lg: (0, import_core39.rem)(14),
2865
- xl: (0, import_core39.rem)(18)
2866
- },
2867
- spacing: {
2868
- xs: (0, import_core39.rem)(8),
2869
- sm: (0, import_core39.rem)(12),
2870
- md: (0, import_core39.rem)(16),
2871
- lg: (0, import_core39.rem)(24),
2872
- xl: (0, import_core39.rem)(32)
2873
- },
2874
- shadows: {
2875
- xs: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
2876
- sm: "0 1px 3px 0 rgb(0 0 0 / 0.06), 0 1px 2px -1px rgb(0 0 0 / 0.06)",
2877
- md: "0 8px 32px rgb(0 0 0 / 0.08)",
2878
- // glass nav
2879
- lg: "0 30px 60px -15px rgb(0 0 0 / 0.05)",
2880
- // card hover lift
2881
- xl: "0 40px 80px -20px rgb(0 0 0 / 0.3)"
2882
- // modal
2883
- },
2884
- breakpoints: {
2885
- xs: "36em",
2886
- sm: "48em",
2887
- md: "62em",
2888
- lg: "75em",
2889
- xl: "88em"
2890
- },
2891
- other: {
2892
- logoSizes: {
2893
- xs: { width: 72 },
2894
- sm: { width: 96 },
2895
- md: { width: 120 },
2896
- lg: { width: 160 },
2897
- xl: { width: 200 }
2898
- },
2899
- surfaceSubtle: "#f8fafc",
2900
- surfaceDark: "#0f172a",
2901
- surfaceDarker: "#020617",
2902
- gradientHeroText: "linear-gradient(to right, #60a5fa, #22d3ee, #3b82f6)",
2903
- gradientAsm: "linear-gradient(to bottom right, #2563eb, #06b6d4)",
2904
- gradientPims: "linear-gradient(to bottom right, #4f46e5, #a855f7)",
2905
- tracking: "-0.04em",
2906
- trackingEyebrow: "0.25em"
2907
- },
2908
- /* ---- Component defaults (match the live site) ---- */
2909
- defaultGradient: { from: "primary.6", to: "cyan.4", deg: 90 },
2910
- components: {
2911
- Container: {
2912
- defaultProps: { size: "xl", h: "100%" }
2913
- },
2914
- Logo: {
2915
- defaultProps: { size: "md" }
2916
- },
2917
- Button: {
2918
- defaultProps: {
2919
- radius: "xl",
2920
- fw: 700
2921
- }
2922
- },
2923
- Card: {
2924
- defaultProps: {
2925
- radius: "lg",
2926
- shadow: "sm",
2927
- withBorder: true,
2928
- padding: "lg"
2929
- }
2930
- },
2931
- Paper: {
2932
- defaultProps: { radius: "lg" }
2933
- },
2934
- Badge: {
2935
- defaultProps: { radius: "xl", variant: "light" }
2936
- },
2937
- Modal: {
2938
- defaultProps: { radius: "lg", centered: true, shadow: "xl" }
2939
- },
2940
- Input: {
2941
- defaultProps: { radius: "sm" }
2942
- },
2943
- TextInput: {
2944
- defaultProps: { radius: "sm" }
2945
- },
2946
- Divider: {
2947
- defaultProps: { c: "slate.5" }
2948
- },
2949
- Anchor: {
2950
- defaultProps: { c: "slate.5", fz: "sm", underline: "never" }
2951
- },
2952
- NavLink: {
2953
- defaultProps: { c: "slate.7", fz: "sm" }
2954
- },
2955
- Table: {
2956
- defaultProps: {
2957
- captionSide: "bottom"
2958
- },
2959
- styles: {
2960
- th: { color: "var(--mantine-color-slate-5)", fontWeight: "700" }
2961
- }
2962
- }
2963
- }
2964
- });
2965
-
2966
- // ui/template/SdProvider.tsx
2967
- var import_jsx_runtime42 = require("react/jsx-runtime");
2968
- function SdProvider({
2969
- children,
2970
- theme: theme2 = theme,
2971
- navItems,
2972
- defaultColorScheme = "light"
2973
- }) {
2974
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core40.MantineProvider, { theme: theme2, defaultColorScheme, children: [
2975
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SdToastProvider, {}),
2976
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(NavProvider, { navItems, children })
2977
- ] });
2978
- }
2979
- // Annotate the CommonJS export names for ESM import in node:
2980
- 0 && (module.exports = {
2981
- HeroCarousel,
2982
- Logo,
2983
- MainLayout,
2984
- NavProvider,
2985
- PageLayout,
2986
- PageLayoutBrand,
2987
- PageLayoutImage,
2988
- PageLayoutMinimal,
2989
- PageLayoutPlain,
2990
- SdBadge,
2991
- SdBadgeDefault,
2992
- SdBadgePrimary,
2993
- SdBadgeSuccess,
2994
- SdBadgeWarning,
2995
- SdBreadcrumb,
2996
- SdButton,
2997
- SdButtonCancel,
2998
- SdButtonDelete,
2999
- SdButtonDownload,
3000
- SdButtonExcel,
3001
- SdButtonGhost,
3002
- SdButtonOutline,
3003
- SdButtonPrimary,
3004
- SdButtonSecondary,
3005
- SdButtonSubmit,
3006
- SdButtonWhite,
3007
- SdClients,
3008
- SdClientsGrid,
3009
- SdClientsMarquee,
3010
- SdContainer,
3011
- SdCta,
3012
- SdCtaBanner,
3013
- SdCtaInline,
3014
- SdCtaSubtle,
3015
- SdErrorView,
3016
- SdErrorViewNotFound,
3017
- SdErrorViewPage,
3018
- SdFaq,
3019
- SdFaqDefault,
3020
- SdFaqFilled,
3021
- SdFaqWithHeader,
3022
- SdFeatureSection,
3023
- SdFeatures,
3024
- SdFooter,
3025
- SdHeader,
3026
- SdHeaderMega,
3027
- SdHeaderPanel,
3028
- SdHeaderSimple,
3029
- SdInput,
3030
- SdInputAutocomplete,
3031
- SdInputCheckbox,
3032
- SdInputColor,
3033
- SdInputDate,
3034
- SdInputDateRange,
3035
- SdInputEmail,
3036
- SdInputFile,
3037
- SdInputJson,
3038
- SdInputMultiSelect,
3039
- SdInputNativeSelect,
3040
- SdInputNumber,
3041
- SdInputPassword,
3042
- SdInputPinCode,
3043
- SdInputRadioGroup,
3044
- SdInputRating,
3045
- SdInputSegmented,
3046
- SdInputSelect,
3047
- SdInputSlider,
3048
- SdInputSwitch,
3049
- SdInputTags,
3050
- SdInputText,
3051
- SdInputTextarea,
3052
- SdInputTime,
3053
- SdLink,
3054
- SdLinkBody,
3055
- SdLinkHint,
3056
- SdLinkStrong,
3057
- SdLinkSub,
3058
- SdLoginView,
3059
- SdLoginViewCard,
3060
- SdLoginViewSplit,
3061
- SdMap,
3062
- SdMapSingle,
3063
- SdMapTabs,
3064
- SdModal,
3065
- SdNumberIcon,
3066
- SdPricingCard,
3067
- SdPricingCardDefault,
3068
- SdPricingCardFeatured,
3069
- SdPricingCardGrid,
3070
- SdProvider,
3071
- SdQuote,
3072
- SdQuoteCard,
3073
- SdQuotePlain,
3074
- SdResult,
3075
- SdResultError,
3076
- SdResultSuccess,
3077
- SdSkeleton,
3078
- SdSkeletonAvatar,
3079
- SdSkeletonCard,
3080
- SdSkeletonImage,
3081
- SdSkeletonText,
3082
- SdSkeletonTitle,
3083
- SdSolution,
3084
- SdSolutionCard,
3085
- SdSolutionCardGrid,
3086
- SdSolutionCardItem,
3087
- SdSolutionFiltered,
3088
- SdSolutionList,
3089
- SdSteps,
3090
- SdStepsBubble,
3091
- SdStepsCard,
3092
- SdStepsSection,
3093
- SdStepsStrip,
3094
- SdTable,
3095
- SdTableSpec,
3096
- SdTabs,
3097
- SdTabsOutline,
3098
- SdTabsPills,
3099
- SdTabsUnderline,
3100
- SdTestimonial,
3101
- SdTestimonialCard,
3102
- SdTestimonialGrid,
3103
- SdTestimonialStrip,
3104
- SdText,
3105
- SdTextBody,
3106
- SdTextBox,
3107
- SdTextBoxCard,
3108
- SdTextBoxHero,
3109
- SdTextBoxSection,
3110
- SdTextBoxSub,
3111
- SdTextError,
3112
- SdTextEyebrow,
3113
- SdTextHint,
3114
- SdTextNumeric,
3115
- SdTextStrong,
3116
- SdTextSub,
3117
- SdTimeline,
3118
- SdTimelineSection,
3119
- SdTitle,
3120
- SdTitleCard,
3121
- SdTitleDisplay,
3122
- SdTitleSection,
3123
- SdTitleSub,
3124
- SdToast,
3125
- SdToastClean,
3126
- SdToastError,
3127
- SdToastHide,
3128
- SdToastInfo,
3129
- SdToastLoading,
3130
- SdToastProvider,
3131
- SdToastSuccess,
3132
- SdToastUpdate,
3133
- SdToastWarning,
3134
- theme,
3135
- useNav
3136
- });