Index: src/config/database.js
===================================================================
--- src/config/database.js	(revision eb5f978375e885d17090a8dedb24802dda9a52b4)
+++ src/config/database.js	(revision 5f483e38e1f3f8ccca8ba962aaacb14f4d06f7a3)
@@ -163,46 +163,4 @@
   `);
 
-  // ── Circles (federation) ────────────────────────────────────
-  // Decentralised, asymmetric connections between solo instances.
-  db.exec(`
-    CREATE TABLE IF NOT EXISTS circle_links (
-      id TEXT PRIMARY KEY,
-      local_site_id TEXT NOT NULL,
-      remote_url TEXT NOT NULL,
-      remote_actor_id TEXT,
-      label TEXT,
-      status TEXT DEFAULT 'active',
-      added_at DATETIME DEFAULT CURRENT_TIMESTAMP,
-      last_synced DATETIME,
-      last_error TEXT,
-      UNIQUE(local_site_id, remote_url),
-      FOREIGN KEY (local_site_id) REFERENCES sites(id)
-    );
-    CREATE TABLE IF NOT EXISTS remote_actors (
-      id TEXT PRIMARY KEY,
-      url TEXT UNIQUE NOT NULL,
-      name TEXT,
-      summary TEXT,
-      avatar TEXT,
-      public_key TEXT NOT NULL,
-      fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP
-    );
-    CREATE TABLE IF NOT EXISTS remote_posts (
-      id TEXT PRIMARY KEY,
-      actor_id TEXT NOT NULL,
-      published DATETIME,
-      title TEXT,
-      summary TEXT,
-      url TEXT,
-      media_json TEXT,
-      raw_json TEXT,
-      fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP,
-      FOREIGN KEY (actor_id) REFERENCES remote_actors(id)
-    );
-  `);
-
-  // Tags from the original post — shown in the circle feed (comma-separated string).
-  ensureColumn('remote_posts', 'tags', 'TEXT');
-
   // Newsletter / mailing list (premium). Subscribers per site; double opt-in when SMTP
   // is configured (status 'pending' until confirmed), otherwise single opt-in ('confirmed').
@@ -252,33 +210,4 @@
   `);
 
-  // Notifications: someone replies to your comment / post, or likes your post. Snapshots
-  // of name/title so the list can be shown cheaply without joins.
-  // NB: deliberately named 'user_notifications' — some older DBs still have a stale,
-  // unused 'notifications' table with a different schema (no read column).
-  db.exec(`
-    CREATE TABLE IF NOT EXISTS user_notifications (
-      id TEXT PRIMARY KEY,
-      user_id TEXT NOT NULL,
-      type TEXT NOT NULL,
-      actor_id TEXT,
-      actor_name TEXT,
-      post_slug TEXT,
-      post_title TEXT,
-      url TEXT,
-      read INTEGER DEFAULT 0,
-      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
-    );
-  `);
-  // Older DBs may have a user_notifications table predating these columns — add
-  // them before the index (which references `read`), else boot crashes.
-  ensureColumn('user_notifications', 'type', 'TEXT');
-  ensureColumn('user_notifications', 'actor_id', 'TEXT');
-  ensureColumn('user_notifications', 'actor_name', 'TEXT');
-  ensureColumn('user_notifications', 'post_slug', 'TEXT');
-  ensureColumn('user_notifications', 'post_title', 'TEXT');
-  ensureColumn('user_notifications', 'url', 'TEXT');
-  ensureColumn('user_notifications', 'read', 'INTEGER DEFAULT 0');
-  db.exec('CREATE INDEX IF NOT EXISTS idx_unotif_user ON user_notifications(user_id, read, created_at);');
-
   // Link-in-bio click statistics (premium #6). One counter per (site, url); the
   // link-in-bio page links via /links/go/:i which counts the click and redirects.
