diff --git a/docker/frontend/src/i18n/en.ts b/docker/frontend/src/i18n/en.ts
index c527bcc..5ae449a 100644
--- a/docker/frontend/src/i18n/en.ts
+++ b/docker/frontend/src/i18n/en.ts
@@ -6,15 +6,15 @@ export const en: Dict = {
'nav.demo': 'TRY DEMO',
'nav.login': 'LOG IN',
'nav.signup': 'SIGN UP',
- 'nav.logout': 'Log out',
- 'nav.account': 'Account',
- 'nav.theme': 'Theme',
- 'nav.language': 'Language',
+ 'nav.logout': 'LOG OUT',
+ 'nav.account': 'ACCOUNT',
+ 'nav.theme': 'THEME',
+ 'nav.language': 'LANGUAGE',
// The phone's way back from a tab's strip to the rail that opened it.
'nav.tabs': 'TABS',
'nav.back': 'Back to home',
'nav.menu': 'MENU',
- 'nav.guest': 'Guest',
+ 'nav.guest': 'GUEST',
// The install offer (see vi.ts).
'install.title': 'Install RecipesCam',
@@ -27,7 +27,7 @@ export const en: Dict = {
'act.redo': 'REDO',
'act.reset': 'RESET',
'act.export': 'EXPORT',
- 'act.exporting': 'Exporting…',
+ 'act.exporting': 'EXPORTING…',
'act.upscaling': 'Upscaling the photo {done}/{total}…',
'act.cancel': 'Cancel',
@@ -410,7 +410,7 @@ export const en: Dict = {
'lib.immich.linkForget': 'REMOVE THE LINK',
'immich.upload': 'Upload to Immich',
'immich.uploadTitle': 'Upload edited photo to Immich Cloud',
- 'immich.uploading': 'Uploading…',
+ 'immich.uploading': 'UPLOADING…',
'immich.uploadSuccess': 'Successfully uploaded photo to Immich Cloud!',
'immich.uploadFailed': 'Failed to upload to Immich Cloud: {msg}',
'immich.uploadToCloud': 'Upload to Immich Cloud',
@@ -440,9 +440,9 @@ export const en: Dict = {
'lib.mobile.disconnect': 'DISCONNECT',
'lib.mobile.searchPlaceholder': 'Search on Immich (filename, tag)...',
- 'nav.admin': 'Admin',
- 'nav.photos': 'My photos',
- 'nav.profile': 'Profile',
+ 'nav.admin': 'ADMIN',
+ 'nav.photos': 'MY PHOTOS',
+ 'nav.profile': 'PROFILE',
'nav.library': 'LIBRARY',
'nav.studio': 'Studio',
'adm.title': 'Strip moderation',
diff --git a/docker/frontend/src/i18n/vi.ts b/docker/frontend/src/i18n/vi.ts
index 798302c..024eb65 100644
--- a/docker/frontend/src/i18n/vi.ts
+++ b/docker/frontend/src/i18n/vi.ts
@@ -9,21 +9,21 @@ export const vi = {
'nav.demo': 'DÙNG THỬ',
'nav.login': 'ĐĂNG NHẬP',
'nav.signup': 'ĐĂNG KÝ',
- 'nav.logout': 'Đăng xuất',
- 'nav.account': 'Tài khoản',
- 'nav.theme': 'Giao diện',
- 'nav.language': 'Ngôn ngữ',
+ 'nav.logout': 'ĐĂNG XUẤT',
+ 'nav.account': 'TÀI KHOẢN',
+ 'nav.theme': 'GIAO DIỆN',
+ 'nav.language': 'NGÔN NGỮ',
'nav.tabs': 'TAB',
'nav.back': 'Về trang chủ',
- 'nav.admin': 'Quản trị',
- 'nav.photos': 'Ảnh của tôi',
- 'nav.profile': 'Hồ sơ',
+ 'nav.admin': 'QUẢN TRỊ',
+ 'nav.photos': 'ẢNH CỦA TÔI',
+ 'nav.profile': 'HỒ SƠ',
// The phone's one button in the header's corner: every control the bar
// carries, folded into a panel under it (see TopBar).
'nav.menu': 'MENU',
'nav.library': 'THƯ VIỆN',
'nav.studio': 'Studio',
- 'nav.guest': 'Khách',
+ 'nav.guest': 'KHÁCH',
// The install offer (src/ui/InstallPrompt.tsx). The only dialog that asks for
// something the visitor did not come for, so the copy sells what they get out of
@@ -38,7 +38,7 @@ export const vi = {
'act.redo': 'LÀM LẠI',
'act.reset': 'ĐẶT LẠI',
'act.export': 'XUẤT ẢNH',
- 'act.exporting': 'Đang xuất…',
+ 'act.exporting': 'ĐANG XUẤT…',
'act.upscaling': 'Đang phóng to ảnh {done}/{total}…',
'act.cancel': 'Huỷ',
@@ -424,7 +424,7 @@ export const vi = {
'lib.immich.linkForget': 'XOÁ LIÊN KẾT',
'immich.upload': 'Lưu lên Immich',
'immich.uploadTitle': 'Tải ảnh đã sửa lên Immich Cloud',
- 'immich.uploading': 'Đang tải lên…',
+ 'immich.uploading': 'ĐANG TẢI LÊN…',
'immich.uploadSuccess': 'Đã tải ảnh lên Immich Cloud thành công!',
'immich.uploadFailed': 'Tải lên Immich Cloud thất bại: {msg}',
'immich.uploadToCloud': 'Tải lên Immich Cloud',
diff --git a/docker/frontend/src/styles/app.css b/docker/frontend/src/styles/app.css
index 98c77c3..142c13b 100644
--- a/docker/frontend/src/styles/app.css
+++ b/docker/frontend/src/styles/app.css
@@ -46,6 +46,7 @@
/* The word a button keeps for that panel: the icon-only rules below take the
words out of the row, and the panel is where they are read again. */
.mob-label { display: none; }
+[data-key="export-photo"] { text-transform: uppercase; letter-spacing: 0.04em; }
.workspace { display: flex; flex: 1 1 auto; min-height: 0; }
@@ -2192,9 +2193,10 @@ form[data-key='immich-modal'] {
line-height: 1.2;
padding: 4px 10px;
}
- /* The names come back. LIBRARY, RESET, SAVE PHOTO, EXPORT and the Immich
- button wear their word as text at font-size 0 in the row; the panel draws
- it, and their ::before glyph comes along as the mark beside it. */
+ /* The names come back. LIBRARY, RESET, SAVE PHOTO, EXPORT, IMMICH, THEME,
+ LANGUAGE, ACCOUNT buttons wear their word as text at font-size 0 in the row;
+ the panel draws it with unified uppercase formatting across all buttons. */
+ .bar-menu.open .btn,
.bar-menu.open [data-key="nav-library"],
.bar-menu.open [data-key="reset-look"],
.bar-menu.open [data-key="save-photo"],
@@ -2205,12 +2207,32 @@ form[data-key='immich-modal'] {
padding: 7px 10px;
gap: 6px;
font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ }
+ .bar-menu.open [data-key="upload-immich"] > span {
+ display: inline;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
}
- .bar-menu.open [data-key="upload-immich"] > span { display: inline; }
/* The count is only half of what SAVE PHOTO says; the PRO marker rides with
the word it belongs to. */
.bar-menu.open [data-key="save-photo"] .pro { display: inline; }
- .bar-menu.open .mob-label { display: inline; margin-left: 6px; font-size: 12px; letter-spacing: 0.06em; }
+ .bar-menu.open .mob-label {
+ display: inline;
+ margin-left: 6px;
+ font-size: 12px;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ }
+ .bar-menu.open [data-key="nav-account"] {
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ }
+ .bar-menu.open [data-key="export-photo"] {
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ }
/* Four labelled buttons — LIBRARY, RESET, SAVE PHOTO, EXPORT — are most of what
wraps the bar onto a third row on a 390px screen: the row's own content is
990px wide with the words and 716px with icons, and the bar measured 135px
diff --git a/docker/frontend/src/ui/TopBar.tsx b/docker/frontend/src/ui/TopBar.tsx
index b12f701..a25715a 100644
--- a/docker/frontend/src/ui/TopBar.tsx
+++ b/docker/frontend/src/ui/TopBar.tsx
@@ -161,7 +161,7 @@ export function TopBar({
- {uploadingImmich ? (t('immich.uploading') || 'Đang tải lên...') : 'Immich'}
+ {uploadingImmich ? (t('immich.uploading') || 'ĐANG TẢI LÊN…') : 'IMMICH'}
) : null}
@@ -292,7 +292,7 @@ export function TopBar({
{user ? (
<>
- {user.email.split('@')[0]}
+ {user.email.split('@')[0].toUpperCase()}
>
) : (
t('nav.guest')
diff --git a/docker/recipescam-images.tar.gz.sha256 b/docker/recipescam-images.tar.gz.sha256
index 8191219..6a9d90a 100644
--- a/docker/recipescam-images.tar.gz.sha256
+++ b/docker/recipescam-images.tar.gz.sha256
@@ -1 +1 @@
-2f1f0b4c603b55de877fe229e3df8b1fc614f54d405935604558d6e23793e97b recipescam-images.tar.gz
+200b894b06829eac11e49895a6d251bdac93acd41ca0ee9862b0b36122a681f0 recipescam-images.tar.gz