Index: c/config/google.js
===================================================================
--- src/config/google.js	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ 	(revision )
@@ -1,72 +1,0 @@
-// Google OAuth2 for LISTENERS (commenting). Per-instance: each self-hoster sets
-// their OWN Google client. This way every site is tied to its own Google Cloud
-// project — no central dependency, no shared liability.
-//
-// Config source (in this order): app_settings (set via Admin → Settings),
-// otherwise env vars. Not configured → no "Login with Google" button; the rest
-// of the site keeps working. Google login NEVER grants admin rights.
-//
-// The redirect URI is derived from PUBLIC_BASE_URL (<base>/auth/google/callback),
-// or explicitly via GOOGLE_REDIRECT_URI. That exact URL must be listed in Google Cloud.
-
-import { getSetting } from '../services/SettingsService.js';
-
-const AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
-const TOKEN_URL = 'https://oauth2.googleapis.com/token';
-const USERINFO_URL = 'https://openidconnect.googleapis.com/v1/userinfo';
-
-// Read dynamically (UI changes take effect without a restart). app_settings wins, env = fallback.
-function clientId() {
-  return getSetting('google_client_id', '') || process.env.GOOGLE_CLIENT_ID || '';
-}
-function clientSecret() {
-  return getSetting('google_client_secret', '') || process.env.GOOGLE_CLIENT_SECRET || '';
-}
-export function redirectUri() {
-  if (process.env.GOOGLE_REDIRECT_URI) return process.env.GOOGLE_REDIRECT_URI;
-  const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
-  return base ? `${base}/auth/google/callback` : '';
-}
-
-export function currentClientId() { return clientId(); } // not secret, used for the settings form
-export function clientSecretSet() { return !!clientSecret(); }
-export function googleConfigured() {
-  return !!(clientId() && clientSecret() && redirectUri());
-}
-
-export function authorizeUrl(state) {
-  const p = new URLSearchParams({
-    client_id: clientId(),
-    redirect_uri: redirectUri(),
-    response_type: 'code',
-    scope: 'openid email profile',
-    state,
-    access_type: 'online',
-    prompt: 'select_account',
-  });
-  return `${AUTH_URL}?${p.toString()}`;
-}
-
-export async function exchangeCode(code) {
-  const body = new URLSearchParams({
-    code,
-    client_id: clientId(),
-    client_secret: clientSecret(),
-    redirect_uri: redirectUri(),
-    grant_type: 'authorization_code',
-  });
-  const r = await fetch(TOKEN_URL, {
-    method: 'POST',
-    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
-    body,
-  });
-  if (!r.ok) throw new Error(`Google token exchange failed: ${r.status}`);
-  return r.json(); // { access_token, id_token, ... }
-}
-
-// Returns { sub, email, email_verified, name, picture }.
-export async function fetchUserinfo(accessToken) {
-  const r = await fetch(USERINFO_URL, { headers: { Authorization: `Bearer ${accessToken}` } });
-  if (!r.ok) throw new Error(`Google userinfo failed: ${r.status}`);
-  return r.json();
-}
Index: src/routes/account.js
===================================================================
--- src/routes/account.js	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ src/routes/account.js	(revision 075185aec7ff8542aa40c1e84a7a70cb05f7599f)
@@ -24,5 +24,4 @@
 import { renderPage } from '../middleware/render.js';
 import { requireAuth } from '../middleware/auth.js';
-import { googleConfigured } from '../config/google.js';
 import { toWebp } from '../services/ImageWebpService.js';
 import { SUPPORTED } from '../services/i18n.js';