@@ -293,17 +222,4 @@
   `);
 
-  // Likes / favourites: a logged-in user can like a post. The set of
-  // posts a user liked = their favourites (/favorieten page). One row
-  // per (post, user); unique so that liking is idempotent.
-  db.exec(`
-    CREATE TABLE IF NOT EXISTS post_likes (
-      post_id TEXT NOT NULL,
-      user_id TEXT NOT NULL,
-      created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
-      PRIMARY KEY (post_id, user_id)
-    );
-    CREATE INDEX IF NOT EXISTS idx_post_likes_user ON post_likes(user_id, created_at);
-    CREATE INDEX IF NOT EXISTS idx_post_likes_post ON post_likes(post_id);
-  `);
 
   // ── ActivityPub (fediverse bridge) ──────────────────────────
Index: src/routes/notifications.js
===================================================================
--- src/routes/notifications.js	(revision eb5f978375e885d17090a8dedb24802dda9a52b4)
+++ 	(revision )
@@ -1,23 +1,0 @@
-/**
- * GET /notifications — notifications page for the logged-in user.
- * Opening it marks everything as read (the counter in the header disappears).
- */
-import express from 'express';
-import { requireAuth } from '../middleware/auth.js';
-import { renderPage } from '../middleware/render.js';
-import { list, markAllRead } from '../services/NotificationService.js';
-
-const router = express.Router();
-
-router.get('/', requireAuth, (req, res) => {
-  const uid = req.session.user.id;
-  const items = list(uid, 50);
-  markAllRead(uid);
-  renderPage(req, res, 'pages/notifications', {
-    pageTitle: 'Meldingen',
-    bodyClass: 'on-special',
-    items,
-  });
-});
-
-export default router;
Index: src/services/NotificationService.js
===================================================================
--- src/services/NotificationService.js	(revision eb5f978375e885d17090a8dedb24802dda9a52b4)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/**
- * Notifications — reply to your comment, comment on your post, like on your post.
- * For every logged-in user (Google visitors/fans and admins). Snapshots of
- * actor name + post title so the list can be rendered without joins.
- */
-import { randomUUID } from 'crypto';
-import db from '../config/database.js';
-
-// Creates a notification. Does nothing if there is no recipient or if you
-// would notify yourself (your own comment/like on your own post/comment).
-export function notify({ userId, actorId, actorName, type, postSlug, postTitle, url }) {
-  if (!userId || userId === actorId) return;
-  try {
-    db.prepare(`
-      INSERT INTO user_notifications (id, user_id, type, actor_id, actor_name, post_slug, post_title, url, read)
-      VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)
-    `).run(randomUUID(), userId, type, actorId || null, actorName || null, postSlug || null, postTitle || null, url || null);
-  } catch { /* notifications are non-fatal */ }
-}
-
-export function unreadCount(userId) {
-  if (!userId) return 0;
-  try { return db.prepare('SELECT COUNT(*) AS c FROM user_notifications WHERE user_id = ? AND read = 0').get(userId).c; }
-  catch { return 0; }
-}
-
-export function list(userId, limit = 50) {
-  if (!userId) return [];
-  try { return db.prepare('SELECT * FROM user_notifications WHERE user_id = ? ORDER BY created_at DESC LIMIT ?').all(userId, limit); }
-  catch { return []; }
-}
-
-export function markAllRead(userId) {
-  if (!userId) return;
-  try { db.prepare('UPDATE user_notifications SET read = 1 WHERE user_id = ? AND read = 0').run(userId); } catch { /* no-op */ }
-}
-
-export default { notify, unreadCount, list, markAllRead };
Index: src/services/i18n.js
===================================================================
--- src/services/i18n.js	(revision eb5f978375e885d17090a8dedb24802dda9a52b4)
+++ src/services/i18n.js	(revision 5f483e38e1f3f8ccca8ba962aaacb14f4d06f7a3)
@@ -69,5 +69,5 @@
     'admin.b_makesite': '🎨 Maak je site aan', 'admin.b_circle': '🔗 Cirkel', 'admin.b_stats': '📊 Statistieken',
     'admin.b_newsletter': '✉️ Nieuwsbrief', 'admin.b_perskit': '📰 Perskit', 'admin.b_downloads': '⬇ Downloads',
-    'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 'admin.b_google': '🔑 Google',
+    'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda',
     'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Handleiding', 'admin.b_fediverse': 'Mijn reacties',
     'admin.st_users': 'Gebruikers', 'admin.st_sites': 'Sites', 'admin.st_posts': 'Posts', 'admin.st_published': 'Gepubliceerd',
@@ -87,9 +87,7 @@
     'auth.password': 'Wachtwoord',
     'auth.forgot': 'Wachtwoord vergeten?',
-    'auth.google_btn': 'Inloggen met Google',
     'auth.public_sub': 'Log in om te reageren en je favorieten te bewaren.',
     'auth.admin_box_q': 'Beheerder?',
     'auth.admin_box_sub': 'Log in met gebruikersnaam & wachtwoord',
-    'auth.google_unavail': 'Inloggen met Google is op deze site nog niet ingesteld.',
     'auth.create_admin': 'Beheerder aanmaken',
     'auth.reg_intro': 'Eerste keer opzetten — maak je beheerdersaccount aan. Dit kan maar één keer.',
@@ -138,17 +136,10 @@
     'aset.solo': 'Solo',
     'aset.solo_title': 'één site (de jouwe).',
-    'aset.solo_desc': 'Geen gebruikers-directory, geen site-wissel. Bezoekers kunnen wel met Google inloggen om te reageren.',
-    'aset.hub': 'Hub',
-    'aset.hub_title': 'bedrijfssite met',
+    'aset.solo_desc': 'Geen gebruikers-directory, geen site-wissel.',
     'aset.premium_badge': 'premium',
-    'aset.hub_desc': 'Jij (admin) wijst gebruikers een eigen Klonkt Hub toe. Gesloten cirkel: geen open registratie.',
-    'aset.hub_locked_note': 'Vereist premium — koppel Patreon in deze pagina.',
     'aset.circle': 'Cirkels',
     'aset.circle_title': 'solo + federatie.',
     'aset.circle_desc': 'Eén eigen site die de publieke posts van andere Klonkt-sites toont. Asymmetrisch: jij bepaalt wie in jouw cirkel zit.',
     'aset.save': 'Opslaan',
-    'aset.hub_home': 'Hub-hoofdpagina',
-    'aset.hub_home_help_1': 'De openbare hub-pagina',
-    'aset.hub_home_help_2': 'is generiek — van geen enkele gebruiker. Hier stel je de naam en intro in. Jouw eigen Klonkt Hub blijft los bestaan onder',
     'aset.name': 'Naam',
     'aset.name_ph': 'bijv. Studio Noord',
@@ -181,9 +172,6 @@
     'aset.patreon_not_connected': 'Nog niet gekoppeld.',
     'aset.patreon_connect': 'Koppel Patreon',
-    'aset.google_login': 'Google-login (bezoekers)',
-    'aset.google_login_help': 'Laat bezoekers met Google inloggen om te reageren — met je eigen Google Cloud-client.',
     'aset.status_set': 'Status: ingesteld',
     'aset.not_set_yet': 'Nog niet ingesteld.',
-    'aset.google_login_setup': 'Google-login instellen',
     'aset.newsletter': 'Nieuwsbrief',
     'aset.newsletter_help_1': 'Toon een',
@@ -254,6 +242,4 @@
     'asite.moderation_moderate': 'Modereren (eerst in de wachtrij)',
     'asite.enable_audio': 'Audiospeler + embeds inschakelen',
-    'asite.enable_prutter': 'Prutter (DM&rsquo;s tussen leden) inschakelen',
-    'asite.enable_prutter_hint': '— Hub-functie, premium',
     'asite.links': 'Social / streaming-links',
     'asite.links_hint': 'Getoond als merk-iconen op de profielkop. Voeg er zoveel toe als je wilt.',
@@ -322,68 +308,4 @@
     'aseo.verify_yandex': 'Yandex',
     'aseo.save': 'SEO opslaan',
-    'agoog.title': 'Google-login',
-    'agoog.intro': 'Hiermee kunnen bezoekers met hun <strong>Google-account</strong> inloggen om te reageren. Je stelt dit één keer in met je eigen (gratis) Google-account — zo\'n 5 minuten, geen creditcard of betaalde dienst nodig.',
-    'agoog.g1': 'Open de Google Cloud Console en log in. Maak bovenaan een <strong>nieuw project</strong> (Project selecteren → Nieuw project), geef het een naam en klik op <strong>Maken</strong>.',
-    'agoog.g2': 'Ga in het menu links naar <strong>APIs en services → OAuth-toestemmingsscherm</strong>. Kies <strong>Extern</strong>, vul de app-naam + je e-mail in en sla op. Vraagt het systeem om testgebruikers? Voeg dan jezelf toe.',
-    'agoog.g3': 'Ga naar <strong>APIs en services → Inloggegevens → Inloggegevens maken → OAuth-client-ID</strong> en kies als type <strong>Webapplicatie</strong>.',
-    'agoog.g4': 'Plak bij <strong>Geautoriseerde omleidings-URI\'s</strong> exact dit adres en klik op <strong>Maken</strong>:',
-    'agoog.g5': 'Google toont nu een <strong>Client-ID</strong> en <strong>Client-secret</strong>. Kopieer die naar de velden hieronder en klik op <strong>Opslaan</strong>. Klaar!',
-    'agoog.copy': 'Kopieer',
-    'agoog.copied': 'Gekopieerd ✓',
-    'agoog.warn_short': 'Let op: moet <strong>exact</strong> kloppen — met <code>https://</code>, het juiste domein, en <strong>geen</strong> schuine streep aan het eind. Anders krijg je "Error 400: redirect_uri_mismatch".',
-    'agoog.need_baseurl': 'Stel eerst <code>PUBLIC_BASE_URL</code> in (de publieke URL van je site) — daar wordt dit adres van afgeleid.',
-    'agoog.no_api_note': '<strong>Tip:</strong> je hoeft géén API\'s aan te zetten (geen "People API" o.i.d.). Alleen het toestemmingsscherm + de OAuth-client zijn nodig.',
-    'agoog.back': 'Instellingen',
-    'agoog.card_title': 'Google-login (bezoekers)',
-    'agoog.card_help_pre': 'Laat bezoekers met Google inloggen om te reageren — met je',
-    'agoog.card_help_own': 'eigen',
-    'agoog.card_help_mid': 'Google Cloud-client. Maak er een aan op',
-    'agoog.card_help_post': '(OAuth client-ID, type "Web application").',
-    'agoog.status_set': 'Status: ingesteld&nbsp;✓',
-    'agoog.status_unset': 'Nog niet ingesteld.',
-    'agoog.guide_summary': 'Hoe stel ik dit in? (stap voor stap)',
-    'agoog.step1_pre': 'Ga naar de',
-    'agoog.step1_post': 'en maak (of kies) een project.',
-    'agoog.step2_usertype': 'User type',
-    'agoog.step2_scopes_pre': 'Voeg de scopes',
-    'agoog.step2_scopes_and': 'en',
-    'agoog.step2_scopes_post': 'toe.',
-    'agoog.step2_testmode': '(In testmodus: voeg jezelf toe als testgebruiker.)',
-    'agoog.step3_type': 'type',
-    'agoog.step4_pre': 'Bij',
-    'agoog.step4_post': ': plak de redirect-URI hieronder (moet exact matchen).',
-    'agoog.step5_pre': 'Kopieer de',
-    'agoog.step5_post': 'die je krijgt naar de velden hieronder en klik Opslaan.',
-    'agoog.note_label': 'Let op:',
-    'agoog.note_pre': 'je hoeft',
-    'agoog.note_noapi': 'geen API\'s aan te zetten',
-    'agoog.note_mid': '— "Google Cloud APIs", People API e.d. zijn',
-    'agoog.note_not': 'niet',
-    'agoog.note_post': 'nodig. Inloggen werkt via OpenID Connect (alleen het toestemmingsscherm + de OAuth-client).',
-    'agoog.redirect_label': 'Redirect-URI — kopieer deze en plak \'m in Google',
-    'agoog.rstep1_pre': 'Ga naar',
-    'agoog.rstep2': 'Open jouw OAuth client-ID (type "Web application").',
-    'agoog.rstep3_pre': 'Onder',
-    'agoog.rstep3_mid': 'klik',
-    'agoog.rstep3_post': 'en plak de regel hierboven.',
-    'agoog.rstep4_pre': 'Klik',
-    'agoog.rstep4_post': 'en wacht ~1 minuut.',
-    'agoog.warn_pre': 'Moet',
-    'agoog.warn_exact': 'exact',
-    'agoog.warn_mid1': 'kloppen:',
-    'agoog.warn_nohttp': 'geen',
-    'agoog.warn_mid2': ', juiste domein, en',
-    'agoog.warn_noslash': 'geen',
-    'agoog.warn_mid3': 'schuine streep aan het eind. Anders krijg je',
-    'agoog.warn_error': '"Error 400: redirect_uri_mismatch"',
-    'agoog.set_baseurl_pre': 'Stel eerst',
-    'agoog.set_baseurl_post': 'in — daar wordt de redirect-URI van afgeleid.',
-    'agoog.client_id': 'Client ID',
-    'agoog.client_secret': 'Client Secret',
-    'agoog.client_secret_set': 'ingesteld; leeg laten = ongewijzigd',
-    'agoog.secret_ph_set': '•••••••• (ingesteld)',
-    'agoog.save': 'Opslaan',
-    'agoog.disconnect': 'Loskoppelen',
-    'agoog.premium_locked': 'Premium-laag staat aan zonder Patreon — de Google-knop blijft verborgen tot premium ontgrendeld is.',
     'aaud.title': 'Audio tracks',
     'aaud.tagline_pre': 'MP3’s op site-niveau. Gebruik',
@@ -696,6 +618,4 @@
     'ahelp.s_premium_h': 'Premium / Patreon',
     'ahelp.s_premium_b': 'Premium-functies (Statistieken, Agenda, Downloads, Perskit, Nieuwsbrief, Link-in-bio, Embed) ontgrendel je in Beheer → Instellingen door Patreon te koppelen ($16 lifetime). Updates en de kernapp blijven altijd gratis.',
-    'ahelp.s_google_h': 'Google-login (bezoekers)',
-    'ahelp.s_google_b': 'Beheer → Instellingen → <strong>Google</strong>. Optioneel: laat bezoekers/fans met Google inloggen om te reageren. Jij beheert met je wachtwoord — Google geeft nooit beheerrechten. Vul je eigen Google-client-gegevens in (per site).',
     'ahelp.s_updates_h': 'Updates',
     'ahelp.s_updates_b': 'Beheer → <strong>Updates</strong> (alleen god) toont de huidige versie en of er een nieuwere is. Met "Nu bijwerken" haal je de laatste versie binnen.',
@@ -836,11 +756,6 @@
     'acct.password_min': '(min 8 tekens)',
     'acct.password_confirm': 'Bevestig nieuw wachtwoord',
-    'acct.google_login': 'Inloggen met Google',
-    'acct.google_linked': '✓ Je Google-account is gekoppeld — je kunt ook met Google inloggen.',
-    'acct.google_unlink': 'Google ontkoppelen',
-    'acct.google_link_hint': 'Koppel je Google-account zodat je voortaan ook met één klik via Google kunt inloggen (naast je wachtwoord).',
-    'acct.google_link': 'Koppel Google-account',
     'acct.login': 'Inloggen',
-    'acct.login_google_only': 'Je bent ingelogd via Google ({email}). Er is geen apart wachtwoord.',
+    'acct.login_google_only': 'Dit account heeft geen wachtwoord ({email}). Gebruik "Wachtwoord vergeten" om er een in te stellen.',
     'news.this_artist': 'deze artiest',
     'news.form_title': 'Blijf op de hoogte',
@@ -938,19 +853,4 @@
     'adir.page_info': 'Pagina {page} van {pages}',
     'adir.next': 'Volgende →',
-    'glog.admin_title': 'Dit is een beheerders-account',
-    'glog.admin_body': 'Je logde in met Google, maar dit e-mailadres hoort bij de beheerder van deze site. Inloggen met Google is alleen voor luisteraars/fans — beheerders gebruiken altijd hun wachtwoord (zo kan een Google-login nooit per ongeluk beheerrechten geven).',
-    'glog.admin_li1': '<strong>Ben je de beheerder?</strong> <a href="/auth/admin">Log in met je gebruikersnaam + wachtwoord</a>.',
-    'glog.admin_li2': '<strong>Wil je voortaan met Google inloggen?</strong> Log eerst in met wachtwoord en <strong>koppel je Google-account</strong> onder Account → daarna werkt Google-login ook voor jou.',
-    'glog.admin_li3': '<strong>Wil je als fan inloggen?</strong> Gebruik een <strong>ander Google-account</strong> (niet je beheerdersadres).',
-    'glog.session_title': 'Login afgebroken',
-    'glog.session_body': 'De Google-login is afgebroken of de sessie was verlopen. Probeer het gewoon opnieuw.',
-    'glog.email_title': 'Geen geverifieerd e-mailadres',
-    'glog.email_body': 'Je Google-account heeft geen geverifieerd e-mailadres. Verifieer je adres bij Google.',
-    'glog.linked_title': 'Adres al gekoppeld',
-    'glog.linked_body': 'Dit e-mailadres is al aan een ander Google-account gekoppeld. Gebruik dat account, of neem contact op met de beheerder.',
-    'glog.unavailable_title': 'Google-login niet beschikbaar',
-    'glog.unavailable_body': 'Inloggen met Google is op deze site (nog) niet ingesteld.',
-    'glog.failed_title': 'Google-login mislukt',
-    'glog.failed_body': 'Er ging iets mis bij het inloggen met Google. Probeer het opnieuw.',
     'pusr.post_one': 'post',
     'pusr.post_many': 'posts',
@@ -1088,5 +988,5 @@
     'admin.b_makesite': '🎨 Create your site', 'admin.b_circle': '🔗 Circle', 'admin.b_stats': '📊 Statistics',
     'admin.b_newsletter': '✉️ Newsletter', 'admin.b_perskit': '📰 Press kit', 'admin.b_downloads': '⬇ Downloads',
-    'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 'admin.b_google': '🔑 Google',
+    'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda',
     'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Manual', 'admin.b_fediverse': 'My replies',
     'admin.st_users': 'Users', 'admin.st_sites': 'Sites', 'admin.st_posts': 'Posts', 'admin.st_published': 'Published',
@@ -1104,9 +1004,7 @@
     'auth.password': 'Password',
     'auth.forgot': 'Forgot password?',
-    'auth.google_btn': 'Sign in with Google',
     'auth.public_sub': 'Log in to comment and save your favorites.',
     'auth.admin_box_q': 'Admin?',
     'auth.admin_box_sub': 'Log in with username & password',
-    'auth.google_unavail': 'Google sign-in isn’t set up on this site yet.',
     'auth.create_admin': 'Create admin',
     'auth.reg_intro': 'First-time setup — create your admin account. This can only be done once.',
@@ -1152,17 +1050,10 @@
     'aset.solo': 'Solo',
     'aset.solo_title': 'one site (yours).',
-    'aset.solo_desc': 'No user directory, no site switching. Visitors can still sign in with Google to comment.',
-    'aset.hub': 'Hub',
-    'aset.hub_title': 'company site with',
+    'aset.solo_desc': 'No user directory, no site switching.',
     'aset.premium_badge': 'premium',
-    'aset.hub_desc': 'You (the admin) assign users their own Klonkt Hub. Closed circle: no open registration.',
-    'aset.hub_locked_note': 'Requires premium — connect Patreon on this page.',
     'aset.circle': 'Circles',
     'aset.circle_title': 'solo + federation.',
     'aset.circle_desc': 'A single site of your own that shows the public posts of other Klonkt sites. Asymmetric: you decide who is in your circle.',
     'aset.save': 'Save',
-    'aset.hub_home': 'Hub home page',
-    'aset.hub_home_help_1': 'The public hub page',
-    'aset.hub_home_help_2': 'is generic — it belongs to no single user. Here you set the name and intro. Your own Klonkt Hub stays separate under',
     'aset.name': 'Name',
     'aset.name_ph': 'e.g. Studio Noord',
@@ -1195,9 +1086,6 @@
     'aset.patreon_not_connected': 'Not connected yet.',
     'aset.patreon_connect': 'Connect Patreon',
-    'aset.google_login': 'Google login (visitors)',
-    'aset.google_login_help': 'Let visitors sign in with Google to comment — using your own Google Cloud client.',
     'aset.status_set': 'Status: configured',
     'aset.not_set_yet': 'Not configured yet.',
-    'aset.google_login_setup': 'Set up Google login',
     'aset.newsletter': 'Newsletter',
     'aset.newsletter_help_1': 'Show a',
@@ -1268,6 +1156,4 @@
     'asite.moderation_moderate': 'Moderate (queue first)',
     'asite.enable_audio': 'Enable audio player + embeds',
-    'asite.enable_prutter': 'Enable Prutter (DMs between members)',
-    'asite.enable_prutter_hint': '— Hub feature, premium',
     'asite.links': 'Social / streaming links',
     'asite.links_hint': 'Shown as brand icons in the profile header. Add as many as you like.',
@@ -1336,68 +1222,4 @@
     'aseo.verify_yandex': 'Yandex',
     'aseo.save': 'Save SEO',
-    'agoog.title': 'Google login',
-    'agoog.intro': 'This lets visitors sign in with their <strong>Google account</strong> to comment. You set it up once with your own (free) Google account — about 5 minutes, no credit card or paid service needed.',
-    'agoog.g1': 'Open the Google Cloud Console and sign in. At the top, create a <strong>new project</strong> (Select project → New project), give it a name and click <strong>Create</strong>.',
-    'agoog.g2': 'In the left menu go to <strong>APIs & Services → OAuth consent screen</strong>. Choose <strong>External</strong>, fill in the app name + your email and save. If it asks for test users, add yourself.',
-    'agoog.g3': 'Go to <strong>APIs & Services → Credentials → Create credentials → OAuth client ID</strong> and choose type <strong>Web application</strong>.',
-    'agoog.g4': 'Under <strong>Authorized redirect URIs</strong> paste exactly this address and click <strong>Create</strong>:',
-    'agoog.g5': 'Google now shows a <strong>Client ID</strong> and <strong>Client secret</strong>. Copy them into the fields below and click <strong>Save</strong>. Done!',
-    'agoog.copy': 'Copy',
-    'agoog.copied': 'Copied ✓',
-    'agoog.warn_short': 'Note: it must match <strong>exactly</strong> — with <code>https://</code>, the correct domain, and <strong>no</strong> trailing slash. Otherwise you get "Error 400: redirect_uri_mismatch".',
-    'agoog.need_baseurl': 'First set <code>PUBLIC_BASE_URL</code> (the public URL of your site) — this address is derived from it.',
-    'agoog.no_api_note': '<strong>Tip:</strong> you do not need to enable any APIs (no "People API" etc.). Only the consent screen + the OAuth client are needed.',
-    'agoog.back': 'Settings',
-    'agoog.card_title': 'Google login (visitors)',
-    'agoog.card_help_pre': 'Let visitors log in with Google to comment — using your',
-    'agoog.card_help_own': 'own',
-    'agoog.card_help_mid': 'Google Cloud client. Create one at',
-    'agoog.card_help_post': '(OAuth client ID, type "Web application").',
-    'agoog.status_set': 'Status: configured&nbsp;✓',
-    'agoog.status_unset': 'Not configured yet.',
-    'agoog.guide_summary': 'How do I set this up? (step by step)',
-    'agoog.step1_pre': 'Go to the',
-    'agoog.step1_post': 'and create (or pick) a project.',
-    'agoog.step2_usertype': 'User type',
-    'agoog.step2_scopes_pre': 'Add the scopes',
-    'agoog.step2_scopes_and': 'and',
-    'agoog.step2_scopes_post': '.',
-    'agoog.step2_testmode': '(In testing mode: add yourself as a test user.)',
-    'agoog.step3_type': 'type',
-    'agoog.step4_pre': 'Under',
-    'agoog.step4_post': ': paste the redirect URI below (it must match exactly).',
-    'agoog.step5_pre': 'Copy the',
-    'agoog.step5_post': 'you receive into the fields below and click Save.',
-    'agoog.note_label': 'Note:',
-    'agoog.note_pre': 'you do',
-    'agoog.note_noapi': 'not need to enable any APIs',
-    'agoog.note_mid': '— "Google Cloud APIs", People API and the like are',
-    'agoog.note_not': 'not',
-    'agoog.note_post': 'required. Login works via OpenID Connect (just the consent screen + the OAuth client).',
-    'agoog.redirect_label': 'Redirect URI — copy this and paste it into Google',
-    'agoog.rstep1_pre': 'Go to',
-    'agoog.rstep2': 'Open your OAuth client ID (type "Web application").',
-    'agoog.rstep3_pre': 'Under',
-    'agoog.rstep3_mid': 'click',
-    'agoog.rstep3_post': 'and paste the line above.',
-    'agoog.rstep4_pre': 'Click',
-    'agoog.rstep4_post': 'and wait ~1 minute.',
-    'agoog.warn_pre': 'It must be',
-    'agoog.warn_exact': 'exactly',
-    'agoog.warn_mid1': 'right:',
-    'agoog.warn_nohttp': 'not',
-    'agoog.warn_mid2': ', the correct domain, and',
-    'agoog.warn_noslash': 'no',
-    'agoog.warn_mid3': 'trailing slash. Otherwise you get',
-    'agoog.warn_error': '"Error 400: redirect_uri_mismatch"',
-    'agoog.set_baseurl_pre': 'First set',
-    'agoog.set_baseurl_post': '— the redirect URI is derived from it.',
-    'agoog.client_id': 'Client ID',
-    'agoog.client_secret': 'Client Secret',
-    'agoog.client_secret_set': 'configured; leave blank to keep unchanged',
-    'agoog.secret_ph_set': '•••••••• (configured)',
-    'agoog.save': 'Save',
-    'agoog.disconnect': 'Disconnect',
-    'agoog.premium_locked': 'The premium tier is on without Patreon — the Google button stays hidden until premium is unlocked.',
     'aaud.title': 'Audio tracks',
     'aaud.tagline_pre': 'Site-level MP3s. Use',
@@ -1710,6 +1532,4 @@
     'ahelp.s_premium_h': 'Premium / Patreon',
     'ahelp.s_premium_b': 'You unlock premium features (Statistics, Agenda, Downloads, Press kit, Newsletter, Link-in-bio, Embed) in Admin → Settings by connecting Patreon ($16 lifetime). Updates and the core app always stay free.',
-    'ahelp.s_google_h': 'Google login (visitors)',
-    'ahelp.s_google_b': 'Admin → Settings → <strong>Google</strong>. Optional: let visitors/fans log in with Google to comment. You manage with your password — Google never grants admin rights. Enter your own Google client details (per site).',
     'ahelp.s_updates_h': 'Updates',
     'ahelp.s_updates_b': 'Admin → <strong>Updates</strong> (god only) shows the current version and whether a newer one is available. With "Update now" you fetch the latest version.',
@@ -1849,11 +1669,6 @@
     'acct.password_min': '(min 8 characters)',
     'acct.password_confirm': 'Confirm new password',
-    'acct.google_login': 'Sign in with Google',
-    'acct.google_linked': '✓ Your Google account is linked — you can also sign in with Google.',
-    'acct.google_unlink': 'Unlink Google',
-    'acct.google_link_hint': 'Link your Google account so you can also sign in with one click via Google (alongside your password).',
-    'acct.google_link': 'Link Google account',
     'acct.login': 'Sign in',
-    'acct.login_google_only': 'You are signed in via Google ({email}). There is no separate password.',
+    'acct.login_google_only': 'This account has no password ({email}). Use "Forgot password" to set one.',
     'news.this_artist': 'this artist',
     'news.form_title': 'Stay in the loop',
@@ -1951,19 +1766,4 @@
     'adir.page_info': 'Page {page} of {pages}',
     'adir.next': 'Next →',
-    'glog.admin_title': 'This is an administrator account',
-    'glog.admin_body': 'You signed in with Google, but this email address belongs to the administrator of this site. Google sign-in is only for listeners/fans — administrators always use their password (so a Google login can never accidentally grant admin rights).',
-    'glog.admin_li1': '<strong>Are you the administrator?</strong> <a href="/auth/admin">Log in with your username + password</a>.',
-    'glog.admin_li2': '<strong>Want to sign in with Google from now on?</strong> Log in with your password first and <strong>link your Google account</strong> under Account → after that Google sign-in works for you too.',
-    'glog.admin_li3': '<strong>Want to sign in as a fan?</strong> Use a <strong>different Google account</strong> (not your administrator address).',
-    'glog.session_title': 'Login interrupted',
-    'glog.session_body': 'The Google login was interrupted or the session had expired. Just try again.',
-    'glog.email_title': 'No verified email address',
-    'glog.email_body': 'Your Google account has no verified email address. Verify your address with Google.',
-    'glog.linked_title': 'Address already linked',
-    'glog.linked_body': 'This email address is already linked to another Google account. Use that account, or contact the administrator.',
-    'glog.unavailable_title': 'Google sign-in unavailable',
-    'glog.unavailable_body': 'Google sign-in has not (yet) been set up on this site.',
-    'glog.failed_title': 'Google sign-in failed',
-    'glog.failed_body': 'Something went wrong signing in with Google. Please try again.',
     'pusr.post_one': 'post',
     'pusr.post_many': 'posts',
@@ -2101,5 +1901,5 @@
     'admin.b_makesite': '🎨 Seite erstellen', 'admin.b_circle': '🔗 Kreis', 'admin.b_stats': '📊 Statistik',
     'admin.b_newsletter': '✉️ Newsletter', 'admin.b_perskit': '📰 Pressekit', 'admin.b_downloads': '⬇ Downloads',
-    'admin.b_linkbio': '🔗 Link-in-Bio', 'admin.b_agenda': '📅 Termine', 'admin.b_google': '🔑 Google',
+    'admin.b_linkbio': '🔗 Link-in-Bio', 'admin.b_agenda': '📅 Termine',
     'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Anleitung', 'admin.b_fediverse': 'Meine Antworten',
     'admin.st_users': 'Nutzer', 'admin.st_sites': 'Seiten', 'admin.st_posts': 'Beiträge', 'admin.st_published': 'Veröffentlicht',
@@ -2117,9 +1917,7 @@
     'auth.password': 'Passwort',
     'auth.forgot': 'Passwort vergessen?',
-    'auth.google_btn': 'Mit Google anmelden',
     'auth.public_sub': 'Melde dich an, um zu kommentieren und Favoriten zu speichern.',
     'auth.admin_box_q': 'Administrator?',
     'auth.admin_box_sub': 'Mit Benutzername & Passwort anmelden',
-    'auth.google_unavail': 'Google-Anmeldung ist auf dieser Seite noch nicht eingerichtet.',
     'auth.create_admin': 'Administrator anlegen',
     'auth.reg_intro': 'Ersteinrichtung — lege dein Administrator-Konto an. Das geht nur einmal.',
@@ -2165,17 +1963,10 @@
     'aset.solo': 'Solo',
     'aset.solo_title': 'eine Site (deine).',
-    'aset.solo_desc': 'Kein Benutzerverzeichnis, kein Site-Wechsel. Besucher können sich aber mit Google anmelden, um zu kommentieren.',
-    'aset.hub': 'Hub',
-    'aset.hub_title': 'Unternehmens-Site mit',
+    'aset.solo_desc': 'Kein Benutzerverzeichnis, kein Site-Wechsel.',
     'aset.premium_badge': 'Premium',
-    'aset.hub_desc': 'Du (Admin) weist Benutzern einen eigenen Klonkt Hub zu. Geschlossener Kreis: keine offene Registrierung.',
-    'aset.hub_locked_note': 'Erfordert Premium — verbinde Patreon auf dieser Seite.',
     'aset.circle': 'Kreise',
     'aset.circle_title': 'Solo + Föderation.',
     'aset.circle_desc': 'Eine eigene Site, die die öffentlichen Beiträge anderer Klonkt-Sites anzeigt. Asymmetrisch: Du bestimmst, wer in deinem Kreis ist.',
     'aset.save': 'Speichern',
-    'aset.hub_home': 'Hub-Startseite',
-    'aset.hub_home_help_1': 'Die öffentliche Hub-Seite',
-    'aset.hub_home_help_2': 'ist generisch — sie gehört keinem einzelnen Benutzer. Hier legst du Name und Intro fest. Dein eigener Klonkt Hub bleibt separat unter',
     'aset.name': 'Name',
     'aset.name_ph': 'z. B. Studio Noord',
@@ -2208,9 +1999,6 @@
     'aset.patreon_not_connected': 'Noch nicht verbunden.',
     'aset.patreon_connect': 'Patreon verbinden',
-    'aset.google_login': 'Google-Login (Besucher)',
-    'aset.google_login_help': 'Lass Besucher sich mit Google anmelden, um zu kommentieren — mit deinem eigenen Google-Cloud-Client.',
     'aset.status_set': 'Status: eingerichtet',
     'aset.not_set_yet': 'Noch nicht eingerichtet.',
-    'aset.google_login_setup': 'Google-Login einrichten',
     'aset.newsletter': 'Newsletter',
     'aset.newsletter_help_1': 'Zeige ein',
@@ -2281,6 +2069,4 @@
     'asite.moderation_moderate': 'Moderieren (zuerst in die Warteschlange)',
     'asite.enable_audio': 'Audioplayer + Embeds aktivieren',
-    'asite.enable_prutter': 'Prutter (DMs zwischen Mitgliedern) aktivieren',
-    'asite.enable_prutter_hint': '— Hub-Funktion, Premium',
     'asite.links': 'Social- / Streaming-Links',
     'asite.links_hint': 'Werden als Marken-Icons im Profilkopf gezeigt. Füge so viele hinzu, wie du möchtest.',
@@ -2349,68 +2135,4 @@
     'aseo.verify_yandex': 'Yandex',
     'aseo.save': 'SEO speichern',
-    'agoog.title': 'Google-Anmeldung',
-    'agoog.intro': 'Damit können sich Besucher mit ihrem <strong>Google-Konto</strong> anmelden, um zu kommentieren. Du richtest das einmalig mit deinem eigenen (kostenlosen) Google-Konto ein — etwa 5 Minuten, keine Kreditkarte oder kostenpflichtiger Dienst nötig.',
-    'agoog.g1': 'Öffne die Google Cloud Console und melde dich an. Erstelle oben ein <strong>neues Projekt</strong> (Projekt auswählen → Neues Projekt), gib ihm einen Namen und klicke auf <strong>Erstellen</strong>.',
-    'agoog.g2': 'Gehe im linken Menü zu <strong>APIs und Dienste → OAuth-Zustimmungsbildschirm</strong>. Wähle <strong>Extern</strong>, trage den App-Namen + deine E-Mail ein und speichere. Falls nach Testnutzern gefragt wird, füge dich selbst hinzu.',
-    'agoog.g3': 'Gehe zu <strong>APIs und Dienste → Anmeldedaten → Anmeldedaten erstellen → OAuth-Client-ID</strong> und wähle den Typ <strong>Webanwendung</strong>.',
-    'agoog.g4': 'Füge unter <strong>Autorisierte Weiterleitungs-URIs</strong> genau diese Adresse ein und klicke auf <strong>Erstellen</strong>:',
-    'agoog.g5': 'Google zeigt nun eine <strong>Client-ID</strong> und ein <strong>Client-Secret</strong>. Kopiere sie in die Felder unten und klicke auf <strong>Speichern</strong>. Fertig!',
-    'agoog.copy': 'Kopieren',
-    'agoog.copied': 'Kopiert ✓',
-    'agoog.warn_short': 'Achtung: muss <strong>exakt</strong> stimmen — mit <code>https://</code>, der richtigen Domain und <strong>ohne</strong> Schrägstrich am Ende. Andernfalls bekommst du „Error 400: redirect_uri_mismatch“.',
-    'agoog.need_baseurl': 'Lege zuerst <code>PUBLIC_BASE_URL</code> fest (die öffentliche URL deiner Seite) — daraus wird diese Adresse abgeleitet.',
-    'agoog.no_api_note': '<strong>Tipp:</strong> du musst keine APIs aktivieren (keine „People API“ usw.). Nur der Zustimmungsbildschirm + der OAuth-Client sind nötig.',
-    'agoog.back': 'Einstellungen',
-    'agoog.card_title': 'Google-Anmeldung (Besucher)',
-    'agoog.card_help_pre': 'Lass Besucher sich mit Google anmelden, um zu kommentieren — mit deinem',
-    'agoog.card_help_own': 'eigenen',
-    'agoog.card_help_mid': 'Google-Cloud-Client. Erstelle einen unter',
-    'agoog.card_help_post': '(OAuth-Client-ID, Typ „Web application“).',
-    'agoog.status_set': 'Status: eingerichtet&nbsp;✓',
-    'agoog.status_unset': 'Noch nicht eingerichtet.',
-    'agoog.guide_summary': 'Wie richte ich das ein? (Schritt für Schritt)',
-    'agoog.step1_pre': 'Gehe zur',
-    'agoog.step1_post': 'und erstelle (oder wähle) ein Projekt.',
-    'agoog.step2_usertype': 'User type',
-    'agoog.step2_scopes_pre': 'Füge die Scopes',
-    'agoog.step2_scopes_and': 'und',
-    'agoog.step2_scopes_post': 'hinzu.',
-    'agoog.step2_testmode': '(Im Testmodus: füge dich selbst als Testnutzer hinzu.)',
-    'agoog.step3_type': 'Typ',
-    'agoog.step4_pre': 'Unter',
-    'agoog.step4_post': ': füge die Redirect-URI unten ein (muss exakt übereinstimmen).',
-    'agoog.step5_pre': 'Kopiere die',
-    'agoog.step5_post': 'die du erhältst, in die Felder unten und klicke auf Speichern.',
-    'agoog.note_label': 'Achtung:',
-    'agoog.note_pre': 'du musst',
-    'agoog.note_noapi': 'keine APIs aktivieren',
-    'agoog.note_mid': '— „Google Cloud APIs“, People API usw. sind',
-    'agoog.note_not': 'nicht',
-    'agoog.note_post': 'erforderlich. Die Anmeldung läuft über OpenID Connect (nur der Zustimmungsbildschirm + der OAuth-Client).',
-    'agoog.redirect_label': 'Redirect-URI — kopiere diese und füge sie in Google ein',
-    'agoog.rstep1_pre': 'Gehe zur',
-    'agoog.rstep2': 'Öffne deine OAuth-Client-ID (Typ „Web application“).',
-    'agoog.rstep3_pre': 'Unter',
-    'agoog.rstep3_mid': 'klicke auf',
-    'agoog.rstep3_post': 'und füge die obige Zeile ein.',
-    'agoog.rstep4_pre': 'Klicke auf',
-    'agoog.rstep4_post': 'und warte ~1 Minute.',
-    'agoog.warn_pre': 'Muss',
-    'agoog.warn_exact': 'exakt',
-    'agoog.warn_mid1': 'stimmen:',
-    'agoog.warn_nohttp': 'kein',
-    'agoog.warn_mid2': ', richtige Domain und',
-    'agoog.warn_noslash': 'kein',
-    'agoog.warn_mid3': 'Schrägstrich am Ende. Andernfalls bekommst du',
-    'agoog.warn_error': '„Error 400: redirect_uri_mismatch“',
-    'agoog.set_baseurl_pre': 'Lege zuerst',
-    'agoog.set_baseurl_post': 'fest — daraus wird die Redirect-URI abgeleitet.',
-    'agoog.client_id': 'Client ID',
-    'agoog.client_secret': 'Client Secret',
-    'agoog.client_secret_set': 'eingerichtet; leer lassen = unverändert',
-    'agoog.secret_ph_set': '•••••••• (eingerichtet)',
-    'agoog.save': 'Speichern',
-    'agoog.disconnect': 'Trennen',
-    'agoog.premium_locked': 'Die Premium-Ebene ist ohne Patreon aktiv — der Google-Button bleibt verborgen, bis Premium freigeschaltet ist.',
     'aaud.title': 'Audio-Tracks',
     'aaud.tagline_pre': 'MP3s auf Site-Ebene. Verwende',
@@ -2723,6 +2445,4 @@
     'ahelp.s_premium_h': 'Premium / Patreon',
     'ahelp.s_premium_b': 'Premium-Funktionen (Statistiken, Termine, Downloads, Pressekit, Newsletter, Link-in-Bio, Embed) schaltest du in Verwaltung → Einstellungen frei, indem du Patreon verknüpfst ($16 lebenslang). Updates und die Kern-App bleiben immer kostenlos.',
-    'ahelp.s_google_h': 'Google-Login (Besucher)',
-    'ahelp.s_google_b': 'Verwaltung → Einstellungen → <strong>Google</strong>. Optional: Lass Besucher/Fans sich mit Google anmelden, um zu kommentieren. Du verwaltest mit deinem Passwort — Google gewährt nie Verwaltungsrechte. Trage deine eigenen Google-Client-Daten ein (pro Seite).',
     'ahelp.s_updates_h': 'Updates',
     'ahelp.s_updates_b': 'Verwaltung → <strong>Updates</strong> (nur God) zeigt die aktuelle Version und ob eine neuere verfügbar ist. Mit „Jetzt aktualisieren“ holst du dir die neueste Version.',
@@ -2862,11 +2582,6 @@
     'acct.password_min': '(mind. 8 Zeichen)',
     'acct.password_confirm': 'Neues Passwort bestätigen',
-    'acct.google_login': 'Mit Google anmelden',
-    'acct.google_linked': '✓ Dein Google-Konto ist verknüpft — du kannst dich auch mit Google anmelden.',
-    'acct.google_unlink': 'Google trennen',
-    'acct.google_link_hint': 'Verknüpfe dein Google-Konto, damit du dich künftig auch mit einem Klick über Google anmelden kannst (zusätzlich zu deinem Passwort).',
-    'acct.google_link': 'Google-Konto verknüpfen',
     'acct.login': 'Anmelden',
-    'acct.login_google_only': 'Du bist über Google angemeldet ({email}). Es gibt kein separates Passwort.',
+    'acct.login_google_only': 'Dieses Konto hat kein Passwort ({email}). Nutze "Passwort vergessen", um eines festzulegen.',
     'news.this_artist': 'diese:r Künstler:in',
     'news.form_title': 'Bleib auf dem Laufenden',
@@ -2964,19 +2679,4 @@
     'adir.page_info': 'Seite {page} von {pages}',
     'adir.next': 'Weiter →',
-    'glog.admin_title': 'Dies ist ein Administrator-Konto',
-    'glog.admin_body': 'Du hast dich mit Google angemeldet, aber diese E-Mail-Adresse gehört dem Administrator dieser Seite. Die Google-Anmeldung ist nur für Hörer/Fans — Administratoren verwenden immer ihr Passwort (so kann eine Google-Anmeldung niemals versehentlich Administratorrechte erteilen).',
-    'glog.admin_li1': '<strong>Bist du der Administrator?</strong> <a href="/auth/admin">Melde dich mit Benutzername + Passwort an</a>.',
-    'glog.admin_li2': '<strong>Möchtest du dich künftig mit Google anmelden?</strong> Melde dich zuerst mit Passwort an und <strong>verknüpfe dein Google-Konto</strong> unter Konto → danach funktioniert die Google-Anmeldung auch für dich.',
-    'glog.admin_li3': '<strong>Möchtest du dich als Fan anmelden?</strong> Verwende ein <strong>anderes Google-Konto</strong> (nicht deine Administrator-Adresse).',
-    'glog.session_title': 'Anmeldung abgebrochen',
-    'glog.session_body': 'Die Google-Anmeldung wurde abgebrochen oder die Sitzung war abgelaufen. Versuche es einfach erneut.',
-    'glog.email_title': 'Keine verifizierte E-Mail-Adresse',
-    'glog.email_body': 'Dein Google-Konto hat keine verifizierte E-Mail-Adresse. Verifiziere deine Adresse bei Google.',
-    'glog.linked_title': 'Adresse bereits verknüpft',
-    'glog.linked_body': 'Diese E-Mail-Adresse ist bereits mit einem anderen Google-Konto verknüpft. Verwende dieses Konto oder wende dich an den Administrator.',
-    'glog.unavailable_title': 'Google-Anmeldung nicht verfügbar',
-    'glog.unavailable_body': 'Die Google-Anmeldung wurde auf dieser Seite (noch) nicht eingerichtet.',
-    'glog.failed_title': 'Google-Anmeldung fehlgeschlagen',
-    'glog.failed_body': 'Beim Anmelden mit Google ist etwas schiefgelaufen. Bitte versuche es erneut.',
     'pusr.post_one': 'Beitrag',
     'pusr.post_many': 'Beiträge',
Index: src/views/pages/auth-login.ejs
===================================================================
--- src/views/pages/auth-login.ejs	(revision eb5f978375e885d17090a8dedb24802dda9a52b4)
+++ src/views/pages/auth-login.ejs	(revision 5f483e38e1f3f8ccca8ba962aaacb14f4d06f7a3)
@@ -1,7 +1,5 @@
 <%
-  // adminLogin = the hidden admin login page (/auth/admin): shows the
-  // username/password form. The public /auth/login shows visitors
-  // ONLY Google login (listeners/fans). This keeps the admin login
-  // off the page where visitors are directed.
+  // The login page shows the admin username/password form. (Public listener
+  // login via Google was removed — interaction now runs via the fediverse.)
   var _admin = (typeof adminLogin !== 'undefined' && adminLogin);
 %>
@@ -9,25 +7,5 @@
   <h1><%= _admin ? t('auth.admin_login_title') : t('nav.login') %></h1>
   <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %>
-  <%
-    var GMAP = {
-      admin: { icon: '🔐', title: t('glog.admin_title'),
-        body: t('glog.admin_body'),
-        list: [t('glog.admin_li1'), t('glog.admin_li2'), t('glog.admin_li3')] },
-      session: { icon: '⏱️', title: t('glog.session_title'), body: t('glog.session_body') },
-      email: { icon: '✉️', title: t('glog.email_title'), body: t('glog.email_body') },
-      linked: { icon: '🔗', title: t('glog.linked_title'), body: t('glog.linked_body') },
-      unavailable: { icon: '🚫', title: t('glog.unavailable_title'), body: t('glog.unavailable_body') },
-      failed: { icon: '⚠️', title: t('glog.failed_title'), body: t('glog.failed_body') },
-    };
-    var _g = (typeof gerr !== 'undefined' && gerr && GMAP[gerr]) ? GMAP[gerr] : null;
-  %>
-  <% if (_g) { %>
-    <div class="auth-notice">
-      <div class="auth-notice-icon"><%= _g.icon %></div>
-      <h2 class="auth-notice-title"><%= _g.title %></h2>
-      <p><%= _g.body %></p>
-      <% if (_g.list) { %><ul class="auth-notice-list"><% _g.list.forEach(function(li){ %><li><%- li %></li><% }); %></ul><% } %>
-    </div>
-  <% } else if (error) { %><div class="alert alert-error"><%= error %></div><% } %>
+  <% if (error) { %><div class="alert alert-error"><%= error %></div><% } %>
 
   <% if (_admin) { %>
@@ -51,26 +29,2 @@
 </div>
 
-<style>
-  .auth-notice { border: 1px solid rgba(128,128,128,.28); border-radius: 14px; padding: 18px 20px; margin-bottom: 18px; background: rgba(128,128,128,.06); }
-  .auth-notice-icon { font-size: 26px; }
-  .auth-notice-title { font-size: 17px; margin: 4px 0 8px; }
-  .auth-notice p { margin: 0 0 10px; line-height: 1.55; opacity: .9; }
-  .auth-notice-list { margin: 0; padding-left: 18px; line-height: 1.6; }
-  .auth-notice-list li { margin: 4px 0; }
-  .auth-sub { color: var(--ink-muted); margin: 0 0 1rem; text-align: center; }
-  /* Google button is white → keep text dark at all times, including hover (the global
-     a.btn:hover rule would otherwise make it near-white on white = unreadable). */
-  a.btn-google, a.btn-google:hover { color: #1f1f1f; }
-  .auth-admin-box {
-    display: flex; align-items: center; gap: .75rem;
-    margin-top: 1.25rem; padding: .8rem 1rem;
-    border: 1px solid var(--rule); border-radius: 12px;
-    background: var(--paper-2); color: var(--ink); text-decoration: none;
-    transition: border-color 120ms, background 120ms;
-  }
-  .auth-admin-box:hover { border-color: var(--accent); background: var(--paper); }
-  .auth-admin-box-icon { font-size: 1.3rem; }
-  .auth-admin-box-text { display: flex; flex-direction: column; line-height: 1.3; flex: 1; }
-  .auth-admin-box-text small { color: var(--ink-muted); font-size: .8rem; }
-  .auth-admin-box-arrow { color: var(--ink-muted); font-size: 1.1rem; }
-</style>
Index: src/views/pages/notifications.ejs
===================================================================
--- src/views/pages/notifications.ejs	(revision eb5f978375e885d17090a8dedb24802dda9a52b4)
+++ 	(revision )
@@ -1,36 +1,0 @@
-<div class="container notif-page">
-  <h1><%= t('notif.title') %></h1>
-
-  <% if (!items || !items.length) { %>
-    <p class="notif-empty"><%= t('notif.empty') %></p>
-  <% } else { %>
-    <ul class="notif-list">
-      <% items.forEach(function(n){
-           var key = n.type === 'reply' ? 'notif.reply' : (n.type === 'comment' ? 'notif.comment' : 'notif.like');
-           var actor = n.actor_name || t('notif.someone');
-      %>
-        <li class="notif-item<%= n.read ? '' : ' is-unread' %>">
-          <a class="notif-link" href="<%= n.url || '#' %>">
-            <span class="notif-text"><%= t(key, { actor: actor }) %></span>
-            <% if (n.post_title) { %><span class="notif-post">&ldquo;<%= n.post_title %>&rdquo;</span><% } %>
-            <span class="notif-time"><%= formatDateTime(n.created_at) %></span>
-          </a>
-        </li>
-      <% }); %>
-    </ul>
-  <% } %>
-</div>
-
-<style>
-.notif-page { max-width: 640px; margin: 2.5rem auto; padding: 0 1rem; }
-.notif-page h1 { font-family: var(--font-display, serif); font-size: 1.8rem; margin: 0 0 1.25rem; }
-.notif-empty { color: var(--ink-muted, var(--ink-soft)); }
-.notif-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
-.notif-item { border: 1px solid var(--rule); border-radius: 10px; background: var(--paper-2); }
-.notif-item.is-unread { border-color: var(--accent); }
-.notif-link { display: flex; flex-direction: column; gap: 0.15rem; padding: 0.7rem 0.9rem; color: var(--ink); text-decoration: none; }
-.notif-link:hover { background: var(--paper); }
-.notif-text { font-size: 0.95rem; }
-.notif-post { color: var(--ink-soft, var(--ink-muted)); font-size: 0.9rem; }
-.notif-time { color: var(--ink-soft, var(--ink-muted)); font-size: 0.78rem; }
-</style>
