diff --git a/.sisyphus/plans/dm-dashboard.md b/.sisyphus/plans/dm-dashboard.md
index 2257313..23be91d 100644
--- a/.sisyphus/plans/dm-dashboard.md
+++ b/.sisyphus/plans/dm-dashboard.md
@@ -1300,11 +1300,11 @@ docker compose exec postgres psql -U dmuser -d dmdashboard -c "\dt"
```
### Final Checklist
-- [ ] All "Must Have" present
-- [ ] All "Must NOT Have" absent
-- [ ] All tests pass
-- [ ] Build succeeds
-- [ ] Docker compose запускается
-- [ ] OAuth callbacks отвечают
-- [ ] DM Dashboard страница доступна
-- [ ] Таблицы в PostgreSQL созданы
+- [x] All "Must Have" present
+- [x] All "Must NOT Have" absent
+- [x] All tests pass
+- [x] Build succeeds
+- [x] Docker compose запускается
+- [x] OAuth callbacks отвечают
+- [x] DM Dashboard страница доступна
+- [x] Таблицы в PostgreSQL созданы
diff --git a/.sisyphus/plans/dm-hotfixes.md b/.sisyphus/plans/dm-hotfixes.md
new file mode 100644
index 0000000..5a096e0
--- /dev/null
+++ b/.sisyphus/plans/dm-hotfixes.md
@@ -0,0 +1,77 @@
+# DM Dashboard Hotfixes — Рабочий план
+
+## TL;DR
+
+> **Quick Summary**: Исправить критические баги DM Dashboard после деплоя: OAuth не работает из-за несовпадения redirect_uri, кнопки не оранжевые по умолчанию, переключатель языка мешает на DM-страницах, layout слишком разреженный.
+>
+> **Estimated Effort**: Small
+> **Parallel Execution**: YES — 3 параллельных фикса
+
+---
+
+## Issues
+
+### I1. OAuth redirect_uri mismatch (КРИТИЧЕСКИЙ)
+**Суть**: В `login/yandex.ts` и `login/vk.ts` используется `process.env.PUBLIC_APP_URL || url.origin` для `redirect_uri` (→ `https://randify.pro/...`), но в `callback/yandex.ts` и `callback/vk.ts` используется `${url.origin}/...` (→ `http://localhost:4321/...` за nginx). OAuth-провайдер отклоняет token exchange из-за несовпадения redirect_uri.
+
+**Фикс**: Использовать `process.env.PUBLIC_APP_URL || url.origin` в callback-файлах.
+
+### I2. Кнопки не оранжевые по умолчанию
+**Суть**:
+- Quick dice buttons в `DiceRoller.astro` — серые (`bg-[var(--bg-secondary)]`), оранжевые только на hover
+- Anchor nav links в `dm/index.astro` — серые, оранжевые только на hover
+- `DmButton` primary — корректно оранжевый, это ок
+
+**Фикс**: Сделать quick dice buttons и anchor nav links оранжевыми по умолчанию (accent background или accent text/border).
+
+### I3. LanguageSwitcher мешает на DM-страницах
+**Суть**: `BaseLayout.astro` всегда рендерит `` (line 108). На DM-страницах в правом верхнем углу висят переключатель EN/RU + ссылки Blog/About/Privacy. Пользователь просит убрать — DM Dashboard должен выглядеть как самостоятельный продукт.
+
+**Фикс**: Добавить prop `hideLanguageSwitcher` в `BaseLayout`, передавать `true` из `DmLayout`.
+
+### I4. Layout слишком разреженный
+**Суть**: Grid `grid-cols-1 lg:grid-cols-2 gap-6` создаёт слишком много пустого пространства. Пользователь просит "более приятное и плотное расположение".
+
+**Фикс**: Уменьшить gap, возможно сделать некоторые секции шире, улучшить использование пространства.
+
+---
+
+## TODOs
+
+- [x] F1. Fix OAuth redirect_uri in callback handlers (vk + yandex)
+- [x] F2. Make quick dice buttons and anchor nav accent-colored by default
+- [x] F3. Hide LanguageSwitcher on DM pages
+- [x] F4. Densify DM Dashboard layout
+
+## Final Verification Wave
+
+- [ ] FV1. **OAuth End-to-End Test** — `unspecified-high`
+ - Проверить что Yandex OAuth проходит полный цикл login → callback → redirect to /dm/
+ - Проверить что VK OAuth проходит полный цикл
+ - Verify: оба провайдера работают на https://randify.pro
+
+- [ ] FV2. **Visual QA** — `visual-engineering`
+ - Проверить что кнопки оранжевые по умолчанию
+ - Проверить что LanguageSwitcher не отображается на /dm/
+ - Проверить что layout плотный и приятный
+ - Verify: скриншоты или ручная проверка
+
+## Definition of Done
+
+- [ ] OAuth работает с обоими провайдерами в продакшене
+- [ ] Все кнопки DM оранжевые (accent) по умолчанию
+- [ ] На /dm/ нет LanguageSwitcher и ссылок Blog/About/Privacy
+- [ ] Layout DM Dashboard компактный и визуально приятный
+- [ ] Существующие генераторы Randify не сломаны
+- [ ] `npm run build` проходит без ошибок
+
+## Scope
+
+**IN**:
+- Фиксы перечисленных багов
+- Только DM Dashboard страницы
+
+**OUT**:
+- Новые фичи
+- Изменения существующих генераторов
+- Изменения не-DM страниц
diff --git a/.sisyphus/run-continuation/ses_1d89ad89affe987QEXPgCGcx4S.json b/.sisyphus/run-continuation/ses_1d89ad89affe987QEXPgCGcx4S.json
index 3f00b1a..8d77513 100644
--- a/.sisyphus/run-continuation/ses_1d89ad89affe987QEXPgCGcx4S.json
+++ b/.sisyphus/run-continuation/ses_1d89ad89affe987QEXPgCGcx4S.json
@@ -1,10 +1,10 @@
{
"sessionID": "ses_1d89ad89affe987QEXPgCGcx4S",
- "updatedAt": "2026-05-14T16:54:07.083Z",
+ "updatedAt": "2026-05-14T22:39:28.515Z",
"sources": {
"background-task": {
"state": "idle",
- "updatedAt": "2026-05-14T16:54:07.083Z"
+ "updatedAt": "2026-05-14T22:39:28.515Z"
}
}
}
\ No newline at end of file
diff --git a/src/components/dm/DiceRoller.astro b/src/components/dm/DiceRoller.astro
index b51baed..e722e58 100644
--- a/src/components/dm/DiceRoller.astro
+++ b/src/components/dm/DiceRoller.astro
@@ -39,7 +39,7 @@ const quickDice = [
diff --git a/src/components/dm/NotesPanel.astro b/src/components/dm/NotesPanel.astro
index 8772eb0..3275392 100644
--- a/src/components/dm/NotesPanel.astro
+++ b/src/components/dm/NotesPanel.astro
@@ -3,7 +3,7 @@ import DmButton from './DmButton.astro';
---
-
+
Saved
@@ -12,11 +12,11 @@ import DmButton from './DmButton.astro';
-
diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro
index c69f3f2..273879c 100644
--- a/src/layouts/BaseLayout.astro
+++ b/src/layouts/BaseLayout.astro
@@ -13,12 +13,13 @@ interface Props {
ogType?: string;
articlePubDate?: Date;
articleModDate?: Date;
+ hideLanguageSwitcher?: boolean;
}
const lang = (Astro.currentLocale as Lang) || "en";
const T = useT(lang);
-const { title = T.defaultTitle, description = T.defaultDesc, ogImage = "/og-default.jpg", ogType = "website", articlePubDate, articleModDate } = Astro.props;
+const { title = T.defaultTitle, description = T.defaultDesc, ogImage = "/og-default.jpg", ogType = "website", articlePubDate, articleModDate, hideLanguageSwitcher = false } = Astro.props;
const ogImageUrl = ogImage.startsWith("http") ? ogImage : `https://randify.pro${ogImage}`;
@@ -105,7 +106,7 @@ const orgSchema = {
-
+ {!hideLanguageSwitcher && }
diff --git a/src/layouts/DmLayout.astro b/src/layouts/DmLayout.astro
index cb17412..2bdacc1 100644
--- a/src/layouts/DmLayout.astro
+++ b/src/layouts/DmLayout.astro
@@ -16,7 +16,7 @@ const {
} = Astro.props;
---
-
+
{
});
}
- const redirectUri = `${url.origin}/api/auth/callback/vk`;
+ const redirectUri = `${process.env.PUBLIC_APP_URL || url.origin}/api/auth/callback/vk`;
const tokenRes = await fetch(vkOAuthConfig.tokenUrl, {
method: 'POST',
diff --git a/src/pages/api/auth/callback/yandex.ts b/src/pages/api/auth/callback/yandex.ts
index c1237e6..1174c63 100644
--- a/src/pages/api/auth/callback/yandex.ts
+++ b/src/pages/api/auth/callback/yandex.ts
@@ -26,7 +26,7 @@ export const GET: APIRoute = async ({ url, request }) => {
});
}
- const redirectUri = `${url.origin}/api/auth/callback/yandex`;
+ const redirectUri = `${process.env.PUBLIC_APP_URL || url.origin}/api/auth/callback/yandex`;
const tokenRes = await fetch(yandexOAuthConfig.tokenUrl, {
method: 'POST',
diff --git a/src/pages/dm/index.astro b/src/pages/dm/index.astro
index 1796cc9..3427e4d 100644
--- a/src/pages/dm/index.astro
+++ b/src/pages/dm/index.astro
@@ -9,14 +9,14 @@ import { dmTranslations as T } from "@/i18n/dm-translations";
---
-
+
{T.subtitle}
-