source: Klonkt/src/views/pages/hub-home.ejs@ 4c5169f

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

hub: overview is a headerless landing with hero image

The hub overview now starts directly with the hero — no masthead/profile-header/
view-switcher/bottom-tab (those belong to a PrutFolio and appear on /user/
pages). Hero supports a background image (setting hub_hero_image, configurable
in Admin) with a dark overlay; otherwise gradient. Roster avatars use each
artist's accent color.

  • shell.ejs: chrome gated on bodyClass 'on-hub'.
  • hub.js: artists.accent + hub.heroImage from settings.
  • admin-settings: hub_hero_image field.

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

  • Property mode set to 100644
File size: 7.4 KB
RevLine 
[4d7443b]1<div class="hub">
[bf61be7]2
[4c5169f]3 <%# ── HERO (label) — de pagina begint hier, geen header erboven ────── %>
4 <header class="hub-hero<%= hub.heroImage ? ' has-img' : '' %>"<% if (hub.heroImage) { %> style="--hero-img:url('<%= hub.heroImage %>')"<% } %>>
[4d7443b]5 <div class="hub-hero-inner container">
[6e0249f]6 <h1 class="hub-hero-title"><%= hub.title %></h1>
7 <% if (hub.tagline) { %>
8 <p class="hub-hero-tag"><%= hub.tagline %></p>
[4d7443b]9 <% } %>
[6e0249f]10 <% if (hub.intro) { %>
11 <p class="hub-hero-desc"><%= hub.intro %></p>
[4d7443b]12 <% } %>
13 </div>
[bf61be7]14 </header>
15
[4d7443b]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 %>">
[4c5169f]25 <span class="roster-avatar"<% if (a.profile_photo) { %> style="background-image:url('<%= a.profile_photo %>')"<% } else { %> style="background:<%= a.accent || 'var(--accent)' %>;color:#fff"<% } %>>
[4d7443b]26 <% if (!a.profile_photo) { %><%= (a.title || a.slug).charAt(0).toUpperCase() %><% } %>
[bf61be7]27 </span>
[4d7443b]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>
[bf61be7]31 </a>
32 <% }); %>
33 </div>
[4d7443b]34 </section>
[bf61be7]35 <% } %>
36
[4d7443b]37 <%# ── LAATSTE POSTS ────────────────────────────────────────────── %>
38 <% if (posts && posts.length) { %>
39 <section class="hub-sec">
[743bb81]40 <h2 class="hub-sec-title">Laatste posts van users</h2>
[4d7443b]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>
[bf61be7]54 <% }); %>
[4d7443b]55 </div>
56 </section>
[bf61be7]57 <% } %>
58
[4d7443b]59 </div>
[bf61be7]60</div>
61
62<style>
[4d7443b]63.hub { width: 100%; }
64
65/* ── Hero ─────────────────────────────────────────────────────────── */
66.hub-hero {
[4c5169f]67 display: flex; align-items: center; justify-content: center;
68 min-height: clamp(340px, 58vh, 560px);
69 text-align: center;
[4d7443b]70 background:
[4c5169f]71 radial-gradient(130% 130% at 50% -10%, color-mix(in srgb, var(--accent) 26%, var(--paper)) 0%, var(--paper) 62%);
[4d7443b]72 border-bottom: 1px solid var(--rule);
73}
[4c5169f]74.hub-hero.has-img {
75 background:
76 linear-gradient(180deg, rgba(0,0,0,.45) 0%, rgba(0,0,0,.55) 100%),
77 var(--hero-img) center / cover no-repeat;
78 border-bottom: 0;
79 color: #fff;
80}
81.hub-hero-inner { padding: 3.5rem 1rem; }
[4d7443b]82.hub-hero-title {
83 font-family: var(--font-display, serif);
[4c5169f]84 font-size: clamp(2.6rem, 7vw, 4.4rem);
85 line-height: 1.02; margin: 0; letter-spacing: -0.015em;
[4d7443b]86}
87.hub-hero-tag {
[4c5169f]88 margin: 0.7rem 0 0; font-size: 1.05rem; font-weight: 600;
89 text-transform: uppercase; letter-spacing: 0.1em;
90 color: var(--accent);
[4d7443b]91}
[4c5169f]92.hub-hero.has-img .hub-hero-tag { color: #fff; opacity: 0.92; }
[4d7443b]93.hub-hero-desc {
[4c5169f]94 margin: 1.1rem auto 0; max-width: 48ch;
95 font-size: 1.1rem; line-height: 1.55; color: var(--ink-muted);
[4d7443b]96}
[4c5169f]97.hub-hero.has-img .hub-hero-desc { color: rgba(255,255,255,.9); }
[bf61be7]98
[4c5169f]99.hub-body { padding-bottom: 4.5rem; }
[4d7443b]100.hub-sec { margin-top: 3rem; }
101.hub-sec-title {
102 font-family: var(--font-display, serif);
103 font-size: 1.5rem; margin: 0 0 1.2rem;
104 display: flex; align-items: center; gap: 0.75rem;
105}
106.hub-sec-title::after { content: ''; flex: 1; height: 1px; background: var(--rule); }
[bf61be7]107
[4d7443b]108/* ── Roster (artiesten) ───────────────────────────────────────────── */
109.roster {
110 display: grid;
111 grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
112 gap: 1rem;
113}
114.roster-card {
115 display: flex; flex-direction: column; align-items: center; text-align: center;
[4c5169f]116 gap: 0.4rem; padding: 1.6rem 1rem 1.3rem;
117 border: 1px solid var(--rule); border-radius: 16px;
[bf61be7]118 background: var(--paper-2); color: var(--ink); text-decoration: none;
[4d7443b]119 transition: border-color 140ms, transform 140ms, box-shadow 140ms;
120}
121.roster-card:hover {
122 border-color: var(--accent); transform: translateY(-3px);
[4c5169f]123 box-shadow: 0 10px 28px -14px color-mix(in srgb, var(--accent) 55%, transparent);
[4d7443b]124}
125.roster-avatar {
[4c5169f]126 width: 88px; height: 88px; border-radius: 50%; margin-bottom: 0.45rem;
127 background-size: cover; background-position: center;
[4d7443b]128 display: inline-flex; align-items: center; justify-content: center;
[4c5169f]129 font-family: var(--font-display, serif); font-size: 2.1rem; font-weight: 700; color: #fff;
130 box-shadow: inset 0 0 0 2px rgba(255,255,255,.18);
[4d7443b]131}
[4c5169f]132.roster-name { font-weight: 700; font-size: 1.1rem; }
[4d7443b]133.roster-tag { color: var(--ink-muted); font-size: 0.82rem; }
134.roster-count {
[4c5169f]135 margin-top: 0.35rem; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em;
[4d7443b]136 color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
137 padding: 0.15rem 0.6rem; border-radius: 99px;
[bf61be7]138}
139
[4d7443b]140/* ── Feed (laatste posts) ─────────────────────────────────────────── */
141.hub-feed { display: flex; flex-direction: column; gap: 0.6rem; }
142.feed-item {
143 display: flex; align-items: center; gap: 1rem;
144 padding: 0.9rem 1rem; border: 1px solid var(--rule); border-radius: 12px;
145 background: var(--paper-2); color: var(--ink); text-decoration: none;
146 transition: border-color 140ms, background 140ms;
147}
148.feed-item:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 5%, var(--paper-2)); }
149.feed-cover {
150 width: 64px; height: 64px; border-radius: 8px; flex-shrink: 0;
151 background-size: cover; background-position: center; background-color: var(--paper);
152}
153.feed-body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; flex: 1; }
154.feed-meta { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--accent); }
155.feed-title { font-weight: 600; font-size: 1.05rem; line-height: 1.25; }
156.feed-excerpt {
157 color: var(--ink-muted); font-size: 0.88rem; line-height: 1.4;
158 display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
159}
160.feed-arrow { color: var(--ink-muted); font-size: 1.2rem; flex-shrink: 0; transition: transform 140ms, color 140ms; }
161.feed-item:hover .feed-arrow { color: var(--accent); transform: translateX(3px); }
[bf61be7]162
[4d7443b]163@media (max-width: 560px) {
[4c5169f]164 .hub-hero-inner { padding: 2.5rem 1rem; }
[4d7443b]165 .feed-cover { width: 52px; height: 52px; }
166 .feed-arrow { display: none; }
167}
[bf61be7]168</style>
Note: See TracBrowser for help on using the repository browser.