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