0, 'bonus_balance' => 0, 'tier' => $isSso ? 'free' : 'caveau',
'storage_used_bytes' => 0, 'storage_quota_bytes' => 0,
'survey_completed_at' => null, 'subscription_period_end' => null,
'trial_active' => false, 'trial_days_remaining' => 0, 'trial_expires_at' => null,
], $userId > 0 ? (FreeTier::balanceDetail($userId) ?: []) : []);
$tier = (string)$detail['tier'];
$isPaidTier = in_array($tier, ['plus', 'pro'], true);
$effective = (int)$detail['balance'] + (int)$detail['bonus_balance'];
$storageBytes = (int)$detail['storage_used_bytes'];
$quotaBytes = (int)$detail['storage_quota_bytes'];
$storageMb = $storageBytes > 0 ? round($storageBytes / 1048576, 1) : 0;
$quotaMb = $quotaBytes > 0 ? (int)round($quotaBytes / 1048576) : 0;
$storagePct = $quotaBytes > 0 ? min(100, (int)round(($storageBytes / $quotaBytes) * 100)) : 0;
$tierLabels = [
'free' => ['Free', '#f3f4f6', '#374151'],
'plus' => ['Plus', '#ddd6fe', '#5b21b6'],
'pro' => ['Pro Familie', '#bfdbfe', '#1e40af'],
'caveau' => ['CaveauAI', '#d1fae5', '#065f46'],
];
$tierLabel = $tierLabels[$tier] ?? $tierLabels['free'];
$profile = $isSso ? dbnToolsMainUserProfile($userId) : null;
$profileVal = static function (string $key) use ($profile): string {
return (string)($profile[$key] ?? '');
};
$seatLimit = $tier === 'pro' ? 3 : 1;
$docs = $isPaidTier ? CaseStore::listDocs($userId) : [];
$results = $isPaidTier ? CaseResults::listForUser($userId, 50) : [];
$recent = [];
if ($userId > 0) {
try {
$stmt = dbnmDb()->prepare(
'SELECT tool, credits_used, created_at FROM user_tool_usage_log
WHERE user_id = ? ORDER BY created_at DESC LIMIT 25'
);
$stmt->execute([$userId]);
$recent = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Throwable $e) {
$recent = [];
}
}
$paidToast = isset($_GET['paid']) && $_GET['paid'] === '1';
// ── Localized strings (en / no / uk / pl) ──────────────────────────────────
$L = [
'en' => [
'page_title' => 'My account',
'page_lede' => 'Plan, profile, case storage, analyses, usage and MCP access — all in one place.',
'signed_in_as' => 'Signed in as',
'jump_plan' => 'Plan',
'jump_profile' => 'Profile',
'jump_workspace' => 'Workspace',
'jump_case' => 'My Case',
'jump_analyses' => 'Saved analyses',
'jump_usage' => 'Usage',
'jump_mcp' => 'MCP',
'trial_badge' => 'Trial — %d days left',
'sec_plan' => 'Plan & credits',
'current_plan' => 'Current plan',
'renews_on' => 'Renews on',
'no_active_sub' => 'No active subscription.',
'see_plans' => 'See all plans',
'available_credits' => 'Available credits',
'monthly' => 'monthly',
'prepaid' => 'prepaid',
'manage_subscription'=> 'Manage subscription',
'upgrade_plan' => 'Upgrade plan',
'top_up_credits' => 'Top up credits',
'payment_confirmed' => 'Payment confirmed. If you just subscribed, it may take a few seconds for your account to update.',
'bonus_survey_title' => 'Bonus credits (survey)',
'bonus_survey_done' => '✓ You have already received 25 bonus credits for completing the survey.',
'bonus_survey_pitch' => 'Answer 5 short questions about your needs and receive 25 bonus credits — never expire.',
'take_survey_btn' => 'Take the survey',
'portal_loading' => 'Connecting…',
'portal_error' => 'Could not open the portal.',
'network_error' => 'Network error: ',
'sec_profile' => 'Profile details',
'profile_optional' => 'Optional',
'f_display_name' => 'Display name',
'f_phone' => 'Phone',
'f_address_1' => 'Address line 1',
'f_address_2' => 'Address line 2',
'f_postal' => 'Postal code',
'f_city' => 'City',
'f_region' => 'Region',
'f_country' => 'Country',
'save_profile' => 'Save profile',
'profile_saving' => 'Saving…',
'profile_saved' => 'Saved',
'profile_error_default' => 'Could not save profile',
'sec_workspace' => 'Workspace access',
'w_email' => 'Email',
'w_seats' => 'Seats',
'w_role' => 'Role',
'w_owner' => 'Owner',
'w_plan_storage' => 'Plan storage',
'w_seats_single' => 'Single-user workspace',
'w_upgrade_for_storage' => 'Upgrade for My Case storage',
'sec_case' => 'My Case',
'case_lede' => 'Upload your case documents once. All tools can reference your private case when you tick "Use my case as context".',
'case_storage' => 'Storage',
'case_documents_count' => '%d documents',
'case_drop_pdf' => 'Drop PDF files here, or click to browse',
'case_hint' => 'Max 25 MB per file · OCR runs automatically · all stored encrypted in the EU',
'case_no_docs' => 'No documents yet. Upload your first PDF above.',
'case_uploaded_ok' => 'Uploaded: %s. OCR starts automatically.',
'case_over_25mb' => '%s is over 25 MB — split the file first.',
'case_unknown_err' => 'Unknown error',
'case_delete_failed' => 'Delete failed.',
'case_pages' => 'pages',
'case_uploaded_label' => 'uploaded',
'case_delete' => 'Delete',
'case_confirm_delete' => 'Delete this document for good?',
'case_ocr_pending' => 'Queued',
'case_ocr_running' => 'OCR in progress',
'case_ocr_ready' => 'Ready',
'case_ocr_failed' => 'Failed',
'case_free_gate_title' => 'My Case — build your own case',
'case_free_gate_pitch' => 'Upload your case documents once, and let all the tools work on your private corpus.',
'case_free_gate_b1' => '📄 Private document bank with OCR',
'case_free_gate_b2' => '🔍 Hybrid search (BM25 + vector) on your case',
'case_free_gate_b3' => '🧠 All tools can reference your own case',
'case_free_gate_b4' => '🇪🇺 Everything stored in the EU (Germany/Finland/Norway)',
'case_free_gate_cta' => 'See plans from NOK 129/mo',
'sec_analyses' => 'Saved analyses',
'analyses_lede' => 'All results from Correspondence, Advocate, CWS, Deep analysis, Discrepancy and Timeline gather here — ready to reopen, rerun or export.',
'no_analyses' => 'No saved analyses yet. Run a tool to save your first.',
'used_case_badge' => 'Use my case',
'pinned_title' => 'Pinned',
'pin' => 'Pin',
'unpin' => 'Unpin',
'open_analysis' => 'Open',
'delete_analysis' => 'Delete',
'confirm_delete_analysis' => 'Delete this analysis for good?',
'pin_failed' => 'Pin failed.',
'sec_usage' => 'Recent usage (last 25)',
'usage_col_tool' => 'Tool / event',
'usage_col_credits' => 'Credits',
'usage_col_when' => 'When',
'no_usage' => 'No usage recorded yet.',
'sec_mcp' => 'Developers & MCP',
'mcp_desc' => 'Connect Claude Desktop, Claude Code, Cursor, or any MCP-compatible client to the full tool suite.',
'mcp_token_lbl' => 'API token',
'mcp_no_token' => 'No active token',
'mcp_stdio_lbl' => 'Claude Desktop / Claude Code (stdio)',
'mcp_remote_lbl' => 'Remote HTTP — Cursor, Zed, Windsurf',
'mcp_copy' => 'Copy',
'mcp_manage' => 'Manage tokens →',
'mcp_full_setup' => 'Full setup guide & token management →',
'mcp_locked' => 'MCP tokens require Plus or Pro — upgrade to connect AI clients.',
'mcp_loading' => 'Loading…',
],
'no' => [
'page_title' => 'Min konto',
'page_lede' => 'Plan, profil, sak-lagring, analyser, bruk og MCP-tilgang — alt på ett sted.',
'signed_in_as' => 'Innlogget som',
'jump_plan' => 'Plan',
'jump_profile' => 'Profil',
'jump_workspace' => 'Arbeidsområde',
'jump_case' => 'Min Sak',
'jump_analyses' => 'Lagrede analyser',
'jump_usage' => 'Bruk',
'jump_mcp' => 'MCP',
'trial_badge' => 'Prøveperiode — %d dager igjen',
'sec_plan' => 'Plan & kreditter',
'current_plan' => 'Nåværende plan',
'renews_on' => 'Fornyes',
'no_active_sub' => 'Ingen aktiv abonnement.',
'see_plans' => 'Se alle planer',
'available_credits' => 'Tilgjengelige kreditter',
'monthly' => 'månedlige',
'prepaid' => 'forhåndsbetalte',
'manage_subscription'=> 'Administrer abonnement',
'upgrade_plan' => 'Oppgrader plan',
'top_up_credits' => 'Kjøp kreditter',
'payment_confirmed' => 'Betalingen er bekreftet. Hvis du nettopp abonnerte, kan det ta noen sekunder før kontoen oppdateres.',
'bonus_survey_title' => 'Bonus-kreditter (undersøkelse)',
'bonus_survey_done' => '✓ Du har allerede mottatt 25 bonuskreditter for å fylle ut undersøkelsen.',
'bonus_survey_pitch' => 'Svar på 5 korte spørsmål om dine behov og motta 25 bonus-kreditter — utløper aldri.',
'take_survey_btn' => 'Ta undersøkelsen',
'portal_loading' => 'Kobler til…',
'portal_error' => 'Kunne ikke åpne portalen.',
'network_error' => 'Nettverksfeil: ',
'sec_profile' => 'Profildetaljer',
'profile_optional' => 'Valgfritt',
'f_display_name' => 'Visningsnavn',
'f_phone' => 'Telefon',
'f_address_1' => 'Adresselinje 1',
'f_address_2' => 'Adresselinje 2',
'f_postal' => 'Postnummer',
'f_city' => 'Sted',
'f_region' => 'Fylke',
'f_country' => 'Land',
'save_profile' => 'Lagre profil',
'profile_saving' => 'Lagrer…',
'profile_saved' => 'Lagret',
'profile_error_default' => 'Kunne ikke lagre profilen',
'sec_workspace' => 'Arbeidsområde-tilgang',
'w_email' => 'E-post',
'w_seats' => 'Plasser',
'w_role' => 'Rolle',
'w_owner' => 'Eier',
'w_plan_storage' => 'Plan-lagring',
'w_seats_single' => 'Enkeltbruker-arbeidsområde',
'w_upgrade_for_storage' => 'Oppgrader for Min Sak-lagring',
'sec_case' => 'Min Sak',
'case_lede' => 'Last opp dokumentene dine én gang. Alle verktøyene kan deretter referere til din private sak når du krysser av "Bruk min sak som kontekst".',
'case_storage' => 'Lagring',
'case_documents_count' => '%d dokumenter',
'case_drop_pdf' => 'Slipp PDF-filer her, eller klikk for å bla',
'case_hint' => 'Maks 25 MB per fil · OCR kjøres automatisk · alt lagres kryptert i EU',
'case_no_docs' => 'Ingen dokumenter ennå. Last opp din første PDF over.',
'case_uploaded_ok' => 'Lastet opp: %s. OCR starter automatisk.',
'case_over_25mb' => '%s er over 25 MB — del opp filen først.',
'case_unknown_err' => 'Ukjent feil',
'case_delete_failed' => 'Sletting feilet.',
'case_pages' => 'sider',
'case_uploaded_label' => 'lastet opp',
'case_delete' => 'Slett',
'case_confirm_delete' => 'Slette dette dokumentet for godt?',
'case_ocr_pending' => 'I kø',
'case_ocr_running' => 'OCR pågår',
'case_ocr_ready' => 'Klar',
'case_ocr_failed' => 'Feilet',
'case_free_gate_title' => 'Min Sak — bygg din egen sak',
'case_free_gate_pitch' => 'Last opp dokumentene fra saken din én gang, og la alle verktøyene jobbe på din private korpus.',
'case_free_gate_b1' => '📄 Privat dokumentbank med OCR',
'case_free_gate_b2' => '🔍 Hybrid søk (BM25 + vektor) i din sak',
'case_free_gate_b3' => '🧠 Alle verktøy kan referere til din egen sak',
'case_free_gate_b4' => '🇪🇺 Alt lagres i EU (Tyskland/Finland/Norge)',
'case_free_gate_cta' => 'Se planer fra NOK 129/mo',
'sec_analyses' => 'Lagrede analyser',
'analyses_lede' => 'Alle resultater fra Korrespondanse, Advokat, BVJ, Dyp analyse, Motstrid og Tidslinje samles her — klar til å gjenåpnes, kjøres på nytt eller eksporteres.',
'no_analyses' => 'Ingen lagrede analyser ennå. Kjør et verktøy for å lagre din første.',
'used_case_badge' => 'Bruk min sak',
'pinned_title' => 'Festet',
'pin' => 'Fest',
'unpin' => 'Løsne',
'open_analysis' => 'Åpne',
'delete_analysis' => 'Slett',
'confirm_delete_analysis' => 'Slette denne analysen for godt?',
'pin_failed' => 'Festing feilet.',
'sec_usage' => 'Nylig bruk (siste 25)',
'usage_col_tool' => 'Verktøy / hendelse',
'usage_col_credits' => 'Kreditter',
'usage_col_when' => 'Tidspunkt',
'no_usage' => 'Ingen bruk registrert ennå.',
'sec_mcp' => 'Utviklere & MCP',
'mcp_desc' => 'Koble Claude Desktop, Claude Code, Cursor eller annen MCP-klient til hele verktøysuiten.',
'mcp_token_lbl' => 'API-token',
'mcp_no_token' => 'Ingen aktiv token',
'mcp_stdio_lbl' => 'Claude Desktop / Claude Code (stdio)',
'mcp_remote_lbl' => 'Ekstern HTTP — Cursor, Zed, Windsurf',
'mcp_copy' => 'Kopier',
'mcp_manage' => 'Administrer tokens →',
'mcp_full_setup' => 'Full oppsettsguide & token-administrasjon →',
'mcp_locked' => 'MCP-tokens krever Plus eller Pro — oppgrader for å koble til AI-klienter.',
'mcp_loading' => 'Laster…',
],
'uk' => [
'page_title' => 'Мій обліковий запис',
'page_lede' => 'План, профіль, сховище справ, аналізи, використання та доступ MCP — все в одному місці.',
'signed_in_as' => 'Ввійшли як',
'jump_plan' => 'План',
'jump_profile' => 'Профіль',
'jump_workspace' => 'Робочий простір',
'jump_case' => 'Моя справа',
'jump_analyses' => 'Збережені аналізи',
'jump_usage' => 'Використання',
'jump_mcp' => 'MCP',
'trial_badge' => 'Пробний — %d дн. залишилось',
'sec_plan' => 'План і кредити',
'current_plan' => 'Поточний план',
'renews_on' => 'Поновлюється',
'no_active_sub' => 'Немає активної підписки.',
'see_plans' => 'Переглянути всі плани',
'available_credits' => 'Доступні кредити',
'monthly' => 'місячних',
'prepaid' => 'передоплачених',
'manage_subscription'=> 'Керувати підпискою',
'upgrade_plan' => 'Покращити план',
'top_up_credits' => 'Поповнити кредити',
'payment_confirmed' => 'Платіж підтверджено. Якщо ви щойно підписалися, оновлення облікового запису може зайняти кілька секунд.',
'bonus_survey_title' => 'Бонусні кредити (опитування)',
'bonus_survey_done' => '✓ Ви вже отримали 25 бонусних кредитів за заповнення опитування.',
'bonus_survey_pitch' => 'Дайте відповідь на 5 коротких запитань про ваші потреби та отримайте 25 бонусних кредитів — без терміну дії.',
'take_survey_btn' => 'Пройти опитування',
'portal_loading' => 'З\'єднання…',
'portal_error' => 'Не вдалося відкрити портал.',
'network_error' => 'Помилка мережі: ',
'sec_profile' => 'Дані профілю',
'profile_optional' => 'Необов\'язково',
'f_display_name' => 'Ім\'я для показу',
'f_phone' => 'Телефон',
'f_address_1' => 'Адреса, рядок 1',
'f_address_2' => 'Адреса, рядок 2',
'f_postal' => 'Поштовий індекс',
'f_city' => 'Місто',
'f_region' => 'Регіон',
'f_country' => 'Країна',
'save_profile' => 'Зберегти профіль',
'profile_saving' => 'Збереження…',
'profile_saved' => 'Збережено',
'profile_error_default' => 'Не вдалося зберегти профіль',
'sec_workspace' => 'Доступ до робочого простору',
'w_email' => 'Email',
'w_seats' => 'Місця',
'w_role' => 'Роль',
'w_owner' => 'Власник',
'w_plan_storage' => 'Сховище плану',
'w_seats_single' => 'Робочий простір на одного користувача',
'w_upgrade_for_storage' => 'Оновіть для сховища «Моя справа»',
'sec_case' => 'Моя справа',
'case_lede' => 'Завантажте документи вашої справи один раз. Усі інструменти зможуть посилатися на вашу приватну справу, коли ви поставите галочку «Використати мою справу як контекст».',
'case_storage' => 'Сховище',
'case_documents_count' => '%d документів',
'case_drop_pdf' => 'Перетягніть PDF-файли сюди або клацніть, щоб вибрати',
'case_hint' => 'Макс. 25 МБ на файл · OCR запускається автоматично · все зберігається зашифрованим у ЄС',
'case_no_docs' => 'Поки що немає документів. Завантажте перший PDF вище.',
'case_uploaded_ok' => 'Завантажено: %s. OCR починається автоматично.',
'case_over_25mb' => '%s перевищує 25 МБ — розділіть файл спочатку.',
'case_unknown_err' => 'Невідома помилка',
'case_delete_failed' => 'Видалення не вдалося.',
'case_pages' => 'стор.',
'case_uploaded_label' => 'завантажено',
'case_delete' => 'Видалити',
'case_confirm_delete' => 'Видалити цей документ назавжди?',
'case_ocr_pending' => 'У черзі',
'case_ocr_running' => 'OCR виконується',
'case_ocr_ready' => 'Готово',
'case_ocr_failed' => 'Не вдалося',
'case_free_gate_title' => 'Моя справа — побудуйте власну справу',
'case_free_gate_pitch' => 'Завантажте документи з вашої справи один раз, і нехай усі інструменти працюють з вашим приватним корпусом.',
'case_free_gate_b1' => '📄 Приватний банк документів з OCR',
'case_free_gate_b2' => '🔍 Гібридний пошук (BM25 + вектор) у вашій справі',
'case_free_gate_b3' => '🧠 Усі інструменти можуть посилатися на вашу справу',
'case_free_gate_b4' => '🇪🇺 Усе зберігається в ЄС (Німеччина/Фінляндія/Норвегія)',
'case_free_gate_cta' => 'Переглянути плани від NOK 129/міс',
'sec_analyses' => 'Збережені аналізи',
'analyses_lede' => 'Усі результати з Кореспонденції, Адвоката, BVJ, Глибокого аналізу, Розбіжностей і Хронології збираються тут — готові до повторного відкриття, перезапуску чи експорту.',
'no_analyses' => 'Поки що немає збережених аналізів. Запустіть інструмент, щоб зберегти перший.',
'used_case_badge' => 'Моя справа',
'pinned_title' => 'Закріплено',
'pin' => 'Закріпити',
'unpin' => 'Відкріпити',
'open_analysis' => 'Відкрити',
'delete_analysis' => 'Видалити',
'confirm_delete_analysis' => 'Видалити цей аналіз назавжди?',
'pin_failed' => 'Закріпити не вдалося.',
'sec_usage' => 'Нещодавнє використання (останні 25)',
'usage_col_tool' => 'Інструмент / подія',
'usage_col_credits' => 'Кредити',
'usage_col_when' => 'Коли',
'no_usage' => 'Використання ще не зареєстровано.',
'sec_mcp' => 'Розробники та MCP',
'mcp_desc' => 'Підключайте Claude Desktop, Claude Code, Cursor або будь-який MCP-клієнт до повного набору інструментів.',
'mcp_token_lbl' => 'API-токен',
'mcp_no_token' => 'Немає активного токена',
'mcp_stdio_lbl' => 'Claude Desktop / Claude Code (stdio)',
'mcp_remote_lbl' => 'Віддалений HTTP — Cursor, Zed, Windsurf',
'mcp_copy' => 'Копіювати',
'mcp_manage' => 'Керувати токенами →',
'mcp_full_setup' => 'Повна документація та управління токенами →',
'mcp_locked' => 'MCP-токени потребують Plus або Pro — оновіться для підключення AI-клієнтів.',
'mcp_loading' => 'Завантаження…',
],
'pl' => [
'page_title' => 'Moje konto',
'page_lede' => 'Plan, profil, magazyn sprawy, analizy, użycie i dostęp MCP — wszystko w jednym miejscu.',
'signed_in_as' => 'Zalogowany jako',
'jump_plan' => 'Plan',
'jump_profile' => 'Profil',
'jump_workspace' => 'Obszar roboczy',
'jump_case' => 'Moja sprawa',
'jump_analyses' => 'Zapisane analizy',
'jump_usage' => 'Użycie',
'jump_mcp' => 'MCP',
'trial_badge' => 'Próba — %d dni pozostało',
'sec_plan' => 'Plan i kredyty',
'current_plan' => 'Bieżący plan',
'renews_on' => 'Odnawia się',
'no_active_sub' => 'Brak aktywnej subskrypcji.',
'see_plans' => 'Zobacz wszystkie plany',
'available_credits' => 'Dostępne kredyty',
'monthly' => 'miesięcznych',
'prepaid' => 'przedpłaconych',
'manage_subscription'=> 'Zarządzaj subskrypcją',
'upgrade_plan' => 'Ulepsz plan',
'top_up_credits' => 'Doładuj kredyty',
'payment_confirmed' => 'Płatność potwierdzona. Jeśli właśnie wykupiono subskrypcję, aktualizacja konta może potrwać kilka sekund.',
'bonus_survey_title' => 'Kredyty bonusowe (ankieta)',
'bonus_survey_done' => '✓ Otrzymałeś już 25 kredytów bonusowych za wypełnienie ankiety.',
'bonus_survey_pitch' => 'Odpowiedz na 5 krótkich pytań o swoje potrzeby i otrzymaj 25 kredytów bonusowych — nigdy nie wygasają.',
'take_survey_btn' => 'Wypełnij ankietę',
'portal_loading' => 'Łączenie…',
'portal_error' => 'Nie można otworzyć portalu.',
'network_error' => 'Błąd sieci: ',
'sec_profile' => 'Dane profilu',
'profile_optional' => 'Opcjonalne',
'f_display_name' => 'Nazwa wyświetlana',
'f_phone' => 'Telefon',
'f_address_1' => 'Adres linia 1',
'f_address_2' => 'Adres linia 2',
'f_postal' => 'Kod pocztowy',
'f_city' => 'Miasto',
'f_region' => 'Region',
'f_country' => 'Kraj',
'save_profile' => 'Zapisz profil',
'profile_saving' => 'Zapisywanie…',
'profile_saved' => 'Zapisano',
'profile_error_default' => 'Nie udało się zapisać profilu',
'sec_workspace' => 'Dostęp do obszaru roboczego',
'w_email' => 'Email',
'w_seats' => 'Miejsca',
'w_role' => 'Rola',
'w_owner' => 'Właściciel',
'w_plan_storage' => 'Magazyn planu',
'w_seats_single' => 'Obszar roboczy jednoosobowy',
'w_upgrade_for_storage' => 'Ulepsz, aby uzyskać magazyn Mojej sprawy',
'sec_case' => 'Moja sprawa',
'case_lede' => 'Prześlij dokumenty swojej sprawy raz. Wszystkie narzędzia mogą się do nich odwoływać, gdy zaznaczysz „Użyj mojej sprawy jako kontekstu".',
'case_storage' => 'Magazyn',
'case_documents_count' => '%d dokumentów',
'case_drop_pdf' => 'Upuść pliki PDF tutaj lub kliknij, aby przeglądać',
'case_hint' => 'Maks. 25 MB na plik · OCR działa automatycznie · wszystko przechowywane zaszyfrowane w UE',
'case_no_docs' => 'Brak dokumentów. Prześlij swój pierwszy PDF powyżej.',
'case_uploaded_ok' => 'Przesłano: %s. OCR rozpoczyna się automatycznie.',
'case_over_25mb' => '%s przekracza 25 MB — najpierw podziel plik.',
'case_unknown_err' => 'Nieznany błąd',
'case_delete_failed' => 'Usuwanie nie powiodło się.',
'case_pages' => 'stron',
'case_uploaded_label' => 'przesłano',
'case_delete' => 'Usuń',
'case_confirm_delete' => 'Usunąć ten dokument na zawsze?',
'case_ocr_pending' => 'W kolejce',
'case_ocr_running' => 'OCR w toku',
'case_ocr_ready' => 'Gotowe',
'case_ocr_failed' => 'Nieudane',
'case_free_gate_title' => 'Moja sprawa — zbuduj własną sprawę',
'case_free_gate_pitch' => 'Prześlij dokumenty swojej sprawy raz i pozwól wszystkim narzędziom pracować na Twoim prywatnym korpusie.',
'case_free_gate_b1' => '📄 Prywatny bank dokumentów z OCR',
'case_free_gate_b2' => '🔍 Wyszukiwanie hybrydowe (BM25 + wektor) w Twojej sprawie',
'case_free_gate_b3' => '🧠 Wszystkie narzędzia mogą odwoływać się do Twojej sprawy',
'case_free_gate_b4' => '🇪🇺 Wszystko przechowywane w UE (Niemcy/Finlandia/Norwegia)',
'case_free_gate_cta' => 'Zobacz plany od NOK 129/mies',
'sec_analyses' => 'Zapisane analizy',
'analyses_lede' => 'Wszystkie wyniki z Korespondencji, Adwokata, BVJ, Głębokiej analizy, Rozbieżności i Osi czasu zbierają się tutaj — gotowe do ponownego otwarcia, uruchomienia lub eksportu.',
'no_analyses' => 'Brak zapisanych analiz. Uruchom narzędzie, aby zapisać pierwszą.',
'used_case_badge' => 'Moja sprawa',
'pinned_title' => 'Przypięte',
'pin' => 'Przypnij',
'unpin' => 'Odepnij',
'open_analysis' => 'Otwórz',
'delete_analysis' => 'Usuń',
'confirm_delete_analysis' => 'Usunąć tę analizę na zawsze?',
'pin_failed' => 'Przypinanie nie powiodło się.',
'sec_usage' => 'Ostatnie użycie (ostatnie 25)',
'usage_col_tool' => 'Narzędzie / zdarzenie',
'usage_col_credits' => 'Kredyty',
'usage_col_when' => 'Kiedy',
'no_usage' => 'Nie zarejestrowano jeszcze użycia.',
'sec_mcp' => 'Deweloperzy i MCP',
'mcp_desc' => 'Podłącz Claude Desktop, Claude Code, Cursor lub dowolnego klienta MCP do pełnego zestawu narzędzi.',
'mcp_token_lbl' => 'Token API',
'mcp_no_token' => 'Brak aktywnego tokenu',
'mcp_stdio_lbl' => 'Claude Desktop / Claude Code (stdio)',
'mcp_remote_lbl' => 'Zdalny HTTP — Cursor, Zed, Windsurf',
'mcp_copy' => 'Kopiuj',
'mcp_manage' => 'Zarządzaj tokenami →',
'mcp_full_setup' => 'Pełna dokumentacja i zarządzanie tokenami →',
'mcp_locked' => 'Tokeny MCP wymagają Plus lub Pro — zaktualizuj, aby połączyć klientów AI.',
'mcp_loading' => 'Ładowanie…',
],
];
$l = $L[$uiLang] ?? $L['en'];
$seatsLabel = $seatLimit > 1 ? '1 / ' . $seatLimit : $l['w_seats_single'];
$dateLocale = match ($uiLang) {
'no' => 'j. F Y',
default => 'j M Y',
};
?>
= htmlspecialchars($l['page_title']) ?> — Do Better Norge
= htmlspecialchars($l['jump_plan']) ?>
= htmlspecialchars($l['jump_profile']) ?>
= htmlspecialchars($l['jump_workspace']) ?>
= htmlspecialchars($l['jump_case']) ?>
= htmlspecialchars($l['jump_analyses']) ?>
= htmlspecialchars($l['jump_usage']) ?>
= htmlspecialchars($l['jump_mcp']) ?>
= htmlspecialchars($l['payment_confirmed']) ?>
= htmlspecialchars($l['sec_plan']) ?>
= htmlspecialchars($l['current_plan']) ?>
= htmlspecialchars($tierLabel[0]) ?>
= htmlspecialchars(sprintf($l['trial_badge'], (int)$detail['trial_days_remaining'])) ?>
= htmlspecialchars($l['renews_on']) ?>: = htmlspecialchars(date($dateLocale, strtotime((string)$detail['subscription_period_end']))) ?>
= htmlspecialchars($l['no_active_sub']) ?> = htmlspecialchars($l['see_plans']) ?>
= htmlspecialchars($l['available_credits']) ?>
= number_format($effective, 0, ',', ' ') ?>
= (int)$detail['balance'] ?> = htmlspecialchars($l['monthly']) ?>
· = (int)$detail['bonus_balance'] ?> = htmlspecialchars($l['prepaid']) ?>
= htmlspecialchars($l['bonus_survey_title']) ?>
= htmlspecialchars($l['bonus_survey_done']) ?>
= htmlspecialchars($l['bonus_survey_pitch']) ?>
= htmlspecialchars($l['sec_profile']) ?>
= htmlspecialchars($l['profile_optional']) ?>
= htmlspecialchars($l['sec_workspace']) ?>
= htmlspecialchars($tierLabel[0]) ?>
= htmlspecialchars($l['w_email']) ?>
= htmlspecialchars($email) ?>
= htmlspecialchars($l['w_seats']) ?>
= htmlspecialchars($seatsLabel) ?>
= htmlspecialchars($l['w_role']) ?>
= htmlspecialchars($l['w_owner']) ?>
= htmlspecialchars($l['w_plan_storage']) ?>
= $isPaidTier ? htmlspecialchars($quotaMb . ' MB') : htmlspecialchars($l['w_upgrade_for_storage']) ?>
= htmlspecialchars($l['sec_case']) ?>
= $l['case_free_gate_pitch'] /* contains */ ?>
= htmlspecialchars($l['case_free_gate_b1']) ?>
= htmlspecialchars($l['case_free_gate_b2']) ?>
= htmlspecialchars($l['case_free_gate_b3']) ?>
= htmlspecialchars($l['case_free_gate_b4']) ?>
= htmlspecialchars($l['case_lede']) ?>
= htmlspecialchars($l['case_storage']) ?>
= $storageMb ?> MB / = $quotaMb ?> MB
= htmlspecialchars(sprintf($l['case_documents_count'], count($docs))) ?>
= htmlspecialchars($l['current_plan']) ?>
= htmlspecialchars($tierLabel[0]) ?>
= htmlspecialchars(sprintf($l['trial_badge'], (int)$detail['trial_days_remaining'])) ?>
📤
= htmlspecialchars($l['case_drop_pdf']) ?>
= htmlspecialchars($l['case_hint']) ?>
= htmlspecialchars($l['case_no_docs']) ?>
📄
= htmlspecialchars($d['filename']) ?>
= round((int)$d['size_bytes'] / 1024, 0) ?> KB
· = (int)$d['page_count'] ?> = htmlspecialchars($l['case_pages']) ?>
· = htmlspecialchars($d['doc_type']) ?>
· = htmlspecialchars($l['case_uploaded_label']) ?> = htmlspecialchars(date($dateLocale, strtotime((string)$d['uploaded_at']))) ?>
= htmlspecialchars($l[$ocrKey] ?? $d['ocr_status']) ?>
= htmlspecialchars($l['case_delete']) ?>
= htmlspecialchars($l['sec_analyses']) ?>
= htmlspecialchars($l['analyses_lede']) ?>
= htmlspecialchars($l['no_analyses']) ?>
= htmlspecialchars(CaseResults::toolIcon((string)$r['tool'])) ?>
= htmlspecialchars(CaseResults::toolLabel((string)$r['tool'])) ?>
· = htmlspecialchars(date($dateLocale . ' H:i', strtotime((string)$r['created_at']))) ?>
· = htmlspecialchars($l['used_case_badge']) ?>
= htmlspecialchars($l['sec_usage']) ?>
= htmlspecialchars($l['no_usage']) ?>
= htmlspecialchars($l['usage_col_tool']) ?>
= htmlspecialchars($l['usage_col_credits']) ?>
= htmlspecialchars($l['usage_col_when']) ?>
= htmlspecialchars($r['tool']) ?>
= $credits < 0 ? '+' . abs($credits) : '−' . $credits ?>
= htmlspecialchars((string)$r['created_at']) ?>
= htmlspecialchars($l['sec_mcp']) ?>
= htmlspecialchars($l['mcp_desc']) ?>
= htmlspecialchars($l['mcp_stdio_lbl']) ?>
claude mcp add dobetternorge -- npx -y @bluenotelogic/mcp dobetternorge-mcp --stdio
# Set token (add to ~/.bashrc or ~/.zshrc to persist):
export DBN_MCP_TOKEN=dbn_user_mcp_…
= htmlspecialchars($l['mcp_copy']) ?>
= htmlspecialchars($l['mcp_remote_lbl']) ?>
URL: https://mcp.dobetternorge.no/mcp
Authorization: Bearer dbn_user_mcp_…
= htmlspecialchars($l['mcp_copy']) ?>
= htmlspecialchars($l['mcp_full_setup']) ?>
= htmlspecialchars($l['sec_mcp']) ?>