Index: c/routes/artists.js
===================================================================
--- src/routes/artists.js	(revision dd856db9b550c437921c0d7464ad5e7133aea91e)
+++ 	(revision )
@@ -1,70 +1,0 @@
-/**
- * Artists directory — hub mode only.
- *
- * GET /leden?q=&page=  -> searchable, paginated list of ALL
- * Klonkt sites. The hub home shows only a limited selection; this page
- * scales to hundreds/thousands of artists via search + pagination.
- *
- * In solo mode there is only one site -> next() (falls through to postsRoutes,
- * which handles 'artiesten' as an unknown slug).
- */
-
-import express from 'express';
-import db from '../config/database.js';
-import { renderPage } from '../middleware/render.js';
-import { getTenancy } from '../services/SettingsService.js';
-
-const router = express.Router();
-
-const PER_PAGE = 24;
-
-router.get('/', (req, res, next) => {
-  if (getTenancy() !== 'hub') return next();
-
-  const q = (req.query.q || '').toString().trim().slice(0, 80);
-  let page = parseInt(req.query.page, 10);
-  if (!Number.isFinite(page) || page < 1) page = 1;
-
-  // The main/label site (oldest) is not an artist -> exclude from the directory,
-  // consistent with the hub home which displays it separately.
-  const mainRow = db.prepare('SELECT id FROM sites ORDER BY created_at ASC LIMIT 1').get();
-  const mainId = mainRow ? mainRow.id : '';
-
-  // Search term against title/slug/tagline (case-insensitive via LIKE; SQLite LIKE is
-  // case-insensitive for ASCII by default). ESCAPE '\' makes %, _, and \
-  // in the search term literal (otherwise they would act as wildcards).
-  const like = '%' + q.replace(/[\\%_]/g, (m) => '\\' + m) + '%';
-  const conds = ['s.id != @mainId'];
-  if (q) conds.push("(s.title LIKE @like ESCAPE '\\' OR s.slug LIKE @like ESCAPE '\\' OR s.tagline LIKE @like ESCAPE '\\')");
-  const where = 'WHERE ' + conds.join(' AND ');
-  const params = q ? { mainId, like } : { mainId };
-
-  const total = db.prepare(`SELECT COUNT(*) AS c FROM sites s ${where}`)
-    .get(params).c;
-  const pages = Math.max(1, Math.ceil(total / PER_PAGE));
-  if (page > pages) page = pages;
-  const offset = (page - 1) * PER_PAGE;
-
-  const artists = db.prepare(`
-    SELECT s.slug, s.title, s.tagline, s.profile_photo, s.accent,
-           u.avatar_url AS owner_avatar,
-           (SELECT COUNT(*) FROM posts WHERE site_id = s.id AND status = 'published') AS post_count
-    FROM sites s
-    LEFT JOIN users u ON u.id = s.owner_id
-    ${where}
-    ORDER BY s.title COLLATE NOCASE ASC
-    LIMIT @limit OFFSET @offset
-  `).all({ ...params, limit: PER_PAGE, offset });
-
-  renderPage(req, res, 'pages/artists-directory', {
-    pageTitle: 'Leden',
-    bodyClass: 'on-hub',
-    q,
-    artists,
-    total,
-    page,
-    pages,
-  });
-});
-
-export default router;
Index: c/routes/hub.js
===================================================================
--- src/routes/hub.js	(revision dd856db9b550c437921c0d7464ad5e7133aea91e)
+++ 	(revision )
@@ -1,89 +1,0 @@
-/**
- * Hub home page — hub mode only. Instead of rendering the primary Klonkt site,
- * '/' renders a company overview here: the latest posts from ALL users combined
- * + a list of the Klonkt sites.
- *
- * In solo mode this does nothing (next()) and posts.js renders the single site.
- */
-
-import express from 'express';
-import db from '../config/database.js';
-import { renderPage } from '../middleware/render.js';
-import { getTenancy, getSetting } from '../services/SettingsService.js';
-
-const router = express.Router();
-
-router.get('/', (req, res, next) => {
-  if (getTenancy() !== 'hub') return next();
-  // If resolveSite addressed a specific site (/user/:slug or /sites/:slug),
-  // req.url was rewritten to '/' — do NOT show the overview but let posts.js
-  // render the site itself. siteUrlBase is set in that case.
-  if (res.locals.siteUrlBase) return next();
-
-  // Latest published posts across all sites.
-  const posts = db.prepare(`
-    SELECT p.title, p.slug, p.excerpt, p.published_at, p.created_at,
-           p.cover_image_url, p.type,
-           s.slug AS site_slug, s.title AS site_title, s.profile_photo AS site_photo,
-           u.username AS author_username
-    FROM posts p
-    JOIN sites s ON s.id = p.site_id
-    LEFT JOIN users u ON u.id = p.author_id
-    WHERE p.status = 'published'
-    ORDER BY COALESCE(p.published_at, p.created_at) DESC
-    LIMIT 24
-  `).all();
-
-  // The main/label site (the explicitly primary = the company/main account) is
-  // NOT an artist; we display it separately at the top, not in the Artists roster.
-  const mainSite = db.prepare(`
-    SELECT s.id, s.slug, s.title, s.tagline, s.profile_photo, s.accent,
-           u.avatar_url AS owner_avatar,
-           (SELECT COUNT(*) FROM posts WHERE site_id = s.id AND status = 'published') AS post_count
-    FROM sites s
-    LEFT JOIN users u ON u.id = s.owner_id
-    WHERE s.is_primary = 1
-    LIMIT 1
-  `).get() || null;
-  const mainId = mainSite ? mainSite.id : '';
-
-  // Featured Klonkt sites for the home roster: most active first (number of
-  // published posts), then newest. Excl. the main site. Capped at
-  // HOME_ROSTER_LIMIT so the home scales — full list is at /leden.
-  const HOME_ROSTER_LIMIT = 24;
-  const artists = db.prepare(`
-    SELECT s.slug, s.title, s.tagline, s.profile_photo, s.accent,
-           u.avatar_url AS owner_avatar,
-           (SELECT COUNT(*) FROM posts WHERE site_id = s.id AND status = 'published') AS post_count
-    FROM sites s
-    LEFT JOIN users u ON u.id = s.owner_id
-    WHERE s.id != @mainId
-    ORDER BY post_count DESC, s.created_at DESC
-    LIMIT @limit
-  `).all({ mainId, limit: HOME_ROSTER_LIMIT });
-  const totalArtists = db.prepare('SELECT COUNT(*) AS c FROM sites WHERE id != ?').get(mainId).c;
-
-  // The hub page is GENERIC (not belonging to any user) — branding comes from global
-  // settings managed by the admin in the admin panel, not from a site.
-  const hub = {
-    title: getSetting('hub_title') || 'Overzicht',
-    tagline: getSetting('hub_tagline') || '',
-    intro: getSetting('hub_intro') || '',
-    heroImage: getSetting('hub_hero_image') || '',
-    heroOverlay: (() => { const v = parseInt(getSetting('hub_hero_overlay'), 10); return Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 45; })(),
-  };
-
-  renderPage(req, res, 'pages/hub-home', {
-    pageTitle: hub.title,
-    socialDescr: hub.intro || hub.tagline || '',
-    bodyClass: 'on-home on-hub',
-    hub,
-    mainSite,
-    artists,
-    totalArtists,
-    rosterLimit: HOME_ROSTER_LIMIT,
-    posts,
-  });
-});
-
-export default router;
Index: src/server.js
===================================================================
--- src/server.js	(revision dd856db9b550c437921c0d7464ad5e7133aea91e)
+++ src/server.js	(revision 48ca5fc43d1ada99e704de7005aa0fcd03b98286)
@@ -40,6 +40,4 @@
 import usersRoutes from './routes/users.js';
 import feedRoutes from './routes/feed.js';
