@naeil/ui 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +5 -5
  3. package/dist/{chunk-XRO3NJAB.js → chunk-KWEWR46R.js} +40 -154
  4. package/dist/{chunk-JDHGKM25.js → chunk-U3IZCFM4.js} +267 -2
  5. package/dist/components/index.js +12 -3
  6. package/dist/components/naeil-footer.d.ts +3 -3
  7. package/dist/components/naeil-footer.js +14 -11
  8. package/dist/components/naeil-header.d.ts +7 -9
  9. package/dist/components/naeil-header.js +2 -2
  10. package/dist/lib/ui-release.d.ts +1 -1
  11. package/dist/lib/ui-release.js +1 -1
  12. package/dist/naeil-locale/checker.d.ts +16 -0
  13. package/dist/naeil-locale/checker.js +91 -0
  14. package/dist/naeil-locale/chrome.d.ts +150 -0
  15. package/dist/naeil-locale/chrome.js +2385 -0
  16. package/dist/naeil-locale/chunk-4U64K4J3.js +56 -0
  17. package/dist/naeil-locale/chunk-N3ETBM74.js +24 -0
  18. package/dist/naeil-locale/chunk-U65OQHZY.js +167 -0
  19. package/dist/naeil-locale/chunk-YQ5OJWBF.js +53 -0
  20. package/dist/naeil-locale/client.d.ts +70 -0
  21. package/dist/naeil-locale/client.js +388 -0
  22. package/dist/naeil-locale/en-ZC66VDHP.js +86 -0
  23. package/dist/naeil-locale/index.d.ts +40 -0
  24. package/dist/naeil-locale/index.js +111 -0
  25. package/dist/naeil-locale/ja-DKIEQUG7.js +86 -0
  26. package/dist/naeil-locale/ko-CY6663RZ.js +86 -0
  27. package/dist/naeil-locale/messages-BuQvB-u2.d.ts +167 -0
  28. package/dist/naeil-locale/messages.d.ts +1 -0
  29. package/dist/naeil-locale/messages.js +14 -0
  30. package/dist/naeil-locale/server.d.ts +75 -0
  31. package/dist/naeil-locale/server.js +172 -0
  32. package/dist/source/components/naeil-footer-core.d.ts +16 -0
  33. package/dist/source/components/naeil-footer-core.js +93 -0
  34. package/dist/source/components/naeil-footer.d.ts +6 -11
  35. package/dist/source/components/naeil-footer.js +4 -75
  36. package/dist/source/components/naeil-header-account-core.d.ts +26 -0
  37. package/dist/source/components/naeil-header-account-core.js +98 -0
  38. package/dist/source/components/naeil-header-account.d.ts +6 -22
  39. package/dist/source/components/naeil-header-account.js +5 -81
  40. package/dist/source/components/naeil-header-content.d.ts +102 -109
  41. package/dist/source/components/naeil-header-content.js +6 -142
  42. package/dist/source/components/naeil-header-core.d.ts +59 -0
  43. package/dist/source/components/naeil-header-core.js +231 -0
  44. package/dist/source/components/naeil-header-data.d.ts +11 -0
  45. package/dist/source/components/naeil-header-data.js +14 -0
  46. package/dist/source/components/naeil-header.d.ts +10 -51
  47. package/dist/source/components/naeil-header.js +9 -200
  48. package/dist/source/components/naeil-messages-context.d.ts +94 -0
  49. package/dist/source/components/naeil-messages-context.js +16 -0
  50. package/dist/source/components/naeil-standalone-messages.d.ts +11 -0
  51. package/dist/source/components/naeil-standalone-messages.js +13 -0
  52. package/dist/source/i18n/routing.d.ts +22 -20
  53. package/dist/source/lib/ui-release.d.ts +1 -1
  54. package/dist/source/lib/ui-release.js +1 -1
  55. package/dist/source/naeil-locale/messages/en.json +78 -0
  56. package/dist/source/naeil-locale/messages/ja.json +78 -0
  57. package/dist/source/naeil-locale/messages/ko.json +78 -0
  58. package/docs/components/naeil-locale.md +52 -0
  59. package/docs/package-release.md +31 -6
  60. package/package.json +35 -7
  61. /package/dist/{naeil-header-content-BvISJ4RV.d.ts → naeil-header-data-BvISJ4RV.d.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.0 — AB Storm locale registration (unpublished candidate)
4
+
5
+ - Add the exact owned `abstorm` origin and five protected UI routes to the opt-in locale runtime, with English, Korean and Japanese paths. Keep auth/API/health endpoints outside localized UI routing.
6
+ - Render localized fail-closed documents with the app’s `abstorm` identity; no favicon is declared by the current app.
7
+ - Fix generated locale declarations: JSON imports previously left variable initializers in `.d.ts` output and failed installed-consumer TypeScript checks with library checking enabled. Normalize only those declarations to ambient JSON types; runtime imports and message loading remain unchanged. Clean packed-consumer tests now import the locale API and run `tsc` without `skipLibCheck`.
8
+ - Additive public API release; existing services, default chrome/footer catalogs, messages and chrome contract 1 remain unchanged. Publish the reviewed exact archive to `next`; package publication and consumer adoption remain separate.
9
+
10
+ ## 0.10.0 — shared language runtime (unpublished candidate)
11
+
12
+ - Add opt-in `naeil-locale` root, client, server, messages, checker and chrome entries for the owned Next applications. English uses unprefixed paths; Korean/Japanese use `/ko` and `/ja`. Strict route/protocol parsing, legacy receiving aliases, selected JSON loading, ICU validation and committed-intent preference writes share one implementation.
13
+ - Keep the transition controller above locale layouts, restore stable focus, and share document-departure protection. Consumers retain business/session state, data authorization and logical-navigation guards.
14
+ - Move canonical header/footer/account copy to one JSON source. Existing React-only imports keep standalone locale props and public overrides; the opt-in chrome entry uses the selected provider dictionary. Generic Navigation/SiteFooter and legacy Nav/Footer routing APIs remain unchanged.
15
+ - Validate all three Next consumers with exact next-intl4.14.8. Publication, receiver deployment, cross-service sending and hosted Docs have separate receipts; see [the integration guide](docs/components/naeil-locale.md).
16
+
3
17
  ## 0.9.0 — page-root scrollbar reservation
4
18
 
5
19
  - Reserve one classic scrollbar gutter at the document root through both package CSS paths; overlay scrollbars reserve no space. The root `data-naeil-scrollbar-gutter="auto"` opt-out disables reservation and shared lock correction together.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  React components, semantic design tokens, and shared styles for naeil products. The approved system uses a neutral light/dark palette, Pretendard, 16px controls, comfortable or compact density, purpose-specific content widths, and restrained motion. Radix supplies interaction behavior.
4
4
 
5
- **Version 0.9.0 adds the shared page-root scrollbar reservation and scroll-lock correction.** Use an exact version with verified registry publication and archive identity. At the 2026-10-29 verification, the published 0.8.0 archive matched frozen SHA-256 `6feb5a8cd50265ace584a0855432683b4127119377e08235282eaebd27081084` (139 files, source `3f708e27d05212af7f7a5be769f13f871e8d10c7`); tags were `latest=0.7.2`, `next=0.8.0`. Current publication, hosted Docs and per-service deployment have separate receipts in the [release policy](docs/package-release.md#publication-and-deployment).
5
+ **0.10.0 published and registry-verified — 2026-11-04.** This release adds the shared language runtime and preserves the page-root scrollbar reservation and scroll-lock correction. The registry archive matches frozen SHA-256 `a4a1e312f2f608358a10f9019c248af37a8172bb116d3bc506144442cb963fb4` (175 files, source/tag `455f2f9aedb108606af2f429c18281260eafd2dd`); verified tags were `latest=0.7.2`, `next=0.10.0`. See the [publication and service acceptance receipts](https://github.com/naeil-dev/naeil-ui/blob/main/docs/design/shared-language-2026-11-04/implementation-progress.md). Hosted Docs remain separately recorded. The retained [local runner](https://github.com/naeil-dev/naeil-ui/blob/main/docs/rollout/local-runner.md) supports historical **0.7.x only** and cannot deploy or recover the current 0.10.0 release.
6
6
 
7
7
  This repository also contains the **naeil.dev brand/example website** and an **optional agent reference workflow**. Choose the path you need:
8
8
 
@@ -15,13 +15,13 @@ This repository also contains the **naeil.dev brand/example website** and an **o
15
15
 
16
16
  ## Use the UI
17
17
 
18
- Use React 19 / ReactDOM 19 and Tailwind 4. UI v2 names the design generation independently of npm versioning. The installation example targets 0.9.0; run it after verifying that exact version's registry publication:
18
+ Use React 19 / ReactDOM 19 and Tailwind 4. UI v2 names the design generation independently of npm versioning. The installation example targets the verified exact 0.10.0 release:
19
19
 
20
20
  ```sh
21
- pnpm add --save-exact @naeil/ui@0.9.0
21
+ pnpm add --save-exact @naeil/ui@0.10.0
22
22
  ```
23
23
 
24
- The [npm 0.8.0 archive](https://registry.npmjs.org/@naeil/ui/-/ui-0.8.0.tgz) is byte-identical to its frozen release archive. Bundled guides record the preparation snapshot; maintained guides record later publication outcomes. For local development, `pnpm build:pkg` and `npm pack --ignore-scripts --pack-destination /tmp` produce `/tmp/naeil-ui-0.9.0.tgz` from the checked-out source. Use the exact reviewed archive for release verification; later source or guide changes require a new freeze. The [0.6.0 release record](https://github.com/naeil-dev/naeil-ui/releases/tag/v0.6.0) retains its archive, publication and deployment evidence.
24
+ The [npm 0.10.0 archive](https://registry.npmjs.org/@naeil/ui/-/ui-0.10.0.tgz) is byte-identical to its frozen release archive. Bundled guides record the preparation snapshot; maintained guides record later publication outcomes. For local development, `pnpm build:pkg` and `npm pack --ignore-scripts --pack-destination /tmp` produce `/tmp/naeil-ui-VERSION.tgz`, where `VERSION` is the checked-out `package.json` version (currently the unpublished 0.11.0 candidate). Use the exact reviewed archive for release verification; later source or guide changes require a new freeze. The [0.6.0 release record](https://github.com/naeil-dev/naeil-ui/releases/tag/v0.6.0) retains its archive, publication and deployment evidence.
25
25
 
26
26
  The preceding [0.5.0 release](https://github.com/naeil-dev/naeil-ui/releases/tag/v0.5.0) was published on 2026-10-15 and introduced the whole shared header. Version 0.6.0 adds the shared 1600px frame; existing applications must upgrade and adopt its layout composition.
27
27
 
@@ -109,7 +109,7 @@ pnpm pack --pack-destination /tmp
109
109
  | `pnpm build:pkg` / `pnpm check:package` | Build package / inspect package boundary and independently install/build packed React + Next consumers |
110
110
  | `pnpm dev` / `pnpm build` | Brand/example website development / build |
111
111
 
112
- A [reusable React consumer example](https://github.com/naeil-dev/naeil-ui/tree/main/examples/react) composes the packaged header, a settings form and footer. [Release policy](docs/package-release.md) and [changelog](CHANGELOG.md) distinguish implementation, publication and deployment. CI verifies the package and separate website/Storybook. Downloadable preview artifacts include notices and local fonts. The current Storybook source defines 17 Docs pages (15 UI families and Brand / Logo plus NaeilHeader), including Usage, JapaneseApplication, ReferenceFull, ReferenceCompact and AccountStates examples. This does not establish a new hosted deployment. [Hosted Docs](https://naeil-dev.github.io/naeil-ui/) have recorded [0.5.0 verification](https://github.com/naeil-dev/naeil-ui/releases/download/v0.5.0/hosted-docs-verification.json); subsequent deployments require their own source and HTTP checks. The same approved brand is live on [naeil.dev](https://naeil.dev/). See [preview instructions](docs/package-release.md#storybook-preview-artifact) and [support limits](docs/design/public-ui-support.md). Native/manual platform acceptance retains its documented limits; service adoption and continuous rollout have separate [dated records](https://github.com/naeil-dev/naeil-ui/tree/main/docs/rollout).
112
+ A [reusable React consumer example](https://github.com/naeil-dev/naeil-ui/tree/main/examples/react) composes the packaged header, a settings form and footer. [Release policy](docs/package-release.md) and [changelog](CHANGELOG.md) distinguish implementation, publication and deployment. CI verifies the package and separate website/Storybook. Downloadable preview artifacts include notices and local fonts. The current Storybook source defines 17 Docs pages (15 UI families and Brand / Logo plus NaeilHeader), including Usage, JapaneseApplication, ReferenceFull, ReferenceCompact and AccountStates examples. This does not establish a new hosted deployment. [Hosted Docs](https://naeil-dev.github.io/naeil-ui/) have recorded [0.5.0 verification](https://github.com/naeil-dev/naeil-ui/releases/download/v0.5.0/hosted-docs-verification.json); subsequent deployments require their own source and HTTP checks. The same approved brand is live on [naeil.dev](https://naeil.dev/). See [preview instructions](docs/package-release.md#storybook-preview-artifact) and [support limits](docs/design/public-ui-support.md). Native/manual platform acceptance retains its documented limits; service adoption and rollout have separate [dated records](https://github.com/naeil-dev/naeil-ui/tree/main/docs/rollout).
113
113
 
114
114
  Read [DESIGN.md](DESIGN.md) before shared UI changes. Numeric values live in `src/tokens/`; generated CSS is not edited by hand. Shared styles live in `src/styles/`, site-only styles in `src/app/`. Hero art, 3D scenes, cursor effects, and site content belong to the example website.
115
115
 
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  Logo,
4
- uiRelease
5
- } from "./chunk-JDHGKM25.js";
4
+ NaeilStandaloneMessages,
5
+ uiRelease,
6
+ useNaeilMessages
7
+ } from "./chunk-U3IZCFM4.js";
6
8
  import {
7
9
  Badge,
8
10
  Button,
@@ -27,14 +29,13 @@ import {
27
29
  cn
28
30
  } from "./chunk-JBTDRVZ7.js";
29
31
 
30
- // src/components/naeil-header.tsx
32
+ // src/components/naeil-header-core.tsx
31
33
  import { useSyncExternalStore } from "react";
32
34
  import { useTheme } from "next-themes";
33
35
  import { Moon, Sun } from "lucide-react";
34
36
 
35
- // src/components/naeil-header-content.ts
37
+ // src/components/naeil-header-data.ts
36
38
  var headerLocales = ["en", "ko", "ja"];
37
- var headerLocaleNames = { en: "English", ko: "\uD55C\uAD6D\uC5B4", ja: "\u65E5\u672C\u8A9E" };
38
39
  var headerProjects = [
39
40
  {
40
41
  "key": "naeilUi",
@@ -44,150 +45,14 @@ var headerProjects = [
44
45
  "status": "active"
45
46
  }
46
47
  ];
47
- var headerContent = {
48
- "en": {
49
- "nav": {
50
- "home": "Home",
51
- "projects": "Projects",
52
- "blog": "Blog",
53
- "navigation": "Main navigation",
54
- "menu": "Menu",
55
- "closeMenu": "Close menu"
56
- },
57
- "theme": {
58
- "switchToLight": "Switch to light theme",
59
- "switchToDark": "Switch to dark theme"
60
- },
61
- "locale": {
62
- "switchLabel": "Language"
63
- },
64
- "projects": {
65
- "cc": {
66
- "name": "Content Collector",
67
- "description": "Automated content collection from RSS, YouTube, Reddit + AI summarization"
68
- },
69
- "pkm": {
70
- "name": "PKM",
71
- "description": "Personal knowledge management \u2014 document parsing, embeddings, semantic search"
72
- },
73
- "naeilUi": {
74
- "name": "naeil-ui",
75
- "description": "Minimal design system \u2014 OKLCH tokens, Tailwind v4, shadcn"
76
- },
77
- "sa": {
78
- "name": "Sustainability Analyzer",
79
- "description": "AI-powered ESG report analysis \u2014 PDF parsing, qualitative assessment, comparison tables"
80
- },
81
- "babyAgent": {
82
- "name": "Baby Agent",
83
- "description": "Parenting AI agent \u2014 LINE-based Q&A, records, reminders"
84
- },
85
- "status": {
86
- "active": "Active",
87
- "coming": "Coming Soon"
88
- }
89
- }
90
- },
91
- "ko": {
92
- "nav": {
93
- "home": "\uD648",
94
- "projects": "\uD504\uB85C\uC81D\uD2B8",
95
- "blog": "\uBE14\uB85C\uADF8",
96
- "navigation": "\uC8FC\uC694 \uBA54\uB274",
97
- "menu": "\uBA54\uB274",
98
- "closeMenu": "\uBA54\uB274 \uB2EB\uAE30"
99
- },
100
- "theme": {
101
- "switchToLight": "\uBC1D\uC740 \uD14C\uB9C8\uB85C \uC804\uD658",
102
- "switchToDark": "\uC5B4\uB450\uC6B4 \uD14C\uB9C8\uB85C \uC804\uD658"
103
- },
104
- "locale": {
105
- "switchLabel": "\uC5B8\uC5B4"
106
- },
107
- "projects": {
108
- "cc": {
109
- "name": "Content Collector",
110
- "description": "RSS, YouTube, Reddit \uC790\uB3D9 \uC218\uC9D1 + AI \uC694\uC57D"
111
- },
112
- "pkm": {
113
- "name": "PKM",
114
- "description": "\uAC1C\uC778 \uC9C0\uC2DD \uAD00\uB9AC \u2014 \uBB38\uC11C \uD30C\uC2F1, \uC784\uBCA0\uB529, \uC2DC\uB9E8\uD2F1 \uAC80\uC0C9"
115
- },
116
- "naeilUi": {
117
- "name": "naeil-ui",
118
- "description": "\uBBF8\uB2C8\uBA40 \uB514\uC790\uC778 \uC2DC\uC2A4\uD15C \u2014 OKLCH \uD1A0\uD070, Tailwind v4, shadcn"
119
- },
120
- "sa": {
121
- "name": "Sustainability Analyzer",
122
- "description": "ESG \uB9AC\uD3EC\uD2B8 AI \uBD84\uC11D \u2014 PDF \uD30C\uC2F1, \uC815\uC131\uD3C9\uAC00, \uBE44\uAD50\uD45C \uC790\uB3D9 \uC0DD\uC131"
123
- },
124
- "babyAgent": {
125
- "name": "Baby Agent",
126
- "description": "\uC721\uC544 AI \uC5D0\uC774\uC804\uD2B8 \u2014 LINE \uAE30\uBC18 Q&A, \uAE30\uB85D, \uB9AC\uB9C8\uC778\uB354"
127
- },
128
- "status": {
129
- "active": "\uD65C\uC131",
130
- "coming": "\uC900\uBE44 \uC911"
131
- }
132
- }
133
- },
134
- "ja": {
135
- "nav": {
136
- "home": "\u30DB\u30FC\u30E0",
137
- "projects": "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8",
138
- "blog": "\u30D6\u30ED\u30B0",
139
- "navigation": "\u30E1\u30A4\u30F3\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3",
140
- "menu": "\u30E1\u30CB\u30E5\u30FC",
141
- "closeMenu": "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B"
142
- },
143
- "theme": {
144
- "switchToLight": "\u30E9\u30A4\u30C8\u30C6\u30FC\u30DE\u306B\u5207\u308A\u66FF\u3048\u308B",
145
- "switchToDark": "\u30C0\u30FC\u30AF\u30C6\u30FC\u30DE\u306B\u5207\u308A\u66FF\u3048\u308B"
146
- },
147
- "locale": {
148
- "switchLabel": "\u8A00\u8A9E"
149
- },
150
- "projects": {
151
- "cc": {
152
- "name": "Content Collector",
153
- "description": "RSS\u3001YouTube\u3001Reddit\u306E\u81EA\u52D5\u53CE\u96C6 + AI\u8981\u7D04"
154
- },
155
- "pkm": {
156
- "name": "PKM",
157
- "description": "\u500B\u4EBA\u30CA\u30EC\u30C3\u30B8\u7BA1\u7406 \u2014 \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u89E3\u6790\u3001\u57CB\u3081\u8FBC\u307F\u3001\u30BB\u30DE\u30F3\u30C6\u30A3\u30C3\u30AF\u691C\u7D22"
158
- },
159
- "naeilUi": {
160
- "name": "naeil-ui",
161
- "description": "\u30DF\u30CB\u30DE\u30EB\u30C7\u30B6\u30A4\u30F3\u30B7\u30B9\u30C6\u30E0 \u2014 OKLCH\u30C8\u30FC\u30AF\u30F3\u3001Tailwind v4\u3001shadcn"
162
- },
163
- "sa": {
164
- "name": "Sustainability Analyzer",
165
- "description": "ESG\u30EC\u30DD\u30FC\u30C8AI\u5206\u6790 \u2014 PDF\u89E3\u6790\u3001\u5B9A\u6027\u8A55\u4FA1\u3001\u6BD4\u8F03\u8868\u306E\u81EA\u52D5\u751F\u6210"
166
- },
167
- "babyAgent": {
168
- "name": "Baby Agent",
169
- "description": "\u80B2\u5150AI\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8 \u2014 LINE Q&A\u3001\u8A18\u9332\u3001\u30EA\u30DE\u30A4\u30F3\u30C0\u30FC"
170
- },
171
- "status": {
172
- "active": "\u30A2\u30AF\u30C6\u30A3\u30D6",
173
- "coming": "\u6E96\u5099\u4E2D"
174
- }
175
- }
176
- }
177
- };
178
48
 
179
- // src/components/naeil-header-account.tsx
49
+ // src/components/naeil-header-account-core.tsx
180
50
  import { UserRound } from "lucide-react";
181
51
  import { useContext, useRef } from "react";
182
52
  import { jsx, jsxs } from "react/jsx-runtime";
183
- var labels = {
184
- en: { menu: "Account menu", account: "Account", login: "Log in", logout: "Log out", busy: "Logging out\u2026" },
185
- ko: { menu: "\uACC4\uC815 \uBA54\uB274", account: "\uACC4\uC815", login: "\uB85C\uADF8\uC778", logout: "\uB85C\uADF8\uC544\uC6C3", busy: "\uB85C\uADF8\uC544\uC6C3 \uC911\u2026" },
186
- ja: { menu: "\u30A2\u30AB\u30A6\u30F3\u30C8\u30E1\u30CB\u30E5\u30FC", account: "\u30A2\u30AB\u30A6\u30F3\u30C8", login: "\u30ED\u30B0\u30A4\u30F3", logout: "\u30ED\u30B0\u30A2\u30A6\u30C8", busy: "\u30ED\u30B0\u30A2\u30A6\u30C8\u4E2D\u2026" }
187
- };
188
53
  var NativeLink = (props) => /* @__PURE__ */ jsx("a", __spreadValues({}, props));
189
54
  function NaeilHeaderAccountControl({ locale, account, Link = NativeLink }) {
190
- const text = labels[locale];
55
+ const text = useNaeilMessages(locale).account;
191
56
  const handoff = useContext(NavigationSheetAction);
192
57
  const pendingAction = useRef(void 0);
193
58
  if (account.status === "signed-out") {
@@ -255,11 +120,12 @@ function NaeilHeaderAccountControl({ locale, account, Link = NativeLink }) {
255
120
  ] });
256
121
  }
257
122
 
258
- // src/components/naeil-header.tsx
123
+ // src/components/naeil-header-core.tsx
259
124
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
260
125
  var subscribe = () => () => {
261
126
  };
262
127
  function NaeilHeaderThemeControl({ locale }) {
128
+ const copy = useNaeilMessages(locale);
263
129
  const { resolvedTheme, setTheme } = useTheme();
264
130
  const mounted = useSyncExternalStore(subscribe, () => true, () => false);
265
131
  const dark = mounted && resolvedTheme === "dark";
@@ -270,23 +136,25 @@ function NaeilHeaderThemeControl({ locale }) {
270
136
  size: "icon",
271
137
  className: "size-11 shrink-0",
272
138
  disabled: !mounted,
273
- "aria-label": headerContent[locale].theme[dark ? "switchToLight" : "switchToDark"],
139
+ "aria-label": copy.header.theme[dark ? "switchToLight" : "switchToDark"],
274
140
  onClick: () => setTheme(dark ? "light" : "dark"),
275
141
  children: dark ? /* @__PURE__ */ jsx2(Sun, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx2(Moon, { "aria-hidden": "true" })
276
142
  }
277
143
  );
278
144
  }
279
145
  function NaeilHeaderLocaleControl({ locale, onLocaleChange }) {
146
+ const copy = useNaeilMessages(locale);
280
147
  return /* @__PURE__ */ jsxs2(Select, { value: locale, onValueChange: (value) => onLocaleChange(value), children: [
281
148
  /* @__PURE__ */ jsx2(
282
149
  SelectTrigger,
283
150
  {
151
+ "data-naeil-focus-id": "locale-control",
284
152
  className: "h-11 w-auto min-w-20 border-transparent bg-transparent px-2",
285
- "aria-label": headerContent[locale].locale.switchLabel,
153
+ "aria-label": copy.header.locale.switchLabel,
286
154
  children: /* @__PURE__ */ jsx2(SelectValue, { children: locale.toUpperCase() })
287
155
  }
288
156
  ),
289
- /* @__PURE__ */ jsx2(SelectContent, { align: "end", "data-naeil-chrome": "", "data-naeil-locale-menu": "", lang: locale, children: headerLocales.map((value) => /* @__PURE__ */ jsx2(SelectItem, { value, className: "min-h-11", lang: value, children: headerLocaleNames[value] }, value)) })
157
+ /* @__PURE__ */ jsx2(SelectContent, { align: "end", "data-naeil-chrome": "", "data-naeil-locale-menu": "", lang: locale, children: headerLocales.map((value) => /* @__PURE__ */ jsx2(SelectItem, { value, className: "min-h-11", lang: value, children: copy.locale.names[value] }, value)) })
290
158
  ] });
291
159
  }
292
160
  var NativeLink2 = (props) => /* @__PURE__ */ jsx2("a", __spreadValues({}, props));
@@ -312,7 +180,7 @@ function NaeilHeader(_a) {
312
180
  subNav,
313
181
  currentProjectKey,
314
182
  currentProjectHref,
315
- labels: labels2,
183
+ labels,
316
184
  Link = NativeLink2,
317
185
  currentHref,
318
186
  onNavigate,
@@ -347,7 +215,7 @@ function NaeilHeader(_a) {
347
215
  "containerClassName"
348
216
  ]);
349
217
  var _b2, _c;
350
- const content = headerContent[locale];
218
+ const content = useNaeilMessages(locale).header;
351
219
  const projectLinks = !showProjects ? [] : projects != null ? projects : headerProjects.map((project) => {
352
220
  var _a3, _b3, _c2;
353
221
  const current = project.key === currentProjectKey;
@@ -425,7 +293,7 @@ function NaeilHeader(_a) {
425
293
  ...appNavigation != null ? appNavigation : [],
426
294
  ...(subNav != null ? subNav : []).map((item) => __spreadProps(__spreadValues({}, item), { id: item.href }))
427
295
  ],
428
- labels: labels2 != null ? labels2 : { navigation: content.nav.navigation, menu: content.nav.menu, close: content.nav.closeMenu },
296
+ labels: labels != null ? labels : { navigation: content.nav.navigation, menu: content.nav.menu, close: content.nav.closeMenu },
429
297
  toolbar,
430
298
  mobileToolbar: toolbar,
431
299
  className: cn("naeil-header fixed top-0 w-full", className),
@@ -434,10 +302,28 @@ function NaeilHeader(_a) {
434
302
  );
435
303
  }
436
304
 
305
+ // src/components/naeil-header-account.tsx
306
+ import { jsx as jsx3 } from "react/jsx-runtime";
307
+ function NaeilHeaderAccountControl2(props) {
308
+ return /* @__PURE__ */ jsx3(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx3(NaeilHeaderAccountControl, __spreadValues({}, props)) });
309
+ }
310
+
311
+ // src/components/naeil-header.tsx
312
+ import { jsx as jsx4 } from "react/jsx-runtime";
313
+ function NaeilHeader2(props) {
314
+ return /* @__PURE__ */ jsx4(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx4(NaeilHeader, __spreadValues({}, props)) });
315
+ }
316
+ function NaeilHeaderThemeControl2(props) {
317
+ return /* @__PURE__ */ jsx4(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx4(NaeilHeaderThemeControl, __spreadValues({}, props)) });
318
+ }
319
+ function NaeilHeaderLocaleControl2(props) {
320
+ return /* @__PURE__ */ jsx4(NaeilStandaloneMessages, { locale: props.locale, children: /* @__PURE__ */ jsx4(NaeilHeaderLocaleControl, __spreadValues({}, props)) });
321
+ }
322
+
437
323
  export {
438
324
  headerLocales,
439
- NaeilHeaderAccountControl,
440
- NaeilHeaderThemeControl,
441
- NaeilHeaderLocaleControl,
442
- NaeilHeader
325
+ NaeilHeaderAccountControl2 as NaeilHeaderAccountControl,
326
+ NaeilHeader2 as NaeilHeader,
327
+ NaeilHeaderThemeControl2 as NaeilHeaderThemeControl,
328
+ NaeilHeaderLocaleControl2 as NaeilHeaderLocaleControl
443
329
  };
@@ -1164,10 +1164,275 @@ function Logo(_a) {
1164
1164
  );
1165
1165
  }
1166
1166
 
1167
+ // src/naeil-locale/messages/en.json
1168
+ var en_default = {
1169
+ naeil: {
1170
+ header: {
1171
+ nav: {
1172
+ home: "Home",
1173
+ projects: "Projects",
1174
+ blog: "Blog",
1175
+ navigation: "Main navigation",
1176
+ menu: "Menu",
1177
+ closeMenu: "Close menu"
1178
+ },
1179
+ theme: {
1180
+ switchToLight: "Switch to light theme",
1181
+ switchToDark: "Switch to dark theme"
1182
+ },
1183
+ locale: {
1184
+ switchLabel: "Language"
1185
+ },
1186
+ projects: {
1187
+ cc: {
1188
+ name: "Content Collector",
1189
+ description: "Automated content collection from RSS, YouTube, Reddit + AI summarization"
1190
+ },
1191
+ pkm: {
1192
+ name: "PKM",
1193
+ description: "Personal knowledge management \u2014 document parsing, embeddings, semantic search"
1194
+ },
1195
+ naeilUi: {
1196
+ name: "naeil-ui",
1197
+ description: "Minimal design system \u2014 OKLCH tokens, Tailwind v4, shadcn"
1198
+ },
1199
+ sa: {
1200
+ name: "Sustainability Analyzer",
1201
+ description: "AI-powered ESG report analysis \u2014 PDF parsing, qualitative assessment, comparison tables"
1202
+ },
1203
+ babyAgent: {
1204
+ name: "Baby Agent",
1205
+ description: "Parenting AI agent \u2014 LINE-based Q&A, records, reminders"
1206
+ },
1207
+ status: {
1208
+ active: "Active",
1209
+ coming: "Coming Soon"
1210
+ }
1211
+ }
1212
+ },
1213
+ account: {
1214
+ menu: "Account menu",
1215
+ account: "Account",
1216
+ login: "Log in",
1217
+ logout: "Log out",
1218
+ busy: "Logging out\u2026"
1219
+ },
1220
+ footer: {
1221
+ navigation: "Navigation",
1222
+ projects: "Projects",
1223
+ blog: "Blog",
1224
+ social: "Social",
1225
+ description: "Tomorrow starts here."
1226
+ },
1227
+ locale: {
1228
+ names: {
1229
+ en: "English",
1230
+ ko: "\uD55C\uAD6D\uC5B4",
1231
+ ja: "\u65E5\u672C\u8A9E"
1232
+ },
1233
+ pending: "Changing language\u2026",
1234
+ failed: "The language could not be changed. Your work is still here.",
1235
+ retry: "Try again",
1236
+ errors: {
1237
+ badRequest: "This address is not valid.",
1238
+ notFound: "Page not found.",
1239
+ unauthenticated: "Sign in to continue.",
1240
+ forbidden: "You do not have access to this page.",
1241
+ unavailable: "The service is temporarily unavailable. Please try again."
1242
+ }
1243
+ }
1244
+ }
1245
+ };
1246
+
1247
+ // src/naeil-locale/messages/ko.json
1248
+ var ko_default = {
1249
+ naeil: {
1250
+ header: {
1251
+ nav: {
1252
+ home: "\uD648",
1253
+ projects: "\uD504\uB85C\uC81D\uD2B8",
1254
+ blog: "\uBE14\uB85C\uADF8",
1255
+ navigation: "\uC8FC\uC694 \uBA54\uB274",
1256
+ menu: "\uBA54\uB274",
1257
+ closeMenu: "\uBA54\uB274 \uB2EB\uAE30"
1258
+ },
1259
+ theme: {
1260
+ switchToLight: "\uBC1D\uC740 \uD14C\uB9C8\uB85C \uC804\uD658",
1261
+ switchToDark: "\uC5B4\uB450\uC6B4 \uD14C\uB9C8\uB85C \uC804\uD658"
1262
+ },
1263
+ locale: {
1264
+ switchLabel: "\uC5B8\uC5B4"
1265
+ },
1266
+ projects: {
1267
+ cc: {
1268
+ name: "Content Collector",
1269
+ description: "RSS, YouTube, Reddit \uC790\uB3D9 \uC218\uC9D1 + AI \uC694\uC57D"
1270
+ },
1271
+ pkm: {
1272
+ name: "PKM",
1273
+ description: "\uAC1C\uC778 \uC9C0\uC2DD \uAD00\uB9AC \u2014 \uBB38\uC11C \uD30C\uC2F1, \uC784\uBCA0\uB529, \uC2DC\uB9E8\uD2F1 \uAC80\uC0C9"
1274
+ },
1275
+ naeilUi: {
1276
+ name: "naeil-ui",
1277
+ description: "\uBBF8\uB2C8\uBA40 \uB514\uC790\uC778 \uC2DC\uC2A4\uD15C \u2014 OKLCH \uD1A0\uD070, Tailwind v4, shadcn"
1278
+ },
1279
+ sa: {
1280
+ name: "Sustainability Analyzer",
1281
+ description: "ESG \uB9AC\uD3EC\uD2B8 AI \uBD84\uC11D \u2014 PDF \uD30C\uC2F1, \uC815\uC131\uD3C9\uAC00, \uBE44\uAD50\uD45C \uC790\uB3D9 \uC0DD\uC131"
1282
+ },
1283
+ babyAgent: {
1284
+ name: "Baby Agent",
1285
+ description: "\uC721\uC544 AI \uC5D0\uC774\uC804\uD2B8 \u2014 LINE \uAE30\uBC18 Q&A, \uAE30\uB85D, \uB9AC\uB9C8\uC778\uB354"
1286
+ },
1287
+ status: {
1288
+ active: "\uD65C\uC131",
1289
+ coming: "\uC900\uBE44 \uC911"
1290
+ }
1291
+ }
1292
+ },
1293
+ account: {
1294
+ menu: "\uACC4\uC815 \uBA54\uB274",
1295
+ account: "\uACC4\uC815",
1296
+ login: "\uB85C\uADF8\uC778",
1297
+ logout: "\uB85C\uADF8\uC544\uC6C3",
1298
+ busy: "\uB85C\uADF8\uC544\uC6C3 \uC911\u2026"
1299
+ },
1300
+ footer: {
1301
+ navigation: "\uB124\uBE44\uAC8C\uC774\uC158",
1302
+ projects: "\uD504\uB85C\uC81D\uD2B8",
1303
+ blog: "\uBE14\uB85C\uADF8",
1304
+ social: "\uC18C\uC15C",
1305
+ description: "Tomorrow starts here."
1306
+ },
1307
+ locale: {
1308
+ names: {
1309
+ en: "English",
1310
+ ko: "\uD55C\uAD6D\uC5B4",
1311
+ ja: "\u65E5\u672C\u8A9E"
1312
+ },
1313
+ pending: "\uC5B8\uC5B4\uB97C \uBCC0\uACBD\uD558\uB294 \uC911\u2026",
1314
+ failed: "\uC5B8\uC5B4\uB97C \uBCC0\uACBD\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC791\uC5C5 \uB0B4\uC6A9\uC740 \uC720\uC9C0\uB429\uB2C8\uB2E4.",
1315
+ retry: "\uB2E4\uC2DC \uC2DC\uB3C4",
1316
+ errors: {
1317
+ badRequest: "\uC62C\uBC14\uB974\uC9C0 \uC54A\uC740 \uC8FC\uC18C\uC785\uB2C8\uB2E4.",
1318
+ notFound: "\uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
1319
+ unauthenticated: "\uACC4\uC18D\uD558\uB824\uBA74 \uB85C\uADF8\uC778\uD558\uC138\uC694.",
1320
+ forbidden: "\uC774 \uD398\uC774\uC9C0\uC5D0 \uC811\uADFC\uD560 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
1321
+ unavailable: "\uC77C\uC2DC\uC801\uC73C\uB85C \uC11C\uBE44\uC2A4\uB97C \uC774\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694."
1322
+ }
1323
+ }
1324
+ }
1325
+ };
1326
+
1327
+ // src/naeil-locale/messages/ja.json
1328
+ var ja_default = {
1329
+ naeil: {
1330
+ header: {
1331
+ nav: {
1332
+ home: "\u30DB\u30FC\u30E0",
1333
+ projects: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8",
1334
+ blog: "\u30D6\u30ED\u30B0",
1335
+ navigation: "\u30E1\u30A4\u30F3\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3",
1336
+ menu: "\u30E1\u30CB\u30E5\u30FC",
1337
+ closeMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B"
1338
+ },
1339
+ theme: {
1340
+ switchToLight: "\u30E9\u30A4\u30C8\u30C6\u30FC\u30DE\u306B\u5207\u308A\u66FF\u3048\u308B",
1341
+ switchToDark: "\u30C0\u30FC\u30AF\u30C6\u30FC\u30DE\u306B\u5207\u308A\u66FF\u3048\u308B"
1342
+ },
1343
+ locale: {
1344
+ switchLabel: "\u8A00\u8A9E"
1345
+ },
1346
+ projects: {
1347
+ cc: {
1348
+ name: "Content Collector",
1349
+ description: "RSS\u3001YouTube\u3001Reddit\u306E\u81EA\u52D5\u53CE\u96C6 + AI\u8981\u7D04"
1350
+ },
1351
+ pkm: {
1352
+ name: "PKM",
1353
+ description: "\u500B\u4EBA\u30CA\u30EC\u30C3\u30B8\u7BA1\u7406 \u2014 \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u89E3\u6790\u3001\u57CB\u3081\u8FBC\u307F\u3001\u30BB\u30DE\u30F3\u30C6\u30A3\u30C3\u30AF\u691C\u7D22"
1354
+ },
1355
+ naeilUi: {
1356
+ name: "naeil-ui",
1357
+ description: "\u30DF\u30CB\u30DE\u30EB\u30C7\u30B6\u30A4\u30F3\u30B7\u30B9\u30C6\u30E0 \u2014 OKLCH\u30C8\u30FC\u30AF\u30F3\u3001Tailwind v4\u3001shadcn"
1358
+ },
1359
+ sa: {
1360
+ name: "Sustainability Analyzer",
1361
+ description: "ESG\u30EC\u30DD\u30FC\u30C8AI\u5206\u6790 \u2014 PDF\u89E3\u6790\u3001\u5B9A\u6027\u8A55\u4FA1\u3001\u6BD4\u8F03\u8868\u306E\u81EA\u52D5\u751F\u6210"
1362
+ },
1363
+ babyAgent: {
1364
+ name: "Baby Agent",
1365
+ description: "\u80B2\u5150AI\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8 \u2014 LINE Q&A\u3001\u8A18\u9332\u3001\u30EA\u30DE\u30A4\u30F3\u30C0\u30FC"
1366
+ },
1367
+ status: {
1368
+ active: "\u30A2\u30AF\u30C6\u30A3\u30D6",
1369
+ coming: "\u6E96\u5099\u4E2D"
1370
+ }
1371
+ }
1372
+ },
1373
+ account: {
1374
+ menu: "\u30A2\u30AB\u30A6\u30F3\u30C8\u30E1\u30CB\u30E5\u30FC",
1375
+ account: "\u30A2\u30AB\u30A6\u30F3\u30C8",
1376
+ login: "\u30ED\u30B0\u30A4\u30F3",
1377
+ logout: "\u30ED\u30B0\u30A2\u30A6\u30C8",
1378
+ busy: "\u30ED\u30B0\u30A2\u30A6\u30C8\u4E2D\u2026"
1379
+ },
1380
+ footer: {
1381
+ navigation: "\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3",
1382
+ projects: "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8",
1383
+ blog: "\u30D6\u30ED\u30B0",
1384
+ social: "\u30BD\u30FC\u30B7\u30E3\u30EB",
1385
+ description: "Tomorrow starts here."
1386
+ },
1387
+ locale: {
1388
+ names: {
1389
+ en: "English",
1390
+ ko: "\uD55C\uAD6D\uC5B4",
1391
+ ja: "\u65E5\u672C\u8A9E"
1392
+ },
1393
+ pending: "\u8A00\u8A9E\u3092\u5909\u66F4\u3057\u3066\u3044\u307E\u3059\u2026",
1394
+ failed: "\u8A00\u8A9E\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u4F5C\u696D\u5185\u5BB9\u306F\u4FDD\u6301\u3055\u308C\u3066\u3044\u307E\u3059\u3002",
1395
+ retry: "\u518D\u8A66\u884C",
1396
+ errors: {
1397
+ badRequest: "\u3053\u306E\u30A2\u30C9\u30EC\u30B9\u306F\u7121\u52B9\u3067\u3059\u3002",
1398
+ notFound: "\u30DA\u30FC\u30B8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002",
1399
+ unauthenticated: "\u7D9A\u3051\u308B\u306B\u306F\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
1400
+ forbidden: "\u3053\u306E\u30DA\u30FC\u30B8\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u6A29\u9650\u304C\u3042\u308A\u307E\u305B\u3093\u3002",
1401
+ unavailable: "\u30B5\u30FC\u30D3\u30B9\u3092\u4E00\u6642\u7684\u306B\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u3082\u3046\u4E00\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044\u3002"
1402
+ }
1403
+ }
1404
+ }
1405
+ };
1406
+
1407
+ // src/components/naeil-messages-context.tsx
1408
+ import { createContext, useContext } from "react";
1409
+ import { jsx as jsx3 } from "react/jsx-runtime";
1410
+ var NaeilMessages = createContext(null);
1411
+ function NaeilMessagesProvider({ locale, messages: messages2, children }) {
1412
+ return /* @__PURE__ */ jsx3(NaeilMessages.Provider, { value: { locale, messages: messages2 }, children });
1413
+ }
1414
+ function useNaeilMessages(locale) {
1415
+ const value = useContext(NaeilMessages);
1416
+ if (!value || value.locale !== locale) throw new Error("Naeil chrome requires messages for its current locale");
1417
+ return value.messages;
1418
+ }
1419
+
1420
+ // src/components/naeil-standalone-messages.tsx
1421
+ import { jsx as jsx4 } from "react/jsx-runtime";
1422
+ var messages = { en: en_default.naeil, ko: ko_default.naeil, ja: ja_default.naeil };
1423
+ function NaeilStandaloneMessages({ locale, children }) {
1424
+ return /* @__PURE__ */ jsx4(NaeilMessagesProvider, { locale, messages: messages[locale], children });
1425
+ }
1426
+
1167
1427
  // src/lib/ui-release.ts
1168
- var uiRelease = { version: "0.9.0", contractVersion: "1" };
1428
+ var uiRelease = { version: "0.11.0", contractVersion: "1" };
1169
1429
 
1170
1430
  export {
1171
1431
  Logo,
1172
- uiRelease
1432
+ uiRelease,
1433
+ useNaeilMessages,
1434
+ en_default,
1435
+ ko_default,
1436
+ ja_default,
1437
+ NaeilStandaloneMessages
1173
1438
  };
@@ -2,10 +2,13 @@
2
2
  import {
3
3
  NaeilHeader,
4
4
  headerLocales
5
- } from "../chunk-XRO3NJAB.js";
5
+ } from "../chunk-KWEWR46R.js";
6
6
  import {
7
- Logo
8
- } from "../chunk-JDHGKM25.js";
7
+ Logo,
8
+ en_default,
9
+ ja_default,
10
+ ko_default
11
+ } from "../chunk-U3IZCFM4.js";
9
12
  import {
10
13
  SiteFooter
11
14
  } from "../chunk-HSTDPY56.js";
@@ -25,6 +28,12 @@ import {
25
28
 
26
29
  // src/components/nav.tsx
27
30
  import { useLocale, useTranslations } from "next-intl";
31
+
32
+ // src/components/naeil-header-content.ts
33
+ var headerLocaleNames = en_default.naeil.locale.names;
34
+ var headerContent = { en: en_default.naeil.header, ko: ko_default.naeil.header, ja: ja_default.naeil.header };
35
+
36
+ // src/components/nav.tsx
28
37
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
29
38
  var NativeBrandLink = (props) => /* @__PURE__ */ jsx("a", __spreadValues({}, props));
30
39
  function Nav({