From 89cf0035daf6c22526b46645ad644b2ee8803e6a Mon Sep 17 00:00:00 2001
From: alpha
Date: Thu, 5 Nov 2026 14:15:13 -0600
Subject: [PATCH 1/6] ui: switches for on/off settings, one-line helper copy
Settings rows and save prompts carried multi-sentence helper text that
buried the controls. Instant-apply toggles now use a Switch, and the
descriptions are cut to one sentence in both locales.
Co-Authored-By: Claude Opus 5.5
---
.../settings/allow-screen-capture-field.tsx | 6 +-
.../custom/settings/hide-taskbar-field.tsx | 6 +-
.../custom/settings/mock-hints-field.tsx | 8 +--
.../settings/transcript-panel-field.tsx | 4 +-
src/renderer/components/ui/switch.tsx | 31 +++++++++
src/renderer/i18n/locales/en.ts | 63 ++++++++-----------
src/renderer/i18n/locales/ru.ts | 61 ++++++++----------
7 files changed, 93 insertions(+), 86 deletions(-)
create mode 100644 src/renderer/components/ui/switch.tsx
diff --git a/src/renderer/components/custom/settings/allow-screen-capture-field.tsx b/src/renderer/components/custom/settings/allow-screen-capture-field.tsx
index 6442ba2a..c146c4ff 100644
--- a/src/renderer/components/custom/settings/allow-screen-capture-field.tsx
+++ b/src/renderer/components/custom/settings/allow-screen-capture-field.tsx
@@ -1,4 +1,4 @@
-import { Checkbox } from '@/components/ui/checkbox';
+import { Switch } from '@/components/ui/switch';
import { useAllowScreenCapture } from '@/hooks/use-allow-screen-capture';
import { useT } from '@/i18n';
@@ -12,9 +12,9 @@ export function AllowScreenCaptureField() {
{t.allowScreenCaptureField.label}
{t.allowScreenCaptureField.description}
- setEnabled(v === true)}
+ onCheckedChange={setEnabled}
aria-label={t.allowScreenCaptureField.label}
/>
diff --git a/src/renderer/components/custom/settings/hide-taskbar-field.tsx b/src/renderer/components/custom/settings/hide-taskbar-field.tsx
index 53f94b8b..6885654c 100644
--- a/src/renderer/components/custom/settings/hide-taskbar-field.tsx
+++ b/src/renderer/components/custom/settings/hide-taskbar-field.tsx
@@ -1,4 +1,4 @@
-import { Checkbox } from '@/components/ui/checkbox';
+import { Switch } from '@/components/ui/switch';
import { useHideTaskbar } from '@/hooks/use-hide-taskbar';
import { useT } from '@/i18n';
@@ -12,9 +12,9 @@ export function HideTaskbarField() {
{t.hideTaskbarField.label}
{t.hideTaskbarField.description}
- setEnabled(v === true)}
+ onCheckedChange={setEnabled}
aria-label={t.hideTaskbarField.label}
/>
diff --git a/src/renderer/components/custom/settings/mock-hints-field.tsx b/src/renderer/components/custom/settings/mock-hints-field.tsx
index bb7058e5..ef46c1bc 100644
--- a/src/renderer/components/custom/settings/mock-hints-field.tsx
+++ b/src/renderer/components/custom/settings/mock-hints-field.tsx
@@ -1,4 +1,4 @@
-import { Checkbox } from '@/components/ui/checkbox';
+import { Switch } from '@/components/ui/switch';
import { useMockLiveSuggestions } from '@/hooks/use-mock-live-suggestions';
import { useT } from '@/i18n';
@@ -20,11 +20,7 @@ export function MockHintsField() {
{t.mockHintsField.label}
{t.mockHintsField.description}
- setEnabled(v === true)}
- aria-label={t.mockHintsField.label}
- />
+
);
}
diff --git a/src/renderer/components/custom/settings/transcript-panel-field.tsx b/src/renderer/components/custom/settings/transcript-panel-field.tsx
index 540bb48f..ec28d183 100644
--- a/src/renderer/components/custom/settings/transcript-panel-field.tsx
+++ b/src/renderer/components/custom/settings/transcript-panel-field.tsx
@@ -1,4 +1,4 @@
-import { Checkbox } from '@/components/ui/checkbox';
+import { Switch } from '@/components/ui/switch';
import { useTranscriptPanel } from '@/hooks/use-transcript-panel';
import { useT } from '@/i18n';
import { Hotkey, HOTKEYS } from '@/lib/hotkeys';
@@ -21,7 +21,7 @@ export function TranscriptPanelField() {
{t.transcriptPanelField.description(HOTKEYS[Hotkey.ToggleTranscript].combo)}
- toggle()}
aria-label={t.transcriptPanelField.label}
diff --git a/src/renderer/components/ui/switch.tsx b/src/renderer/components/ui/switch.tsx
new file mode 100644
index 00000000..80af6757
--- /dev/null
+++ b/src/renderer/components/ui/switch.tsx
@@ -0,0 +1,31 @@
+import { Switch as SwitchPrimitive } from 'radix-ui';
+import * as React from 'react';
+
+import { cn } from '@/lib/utils';
+
+function Switch({
+ className,
+ size = 'default',
+ ...props
+}: React.ComponentProps & {
+ size?: 'sm' | 'default';
+}) {
+ return (
+
+
+
+ );
+}
+
+export { Switch };
diff --git a/src/renderer/i18n/locales/en.ts b/src/renderer/i18n/locales/en.ts
index f77a6c43..d4e433e5 100644
--- a/src/renderer/i18n/locales/en.ts
+++ b/src/renderer/i18n/locales/en.ts
@@ -34,8 +34,7 @@ export const en = {
uiLanguageField: {
label: 'App language',
- description:
- 'The app itself: buttons, headings and messages. What your interview runs in is a separate setting.',
+ description: 'Buttons, menus and messages. Separate from the interview language.',
},
onboarding: {
@@ -50,20 +49,17 @@ export const en = {
uiLanguage: {
label: 'App language',
title: 'Which language should the app be in?',
- description:
- 'Pick the language you read most comfortably. Everything from here on, including this step, follows it.',
+ description: 'Everything from here on follows it.',
},
profile: {
label: 'Profile',
title: 'Tell us who you are',
- description:
- 'Every suggestion is written from this, in your own experience and your own words. It is the one thing the app cannot run without.',
+ description: 'Suggestions are written from your experience, so this is required.',
},
context: {
label: 'Job context',
title: 'What are you interviewing for?',
- description:
- 'Optional, and worth the paste: with the job description in hand the assistant answers for that role rather than in general.',
+ description: 'Optional. Paste the job description for answers tailored to the role.',
},
language: {
label: 'Language',
@@ -74,7 +70,7 @@ export const en = {
label: 'Microphone',
title: 'Choose your microphone',
description:
- 'Pick the microphone you will actually be speaking into, then test it. Wear headphones during interviews - on speakers the app hears the interviewer through your microphone and goes quiet.',
+ 'Pick the microphone you will speak into and test it. Use headphones during interviews.',
},
mode: {
label: 'Suggestions',
@@ -84,14 +80,12 @@ export const en = {
mockHints: {
label: 'Mock interview',
title: 'Hints in a mock interview?',
- description:
- 'A mock interview is where you practise against the AI interviewer. This decides whether it hands you the answer as well.',
+ description: 'Whether mock interviews show the answer as well as the question.',
},
zoom: {
label: 'Size',
title: 'Is this comfortable to read?',
- description:
- 'The interview window is small on purpose, so it does not cover the call. Size it now, while you can take your time over it, rather than mid-question.',
+ description: 'Make suggestions comfortable to read at a glance.',
},
transcript: {
label: 'Transcript',
@@ -325,11 +319,9 @@ export const en = {
suggestionModeField: {
label: 'Suggestion style',
hintOnly: 'Hint-only',
- hintOnlyDescription:
- 'A headline and keyword bullets you can read at a glance while you keep talking. Recommended.',
+ hintOnlyDescription: 'A headline and keywords to read at a glance. Recommended.',
fullSentences: 'Full sentences',
- fullSentencesDescription:
- 'The answer written out the way it would be spoken. More to read, less to improvise.',
+ fullSentencesDescription: 'The full answer, written out as you would say it.',
switchHint: (combo: string) => `Switchable mid-interview from the control bar or ${combo}.`,
},
@@ -338,30 +330,27 @@ export const en = {
smaller: 'Smaller',
larger: 'Larger',
reset: 'Reset',
- description: (combo: string) =>
- `Scales the whole app. The interview window is small on purpose - this is how you make the suggestions readable at a glance. Also on ${combo}.`,
+ description: (combo: string) => `Scales the whole app. Also on ${combo}.`,
},
transcriptPanelField: {
label: 'Show the transcript panel',
- description: (combo: string) =>
- `Keeps a live transcript docked under your suggestions. Turn it off for more room to read them. Toggle any time with ${combo}.`,
+ description: (combo: string) => `Live transcript under your suggestions. Toggle with ${combo}.`,
},
hideTaskbarField: {
label: 'Hide taskbar icon during live interviews',
description:
- 'Off by default. When on, the app leaves the taskbar (and the Dock on macOS) and stays on top of other windows while a live interview is running. The window cannot be minimized while this is on. If the window gets lost, launch the app again to bring it back.',
+ 'Hides the app from the taskbar and keeps it on top during live interviews. It cannot be minimized - relaunch the app if it gets lost.',
},
allowScreenCaptureField: {
label: 'Allow screen capture',
description:
- "Off by default. When on, the app window appears in screen shares, recordings and other apps' screenshots. The app's own screenshots and stealth mode always leave it out, whatever this is set to.",
+ 'Lets screen shares and recordings see the app window. Stealth mode always hides it.',
},
mockHintsField: {
label: 'Show hints in mock interviews',
- description:
- 'Puts what the live assistant would have answered beside each mock interview question, so you can compare it against your own. Turn it off to answer unaided - either way, you can switch it mid-session from the mock interview bar. This changes nothing about a real interview.',
+ description: "Shows the assistant's answer beside each mock question, to compare with yours.",
},
languageField: {
@@ -685,32 +674,32 @@ export const en = {
live: {
clear: {
title: 'Save this interview before clearing?',
- body: 'Clearing drops the transcript and the suggestions from this session, and nothing is written to disk until you export.',
+ body: 'The transcript and suggestions will be lost.',
discard: 'Clear without saving',
},
start: {
title: 'Save this interview before starting a new one?',
- body: 'Starting a session drops the transcript and the suggestions from the last one, and nothing is written to disk until you export.',
+ body: 'The transcript and suggestions will be lost.',
discard: 'Start without saving',
},
close: {
title: 'Save this interview before closing?',
- body: 'Closing drops the transcript and the suggestions from this session, and nothing is written to disk until you export.',
+ body: 'The transcript and suggestions will be lost.',
discard: 'Close without saving',
},
update: {
title: 'Save this interview before installing the update?',
- body: 'Installing restarts the app and drops the transcript and the suggestions from this session, and nothing is written to disk until you export.',
+ body: 'The app restarts and the transcript and suggestions will be lost.',
discard: 'Install without saving',
},
signout: {
title: 'Save this interview before signing out?',
- body: 'Signing out drops the transcript and the suggestions from this session, and nothing is written to disk until you export.',
+ body: 'The transcript and suggestions will be lost.',
discard: 'Sign out without saving',
},
stop: {
title: 'Save this interview?',
- body: 'Your interview has ended. The transcript and the suggestions are dropped from here, and nothing has been written to disk.',
+ body: 'The interview has ended. Its transcript and suggestions are not saved anywhere yet.',
discard: 'Discard and go home',
},
'mock-done': {
@@ -729,32 +718,32 @@ export const en = {
mock: {
clear: {
title: 'Save your mock interview report first?',
- body: 'Clearing drops this report and the answers behind it, and nothing is written to disk until you save.',
+ body: 'This report and your answers will be lost.',
discard: 'Clear without saving',
},
start: {
title: 'Save your mock interview report first?',
- body: 'Starting a session replaces this report and the answers behind it, and nothing is written to disk until you save.',
+ body: 'This report and your answers will be lost.',
discard: 'Start without saving',
},
close: {
title: 'Save your mock interview report before closing?',
- body: 'This report and the answers behind it exist only in this app, and closing drops them.',
+ body: 'This report and your answers will be lost.',
discard: 'Close without saving',
},
update: {
title: 'Save your mock interview report before installing the update?',
- body: 'Installing restarts the app, which drops this report and the answers behind it.',
+ body: 'The app restarts and this report and your answers will be lost.',
discard: 'Install without saving',
},
signout: {
title: 'Save your mock interview report before signing out?',
- body: 'Signing out drops this report and the answers behind it, and nothing has been written to disk.',
+ body: 'This report and your answers will be lost.',
discard: 'Sign out without saving',
},
stop: {
title: 'Save your mock interview report?',
- body: 'The interview has ended. This report and the answers behind it are dropped from here, and nothing has been written to disk.',
+ body: 'The interview has ended. This report is not saved anywhere yet.',
discard: 'Discard and go home',
},
},
diff --git a/src/renderer/i18n/locales/ru.ts b/src/renderer/i18n/locales/ru.ts
index 43664983..9ae5fee1 100644
--- a/src/renderer/i18n/locales/ru.ts
+++ b/src/renderer/i18n/locales/ru.ts
@@ -44,8 +44,7 @@ export const ru: Translation = {
uiLanguageField: {
label: 'Язык приложения',
- description:
- 'Сам интерфейс: кнопки, заголовки и сообщения. Язык собеседования настраивается отдельно.',
+ description: 'Кнопки, меню и сообщения. Не зависит от языка собеседования.',
},
onboarding: {
@@ -58,20 +57,17 @@ export const ru: Translation = {
uiLanguage: {
label: 'Язык приложения',
title: 'На каком языке показывать приложение?',
- description:
- 'Выберите язык, на котором вам удобнее читать. Всё дальше, включая этот шаг, будет на нём.',
+ description: 'Всё дальше будет на этом языке.',
},
profile: {
label: 'Профиль',
title: 'Расскажите о себе',
- description:
- 'Все подсказки опираются на это - на ваш опыт и ваши слова. Без этого приложение работать не сможет.',
+ description: 'Подсказки строятся на вашем опыте, поэтому это обязательно.',
},
context: {
label: 'О вакансии',
title: 'На какую позицию вы проходите собеседование?',
- description:
- 'Необязательно, но стоит вставить: с описанием вакансии ассистент отвечает с учётом этой роли, а не в общем.',
+ description: 'Необязательно. Вставьте описание вакансии, чтобы ответы учитывали роль.',
},
language: {
label: 'Язык',
@@ -82,7 +78,7 @@ export const ru: Translation = {
label: 'Микрофон',
title: 'Выберите микрофон',
description:
- 'Выберите микрофон, в который вы действительно будете говорить, и проверьте его. На собеседовании используйте наушники - через динамики приложение слышит интервьюера через ваш микрофон и замолкает.',
+ 'Выберите микрофон, в который будете говорить, и проверьте его. На собеседовании используйте наушники.',
},
mode: {
label: 'Подсказки',
@@ -92,14 +88,12 @@ export const ru: Translation = {
mockHints: {
label: 'Пробное собеседование',
title: 'Показывать подсказки в пробном собеседовании?',
- description:
- 'Пробное собеседование - это тренировка с ИИ-интервьюером. Здесь вы решаете, будет ли он подсказывать ответы.',
+ description: 'Показывать ли в пробных собеседованиях ответ вместе с вопросом.',
},
zoom: {
label: 'Размер',
title: 'Так читать удобно?',
- description:
- 'Окно собеседования небольшое специально, чтобы не закрывать звонок. Настройте размер сейчас, пока есть время, а не посреди вопроса.',
+ description: 'Сделайте подсказки удобными для чтения одним взглядом.',
},
transcript: {
label: 'Расшифровка',
@@ -336,11 +330,9 @@ export const ru: Translation = {
suggestionModeField: {
label: 'Вид подсказок',
hintOnly: 'Краткие подсказки',
- hintOnlyDescription:
- 'Заголовок и ключевые слова, которые читаются одним взглядом, пока вы продолжаете говорить. Рекомендуется.',
+ hintOnlyDescription: 'Заголовок и ключевые слова, понятные с одного взгляда. Рекомендуется.',
fullSentences: 'Полные фразы',
- fullSentencesDescription:
- 'Ответ, записанный так, как его можно произнести. Читать больше, придумывать меньше.',
+ fullSentencesDescription: 'Полный ответ, записанный так, как его можно произнести.',
switchHint: (combo: string) =>
`Переключается во время собеседования с панели управления или по ${combo}.`,
},
@@ -350,30 +342,29 @@ export const ru: Translation = {
smaller: 'Меньше',
larger: 'Больше',
reset: 'Сбросить',
- description: (combo: string) =>
- `Масштабирует всё приложение. Окно собеседования небольшое специально - так подсказки можно прочитать одним взглядом. Также доступно по ${combo}.`,
+ description: (combo: string) => `Масштабирует всё приложение. Также по ${combo}.`,
},
transcriptPanelField: {
label: 'Показывать панель расшифровки',
description: (combo: string) =>
- `Показывает расшифровку разговора под подсказками. Выключите, чтобы освободить место для чтения подсказок. Переключается в любой момент по ${combo}.`,
+ `Расшифровка разговора под подсказками. Переключается по ${combo}.`,
},
hideTaskbarField: {
label: 'Скрывать значок на панели задач во время собеседования',
description:
- 'По умолчанию выключено. Когда включено, приложение убирается с панели задач (и из Dock на macOS) и остаётся поверх других окон, пока идёт живое собеседование. Пока настройка включена, окно нельзя свернуть. Если окно потерялось, запустите приложение ещё раз - оно вернётся.',
+ 'Убирает приложение с панели задач и держит его поверх окон во время собеседования. Свернуть окно нельзя - если оно потерялось, запустите приложение снова.',
},
allowScreenCaptureField: {
label: 'Разрешить захват экрана',
description:
- 'По умолчанию выключено. Когда включено, окно приложения видно при демонстрации экрана, в записях и на снимках экрана из других приложений. Собственные снимки приложения и скрытый режим не показывают его никогда, независимо от этой настройки.',
+ 'Окно приложения будет видно при демонстрации экрана и в записях. В скрытом режиме оно всегда скрыто.',
},
mockHintsField: {
label: 'Показывать подсказки в пробных собеседованиях',
description:
- 'Показывает рядом с каждым вопросом пробного собеседования то, что ответил бы живой ассистент, чтобы вы могли сравнить со своим ответом. Выключите, чтобы отвечать самостоятельно - в любом случае это переключается во время сессии с панели пробного собеседования. На настоящее собеседование это никак не влияет.',
+ 'Показывает ответ ассистента рядом с каждым пробным вопросом, чтобы сравнить со своим.',
},
languageField: {
@@ -697,32 +688,32 @@ export const ru: Translation = {
live: {
clear: {
title: 'Сохранить это собеседование перед очисткой?',
- body: 'Очистка удалит расшифровку и подсказки этой сессии, а на диск ничего не записывается до экспорта.',
+ body: 'Расшифровка и подсказки будут потеряны.',
discard: 'Очистить без сохранения',
},
start: {
title: 'Сохранить это собеседование перед началом нового?',
- body: 'Запуск сессии удалит расшифровку и подсказки предыдущей, а на диск ничего не записывается до экспорта.',
+ body: 'Расшифровка и подсказки будут потеряны.',
discard: 'Начать без сохранения',
},
close: {
title: 'Сохранить это собеседование перед закрытием?',
- body: 'Закрытие удалит расшифровку и подсказки этой сессии, а на диск ничего не записывается до экспорта.',
+ body: 'Расшифровка и подсказки будут потеряны.',
discard: 'Закрыть без сохранения',
},
update: {
title: 'Сохранить это собеседование перед установкой обновления?',
- body: 'Установка перезапустит приложение и удалит расшифровку и подсказки этой сессии, а на диск ничего не записывается до экспорта.',
+ body: 'Приложение перезапустится, расшифровка и подсказки будут потеряны.',
discard: 'Установить без сохранения',
},
signout: {
title: 'Сохранить это собеседование перед выходом?',
- body: 'Выход удалит расшифровку и подсказки этой сессии, а на диск ничего не записывается до экспорта.',
+ body: 'Расшифровка и подсказки будут потеряны.',
discard: 'Выйти без сохранения',
},
stop: {
title: 'Сохранить это собеседование?',
- body: 'Собеседование завершено. Расшифровка и подсказки будут удалены отсюда, и на диск ничего не записано.',
+ body: 'Собеседование завершено. Расшифровка и подсказки пока нигде не сохранены.',
discard: 'Удалить и выйти на главную',
},
'mock-done': {
@@ -740,32 +731,32 @@ export const ru: Translation = {
mock: {
clear: {
title: 'Сначала сохранить отчёт о пробном собеседовании?',
- body: 'Очистка удалит этот отчёт и ваши ответы, а на диск ничего не записывается до сохранения.',
+ body: 'Этот отчёт и ваши ответы будут потеряны.',
discard: 'Очистить без сохранения',
},
start: {
title: 'Сначала сохранить отчёт о пробном собеседовании?',
- body: 'Запуск сессии заменит этот отчёт и ваши ответы, а на диск ничего не записывается до сохранения.',
+ body: 'Этот отчёт и ваши ответы будут потеряны.',
discard: 'Начать без сохранения',
},
close: {
title: 'Сохранить отчёт о пробном собеседовании перед закрытием?',
- body: 'Этот отчёт и ваши ответы существуют только в приложении, и закрытие их удалит.',
+ body: 'Этот отчёт и ваши ответы будут потеряны.',
discard: 'Закрыть без сохранения',
},
update: {
title: 'Сохранить отчёт о пробном собеседовании перед установкой обновления?',
- body: 'Установка перезапустит приложение, а это удалит отчёт и ваши ответы.',
+ body: 'Приложение перезапустится, отчёт и ваши ответы будут потеряны.',
discard: 'Установить без сохранения',
},
signout: {
title: 'Сохранить отчёт о пробном собеседовании перед выходом?',
- body: 'Выход удалит этот отчёт и ваши ответы, и на диск ничего не записано.',
+ body: 'Этот отчёт и ваши ответы будут потеряны.',
discard: 'Выйти без сохранения',
},
stop: {
title: 'Сохранить отчёт о пробном собеседовании?',
- body: 'Собеседование завершено. Этот отчёт и ваши ответы будут удалены отсюда, и на диск ничего не записано.',
+ body: 'Собеседование завершено. Этот отчёт пока нигде не сохранён.',
discard: 'Удалить и выйти на главную',
},
},
From 36ae6006b7d6d6ec0c63a1429332f5ef3f31cd42 Mon Sep 17 00:00:00 2001
From: alpha
Date: Thu, 5 Nov 2026 14:20:59 -0600
Subject: [PATCH 2/6] ui: readable switch states, consistent toggles, review
copy fixes
- Off track and thumb now contrast in both themes; stock tokens left
the off state near-invisible in light mode.
- Panel auto-scroll checkboxes become small switches, matching the
settings rows.
- Settings switches reference their description via aria-describedby.
- Restore the macOS Dock and the speakers consequence in copy, clarify
the app-language step, shorten the remaining mock save prompts.
Co-Authored-By: Claude Opus 5.5
---
.../custom/panels/action-suggestions-panel.tsx | 6 +++---
.../custom/panels/live-suggestions-panel.tsx | 6 +++---
.../custom/panels/mock-transcript-panel.tsx | 6 +++---
.../components/custom/panels/transcript-panel.tsx | 6 +++---
.../custom/settings/allow-screen-capture-field.tsx | 8 +++++++-
.../custom/settings/hide-taskbar-field.tsx | 8 +++++++-
.../custom/settings/mock-hints-field.tsx | 14 ++++++++++++--
.../custom/settings/transcript-panel-field.tsx | 6 +++++-
src/renderer/components/ui/switch.tsx | 4 ++--
src/renderer/i18n/locales/en.ts | 10 +++++-----
src/renderer/i18n/locales/ru.ts | 11 ++++++-----
11 files changed, 56 insertions(+), 29 deletions(-)
diff --git a/src/renderer/components/custom/panels/action-suggestions-panel.tsx b/src/renderer/components/custom/panels/action-suggestions-panel.tsx
index e7f32d76..579ed417 100644
--- a/src/renderer/components/custom/panels/action-suggestions-panel.tsx
+++ b/src/renderer/components/custom/panels/action-suggestions-panel.tsx
@@ -12,7 +12,7 @@ import { type ActionSuggestion, SuggestionState } from '@/types/suggestion';
const MAX_QUESTION_LENGTH = 256;
import { Button } from '../../ui/button';
-import { Checkbox } from '../../ui/checkbox';
+import { Switch } from '../../ui/switch';
import { SafeMarkdown } from '../safe-markdown';
import SuggestionReveal from './suggestion-reveal';
@@ -176,7 +176,8 @@ function ActionSuggestionsPanel({
{!isStealth && (