-import hubRoutes from './routes/hub.js';
-import artistsRoutes from './routes/artists.js';
 import postsRoutes from './routes/posts.js';
 import langRoutes from './routes/lang.js';
@@ -320,8 +318,5 @@
 // Feed/sitemap routes are mounted at root because they're at well-known paths
 app.use('/', feedRoutes);
-app.use('/leden', artistsRoutes); // searchable member directory (hub only; solo: next())
-app.get('/artiesten', (req, res) => res.redirect(301, req.originalUrl.replace(/^\/artiesten/, '/leden'))); // oude URL -> /leden
-app.use('/', hubRoutes); // hub-overview op '/' (solo: next() -> postsRoutes)
-app.use('/', circleRoutes); // /cirkel-feed (solo/hub: next() -> postsRoutes)
+app.use('/', circleRoutes); // /cirkel-feed (solo: next() -> postsRoutes)
 app.use('/', epkRoutes); // /pers perskit (premium; niet-premium: next() -> 404)
 app.use('/', newsletterRoutes); // /nieuwsbrief in/uitschrijven (premium; niet-premium: next())
Index: c/views/pages/artists-directory.ejs
===================================================================
--- src/views/pages/artists-directory.ejs	(revision dd856db9b550c437921c0d7464ad5e7133aea91e)
+++ 	(revision )
@@ -1,154 +1,0 @@
-<%
-// Artiesten-directory — bodyClass 'on-hub' => headerloos (bareChrome), dus deze
-// pagina draagt z'n eigen minimale nav + kop, net als de hub-overview.
-function _qs(extra) {
-  const p = new URLSearchParams();
-  if (q) p.set('q', q);
-  Object.keys(extra || {}).forEach(k => p.set(k, extra[k]));
-  const s = p.toString();
-  return s ? ('?' + s) : '';
-}
-%>
-<div class="adir">
-
-  <%# ── Minimale nav (terug naar hub + auth) ── %>
-  <nav class="adir-nav">
-    <div class="adir-nav-inner container">
-      <a class="adir-nav-home" href="/"><span aria-hidden="true">←</span> <%= (typeof hubTitle !== 'undefined' && hubTitle) ? hubTitle : t('adir.home') %></a>
-      <span class="adir-nav-spacer"></span>
-      <% if (user) { %>
-        <a class="adir-nav-link" href="/account"><%= user.username %></a>
-        <a class="adir-nav-link" href="/auth/logout"><%= t('adir.logout') %></a>
-      <% } else { %>
-        <a class="adir-nav-link" href="/auth/login"><%= t('adir.login') %></a>
-      <% } %>
-    </div>
-  </nav>
-
-  <header class="adir-head container">
-    <h1 class="adir-title"><%= t('adir.title') %></h1>
-    <p class="adir-sub"><%= t(total === 1 ? 'adir.count_one' : 'adir.count_many', { n: total }) %></p>
-
-    <form class="adir-search" method="get" action="/leden" role="search">
-      <input type="search" name="q" value="<%= q %>" placeholder="<%= t('adir.search_ph') %>"
-             autocomplete="off" aria-label="<%= t('adir.search_aria') %>">
-      <button type="submit" class="adir-search-btn" aria-label="<%= t('adir.search_btn') %>">
-        <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
-      </button>
-      <% if (q) { %><a class="adir-search-clear" href="/leden"><%= t('adir.clear') %></a><% } %>
-    </form>
-  </header>
-
-  <div class="container adir-body">
-    <% if (!artists.length) { %>
-      <p class="adir-empty">
-        <% if (q) { %><%- t('adir.empty_q', { q: '<strong>' + q + '</strong>' }) %><% } else { %><%= t('adir.empty') %><% } %>
-      </p>
-    <% } else { %>
-      <div class="roster">
-        <% artists.forEach(function(a){ %>
-          <a class="roster-card" href="/user/<%= a.slug %>">
-            <% var _ava = a.profile_photo || a.owner_avatar; %>
-            <span class="roster-avatar"<% if (_ava) { %> style="background-image:url('<%= _ava %>')"<% } else { %> style="background:<%= a.accent || 'var(--accent)' %>;color:#fff"<% } %>>
-              <% if (!_ava) { %><%= (a.title || a.slug).charAt(0).toUpperCase() %><% } %>
-            </span>
-            <span class="roster-name"><%= a.title %></span>
-            <% if (a.tagline) { %><span class="roster-tag"><%= a.tagline %></span><% } %>
-            <span class="roster-count"><%= t(a.post_count === 1 ? 'adir.posts_one' : 'adir.posts_many', { n: a.post_count }) %></span>
-          </a>
-        <% }); %>
-      </div>
-
-      <% if (pages > 1) { %>
-        <nav class="adir-pager" aria-label="<%= t('adir.pager_aria') %>">
-          <% if (page > 1) { %>
-            <a class="adir-page" href="<%= _qs({ page: page - 1 }) %>" rel="prev"><%= t('adir.prev') %></a>
-          <% } else { %>
-            <span class="adir-page is-disabled"><%= t('adir.prev') %></span>
-          <% } %>
-          <span class="adir-page-info"><%= t('adir.page_info', { page: page, pages: pages }) %></span>
-          <% if (page < pages) { %>
-            <a class="adir-page" href="<%= _qs({ page: page + 1 }) %>" rel="next"><%= t('adir.next') %></a>
-          <% } else { %>
-            <span class="adir-page is-disabled"><%= t('adir.next') %></span>
-          <% } %>
-        </nav>
-      <% } %>
-    <% } %>
-  </div>
-</div>
-
-<style>
-.adir { width: 100%; }
-
-/* ── Nav ── */
-.adir-nav { border-bottom: 1px solid var(--rule); padding: 0.9rem 0; }
-.adir-nav-inner { display: flex; align-items: center; gap: 1.2rem; }
-.adir-nav-home { color: var(--ink); text-decoration: none; font-weight: 700; }
-.adir-nav-home:hover { color: var(--accent); }
-.adir-nav-spacer { flex: 1; }
-.adir-nav-link { color: var(--ink-muted); text-decoration: none; font-weight: 600; font-size: 0.9rem; }
-.adir-nav-link:hover { color: var(--accent); }
-
-/* ── Header + search ── */
-.adir-head { padding: 2.5rem 1rem 1.5rem; }
-.adir-title { font-family: var(--font-display, serif); font-size: clamp(2rem, 5vw, 3rem); margin: 0; }
-.adir-sub { color: var(--ink-muted); margin: 0.3rem 0 1.3rem; }
-.adir-search { display: flex; align-items: center; gap: 0.5rem; max-width: 480px; }
-.adir-search input {
-  flex: 1; min-width: 0; box-sizing: border-box;
-  padding: 0.65rem 0.9rem; border: 1px solid var(--rule); border-radius: 99px;
-  background: var(--paper-2); color: var(--ink); font: inherit; font-size: 0.95rem;
-}
-.adir-search input:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
-.adir-search-btn {
-  display: inline-flex; align-items: center; justify-content: center;
-  width: 44px; height: 44px; flex-shrink: 0;
-  border: 1px solid var(--accent); border-radius: 50%;
-  background: var(--accent); color: #fff; cursor: pointer;
-}
-.adir-search-clear { color: var(--ink-muted); font-size: 0.85rem; text-decoration: underline; white-space: nowrap; }
-
-.adir-body { padding-bottom: 4rem; }
-.adir-empty { color: var(--ink-muted); padding: 2rem 0; }
-
-/* ── Roster (zelfde stijl als hub-home) ── */
-.roster {
-  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 1rem;
-}
-.roster-card {
-  display: flex; flex-direction: column; align-items: center; text-align: center;
-  gap: 0.4rem; padding: 1.6rem 1rem 1.3rem;
-  border: 1px solid var(--rule); border-radius: 16px;
-  background: var(--paper-2); color: var(--ink); text-decoration: none;
-  transition: border-color 140ms, transform 140ms, box-shadow 140ms;
-}
-.roster-card:hover {
-  border-color: var(--accent); transform: translateY(-3px);
-  box-shadow: 0 10px 28px -14px color-mix(in srgb, var(--accent) 55%, transparent);
-}
-.roster-avatar {
-  width: 88px; height: 88px; border-radius: 50%; margin-bottom: 0.45rem;
-  background-size: cover; background-position: center;
-  display: inline-flex; align-items: center; justify-content: center;
-  font-family: var(--font-display, serif); font-size: 2.1rem; font-weight: 700; color: #fff;
-  box-shadow: inset 0 0 0 2px rgba(255,255,255,.18);
-}
-.roster-name { font-weight: 700; font-size: 1.1rem; }
-.roster-tag { color: var(--ink-muted); font-size: 0.82rem; }
-.roster-count {
-  margin-top: 0.35rem; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em;
-  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
-  padding: 0.15rem 0.6rem; border-radius: 99px;
-}
-
-/* ── Pager ── */
-.adir-pager { display: flex; align-items: center; justify-content: center; gap: 1.25rem; margin-top: 2.5rem; }
-.adir-page {
-  color: var(--ink); text-decoration: none; font-weight: 600; font-size: 0.9rem;
-  padding: 0.5rem 1rem; border: 1px solid var(--rule); border-radius: 99px;
-}
-.adir-page:hover { border-color: var(--accent); color: var(--accent); }
-.adir-page.is-disabled { color: var(--ink-muted); opacity: 0.4; pointer-events: none; }
-.adir-page-info { color: var(--ink-muted); font-size: 0.85rem; }
-</style>
Index: c/views/pages/hub-home.ejs
===================================================================
--- src/views/pages/hub-home.ejs	(revision dd856db9b550c437921c0d7464ad5e7133aea91e)
+++ 	(revision )
@@ -1,261 +1,0 @@
-<div class="hub<%= hub.heroImage ? ' hub--img' : '' %>">
-
-  <%# ── HERO (label) — the mini topnav bar sits above it (chrome.ejs);
-        the hero itself is the "large" header of the hub home ──────────────── %>
-  <header class="hub-hero<%= hub.heroImage ? ' has-img' : '' %>"<% if (hub.heroImage) { %> style="--hero-img:url('<%= hub.heroImage %>'); --hero-ov:<%= ((hub.heroOverlay == null ? 45 : hub.heroOverlay)/100).toFixed(2) %>"<% } %>>
-    <div class="hub-hero-inner container">
-      <h1 class="hub-hero-title"><%= hub.title %></h1>
-      <% if (hub.tagline) { %>
-        <p class="hub-hero-tag"><%= hub.tagline %></p>
-      <% } %>
-      <% if (hub.intro) { %>
-        <p class="hub-hero-desc"><%= hub.intro %></p>
-      <% } %>
-    </div>
-  </header>
-
-  <div class="container hub-body">
-
-    <%# ── MAIN PAGE (label-/primary account — not an artist) ──────────── %>
-    <% if (mainSite) { %>
-    <section class="hub-sec hub-sec-main">
-      <a class="hub-main-card" href="/user/<%= mainSite.slug %>"
-         hx-get="/user/<%= mainSite.slug %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-         hx-push-url="/user/<%= mainSite.slug %>" hx-indicator="#pcms-loading">
-        <% var _mAva = mainSite.profile_photo || mainSite.owner_avatar; %>
-        <span class="hub-main-avatar"<% if (_mAva) { %> style="background-image:url('<%= _mAva %>')"<% } else { %> style="background:<%= mainSite.accent || 'var(--accent)' %>;color:#fff"<% } %>>
-          <% if (!_mAva) { %><%= (mainSite.title || mainSite.slug).charAt(0).toUpperCase() %><% } %>
-        </span>
-        <span class="hub-main-info">
-          <span class="hub-main-badge"><%= t('phub.main_badge') %></span>
-          <span class="hub-main-name"><%= mainSite.title %></span>
-          <% if (mainSite.tagline) { %><span class="hub-main-tag"><%= mainSite.tagline %></span><% } %>
-        </span>
-        <span class="hub-main-cta"><%= t('phub.view_page') %> <span aria-hidden="true">→</span></span>
-      </a>
-    </section>
-    <% } %>
-
-    <%# ── ARTIST ROSTER ─────────────────────────────────────────── %>
-    <% if (artists && artists.length) { %>
-    <% var _total = (typeof totalArtists !== 'undefined') ? totalArtists : artists.length; %>
-    <% var _hasMore = _total > artists.length; %>
-    <section class="hub-sec">
-      <h2 class="hub-sec-title">
-        <%= t('phub.members') %>
-        <% if (_hasMore) { %><span class="hub-sec-count"><%= _total %></span><% } %>
-      </h2>
-      <div class="roster">
-        <% artists.forEach(function(a){ %>
-          <a class="roster-card" href="/user/<%= a.slug %>"
-             hx-get="/user/<%= a.slug %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-             hx-push-url="/user/<%= a.slug %>" hx-indicator="#pcms-loading">
-            <% var _ava = a.profile_photo || a.owner_avatar; %>
-            <span class="roster-avatar"<% if (_ava) { %> style="background-image:url('<%= _ava %>')"<% } else { %> style="background:<%= a.accent || 'var(--accent)' %>;color:#fff"<% } %>>
-              <% if (!_ava) { %><%= (a.title || a.slug).charAt(0).toUpperCase() %><% } %>
-            </span>
-            <span class="roster-name"><%= a.title %></span>
-            <% if (a.tagline) { %><span class="roster-tag"><%= a.tagline %></span><% } %>
-            <span class="roster-count"><%= a.post_count %> <%= a.post_count === 1 ? t('phub.post_one') : t('phub.post_many') %></span>
-          </a>
-        <% }); %>
-      </div>
-      <% if (_hasMore) { %>
-        <div class="hub-more">
-          <a class="hub-more-link" href="/leden"><%= t('phub.all_members', { n: _total }) %> <span aria-hidden="true">→</span></a>
-        </div>
-      <% } %>
-    </section>
-    <% } %>
-
-    <%# ── LATEST POSTS ────────────────────────────────────────────── %>
-    <% if (posts && posts.length) { %>
-    <section class="hub-sec">
-      <h2 class="hub-sec-title"><%= t('phub.latest_posts') %></h2>
-      <div class="hub-feed">
-        <% posts.forEach(function(p){ %>
-          <a class="feed-item" href="/user/<%= p.site_slug %>/<%= p.slug %>"
-             hx-get="/user/<%= p.site_slug %>/<%= p.slug %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
-             hx-push-url="/user/<%= p.site_slug %>/<%= p.slug %>" hx-indicator="#pcms-loading">
-            <% if (p.cover_image_url) { %>
-              <span class="feed-cover" style="background-image:url('<%= p.cover_image_url %>')"></span>
-            <% } %>
-            <span class="feed-body">
-              <span class="feed-meta"><%= p.site_title %> · <%= formatDate(p.published_at || p.created_at) %></span>
-              <span class="feed-title"><%= p.title %></span>
-              <% if (p.excerpt) { %><span class="feed-excerpt"><%= p.excerpt %></span><% } %>
-            </span>
-            <span class="feed-arrow" aria-hidden="true">→</span>
-          </a>
-        <% }); %>
-      </div>
-    </section>
-    <% } %>
-
-  </div>
-</div>
-
-<style>
-.hub { width: 100%; position: relative; }
-
-/* Hero connects directly to the mini topnav bar — no gap above the
-   hub home (overrides the global main-padding-top). */
-.pcms-main { padding-top: 0; }
-.hub-hero { margin-top: 0; }
-
-/* ── Hero ─────────────────────────────────────────────────────────── */
-.hub-hero {
-  display: flex; align-items: center; justify-content: center;
-  min-height: clamp(340px, 58vh, 560px);
-  text-align: center;
-  background:
-    radial-gradient(130% 130% at 50% -10%, color-mix(in srgb, var(--accent) 26%, var(--paper)) 0%, var(--paper) 62%);
-  border-bottom: 1px solid var(--rule);
-}
-.hub-hero.has-img {
-  background:
-    linear-gradient(rgba(0,0,0,var(--hero-ov,.45)), rgba(0,0,0,var(--hero-ov,.45))),
-    var(--hero-img) center / cover no-repeat;
-  border-bottom: 0;
-  color: #fff;
-}
-.hub-hero-inner { padding: 3.5rem 1rem; }
-.hub-hero-title {
-  font-family: var(--font-display, serif);
-  font-size: clamp(2.6rem, 7vw, 4.4rem);
-  line-height: 1.02; margin: 0; letter-spacing: -0.015em;
-}
-.hub-hero-tag {
-  margin: 0.7rem 0 0; font-size: 1.05rem; font-weight: 600;
-  text-transform: uppercase; letter-spacing: 0.1em;
-  color: var(--accent);
-}
-.hub-hero.has-img .hub-hero-tag { color: #fff; opacity: 0.92; }
-.hub-hero-desc {
-  margin: 1.1rem auto 0; max-width: 48ch;
-  font-size: 1.1rem; line-height: 1.55; color: var(--ink-muted);
-}
-.hub-hero.has-img .hub-hero-desc { color: rgba(255,255,255,.9); }
-
-.hub-body { padding-bottom: 4.5rem; }
-.hub-sec { margin-top: 3rem; }
-.hub-sec-title {
-  font-family: var(--font-display, serif);
-  font-size: 1.5rem; margin: 0 0 1.2rem;
-  display: flex; align-items: center; gap: 0.75rem;
-}
-.hub-sec-title::after { content: ''; flex: 1; height: 1px; background: var(--rule); }
-.hub-sec-count {
-  font-family: var(--font-ui, system-ui); font-size: 0.8rem; font-weight: 700;
-  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
-  padding: 0.1rem 0.55rem; border-radius: 99px; order: 1;
-}
-.hub-more { margin-top: 1.25rem; text-align: center; }
-.hub-more-link {
-  display: inline-flex; align-items: center; gap: 0.4rem;
-  padding: 0.6rem 1.3rem; border: 1px solid var(--rule); border-radius: 99px;
-  background: var(--paper-2); color: var(--ink); text-decoration: none;
-  font-weight: 600; font-size: 0.92rem; transition: border-color 140ms, background 140ms;
-}
-.hub-more-link:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 7%, var(--paper-2)); }
-
-/* ── Main page card (label-/primary account, separate from the artists) ── */
-.hub-sec-main { margin-top: 2.25rem; }
-.hub-main-card {
-  display: flex; align-items: center; gap: 1.25rem;
-  padding: 1.2rem 1.5rem;
-  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--rule));
-  border-radius: 18px;
-  background: linear-gradient(120deg, color-mix(in srgb, var(--accent) 11%, var(--paper-2)) 0%, var(--paper-2) 72%);
-  color: var(--ink); text-decoration: none;
-  transition: border-color 140ms, transform 140ms, box-shadow 140ms;
-}
-.hub-main-card:hover {
-  border-color: var(--accent); transform: translateY(-2px);
-  box-shadow: 0 12px 30px -16px color-mix(in srgb, var(--accent) 60%, transparent);
-}
-.hub-main-avatar {
-  width: 72px; height: 72px; border-radius: 50%; flex-shrink: 0;
-  background-size: cover; background-position: center;
-  display: inline-flex; align-items: center; justify-content: center;
-  font-family: var(--font-display, serif); font-size: 1.8rem; font-weight: 700; color: #fff;
-  box-shadow: inset 0 0 0 2px rgba(255,255,255,.18);
-}
-.hub-main-info { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; flex: 1; }
-.hub-main-badge {
-  align-self: flex-start; font-size: 0.65rem; font-weight: 700;
-  text-transform: uppercase; letter-spacing: 0.08em;
-  color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent);
-  padding: 0.12rem 0.55rem; border-radius: 99px;
-}
-.hub-main-name { font-family: var(--font-display, serif); font-size: 1.5rem; font-weight: 700; line-height: 1.1; }
-.hub-main-tag { color: var(--ink-muted); font-size: 0.9rem; }
-.hub-main-cta { color: var(--accent); font-weight: 600; font-size: 0.9rem; white-space: nowrap; flex-shrink: 0; }
-@media (max-width: 560px) {
-  .hub-main-card { flex-direction: column; text-align: center; }
-  .hub-main-info { align-items: center; }
-  .hub-main-badge { align-self: center; }
-  .hub-main-cta { display: none; }
-}
-
-/* ── Roster (artists) ───────────────────────────────────────────── */
-.roster {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
-  gap: 1rem;
-}
-.roster-card {
-  display: flex; flex-direction: column; align-items: center; text-align: center;
-  gap: 0.4rem; padding: 1.6rem 1rem 1.3rem;
-  border: 1px solid var(--rule); border-radius: 16px;
-  background: var(--paper-2); color: var(--ink); text-decoration: none;
-  transition: border-color 140ms, transform 140ms, box-shadow 140ms;
-}
-.roster-card:hover {
-  border-color: var(--accent); transform: translateY(-3px);
-  box-shadow: 0 10px 28px -14px color-mix(in srgb, var(--accent) 55%, transparent);
-}
-.roster-avatar {
-  width: 88px; height: 88px; border-radius: 50%; margin-bottom: 0.45rem;
-  background-size: cover; background-position: center;
-  display: inline-flex; align-items: center; justify-content: center;
-  font-family: var(--font-display, serif); font-size: 2.1rem; font-weight: 700; color: #fff;
-  box-shadow: inset 0 0 0 2px rgba(255,255,255,.18);
-}
-.roster-name { font-weight: 700; font-size: 1.1rem; }
-.roster-tag { color: var(--ink-muted); font-size: 0.82rem; }
-.roster-count {
-  margin-top: 0.35rem; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em;
-  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
-  padding: 0.15rem 0.6rem; border-radius: 99px;
-}
-
-/* ── Feed (latest posts) ─────────────────────────────────────────── */
-.hub-feed { display: flex; flex-direction: column; gap: 0.6rem; }
-.feed-item {
-  display: flex; align-items: center; gap: 1rem;
-  padding: 0.9rem 1rem; border: 1px solid var(--rule); border-radius: 12px;
-  background: var(--paper-2); color: var(--ink); text-decoration: none;
-  transition: border-color 140ms, background 140ms;
-}
-.feed-item:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 5%, var(--paper-2)); }
-.feed-cover {
-  width: 64px; height: 64px; border-radius: 8px; flex-shrink: 0;
-  background-size: cover; background-position: center; background-color: var(--paper);
-}
-.feed-body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; flex: 1; }
-.feed-meta { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); }
-.feed-title { font-weight: 600; font-size: 1.05rem; line-height: 1.25; }
-.feed-excerpt {
-  color: var(--ink-muted); font-size: 0.88rem; line-height: 1.4;
-  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
-}
-.feed-arrow { color: var(--ink-muted); font-size: 1.2rem; flex-shrink: 0; transition: transform 140ms, color 140ms; }
-.feed-item:hover .feed-arrow { color: var(--accent); transform: translateX(3px); }
-
-@media (max-width: 560px) {
-  .hub-hero-inner { padding: 2.5rem 1rem; }
-  .feed-cover { width: 52px; height: 52px; }
-  .feed-arrow { display: none; }
-}
-</style>
