@yeongseoksong/framework 1.3.1 → 1.5.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.mjs CHANGED
@@ -68,6 +68,7 @@ function Logo(_props) {
68
68
  }
69
69
 
70
70
  // ui/atom/Tabs.tsx
71
+ import { useEffect, useState } from "react";
71
72
  import { Box, Tabs } from "@mantine/core";
72
73
 
73
74
  // ui/atom/Container.tsx
@@ -89,8 +90,30 @@ function SdScrollableList(_a4) {
89
90
  return /* @__PURE__ */ jsx3(Box, { style: { overflowX: "auto", width: "100%" }, children: /* @__PURE__ */ jsx3(Tabs.List, __spreadProps(__spreadValues({}, props), { children })) });
90
91
  }
91
92
  function createTabs(defaults, scrollable = false) {
92
- function SdTabsRoot(props) {
93
- return /* @__PURE__ */ jsx3(Tabs, __spreadValues(__spreadValues({}, defaults), props));
93
+ function SdTabsRoot(_a4) {
94
+ var _b = _a4, { syncHash, value, onChange } = _b, props = __objRest(_b, ["syncHash", "value", "onChange"]);
95
+ const [hashValue, setHashValue] = useState(null);
96
+ useEffect(() => {
97
+ if (!syncHash) return;
98
+ const apply = () => {
99
+ const id = decodeURIComponent(window.location.hash.slice(1));
100
+ if (id) setHashValue(id);
101
+ };
102
+ apply();
103
+ window.addEventListener("hashchange", apply);
104
+ return () => window.removeEventListener("hashchange", apply);
105
+ }, [syncHash]);
106
+ if (!syncHash) {
107
+ return /* @__PURE__ */ jsx3(Tabs, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { value, onChange }));
108
+ }
109
+ const handleChange = (next) => {
110
+ if (next) {
111
+ window.history.replaceState(null, "", `#${next}`);
112
+ setHashValue(next);
113
+ }
114
+ onChange == null ? void 0 : onChange(next);
115
+ };
116
+ return /* @__PURE__ */ jsx3(Tabs, __spreadProps(__spreadValues(__spreadValues({}, defaults), props), { value: value != null ? value : hashValue, onChange: handleChange }));
94
117
  }
95
118
  SdTabsRoot.List = scrollable ? SdScrollableList : Tabs.List;
96
119
  SdTabsRoot.Tab = Tabs.Tab;
@@ -186,6 +209,36 @@ var SdTitleSub = SdTitle.Sub;
186
209
 
187
210
  // ui/atom/Text.tsx
188
211
  import { Text as MantineText } from "@mantine/core";
212
+
213
+ // ui/typography.ts
214
+ var textStyles = {
215
+ /** 최상위 강조 */
216
+ Strong: { fw: 700, c: "slate.9", fz: "md", style: { letterSpacing: "-0.04em" } },
217
+ /** 기본 본문 */
218
+ Body: { fw: 500, c: "slate.7", fz: "sm", lh: 1.7 },
219
+ /** 보조 정보 */
220
+ Sub: { fw: 400, c: "slate.5", fz: "xs", lh: 1.6 },
221
+ /** 최소 강조 — 밀도 높은 목록 */
222
+ Hint: { fw: 400, c: "slate.4", fz: "xs", lh: 1.5 },
223
+ /** 섹션 라벨 */
224
+ Eyebrow: {
225
+ fw: 700,
226
+ c: "primary.6",
227
+ fz: "xs",
228
+ style: { letterSpacing: "0.12em", textTransform: "uppercase" }
229
+ },
230
+ /** 오류 메시지 */
231
+ Error: { fw: 400, c: "red.6", fz: "sm" },
232
+ /** 숫자 — 자릿수 정렬 */
233
+ Numeric: {
234
+ fw: 700,
235
+ c: "slate.8",
236
+ fz: "md",
237
+ style: { fontVariantNumeric: "tabular-nums", letterSpacing: "-0.02em" }
238
+ }
239
+ };
240
+
241
+ // ui/atom/Text.tsx
189
242
  import { jsx as jsx5 } from "react/jsx-runtime";
190
243
  function createText(defaults) {
191
244
  return function SdText2(_a4) {
@@ -195,23 +248,13 @@ function createText(defaults) {
195
248
  };
196
249
  }
197
250
  var SdText = {
198
- Strong: createText({ fw: 700, c: "slate.9", fz: "md", style: { letterSpacing: "-0.04em" } }),
199
- Body: createText({ fw: 400, c: "slate.7", fz: "md", lh: 1.7 }),
200
- Sub: createText({ fw: 400, c: "slate.5", fz: "xs", lh: 1.6 }),
201
- Eyebrow: createText({
202
- fw: 700,
203
- c: "primary.6",
204
- fz: "xs",
205
- style: { letterSpacing: "0.12em", textTransform: "uppercase" }
206
- }),
207
- Error: createText({ fw: 400, c: "red.6", fz: "sm" }),
208
- Hint: createText({ fw: 400, c: "slate.4", fz: "xs", lh: 1.5 }),
209
- Numeric: createText({
210
- fw: 700,
211
- c: "slate.8",
212
- fz: "md",
213
- style: { fontVariantNumeric: "tabular-nums", letterSpacing: "-0.02em" }
214
- })
251
+ Strong: createText(textStyles.Strong),
252
+ Body: createText(textStyles.Body),
253
+ Sub: createText(textStyles.Sub),
254
+ Eyebrow: createText(textStyles.Eyebrow),
255
+ Error: createText(textStyles.Error),
256
+ Hint: createText(textStyles.Hint),
257
+ Numeric: createText(textStyles.Numeric)
215
258
  };
216
259
  var SdTextStrong = SdText.Strong;
217
260
  var SdTextBody = SdText.Body;
@@ -405,7 +448,7 @@ var SdBadge = {
405
448
  /** 성공/완료 */
406
449
  Success: createBadge({ variant: "light", color: "green" }),
407
450
  /** 주의/경고 */
408
- Warning: createBadge({ variant: "light", color: "orange" })
451
+ Warning: createBadge({ variant: "light", color: "amber" })
409
452
  };
410
453
  var SdBadgeDefault = SdBadge.Default;
411
454
  var SdBadgePrimary = SdBadge.Primary;
@@ -414,56 +457,157 @@ var SdBadgeWarning = SdBadge.Warning;
414
457
 
415
458
  // ui/atom/Input.tsx
416
459
  import {
460
+ Autocomplete,
461
+ Checkbox,
462
+ ColorInput,
463
+ FileInput,
464
+ Group as Group2,
465
+ Input,
466
+ JsonInput,
467
+ MultiSelect,
468
+ NativeSelect,
469
+ NumberInput,
417
470
  PasswordInput,
471
+ PinInput,
472
+ Radio,
473
+ Rating,
474
+ SegmentedControl,
418
475
  Select,
476
+ Slider,
477
+ Stack as Stack2,
478
+ Switch,
479
+ TagsInput,
419
480
  Textarea,
420
481
  TextInput
421
482
  } from "@mantine/core";
483
+ import {
484
+ DateInput,
485
+ DatePickerInput,
486
+ TimeInput
487
+ } from "@mantine/dates";
422
488
  import { jsx as jsx12 } from "react/jsx-runtime";
423
- function createTextInput(defaults) {
424
- return function SdInput2(_a4) {
425
- var props = __objRest(_a4, []);
426
- return /* @__PURE__ */ jsx12(TextInput, __spreadValues(__spreadValues({}, defaults), props));
427
- };
428
- }
429
- function createTextarea(defaults) {
430
- return function SdInputTextarea2(_a4) {
431
- var props = __objRest(_a4, []);
432
- return /* @__PURE__ */ jsx12(Textarea, __spreadValues(__spreadValues({}, defaults), props));
489
+ function createInput(Component, defaults) {
490
+ return function SdInput2(props) {
491
+ return /* @__PURE__ */ jsx12(Component, __spreadValues(__spreadValues({}, defaults), props));
433
492
  };
434
493
  }
435
- function createPasswordInput(defaults) {
436
- return function SdInputPassword2(_a4) {
437
- var props = __objRest(_a4, []);
438
- return /* @__PURE__ */ jsx12(PasswordInput, __spreadValues(__spreadValues({}, defaults), props));
494
+ function createWrappedInput(Component, defaults) {
495
+ return function SdWrappedInput(_a4) {
496
+ var _b = _a4, {
497
+ label,
498
+ description,
499
+ error,
500
+ required,
501
+ withAsterisk
502
+ } = _b, rest = __objRest(_b, [
503
+ "label",
504
+ "description",
505
+ "error",
506
+ "required",
507
+ "withAsterisk"
508
+ ]);
509
+ return /* @__PURE__ */ jsx12(
510
+ Input.Wrapper,
511
+ {
512
+ label,
513
+ description,
514
+ error,
515
+ required,
516
+ withAsterisk,
517
+ children: /* @__PURE__ */ jsx12(Component, __spreadValues(__spreadValues({}, defaults), rest))
518
+ }
519
+ );
439
520
  };
440
521
  }
441
- function createSelect(defaults) {
442
- return function SdInputSelect2(_a4) {
443
- var props = __objRest(_a4, []);
444
- return /* @__PURE__ */ jsx12(Select, __spreadValues(__spreadValues({}, defaults), props));
445
- };
522
+ function SdInputRadio(_a4) {
523
+ var _b = _a4, { data, orientation = "horizontal" } = _b, props = __objRest(_b, ["data", "orientation"]);
524
+ const Layout = orientation === "vertical" ? Stack2 : Group2;
525
+ return /* @__PURE__ */ jsx12(Radio.Group, __spreadProps(__spreadValues({}, props), { children: /* @__PURE__ */ jsx12(Layout, { gap: "sm", mt: "xs", children: data.map((item) => /* @__PURE__ */ jsx12(Radio, { value: item.value, label: item.label, disabled: item.disabled }, item.value)) }) }));
446
526
  }
447
527
  var SdInput = {
528
+ // ── 텍스트 ──
448
529
  /** 일반 텍스트 — 이름, 회사명 등 */
449
- Text: createTextInput({}),
530
+ Text: createInput(TextInput),
450
531
  /** 이메일 입력 */
451
- Email: createTextInput({ type: "email" }),
532
+ Email: createInput(TextInput, { type: "email" }),
452
533
  /** 비밀번호 입력 — 마스킹 토글 포함 */
453
- Password: createPasswordInput({}),
534
+ Password: createInput(PasswordInput),
454
535
  /** 멀티라인 텍스트 — 문의 메시지 등 */
455
- Textarea: createTextarea({ autosize: true, minRows: 3 }),
536
+ Textarea: createInput(Textarea, { autosize: true, minRows: 3 }),
537
+ /** JSON 입력 — 포맷·검증 버튼 포함 */
538
+ Json: createInput(JsonInput, { autosize: true, minRows: 4, formatOnBlur: true }),
539
+ // ── 숫자 ──
540
+ /** 숫자 입력 — 증감 컨트롤 포함 */
541
+ Number: createInput(NumberInput),
542
+ /** 범위 선택 슬라이더 */
543
+ Slider: createWrappedInput(Slider),
544
+ /** 별점 */
545
+ Rating: createWrappedInput(Rating),
546
+ /** 인증번호 등 자리수가 고정된 코드 */
547
+ PinCode: createWrappedInput(PinInput),
548
+ // ── 선택 ──
456
549
  /** 드롭다운 선택 */
457
- Select: createSelect({})
550
+ Select: createInput(Select),
551
+ /** 브라우저 기본 select — 모바일·간단한 목록 */
552
+ NativeSelect: createInput(NativeSelect),
553
+ /** 다중 선택 */
554
+ MultiSelect: createInput(MultiSelect),
555
+ /** 입력하며 후보를 좁히는 자동완성(자유 입력 허용) */
556
+ Autocomplete: createInput(Autocomplete),
557
+ /** 자유롭게 추가하는 태그 목록 */
558
+ Tags: createInput(TagsInput),
559
+ /** 라디오 그룹 — data로 항목을 넘긴다 */
560
+ Radio: SdInputRadio,
561
+ /** 두세 개 중 하나 — 탭처럼 보이는 선택 */
562
+ Segmented: createWrappedInput(SegmentedControl),
563
+ // ── 불리언 ──
564
+ /** 체크박스 — getInputProps(name, { type: 'checkbox' }) */
565
+ Checkbox: createInput(Checkbox),
566
+ /** 스위치 — 즉시 반영되는 on/off */
567
+ Switch: createInput(Switch),
568
+ // ── 기타 ──
569
+ /** 파일 선택 */
570
+ File: createInput(FileInput, { clearable: true }),
571
+ /** 색상 선택 */
572
+ Color: createInput(ColorInput),
573
+ // ── 날짜·시간 (@mantine/dates) ──
574
+ /** 날짜 — 직접 입력 + 달력 팝오버. 값은 'YYYY-MM-DD' 문자열 */
575
+ Date: createInput(DateInput, { valueFormat: "YYYY-MM-DD", clearable: true }),
576
+ /** 기간 — 시작·종료 두 날짜 */
577
+ DateRange: createInput(DatePickerInput, {
578
+ type: "range",
579
+ valueFormat: "YYYY-MM-DD",
580
+ clearable: true
581
+ }),
582
+ /** 시각 */
583
+ Time: createInput(TimeInput)
458
584
  };
459
585
  var SdInputText = SdInput.Text;
460
586
  var SdInputEmail = SdInput.Email;
461
587
  var SdInputPassword = SdInput.Password;
462
588
  var SdInputTextarea = SdInput.Textarea;
589
+ var SdInputJson = SdInput.Json;
590
+ var SdInputNumber = SdInput.Number;
591
+ var SdInputSlider = SdInput.Slider;
592
+ var SdInputRating = SdInput.Rating;
593
+ var SdInputPinCode = SdInput.PinCode;
463
594
  var SdInputSelect = SdInput.Select;
595
+ var SdInputNativeSelect = SdInput.NativeSelect;
596
+ var SdInputMultiSelect = SdInput.MultiSelect;
597
+ var SdInputAutocomplete = SdInput.Autocomplete;
598
+ var SdInputTags = SdInput.Tags;
599
+ var SdInputRadioGroup = SdInput.Radio;
600
+ var SdInputSegmented = SdInput.Segmented;
601
+ var SdInputCheckbox = SdInput.Checkbox;
602
+ var SdInputSwitch = SdInput.Switch;
603
+ var SdInputFile = SdInput.File;
604
+ var SdInputColor = SdInput.Color;
605
+ var SdInputDate = SdInput.Date;
606
+ var SdInputDateRange = SdInput.DateRange;
607
+ var SdInputTime = SdInput.Time;
464
608
 
465
609
  // ui/atom/Skeleton.tsx
466
- import { Box as Box3, Skeleton as MantineSkeleton, Stack as Stack2 } from "@mantine/core";
610
+ import { Box as Box3, Skeleton as MantineSkeleton, Stack as Stack3 } from "@mantine/core";
467
611
  import { jsx as jsx13, jsxs as jsxs2 } from "react/jsx-runtime";
468
612
  function SkeletonText(_a4) {
469
613
  var _b = _a4, { width = "100%" } = _b, props = __objRest(_b, ["width"]);
@@ -491,7 +635,7 @@ function SkeletonCard({ height, lines = 3 }) {
491
635
  border: "1px solid var(--mantine-color-gray-3)",
492
636
  height
493
637
  },
494
- children: /* @__PURE__ */ jsxs2(Stack2, { gap: "sm", children: [
638
+ children: /* @__PURE__ */ jsxs2(Stack3, { gap: "sm", children: [
495
639
  /* @__PURE__ */ jsx13(MantineSkeleton, { height: 20, width: "50%", radius: "sm" }),
496
640
  Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx13(
497
641
  MantineSkeleton,
@@ -522,7 +666,7 @@ var SdSkeletonAvatar = SkeletonAvatar;
522
666
  // ui/atom/Link.tsx
523
667
  import { Anchor as MantineAnchor } from "@mantine/core";
524
668
 
525
- // util/style.util.ts
669
+ // ui/style.util.ts
526
670
  function toCssColor(value) {
527
671
  if (typeof value !== "string") return "";
528
672
  return value.includes(".") ? `var(--mantine-color-${value.replace(".", "-")})` : value;
@@ -531,11 +675,16 @@ function toCssColor(value) {
531
675
  // ui/atom/Link.tsx
532
676
  import { jsx as jsx14 } from "react/jsx-runtime";
533
677
  var HOVER_COLOR = "var(--mantine-color-primary-6)";
534
- function createLink(defaults) {
678
+ function createLink(defaults, Fallback) {
535
679
  return function SdLink2(_a4) {
536
680
  var _b = _a4, { children, onMouseEnter, onMouseLeave } = _b, props = __objRest(_b, ["children", "onMouseEnter", "onMouseLeave"]);
537
681
  var _a5;
538
682
  const baseColor = toCssColor((_a5 = props.c) != null ? _a5 : defaults.c);
683
+ const resolved = typeof children === "string" ? t(children) : children;
684
+ if (!props.href) {
685
+ const _b2 = props, { href: _href, target: _target, rel: _rel } = _b2, textProps = __objRest(_b2, ["href", "target", "rel"]);
686
+ return /* @__PURE__ */ jsx14(Fallback, __spreadProps(__spreadValues({}, textProps), { children }));
687
+ }
539
688
  const handleEnter = (e) => {
540
689
  e.currentTarget.style.color = HOVER_COLOR;
541
690
  onMouseEnter == null ? void 0 : onMouseEnter(e);
@@ -550,29 +699,88 @@ function createLink(defaults) {
550
699
  style: { transition: "color 0.15s" },
551
700
  onMouseEnter: handleEnter,
552
701
  onMouseLeave: handleLeave,
553
- children
702
+ children: resolved
554
703
  })
555
704
  );
556
705
  };
557
706
  }
707
+ function linkStyle(base2, extra) {
708
+ return Object.assign({ underline: "never" }, base2, extra);
709
+ }
558
710
  var SdLink = {
559
711
  /** 최상위 강조 — 눈에 띄어야 하는 단일 링크 */
560
- Strong: createLink({ fw: 700, c: "primary.6", fz: "xs", underline: "never" }),
712
+ Strong: createLink(linkStyle(textStyles.Strong), SdText.Strong),
561
713
  /** 기본 — 본문·네비게이션 수준의 일반 링크 */
562
- Body: createLink({ fw: 500, c: "slate.7", fz: 15, underline: "never" }),
714
+ Body: createLink(linkStyle(textStyles.Body), SdText.Body),
563
715
  /** 보조 — 연락처·정책 등 부가 정보 */
564
- Sub: createLink({ fw: 400, c: "slate.5", fz: "xs", underline: "never" }),
716
+ Sub: createLink(linkStyle(textStyles.Sub), SdText.Sub),
565
717
  /** 최소 강조 — 링크 목록처럼 밀도가 높고 톤을 낮춰야 하는 곳 */
566
- Hint: createLink({ fw: 400, c: "slate.4", fz: "xs", underline: "never" })
718
+ Hint: createLink(linkStyle(textStyles.Hint), SdText.Hint)
567
719
  };
568
720
  var SdLinkStrong = SdLink.Strong;
569
721
  var SdLinkBody = SdLink.Body;
570
722
  var SdLinkSub = SdLink.Sub;
571
723
  var SdLinkHint = SdLink.Hint;
572
724
 
725
+ // ui/atom/Toast.tsx
726
+ import { Notifications, notifications } from "@mantine/notifications";
727
+ import { IconAlertTriangle, IconCheck, IconInfoCircle, IconX as IconX2 } from "@tabler/icons-react";
728
+ import { jsx as jsx15 } from "react/jsx-runtime";
729
+ var toastStyles = {
730
+ /** 성공 — 저장·전송 완료 */
731
+ Success: { color: "green", icon: /* @__PURE__ */ jsx15(IconCheck, { size: 18 }), title: "\uC644\uB8CC" },
732
+ /** 실패 — 요청 오류·검증 실패 */
733
+ Error: { color: "red", icon: /* @__PURE__ */ jsx15(IconX2, { size: 18 }), title: "\uC624\uB958" },
734
+ /** 주의 — 되돌릴 수 없는 동작 안내 등 */
735
+ Warning: { color: "amber", icon: /* @__PURE__ */ jsx15(IconAlertTriangle, { size: 18 }), title: "\uC8FC\uC758" },
736
+ /** 안내 — 중립 정보 */
737
+ Info: { color: "primary", icon: /* @__PURE__ */ jsx15(IconInfoCircle, { size: 18 }), title: "\uC548\uB0B4" },
738
+ /** 진행 중 — 스피너 + 자동 닫힘 없음. Update로 결과 변형으로 바꾼다. */
739
+ Loading: { loading: true, autoClose: false, withCloseButton: false, title: "\uCC98\uB9AC \uC911" }
740
+ };
741
+ function createToast(defaults) {
742
+ return function SdToast2(message, options) {
743
+ return notifications.show(__spreadValues(__spreadProps(__spreadValues({}, defaults), { message }), options));
744
+ };
745
+ }
746
+ var SdToast = {
747
+ Success: createToast(toastStyles.Success),
748
+ Error: createToast(toastStyles.Error),
749
+ Warning: createToast(toastStyles.Warning),
750
+ Info: createToast(toastStyles.Info),
751
+ Loading: createToast(toastStyles.Loading),
752
+ /**
753
+ * 이미 떠 있는 알림을 다른 변형으로 교체한다 — `Loading` → `Success`/`Error` 전환용.
754
+ * `loading: false`·`autoClose`를 먼저 깔아 두므로 스피너가 그대로 남지 않는다.
755
+ */
756
+ Update: (id, variant, message, options) => notifications.update(__spreadValues(__spreadProps(__spreadValues({
757
+ id,
758
+ loading: false,
759
+ autoClose: 4e3,
760
+ withCloseButton: true
761
+ }, toastStyles[variant]), {
762
+ message
763
+ }), options)),
764
+ /** 특정 알림 닫기 */
765
+ Hide: (id) => notifications.hide(id),
766
+ /** 떠 있는 알림 전부 닫기 */
767
+ Clean: () => notifications.clean()
768
+ };
769
+ function SdToastProvider(props) {
770
+ return /* @__PURE__ */ jsx15(Notifications, __spreadValues({ position: "top-right", autoClose: 4e3, limit: 3 }, props));
771
+ }
772
+ var SdToastSuccess = SdToast.Success;
773
+ var SdToastError = SdToast.Error;
774
+ var SdToastWarning = SdToast.Warning;
775
+ var SdToastInfo = SdToast.Info;
776
+ var SdToastLoading = SdToast.Loading;
777
+ var SdToastUpdate = SdToast.Update;
778
+ var SdToastHide = SdToast.Hide;
779
+ var SdToastClean = SdToast.Clean;
780
+
573
781
  // ui/molecule/TextBox.tsx
574
- import { Stack as Stack3 } from "@mantine/core";
575
- import { jsx as jsx15, jsxs as jsxs3 } from "react/jsx-runtime";
782
+ import { Stack as Stack4 } from "@mantine/core";
783
+ import { jsx as jsx16, jsxs as jsxs3 } from "react/jsx-runtime";
576
784
  function createTextBox(titleVariant, defaultGap = "xs", descVariant = "Body", color_ = void 0) {
577
785
  return function SdTextBox2(_a4) {
578
786
  var _b = _a4, {
@@ -596,10 +804,10 @@ function createTextBox(titleVariant, defaultGap = "xs", descVariant = "Body", co
596
804
  const variant = variantOverride != null ? variantOverride : titleVariant;
597
805
  const TitleComponent = SdTitle[variant];
598
806
  const DescComponent = SdText[descVariant];
599
- return /* @__PURE__ */ jsxs3(Stack3, __spreadProps(__spreadValues({ gap: defaultGap }, stackProps), { children: [
600
- label && /* @__PURE__ */ jsx15(SdText.Eyebrow, { children: label }),
601
- /* @__PURE__ */ jsx15(TitleComponent, { c: colorRes, children: title }),
602
- description && /* @__PURE__ */ jsx15(DescComponent, { c: colorRes, maw: maxDescWidth, mt: 4, children: description }),
807
+ return /* @__PURE__ */ jsxs3(Stack4, __spreadProps(__spreadValues({ gap: defaultGap }, stackProps), { children: [
808
+ label && /* @__PURE__ */ jsx16(SdText.Eyebrow, { children: label }),
809
+ /* @__PURE__ */ jsx16(TitleComponent, { c: colorRes, children: title }),
810
+ description && /* @__PURE__ */ jsx16(DescComponent, { c: colorRes, maw: maxDescWidth, mt: 4, children: description }),
603
811
  children
604
812
  ] }));
605
813
  };
@@ -616,26 +824,27 @@ var SdTextBoxCard = SdTextBox.Card;
616
824
  var SdTextBoxSub = SdTextBox.Sub;
617
825
 
618
826
  // ui/molecule/Features.tsx
619
- import { Card as Card2, SimpleGrid, Stack as Stack4 } from "@mantine/core";
827
+ import { Card as Card2, SimpleGrid, Stack as Stack5 } from "@mantine/core";
620
828
 
621
829
  // util/sort.util.ts
622
- function filterAndSort(items) {
623
- return (items != null ? items : []).filter((item) => item.isShow).sort((a, b) => a.order - b.order);
830
+ function filterAndSort(items, direction = "asc") {
831
+ const sign = direction === "asc" ? 1 : -1;
832
+ return (items != null ? items : []).filter((item) => item.isShow).sort((a, b) => (a.order - b.order) * sign);
624
833
  }
625
834
 
626
835
  // ui/molecule/Features.tsx
627
- import { jsx as jsx16, jsxs as jsxs4 } from "react/jsx-runtime";
836
+ import { jsx as jsx17, jsxs as jsxs4 } from "react/jsx-runtime";
628
837
  function SdFeatures({ items, cols = { base: 1, sm: 2, md: 3 } }) {
629
838
  const visible = filterAndSort(items);
630
- return /* @__PURE__ */ jsx16(SimpleGrid, { cols, spacing: "xl", children: visible.map((item) => /* @__PURE__ */ jsx16(Card2, { children: /* @__PURE__ */ jsxs4(Stack4, { gap: "sm", children: [
839
+ return /* @__PURE__ */ jsx17(SimpleGrid, { cols, spacing: "xl", children: visible.map((item) => /* @__PURE__ */ jsx17(Card2, { children: /* @__PURE__ */ jsxs4(Stack5, { gap: "sm", children: [
631
840
  item.icon,
632
- /* @__PURE__ */ jsx16(SdTextBox.Card, { label: item.label, title: item.title, description: item.description })
841
+ /* @__PURE__ */ jsx17(SdTextBox.Card, { label: item.label, title: item.title, description: item.description })
633
842
  ] }, item.id) }, item.id)) });
634
843
  }
635
844
 
636
845
  // ui/molecule/Timeline.tsx
637
- import { Group as Group2, Stack as Stack5, Timeline as MantineTimeline } from "@mantine/core";
638
- import { jsx as jsx17, jsxs as jsxs5 } from "react/jsx-runtime";
846
+ import { Group as Group3, Stack as Stack6, Timeline as MantineTimeline } from "@mantine/core";
847
+ import { jsx as jsx18, jsxs as jsxs5 } from "react/jsx-runtime";
639
848
  function SdTimeline({ items }) {
640
849
  const grouped = items.filter((item) => item.isShow).sort((a, b) => b.year - a.year || b.month - a.month).reduce((acc, item) => {
641
850
  var _a4, _b;
@@ -644,32 +853,32 @@ function SdTimeline({ items }) {
644
853
  return acc;
645
854
  }, {});
646
855
  const years = Object.keys(grouped).map(Number).sort((a, b) => b - a);
647
- return /* @__PURE__ */ jsx17(MantineTimeline, { active: items.length, bulletSize: 24, lineWidth: 2, children: years.map((year) => /* @__PURE__ */ jsx17(MantineTimeline.Item, { title: /* @__PURE__ */ jsxs5(SdTitle.Sub, { children: [
856
+ return /* @__PURE__ */ jsx18(MantineTimeline, { active: items.length, bulletSize: 24, lineWidth: 2, children: years.map((year) => /* @__PURE__ */ jsx18(MantineTimeline.Item, { title: /* @__PURE__ */ jsxs5(SdTitle.Sub, { children: [
648
857
  year,
649
858
  "\uB144"
650
- ] }), children: /* @__PURE__ */ jsx17(Stack5, { gap: 6, mt: "xs", children: grouped[year].map((event) => /* @__PURE__ */ jsxs5(Group2, { gap: "md", align: "center", wrap: "nowrap", children: [
859
+ ] }), children: /* @__PURE__ */ jsx18(Stack6, { gap: 6, mt: "xs", children: grouped[year].map((event) => /* @__PURE__ */ jsxs5(Group3, { gap: "md", align: "center", wrap: "nowrap", children: [
651
860
  /* @__PURE__ */ jsxs5(SdText.Eyebrow, { miw: 28, children: [
652
861
  event.month,
653
862
  "\uC6D4"
654
863
  ] }),
655
- /* @__PURE__ */ jsx17(SdText.Sub, { style: { flex: 1 }, children: event.description })
864
+ /* @__PURE__ */ jsx18(SdText.Sub, { style: { flex: 1 }, children: event.description })
656
865
  ] }, event.id)) }) }, year)) });
657
866
  }
658
867
 
659
868
  // ui/molecule/Steps.tsx
660
- import { Box as Box4, Card as Card3, Group as Group3, Stack as Stack6, ThemeIcon as ThemeIcon2 } from "@mantine/core";
869
+ import { Box as Box4, Card as Card3, Group as Group4, Stack as Stack7, ThemeIcon as ThemeIcon2 } from "@mantine/core";
661
870
  import { IconArrowDown, IconArrowRight } from "@tabler/icons-react";
662
871
  import { Fragment } from "react/jsx-runtime";
663
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs6 } from "react/jsx-runtime";
872
+ import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs6 } from "react/jsx-runtime";
664
873
  function BubbleStep({ item, index, isLast }) {
665
- return /* @__PURE__ */ jsxs6(Group3, { align: "flex-start", gap: "lg", wrap: "nowrap", children: [
874
+ return /* @__PURE__ */ jsxs6(Group4, { align: "flex-start", gap: "lg", wrap: "nowrap", children: [
666
875
  /* @__PURE__ */ jsxs6(
667
876
  Box4,
668
877
  {
669
878
  style: { display: "flex", flexDirection: "column", alignItems: "center", flexShrink: 0 },
670
879
  children: [
671
- /* @__PURE__ */ jsx18(SdNumberIcon, { value: String(index + 1).padStart(2, "0") }),
672
- !isLast && /* @__PURE__ */ jsx18(
880
+ /* @__PURE__ */ jsx19(SdNumberIcon, { value: String(index + 1).padStart(2, "0"), color: "primary" }),
881
+ !isLast && /* @__PURE__ */ jsx19(
673
882
  Box4,
674
883
  {
675
884
  style: {
@@ -684,7 +893,7 @@ function BubbleStep({ item, index, isLast }) {
684
893
  ]
685
894
  }
686
895
  ),
687
- /* @__PURE__ */ jsx18(
896
+ /* @__PURE__ */ jsx19(
688
897
  SdTextBox.Card,
689
898
  {
690
899
  title: item.title,
@@ -696,11 +905,11 @@ function BubbleStep({ item, index, isLast }) {
696
905
  ] });
697
906
  }
698
907
  function Bubble({ items }) {
699
- return /* @__PURE__ */ jsx18(Box4, { children: items.map((item, i) => /* @__PURE__ */ jsx18(BubbleStep, { item, index: i, isLast: i === items.length - 1 }, i)) });
908
+ return /* @__PURE__ */ jsx19(Box4, { children: items.map((item, i) => /* @__PURE__ */ jsx19(BubbleStep, { item, index: i, isLast: i === items.length - 1 }, i)) });
700
909
  }
701
910
  function CardStep({ item, index }) {
702
911
  return /* @__PURE__ */ jsxs6(Card3, { withBorder: true, radius: "md", p: 0, style: { height: "100%", overflow: "hidden" }, children: [
703
- /* @__PURE__ */ jsx18(
912
+ /* @__PURE__ */ jsx19(
704
913
  Box4,
705
914
  {
706
915
  py: "lg",
@@ -715,35 +924,35 @@ function CardStep({ item, index }) {
715
924
  ] })
716
925
  }
717
926
  ),
718
- /* @__PURE__ */ jsx18(Box4, { p: "lg", style: { textAlign: "center" }, children: /* @__PURE__ */ jsx18(SdTextBox.Card, { title: item.title, description: item.description }) })
927
+ /* @__PURE__ */ jsx19(Box4, { p: "lg", style: { textAlign: "center" }, children: /* @__PURE__ */ jsx19(SdTextBox.Card, { title: item.title, description: item.description }) })
719
928
  ] });
720
929
  }
721
930
  function CardArrow({ direction }) {
722
- return /* @__PURE__ */ jsx18(ThemeIcon2, { size: 36, radius: "xl", variant: "light", color: "primary", children: direction === "right" ? /* @__PURE__ */ jsx18(IconArrowRight, { size: 20, stroke: 2.5 }) : /* @__PURE__ */ jsx18(IconArrowDown, { size: 20, stroke: 2.5 }) });
931
+ return /* @__PURE__ */ jsx19(ThemeIcon2, { size: 36, radius: "xl", variant: "light", color: "primary", children: direction === "right" ? /* @__PURE__ */ jsx19(IconArrowRight, { size: 20, stroke: 2.5 }) : /* @__PURE__ */ jsx19(IconArrowDown, { size: 20, stroke: 2.5 }) });
723
932
  }
724
933
  function CardVariant({ items }) {
725
934
  return /* @__PURE__ */ jsxs6(Fragment2, { children: [
726
- /* @__PURE__ */ jsx18(Stack6, { gap: "sm", hiddenFrom: "sm", children: items.map((item, i) => /* @__PURE__ */ jsxs6(Fragment, { children: [
727
- /* @__PURE__ */ jsx18(CardStep, { item, index: i }),
728
- i < items.length - 1 && /* @__PURE__ */ jsx18(Box4, { style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx18(CardArrow, { direction: "down" }) })
935
+ /* @__PURE__ */ jsx19(Stack7, { gap: "sm", hiddenFrom: "sm", children: items.map((item, i) => /* @__PURE__ */ jsxs6(Fragment, { children: [
936
+ /* @__PURE__ */ jsx19(CardStep, { item, index: i }),
937
+ i < items.length - 1 && /* @__PURE__ */ jsx19(Box4, { style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx19(CardArrow, { direction: "down" }) })
729
938
  ] }, i)) }),
730
- /* @__PURE__ */ jsx18(Group3, { wrap: "nowrap", align: "stretch", gap: 0, visibleFrom: "sm", children: items.map((item, i) => /* @__PURE__ */ jsxs6(Fragment, { children: [
731
- /* @__PURE__ */ jsx18(Box4, { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx18(CardStep, { item, index: i }) }),
732
- i < items.length - 1 && /* @__PURE__ */ jsx18(Box4, { style: { display: "flex", alignItems: "center", padding: "0 8px" }, children: /* @__PURE__ */ jsx18(CardArrow, { direction: "right" }) })
939
+ /* @__PURE__ */ jsx19(Group4, { wrap: "nowrap", align: "stretch", gap: 0, visibleFrom: "sm", children: items.map((item, i) => /* @__PURE__ */ jsxs6(Fragment, { children: [
940
+ /* @__PURE__ */ jsx19(Box4, { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx19(CardStep, { item, index: i }) }),
941
+ i < items.length - 1 && /* @__PURE__ */ jsx19(Box4, { style: { display: "flex", alignItems: "center", padding: "0 8px" }, children: /* @__PURE__ */ jsx19(CardArrow, { direction: "right" }) })
733
942
  ] }, i)) })
734
943
  ] });
735
944
  }
736
945
  function StripStep({ item, index }) {
737
- return /* @__PURE__ */ jsx18(Box4, { pl: "md", style: { borderLeft: "3px solid var(--mantine-color-primary-6)" }, children: /* @__PURE__ */ jsxs6(Stack6, { gap: 4, children: [
946
+ return /* @__PURE__ */ jsx19(Box4, { pl: "md", style: { borderLeft: "3px solid var(--mantine-color-primary-6)" }, children: /* @__PURE__ */ jsxs6(Stack7, { gap: 4, children: [
738
947
  /* @__PURE__ */ jsxs6(SdText.Eyebrow, { children: [
739
948
  "STEP ",
740
949
  String(index + 1).padStart(2, "0")
741
950
  ] }),
742
- /* @__PURE__ */ jsx18(SdTextBox.Card, { title: item.title, description: item.description })
951
+ /* @__PURE__ */ jsx19(SdTextBox.Card, { title: item.title, description: item.description })
743
952
  ] }) });
744
953
  }
745
954
  function Strip({ items }) {
746
- return /* @__PURE__ */ jsx18(Stack6, { gap: "xl", children: items.map((item, i) => /* @__PURE__ */ jsx18(StripStep, { item, index: i }, i)) });
955
+ return /* @__PURE__ */ jsx19(Stack7, { gap: "xl", children: items.map((item, i) => /* @__PURE__ */ jsx19(StripStep, { item, index: i }, i)) });
747
956
  }
748
957
  var SdSteps = { Bubble, Card: CardVariant, Strip };
749
958
  var SdStepsBubble = SdSteps.Bubble;
@@ -755,18 +964,18 @@ import {
755
964
  Avatar,
756
965
  Box as Box5,
757
966
  Card as Card4,
758
- Group as Group4,
759
- Rating,
967
+ Group as Group5,
968
+ Rating as Rating2,
760
969
  SimpleGrid as SimpleGrid2,
761
- Stack as Stack7
970
+ Stack as Stack8
762
971
  } from "@mantine/core";
763
- import { jsx as jsx19, jsxs as jsxs7 } from "react/jsx-runtime";
972
+ import { jsx as jsx20, jsxs as jsxs7 } from "react/jsx-runtime";
764
973
  function AuthorRow({ item }) {
765
- return /* @__PURE__ */ jsxs7(Group4, { gap: "sm", wrap: "nowrap", children: [
766
- item.avatar && /* @__PURE__ */ jsx19(Avatar, { src: item.avatar, size: "md", radius: "xl" }),
767
- !item.avatar && /* @__PURE__ */ jsx19(Avatar, { size: "md", radius: "xl", color: "primary", children: item.name.charAt(0) }),
768
- /* @__PURE__ */ jsxs7(Stack7, { gap: 0, children: [
769
- /* @__PURE__ */ jsx19(SdText.Strong, { fz: "sm", children: item.name }),
974
+ return /* @__PURE__ */ jsxs7(Group5, { gap: "sm", wrap: "nowrap", children: [
975
+ item.avatar && /* @__PURE__ */ jsx20(Avatar, { src: item.avatar, size: "md", radius: "xl" }),
976
+ !item.avatar && /* @__PURE__ */ jsx20(Avatar, { size: "md", radius: "xl", color: "primary", children: item.name.charAt(0) }),
977
+ /* @__PURE__ */ jsxs7(Stack8, { gap: 0, children: [
978
+ /* @__PURE__ */ jsx20(SdText.Strong, { fz: "sm", children: item.name }),
770
979
  /* @__PURE__ */ jsxs7(SdText.Sub, { children: [
771
980
  item.role,
772
981
  item.company ? ` \xB7 ${item.company}` : ""
@@ -776,28 +985,28 @@ function AuthorRow({ item }) {
776
985
  }
777
986
  function CardTestimonial(_a4) {
778
987
  var _b = _a4, { item } = _b, boxProps = __objRest(_b, ["item"]);
779
- return /* @__PURE__ */ jsx19(Card4, __spreadProps(__spreadValues({ h: "100%" }, boxProps), { children: /* @__PURE__ */ jsxs7(Stack7, { gap: "md", h: "100%", children: [
780
- item.rating && /* @__PURE__ */ jsx19(Rating, { value: item.rating, readOnly: true, size: "sm", color: "primary" }),
781
- /* @__PURE__ */ jsxs7(Stack7, { gap: "xs", style: { flex: 1 }, children: [
782
- /* @__PURE__ */ jsx19(SdTitle.Display, { c: "primary.6", lh: 0.8, "aria-hidden": true, children: "\u201C" }),
783
- item.lines.map((line, i) => /* @__PURE__ */ jsx19(SdText.Body, { children: line }, i))
988
+ return /* @__PURE__ */ jsx20(Card4, __spreadProps(__spreadValues({ h: "100%" }, boxProps), { children: /* @__PURE__ */ jsxs7(Stack8, { gap: "md", h: "100%", children: [
989
+ item.rating && /* @__PURE__ */ jsx20(Rating2, { value: item.rating, readOnly: true, size: "sm", color: "primary" }),
990
+ /* @__PURE__ */ jsxs7(Stack8, { gap: "xs", style: { flex: 1 }, children: [
991
+ /* @__PURE__ */ jsx20(SdTitle.Display, { c: "primary.6", lh: 0.8, "aria-hidden": true, children: "\u201C" }),
992
+ item.lines.map((line, i) => /* @__PURE__ */ jsx20(SdText.Body, { children: line }, i))
784
993
  ] }),
785
- /* @__PURE__ */ jsx19(AuthorRow, { item })
994
+ /* @__PURE__ */ jsx20(AuthorRow, { item })
786
995
  ] }) }));
787
996
  }
788
997
  function Strip2(_a4) {
789
998
  var _b = _a4, { item } = _b, boxProps = __objRest(_b, ["item"]);
790
- return /* @__PURE__ */ jsx19(Box5, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsxs7(Stack7, { gap: "md", children: [
791
- item.rating && /* @__PURE__ */ jsx19(Rating, { value: item.rating, readOnly: true, size: "sm", color: "primary" }),
792
- /* @__PURE__ */ jsxs7(Group4, { gap: 4, align: "flex-start", children: [
793
- /* @__PURE__ */ jsx19(SdTitle.Display, { c: "primary.6", lh: 0.8, "aria-hidden": true, children: "\u201C" }),
794
- /* @__PURE__ */ jsx19(Stack7, { gap: "xs", style: { flex: 1 }, children: item.lines.map((line, i) => /* @__PURE__ */ jsx19(SdText.Body, { children: line }, i)) })
999
+ return /* @__PURE__ */ jsx20(Box5, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsxs7(Stack8, { gap: "md", children: [
1000
+ item.rating && /* @__PURE__ */ jsx20(Rating2, { value: item.rating, readOnly: true, size: "sm", color: "primary" }),
1001
+ /* @__PURE__ */ jsxs7(Group5, { gap: 4, align: "flex-start", children: [
1002
+ /* @__PURE__ */ jsx20(SdTitle.Display, { c: "primary.6", lh: 0.8, "aria-hidden": true, children: "\u201C" }),
1003
+ /* @__PURE__ */ jsx20(Stack8, { gap: "xs", style: { flex: 1 }, children: item.lines.map((line, i) => /* @__PURE__ */ jsx20(SdText.Body, { children: line }, i)) })
795
1004
  ] }),
796
- /* @__PURE__ */ jsx19(AuthorRow, { item })
1005
+ /* @__PURE__ */ jsx20(AuthorRow, { item })
797
1006
  ] }) }));
798
1007
  }
799
1008
  function Grid({ items, cols = { base: 1, sm: 2, md: 3 } }) {
800
- return /* @__PURE__ */ jsx19(SimpleGrid2, { cols, spacing: "xl", style: { alignItems: "stretch" }, children: items.map((item, i) => /* @__PURE__ */ jsx19(CardTestimonial, { item }, i)) });
1009
+ return /* @__PURE__ */ jsx20(SimpleGrid2, { cols, spacing: "xl", style: { alignItems: "stretch" }, children: items.map((item, i) => /* @__PURE__ */ jsx20(CardTestimonial, { item }, i)) });
801
1010
  }
802
1011
  var SdTestimonial = {
803
1012
  /** 카드형 — 그리드 배치용 */
@@ -815,86 +1024,86 @@ var SdTestimonialGrid = SdTestimonial.Grid;
815
1024
  import {
816
1025
  Card as Card5,
817
1026
  Divider,
818
- Group as Group5,
1027
+ Group as Group6,
819
1028
  SimpleGrid as SimpleGrid3,
820
- Stack as Stack8,
1029
+ Stack as Stack9,
821
1030
  ThemeIcon as ThemeIcon3
822
1031
  } from "@mantine/core";
823
- import { IconCheck, IconX as IconX2 } from "@tabler/icons-react";
824
- import { jsx as jsx20, jsxs as jsxs8 } from "react/jsx-runtime";
1032
+ import { IconCheck as IconCheck2, IconX as IconX3 } from "@tabler/icons-react";
1033
+ import { jsx as jsx21, jsxs as jsxs8 } from "react/jsx-runtime";
825
1034
  function Default(_a4) {
826
1035
  var _b = _a4, { item, onSelect } = _b, cardProps = __objRest(_b, ["item", "onSelect"]);
827
1036
  var _a5;
828
- return /* @__PURE__ */ jsx20(Card5, __spreadProps(__spreadValues({ withBorder: true, style: { position: "relative" } }, cardProps), { children: /* @__PURE__ */ jsxs8(Stack8, { gap: "xl", children: [
829
- /* @__PURE__ */ jsxs8(Stack8, { gap: "xs", children: [
830
- /* @__PURE__ */ jsxs8(Group5, { justify: "space-between", align: "flex-start", children: [
831
- /* @__PURE__ */ jsx20(SdTitle.Card, { children: item.name }),
832
- item.isPopular && /* @__PURE__ */ jsx20(SdBadge.Primary, { children: "\uCD94\uCC9C" })
1037
+ return /* @__PURE__ */ jsx21(Card5, __spreadProps(__spreadValues({ withBorder: true, style: { position: "relative" } }, cardProps), { children: /* @__PURE__ */ jsxs8(Stack9, { gap: "xl", children: [
1038
+ /* @__PURE__ */ jsxs8(Stack9, { gap: "xs", children: [
1039
+ /* @__PURE__ */ jsxs8(Group6, { justify: "space-between", align: "flex-start", children: [
1040
+ /* @__PURE__ */ jsx21(SdTitle.Card, { children: item.name }),
1041
+ item.isPopular && /* @__PURE__ */ jsx21(SdBadge.Primary, { children: "\uCD94\uCC9C" })
833
1042
  ] }),
834
- item.description && /* @__PURE__ */ jsx20(SdText.Sub, { children: item.description })
1043
+ item.description && /* @__PURE__ */ jsx21(SdText.Sub, { children: item.description })
835
1044
  ] }),
836
- /* @__PURE__ */ jsxs8(Group5, { gap: 4, align: "baseline", children: [
837
- /* @__PURE__ */ jsx20(SdTitle.Display, { children: item.price }),
1045
+ /* @__PURE__ */ jsxs8(Group6, { gap: 4, align: "baseline", children: [
1046
+ /* @__PURE__ */ jsx21(SdTitle.Display, { children: item.price }),
838
1047
  item.period && /* @__PURE__ */ jsxs8(SdText.Sub, { children: [
839
1048
  "/ ",
840
1049
  item.period
841
1050
  ] })
842
1051
  ] }),
843
- /* @__PURE__ */ jsx20(Divider, {}),
844
- /* @__PURE__ */ jsx20(Stack8, { gap: "sm", children: item.features.map((f, i) => /* @__PURE__ */ jsxs8(Group5, { gap: "sm", wrap: "nowrap", children: [
845
- /* @__PURE__ */ jsx20(
1052
+ /* @__PURE__ */ jsx21(Divider, {}),
1053
+ /* @__PURE__ */ jsx21(Stack9, { gap: "sm", children: item.features.map((f, i) => /* @__PURE__ */ jsxs8(Group6, { gap: "sm", wrap: "nowrap", children: [
1054
+ /* @__PURE__ */ jsx21(
846
1055
  ThemeIcon3,
847
1056
  {
848
1057
  size: "xs",
849
1058
  radius: "xl",
850
1059
  color: f.included ? "primary" : "slate",
851
1060
  variant: f.included ? "filled" : "subtle",
852
- children: f.included ? /* @__PURE__ */ jsx20(IconCheck, { size: 12 }) : /* @__PURE__ */ jsx20(IconX2, { size: 12 })
1061
+ children: f.included ? /* @__PURE__ */ jsx21(IconCheck2, { size: 12 }) : /* @__PURE__ */ jsx21(IconX3, { size: 12 })
853
1062
  }
854
1063
  ),
855
- /* @__PURE__ */ jsx20(SdText.Body, { fz: "sm", c: f.included ? "slate.7" : "slate.4", children: f.text })
1064
+ /* @__PURE__ */ jsx21(SdText.Body, { fz: "sm", c: f.included ? "slate.7" : "slate.4", children: f.text })
856
1065
  ] }, i)) }),
857
- /* @__PURE__ */ jsx20(SdButton.Outline, { fullWidth: true, onClick: () => onSelect == null ? void 0 : onSelect(item), children: (_a5 = item.ctaLabel) != null ? _a5 : "\uC2DC\uC791\uD558\uAE30" })
1066
+ /* @__PURE__ */ jsx21(SdButton.Outline, { fullWidth: true, onClick: () => onSelect == null ? void 0 : onSelect(item), children: (_a5 = item.ctaLabel) != null ? _a5 : "\uC2DC\uC791\uD558\uAE30" })
858
1067
  ] }) }));
859
1068
  }
860
1069
  function Featured(_a4) {
861
1070
  var _b = _a4, { item, onSelect } = _b, cardProps = __objRest(_b, ["item", "onSelect"]);
862
1071
  var _a5;
863
- return /* @__PURE__ */ jsx20(Card5, __spreadProps(__spreadValues({ bg: "primary.6", style: { position: "relative" } }, cardProps), { children: /* @__PURE__ */ jsxs8(Stack8, { gap: "xl", children: [
864
- /* @__PURE__ */ jsxs8(Stack8, { gap: "xs", children: [
865
- /* @__PURE__ */ jsxs8(Group5, { justify: "space-between", align: "flex-start", children: [
866
- /* @__PURE__ */ jsx20(SdTitle.Card, { c: "white", children: item.name }),
867
- item.isPopular && /* @__PURE__ */ jsx20(SdBadge.Default, { c: "white", style: { borderColor: "rgba(255,255,255,0.5)" }, children: "\uCD94\uCC9C" })
1072
+ return /* @__PURE__ */ jsx21(Card5, __spreadProps(__spreadValues({ bg: "primary.6", style: { position: "relative" } }, cardProps), { children: /* @__PURE__ */ jsxs8(Stack9, { gap: "xl", children: [
1073
+ /* @__PURE__ */ jsxs8(Stack9, { gap: "xs", children: [
1074
+ /* @__PURE__ */ jsxs8(Group6, { justify: "space-between", align: "flex-start", children: [
1075
+ /* @__PURE__ */ jsx21(SdTitle.Card, { c: "white", children: item.name }),
1076
+ item.isPopular && /* @__PURE__ */ jsx21(SdBadge.Default, { c: "white", style: { borderColor: "rgba(255,255,255,0.5)" }, children: "\uCD94\uCC9C" })
868
1077
  ] }),
869
- item.description && /* @__PURE__ */ jsx20(SdText.Body, { c: "primary.1", children: item.description })
1078
+ item.description && /* @__PURE__ */ jsx21(SdText.Body, { c: "primary.1", children: item.description })
870
1079
  ] }),
871
- /* @__PURE__ */ jsxs8(Group5, { gap: 4, align: "baseline", children: [
872
- /* @__PURE__ */ jsx20(SdTitle.Display, { c: "white", children: item.price }),
1080
+ /* @__PURE__ */ jsxs8(Group6, { gap: 4, align: "baseline", children: [
1081
+ /* @__PURE__ */ jsx21(SdTitle.Display, { c: "white", children: item.price }),
873
1082
  item.period && /* @__PURE__ */ jsxs8(SdText.Body, { c: "primary.2", children: [
874
1083
  "/ ",
875
1084
  item.period
876
1085
  ] })
877
1086
  ] }),
878
- /* @__PURE__ */ jsx20(Divider, { color: "primary.4" }),
879
- /* @__PURE__ */ jsx20(Stack8, { gap: "sm", children: item.features.map((f, i) => /* @__PURE__ */ jsxs8(Group5, { gap: "sm", wrap: "nowrap", children: [
880
- /* @__PURE__ */ jsx20(
1087
+ /* @__PURE__ */ jsx21(Divider, { color: "primary.4" }),
1088
+ /* @__PURE__ */ jsx21(Stack9, { gap: "sm", children: item.features.map((f, i) => /* @__PURE__ */ jsxs8(Group6, { gap: "sm", wrap: "nowrap", children: [
1089
+ /* @__PURE__ */ jsx21(
881
1090
  ThemeIcon3,
882
1091
  {
883
1092
  size: "xs",
884
1093
  radius: "xl",
885
1094
  color: "white",
886
1095
  variant: f.included ? "filled" : "subtle",
887
- children: f.included ? /* @__PURE__ */ jsx20(IconCheck, { size: 12, color: "var(--mantine-color-primary-6)" }) : /* @__PURE__ */ jsx20(IconX2, { size: 12, color: "rgba(255,255,255,0.4)" })
1096
+ children: f.included ? /* @__PURE__ */ jsx21(IconCheck2, { size: 12, color: "var(--mantine-color-primary-6)" }) : /* @__PURE__ */ jsx21(IconX3, { size: 12, color: "rgba(255,255,255,0.4)" })
888
1097
  }
889
1098
  ),
890
- /* @__PURE__ */ jsx20(SdText.Body, { fz: "sm", c: f.included ? "white" : "primary.3", children: f.text })
1099
+ /* @__PURE__ */ jsx21(SdText.Body, { fz: "sm", c: f.included ? "white" : "primary.3", children: f.text })
891
1100
  ] }, i)) }),
892
- /* @__PURE__ */ jsx20(SdButton.White, { fullWidth: true, onClick: () => onSelect == null ? void 0 : onSelect(item), children: (_a5 = item.ctaLabel) != null ? _a5 : "\uC2DC\uC791\uD558\uAE30" })
1101
+ /* @__PURE__ */ jsx21(SdButton.White, { fullWidth: true, onClick: () => onSelect == null ? void 0 : onSelect(item), children: (_a5 = item.ctaLabel) != null ? _a5 : "\uC2DC\uC791\uD558\uAE30" })
893
1102
  ] }) }));
894
1103
  }
895
1104
  function Grid2({ items, cols = { base: 1, sm: 2, md: 3 }, onSelect }) {
896
- return /* @__PURE__ */ jsx20(SimpleGrid3, { cols, spacing: "xl", style: { alignItems: "stretch" }, children: items.map(
897
- (item, i) => item.isPopular ? /* @__PURE__ */ jsx20(Featured, { item, onSelect }, i) : /* @__PURE__ */ jsx20(Default, { item, onSelect }, i)
1105
+ return /* @__PURE__ */ jsx21(SimpleGrid3, { cols, spacing: "xl", style: { alignItems: "stretch" }, children: items.map(
1106
+ (item, i) => item.isPopular ? /* @__PURE__ */ jsx21(Featured, { item, onSelect }, i) : /* @__PURE__ */ jsx21(Default, { item, onSelect }, i)
898
1107
  ) });
899
1108
  }
900
1109
  var SdPricingCard = {
@@ -910,31 +1119,31 @@ var SdPricingCardFeatured = SdPricingCard.Featured;
910
1119
  var SdPricingCardGrid = SdPricingCard.Grid;
911
1120
 
912
1121
  // ui/molecule/Faq.tsx
913
- import { Accordion, Box as Box7, Stack as Stack9 } from "@mantine/core";
914
- import { jsx as jsx21, jsxs as jsxs9 } from "react/jsx-runtime";
1122
+ import { Accordion, Box as Box7, Stack as Stack10 } from "@mantine/core";
1123
+ import { jsx as jsx22, jsxs as jsxs9 } from "react/jsx-runtime";
915
1124
  function Default2(_a4) {
916
1125
  var _b = _a4, { items } = _b, boxProps = __objRest(_b, ["items"]);
917
- return /* @__PURE__ */ jsx21(Box7, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsx21(Accordion, { variant: "separated", radius: "md", children: items.map((item, i) => /* @__PURE__ */ jsxs9(Accordion.Item, { value: String(i), children: [
918
- /* @__PURE__ */ jsx21(Accordion.Control, { children: /* @__PURE__ */ jsx21(SdText.Strong, { fz: "sm", children: item.question }) }),
919
- /* @__PURE__ */ jsx21(Accordion.Panel, { children: /* @__PURE__ */ jsx21(SdText.Body, { fz: "sm", children: item.answer }) })
1126
+ return /* @__PURE__ */ jsx22(Box7, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsx22(Accordion, { variant: "separated", radius: "md", children: items.map((item, i) => /* @__PURE__ */ jsxs9(Accordion.Item, { value: String(i), children: [
1127
+ /* @__PURE__ */ jsx22(Accordion.Control, { children: /* @__PURE__ */ jsx22(SdText.Strong, { fz: "sm", children: item.question }) }),
1128
+ /* @__PURE__ */ jsx22(Accordion.Panel, { children: /* @__PURE__ */ jsx22(SdText.Body, { fz: "sm", children: item.answer }) })
920
1129
  ] }, i)) }) }));
921
1130
  }
922
1131
  function Filled(_a4) {
923
1132
  var _b = _a4, { items } = _b, boxProps = __objRest(_b, ["items"]);
924
- return /* @__PURE__ */ jsx21(Box7, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsx21(Accordion, { variant: "filled", radius: "md", children: items.map((item, i) => /* @__PURE__ */ jsxs9(Accordion.Item, { value: String(i), children: [
925
- /* @__PURE__ */ jsx21(Accordion.Control, { children: /* @__PURE__ */ jsx21(SdText.Strong, { fz: "sm", children: item.question }) }),
926
- /* @__PURE__ */ jsx21(Accordion.Panel, { children: /* @__PURE__ */ jsx21(SdText.Body, { fz: "sm", children: item.answer }) })
1133
+ return /* @__PURE__ */ jsx22(Box7, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsx22(Accordion, { variant: "filled", radius: "md", children: items.map((item, i) => /* @__PURE__ */ jsxs9(Accordion.Item, { value: String(i), children: [
1134
+ /* @__PURE__ */ jsx22(Accordion.Control, { children: /* @__PURE__ */ jsx22(SdText.Strong, { fz: "sm", children: item.question }) }),
1135
+ /* @__PURE__ */ jsx22(Accordion.Panel, { children: /* @__PURE__ */ jsx22(SdText.Body, { fz: "sm", children: item.answer }) })
927
1136
  ] }, i)) }) }));
928
1137
  }
929
1138
  function WithHeader(_a4) {
930
1139
  var _b = _a4, { label, title, description, items } = _b, boxProps = __objRest(_b, ["label", "title", "description", "items"]);
931
- return /* @__PURE__ */ jsxs9(Stack9, __spreadProps(__spreadValues({ gap: "xl" }, boxProps), { children: [
932
- /* @__PURE__ */ jsxs9(Stack9, { gap: "xs", children: [
933
- label && /* @__PURE__ */ jsx21(SdText.Eyebrow, { children: label }),
934
- /* @__PURE__ */ jsx21(SdTitle.Section, { children: title }),
935
- description && /* @__PURE__ */ jsx21(SdText.Body, { children: description })
1140
+ return /* @__PURE__ */ jsxs9(Stack10, __spreadProps(__spreadValues({ gap: "xl" }, boxProps), { children: [
1141
+ /* @__PURE__ */ jsxs9(Stack10, { gap: "xs", children: [
1142
+ label && /* @__PURE__ */ jsx22(SdText.Eyebrow, { children: label }),
1143
+ /* @__PURE__ */ jsx22(SdTitle.Section, { children: title }),
1144
+ description && /* @__PURE__ */ jsx22(SdText.Body, { children: description })
936
1145
  ] }),
937
- /* @__PURE__ */ jsx21(Default2, { items })
1146
+ /* @__PURE__ */ jsx22(Default2, { items })
938
1147
  ] }));
939
1148
  }
940
1149
  var SdFaq = {
@@ -950,8 +1159,8 @@ var SdFaqFilled = SdFaq.Filled;
950
1159
  var SdFaqWithHeader = SdFaq.WithHeader;
951
1160
 
952
1161
  // ui/molecule/Cta.tsx
953
- import { Box as Box8, Center as Center2, Group as Group6, Stack as Stack10 } from "@mantine/core";
954
- import { jsx as jsx22, jsxs as jsxs10 } from "react/jsx-runtime";
1162
+ import { Box as Box8, Center as Center2, Group as Group7, Stack as Stack11 } from "@mantine/core";
1163
+ import { jsx as jsx23, jsxs as jsxs10 } from "react/jsx-runtime";
955
1164
  function Banner(_a4) {
956
1165
  var _b = _a4, {
957
1166
  label,
@@ -970,15 +1179,15 @@ function Banner(_a4) {
970
1179
  "onPrimary",
971
1180
  "onSecondary"
972
1181
  ]);
973
- return /* @__PURE__ */ jsx22(Box8, __spreadProps(__spreadValues({ bg: "primary.7", py: { base: "xl", md: 80 }, px: { base: "md", md: "xl" } }, boxProps), { children: /* @__PURE__ */ jsx22(Center2, { children: /* @__PURE__ */ jsxs10(Stack10, { gap: "xl", align: "center", maw: 600, children: [
974
- /* @__PURE__ */ jsxs10(Stack10, { gap: "sm", align: "center", children: [
975
- label && /* @__PURE__ */ jsx22(SdText.Eyebrow, { c: "primary.3", children: label }),
976
- /* @__PURE__ */ jsx22(SdTitle.Section, { c: "white", ta: "center", children: title }),
977
- description && /* @__PURE__ */ jsx22(SdText.Body, { c: "primary.2", ta: "center", children: description })
1182
+ return /* @__PURE__ */ jsx23(Box8, __spreadProps(__spreadValues({ bg: "primary.7", py: { base: "xl", md: 80 }, px: { base: "md", md: "xl" } }, boxProps), { children: /* @__PURE__ */ jsx23(Center2, { children: /* @__PURE__ */ jsxs10(Stack11, { gap: "xl", align: "center", maw: 600, children: [
1183
+ /* @__PURE__ */ jsxs10(Stack11, { gap: "sm", align: "center", children: [
1184
+ label && /* @__PURE__ */ jsx23(SdText.Eyebrow, { c: "primary.3", children: label }),
1185
+ /* @__PURE__ */ jsx23(SdTitle.Section, { c: "white", ta: "center", children: title }),
1186
+ description && /* @__PURE__ */ jsx23(SdText.Body, { c: "primary.2", ta: "center", children: description })
978
1187
  ] }),
979
- /* @__PURE__ */ jsxs10(Group6, { gap: "sm", children: [
980
- /* @__PURE__ */ jsx22(SdButton.White, { size: "md", onClick: onPrimary, children: primaryLabel }),
981
- secondaryLabel && /* @__PURE__ */ jsx22(SdButton.Ghost, { size: "md", c: "primary.2", onClick: onSecondary, children: secondaryLabel })
1188
+ /* @__PURE__ */ jsxs10(Group7, { gap: "sm", children: [
1189
+ /* @__PURE__ */ jsx23(SdButton.White, { size: "md", onClick: onPrimary, children: primaryLabel }),
1190
+ secondaryLabel && /* @__PURE__ */ jsx23(SdButton.Ghost, { size: "md", c: "primary.2", onClick: onSecondary, children: secondaryLabel })
982
1191
  ] })
983
1192
  ] }) }) }));
984
1193
  }
@@ -1000,7 +1209,7 @@ function Subtle(_a4) {
1000
1209
  "onPrimary",
1001
1210
  "onSecondary"
1002
1211
  ]);
1003
- return /* @__PURE__ */ jsx22(
1212
+ return /* @__PURE__ */ jsx23(
1004
1213
  Box8,
1005
1214
  __spreadProps(__spreadValues({
1006
1215
  bg: "primary.0",
@@ -1008,15 +1217,15 @@ function Subtle(_a4) {
1008
1217
  px: { base: "md", md: "xl" },
1009
1218
  style: { borderRadius: "var(--mantine-radius-lg)" }
1010
1219
  }, boxProps), {
1011
- children: /* @__PURE__ */ jsx22(Center2, { children: /* @__PURE__ */ jsxs10(Stack10, { gap: "lg", align: "center", maw: 560, children: [
1012
- /* @__PURE__ */ jsxs10(Stack10, { gap: "sm", align: "center", children: [
1013
- label && /* @__PURE__ */ jsx22(SdText.Eyebrow, { children: label }),
1014
- /* @__PURE__ */ jsx22(SdTitle.Section, { ta: "center", children: title }),
1015
- description && /* @__PURE__ */ jsx22(SdText.Body, { ta: "center", children: description })
1220
+ children: /* @__PURE__ */ jsx23(Center2, { children: /* @__PURE__ */ jsxs10(Stack11, { gap: "lg", align: "center", maw: 560, children: [
1221
+ /* @__PURE__ */ jsxs10(Stack11, { gap: "sm", align: "center", children: [
1222
+ label && /* @__PURE__ */ jsx23(SdText.Eyebrow, { children: label }),
1223
+ /* @__PURE__ */ jsx23(SdTitle.Section, { ta: "center", children: title }),
1224
+ description && /* @__PURE__ */ jsx23(SdText.Body, { ta: "center", children: description })
1016
1225
  ] }),
1017
- /* @__PURE__ */ jsxs10(Group6, { gap: "sm", children: [
1018
- /* @__PURE__ */ jsx22(SdButton.Primary, { size: "md", onClick: onPrimary, children: primaryLabel }),
1019
- secondaryLabel && /* @__PURE__ */ jsx22(SdButton.Outline, { size: "md", onClick: onSecondary, children: secondaryLabel })
1226
+ /* @__PURE__ */ jsxs10(Group7, { gap: "sm", children: [
1227
+ /* @__PURE__ */ jsx23(SdButton.Primary, { size: "md", onClick: onPrimary, children: primaryLabel }),
1228
+ secondaryLabel && /* @__PURE__ */ jsx23(SdButton.Outline, { size: "md", onClick: onSecondary, children: secondaryLabel })
1020
1229
  ] })
1021
1230
  ] }) })
1022
1231
  })
@@ -1040,7 +1249,7 @@ function Inline(_a4) {
1040
1249
  "onPrimary",
1041
1250
  "onSecondary"
1042
1251
  ]);
1043
- return /* @__PURE__ */ jsx22(
1252
+ return /* @__PURE__ */ jsx23(
1044
1253
  Box8,
1045
1254
  __spreadProps(__spreadValues({
1046
1255
  py: { base: "xl", md: 48 },
@@ -1050,15 +1259,15 @@ function Inline(_a4) {
1050
1259
  borderBottom: "1px solid var(--mantine-color-slate-2)"
1051
1260
  }
1052
1261
  }, boxProps), {
1053
- children: /* @__PURE__ */ jsxs10(Group6, { justify: "space-between", align: "center", gap: "xl", children: [
1054
- /* @__PURE__ */ jsxs10(Stack10, { gap: "xs", style: { flex: 1 }, children: [
1055
- label && /* @__PURE__ */ jsx22(SdText.Eyebrow, { children: label }),
1056
- /* @__PURE__ */ jsx22(SdTitle.Card, { children: title }),
1057
- description && /* @__PURE__ */ jsx22(SdText.Sub, { children: description })
1262
+ children: /* @__PURE__ */ jsxs10(Group7, { justify: "space-between", align: "center", gap: "xl", children: [
1263
+ /* @__PURE__ */ jsxs10(Stack11, { gap: "xs", style: { flex: 1 }, children: [
1264
+ label && /* @__PURE__ */ jsx23(SdText.Eyebrow, { children: label }),
1265
+ /* @__PURE__ */ jsx23(SdTitle.Card, { children: title }),
1266
+ description && /* @__PURE__ */ jsx23(SdText.Sub, { children: description })
1058
1267
  ] }),
1059
- /* @__PURE__ */ jsxs10(Group6, { gap: "sm", wrap: "nowrap", children: [
1060
- /* @__PURE__ */ jsx22(SdButton.Primary, { size: "md", onClick: onPrimary, children: primaryLabel }),
1061
- secondaryLabel && /* @__PURE__ */ jsx22(SdButton.Outline, { size: "md", onClick: onSecondary, children: secondaryLabel })
1268
+ /* @__PURE__ */ jsxs10(Group7, { gap: "sm", wrap: "nowrap", children: [
1269
+ /* @__PURE__ */ jsx23(SdButton.Primary, { size: "md", onClick: onPrimary, children: primaryLabel }),
1270
+ secondaryLabel && /* @__PURE__ */ jsx23(SdButton.Outline, { size: "md", onClick: onSecondary, children: secondaryLabel })
1062
1271
  ] })
1063
1272
  ] })
1064
1273
  })
@@ -1077,33 +1286,33 @@ var SdCtaSubtle = SdCta.Subtle;
1077
1286
  var SdCtaInline = SdCta.Inline;
1078
1287
 
1079
1288
  // ui/molecule/Solution.tsx
1080
- import { useState } from "react";
1081
- import { Button as Button2, Divider as Divider2, Group as Group7, Stack as Stack12, ThemeIcon as ThemeIcon4 } from "@mantine/core";
1289
+ import { useState as useState2 } from "react";
1290
+ import { Button as Button2, Divider as Divider2, Group as Group8, Stack as Stack13, ThemeIcon as ThemeIcon4 } from "@mantine/core";
1082
1291
  import Link3 from "next/link";
1083
1292
 
1084
1293
  // ui/molecule/SolutionCard.tsx
1085
- import { Button, Card as Card6, SimpleGrid as SimpleGrid4, Stack as Stack11 } from "@mantine/core";
1294
+ import { Button, Card as Card6, SimpleGrid as SimpleGrid4, Stack as Stack12 } from "@mantine/core";
1086
1295
  import Link2 from "next/link";
1087
- import { jsx as jsx23, jsxs as jsxs11 } from "react/jsx-runtime";
1296
+ import { jsx as jsx24, jsxs as jsxs11 } from "react/jsx-runtime";
1088
1297
  function SolutionCardItem(_a4) {
1089
1298
  var _b = _a4, { item, onSelect } = _b, cardProps = __objRest(_b, ["item", "onSelect"]);
1090
1299
  var _a5, _b2;
1091
- return /* @__PURE__ */ jsx23(Card6, __spreadProps(__spreadValues({ withBorder: true }, cardProps), { children: /* @__PURE__ */ jsxs11(Stack11, { gap: "md", children: [
1300
+ return /* @__PURE__ */ jsx24(Card6, __spreadProps(__spreadValues({ withBorder: true, h: "100%", style: { display: "flex", flexDirection: "column" } }, cardProps), { children: /* @__PURE__ */ jsxs11(Stack12, { gap: "md", style: { flex: 1 }, children: [
1092
1301
  item.icon,
1093
- /* @__PURE__ */ jsx23(SdBadge.Primary, { children: item.category }),
1094
- /* @__PURE__ */ jsx23(SdTitle.Card, { children: item.title }),
1095
- /* @__PURE__ */ jsx23(SdText.Body, { children: item.description }),
1096
- item.href ? /* @__PURE__ */ jsxs11(Button, { variant: "subtle", color: "slate", component: Link2, href: item.href, children: [
1302
+ /* @__PURE__ */ jsx24(SdBadge.Primary, { children: item.category }),
1303
+ /* @__PURE__ */ jsx24(SdTitle.Card, { children: item.title }),
1304
+ /* @__PURE__ */ jsx24(SdText.Body, { children: item.description }),
1305
+ item.href ? /* @__PURE__ */ jsxs11(Button, { variant: "subtle", color: "slate", component: Link2, href: item.href, mt: "auto", children: [
1097
1306
  (_a5 = item.ctaLabel) != null ? _a5 : "\uC790\uC138\uD788 \uBCF4\uAE30",
1098
1307
  " \u2192"
1099
- ] }) : /* @__PURE__ */ jsxs11(SdButton.Ghost, { onClick: () => onSelect == null ? void 0 : onSelect(item), children: [
1308
+ ] }) : /* @__PURE__ */ jsxs11(SdButton.Ghost, { onClick: () => onSelect == null ? void 0 : onSelect(item), mt: "auto", children: [
1100
1309
  (_b2 = item.ctaLabel) != null ? _b2 : "\uC790\uC138\uD788 \uBCF4\uAE30",
1101
1310
  " \u2192"
1102
1311
  ] })
1103
1312
  ] }) }));
1104
1313
  }
1105
1314
  function Grid3({ items, cols = { base: 1, sm: 2, md: 3 }, onSelect }) {
1106
- return /* @__PURE__ */ jsx23(SimpleGrid4, { cols, spacing: "xl", children: items.map((item, i) => /* @__PURE__ */ jsx23(SolutionCardItem, { item, onSelect }, i)) });
1315
+ return /* @__PURE__ */ jsx24(SimpleGrid4, { cols, spacing: "xl", children: items.map((item, i) => /* @__PURE__ */ jsx24(SolutionCardItem, { item, onSelect }, i)) });
1107
1316
  }
1108
1317
  var SdSolutionCard = {
1109
1318
  /** 단일 compact 카드 */
@@ -1115,27 +1324,27 @@ var SdSolutionCardItem = SdSolutionCard.Item;
1115
1324
  var SdSolutionCardGrid = SdSolutionCard.Grid;
1116
1325
 
1117
1326
  // ui/molecule/Solution.tsx
1118
- import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
1327
+ import { jsx as jsx25, jsxs as jsxs12 } from "react/jsx-runtime";
1119
1328
  function Filtered({ items, allLabel = "\uC804\uCCB4", cols, onSelect }) {
1120
1329
  const categories = ["all", ...Array.from(new Set(items.map((i) => i.category)))];
1121
- const [active, setActive] = useState("all");
1330
+ const [active, setActive] = useState2("all");
1122
1331
  const filtered = active === "all" ? items : items.filter((i) => i.category === active);
1123
- return /* @__PURE__ */ jsxs12(Stack12, { gap: "xl", children: [
1124
- /* @__PURE__ */ jsx24(SdTabs.Pills, { value: active, onChange: (v) => setActive(v != null ? v : "all"), children: /* @__PURE__ */ jsx24(SdTabs.Pills.List, { children: categories.map((cat) => /* @__PURE__ */ jsx24(SdTabs.Pills.Tab, { value: cat, children: cat === "all" ? allLabel : cat }, cat)) }) }),
1125
- /* @__PURE__ */ jsx24(SdSolutionCard.Grid, { items: filtered, cols, onSelect })
1332
+ return /* @__PURE__ */ jsxs12(Stack13, { gap: "xl", children: [
1333
+ /* @__PURE__ */ jsx25(SdTabs.Pills, { value: active, onChange: (v) => setActive(v != null ? v : "all"), children: /* @__PURE__ */ jsx25(SdTabs.Pills.List, { children: categories.map((cat) => /* @__PURE__ */ jsx25(SdTabs.Pills.Tab, { value: cat, children: cat === "all" ? allLabel : cat }, cat)) }) }),
1334
+ /* @__PURE__ */ jsx25(SdSolutionCard.Grid, { items: filtered, cols, onSelect })
1126
1335
  ] });
1127
1336
  }
1128
1337
  function List({ items, onSelect }) {
1129
- return /* @__PURE__ */ jsx24(Stack12, { gap: 0, children: items.map((item, i) => {
1338
+ return /* @__PURE__ */ jsx25(Stack13, { gap: 0, children: items.map((item, i) => {
1130
1339
  var _a4, _b;
1131
1340
  return /* @__PURE__ */ jsxs12("div", { children: [
1132
- i > 0 && /* @__PURE__ */ jsx24(Divider2, {}),
1133
- /* @__PURE__ */ jsxs12(Group7, { align: "flex-start", py: "lg", gap: "lg", children: [
1134
- item.icon && /* @__PURE__ */ jsx24(ThemeIcon4, { variant: "light", color: "primary", size: "xl", radius: "md", children: item.icon }),
1135
- /* @__PURE__ */ jsxs12(Stack12, { gap: "xs", style: { flex: 1 }, children: [
1136
- /* @__PURE__ */ jsx24(SdBadge.Primary, { children: item.category }),
1137
- /* @__PURE__ */ jsx24(SdTitle.Card, { children: item.title }),
1138
- /* @__PURE__ */ jsx24(SdText.Body, { children: item.description }),
1341
+ i > 0 && /* @__PURE__ */ jsx25(Divider2, {}),
1342
+ /* @__PURE__ */ jsxs12(Group8, { align: "flex-start", py: "lg", gap: "lg", children: [
1343
+ item.icon && /* @__PURE__ */ jsx25(ThemeIcon4, { variant: "light", color: "primary", size: "xl", radius: "md", children: item.icon }),
1344
+ /* @__PURE__ */ jsxs12(Stack13, { gap: "xs", style: { flex: 1 }, children: [
1345
+ /* @__PURE__ */ jsx25(SdBadge.Primary, { children: item.category }),
1346
+ /* @__PURE__ */ jsx25(SdTitle.Card, { children: item.title }),
1347
+ /* @__PURE__ */ jsx25(SdText.Body, { children: item.description }),
1139
1348
  item.href ? /* @__PURE__ */ jsxs12(
1140
1349
  Button2,
1141
1350
  {
@@ -1176,7 +1385,7 @@ var SdSolutionList = SdSolution.List;
1176
1385
 
1177
1386
  // ui/molecule/Clients.tsx
1178
1387
  import { Anchor, Box as Box9, SimpleGrid as SimpleGrid5, Tooltip } from "@mantine/core";
1179
- import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
1388
+ import { jsx as jsx26, jsxs as jsxs13 } from "react/jsx-runtime";
1180
1389
  var grayStyle = {
1181
1390
  filter: "grayscale(1) opacity(0.5)",
1182
1391
  transition: "filter 0.25s"
@@ -1185,12 +1394,18 @@ var colorStyle = {
1185
1394
  filter: "grayscale(0) opacity(1)"
1186
1395
  };
1187
1396
  function LogoImage({ client, height }) {
1188
- return /* @__PURE__ */ jsx25(Tooltip, { label: client.name, withArrow: true, children: /* @__PURE__ */ jsx25(Anchor, { href: client.url, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx25(
1397
+ return /* @__PURE__ */ jsx26(Tooltip, { label: client.name, withArrow: true, children: /* @__PURE__ */ jsx26(Anchor, { href: client.url, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx26(
1189
1398
  "img",
1190
1399
  {
1191
1400
  src: client.logo,
1192
1401
  alt: client.name,
1193
- style: __spreadValues({ height, width: "auto", objectFit: "contain", display: "block" }, grayStyle),
1402
+ style: __spreadValues({
1403
+ height,
1404
+ width: "auto",
1405
+ maxWidth: "100%",
1406
+ objectFit: "contain",
1407
+ display: "block"
1408
+ }, grayStyle),
1194
1409
  onMouseEnter: (e) => Object.assign(e.currentTarget.style, colorStyle),
1195
1410
  onMouseLeave: (e) => Object.assign(e.currentTarget.style, grayStyle)
1196
1411
  }
@@ -1201,16 +1416,19 @@ function Grid4({
1201
1416
  cols = { base: 2, sm: 3, md: 4, lg: 6 },
1202
1417
  logoHeight = 40
1203
1418
  }) {
1204
- return /* @__PURE__ */ jsx25(SimpleGrid5, { cols, spacing: "xl", children: items.map((client, i) => /* @__PURE__ */ jsx25(
1419
+ return /* @__PURE__ */ jsx26(SimpleGrid5, { cols, spacing: "xl", children: items.map((client, i) => /* @__PURE__ */ jsx26(
1205
1420
  Box9,
1206
1421
  {
1207
1422
  style: {
1208
1423
  display: "flex",
1209
1424
  alignItems: "center",
1210
1425
  justifyContent: "center",
1211
- padding: "12px 8px"
1426
+ padding: "12px 8px",
1427
+ minWidth: 0,
1428
+ // 그리드 트랙이 이미지 intrinsic width로 밀려 깨지는 것 방지
1429
+ overflow: "hidden"
1212
1430
  },
1213
- children: /* @__PURE__ */ jsx25(LogoImage, { client, height: logoHeight })
1431
+ children: /* @__PURE__ */ jsx26(LogoImage, { client, height: logoHeight })
1214
1432
  },
1215
1433
  i
1216
1434
  )) });
@@ -1219,8 +1437,8 @@ var KEYFRAME = `@keyframes sd-clients-marquee { from { transform: translateX(0)
1219
1437
  function Marquee({ items, speed = 40, logoHeight = 36, gap = 64 }) {
1220
1438
  const doubled = [...items, ...items];
1221
1439
  return /* @__PURE__ */ jsxs13(Box9, { style: { overflow: "hidden" }, children: [
1222
- /* @__PURE__ */ jsx25("style", { children: KEYFRAME }),
1223
- /* @__PURE__ */ jsx25(
1440
+ /* @__PURE__ */ jsx26("style", { children: KEYFRAME }),
1441
+ /* @__PURE__ */ jsx26(
1224
1442
  Box9,
1225
1443
  {
1226
1444
  style: {
@@ -1238,7 +1456,7 @@ function Marquee({ items, speed = 40, logoHeight = 36, gap = 64 }) {
1238
1456
  ;
1239
1457
  e.currentTarget.style.animationPlayState = "running";
1240
1458
  },
1241
- children: doubled.map((client, i) => /* @__PURE__ */ jsx25(LogoImage, { client, height: logoHeight }, i))
1459
+ children: doubled.map((client, i) => /* @__PURE__ */ jsx26(LogoImage, { client, height: logoHeight }, i))
1242
1460
  }
1243
1461
  )
1244
1462
  ] });
@@ -1253,12 +1471,12 @@ var SdClientsGrid = Grid4;
1253
1471
  var SdClientsMarquee = Marquee;
1254
1472
 
1255
1473
  // ui/molecule/Map.tsx
1256
- import { useState as useState2 } from "react";
1257
- import { Box as Box10, Stack as Stack13 } from "@mantine/core";
1258
- import { jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
1474
+ import { useState as useState3 } from "react";
1475
+ import { Box as Box10, Stack as Stack14 } from "@mantine/core";
1476
+ import { jsx as jsx27, jsxs as jsxs14 } from "react/jsx-runtime";
1259
1477
  function MapFrame({ address, height }) {
1260
- return /* @__PURE__ */ jsxs14(Stack13, { gap: "xs", children: [
1261
- /* @__PURE__ */ jsx26(Box10, { style: { borderRadius: "var(--mantine-radius-md)", overflow: "hidden", height }, children: /* @__PURE__ */ jsx26(
1478
+ return /* @__PURE__ */ jsxs14(Stack14, { gap: "xs", children: [
1479
+ /* @__PURE__ */ jsx27(Box10, { style: { borderRadius: "var(--mantine-radius-md)", overflow: "hidden", height }, children: /* @__PURE__ */ jsx27(
1262
1480
  "iframe",
1263
1481
  {
1264
1482
  src: address.embbedUrl,
@@ -1282,18 +1500,18 @@ function MapFrame({ address, height }) {
1282
1500
  function Single(_a4) {
1283
1501
  var _b = _a4, { address, height = 400 } = _b, boxProps = __objRest(_b, ["address", "height"]);
1284
1502
  if (!address.embbedUrl) return null;
1285
- return /* @__PURE__ */ jsx26(Box10, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsx26(MapFrame, { address, height }) }));
1503
+ return /* @__PURE__ */ jsx27(Box10, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsx27(MapFrame, { address, height }) }));
1286
1504
  }
1287
1505
  function Tabs2({ addresses, height = 400 }) {
1288
1506
  var _a4, _b, _c;
1289
1507
  const mapped = addresses.filter((a) => a.embbedUrl);
1290
- const [active, setActive] = useState2((_b = (_a4 = mapped[0]) == null ? void 0 : _a4.label) != null ? _b : "");
1508
+ const [active, setActive] = useState3((_b = (_a4 = mapped[0]) == null ? void 0 : _a4.label) != null ? _b : "");
1291
1509
  if (mapped.length === 0) return null;
1292
- if (mapped.length === 1) return /* @__PURE__ */ jsx26(MapFrame, { address: mapped[0], height });
1510
+ if (mapped.length === 1) return /* @__PURE__ */ jsx27(MapFrame, { address: mapped[0], height });
1293
1511
  const current = (_c = mapped.find((a) => a.label === active)) != null ? _c : mapped[0];
1294
- return /* @__PURE__ */ jsxs14(Stack13, { gap: "md", children: [
1295
- /* @__PURE__ */ jsx26(SdTabs.Pills, { value: active, onChange: (v) => setActive(v != null ? v : mapped[0].label), children: /* @__PURE__ */ jsx26(SdTabs.Pills.List, { children: mapped.map((addr) => /* @__PURE__ */ jsx26(SdTabs.Pills.Tab, { value: addr.label, children: addr.label }, addr.label)) }) }),
1296
- /* @__PURE__ */ jsx26(MapFrame, { address: current, height })
1512
+ return /* @__PURE__ */ jsxs14(Stack14, { gap: "md", children: [
1513
+ /* @__PURE__ */ jsx27(SdTabs.Pills, { value: active, onChange: (v) => setActive(v != null ? v : mapped[0].label), children: /* @__PURE__ */ jsx27(SdTabs.Pills.List, { children: mapped.map((addr) => /* @__PURE__ */ jsx27(SdTabs.Pills.Tab, { value: addr.label, children: addr.label }, addr.label)) }) }),
1514
+ /* @__PURE__ */ jsx27(MapFrame, { address: current, height })
1297
1515
  ] });
1298
1516
  }
1299
1517
  var SdMap = {
@@ -1305,11 +1523,78 @@ var SdMap = {
1305
1523
  var SdMapSingle = Single;
1306
1524
  var SdMapTabs = Tabs2;
1307
1525
 
1526
+ // ui/molecule/Breadcrumb.tsx
1527
+ import { Box as Box11, Breadcrumbs } from "@mantine/core";
1528
+ import { usePathname } from "next/navigation";
1529
+ import { IconChevronRight, IconHome } from "@tabler/icons-react";
1530
+ import { jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
1531
+ function normalizePath(href) {
1532
+ if (!href) return "";
1533
+ const trimmed = href.replace(/\/+$/, "");
1534
+ return trimmed === "" ? "/" : trimmed;
1535
+ }
1536
+ function buildTrail(navItems, currentHref) {
1537
+ const target = normalizePath(currentHref);
1538
+ const byId = new Map(navItems.map((item) => [item.id, item]));
1539
+ let current = navItems.find((item) => normalizePath(item.href) === target);
1540
+ if (!current) {
1541
+ current = navItems.filter((item) => item.href && target.startsWith(normalizePath(item.href) + "/")).sort((a, b) => normalizePath(b.href).length - normalizePath(a.href).length)[0];
1542
+ }
1543
+ if (!current) return [];
1544
+ const trail = [];
1545
+ const seen = /* @__PURE__ */ new Set();
1546
+ let node = current;
1547
+ while (node && !seen.has(node.id)) {
1548
+ seen.add(node.id);
1549
+ trail.unshift(node);
1550
+ node = node.parentId != null ? byId.get(node.parentId) : void 0;
1551
+ }
1552
+ return trail;
1553
+ }
1554
+ function SdBreadcrumb(_a4) {
1555
+ var _b = _a4, {
1556
+ navItems,
1557
+ currentHref,
1558
+ homeHref = "/",
1559
+ homeLabel = "\uD648"
1560
+ } = _b, boxProps = __objRest(_b, [
1561
+ "navItems",
1562
+ "currentHref",
1563
+ "homeHref",
1564
+ "homeLabel"
1565
+ ]);
1566
+ var _a5;
1567
+ const pathname = usePathname();
1568
+ const trail = buildTrail(navItems, (_a5 = currentHref != null ? currentHref : pathname) != null ? _a5 : "");
1569
+ return /* @__PURE__ */ jsx28(Box11, __spreadProps(__spreadValues({}, boxProps), { children: /* @__PURE__ */ jsxs15(
1570
+ Breadcrumbs,
1571
+ {
1572
+ separator: /* @__PURE__ */ jsx28(IconChevronRight, { size: 14, stroke: 2, color: "var(--mantine-color-slate-4)" }),
1573
+ separatorMargin: "xs",
1574
+ children: [
1575
+ /* @__PURE__ */ jsx28(
1576
+ SdLink.Sub,
1577
+ {
1578
+ href: homeHref,
1579
+ "aria-label": homeLabel,
1580
+ style: { display: "inline-flex", alignItems: "center" },
1581
+ children: /* @__PURE__ */ jsx28(IconHome, { size: 16, stroke: 2 })
1582
+ }
1583
+ ),
1584
+ trail.map((item, i) => {
1585
+ const isLast = i === trail.length - 1;
1586
+ return isLast ? /* @__PURE__ */ jsx28(SdLink.Body, { children: item.label }, item.id) : /* @__PURE__ */ jsx28(SdLink.Sub, { href: item.href, children: item.label }, item.id);
1587
+ })
1588
+ ]
1589
+ }
1590
+ ) }));
1591
+ }
1592
+
1308
1593
  // ui/organism/HeroCarousel.tsx
1309
1594
  import { Carousel } from "@mantine/carousel";
1310
- import { Anchor as Anchor2, Box as Box11, Group as Group8, Stack as Stack14 } from "@mantine/core";
1595
+ import { Anchor as Anchor2, Box as Box12, Group as Group9, Stack as Stack15 } from "@mantine/core";
1311
1596
  import { IconArrowNarrowRight } from "@tabler/icons-react";
1312
- import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
1597
+ import { Fragment as Fragment3, jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
1313
1598
  var variantMap = {
1314
1599
  primary: SdButton.Primary,
1315
1600
  secondary: SdButton.Secondary,
@@ -1319,25 +1604,25 @@ var variantMap = {
1319
1604
  function CtaButton({ cta }) {
1320
1605
  var _a4;
1321
1606
  const Button3 = variantMap[(_a4 = cta.variant) != null ? _a4 : "primary"];
1322
- return /* @__PURE__ */ jsx27(Anchor2, { href: cta.href, underline: "never", children: cta.icon ? /* @__PURE__ */ jsx27(Button3, { size: "md", rightSection: /* @__PURE__ */ jsx27(IconArrowNarrowRight, {}), children: cta.label }) : /* @__PURE__ */ jsx27(Button3, { size: "md", children: cta.label }) });
1607
+ return /* @__PURE__ */ jsx29(Anchor2, { href: cta.href, underline: "never", children: cta.icon ? /* @__PURE__ */ jsx29(Button3, { size: "md", rightSection: /* @__PURE__ */ jsx29(IconArrowNarrowRight, {}), children: cta.label }) : /* @__PURE__ */ jsx29(Button3, { size: "md", children: cta.label }) });
1323
1608
  }
1324
1609
  function HeroCarousel({ slides, children }) {
1325
- if (children) return /* @__PURE__ */ jsx27(Fragment3, { children });
1610
+ if (children) return /* @__PURE__ */ jsx29(Fragment3, { children });
1326
1611
  const filterdSlides = filterAndSort(slides);
1327
- return /* @__PURE__ */ jsx27(Carousel, { withIndicators: true, height: "60svh", children: filterdSlides.map((slide, i) => /* @__PURE__ */ jsx27(Carousel.Slide, { children: /* @__PURE__ */ jsx27(
1328
- Box11,
1612
+ return /* @__PURE__ */ jsx29(Carousel, { withIndicators: true, height: "60svh", children: filterdSlides.map((slide, i) => /* @__PURE__ */ jsx29(Carousel.Slide, { children: /* @__PURE__ */ jsx29(
1613
+ Box12,
1329
1614
  {
1330
1615
  style: {
1331
1616
  height: "100%",
1332
- backgroundImage: `url(${slide.image})`,
1617
+ backgroundImage: `linear-gradient(rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.45)), url(${slide.image})`,
1333
1618
  backgroundSize: "cover",
1334
1619
  backgroundPosition: "center",
1335
1620
  display: "flex",
1336
1621
  alignItems: "center",
1337
1622
  justifyContent: "center"
1338
1623
  },
1339
- children: /* @__PURE__ */ jsxs15(Stack14, { align: "center", style: { textAlign: "center", maxWidth: 780 }, px: "xl", children: [
1340
- /* @__PURE__ */ jsx27(
1624
+ children: /* @__PURE__ */ jsxs16(Stack15, { align: "center", style: { textAlign: "center", maxWidth: 780 }, px: "xl", children: [
1625
+ /* @__PURE__ */ jsx29(
1341
1626
  SdTextBox.Hero,
1342
1627
  {
1343
1628
  title: slide.title,
@@ -1346,30 +1631,77 @@ function HeroCarousel({ slides, children }) {
1346
1631
  align: "center"
1347
1632
  }
1348
1633
  ),
1349
- slide.ctas && slide.ctas.length > 0 && /* @__PURE__ */ jsx27(Group8, { gap: "sm", mt: "md", children: slide.ctas.map((cta, i2) => /* @__PURE__ */ jsx27(CtaButton, { cta }, cta.href)) })
1634
+ slide.ctas && slide.ctas.length > 0 && /* @__PURE__ */ jsx29(Group9, { gap: "sm", mt: "md", children: slide.ctas.map((cta, i2) => /* @__PURE__ */ jsx29(CtaButton, { cta }, cta.href)) })
1350
1635
  ] })
1351
1636
  }
1352
1637
  ) }, i)) });
1353
1638
  }
1354
1639
 
1355
1640
  // ui/organism/Header.tsx
1356
- import { Box as Box12, Burger, Drawer, Group as Group9, NavLink, Stack as Stack15 } from "@mantine/core";
1641
+ import { Box as Box13, Burger, Drawer, Group as Group10, Menu, NavLink, Stack as Stack16 } from "@mantine/core";
1642
+ import { IconChevronDown } from "@tabler/icons-react";
1357
1643
  import { useDisclosure, useFocusWithin, useHover, useMergedRef } from "@mantine/hooks";
1358
- import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs16 } from "react/jsx-runtime";
1644
+ import { Fragment as Fragment4, jsx as jsx30, jsxs as jsxs17 } from "react/jsx-runtime";
1359
1645
  var BAR_HEIGHT = 60;
1360
- function SdHeader({ navItems, loginFlag }) {
1361
- const [opened, { toggle, close }] = useDisclosure();
1646
+ var MAX_DEPTH = 3;
1647
+ var NAV_LINK_STYLES = {
1648
+ label: {
1649
+ fontWeight: textStyles.Body.fw,
1650
+ fontSize: `var(--mantine-font-size-${textStyles.Body.fz})`,
1651
+ color: toCssColor(textStyles.Body.c),
1652
+ lineHeight: textStyles.Body.lh
1653
+ }
1654
+ };
1655
+ function useNavTree(navItems) {
1362
1656
  const visibleItems = filterAndSort(navItems);
1363
- const topItems = visibleItems.filter((item) => !item.parentId);
1364
- const childrenOf = (parentId) => visibleItems.filter((item) => item.parentId === parentId);
1365
- const hasAnyChildren = visibleItems.some((item) => item.parentId);
1657
+ return {
1658
+ topItems: visibleItems.filter((item) => !item.parentId),
1659
+ childrenOf: (parentId) => visibleItems.filter((item) => item.parentId === parentId),
1660
+ hasAnyChildren: visibleItems.some((item) => item.parentId)
1661
+ };
1662
+ }
1663
+ function MobileNavNode({ item, depth, childrenOf, close }) {
1664
+ const kids = depth < MAX_DEPTH ? childrenOf(item.id) : [];
1665
+ if (kids.length === 0) {
1666
+ return /* @__PURE__ */ jsx30(Box13, { px: "sm", py: 8, children: /* @__PURE__ */ jsx30(SdLink.Body, { href: item.href, onClick: close, children: item.label }) });
1667
+ }
1668
+ return /* @__PURE__ */ jsx30(
1669
+ NavLink,
1670
+ {
1671
+ label: item.label,
1672
+ styles: NAV_LINK_STYLES,
1673
+ component: item.href ? "a" : "button",
1674
+ href: item.href,
1675
+ childrenOffset: 28,
1676
+ children: kids.map((kid) => /* @__PURE__ */ jsx30(
1677
+ MobileNavNode,
1678
+ {
1679
+ item: kid,
1680
+ depth: depth + 1,
1681
+ childrenOf,
1682
+ close
1683
+ },
1684
+ kid.id
1685
+ ))
1686
+ }
1687
+ );
1688
+ }
1689
+ function MobileNav({ opened, close, topItems, childrenOf, loginFlag }) {
1690
+ return /* @__PURE__ */ jsx30(Drawer, { opened, onClose: close, hiddenFrom: "sm", size: "xs", children: /* @__PURE__ */ jsxs17(Stack16, { gap: 0, children: [
1691
+ topItems.map((item) => /* @__PURE__ */ jsx30(MobileNavNode, { item, depth: 1, childrenOf, close }, item.id)),
1692
+ loginFlag && /* @__PURE__ */ jsx30(Stack16, { gap: "xs", mt: "md", children: /* @__PURE__ */ jsx30(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1693
+ ] }) });
1694
+ }
1695
+ function MegaHeader({ navItems, loginFlag }) {
1696
+ const [opened, { toggle, close }] = useDisclosure();
1697
+ const { topItems, childrenOf, hasAnyChildren } = useNavTree(navItems);
1366
1698
  const { hovered, ref: hoverRef } = useHover();
1367
1699
  const { focused, ref: focusRef } = useFocusWithin();
1368
1700
  const rootRef = useMergedRef(hoverRef, focusRef);
1369
1701
  const expanded = hasAnyChildren && (hovered || focused);
1370
- return /* @__PURE__ */ jsxs16(Fragment4, { children: [
1371
- /* @__PURE__ */ jsx28(
1372
- Box12,
1702
+ return /* @__PURE__ */ jsxs17(Fragment4, { children: [
1703
+ /* @__PURE__ */ jsx30(
1704
+ Box13,
1373
1705
  {
1374
1706
  ref: rootRef,
1375
1707
  pos: "relative",
@@ -1379,12 +1711,12 @@ function SdHeader({ navItems, loginFlag }) {
1379
1711
  borderBottom: expanded ? "1px solid var(--mantine-color-slate-2)" : void 0,
1380
1712
  transition: "box-shadow 0.15s"
1381
1713
  },
1382
- children: /* @__PURE__ */ jsx28(SdContainer, { children: /* @__PURE__ */ jsxs16(Group9, { justify: "space-between", align: "flex-start", wrap: "nowrap", children: [
1383
- /* @__PURE__ */ jsx28(Group9, { h: BAR_HEIGHT, align: "center", children: /* @__PURE__ */ jsx28(Logo, {}) }),
1384
- /* @__PURE__ */ jsx28(Group9, { gap: "xl", align: "flex-start", wrap: "nowrap", visibleFrom: "sm", children: topItems.map((item) => {
1714
+ children: /* @__PURE__ */ jsx30(SdContainer, { children: /* @__PURE__ */ jsxs17(Group10, { justify: "space-between", align: "flex-start", wrap: "nowrap", children: [
1715
+ /* @__PURE__ */ jsx30(Group10, { h: BAR_HEIGHT, align: "center", children: /* @__PURE__ */ jsx30(Logo, {}) }),
1716
+ /* @__PURE__ */ jsx30(Group10, { gap: "xl", align: "flex-start", wrap: "nowrap", visibleFrom: "sm", children: topItems.map((item) => {
1385
1717
  const kids = childrenOf(item.id);
1386
- return /* @__PURE__ */ jsxs16(Stack15, { gap: 0, align: "center", children: [
1387
- /* @__PURE__ */ jsx28(Group9, { h: BAR_HEIGHT, align: "center", children: item.href ? /* @__PURE__ */ jsx28(SdLink.Body, { href: item.href, children: item.label }) : /* @__PURE__ */ jsx28(SdText.Strong, { children: item.label }) }),
1718
+ return /* @__PURE__ */ jsxs17(Stack16, { gap: 0, align: "center", children: [
1719
+ /* @__PURE__ */ jsx30(Group10, { h: BAR_HEIGHT, align: "center", children: /* @__PURE__ */ jsx30(SdLink.Body, { href: item.href, children: item.label }) }),
1388
1720
  kids.length > 0 && /*
1389
1721
  Mantine Collapse를 쓰지 않는다 — 접힐 때 display:none이 되어
1390
1722
  하위 링크가 폭 계산에서 빠졌다가 펼칠 때 다시 들어오면서
@@ -1392,8 +1724,8 @@ function SdHeader({ navItems, loginFlag }) {
1392
1724
  height 0 + overflow hidden은 폭 기여를 유지하므로 간격이 고정된다.
1393
1725
  visibility:hidden이 접힌 상태의 링크를 탭 순서에서도 빼준다.
1394
1726
  */
1395
- /* @__PURE__ */ jsx28(
1396
- Box12,
1727
+ /* @__PURE__ */ jsx30(
1728
+ Box13,
1397
1729
  {
1398
1730
  "aria-hidden": !expanded,
1399
1731
  style: {
@@ -1403,43 +1735,178 @@ function SdHeader({ navItems, loginFlag }) {
1403
1735
  visibility: expanded ? "visible" : "hidden",
1404
1736
  transition: "opacity 0.15s ease"
1405
1737
  },
1406
- children: /* @__PURE__ */ jsx28(Stack15, { gap: "xs", pt: 4, pb: "lg", align: "center", children: kids.map((kid) => /* @__PURE__ */ jsx28(SdLink.Sub, { href: kid.href, children: kid.label }, kid.id)) })
1738
+ children: /* @__PURE__ */ jsx30(Stack16, { gap: "xs", pt: 4, pb: "lg", align: "center", children: kids.map((kid) => {
1739
+ const grandkids = childrenOf(kid.id);
1740
+ if (grandkids.length === 0) {
1741
+ return /* @__PURE__ */ jsx30(SdLink.Body, { href: kid.href, children: kid.label }, kid.id);
1742
+ }
1743
+ return /* @__PURE__ */ jsxs17(Stack16, { gap: 2, align: "center", children: [
1744
+ /* @__PURE__ */ jsx30(SdLink.Body, { href: kid.href, children: kid.label }),
1745
+ grandkids.map((gk) => /* @__PURE__ */ jsx30(SdLink.Sub, { href: gk.href, children: gk.label }, gk.id))
1746
+ ] }, kid.id);
1747
+ }) })
1407
1748
  }
1408
1749
  )
1409
1750
  ] }, item.id);
1410
1751
  }) }),
1411
- /* @__PURE__ */ jsxs16(Group9, { h: BAR_HEIGHT, align: "center", gap: "sm", wrap: "nowrap", children: [
1412
- /* @__PURE__ */ jsx28(Burger, { hiddenFrom: "sm", opened, onClick: toggle }),
1413
- loginFlag && /* @__PURE__ */ jsx28(Group9, { gap: "sm", visibleFrom: "sm", children: /* @__PURE__ */ jsx28(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1752
+ /* @__PURE__ */ jsxs17(Group10, { h: BAR_HEIGHT, align: "center", gap: "sm", wrap: "nowrap", children: [
1753
+ /* @__PURE__ */ jsx30(Burger, { hiddenFrom: "sm", opened, onClick: toggle }),
1754
+ loginFlag && /* @__PURE__ */ jsx30(Group10, { gap: "sm", visibleFrom: "sm", children: /* @__PURE__ */ jsx30(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1414
1755
  ] })
1415
1756
  ] }) })
1416
1757
  }
1417
1758
  ),
1418
- /* @__PURE__ */ jsx28(Drawer, { opened, onClose: close, hiddenFrom: "sm", size: "xs", children: /* @__PURE__ */ jsxs16(Stack15, { gap: 0, children: [
1419
- topItems.map((item) => {
1759
+ /* @__PURE__ */ jsx30(
1760
+ MobileNav,
1761
+ {
1762
+ opened,
1763
+ close,
1764
+ topItems,
1765
+ childrenOf,
1766
+ loginFlag
1767
+ }
1768
+ )
1769
+ ] });
1770
+ }
1771
+ function renderMenuLeaf(item) {
1772
+ return item.href ? /* @__PURE__ */ jsx30(Menu.Item, { component: "a", href: item.href, children: item.label }, item.id) : /* @__PURE__ */ jsx30(Menu.Label, { children: item.label }, item.id);
1773
+ }
1774
+ function SimpleHeader({ navItems, loginFlag }) {
1775
+ const [opened, { toggle, close }] = useDisclosure();
1776
+ const { topItems, childrenOf } = useNavTree(navItems);
1777
+ return /* @__PURE__ */ jsxs17(Fragment4, { children: [
1778
+ /* @__PURE__ */ jsx30(Box13, { bg: "var(--mantine-color-body)", children: /* @__PURE__ */ jsx30(SdContainer, { children: /* @__PURE__ */ jsxs17(Group10, { h: BAR_HEIGHT, justify: "space-between", align: "center", wrap: "nowrap", children: [
1779
+ /* @__PURE__ */ jsx30(Logo, {}),
1780
+ /* @__PURE__ */ jsx30(Group10, { gap: "xl", align: "center", wrap: "nowrap", visibleFrom: "sm", children: topItems.map((item) => {
1781
+ const kids = childrenOf(item.id);
1782
+ if (kids.length === 0) {
1783
+ return /* @__PURE__ */ jsx30(SdLink.Body, { href: item.href, children: item.label }, item.id);
1784
+ }
1785
+ return (
1786
+ /*
1787
+ trigger="click-hover" — 마우스는 hover로, 키보드/터치는 click으로 연다.
1788
+ Menu.Target은 ref를 받을 수 있는 단일 엘리먼트여야 하므로
1789
+ SdLink/SdText가 아니라 Box를 타깃으로 두고 라벨을 그 안에 넣는다.
1790
+ */
1791
+ /* @__PURE__ */ jsxs17(
1792
+ Menu,
1793
+ {
1794
+ trigger: "click-hover",
1795
+ openDelay: 50,
1796
+ closeDelay: 120,
1797
+ position: "bottom",
1798
+ offset: 12,
1799
+ shadow: "md",
1800
+ radius: "md",
1801
+ withinPortal: true,
1802
+ children: [
1803
+ /* @__PURE__ */ jsx30(Menu.Target, { children: /* @__PURE__ */ jsx30(Box13, { style: { cursor: "pointer" }, children: /* @__PURE__ */ jsxs17(Group10, { gap: 4, align: "center", wrap: "nowrap", children: [
1804
+ /* @__PURE__ */ jsx30(SdLink.Body, { href: item.href, children: item.label }),
1805
+ /* @__PURE__ */ jsx30(IconChevronDown, { size: 14, stroke: 2 })
1806
+ ] }) }) }),
1807
+ /* @__PURE__ */ jsx30(Menu.Dropdown, { children: kids.map((kid) => {
1808
+ const grandkids = childrenOf(kid.id);
1809
+ if (grandkids.length > 0) {
1810
+ return /* @__PURE__ */ jsxs17(Menu.Sub, { children: [
1811
+ /* @__PURE__ */ jsx30(Menu.Sub.Target, { children: /* @__PURE__ */ jsx30(Menu.Sub.Item, { children: kid.label }) }),
1812
+ /* @__PURE__ */ jsx30(Menu.Sub.Dropdown, { children: grandkids.map(renderMenuLeaf) })
1813
+ ] }, kid.id);
1814
+ }
1815
+ return renderMenuLeaf(kid);
1816
+ }) })
1817
+ ]
1818
+ },
1819
+ item.id
1820
+ )
1821
+ );
1822
+ }) }),
1823
+ /* @__PURE__ */ jsxs17(Group10, { align: "center", gap: "sm", wrap: "nowrap", children: [
1824
+ /* @__PURE__ */ jsx30(Burger, { hiddenFrom: "sm", opened, onClick: toggle }),
1825
+ loginFlag && /* @__PURE__ */ jsx30(Group10, { gap: "sm", visibleFrom: "sm", children: /* @__PURE__ */ jsx30(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1826
+ ] })
1827
+ ] }) }) }),
1828
+ /* @__PURE__ */ jsx30(
1829
+ MobileNav,
1830
+ {
1831
+ opened,
1832
+ close,
1833
+ topItems,
1834
+ childrenOf,
1835
+ loginFlag
1836
+ }
1837
+ )
1838
+ ] });
1839
+ }
1840
+ function PanelHeader({ navItems, loginFlag }) {
1841
+ const [opened, { toggle, close }] = useDisclosure();
1842
+ const { topItems, childrenOf } = useNavTree(navItems);
1843
+ return /* @__PURE__ */ jsxs17(Fragment4, { children: [
1844
+ /* @__PURE__ */ jsx30(Box13, { bg: "var(--mantine-color-body)", children: /* @__PURE__ */ jsx30(SdContainer, { children: /* @__PURE__ */ jsxs17(Group10, { h: BAR_HEIGHT, justify: "space-between", align: "center", wrap: "nowrap", children: [
1845
+ /* @__PURE__ */ jsx30(Logo, {}),
1846
+ /* @__PURE__ */ jsx30(Group10, { gap: "xl", align: "center", wrap: "nowrap", visibleFrom: "sm", children: topItems.map((item) => {
1420
1847
  const kids = childrenOf(item.id);
1421
1848
  if (kids.length === 0) {
1422
- return /* @__PURE__ */ jsx28(Box12, { px: "sm", py: 8, children: /* @__PURE__ */ jsx28(SdLink.Body, { href: item.href, onClick: close, children: item.label }) }, item.id);
1849
+ return /* @__PURE__ */ jsx30(SdLink.Body, { href: item.href, children: item.label }, item.id);
1423
1850
  }
1424
- return /* @__PURE__ */ jsx28(
1425
- NavLink,
1851
+ return /* @__PURE__ */ jsxs17(
1852
+ Menu,
1426
1853
  {
1427
- label: item.label,
1428
- href: item.href,
1429
- childrenOffset: 28,
1430
- onClick: kids.length > 0 ? void 0 : close,
1431
- children: kids.map((kid) => /* @__PURE__ */ jsx28(NavLink, { label: kid.label, href: kid.href, onClick: close }, kid.id))
1854
+ trigger: "click-hover",
1855
+ openDelay: 50,
1856
+ closeDelay: 120,
1857
+ position: "bottom",
1858
+ offset: 12,
1859
+ shadow: "md",
1860
+ radius: "md",
1861
+ withinPortal: true,
1862
+ children: [
1863
+ /* @__PURE__ */ jsx30(Menu.Target, { children: /* @__PURE__ */ jsx30(Box13, { style: { cursor: "pointer" }, children: /* @__PURE__ */ jsxs17(Group10, { gap: 4, align: "center", wrap: "nowrap", children: [
1864
+ /* @__PURE__ */ jsx30(SdLink.Body, { href: item.href, children: item.label }),
1865
+ /* @__PURE__ */ jsx30(IconChevronDown, { size: 14, stroke: 2 })
1866
+ ] }) }) }),
1867
+ /* @__PURE__ */ jsx30(Menu.Dropdown, { children: /* @__PURE__ */ jsx30(Stack16, { gap: "xs", p: "xs", children: kids.map((kid) => {
1868
+ const grandkids = childrenOf(kid.id);
1869
+ if (grandkids.length === 0) {
1870
+ return /* @__PURE__ */ jsx30(SdLink.Body, { href: kid.href, children: kid.label }, kid.id);
1871
+ }
1872
+ return /* @__PURE__ */ jsxs17(Stack16, { gap: 2, children: [
1873
+ /* @__PURE__ */ jsx30(SdLink.Body, { href: kid.href, children: kid.label }),
1874
+ grandkids.map((gk) => /* @__PURE__ */ jsx30(SdLink.Sub, { href: gk.href, pl: "sm", children: gk.label }, gk.id))
1875
+ ] }, kid.id);
1876
+ }) }) })
1877
+ ]
1432
1878
  },
1433
1879
  item.id
1434
1880
  );
1435
- }),
1436
- loginFlag && /* @__PURE__ */ jsx28(Stack15, { gap: "xs", mt: "md", children: /* @__PURE__ */ jsx28(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1437
- ] }) })
1881
+ }) }),
1882
+ /* @__PURE__ */ jsxs17(Group10, { align: "center", gap: "sm", wrap: "nowrap", children: [
1883
+ /* @__PURE__ */ jsx30(Burger, { hiddenFrom: "sm", opened, onClick: toggle }),
1884
+ loginFlag && /* @__PURE__ */ jsx30(Group10, { gap: "sm", visibleFrom: "sm", children: /* @__PURE__ */ jsx30(SdButton.Primary, { size: "xs", children: "\uB85C\uADF8\uC778" }) })
1885
+ ] })
1886
+ ] }) }) }),
1887
+ /* @__PURE__ */ jsx30(
1888
+ MobileNav,
1889
+ {
1890
+ opened,
1891
+ close,
1892
+ topItems,
1893
+ childrenOf,
1894
+ loginFlag
1895
+ }
1896
+ )
1438
1897
  ] });
1439
1898
  }
1899
+ var SdHeader = Object.assign(MegaHeader, {
1900
+ Mega: MegaHeader,
1901
+ Simple: SimpleHeader,
1902
+ Panel: PanelHeader
1903
+ });
1904
+ var SdHeaderMega = MegaHeader;
1905
+ var SdHeaderSimple = SimpleHeader;
1906
+ var SdHeaderPanel = PanelHeader;
1440
1907
 
1441
1908
  // ui/organism/Footer.tsx
1442
- import { ActionIcon, Box as Box13, Divider as Divider3, Flex, Grid as Grid5, Group as Group10, SimpleGrid as SimpleGrid6, Stack as Stack16 } from "@mantine/core";
1909
+ import { ActionIcon, Box as Box14, Divider as Divider3, Flex, Grid as Grid5, Group as Group11, SimpleGrid as SimpleGrid6, Stack as Stack17 } from "@mantine/core";
1443
1910
  import {
1444
1911
  IconBrandFacebook,
1445
1912
  IconBrandGithub,
@@ -1449,16 +1916,16 @@ import {
1449
1916
  IconBrandYoutube,
1450
1917
  IconWorld
1451
1918
  } from "@tabler/icons-react";
1452
- import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs17 } from "react/jsx-runtime";
1919
+ import { Fragment as Fragment5, jsx as jsx31, jsxs as jsxs18 } from "react/jsx-runtime";
1453
1920
  function FooterNavColumns({ items }) {
1454
1921
  const topLevel = items.filter((item) => !item.parentId);
1455
1922
  const getChildren = (parentId) => items.filter((item) => item.parentId === parentId);
1456
1923
  const CHILD_THRESH = 4;
1457
- return /* @__PURE__ */ jsx29(Fragment5, { children: topLevel.map((group) => /* @__PURE__ */ jsx29(Grid5.Col, { span: { base: 6, sm: 4, md: "auto" }, children: /* @__PURE__ */ jsxs17(Stack16, { gap: "xs", children: [
1458
- /* @__PURE__ */ jsx29(SdText.Sub, { children: group.label }),
1924
+ return /* @__PURE__ */ jsx31(Fragment5, { children: topLevel.map((group) => /* @__PURE__ */ jsx31(Grid5.Col, { span: { base: 6, sm: 4, md: "auto" }, children: /* @__PURE__ */ jsxs18(Stack17, { gap: "xs", children: [
1925
+ /* @__PURE__ */ jsx31(SdLink.Sub, { href: group.href, children: group.label }, group.id),
1459
1926
  getChildren(group.id).map((link, id) => {
1460
1927
  if (id >= CHILD_THRESH) return;
1461
- return /* @__PURE__ */ jsx29(SdLink.Hint, { href: link.href, children: link.label }, link.id);
1928
+ return /* @__PURE__ */ jsx31(SdLink.Hint, { href: link.href, children: link.label }, link.id);
1462
1929
  })
1463
1930
  ] }) }, group.id)) });
1464
1931
  }
@@ -1472,10 +1939,10 @@ var SOCIAL_ICONS = {
1472
1939
  blog: IconWorld
1473
1940
  };
1474
1941
  function FooterSocials({ items }) {
1475
- return /* @__PURE__ */ jsx29(Group10, { gap: 0, wrap: "nowrap", children: items.map((item) => {
1942
+ return /* @__PURE__ */ jsx31(Group11, { gap: 0, wrap: "nowrap", children: items.map((item) => {
1476
1943
  var _a4, _b;
1477
1944
  const Icon = (_a4 = SOCIAL_ICONS[item.platform]) != null ? _a4 : IconWorld;
1478
- return /* @__PURE__ */ jsx29(
1945
+ return /* @__PURE__ */ jsx31(
1479
1946
  ActionIcon,
1480
1947
  {
1481
1948
  component: "a",
@@ -1486,62 +1953,62 @@ function FooterSocials({ items }) {
1486
1953
  color: "gray",
1487
1954
  variant: "subtle",
1488
1955
  "aria-label": (_b = item.label) != null ? _b : item.platform,
1489
- children: /* @__PURE__ */ jsx29(Icon, { size: 18, stroke: 1.5 })
1956
+ children: /* @__PURE__ */ jsx31(Icon, { size: 18, stroke: 1.5 })
1490
1957
  },
1491
1958
  item.url
1492
1959
  );
1493
1960
  }) });
1494
1961
  }
1495
1962
  function InfoCell({ label, children }) {
1496
- return /* @__PURE__ */ jsxs17(Group10, { gap: 6, wrap: "nowrap", align: "baseline", children: [
1497
- /* @__PURE__ */ jsx29(SdText.Sub, { c: "slate.4", style: { whiteSpace: "nowrap" }, children: label }),
1498
- typeof children === "string" ? /* @__PURE__ */ jsx29(SdText.Sub, { children }) : children
1963
+ return /* @__PURE__ */ jsxs18(Group11, { gap: 6, wrap: "nowrap", align: "baseline", children: [
1964
+ /* @__PURE__ */ jsx31(SdText.Sub, { c: "slate.4", style: { whiteSpace: "nowrap" }, children: label }),
1965
+ typeof children === "string" ? /* @__PURE__ */ jsx31(SdText.Sub, { children }) : children
1499
1966
  ] });
1500
1967
  }
1501
1968
  function FooterCompanyInfo({ company }) {
1502
1969
  const sortedAddresses = [...company.addresses].sort((a, b) => a.order - b.order);
1503
- return /* @__PURE__ */ jsxs17(SimpleGrid6, { cols: { base: 2, sm: 2, md: 1 }, spacing: "md", verticalSpacing: 0, children: [
1504
- /* @__PURE__ */ jsx29(InfoCell, { label: "\uC0C1\uD638", children: company.name }),
1505
- /* @__PURE__ */ jsx29(InfoCell, { label: "\uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638", children: company.registrationNumber }),
1506
- sortedAddresses.map((addr) => /* @__PURE__ */ jsx29(InfoCell, { label: addr.label, children: addr.address }, addr.label)),
1507
- /* @__PURE__ */ jsx29(InfoCell, { label: "Tel", children: /* @__PURE__ */ jsx29(SdLink.Sub, { href: `tel:${company.tel}`, children: company.tel }) }),
1508
- company.fax && /* @__PURE__ */ jsx29(InfoCell, { label: "Fax", children: company.fax }),
1509
- /* @__PURE__ */ jsx29(InfoCell, { label: "Email", children: /* @__PURE__ */ jsx29(SdLink.Sub, { href: `mailto:${company.email}`, children: company.email }) })
1970
+ return /* @__PURE__ */ jsxs18(SimpleGrid6, { cols: { base: 2, sm: 2, md: 1 }, spacing: "md", verticalSpacing: 0, children: [
1971
+ /* @__PURE__ */ jsx31(InfoCell, { label: "\uC0C1\uD638", children: company.name }),
1972
+ /* @__PURE__ */ jsx31(InfoCell, { label: "\uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638", children: company.registrationNumber }),
1973
+ sortedAddresses.map((addr) => /* @__PURE__ */ jsx31(InfoCell, { label: addr.label, children: addr.address }, addr.label)),
1974
+ /* @__PURE__ */ jsx31(InfoCell, { label: "Tel", children: /* @__PURE__ */ jsx31(SdLink.Sub, { href: `tel:${company.tel}`, children: company.tel }) }),
1975
+ company.fax && /* @__PURE__ */ jsx31(InfoCell, { label: "Fax", children: company.fax }),
1976
+ /* @__PURE__ */ jsx31(InfoCell, { label: "Email", children: /* @__PURE__ */ jsx31(SdLink.Sub, { href: `mailto:${company.email}`, children: company.email }) })
1510
1977
  ] });
1511
1978
  }
1512
1979
  function SdFooter({ company, navItems, policyLinks, description }) {
1513
1980
  const visibleNav = filterAndSort(navItems);
1514
1981
  const visiblePolicy = filterAndSort(policyLinks);
1515
- return /* @__PURE__ */ jsx29(Box13, { component: "footer", children: /* @__PURE__ */ jsx29(SdContainer, { children: /* @__PURE__ */ jsxs17(Stack16, { children: [
1516
- /* @__PURE__ */ jsx29(Logo, { size: "sm" }),
1517
- description && /* @__PURE__ */ jsx29(SdText.Sub, { children: description }),
1518
- /* @__PURE__ */ jsxs17(Flex, { direction: { base: "column", md: "row" }, gap: 48, align: "flex-start", children: [
1519
- /* @__PURE__ */ jsx29(Box13, { flex: { base: "0 0 auto", md: "1 1 0" }, w: { base: "100%", md: "auto" }, children: /* @__PURE__ */ jsx29(FooterCompanyInfo, { company }) }),
1520
- visibleNav.length > 0 && /* @__PURE__ */ jsx29(Box13, { flex: { base: "0 0 auto", md: "2 1 0" }, w: { base: "100%", md: "auto" }, children: /* @__PURE__ */ jsx29(Grid5, { style: { "--grid-gutter": "24px" }, children: /* @__PURE__ */ jsx29(FooterNavColumns, { items: visibleNav }) }) })
1982
+ return /* @__PURE__ */ jsx31(Box14, { component: "footer", children: /* @__PURE__ */ jsx31(SdContainer, { py: "lg", children: /* @__PURE__ */ jsxs18(Stack17, { children: [
1983
+ /* @__PURE__ */ jsx31(Logo, { size: "sm" }),
1984
+ description && /* @__PURE__ */ jsx31(SdText.Sub, { children: description }),
1985
+ /* @__PURE__ */ jsxs18(Flex, { direction: { base: "column", md: "row" }, gap: 48, align: "flex-start", children: [
1986
+ /* @__PURE__ */ jsx31(Box14, { flex: { base: "0 0 auto", md: "1 1 0" }, w: { base: "100%", md: "auto" }, children: /* @__PURE__ */ jsx31(FooterCompanyInfo, { company }) }),
1987
+ visibleNav.length > 0 && /* @__PURE__ */ jsx31(Box14, { flex: { base: "0 0 auto", md: "2 1 0" }, w: { base: "100%", md: "auto" }, children: /* @__PURE__ */ jsx31(Grid5, { style: { "--grid-gutter": "24px" }, children: /* @__PURE__ */ jsx31(FooterNavColumns, { items: visibleNav }) }) })
1521
1988
  ] }),
1522
- /* @__PURE__ */ jsx29(Divider3, {}),
1523
- /* @__PURE__ */ jsxs17(Group10, { justify: "space-between", wrap: "wrap", gap: "xs", children: [
1524
- /* @__PURE__ */ jsxs17(SdText.Sub, { children: [
1989
+ /* @__PURE__ */ jsx31(Divider3, {}),
1990
+ /* @__PURE__ */ jsxs18(Group11, { justify: "space-between", wrap: "wrap", gap: "xs", children: [
1991
+ /* @__PURE__ */ jsxs18(SdText.Sub, { children: [
1525
1992
  "\xA9 ",
1526
1993
  company.copyrightYear,
1527
1994
  " ",
1528
- company.name,
1995
+ t(company.name),
1529
1996
  ". All rights reserved."
1530
1997
  ] }),
1531
- /* @__PURE__ */ jsxs17(Group10, { gap: "lg", wrap: "wrap", children: [
1532
- visiblePolicy.length > 0 && /* @__PURE__ */ jsx29(Group10, { gap: "lg", children: visiblePolicy.map((item) => {
1533
- const Link4 = item.highlight ? SdLink.Strong : SdLink.Sub;
1534
- return /* @__PURE__ */ jsx29(Link4, { href: item.href, children: item.label }, item.id);
1998
+ /* @__PURE__ */ jsxs18(Group11, { gap: "lg", wrap: "wrap", children: [
1999
+ visiblePolicy.length > 0 && /* @__PURE__ */ jsx31(Group11, { gap: "lg", children: visiblePolicy.map((item) => {
2000
+ const Link4 = item.highlight ? SdLink.Body : SdLink.Sub;
2001
+ return /* @__PURE__ */ jsx31(Link4, { href: item.href, children: item.label }, item.id);
1535
2002
  }) }),
1536
- company.socials && company.socials.length > 0 && /* @__PURE__ */ jsx29(FooterSocials, { items: company.socials })
2003
+ company.socials && company.socials.length > 0 && /* @__PURE__ */ jsx31(FooterSocials, { items: company.socials })
1537
2004
  ] })
1538
2005
  ] })
1539
2006
  ] }) }) });
1540
2007
  }
1541
2008
 
1542
2009
  // ui/organism/FeatureSection.tsx
1543
- import { Stack as Stack17 } from "@mantine/core";
1544
- import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
2010
+ import { Stack as Stack18 } from "@mantine/core";
2011
+ import { jsx as jsx32, jsxs as jsxs19 } from "react/jsx-runtime";
1545
2012
  function SdFeatureSection(_a4) {
1546
2013
  var _b = _a4, {
1547
2014
  label,
@@ -1558,8 +2025,8 @@ function SdFeatureSection(_a4) {
1558
2025
  "cols",
1559
2026
  "py"
1560
2027
  ]);
1561
- return /* @__PURE__ */ jsx30(SdContainer, __spreadProps(__spreadValues({ py }, boxProps), { children: /* @__PURE__ */ jsxs18(Stack17, { gap: "xl", children: [
1562
- /* @__PURE__ */ jsx30(
2028
+ return /* @__PURE__ */ jsx32(SdContainer, __spreadProps(__spreadValues({ py }, boxProps), { children: /* @__PURE__ */ jsxs19(Stack18, { gap: "xl", children: [
2029
+ /* @__PURE__ */ jsx32(
1563
2030
  SdTextBox.Section,
1564
2031
  {
1565
2032
  label,
@@ -1570,13 +2037,13 @@ function SdFeatureSection(_a4) {
1570
2037
  align: "center"
1571
2038
  }
1572
2039
  ),
1573
- /* @__PURE__ */ jsx30(SdFeatures, { items, cols })
2040
+ /* @__PURE__ */ jsx32(SdFeatures, { items, cols })
1574
2041
  ] }) }));
1575
2042
  }
1576
2043
 
1577
2044
  // ui/organism/TimelineSection.tsx
1578
- import { Center as Center3, Stack as Stack18 } from "@mantine/core";
1579
- import { jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
2045
+ import { Center as Center3, Stack as Stack19 } from "@mantine/core";
2046
+ import { jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
1580
2047
  function SdTimelineSection(_a4) {
1581
2048
  var _b = _a4, {
1582
2049
  label,
@@ -1591,15 +2058,15 @@ function SdTimelineSection(_a4) {
1591
2058
  "items",
1592
2059
  "py"
1593
2060
  ]);
1594
- return /* @__PURE__ */ jsx31(Center3, { children: /* @__PURE__ */ jsxs19(Stack18, __spreadProps(__spreadValues({ py, gap: "md" }, boxProps), { children: [
1595
- /* @__PURE__ */ jsx31(SdTextBox.Section, { label, title, description }),
1596
- /* @__PURE__ */ jsx31(Center3, { children: /* @__PURE__ */ jsx31(SdTimeline, { items }) })
2061
+ return /* @__PURE__ */ jsx33(Center3, { children: /* @__PURE__ */ jsxs20(Stack19, __spreadProps(__spreadValues({ py, gap: "md" }, boxProps), { children: [
2062
+ /* @__PURE__ */ jsx33(SdTextBox.Section, { label, title, description }),
2063
+ /* @__PURE__ */ jsx33(Center3, { children: /* @__PURE__ */ jsx33(SdTimeline, { items }) })
1597
2064
  ] })) });
1598
2065
  }
1599
2066
 
1600
2067
  // ui/organism/StepsSection.tsx
1601
- import { Stack as Stack19 } from "@mantine/core";
1602
- import { jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
2068
+ import { Stack as Stack20 } from "@mantine/core";
2069
+ import { jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
1603
2070
  function SdStepsSection(_a4) {
1604
2071
  var _b = _a4, {
1605
2072
  label,
@@ -1614,17 +2081,17 @@ function SdStepsSection(_a4) {
1614
2081
  "items",
1615
2082
  "py"
1616
2083
  ]);
1617
- return /* @__PURE__ */ jsx32(SdContainer, __spreadProps(__spreadValues({ py }, boxProps), { children: /* @__PURE__ */ jsxs20(Stack19, { gap: "xl", children: [
1618
- (label || title || description) && /* @__PURE__ */ jsx32(SdTextBox.Section, { label, title, description }),
1619
- /* @__PURE__ */ jsx32(SdSteps.Bubble, { items })
2084
+ return /* @__PURE__ */ jsx34(SdContainer, __spreadProps(__spreadValues({ py }, boxProps), { children: /* @__PURE__ */ jsxs21(Stack20, { gap: "xl", children: [
2085
+ (label || title || description) && /* @__PURE__ */ jsx34(SdTextBox.Section, { label, title, description }),
2086
+ /* @__PURE__ */ jsx34(SdSteps.Bubble, { items })
1620
2087
  ] }) }));
1621
2088
  }
1622
2089
 
1623
2090
  // ui/organism/ErrorView.tsx
1624
- import { Center as Center4, Group as Group11, Stack as Stack20, Text as Text2 } from "@mantine/core";
1625
- import { jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
2091
+ import { Center as Center4, Group as Group12, Stack as Stack21, Text as Text2 } from "@mantine/core";
2092
+ import { jsx as jsx35, jsxs as jsxs22 } from "react/jsx-runtime";
1626
2093
  function StatusCode({ code }) {
1627
- return /* @__PURE__ */ jsx33(
2094
+ return /* @__PURE__ */ jsx35(
1628
2095
  Text2,
1629
2096
  {
1630
2097
  fz: 160,
@@ -1638,15 +2105,15 @@ function StatusCode({ code }) {
1638
2105
  );
1639
2106
  }
1640
2107
  function Page({ error, onReset, onHome }) {
1641
- return /* @__PURE__ */ jsx33(Center4, { mih: "60vh", children: /* @__PURE__ */ jsx33(SdContainer, { children: /* @__PURE__ */ jsxs21(Stack20, { align: "center", gap: "lg", ta: "center", children: [
1642
- /* @__PURE__ */ jsx33(StatusCode, { code: "500" }),
1643
- /* @__PURE__ */ jsxs21(Stack20, { gap: "sm", align: "center", children: [
1644
- /* @__PURE__ */ jsx33(SdTitle.Section, { children: "\uC11C\uBC84\uC5D0\uC11C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4" }),
1645
- /* @__PURE__ */ jsx33(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." })
2108
+ return /* @__PURE__ */ jsx35(Center4, { mih: "60vh", children: /* @__PURE__ */ jsx35(SdContainer, { children: /* @__PURE__ */ jsxs22(Stack21, { align: "center", gap: "lg", ta: "center", children: [
2109
+ /* @__PURE__ */ jsx35(StatusCode, { code: "500" }),
2110
+ /* @__PURE__ */ jsxs22(Stack21, { gap: "sm", align: "center", children: [
2111
+ /* @__PURE__ */ jsx35(SdTitle.Section, { children: "\uC11C\uBC84\uC5D0\uC11C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4" }),
2112
+ /* @__PURE__ */ jsx35(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." })
1646
2113
  ] }),
1647
- /* @__PURE__ */ jsxs21(Group11, { gap: "sm", justify: "center", children: [
1648
- /* @__PURE__ */ jsx33(SdButton.Primary, { onClick: onReset, children: "\uB2E4\uC2DC \uC2DC\uB3C4" }),
1649
- onHome && /* @__PURE__ */ jsx33(SdButton.Ghost, { onClick: onHome, children: "\uD648\uC73C\uB85C" })
2114
+ /* @__PURE__ */ jsxs22(Group12, { gap: "sm", justify: "center", children: [
2115
+ /* @__PURE__ */ jsx35(SdButton.Primary, { onClick: onReset, children: "\uB2E4\uC2DC \uC2DC\uB3C4" }),
2116
+ onHome && /* @__PURE__ */ jsx35(SdButton.Ghost, { onClick: onHome, children: "\uD648\uC73C\uB85C" })
1650
2117
  ] })
1651
2118
  ] }) }) });
1652
2119
  }
@@ -1658,15 +2125,15 @@ function NotFound({
1658
2125
  },
1659
2126
  onBack = () => window.history.back()
1660
2127
  }) {
1661
- return /* @__PURE__ */ jsx33(Center4, { mih: "60vh", children: /* @__PURE__ */ jsx33(SdContainer, { children: /* @__PURE__ */ jsxs21(Stack20, { align: "center", gap: "lg", ta: "center", children: [
1662
- /* @__PURE__ */ jsx33(StatusCode, { code: "404" }),
1663
- /* @__PURE__ */ jsxs21(Stack20, { gap: "sm", align: "center", children: [
1664
- /* @__PURE__ */ jsx33(SdTitle.Section, { children: title }),
1665
- /* @__PURE__ */ jsx33(SdText.Body, { maw: 480, children: description })
2128
+ return /* @__PURE__ */ jsx35(Center4, { mih: "60vh", children: /* @__PURE__ */ jsx35(SdContainer, { children: /* @__PURE__ */ jsxs22(Stack21, { align: "center", gap: "lg", ta: "center", children: [
2129
+ /* @__PURE__ */ jsx35(StatusCode, { code: "404" }),
2130
+ /* @__PURE__ */ jsxs22(Stack21, { gap: "sm", align: "center", children: [
2131
+ /* @__PURE__ */ jsx35(SdTitle.Section, { children: title }),
2132
+ /* @__PURE__ */ jsx35(SdText.Body, { maw: 480, children: description })
1666
2133
  ] }),
1667
- /* @__PURE__ */ jsxs21(Group11, { gap: "sm", justify: "center", children: [
1668
- onHome && /* @__PURE__ */ jsx33(SdButton.Primary, { onClick: onHome, children: "\uD648\uC73C\uB85C" }),
1669
- onBack && /* @__PURE__ */ jsx33(SdButton.Ghost, { onClick: onBack, children: "\uB4A4\uB85C \uAC00\uAE30" })
2134
+ /* @__PURE__ */ jsxs22(Group12, { gap: "sm", justify: "center", children: [
2135
+ onHome && /* @__PURE__ */ jsx35(SdButton.Primary, { onClick: onHome, children: "\uD648\uC73C\uB85C" }),
2136
+ onBack && /* @__PURE__ */ jsx35(SdButton.Ghost, { onClick: onBack, children: "\uB4A4\uB85C \uAC00\uAE30" })
1670
2137
  ] })
1671
2138
  ] }) }) });
1672
2139
  }
@@ -1679,175 +2146,418 @@ var SdErrorView = {
1679
2146
  var SdErrorViewPage = SdErrorView.Page;
1680
2147
  var SdErrorViewNotFound = SdErrorView.NotFound;
1681
2148
 
2149
+ // ui/organism/LoginView.tsx
2150
+ import { Box as Box16, Center as Center5, Checkbox as Checkbox2, Divider as Divider4, Group as Group13, Paper, SimpleGrid as SimpleGrid7, Stack as Stack22 } from "@mantine/core";
2151
+ import {
2152
+ IconBrandApple,
2153
+ IconBrandGithub as IconBrandGithub2,
2154
+ IconBrandGoogle,
2155
+ IconBrandKakaoTalk,
2156
+ IconCircleLetterN,
2157
+ IconLogin2
2158
+ } from "@tabler/icons-react";
2159
+
2160
+ // ui/surface.ts
2161
+ var brandSurface = {
2162
+ background: `
2163
+ radial-gradient(90% 120% at 12% 0%, var(--mantine-color-primary-7) 0%, transparent 58%),
2164
+ radial-gradient(70% 100% at 100% 100%, var(--mantine-color-primary-9) 0%, transparent 55%),
2165
+ var(--mantine-color-slate-9)`
2166
+ };
2167
+ var brandDotTexture = {
2168
+ backgroundImage: "radial-gradient(rgba(255,255,255,0.10) 1px, transparent 1px)",
2169
+ backgroundSize: "18px 18px",
2170
+ maskImage: "linear-gradient(180deg, rgba(0,0,0,0.9) 0%, transparent 70%)",
2171
+ WebkitMaskImage: "linear-gradient(180deg, rgba(0,0,0,0.9) 0%, transparent 70%)",
2172
+ pointerEvents: "none"
2173
+ };
2174
+
2175
+ // ui/organism/LoginView.tsx
2176
+ import { Fragment as Fragment6, jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
2177
+ var SOCIAL_META = {
2178
+ google: { Icon: IconBrandGoogle, label: "\uAD6C\uAE00\uB85C \uB85C\uADF8\uC778" },
2179
+ kakao: { Icon: IconBrandKakaoTalk, label: "\uCE74\uCE74\uC624\uB85C \uB85C\uADF8\uC778" },
2180
+ naver: { Icon: IconCircleLetterN, label: "\uB124\uC774\uBC84\uB85C \uB85C\uADF8\uC778" },
2181
+ apple: { Icon: IconBrandApple, label: "\uC560\uD50C\uB85C \uB85C\uADF8\uC778" },
2182
+ github: { Icon: IconBrandGithub2, label: "\uAE43\uD5C8\uBE0C\uB85C \uB85C\uADF8\uC778" }
2183
+ };
2184
+ function LoginForm({
2185
+ onSubmit,
2186
+ loading,
2187
+ error,
2188
+ submitLabel = "\uB85C\uADF8\uC778",
2189
+ withRemember = true,
2190
+ findPasswordHref,
2191
+ signUpHref,
2192
+ socials,
2193
+ children
2194
+ }) {
2195
+ function handleSubmit(event) {
2196
+ var _a4, _b;
2197
+ event.preventDefault();
2198
+ const data = new FormData(event.currentTarget);
2199
+ onSubmit == null ? void 0 : onSubmit({
2200
+ email: String((_a4 = data.get("email")) != null ? _a4 : ""),
2201
+ password: String((_b = data.get("password")) != null ? _b : ""),
2202
+ remember: data.get("remember") === "on"
2203
+ });
2204
+ }
2205
+ return /* @__PURE__ */ jsx36("form", { onSubmit: handleSubmit, noValidate: true, children: /* @__PURE__ */ jsxs23(Stack22, { gap: "md", children: [
2206
+ error && /* @__PURE__ */ jsx36(SdText.Error, { children: error }),
2207
+ /* @__PURE__ */ jsx36(
2208
+ SdInput.Email,
2209
+ {
2210
+ name: "email",
2211
+ label: "\uC774\uBA54\uC77C",
2212
+ placeholder: "name@example.com",
2213
+ autoComplete: "email",
2214
+ required: true
2215
+ }
2216
+ ),
2217
+ /* @__PURE__ */ jsx36(
2218
+ SdInput.Password,
2219
+ {
2220
+ name: "password",
2221
+ label: "\uBE44\uBC00\uBC88\uD638",
2222
+ placeholder: "\uBE44\uBC00\uBC88\uD638\uB97C \uC785\uB825\uD558\uC138\uC694",
2223
+ autoComplete: "current-password",
2224
+ required: true
2225
+ }
2226
+ ),
2227
+ (withRemember || findPasswordHref) && /* @__PURE__ */ jsxs23(Group13, { justify: "space-between", align: "center", wrap: "nowrap", children: [
2228
+ withRemember ? /* @__PURE__ */ jsx36(Checkbox2, { name: "remember", size: "xs", label: "\uC790\uB3D9 \uB85C\uADF8\uC778" }) : /* @__PURE__ */ jsx36("span", {}),
2229
+ findPasswordHref && /* @__PURE__ */ jsx36(SdLink.Sub, { href: findPasswordHref, children: "\uBE44\uBC00\uBC88\uD638\uB97C \uC78A\uC73C\uC168\uB098\uC694?" })
2230
+ ] }),
2231
+ /* @__PURE__ */ jsx36(
2232
+ SdButton.Primary,
2233
+ {
2234
+ type: "submit",
2235
+ fullWidth: true,
2236
+ loading,
2237
+ leftSection: /* @__PURE__ */ jsx36(IconLogin2, { size: 16 }),
2238
+ children: submitLabel
2239
+ }
2240
+ ),
2241
+ socials && socials.length > 0 && /* @__PURE__ */ jsxs23(Fragment6, { children: [
2242
+ /* @__PURE__ */ jsx36(Divider4, { label: "\uB610\uB294", labelPosition: "center" }),
2243
+ /* @__PURE__ */ jsx36(Stack22, { gap: "xs", children: socials.map((social) => {
2244
+ var _a4;
2245
+ const { Icon, label } = SOCIAL_META[social.provider];
2246
+ return /* @__PURE__ */ jsx36(
2247
+ SdButton.Outline,
2248
+ {
2249
+ color: "slate",
2250
+ fullWidth: true,
2251
+ type: "button",
2252
+ onClick: social.onClick,
2253
+ leftSection: /* @__PURE__ */ jsx36(Icon, { size: 16 }),
2254
+ children: (_a4 = social.label) != null ? _a4 : label
2255
+ },
2256
+ social.provider
2257
+ );
2258
+ }) })
2259
+ ] }),
2260
+ signUpHref && /* @__PURE__ */ jsxs23(Group13, { gap: 6, justify: "center", children: [
2261
+ /* @__PURE__ */ jsx36(SdText.Sub, { children: "\uC544\uC9C1 \uACC4\uC815\uC774 \uC5C6\uC73C\uC2E0\uAC00\uC694?" }),
2262
+ /* @__PURE__ */ jsx36(SdLink.Sub, { href: signUpHref, c: "primary.6", children: "\uD68C\uC6D0\uAC00\uC785" })
2263
+ ] }),
2264
+ children
2265
+ ] }) });
2266
+ }
2267
+ function FormHeader({ title, description }) {
2268
+ return /* @__PURE__ */ jsxs23(Stack22, { gap: "lg", children: [
2269
+ /* @__PURE__ */ jsx36(Logo, { size: "sm" }),
2270
+ /* @__PURE__ */ jsx36(SdTextBox.Card, { title, description: description != null ? description : "" })
2271
+ ] });
2272
+ }
2273
+ function Card7(_a4) {
2274
+ var _b = _a4, {
2275
+ title = "\uB85C\uADF8\uC778",
2276
+ description = "%c \uC11C\uBE44\uC2A4\uB97C \uC774\uC6A9\uD558\uB824\uBA74 \uB85C\uADF8\uC778\uD574 \uC8FC\uC138\uC694.",
2277
+ mih = "100svh"
2278
+ } = _b, formProps = __objRest(_b, [
2279
+ "title",
2280
+ "description",
2281
+ "mih"
2282
+ ]);
2283
+ return /* @__PURE__ */ jsx36(Center5, { mih, bg: "slate.0", p: "md", children: /* @__PURE__ */ jsx36(Paper, { w: "100%", maw: 420, p: { base: "lg", sm: "xl" }, radius: "lg", withBorder: true, shadow: "sm", children: /* @__PURE__ */ jsxs23(Stack22, { gap: "xl", children: [
2284
+ /* @__PURE__ */ jsx36(FormHeader, { title, description }),
2285
+ /* @__PURE__ */ jsx36(LoginForm, __spreadValues({}, formProps))
2286
+ ] }) }) });
2287
+ }
2288
+ function Split(_a4) {
2289
+ var _b = _a4, {
2290
+ title = "\uB85C\uADF8\uC778",
2291
+ description = "\uACC4\uC815 \uC815\uBCF4\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.",
2292
+ brandTitle = "%c",
2293
+ brandDescription = "\uD558\uB098\uC758 \uACC4\uC815\uC73C\uB85C \uBAA8\uB4E0 \uC11C\uBE44\uC2A4\uB97C \uC774\uC6A9\uD558\uC138\uC694.",
2294
+ mih = "100svh"
2295
+ } = _b, formProps = __objRest(_b, [
2296
+ "title",
2297
+ "description",
2298
+ "brandTitle",
2299
+ "brandDescription",
2300
+ "mih"
2301
+ ]);
2302
+ return /* @__PURE__ */ jsxs23(SimpleGrid7, { cols: { base: 1, md: 2 }, spacing: 0, mih, children: [
2303
+ /* @__PURE__ */ jsxs23(
2304
+ Box16,
2305
+ {
2306
+ visibleFrom: "md",
2307
+ pos: "relative",
2308
+ style: __spreadValues({ overflow: "hidden", display: "flex", alignItems: "flex-end" }, brandSurface),
2309
+ children: [
2310
+ /* @__PURE__ */ jsx36(Box16, { "aria-hidden": true, pos: "absolute", inset: 0, style: brandDotTexture }),
2311
+ /* @__PURE__ */ jsx36(Box16, { pos: "relative", p: 48, style: { zIndex: 1, width: "100%" }, children: /* @__PURE__ */ jsx36(
2312
+ SdTextBox.Hero,
2313
+ {
2314
+ title: brandTitle,
2315
+ description: brandDescription,
2316
+ gap: "sm",
2317
+ maxDescWidth: 420,
2318
+ ta: "left",
2319
+ align: "flex-start"
2320
+ }
2321
+ ) })
2322
+ ]
2323
+ }
2324
+ ),
2325
+ /* @__PURE__ */ jsx36(Center5, { p: { base: "md", sm: "xl" }, bg: "white", children: /* @__PURE__ */ jsxs23(Stack22, { gap: "xl", w: "100%", maw: 400, children: [
2326
+ /* @__PURE__ */ jsx36(FormHeader, { title, description }),
2327
+ /* @__PURE__ */ jsx36(LoginForm, __spreadValues({}, formProps))
2328
+ ] }) })
2329
+ ] });
2330
+ }
2331
+ var SdLoginView = {
2332
+ /** 중앙 정렬 카드 — 기본 로그인 화면 */
2333
+ Card: Card7,
2334
+ /** 좌측 브랜드 패널 + 우측 폼 — 넓은 화면용 */
2335
+ Split
2336
+ };
2337
+ var SdLoginViewCard = SdLoginView.Card;
2338
+ var SdLoginViewSplit = SdLoginView.Split;
2339
+
2340
+ // ui/organism/Result.tsx
2341
+ import { Box as Box17, Center as Center6, Group as Group14, Stack as Stack23 } from "@mantine/core";
2342
+ import { IconCircleCheck, IconCircleX } from "@tabler/icons-react";
2343
+ import { jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
2344
+ function ResultIcon({ color, Icon }) {
2345
+ return /* @__PURE__ */ jsx37(Center6, { w: 88, h: 88, bg: `${color}.0`, style: { borderRadius: "50%" }, "aria-hidden": true, children: /* @__PURE__ */ jsx37(Icon, { size: 48, stroke: 1.5, color: `var(--mantine-color-${color}-6)` }) });
2346
+ }
2347
+ function createResult(defaults) {
2348
+ return function SdResult2({
2349
+ title = defaults.title,
2350
+ description,
2351
+ primaryAction,
2352
+ secondaryAction,
2353
+ children,
2354
+ mih = "60vh"
2355
+ }) {
2356
+ return /* @__PURE__ */ jsx37(Center6, { mih, children: /* @__PURE__ */ jsx37(SdContainer, { children: /* @__PURE__ */ jsxs24(Stack23, { align: "center", gap: "lg", ta: "center", children: [
2357
+ /* @__PURE__ */ jsx37(ResultIcon, { color: defaults.color, Icon: defaults.Icon }),
2358
+ /* @__PURE__ */ jsxs24(Stack23, { gap: "sm", align: "center", children: [
2359
+ /* @__PURE__ */ jsx37(SdTitle.Section, { children: title }),
2360
+ description && /* @__PURE__ */ jsx37(SdText.Body, { maw: 480, children: description })
2361
+ ] }),
2362
+ children && /* @__PURE__ */ jsx37(Box17, { children }),
2363
+ (primaryAction || secondaryAction) && /* @__PURE__ */ jsxs24(Group14, { gap: "sm", justify: "center", children: [
2364
+ primaryAction && /* @__PURE__ */ jsx37(SdButton.Primary, { onClick: primaryAction.onClick, children: primaryAction.label }),
2365
+ secondaryAction && /* @__PURE__ */ jsx37(SdButton.Ghost, { onClick: secondaryAction.onClick, children: secondaryAction.label })
2366
+ ] })
2367
+ ] }) }) });
2368
+ };
2369
+ }
2370
+ var SdResult = {
2371
+ /** 성공 — 가입 완료·결제 완료 등 */
2372
+ Success: createResult({
2373
+ color: "green",
2374
+ Icon: IconCircleCheck,
2375
+ title: "\uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4"
2376
+ }),
2377
+ /** 실패 — 결제 실패·처리 중 오류 등. 서버 오류·404는 SdErrorView를 쓴다. */
2378
+ Error: createResult({
2379
+ color: "red",
2380
+ Icon: IconCircleX,
2381
+ title: "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4"
2382
+ })
2383
+ };
2384
+ var SdResultSuccess = SdResult.Success;
2385
+ var SdResultError = SdResult.Error;
2386
+
1682
2387
  // ui/template/MainLayout.tsx
1683
2388
  import { AppShell } from "@mantine/core";
1684
- import { jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
2389
+ import { jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
2390
+ var headers = {
2391
+ mega: SdHeader.Mega,
2392
+ simple: SdHeader.Simple,
2393
+ panel: SdHeader.Panel
2394
+ };
1685
2395
  function MainLayout({
1686
2396
  children,
1687
2397
  navItems,
1688
2398
  companyInfo,
1689
- loginFlag
2399
+ loginFlag,
2400
+ headerVariant = "mega"
1690
2401
  }) {
1691
- return /* @__PURE__ */ jsxs22(AppShell, { header: { height: 60 }, children: [
1692
- /* @__PURE__ */ jsx34(AppShell.Header, { children: /* @__PURE__ */ jsx34(SdHeader, { navItems, loginFlag }) }),
1693
- /* @__PURE__ */ jsx34(AppShell.Main, { children }),
1694
- /* @__PURE__ */ jsx34(SdFooter, { company: companyInfo, navItems })
2402
+ const Header = headers[headerVariant];
2403
+ return /* @__PURE__ */ jsxs25(AppShell, { header: { height: 60 }, children: [
2404
+ /* @__PURE__ */ jsx38(AppShell.Header, { children: /* @__PURE__ */ jsx38(Header, { navItems, loginFlag }) }),
2405
+ /* @__PURE__ */ jsx38(AppShell.Main, { children }),
2406
+ /* @__PURE__ */ jsx38(SdFooter, { company: companyInfo, navItems })
1695
2407
  ] });
1696
2408
  }
1697
2409
 
1698
2410
  // ui/template/PageLayout.tsx
1699
- import { Box as Box15, Divider as Divider4, Space, Stack as Stack21 } from "@mantine/core";
1700
- import { Fragment as Fragment6, jsx as jsx35, jsxs as jsxs23 } from "react/jsx-runtime";
1701
- function Content({ children }) {
1702
- return /* @__PURE__ */ jsx35(SdContainer, { py: "xl", children: /* @__PURE__ */ jsx35(Stack21, { gap: "xl", children }) });
2411
+ import { Box as Box18, Divider as Divider5, Group as Group15, Space, Stack as Stack24 } from "@mantine/core";
2412
+ import { Fragment as Fragment7, jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
2413
+ var HERO_MIN_H = "38svh";
2414
+ var HERO_PY = { base: 56, sm: 88 };
2415
+ var HERO_MAW = 680;
2416
+ function Content({
2417
+ children,
2418
+ navItems,
2419
+ breadcrumb = true,
2420
+ currentHref
2421
+ }) {
2422
+ const showBreadcrumb = breadcrumb && !!navItems && navItems.length > 0;
2423
+ return /* @__PURE__ */ jsxs26(SdContainer, { py: "xl", children: [
2424
+ showBreadcrumb && /* @__PURE__ */ jsx39(SdBreadcrumb, { navItems, currentHref, mb: "lg" }),
2425
+ /* @__PURE__ */ jsx39(Stack24, { gap: "xl", children })
2426
+ ] });
1703
2427
  }
1704
2428
  function LayoutGap() {
1705
- return /* @__PURE__ */ jsx35(Space, { h: 48 });
2429
+ return /* @__PURE__ */ jsx39(Space, {});
1706
2430
  }
1707
- function Minimal({ label, title, description, children }) {
1708
- return /* @__PURE__ */ jsx35(Fragment6, { children: /* @__PURE__ */ jsxs23(Plain2, { children: [
1709
- /* @__PURE__ */ jsx35(SdTextBox.Section, { label, title, description: description != null ? description : "" }),
1710
- /* @__PURE__ */ jsx35(Divider4, {}),
2431
+ function Minimal({
2432
+ label,
2433
+ title,
2434
+ description,
2435
+ children,
2436
+ navItems,
2437
+ breadcrumb,
2438
+ currentHref
2439
+ }) {
2440
+ return /* @__PURE__ */ jsxs26(Plain2, { navItems, breadcrumb, currentHref, children: [
2441
+ /* @__PURE__ */ jsx39(LayoutGap, {}),
2442
+ /* @__PURE__ */ jsx39(SdTextBox.Section, { label, title, description: description != null ? description : "" }),
2443
+ /* @__PURE__ */ jsx39(Divider5, {}),
1711
2444
  children
1712
- ] }) });
2445
+ ] });
2446
+ }
2447
+ function Plain2({
2448
+ children,
2449
+ navItems,
2450
+ breadcrumb,
2451
+ currentHref
2452
+ }) {
2453
+ return /* @__PURE__ */ jsx39(Fragment7, { children: /* @__PURE__ */ jsx39(Content, { navItems, breadcrumb, currentHref, children }) });
1713
2454
  }
1714
- function Plain2({ children }) {
1715
- return /* @__PURE__ */ jsxs23(Fragment6, { children: [
1716
- /* @__PURE__ */ jsx35(LayoutGap, {}),
1717
- /* @__PURE__ */ jsx35(Content, { children })
2455
+ function HeroCopy({ label, title, description }) {
2456
+ return /* @__PURE__ */ jsxs26(Stack24, { gap: "md", maw: HERO_MAW, children: [
2457
+ label && /* @__PURE__ */ jsxs26(Group15, { gap: "sm", align: "center", wrap: "nowrap", children: [
2458
+ /* @__PURE__ */ jsx39(Box18, { w: 28, h: 2, bg: "primary.3", style: { borderRadius: 2 } }),
2459
+ /* @__PURE__ */ jsx39(SdText.Eyebrow, { c: "primary.1", children: label })
2460
+ ] }),
2461
+ /* @__PURE__ */ jsx39(
2462
+ SdTextBox.Hero,
2463
+ {
2464
+ title,
2465
+ description,
2466
+ gap: "sm",
2467
+ maxDescWidth: 560,
2468
+ ta: "left",
2469
+ align: "flex-start"
2470
+ }
2471
+ )
1718
2472
  ] });
1719
2473
  }
1720
- function Image2({ image, label, title, description, children }) {
1721
- return /* @__PURE__ */ jsxs23(Fragment6, { children: [
1722
- /* @__PURE__ */ jsxs23(
1723
- Box15,
2474
+ function Image2({
2475
+ image,
2476
+ label,
2477
+ title,
2478
+ description,
2479
+ children,
2480
+ navItems,
2481
+ breadcrumb,
2482
+ currentHref
2483
+ }) {
2484
+ return /* @__PURE__ */ jsxs26(Fragment7, { children: [
2485
+ /* @__PURE__ */ jsxs26(
2486
+ Box18,
1724
2487
  {
2488
+ pos: "relative",
1725
2489
  style: {
1726
- position: "relative",
1727
- minHeight: "30svh",
2490
+ minHeight: HERO_MIN_H,
1728
2491
  display: "flex",
1729
- alignItems: "center",
2492
+ alignItems: "flex-end",
1730
2493
  backgroundImage: image ? `url(${image})` : void 0,
1731
2494
  backgroundSize: "cover",
1732
2495
  backgroundPosition: "center",
1733
2496
  backgroundColor: "var(--mantine-color-slate-9)"
1734
2497
  },
1735
2498
  children: [
1736
- /* @__PURE__ */ jsx35(
1737
- Box15,
2499
+ /* @__PURE__ */ jsx39(
2500
+ Box18,
1738
2501
  {
2502
+ "aria-hidden": true,
2503
+ pos: "absolute",
2504
+ inset: 0,
1739
2505
  style: {
1740
- position: "absolute",
1741
- inset: 0,
1742
- background: "rgba(0, 0, 0, 0.55)"
2506
+ 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%)"
1743
2507
  }
1744
2508
  }
1745
2509
  ),
1746
- /* @__PURE__ */ jsx35(SdContainer, { style: { position: "relative", zIndex: 1, width: "100%" }, children: /* @__PURE__ */ jsx35(
1747
- Box15,
1748
- {
1749
- py: 48,
1750
- px: 40,
1751
- maw: 420,
1752
- style: {
1753
- backdropFilter: "blur(24px)",
1754
- WebkitBackdropFilter: "blur(24px)",
1755
- background: "rgba(255,255,255,0.10)",
1756
- borderRadius: "var(--mantine-radius-md)",
1757
- border: "1px solid rgba(255,255,255,0.18)"
1758
- },
1759
- children: /* @__PURE__ */ jsx35(
1760
- SdTextBox.Hero,
1761
- {
1762
- label,
1763
- title,
1764
- description,
1765
- ta: "left",
1766
- align: "flex-start"
1767
- }
1768
- )
1769
- }
1770
- ) })
2510
+ /* @__PURE__ */ jsx39(SdContainer, { pos: "relative", py: HERO_PY, style: { zIndex: 1, width: "100%" }, children: /* @__PURE__ */ jsx39(HeroCopy, { label, title, description }) })
1771
2511
  ]
1772
2512
  }
1773
2513
  ),
1774
- /* @__PURE__ */ jsx35(Content, { children })
2514
+ /* @__PURE__ */ jsx39(Content, { navItems, breadcrumb, currentHref, children })
1775
2515
  ] });
1776
2516
  }
1777
- function Brand({ label, title, description, children }) {
1778
- return /* @__PURE__ */ jsxs23(Fragment6, { children: [
1779
- /* @__PURE__ */ jsxs23(
1780
- Box15,
2517
+ function Brand({
2518
+ label,
2519
+ title,
2520
+ description,
2521
+ children,
2522
+ navItems,
2523
+ breadcrumb,
2524
+ currentHref
2525
+ }) {
2526
+ return /* @__PURE__ */ jsxs26(Fragment7, { children: [
2527
+ /* @__PURE__ */ jsxs26(
2528
+ Box18,
1781
2529
  {
1782
- style: {
1783
- position: "relative",
1784
- minHeight: "40svh",
2530
+ pos: "relative",
2531
+ style: __spreadValues({
2532
+ minHeight: HERO_MIN_H,
1785
2533
  display: "flex",
1786
- alignItems: "center",
2534
+ alignItems: "flex-end",
1787
2535
  overflow: "hidden",
1788
- background: "linear-gradient(135deg, var(--mantine-color-primary-8) 0%, var(--mantine-color-primary-6) 50%, var(--mantine-color-primary-4) 100%)"
1789
- },
2536
+ borderBottom: "1px solid var(--mantine-color-slate-8)"
2537
+ }, brandSurface),
1790
2538
  children: [
1791
- /* @__PURE__ */ jsx35(
1792
- Box15,
1793
- {
1794
- style: {
1795
- position: "absolute",
1796
- top: -80,
1797
- right: -80,
1798
- width: 360,
1799
- height: 360,
1800
- borderRadius: "50%",
1801
- background: "rgba(255,255,255,0.06)",
1802
- pointerEvents: "none"
1803
- }
1804
- }
1805
- ),
1806
- /* @__PURE__ */ jsx35(
1807
- Box15,
1808
- {
1809
- style: {
1810
- position: "absolute",
1811
- bottom: -60,
1812
- left: -60,
1813
- width: 240,
1814
- height: 240,
1815
- borderRadius: "50%",
1816
- background: "rgba(255,255,255,0.04)",
1817
- pointerEvents: "none"
1818
- }
1819
- }
1820
- ),
1821
- /* @__PURE__ */ jsx35(SdContainer, { style: { position: "relative", zIndex: 1, width: "100%" }, children: /* @__PURE__ */ jsx35(
1822
- SdTextBox.Hero,
1823
- {
1824
- label,
1825
- title,
1826
- description,
1827
- ta: "center",
1828
- align: "center",
1829
- maw: 640,
1830
- mx: "auto",
1831
- pt: 80,
1832
- pb: 64
1833
- }
1834
- ) })
2539
+ /* @__PURE__ */ jsx39(Box18, { "aria-hidden": true, pos: "absolute", inset: 0, style: brandDotTexture }),
2540
+ /* @__PURE__ */ jsx39(SdContainer, { pos: "relative", py: HERO_PY, style: { zIndex: 1, width: "100%" }, children: /* @__PURE__ */ jsx39(HeroCopy, { label, title, description }) })
1835
2541
  ]
1836
2542
  }
1837
2543
  ),
1838
- /* @__PURE__ */ jsx35(Content, { children })
2544
+ /* @__PURE__ */ jsx39(Content, { navItems, breadcrumb, currentHref, children })
1839
2545
  ] });
1840
2546
  }
1841
2547
  var PageLayout = {
1842
- /** 이미지 배경 + 대각선 그라디언트 + 좌하단 텍스트 */
2548
+ /** 사진 배경 + 하단 스크림 + 좌측 정렬 텍스트 */
1843
2549
  Image: Image2,
1844
2550
  /** SdTextBox.Section 타이틀 + Plain 컨테이너 */
1845
2551
  Minimal,
1846
- /** primary 그라디언트 배경 + 중앙 텍스트 */
2552
+ /** slate 바탕 + primary 라이트 + 도트 텍스처 */
1847
2553
  Brand,
1848
2554
  /** 히어로 없이 SdContainer + py="xl" 만 */
1849
2555
  Plain: Plain2
1850
2556
  };
2557
+ var PageLayoutImage = PageLayout.Image;
2558
+ var PageLayoutMinimal = PageLayout.Minimal;
2559
+ var PageLayoutBrand = PageLayout.Brand;
2560
+ var PageLayoutPlain = PageLayout.Plain;
1851
2561
 
1852
2562
  // ui/theme.ts
1853
2563
  import { createTheme, rem as rem2 } from "@mantine/core";
@@ -1944,9 +2654,31 @@ var green = [
1944
2654
  "#14532d"
1945
2655
  // 9 green-900
1946
2656
  ];
2657
+ var amber = [
2658
+ "#fffbeb",
2659
+ // 0 amber-50
2660
+ "#fef3c7",
2661
+ // 1 amber-100
2662
+ "#fde68a",
2663
+ // 2 amber-200
2664
+ "#fcd34d",
2665
+ // 3 amber-300
2666
+ "#fbbf24",
2667
+ // 4 amber-400
2668
+ "#f59e0b",
2669
+ // 5 amber-500
2670
+ "#d97706",
2671
+ // 6 amber-600
2672
+ "#b45309",
2673
+ // 7 amber-700
2674
+ "#92400e",
2675
+ // 8 amber-800
2676
+ "#78350f"
2677
+ // 9 amber-900
2678
+ ];
1947
2679
  var theme = createTheme({
1948
2680
  /* ---- Color ---- */
1949
- colors: { primary, secondary, slate, red, green, dark: slate },
2681
+ colors: { primary, secondary, slate, red, green, amber, dark: slate },
1950
2682
  primaryColor: "primary",
1951
2683
  primaryShade: { light: 6, dark: 5 },
1952
2684
  /* ---- Type ---- */
@@ -2071,7 +2803,6 @@ var theme = createTheme({
2071
2803
  Anchor: {
2072
2804
  defaultProps: { c: "slate.5", fz: "sm", underline: "never" }
2073
2805
  },
2074
- // SdHeader 모바일 드로어의 2단 아코디언 타이포를 SdLink와 맞춘다.
2075
2806
  NavLink: {
2076
2807
  defaultProps: { c: "slate.7", fz: "sm" }
2077
2808
  },
@@ -2090,11 +2821,16 @@ export {
2090
2821
  Logo,
2091
2822
  MainLayout,
2092
2823
  PageLayout,
2824
+ PageLayoutBrand,
2825
+ PageLayoutImage,
2826
+ PageLayoutMinimal,
2827
+ PageLayoutPlain,
2093
2828
  SdBadge,
2094
2829
  SdBadgeDefault,
2095
2830
  SdBadgePrimary,
2096
2831
  SdBadgeSuccess,
2097
2832
  SdBadgeWarning,
2833
+ SdBreadcrumb,
2098
2834
  SdButton,
2099
2835
  SdButtonCancel,
2100
2836
  SdButtonDelete,
@@ -2125,17 +2861,41 @@ export {
2125
2861
  SdFeatures,
2126
2862
  SdFooter,
2127
2863
  SdHeader,
2864
+ SdHeaderMega,
2865
+ SdHeaderPanel,
2866
+ SdHeaderSimple,
2128
2867
  SdInput,
2868
+ SdInputAutocomplete,
2869
+ SdInputCheckbox,
2870
+ SdInputColor,
2871
+ SdInputDate,
2872
+ SdInputDateRange,
2129
2873
  SdInputEmail,
2874
+ SdInputFile,
2875
+ SdInputJson,
2876
+ SdInputMultiSelect,
2877
+ SdInputNativeSelect,
2878
+ SdInputNumber,
2130
2879
  SdInputPassword,
2880
+ SdInputPinCode,
2881
+ SdInputRadioGroup,
2882
+ SdInputRating,
2883
+ SdInputSegmented,
2131
2884
  SdInputSelect,
2885
+ SdInputSlider,
2886
+ SdInputSwitch,
2887
+ SdInputTags,
2132
2888
  SdInputText,
2133
2889
  SdInputTextarea,
2890
+ SdInputTime,
2134
2891
  SdLink,
2135
2892
  SdLinkBody,
2136
2893
  SdLinkHint,
2137
2894
  SdLinkStrong,
2138
2895
  SdLinkSub,
2896
+ SdLoginView,
2897
+ SdLoginViewCard,
2898
+ SdLoginViewSplit,
2139
2899
  SdMap,
2140
2900
  SdMapSingle,
2141
2901
  SdMapTabs,
@@ -2148,6 +2908,9 @@ export {
2148
2908
  SdQuote,
2149
2909
  SdQuoteCard,
2150
2910
  SdQuotePlain,
2911
+ SdResult,
2912
+ SdResultError,
2913
+ SdResultSuccess,
2151
2914
  SdSkeleton,
2152
2915
  SdSkeletonAvatar,
2153
2916
  SdSkeletonCard,
@@ -2195,5 +2958,15 @@ export {
2195
2958
  SdTitleDisplay,
2196
2959
  SdTitleSection,
2197
2960
  SdTitleSub,
2961
+ SdToast,
2962
+ SdToastClean,
2963
+ SdToastError,
2964
+ SdToastHide,
2965
+ SdToastInfo,
2966
+ SdToastLoading,
2967
+ SdToastProvider,
2968
+ SdToastSuccess,
2969
+ SdToastUpdate,
2970
+ SdToastWarning,
2198
2971
  theme
2199
2972
  };