diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c3a0518..27f328c 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -28,7 +28,7 @@ jobs:
New-Item -ItemType Directory -Path 'package\dist' -Force | Out-Null
Copy-Item -LiteralPath 'dist\WeeklyUsageIndicator.exe','dist\SHA256SUMS.txt' -Destination 'package\dist'
Copy-Item -LiteralPath 'scripts\install.ps1','scripts\uninstall.ps1','scripts\install-environment.ps1' -Destination 'package\scripts'
- Copy-Item -LiteralPath 'README.md','PRIVACY.md','SECURITY.md','LICENSE' -Destination 'package'
+ Copy-Item -LiteralPath 'README.md','PRIVACY.md','SECURITY.md','LICENSE','THIRD_PARTY_NOTICES.txt' -Destination 'package'
Compress-Archive -Path 'package\*' -DestinationPath "CodexWeeklyUsageIndicator-$env:GITHUB_REF_NAME-win-x64.zip"
- name: Create draft release for artifact verification
shell: pwsh
diff --git a/PRIVACY.md b/PRIVACY.md
index e0e34de..220bbf9 100644
--- a/PRIVACY.md
+++ b/PRIVACY.md
@@ -5,7 +5,7 @@ Codex + Claude Usage Indicator reads Codex rate-limit windows from the locally i
The application:
- does not store a timeline of usage history; optional Codex account management retains each account's latest usage snapshot;
-- stores the last window coordinates and the Claude visibility preference in a local `settings.json` file;
+- stores the last window coordinates, Claude visibility preference and UI language in a local `settings.json` file;
- stores one latest successful Claude snapshot in local `claude-usage-cache.json`, containing only usage percentages, reset times, and the update time;
- does not read, print, log, copy, or persist Claude authentication tokens;
- reads Codex account identifiers only after optional account registration, and stores them with labels and login snapshots in a Windows CurrentUser DPAPI encrypted vault;
diff --git a/README.md b/README.md
index 6306bf6..df840f2 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,28 @@
# Codex + Claude Usage Indicator
-An unofficial Windows widget that stays on top while Codex Desktop is running and shows Codex weekly usage alongside Claude Fable usage.
+Keep your remaining Codex and Claude usage in sight, then check and switch your saved Codex accounts from one place.
+
+**Windows · 한국어 / English · Manual account switching**
+
+
+
+The blue bar is Codex; the orange bar is Claude Fable. The numbers show how much weekly usage remains. The widget stays visible while Codex is open, so you can check without leaving your work.
+
+
+
+- **See what is left across your accounts.** The manager adds their remaining weekly percentages and shows which account resets next.
+- **Check another account without switching.** Refresh one account or all accounts when you need an update.
+- **Switch when you choose.** Pick an account, finish your Codex work and confirm the switch. The tool saves your logins for the next time.
+
+Screenshots use synthetic accounts and usage. This is an unofficial community project.
+
+[Download the Windows release](https://github.com/extsvforest/codex-weekly-usage-indicator/releases/latest) · [Installation](#install-from-a-release) · [Language](#language)
## What it does
+
+Widget behavior and refresh details
+
- Appears while Codex Desktop is running and hides when Codex exits.
- Keeps the existing 272 × 64 window and uses one or two fluid panels depending on which providers are available.
- Shows only white remaining percentages: Codex is identified by a blue bar and Claude Fable by a terracotta-orange bar.
@@ -16,18 +35,37 @@ An unofficial Windows widget that stays on top while Codex Desktop is running an
- Refreshes every 60 seconds; double-click to refresh Codex immediately while Claude continues to honor its ten-minute cache.
- Supports dragging, copying the current values, toggling always-on-top, and turning the Claude panel on or off from the right-click menu.
- Remembers the last dragged position and restores it on the next launch.
+- Switches the interface between Korean and English from **Language / 언어** in the widget or tray menu.
- Hides while another foreground app is fullscreen, then returns at the saved position.
- Uses a per-user Windows scheduled task at sign-in, so the widget runs independently of Codex. A lightweight supervisor restarts the widget after an abnormal exit, waiting one minute (up to 999 retries per supervisor run).
-Account management is optional. After you register a Codex account, the widget stores account labels, identities, each account's latest usage snapshot, and Codex login snapshots encrypted with Windows CurrentUser DPAPI. The live authentication file remains authoritative for the active account. Claude credentials are never accessed; Claude Code owns its authentication and token refresh. See [PRIVACY.md](PRIVACY.md).
+
+
+You can use the widget on its own. Saving accounts is optional; it adds the account manager shown above. Saved Codex logins are encrypted for your Windows user. Claude Code handles its own login. See [PRIVACY.md](PRIVACY.md) for storage details.
## Manual Codex accounts
-Open **Codex 계정 관리…** from the widget menu, or double-click the tray icon. The light-themed manager uses one overview and one account list, sorted by the nearest weekly reset. Its default height fits three accounts without scrolling on a sufficiently tall display. Account names appear in the manager and hover details; the compact indicator remains percentages and bars. Hover details separate the current account, the last combined observation with each account reset, and Claude. Hover never requests usage; the combined observation remains available after closing the manager and lasts for the widget process.
+Right-click the widget and open **Codex accounts… / Codex 계정 관리…**, or double-click its tray icon.
+
+1. **Save the account you already use.** Choose **Save current account**. Open its **···** menu to give it a name you recognize.
+2. **Add another account.** Choose **+ Add account** and complete the official sign-in in your browser. Your current Codex session stays signed in.
+3. **Check the balances.** Opening the manager checks your saved accounts once. Press **Refresh all** for another complete check, or use a row's **···** menu to check just that account.
+4. **Switch when you are ready.** Press **Switch** on the account you want. Save your work and close Codex Desktop and any Codex terminal or IDE sessions. The confirmation button becomes available when they have stopped; it applies the saved login and tries to reopen Codex. Check that Codex shows the intended account.
+
+The list puts the soonest reset first. Three accounts fit in the default window on a sufficiently tall display; a smaller window can scroll. Names appear here and in hover details, while the small widget stays focused on percentages.
Hover details open outside the widget after a short delay and stay in place while you read. New observations appear on the next hover; moving away, dragging, or opening the context menu closes the details. The hover window never takes keyboard focus.
-The overview adds the remaining weekly percentages: for example, **168% of 300%** across three accounts. Each account contributes up to 100%; this is an unweighted sum of account percentages, not a shared service limit or a comparison of different plans' absolute quotas. **다음 초기화** identifies the next confirmed reset and that account's remaining amount. The latest reset appears as secondary context; it is not a common deadline for the whole total.
+
+
+In the example above, the accounts have **63%, 81% and 24%** left. Adding them gives **168% out of 300%**. Each full account contributes 100%, so this helps you compare the saved balances. Accounts on different plans can have different actual quotas; the sum does not measure an equal number of messages or tokens.
+
+**Next reset** tells you which account resets first. **Latest reset** shows the last reset among the accounts. Each balance still follows its own reset time, so the latest date is not a deadline for spending the whole 168%.
+
+Other accounts are checked when you open the manager or request a refresh. Moving the mouse, changing the language or returning to the window does not request another check. If a check fails or a reset has passed, the manager marks what needs attention instead of presenting an old balance as a current total.
+
+
+Refresh rules, saved logins and recovery
Opening a new manager window starts one sequential usage query for all registered accounts. After that, **전체 갱신** is the only way to refresh the whole observation set. Restoring focus, changing selection, the local five-second UI timer, and the active widget's own polling do not trigger another batch or change this snapshot. Closing the window during a batch cancels the request and waits for safe cleanup. Failure, cancellation, missing/expired weekly data, or changed membership withholds the total and distinguishes the confirmed subtotal from previous values. Cleanup or credential recovery stops the remaining batch.
@@ -45,9 +83,17 @@ If credentials are already saved and only temporary files remain, the manager in
The first version supports local Windows file-based ChatGPT authentication. Unsupported keyring/managed configurations fail closed. The vault is stored separately at `%LOCALAPPDATA%\CodexWeeklyUsageIndicator.Accounts`; uninstall preserves it. Delete inactive accounts from the manager before removing the app if you no longer want their saved credentials. This convenience tool does not establish that any particular multi-account usage pattern is permitted by the service terms.
+
+
> [!IMPORTANT]
> This is an unofficial community project. It relies on an experimental local Codex app-server method (`account/rateLimits/read`) and the text output of Claude Code's built-in `/usage` command. Either may change without notice.
+## Language
+
+Right-click the widget or tray icon, then choose **Language / 언어 → 한국어 / English**. Menus, account management, dialogs, usage details and known application errors change immediately. An open idle account manager keeps its size and last usage observation when the language changes; changing language does not request usage or sign you in again. Finish or cancel an account operation or close its dialog before changing language.
+
+The choice is saved locally. Existing installations with a settings file keep Korean; a new installation starts in Korean on Korean Windows and English otherwise. Account names, identities, credentials and usage values are not translated. Windows-provided confirmation buttons follow the Windows display language. Diagnostic text supplied by the operating system or an external tool may remain in its original language.
+
## Requirements
- Windows 10 or 11
@@ -58,7 +104,7 @@ The first version supports local Windows file-based ChatGPT authentication. Unsu
## Install from a release
-1. Download and extract the Windows zip from [Releases](https://github.com/GiantForestStudio/codex-weekly-usage-indicator/releases).
+1. Download and extract the Windows zip from [Releases](https://github.com/extsvforest/codex-weekly-usage-indicator/releases).
2. Review the included PowerShell scripts.
3. Open a standalone Windows PowerShell window (outside packaged apps such as Codex), change to the extracted directory, and run:
@@ -67,7 +113,7 @@ The first version supports local Windows file-based ChatGPT authentication. Unsu
```
The app is installed to `%LOCALAPPDATA%\CodexWeeklyUsageIndicator`. A per-user `CodexWeeklyUsageIndicator-` scheduled task starts its supervisor at sign-in, using the signed-in user's normal privileges without storing a password. The supervisor launches and watches the widget; two processes from the same EXE are expected, but only one window. Installation also starts the task immediately, checks that both processes appear, and then removes the old Startup shortcut. Windows Task Scheduler must be available; an installation error must be resolved before relying on automatic recovery.
-The saved window position and Claude visibility preference are kept locally in `settings.json` inside that install directory. One sanitized Claude recovery snapshot may be kept in `claude-usage-cache.json` and is ignored after 24 hours or after its Fable reset.
+The saved window position, Claude visibility preference and UI language are kept locally in `settings.json` inside that install directory. One sanitized Claude recovery snapshot may be kept in `claude-usage-cache.json` and is ignored after 24 hours or after its Fable reset.
Run installation and removal outside packaged app terminals: Windows can redirect their AppData writes into an app-private folder that Task Scheduler cannot see, causing `0x80070002` even when that terminal reports the EXE exists. Both scripts check the real directory path and refuse redirected locations before changing tasks or running widgets.
@@ -115,4 +161,4 @@ The app-server child process is stopped whenever Codex is no longer running.
## License
-[MIT](LICENSE)
+[MIT](LICENSE). Bundled Pretendard fonts use the SIL Open Font License; see [THIRD_PARTY_NOTICES.txt](THIRD_PARTY_NOTICES.txt).
diff --git a/THIRD_PARTY_NOTICES.txt b/THIRD_PARTY_NOTICES.txt
new file mode 100644
index 0000000..c3c6f62
--- /dev/null
+++ b/THIRD_PARTY_NOTICES.txt
@@ -0,0 +1,97 @@
+Pretendard 1.3.9 - Regular, SemiBold, Bold (unmodified static TrueType files).
+Source: https://github.com/orioncactus/pretendard/tree/v1.3.9/packages/pretendard/dist/public/static/alternative
+
+Copyright (c) 2021, Kil Hyung-jin (https://github.com/orioncactus/pretendard),
+with Reserved Font Name Pretendard.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/docs/account-opening-stability.md b/docs/account-opening-stability.md
new file mode 100644
index 0000000..3d69430
--- /dev/null
+++ b/docs/account-opening-stability.md
@@ -0,0 +1,61 @@
+# Account manager opening stability
+
+The 1.8.0-preview.2 candidate fixes the visible layout churn reported after the
+Soft Paper restyle. It keeps the existing manager structure, fonts, palette,
+account actions and manual query boundaries.
+
+## Reproduction and cause
+
+The production form was tested at 175% Windows scaling with three synthetic
+accounts, both with saved observations and without them. Geometry was observed
+from the first native `Paint`, not just a settled `DrawToBitmap` capture.
+
+Before the fix, the first paint contained no account rows. `Shown` then populated
+rows at a temporary width of 262 pixels before expanding them to 1,526 pixels,
+and opened the query notice below the overview. With no cached reset times,
+individual responses also changed the row order while the batch was running.
+
+The new transparent paper surfaces exposed these intermediate states. A native
+paint stack confirmed that disabling the whole account table recursively called
+`Control.OnEnabledChanged`, which forces `UpdateWindow`. Suspending layout alone
+did not stop that synchronous paint; moving preparation to `Load` alone was also
+insufficient. The relevant framework behavior is in the official
+[WinForms Control source](https://github.com/dotnet/winforms/blob/v8.0.0/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs).
+
+## Fix
+
+- Prepare the initial account list, DPI-adjusted size and query state in `Load`
+ before presenting the window. The query continues asynchronously; display and
+ cancellation do not wait for a network response.
+- Batch layout changes through the nested tables. Compose the manager's child
+ windows together so transparent controls do not expose separate paper layers.
+- Disable the account action buttons individually instead of disabling all
+ labels and containers. Custom buttons keep native enabled/accessibility
+ semantics but enqueue repainting instead of forcing an immediate update.
+- Preserve row positions throughout a batch. When it finishes, apply the final
+ nearest-reset order once. Value changes do not rebuild an unchanged row grid.
+
+The existing query notice still closes on success, so the list moves up once
+when that notice disappears. Errors, cancellation and recovery retain their
+existing visible messages. No authentication or account query implementation
+was changed, and the widget/tooltip retain their separate nonactivation behavior.
+
+## Verification
+
+`AccountOpeningSmoke` exercises actual production forms with held synthetic
+responses. It checks all three rows and final widths from the first native paint,
+stable geometry in painted loading frames and between individual responses,
+final reset ordering, scrolling, quiet local refresh, hide/show and unchanged
+active credentials. Run it with `--account-opening-smoke`; `--trace-only` is a
+diagnostic mode that records failures without substituting for the required test.
+
+The in-flight query test verifies every row's switch/menu button and the
+add/rename/delete actions are disabled, and tries the disabled row buttons. It
+does not equate a disabled container with protected account actions.
+
+Preserved synthetic captures: [loading](images/soft-paper/opening-loading.png),
+[completed](images/soft-paper/opening-complete.png). These document appearance;
+the native paint/geometry regression is the evidence for opening stability.
+
+Full build and local installation verification are recorded in
+[the Soft Paper UI record](soft-paper-ui.md).
diff --git a/docs/design/2026-09-22/README.md b/docs/design/2026-09-22/README.md
new file mode 100644
index 0000000..73085cc
--- /dev/null
+++ b/docs/design/2026-09-22/README.md
@@ -0,0 +1,155 @@
+# Account manager design exploration · 2026-09-22
+
+The user asked to improve the current interface together, following the latest
+design-partner guidance, and selected **A — ordered list** on 2026-09-22.
+Its bright canvas, unboxed three-part summary and aligned account rows are now
+implemented in native WinForms for 1.8.0. The approved raster is the
+visual reference; the earlier HTML sketches are not the implementation source.
+
+## Compared directions
+
+- [A — ordered list](direction-a.png): one light canvas, a clear total and reset
+ summary, aligned account/value/reset/action columns, restrained row boundaries.
+ Recommended for quick comparisons, longer names and more accounts. Its visual
+ character is quieter, and the large reset date could be reduced further in the
+ native pass if it competes with the balance.
+- [B — three cards](direction-b.png): each account becomes a distinct paper card.
+ The three-account composition is stronger and more tactile. It uses more space,
+ and additional accounts or long aliases need a layout rule before implementation.
+
+Both use synthetic values: 63 + 81 + 24 = 168 percent remaining out of 300 percent,
+with distinct future reset times. The latest reset is explicitly a reset time,
+not an expiry deadline for all remaining capacity. No real identities or usage
+were accessed for these concepts.
+
+## Critique and comparison basis
+
+The current [installed-design capture](../../images/soft-paper/opening-complete.png)
+has a large bordered summary, repeated row borders and status phrases, and a
+decorative three-shape motif detached from the task. The alternatives emphasize
+typographic hierarchy and alignment instead of adding more decoration.
+
+The Library's Soft Paper specimen supplied the warm ivory/plum palette and the
+relationship of firm type to gentle paper surfaces. The Library's preserved
+Microsoft WinUI settings illustration and Carbon table captures were inspected
+for shared baselines, quiet default states, restrained borders and action emphasis.
+Their upstream references are
+[Microsoft settings layout](https://learn.microsoft.com/en-us/windows/apps/design/app-settings/guidelines-for-app-settings#layout)
+and [Carbon data table](https://carbondesignsystem.com/components/data-table/usage/).
+This round used the preserved reference images, not a fresh live product audit.
+
+The v1 and refined images are retained. Refinement removed invented account-role
+subtitles, reduced a competing headline, removed an unquantified pie icon, and
+restored the active account management menu. These are generated raster concepts:
+minor icon/text details are not new feature commitments. In particular B's small
+sort chevron does not establish a selectable sorting feature.
+
+## Artifacts and limits
+
+- `direction-a.png`, `direction-b.png`: current comparison proposals, generated
+ with built-in imagegen. [Prompt set and focused edits](prompts.md).
+- `direction-a-v1.png`, `direction-b-v1.png`: first versions, kept so intermediate
+ visuals remain recoverable rather than disappearing with temporary work.
+- `index.html`, `styles.css`, `app.js`: independent exploratory HTML with synthetic
+ normal/loading/partial states, name editor and simulated actions. It predates
+ the generated refinements and is **not a pixel-equivalent implementation** of
+ either final image. JavaScript syntax was checked; browser rendering and
+ interactions were not verified. A local server launch was blocked by automatic
+ approval review; local file navigation was blocked by browser URL policy.
+ No alternate browser or security workaround was attempted.
+
+## Native implementation
+
+- The overview separates total remaining capacity, nearest reset and latest
+ confirmed reset. A failed or incomplete batch still shows an unknown total
+ and a clearly labelled confirmed subtotal. Reset times remain per-account.
+- Shared account/value/reset/action columns replace individual bordered cards.
+ Muted identity tiles and meter colors stay attached to accounts during sorting;
+ the active account has one quiet background and a readable status badge.
+- Names occupy one line with ellipsis; hover exposes the full alias. Compact
+ query states expose their complete reason and last observation through hover
+ and accessibility descriptions. Rename, individual refresh, details, delete
+ and switching remain available through the existing controls and menus.
+- Native text and vector painting reproduce the direction without rasterized
+ text, new dependencies or any change to authentication/query rules. The
+ original first-paint batching, in-place partial responses and native disabled
+ action semantics remain in place.
+- Default size remains 920 × 740 logical pixels so all three accounts also fit
+ while the progress or partial-result message is present. Deliberately reducing
+ the window height permits scrolling rather than shrinking controls.
+
+The user approved the A direction, then confirmed satisfaction with its installed
+preview.3 execution and requested a public release. The release also includes
+Korean/English switching at the user's explicit request.
+
+## Actual output and checks
+
+Native production forms with synthetic accounts:
+[175% manager](native/manager-175.png), [100% manager](native/manager-100.png),
+[long alias](native/long-name.png), [name editor](native/rename.png),
+[loading](native/progress.png), [partial failure](native/partial.png),
+[minimum window](native/minimum.png). The 100% fixture uses a DPI-unaware process
+to exercise the native 96-DPI layout without changing Windows display settings.
+The 175% captures use the actual per-monitor DPI mode. These are WinForms
+DrawToBitmap captures; nonclient title-bar rendering may differ from DWM.
+
+The full 30-group regression suite passed during this implementation, including
+four-corner tooltip stability, focus, authentication isolation, account operations
+and first-paint geometry. The final row sizing refinements were then checked with
+the combined-manager, opening and style fixtures at 96 and 168 DPI. Parent-bound
+assertions now catch clipped child layouts as well as clipped text and buttons.
+The small-window fixture resizes the outer window to its scaled native minimum;
+an impossible ClientSize request had left WinForms reporting rejected bounds.
+
+Two final full-suite attempts stopped at the initial pointer-driven hover check:
+the trace recorded actual pointer departure (`cursorHeld=False`, enter/leave),
+not an observed stationary-hover regression. The earlier four-corner checks
+passed twice. No hover assertions were weakened, and no further cursor retries
+were made. Final packaging used the same publish options after the focused UI
+checks; the complete suite was not reported as a fresh pass on that final run.
+
+Final opening inspection recorded 72 events with zero violated expectations.
+The normal-user installer upgraded preview.2 to **1.8.0-preview.3** on 2026-09-22.
+The installed executable matched the packaged SHA-256
+`476cdfea0b10216ad92b31578f91866893e14586adc2b50263b472bbf336fe45`
+(8,455,350 bytes). One supervisor and one widget remained running; the one-time
+helper completed with exit code 0. The executable passed the private-path scan
+and contains no PDB. This is a local preview installation, not a public release.
+
+## Korean and English release candidate
+
+The native interface, menus, dialogs, tooltip and known application errors use
+explicit translation templates. Existing account aliases and stored authentication
+remain unchanged. **Language / 언어** is in the widget and tray context menu.
+An idle open manager is recreated from the same dependencies and observation set
+without querying. Physical bounds are restored during Load after DPI scaling.
+Busy operations, owned dialogs and a disabled modal owner block language changes.
+
+English output with synthetic accounts is preserved at [175%](native/en-manager-175.png)
+and [100%](native/en-manager-100.png), with the [name editor](native/en-rename.png),
+[switch preparation](native/en-switch.png) and [tooltip renderer](native/en-tooltip.png).
+Korean account names in these images demonstrate that aliases are not translated.
+
+`LanguageUiSmoke` passed at actual 175% scaling: KO→EN→KO retained physical bounds,
+the completed batch, aliases and active auth bytes, with zero usage calls. It also
+tested in-flight and modal blockers. `LocalizationTests` passed resource loading,
+format parity and rendering, known-message round trips, direct literal coverage,
+tooltip labels and isolated settings migration/preservation. Language resources
+explicitly disable culture-based satellite splitting so the single-file binary
+contains both catalogs. Existing settings retain Korean; new settings use the
+Windows language, including the first position/visibility save.
+
+A fresh local full build stopped at its first real-pointer hover fixture because
+the pointer left the widget (`cursorHeld=False`). The full suite was not claimed
+as passed and was not retried locally. The required full-suite result and final
+artifact verification are recorded in the v1.8.0 PR, Windows CI and release.
+
+Claude implementation advice identified the open-window DPI restoration risk and
+catalog validation gap; both received specific fixes and native/runtime checks.
+The separate frozen-candidate reviewer recommended ready with no remaining code
+blockers. Its clean-CI test-root finding was fixed and the localization test passed
+with that environment variable absent. Passing full Windows CI and downloaded
+artifact checks remain required before publishing. The font's OFL notice is
+included in release packaging. The README now starts with native widget and
+manager images, a simple usage path, a concrete 63 + 81 + 24 example and hover
+details; implementation and recovery details remain available in expandable sections.
diff --git a/docs/design/2026-09-22/app.js b/docs/design/2026-09-22/app.js
new file mode 100644
index 0000000..1f01ff6
--- /dev/null
+++ b/docs/design/2026-09-22/app.js
@@ -0,0 +1,52 @@
+const app = document.querySelector('#app');
+const accounts = [
+ {name:'메인 계정',remaining:63,date:'09.24 20:40',relative:'2일 6시간 뒤',wash:'#efe1d2',tone:'#9c765e'},
+ {name:'서브 계정',remaining:81,date:'09.26 20:40',relative:'4일 6시간 뒤',wash:'#e3e8eb',tone:'#7b8a9d'},
+ {name:'서브 계정2',remaining:24,date:'09.28 20:40',relative:'6일 6시간 뒤',wash:'#eee6cd',tone:'#ad965d'}
+];
+let current=0, selected=0, mode='ready', direction='a', confirmAction=null, refreshTimer=null;
+const escapeHtml = value => value.replace(/[&<>"']/g,char=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[char]));
+function render(){
+ document.querySelector('#accounts').innerHTML = accounts.map((a,i)=>`
+
0${i+1}
${escapeHtml(a.name)}
${mode==='partial'&&i===1?'확인 실패 · 이전 값':i===current?'사용 중':'14:30 확인'}