source: Klonkt/src/views/pages/hub-home.ejs@ 6e0249f

main
Last change on this file since 6e0249f was 6e0249f, checked in by roboburr <roboburr@…>, 3 months ago

hub: generic home page (not owned by any user) + admin-managed branding

The hub home page was the oldest site (a user's PrutFolio). Now it is a
generic page: title/tagline/intro come from global settings (hub_title/
hub_tagline/hub_intro), editable in Admin -> Settings (hub only). The roster
now shows ALL users (including the admin's own PrutFolio under /user/<slug>)
— no site is singled out as "the company" any more.

POST /admin/settings only updates tenancy when the field is present (a
separate branding form no longer accidentally flips the mode).

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 6.9 KB
Line 
1<div class="hub">
2
3 <%# ── HERO (label / bedrijf) ─────────────────────────────────────── %>
4 <header class="hub-hero">
5 <div class="hub-hero-inner container">
6 <h1 class="hub-hero-title"><%= hub.title %></h1>
7 <% if (hub.tagline) { %>
8 <p class="hub-hero-tag"><%= hub.tagline %></p>
9 <% } %>
10 <% if (hub.intro) { %>
11 <p class="hub-hero-desc"><%= hub.intro %></p>
12 <% } %>
13 </div>
14 </header>
15
16 <div class="container hub-body">
17
18 <%# ── ARTIESTEN-ROSTER ─────────────────────────────────────────── %>
19 <% if (artists && artists.length) { %>
20 <section class="hub-sec">
21 <h2 class="hub-sec-title">Artiesten</h2>
22 <div class="roster">
23 <% artists.forEach(function(a){ %>
24 <a class="roster-card" href="/user/<%= a.slug %>">
25 <span class="roster-avatar"<% if (a.profile_photo) { %> style="background-image:url('<%= a.profile_photo %>')"<% } %>>
26 <% if (!a.profile_photo) { %><%= (a.title || a.slug).charAt(0).toUpperCase() %><% } %>
27 </span>
28 <span class="roster-name"><%= a.title %></span>
29 <% if (a.tagline) { %><span class="roster-tag"><%= a.tagline %></span><% } %>
30 <span class="roster-count"><%= a.post_count %> post<%= a.post_count === 1 ? '' : 's' %></span>
31 </a>
32 <% }); %>
33 </div>
34 </section>
35 <% } %>
36
37 <%# ── LAATSTE POSTS ────────────────────────────────────────────── %>
38 <% if (posts && posts.length) { %>
39 <section class="hub-sec">
40 <h2 class="hub-sec-title">Laatste posts van users</h2>
41 <div class="hub-feed">
42 <% posts.forEach(function(p){ %>
43 <a class="feed-item" href="/user/<%= p.site_slug %>/<%= p.slug %>">
44 <% if (p.cover_image_url) { %>
45 <span class="feed-cover" style="background-image:url('<%= p.cover_image_url %>')"></span>
46 <% } %>
47 <span class="feed-body">
48 <span class="feed-meta"><%= p.site_title %> · <%= formatDate(p.published_at || p.created_at) %></span>
49 <span class="feed-title"><%= p.title %></span>
50 <% if (p.excerpt) { %><span class="feed-excerpt"><%= p.excerpt %></span><% } %>
51 </span>
52 <span class="feed-arrow" aria-hidden="true">→</span>
53 </a>
54 <% }); %>
55 </div>
56 </section>
57 <% } %>
58
59 </div>
60</div>
61
62<style>
63.hub { width: 100%; }
64
65/* ── Hero ─────────────────────────────────────────────────────────── */
66.hub-hero {
67 background:
68 radial-gradient(120% 140% at 50% -20%, color-mix(in srgb, var(--accent) 22%, var(--paper)) 0%, var(--paper) 60%);
69 border-bottom: 1px solid var(--rule);
70 text-align: center;
71}
72.hub-hero-inner { padding: 4rem 1rem 3.25rem; }
73.hub-hero-title {
74 font-family: var(--font-display, serif);
75 font-size: clamp(2.4rem, 6vw, 3.6rem);
76 line-height: 1.05; margin: 0;
77 letter-spacing: -0.01em;
78}
79.hub-hero-tag {
80 margin: 0.6rem 0 0; font-size: 1.05rem; font-weight: 600;
81 color: var(--accent); text-transform: uppercase; letter-spacing: 0.08em;
82}
83.hub-hero-desc {
84 margin: 1rem auto 0; max-width: 46ch;
85 color: var(--ink-muted); font-size: 1.05rem; line-height: 1.5;
86}
87
88.hub-body { padding-bottom: 4rem; }
89.hub-sec { margin-top: 3rem; }
90.hub-sec-title {
91 font-family: var(--font-display, serif);
92 font-size: 1.5rem; margin: 0 0 1.2rem;
93 display: flex; align-items: center; gap: 0.75rem;
94}
95.hub-sec-title::after { content: ''; flex: 1; height: 1px; background: var(--rule); }
96
97/* ── Roster (artiesten) ───────────────────────────────────────────── */
98.roster {
99 display: grid;
100 grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
101 gap: 1rem;
102}
103.roster-card {
104 display: flex; flex-direction: column; align-items: center; text-align: center;
105 gap: 0.4rem; padding: 1.5rem 1rem 1.25rem;
106 border: 1px solid var(--rule); border-radius: 14px;
107 background: var(--paper-2); color: var(--ink); text-decoration: none;
108 transition: border-color 140ms, transform 140ms, box-shadow 140ms;
109}
110.roster-card:hover {
111 border-color: var(--accent); transform: translateY(-3px);
112 box-shadow: 0 8px 24px -12px color-mix(in srgb, var(--accent) 50%, transparent);
113}
114.roster-avatar {
115 width: 84px; height: 84px; border-radius: 50%; margin-bottom: 0.4rem;
116 background-size: cover; background-position: center; background-color: var(--paper);
117 display: inline-flex; align-items: center; justify-content: center;
118 font-family: var(--font-display, serif); font-size: 2rem; font-weight: 600; color: var(--accent);
119 border: 2px solid color-mix(in srgb, var(--accent) 30%, var(--rule));
120}
121.roster-name { font-weight: 700; font-size: 1.08rem; }
122.roster-tag { color: var(--ink-muted); font-size: 0.82rem; }
123.roster-count {
124 margin-top: 0.3rem; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em;
125 color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
126 padding: 0.15rem 0.6rem; border-radius: 99px;
127}
128
129/* ── Feed (laatste posts) ─────────────────────────────────────────── */
130.hub-feed { display: flex; flex-direction: column; gap: 0.6rem; }
131.feed-item {
132 display: flex; align-items: center; gap: 1rem;
133 padding: 0.9rem 1rem; border: 1px solid var(--rule); border-radius: 12px;
134 background: var(--paper-2); color: var(--ink); text-decoration: none;
135 transition: border-color 140ms, background 140ms;
136}
137.feed-item:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 5%, var(--paper-2)); }
138.feed-cover {
139 width: 64px; height: 64px; border-radius: 8px; flex-shrink: 0;
140 background-size: cover; background-position: center; background-color: var(--paper);
141}
142.feed-body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; flex: 1; }
143.feed-meta { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); }
144.feed-title { font-weight: 600; font-size: 1.05rem; line-height: 1.25; }
145.feed-excerpt {
146 color: var(--ink-muted); font-size: 0.88rem; line-height: 1.4;
147 display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
148}
149.feed-arrow { color: var(--ink-muted); font-size: 1.2rem; flex-shrink: 0; transition: transform 140ms, color 140ms; }
150.feed-item:hover .feed-arrow { color: var(--accent); transform: translateX(3px); }
151
152@media (max-width: 560px) {
153 .hub-hero-inner { padding: 2.75rem 1rem 2.25rem; }
154 .feed-cover { width: 52px; height: 52px; }
155 .feed-arrow { display: none; }
156}
157</style>
Note: See TracBrowser for help on using the repository browser.