@@ -65,5 +64,4 @@
   `).get(req.session.user.id);
   const hasPassword = !!(account && account.password_hash && account.password_hash !== '!google-oauth');
-  const googleLinked = !!(account && account.google_sub);
   if (account) { delete account.password_hash; delete account.google_sub; } // don't leak to the view
 
@@ -74,6 +72,4 @@
     account,
     hasPassword,
-    googleLinked,
-    googleAvailable: googleConfigured(),
     editableSite,
     // Display fallback: when you have no own account avatar, show your site's photo.
@@ -204,18 +200,4 @@
 });
 
-// Unlink Google account. Only allowed if a password is set,
-// otherwise the user would lock themselves out (no login method left).
-router.post('/google/unlink', requireAuth, (req, res) => {
-  const row = db.prepare('SELECT password_hash, google_sub FROM users WHERE id = ?').get(req.session.user.id);
-  if (!row || !row.google_sub) {
-    return res.redirect('/account?error=' + encodeURIComponent('Er is geen Google-account gekoppeld'));
-  }
-  if (!row.password_hash || row.password_hash === '!google-oauth') {
-    return res.redirect('/account?error=' + encodeURIComponent('Stel eerst een wachtwoord in — anders kun je niet meer inloggen.'));
-  }
-  db.prepare('UPDATE users SET google_sub = NULL, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(req.session.user.id);
-  res.redirect('/account?success=' + encodeURIComponent('Google-account ontkoppeld'));
-});
-
 // ==================== UPLOAD AVATAR ====================
 router.post('/avatar', requireAuth, (req, res) => {
Index: src/routes/admin-settings.js
===================================================================
--- src/routes/admin-settings.js	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ src/routes/admin-settings.js	(revision 075185aec7ff8542aa40c1e84a7a70cb05f7599f)
@@ -25,5 +25,4 @@
 import { mailerStatus, sendMail } from '../config/mailer.js';
 import { entitlementStatus, premiumUnlocked } from '../services/PatreonService.js';
-import { googleConfigured, redirectUri, currentClientId, clientSecretSet } from '../config/google.js';
 import { toWebp } from '../services/ImageWebpService.js';
 
@@ -81,10 +80,4 @@
     defaultLang: getSetting('default_lang') || '',
     premium: entitlementStatus(),
-    google: {
-      configured: googleConfigured(),
-      redirectUri: redirectUri(),
-      clientId: currentClientId(),
-      secretSet: clientSecretSet(),
-    },
     smtp: mailerStatus(),
     footerNewsletter: getSetting('footer_newsletter') === '1',
@@ -155,35 +148,4 @@
 });
 
-// Google login on its own admin page (separate from the general settings).
-router.get('/google', requireGod, (req, res) => {
-  renderPage(req, res, 'pages/admin-google', {
-    pageTitle: 'Google-login',
-    bodyClass: 'on-admin',
-    google: {
-      configured: googleConfigured(),
-      redirectUri: redirectUri(),
-      clientId: currentClientId(),
-      secretSet: clientSecretSet(),
-    },
-    success: req.query.success || null,
-    error: req.query.error || null,
-  });
-});
-
-// Configure Google login (listeners) — Client ID + Secret in app_settings.
-// The redirect URI is derived from PUBLIC_BASE_URL (see config/google.js).
-router.post('/google', requireGod, (req, res) => {
-  if (req.body.clear === '1') {
-    setSetting('google_client_id', '');
-    setSetting('google_client_secret', '');
-    return res.redirect('/admin/settings?success=' + encodeURIComponent('Google-login losgekoppeld'));
-  }
-  setSetting('google_client_id', (req.body.google_client_id || '').toString().trim());
-  // Only overwrite the secret if a new value was entered (empty = leave as-is).
-  const secret = (req.body.google_client_secret || '').toString().trim();
-  if (secret) setSetting('google_client_secret', secret);
-  res.redirect('/admin/settings?success=' + encodeURIComponent('Google-login opgeslagen'));
-});
-
 // ── SMTP / e-mail-instellingen ────────────────────────────────────
 router.post('/smtp', requireGod, (req, res) => {
Index: src/routes/auth.js
===================================================================
--- src/routes/auth.js	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ src/routes/auth.js	(revision 075185aec7ff8542aa40c1e84a7a70cb05f7599f)
@@ -7,13 +7,4 @@
 import { loginLimiter, registerLimiter } from '../middleware/rate-limit.js';
 import { safeNext, requireAuth } from '../middleware/auth.js';
-import { googleConfigured, authorizeUrl, exchangeCode, fetchUserinfo } from '../config/google.js';
-import { premiumUnlocked } from '../services/PatreonService.js';
-
-// Fan login (listeners signing in with Google to comment) is a premium feature:
-// available when Google is configured AND the premium layer is unlocked
-// (premium off = open to all; on = Patreon required).
-function fanLoginReady() {
-  return googleConfigured() && premiumUnlocked();
-}
 import { mailerConfigured, sendMail } from '../config/mailer.js';
 import { resolveLang, t } from '../services/i18n.js';
@@ -47,7 +38,6 @@
 
 // ==================== LOGIN ====================
-// Public login page: for VISITORS only Google-login (listeners/fans).
-// The admin login (password) is intentionally NOT here — it lives hidden at
-// /auth/admin (see below), so the admin login is not visible where visitors land.
+// Single login = admin/owner password (no public/listener login anymore; social
+// interaction happens via the fediverse). /login and /auth/admin both show it.
 router.get('/login', (req, res) => {
   const next = safeNext(req.query.next) || '';
@@ -58,9 +48,9 @@
     bodyClass: 'on-special on-auth',
     error: req.query.error || null,
-    gerr: req.query.gerr || null, // foutcode voor een rijkere uitleg (bv. 'admin')
+    gerr: null,
     success: req.query.success || null,
     username: '',
-    adminLogin: false,
-    googleReady: fanLoginReady(),
+    adminLogin: true,
+    googleReady: false,
     next,
   });
@@ -265,130 +255,4 @@
 });
 
-// ==================== GOOGLE LOGIN (listeners/commenters) ====================
-// Per-instance, own Google client. ALWAYS grants role member — never admin.
-router.get('/google', (req, res) => {
-  if (!fanLoginReady()) {
-    return res.redirect('/auth/login?gerr=unavailable');
-  }
-  const state = crypto.randomBytes(16).toString('hex');
-  req.session.oauthState = state;
-  req.session.oauthNext = safeNext(req.query.next) || '';
-  delete req.session.oauthLink;
-  res.redirect(authorizeUrl(state));
-});
-
-// LINK Google to the current (logged-in) account — e.g. an admin who also wants
-// to log in with Google. Requires being already logged in (with password); the
-// link stores the google_sub on their own account.
-// Only googleConfigured() needed (no premium gate — this is not fan login).
-router.get('/google/link', requireAuth, (req, res) => {
-  if (!googleConfigured()) {
-    return res.redirect('/account?error=' + encodeURIComponent('Google-login is op deze site niet ingesteld.'));
-  }
-  const state = crypto.randomBytes(16).toString('hex');
-  req.session.oauthState = state;
-  req.session.oauthLink = true; // link mode instead of login mode
-  res.redirect(authorizeUrl(state));
-});
-
-function uniqueUsername(base) {
-  let u = String(base || 'luisteraar').toLowerCase().replace(/[^a-z0-9_-]/g, '').slice(0, 28);
-  if (u.length < 3) u = 'luisteraar';
-  let candidate = u, n = 1;
-  while (db.prepare('SELECT 1 FROM users WHERE username = ?').get(candidate)) {
-    candidate = (u.slice(0, 26) + n).slice(0, 32);
-    n++;
-  }
-  return candidate;
-}
-
-router.get('/google/callback', async (req, res) => {
-  const linking = !!req.session.oauthLink;
-  const failLogin = (code) => res.redirect('/auth/login?gerr=' + code);
-  const failLink = (msg) => res.redirect('/account?error=' + encodeURIComponent(msg));
-
-  try {
-    const { code, state } = req.query;
-    if (!code || !state || state !== req.session.oauthState) {
-      delete req.session.oauthState; delete req.session.oauthLink; delete req.session.oauthNext;
-      return linking ? failLink('Google-koppeling afgebroken of sessie verlopen. Probeer opnieuw.') : failLogin('session');
-    }
-
-    const tok = await exchangeCode(String(code));
-    const info = await fetchUserinfo(tok.access_token);
-    const email = (info.email || '').trim().toLowerCase();
-
-    // ── LINK MODE: attach Google to the current (logged-in) account ──
-    if (linking) {
-      delete req.session.oauthState; delete req.session.oauthLink;
-      if (!req.session.user) return failLogin('session');
-      if (!info.sub) return failLink('Google gaf geen account-id terug. Probeer opnieuw.');
-      if (info.email && info.email_verified === false) return failLink('Je Google-adres is niet geverifieerd.');
-      // This Google account must not already be linked to a DIFFERENT account.
-      const other = db.prepare('SELECT id FROM users WHERE google_sub = ? AND id != ?').get(info.sub, req.session.user.id);
-      if (other) return failLink('Dit Google-account is al aan een andere gebruiker gekoppeld.');
-      db.prepare(`
-        UPDATE users SET google_sub = ?, avatar_url = COALESCE(avatar_url, ?),
-          updated_at = CURRENT_TIMESTAMP WHERE id = ?
-      `).run(info.sub, info.picture || null, req.session.user.id);
-      return res.redirect('/account?success=' + encodeURIComponent('Google-account gekoppeld — je kunt nu ook met Google inloggen.'));
-    }
-
-    // ── LOGIN MODE (listeners/fans + linked admin) ──
-    if (!fanLoginReady()) return failLogin('unavailable');
-    const next = safeNext(req.session.oauthNext) || '';
-    delete req.session.oauthState; delete req.session.oauthNext;
-    if (!email || info.email_verified === false) return failLogin('email');
-
-    // Look FIRST by linked Google account (google_sub). A sub-match is explicit
-    // proof of the link → log in with their own role, EVEN IF the Google email
-    // differs from the account email (e.g. an admin who linked a different Gmail).
-    // Only then fall back to email lookup.
-    let user = info.sub ? db.prepare('SELECT * FROM users WHERE google_sub = ?').get(info.sub) : null;
-
-    if (user) {
-      // Linked account found → keep their own role. Update avatar if empty.
-      db.prepare(`
-        UPDATE users SET avatar_url = COALESCE(avatar_url, ?), updated_at = CURRENT_TIMESTAMP WHERE id = ?
-      `).run(info.picture || null, user.id);
-    } else {
-      user = db.prepare('SELECT * FROM users WHERE LOWER(email) = ?').get(email);
-      if (user && (user.role === 'god' || user.role === 'admin')) {
-        // Admin found by email but WITHOUT a linked sub → Google never grants admin.
-        // Must first link via Account → Sign in with Google.
-        return failLogin('admin');
-      } else if (user) {
-        // Existing listener: link google_sub/avatar if missing.
-        db.prepare(`
-          UPDATE users SET google_sub = COALESCE(google_sub, ?), avatar_url = COALESCE(avatar_url, ?),
-            updated_at = CURRENT_TIMESTAMP WHERE id = ?
-        `).run(info.sub || null, info.picture || null, user.id);
-      } else {
-        // New listener — always member.
-        const userId = uuid();
-        const username = uniqueUsername(info.name || email.split('@')[0]);
-        db.prepare(`
-          INSERT INTO users (id, username, email, password_hash, role, avatar_url, theme, palette, google_sub)
-          VALUES (?, ?, ?, '!google-oauth', 'member', ?, 'dark', 'sage', ?)
-        `).run(userId, username, info.email || email, info.picture || null, info.sub || null);
-        user = db.prepare('SELECT * FROM users WHERE id = ?').get(userId);
-      }
-    }
-
-    req.session.user = {
-      id: user.id, username: user.username, email: user.email, role: user.role,
-      avatar_url: user.avatar_url, palette: user.palette, theme: user.theme,
-      readonly: !!user.readonly,
-    };
-    res.redirect(next || '/');
-  } catch (e) {
-    console.error('[auth/google/callback]', e.message);
-    delete req.session.oauthState; delete req.session.oauthLink; delete req.session.oauthNext;
-    return linking
-      ? res.redirect('/account?error=' + encodeURIComponent('Google koppelen mislukt — probeer opnieuw.'))
-      : failLogin('failed');
-  }
-});
-
 // ==================== LOGOUT ====================
 router.get('/logout', (req, res) => { req.session.destroy(() => res.redirect('/')); });
Index: src/views/pages/account.ejs
===================================================================
--- src/views/pages/account.ejs	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ src/views/pages/account.ejs	(revision 075185aec7ff8542aa40c1e84a7a70cb05f7599f)
@@ -163,18 +163,4 @@
   </section>
 
-  <% if (typeof googleAvailable !== 'undefined' && googleAvailable) { %>
-  <section class="ax-card">
-    <div class="ax-card-title"><%= t('acct.google_login') %></div>
-    <% if (typeof googleLinked !== 'undefined' && googleLinked) { %>
-      <p class="ax-tagline" style="margin:0 0 1rem"><%= t('acct.google_linked') %></p>
-      <form action="/account/google/unlink" method="post">
-        <button type="submit" class="ax-btn"><%= t('acct.google_unlink') %></button>
-      </form>
-    <% } else { %>
-      <p class="ax-tagline" style="margin:0 0 1rem"><%= t('acct.google_link_hint') %></p>
-      <a href="/auth/google/link" class="ax-btn ax-btn-primary" data-full-load><%= t('acct.google_link') %></a>
-    <% } %>
-  </section>
-  <% } %>
   <% } else { %>
   <section class="ax-card">
Index: c/views/pages/admin-google.ejs
===================================================================
--- src/views/pages/admin-google.ejs	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ 	(revision )
@@ -1,131 +1,0 @@
-<div class="container admin-page">
-  <h1><%= t('agoog.title') %></h1>
-  <p><a href="/admin/settings" class="btn">&larr; <%= t('agoog.back') %></a></p>
-
-  <% if (success) { %><div class="alert alert-success"><%= success %></div><% } %>
-  <% if (typeof error !== 'undefined' && error) { %><div class="alert alert-error"><%= error %></div><% } %>
-
-  <section class="set-card">
-    <h2><%= t('agoog.card_title') %></h2>
-    <p class="set-help"><%- t('agoog.intro') %>
-      <% if (google && google.configured) { %><strong><%= t('agoog.status_set') %></strong><% } else { %><%= t('agoog.status_unset') %><% } %></p>
-
-    <ol class="gg-steps">
-      <li>
-        <span class="gg-num">1</span>
-        <div class="gg-body"><%- t('agoog.g1') %> <a href="https://console.cloud.google.com/" target="_blank" rel="noopener">Google Cloud Console ↗</a></div>
-      </li>
-      <li>
-        <span class="gg-num">2</span>
-        <div class="gg-body"><%- t('agoog.g2') %></div>
-      </li>
-      <li>
-        <span class="gg-num">3</span>
-        <div class="gg-body"><%- t('agoog.g3') %></div>
-      </li>
-      <li>
-        <span class="gg-num">4</span>
-        <div class="gg-body">
-          <%- t('agoog.g4') %>
-          <% if (google && google.redirectUri) { %>
-            <div class="gg-redirect">
-              <code class="gg-url"><%= google.redirectUri %></code>
-              <button type="button" class="btn gg-copy" data-copy="<%= google.redirectUri %>"><%= t('agoog.copy') %></button>
-            </div>
-            <p class="gg-warn"><%- t('agoog.warn_short') %></p>
-          <% } else { %>
-            <p class="gg-warn" style="color:var(--accent)"><%- t('agoog.need_baseurl') %></p>
-          <% } %>
-        </div>
-      </li>
-      <li>
-        <span class="gg-num">5</span>
-        <div class="gg-body"><%- t('agoog.g5') %></div>
-      </li>
-    </ol>
-    <p class="gg-tip"><%- t('agoog.no_api_note') %></p>
-
-    <form method="post" action="/admin/settings/google" class="set-form">
-      <label class="set-field">
-        <span><%= t('agoog.client_id') %></span>
-        <input type="text" name="google_client_id" value="<%= google ? google.clientId : '' %>" placeholder="123-abc.apps.googleusercontent.com" autocomplete="off">
-      </label>
-      <label class="set-field">
-        <span><%= t('agoog.client_secret') %> <% if (google && google.secretSet) { %><small style="font-weight:400">— <%= t('agoog.client_secret_set') %></small><% } %></span>
-        <input type="password" name="google_client_secret" placeholder="<%= (google && google.secretSet) ? t('agoog.secret_ph_set') : 'GOCSPX-…' %>" autocomplete="off">
-      </label>
-      <div class="set-actions">
-        <button type="submit" class="btn btn-primary"><%= t('agoog.save') %></button>
-        <% if (google && (google.clientId || google.secretSet)) { %>
-          <button type="submit" name="clear" value="1" class="btn"><%= t('agoog.disconnect') %></button>
-        <% } %>
-      </div>
-    </form>
-    <% if (typeof premiumEnabled !== 'undefined' && premiumEnabled && !isPremium) { %>
-      <p class="set-help" style="margin-top:.7rem; color:var(--accent)"><%= t('agoog.premium_locked') %></p>
-    <% } %>
-  </section>
-</div>
-
-<style>
-.admin-page { max-width: 700px; margin: 3rem auto; padding: 0 1rem; }
-.admin-page h1 { font-family: var(--font-display, serif); font-size: 2rem; margin: 0 0 0.75rem; }
-.set-card { background: var(--paper-2); border: 1px solid var(--rule); border-radius: 12px; padding: 1.25rem; }
-.set-card h2 { font-family: var(--font-display, serif); font-size: 1.25rem; margin: 0 0 0.5rem; }
-.set-help { color: var(--ink-muted); font-size: 0.9rem; margin: 0 0 1.25rem; }
-.set-google-guide { margin: 0 0 1rem; border: 1px solid var(--rule); border-radius: 8px; background: var(--paper); }
-.set-google-guide > summary { cursor: pointer; padding: 0.6rem 0.85rem; font-size: 0.9rem; font-weight: 600; color: var(--accent); list-style: none; }
-.set-google-guide > summary::-webkit-details-marker { display: none; }
-.set-google-guide > summary::before { content: "▸ "; }
-.set-google-guide[open] > summary::before { content: "▾ "; }
-.set-google-steps { margin: 0; padding: 0 1rem 0.6rem 2rem; font-size: 0.88rem; color: var(--ink); line-height: 1.5; }
-.set-google-steps li { margin: 0.35rem 0; }
-.set-google-guide code { background: var(--paper-2); padding: 0.05rem 0.35rem; border-radius: 4px; font-size: 0.85em; }
-.set-google-guide .set-help { padding: 0 0.85rem; }
-.set-form { display: flex; flex-direction: column; gap: 1rem; max-width: 460px; }
-.set-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.25rem; }
-.set-field { display: flex; flex-direction: column; gap: 0.3rem; }
-.set-field > span { font-size: 0.8rem; font-weight: 600; color: var(--ink-soft, var(--ink-muted)); }
-.set-field input {
-  width: 100%; box-sizing: border-box; padding: 0.55rem 0.7rem;
-  border: 1px solid var(--rule); border-radius: 6px; background: var(--paper); color: var(--ink);
-  font: inherit; font-size: 0.95rem;
-}
-.set-field input:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
-.alert { padding: 0.75rem 1rem; border-radius: 6px; margin-bottom: 1rem; }
-.alert-success { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
-.set-redirect { border: 1px solid var(--accent); border-radius: 10px; padding: 1rem; margin: 0 0 1.25rem; background: var(--paper); }
-.set-redirect-label { font-weight: 700; font-size: 0.9rem; margin-bottom: 0.5rem; }
-.set-redirect-url { display: block; padding: 0.6rem 0.8rem; background: var(--paper-2); border: 1px dashed var(--rule); border-radius: 6px; font-size: 0.9rem; word-break: break-all; }
-.set-redirect-steps { margin: 0.85rem 0 0; padding-left: 1.3rem; font-size: 0.9rem; line-height: 1.55; color: var(--ink); }
-.set-redirect-steps li { margin: 0.3rem 0; }
-.set-redirect-steps a { color: var(--accent); }
-.set-redirect-warn { margin: 0.85rem 0 0; font-size: 0.85rem; color: var(--ink-muted); }
-.set-redirect-warn code { background: var(--paper-2); padding: 0.05rem 0.35rem; border-radius: 4px; }
-/* Numbered, always-visible step-by-step instructions (beginner-friendly) */
-.gg-steps { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
-.gg-steps > li { display: flex; gap: 0.7rem; align-items: flex-start; }
-.gg-num { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; background: var(--accent); color: #fff; font-weight: 700; font-size: 0.85rem; display: inline-flex; align-items: center; justify-content: center; }
-.gg-body { font-size: 0.92rem; line-height: 1.5; color: var(--ink); padding-top: 2px; min-width: 0; }
-.gg-body code { background: var(--paper-2); padding: 0.05rem 0.35rem; border-radius: 4px; font-size: 0.88em; }
-.gg-redirect { display: flex; gap: 0.5rem; align-items: stretch; margin: 0.5rem 0 0.3rem; flex-wrap: wrap; }
-.gg-url { flex: 1 1 220px; min-width: 0; padding: 0.5rem 0.7rem; background: var(--paper-2); border: 1px dashed var(--accent); border-radius: 6px; font-size: 0.85rem; word-break: break-all; align-self: center; }
-.gg-copy { flex: 0 0 auto; }
-.gg-warn { font-size: 0.82rem; color: var(--ink-muted); margin: 0.3rem 0 0; }
-.gg-tip { font-size: 0.85rem; color: var(--ink-muted); background: var(--paper); border: 1px solid var(--rule); border-radius: 8px; padding: 0.6rem 0.8rem; margin: 0 0 1.25rem; }
-</style>
-<script>
-  (function () {
-    if (window.__ggCopyWired) return;
-    window.__ggCopyWired = true;
-    document.addEventListener('click', function (e) {
-      var b = e.target.closest && e.target.closest('.gg-copy');
-      if (!b) return;
-      e.preventDefault();
-      var txt = b.getAttribute('data-copy') || '';
-      var done = function () { var o = b.getAttribute('data-label') || b.textContent; b.setAttribute('data-label', o); b.textContent = '<%= t('agoog.copied') %>'; setTimeout(function () { b.textContent = o; }, 1500); };
-      if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(txt).then(done, function () {}); }
-      else { try { var ta = document.createElement('textarea'); ta.value = txt; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove(); done(); } catch (_) {} }
-    });
-  })();
-</script>
Index: src/views/pages/admin-settings.ejs
===================================================================
--- src/views/pages/admin-settings.ejs	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ src/views/pages/admin-settings.ejs	(revision 075185aec7ff8542aa40c1e84a7a70cb05f7599f)
@@ -161,12 +161,4 @@
   </section>
   <% } %>
-
-  <%# Google login has its own admin page (compact link shown here). %>
-  <section class="set-card" style="margin-top:1rem">
-    <h2><%= t('aset.google_login') %></h2>
-    <p class="set-help"><%= t('aset.google_login_help') %>
-      <% if (google && google.configured) { %><strong><%= t('aset.status_set') %>&nbsp;✓</strong><% } else { %><%= t('aset.not_set_yet') %><% } %></p>
-    <div class="set-actions"><a href="/admin/settings/google" class="btn btn-primary"><%= t('aset.google_login_setup') %> &rarr;</a></div>
-  </section>
 
   <%# Newsletter signup in the footer (premium). %>
Index: src/views/pages/admin.ejs
===================================================================
--- src/views/pages/admin.ejs	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ src/views/pages/admin.ejs	(revision 075185aec7ff8542aa40c1e84a7a70cb05f7599f)
@@ -59,5 +59,4 @@
       <a href="/admin/shows" class="btn"><%= t('admin.b_agenda') %></a>
     <% } %>
-    <a href="/admin/settings/google" class="btn"><%= t('admin.b_google') %></a>
     <a href="/admin/updates" class="btn"><%= t('admin.b_updates') %></a>
     <a href="/admin/handleiding" class="btn"><%= t('admin.b_help') %></a>
Index: src/views/pages/auth-login.ejs
===================================================================
--- src/views/pages/auth-login.ejs	(revision 5b476195e7b9aa4c0435ef952a907772473898af)
+++ src/views/pages/auth-login.ejs	(revision 075185aec7ff8542aa40c1e84a7a70cb05f7599f)
@@ -48,30 +48,4 @@
       <p class="auth-link auth-link-muted"><a href="/auth/reset-request"><%= t('auth.forgot') %></a></p>
     </form>
-  <% } else if (googleReady) { %>
-    <%# Public login: Google only, for listeners/fans. %>
-    <p class="auth-sub"><%= t('auth.public_sub') %></p>
-    <a class="btn btn-google" href="/auth/google<%= (typeof next !== 'undefined' && next) ? '?next=' + encodeURIComponent(next) : '' %>">
-      <svg class="g-icon" width="18" height="18" viewBox="0 0 18 18" aria-hidden="true">
-        <path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62z"/>
-        <path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z"/>
-        <path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33z"/>
-        <path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z"/>
-      </svg>
-      <span><%= t('auth.google_btn') %></span>
-    </a>
-  <% } else { %>
-    <div class="alert"><%= t('auth.google_unavail') %></div>
-  <% } %>
-
-  <% if (!_admin) { %>
-    <%# Clickable box for the admin → navigates to the hidden password login. %>
-    <a class="auth-admin-box" href="/auth/admin<%= (typeof next !== 'undefined' && next) ? '?next=' + encodeURIComponent(next) : '' %>">
-      <span class="auth-admin-box-icon" aria-hidden="true">🔑</span>
-      <span class="auth-admin-box-text">
-        <strong><%= t('auth.admin_box_q') %></strong>
-        <small><%= t('auth.admin_box_sub') %></small>
-      </span>
-      <span class="auth-admin-box-arrow" aria-hidden="true">&rarr;</span>
-    </a>
   <% } %>
 </div>
