| 1 | <!-- Profile header (v9 structure)
|
|---|
| 2 | Body class controls collapse:
|
|---|
| 3 | .on-home → full size, avatar + bio + links
|
|---|
| 4 | .on-post → compact, just avatar + name
|
|---|
| 5 | .on-special → compact (archive/search/tag pages)
|
|---|
| 6 | .on-admin → hidden (admin pages don't show profile)
|
|---|
| 7 | -->
|
|---|
| 8 |
|
|---|
| 9 | <%
|
|---|
| 10 | // Show profile-header unless we're on an admin page or the site explicitly
|
|---|
| 11 | // disabled it via profile_enabled=0.
|
|---|
| 12 | const _showProfile = site
|
|---|
| 13 | && (site.profile_enabled === undefined || site.profile_enabled !== 0)
|
|---|
| 14 | && !(typeof bodyClass !== 'undefined' && bodyClass.indexOf('on-admin') >= 0);
|
|---|
| 15 |
|
|---|
| 16 | // profile_name and profile_bio used to be optional overrides exposed in the
|
|---|
| 17 | // admin form. P62 removed those form fields — title and description are the
|
|---|
| 18 | // single source of truth. We still consult the override columns first for
|
|---|
| 19 | // backward compat with any legacy data, but the form no longer writes them.
|
|---|
| 20 | const _displayName = (site && (site.profile_name || site.title)) || '';
|
|---|
| 21 | const _bioText = (site && (site.profile_bio || site.description || site.tagline)) || '';
|
|---|
| 22 |
|
|---|
| 23 | // Parse profile_links JSON column once.
|
|---|
| 24 | let _profileLinks = [];
|
|---|
| 25 | if (site && site.profile_links) {
|
|---|
| 26 | try { _profileLinks = JSON.parse(site.profile_links) || []; } catch (e) { _profileLinks = []; }
|
|---|
| 27 | }
|
|---|
| 28 |
|
|---|
| 29 | // Profile-summary (lightbox) helpers — used by the avatar + the summary modal.
|
|---|
| 30 | const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
|
|---|
| 31 | const _avatarUrl = (site && site.profile_photo) || ((typeof siteOwnerAvatar !== 'undefined' && siteOwnerAvatar) || '');
|
|---|
| 32 | const _platforms = (typeof platforms_catalog !== 'undefined' && platforms_catalog) || {};
|
|---|
| 33 | const _linkHref = function (p, u) { u = String(u || '').trim(); if (p === 'email' && u && u.indexOf('mailto:') !== 0) return 'mailto:' + u; if (p === 'phone' && u && !/^tel:/i.test(u)) return 'tel:' + u.replace(/[^\d+]/g, ''); return u; };
|
|---|
| 34 | const _linkVal = function (u) { return String(u || '').replace(/^(mailto:|tel:|https?:\/\/)/i, '').replace(/\/$/, ''); };
|
|---|
| 35 | const _isPrem = (typeof isPremium !== 'undefined' && isPremium);
|
|---|
| 36 | let _sinceStr = ''; try { if (site && site.created_at) _sinceStr = new Date(site.created_at).toLocaleDateString('nl-NL', { day: '2-digit', month: 'short', year: 'numeric' }); } catch (e) {}
|
|---|
| 37 | %>
|
|---|
| 38 |
|
|---|
| 39 | <% if (_showProfile) { %>
|
|---|
| 40 | <aside class="profile-header" aria-label="Site profile">
|
|---|
| 41 | <div class="container profile-header-inner">
|
|---|
| 42 |
|
|---|
| 43 | <%# Clicking the avatar — photo OR placeholder — opens the profile-summary modal. %>
|
|---|
| 44 | <button type="button" class="profile-photo" data-pf-summary aria-label="<%= _displayName || 'Profile' %>">
|
|---|
| 45 | <% if (_avatarUrl) { %>
|
|---|
| 46 | <img src="<%= avatar(_avatarUrl, 256) %>" alt="">
|
|---|
| 47 | <% } else if (site.enable_audio_player && (typeof audioEnabled === 'undefined' || audioEnabled)) { %>
|
|---|
| 48 | <span class="profile-photo-fallback profile-photo-fallback--music" aria-hidden="true">
|
|---|
| 49 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|---|
| 50 | <path d="M9 17V5l12-2v12"/>
|
|---|
| 51 | <circle cx="6" cy="17" r="3"/>
|
|---|
| 52 | <circle cx="18" cy="15" r="3"/>
|
|---|
| 53 | </svg>
|
|---|
| 54 | </span>
|
|---|
| 55 | <% } else { %>
|
|---|
| 56 | <span class="profile-photo-fallback" aria-hidden="true"><%= (_displayName || '?').charAt(0).toUpperCase() %></span>
|
|---|
| 57 | <% } %>
|
|---|
| 58 | </button>
|
|---|
| 59 |
|
|---|
| 60 | <div class="profile-info">
|
|---|
| 61 | <h2 class="profile-name">
|
|---|
| 62 | <a href="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/"
|
|---|
| 63 | hx-get="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/?partial=1"
|
|---|
| 64 | hx-target="#pcms-main" hx-swap="innerHTML"
|
|---|
| 65 | hx-push-url="<%= (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '' %>/"
|
|---|
| 66 | hx-indicator="#pcms-loading">
|
|---|
| 67 | <%= _displayName %>
|
|---|
| 68 | </a>
|
|---|
| 69 | </h2>
|
|---|
| 70 | <% if (_bioText) { %>
|
|---|
| 71 | <p class="profile-bio"><%= _bioText %></p>
|
|---|
| 72 | <% } %>
|
|---|
| 73 |
|
|---|
| 74 | <%# Follow-via-fediverse: a compact icon in the links row (keeps the header
|
|---|
| 75 | short), and hidden for the owner — you don't follow yourself. %>
|
|---|
| 76 | <% var _showFollow = (typeof canManageFedi === 'undefined' || !canManageFedi) && site && site.slug && (typeof apEnabled === 'undefined' || apEnabled); %>
|
|---|
| 77 | <% if (_profileLinks.length || _showFollow) { %>
|
|---|
| 78 | <% const _platforms = (typeof platforms_catalog !== 'undefined' && platforms_catalog) || {}; %>
|
|---|
| 79 | <ul class="profile-links" aria-label="External links">
|
|---|
| 80 | <% _profileLinks.forEach(function(l) {
|
|---|
| 81 | const meta = _platforms[l.platform];
|
|---|
| 82 | if (!meta) return; %>
|
|---|
| 83 | <li>
|
|---|
| 84 | <a class="profile-link profile-link--<%= l.platform %>"
|
|---|
| 85 | href="<%= l.platform === 'email' && l.url.indexOf('mailto:') !== 0 ? ('mailto:' + l.url) : l.url %>"
|
|---|
| 86 | target="<%= l.platform === 'email' ? '_self' : '_blank' %>"
|
|---|
| 87 | rel="noopener noreferrer"
|
|---|
| 88 | aria-label="<%= meta.label %>"
|
|---|
| 89 | title="<%= meta.label %>"
|
|---|
| 90 | style="--brand: <%= meta.brand %>">
|
|---|
| 91 | <%- meta.svg %>
|
|---|
| 92 | </a>
|
|---|
| 93 | </li>
|
|---|
| 94 | <% }); %>
|
|---|
| 95 | <% if (_showFollow) { %>
|
|---|
| 96 | <li style="order:-1">
|
|---|
| 97 | <button type="button" class="profile-link profile-fedi-link" data-fedi-actor-slug="<%= site.slug %>"
|
|---|
| 98 | aria-label="<%= t('fedi.profile_follow') %>" title="<%= t('fedi.profile_follow') %>"><svg viewBox="151 31 530 530" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><g transform="translate(6.6789703,-32.495842)"><path d="M257.1,266.8c-4.9,9.4-12.6,17.1-22.1,22l121.3,121.8l29.2-14.8L257.1,266.8z M417.1,427.4l-29.2,14.8l61.5,61.7c4.9-9.4,12.6-17.1,22.1-22L417.1,427.4z"/><path d="M557.5,315l-68.7,34.8l5.1,32.4l77.7-39.4C564.1,335.2,559.2,325.5,557.5,315z M448.9,370l-162.4,82.3c7.5,7.6,12.4,17.3,14.1,27.8L454,402.4L448.9,370z"/><path d="M396.7,167.3l-78.4,153l23.1,23.2l83-162C414,179.7,404.3,174.7,396.7,167.3z M298,360l-39.7,77.5c10.5,1.8,20.2,6.7,27.7,14.2l35.1-68.5L298,360z"/><path d="M234.3,289.1c-8,4-16.9,5.9-25.8,5.4c-1.7-0.1-3.3-0.3-5-0.5l23.2,148.2c8-4,16.9-5.9,25.8-5.4c1.7,0.1,3.3,0.3,5,0.5L234.3,289.1z"/><path d="M300.8,480.8c0.5,3.4,0.7,6.9,0.5,10.4c-0.4,7.1-2.3,14-5.5,20.4l148.2,23.8c-0.5-3.4-0.7-6.9-0.5-10.4c0.4-7.1,2.3-14,5.5-20.4L300.8,480.8z"/><path d="M572.1,343.3l-68.4,133.6c10.5,1.8,20.2,6.7,27.7,14.2l68.4-133.6C589.4,355.8,579.7,350.8,572.1,343.3z"/><path d="M478.8,154.4c-4.9,9.4-12.6,17.1-22.1,22l105.9,106.4c4.9-9.4,12.6-17.1,22.1-22L478.8,154.4z"/><path d="M382.1,138.9l-133.9,67.9c7.5,7.6,12.4,17.3,14.1,27.8l133.9-67.9C388.7,159.1,383.8,149.4,382.1,138.9z"/><path d="M456.5,176.6c-8.1,4.1-17.1,6.1-26.2,5.6c-1.5-0.1-3-0.3-4.5-0.5l11.9,76l32.4,5.2L456.5,176.6z M444.5,301.8l28.1,179.6c7.9-3.9,16.7-5.7,25.4-5.2c1.8,0.1,3.6,0.3,5.4,0.6L476.8,307L444.5,301.8z"/><path d="M262.4,235.2c0.6,3.5,0.7,7,0.6,10.6c-0.4,7-2.2,13.9-5.4,20.2l76,12.2l14.9-29.2L262.4,235.2z M392.7,256.1l-14.9,29.2l179.6,28.9c-0.5-3.4-0.7-6.9-0.5-10.3c0.4-7.1,2.3-14.1,5.5-20.5L392.7,256.1z"/><circle cx="433" cy="130.6" r="47"/><circle cx="608.4" cy="306.6" r="47"/><circle cx="495.1" cy="527.8" r="47"/><circle cx="249.7" cy="488.4" r="47"/><circle cx="211.3" cy="242.9" r="47"/></g></svg></button>
|
|---|
| 99 | </li>
|
|---|
| 100 | <% } %>
|
|---|
| 101 | </ul>
|
|---|
| 102 | <% } %>
|
|---|
| 103 | </div>
|
|---|
| 104 |
|
|---|
| 105 | </div>
|
|---|
| 106 | </aside>
|
|---|
| 107 |
|
|---|
| 108 | <%# Profile-summary modal — opened by clicking the avatar. Shows photo + title + subtitle
|
|---|
| 109 | + contact details + start date + premium status. %>
|
|---|
| 110 | <div class="pf-summary">
|
|---|
| 111 | <div class="pf-summary-card" role="dialog" aria-label="<%= _displayName %>">
|
|---|
| 112 | <button type="button" class="pf-summary-close" aria-label="Sluiten">×</button>
|
|---|
| 113 | <% if (_avatarUrl) { %>
|
|---|
| 114 | <img class="pf-summary-photo" src="<%= avatar(_avatarUrl, 128) %>" alt="">
|
|---|
| 115 | <% } else { %>
|
|---|
| 116 | <div class="pf-summary-photo pf-summary-photo--ph" aria-hidden="true">
|
|---|
| 117 | <% if (site.enable_audio_player && (typeof audioEnabled === 'undefined' || audioEnabled)) { %>
|
|---|
| 118 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17V5l12-2v12"/><circle cx="6" cy="17" r="3"/><circle cx="18" cy="15" r="3"/></svg>
|
|---|
| 119 | <% } else { %><span><%= (_displayName || '?').charAt(0).toUpperCase() %></span><% } %>
|
|---|
| 120 | </div>
|
|---|
| 121 | <% } %>
|
|---|
| 122 | <h3 class="pf-summary-name"><%= _displayName %></h3>
|
|---|
| 123 | <span class="pf-summary-prem<%= _isPrem ? ' is-prem' : '' %>"><%= _isPrem ? '★ Premium' : t('profile.free') %></span>
|
|---|
| 124 | <% if (_bioText) { %><p class="pf-summary-bio"><%= _bioText %></p><% } %>
|
|---|
| 125 | <% if (_profileLinks.length) { %>
|
|---|
| 126 | <ul class="pf-summary-links">
|
|---|
| 127 | <% _profileLinks.forEach(function (l) { var meta = _platforms[l.platform]; if (!meta) return; var href = _linkHref(l.platform, l.url); var ext = (l.platform !== 'email' && l.platform !== 'phone'); %>
|
|---|
| 128 | <li>
|
|---|
| 129 | <a href="<%= href %>" <% if (ext) { %>target="_blank" rel="noopener noreferrer"<% } %> style="--brand: <%= meta.brand %>">
|
|---|
| 130 | <span class="pf-summary-ico" aria-hidden="true"><%- meta.svg %></span>
|
|---|
| 131 | <span class="pf-summary-rowtext"><span class="pf-summary-lbl"><%= meta.label %></span><span class="pf-summary-val"><%= _linkVal(l.url) %></span></span>
|
|---|
| 132 | </a>
|
|---|
| 133 | </li>
|
|---|
| 134 | <% }); %>
|
|---|
| 135 | </ul>
|
|---|
| 136 | <% } %>
|
|---|
| 137 | <% if (_showFollow) { %>
|
|---|
| 138 | <button type="button" class="pf-summary-follow profile-fedi-link" data-fedi-actor-slug="<%= site.slug %>" aria-label="<%= t('fedi.profile_follow') %>">
|
|---|
| 139 | <svg class="pf-summary-follow-ico" viewBox="151 31 530 530" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><g transform="translate(6.6789703,-32.495842)"><path d="M257.1,266.8c-4.9,9.4-12.6,17.1-22.1,22l121.3,121.8l29.2-14.8L257.1,266.8z M417.1,427.4l-29.2,14.8l61.5,61.7c4.9-9.4,12.6-17.1,22.1-22L417.1,427.4z"/><path d="M557.5,315l-68.7,34.8l5.1,32.4l77.7-39.4C564.1,335.2,559.2,325.5,557.5,315z M448.9,370l-162.4,82.3c7.5,7.6,12.4,17.3,14.1,27.8L454,402.4L448.9,370z"/><path d="M396.7,167.3l-78.4,153l23.1,23.2l83-162C414,179.7,404.3,174.7,396.7,167.3z M298,360l-39.7,77.5c10.5,1.8,20.2,6.7,27.7,14.2l35.1-68.5L298,360z"/><path d="M234.3,289.1c-8,4-16.9,5.9-25.8,5.4c-1.7-0.1-3.3-0.3-5-0.5l23.2,148.2c8-4,16.9-5.9,25.8-5.4c1.7,0.1,3.3,0.3,5,0.5L234.3,289.1z"/><path d="M300.8,480.8c0.5,3.4,0.7,6.9,0.5,10.4c-0.4,7.1-2.3,14-5.5,20.4l148.2,23.8c-0.5-3.4-0.7-6.9-0.5-10.4c0.4-7.1,2.3-14,5.5-20.4L300.8,480.8z"/><path d="M572.1,343.3l-68.4,133.6c10.5,1.8,20.2,6.7,27.7,14.2l68.4-133.6C589.4,355.8,579.7,350.8,572.1,343.3z"/><path d="M478.8,154.4c-4.9,9.4-12.6,17.1-22.1,22l105.9,106.4c4.9-9.4,12.6-17.1,22.1-22L478.8,154.4z"/><path d="M382.1,138.9l-133.9,67.9c7.5,7.6,12.4,17.3,14.1,27.8l133.9-67.9C388.7,159.1,383.8,149.4,382.1,138.9z"/><path d="M456.5,176.6c-8.1,4.1-17.1,6.1-26.2,5.6c-1.5-0.1-3-0.3-4.5-0.5l11.9,76l32.4,5.2L456.5,176.6z M444.5,301.8l28.1,179.6c7.9-3.9,16.7-5.7,25.4-5.2c1.8,0.1,3.6,0.3,5.4,0.6L476.8,307L444.5,301.8z"/><path d="M262.4,235.2c0.6,3.5,0.7,7,0.6,10.6c-0.4,7-2.2,13.9-5.4,20.2l76,12.2l14.9-29.2L262.4,235.2z M392.7,256.1l-14.9,29.2l179.6,28.9c-0.5-3.4-0.7-6.9-0.5-10.3c0.4-7.1,2.3-14.1,5.5-20.5L392.7,256.1z"/><circle cx="433" cy="130.6" r="47"/><circle cx="608.4" cy="306.6" r="47"/><circle cx="495.1" cy="527.8" r="47"/><circle cx="249.7" cy="488.4" r="47"/><circle cx="211.3" cy="242.9" r="47"/></g></svg>
|
|---|
| 140 | <span><%= t('fedi.profile_follow') %></span>
|
|---|
| 141 | </button>
|
|---|
| 142 | <% } %>
|
|---|
| 143 | <% if (_sinceStr) { %><p class="pf-summary-since"><%= t('profile.since') %> <%= _sinceStr %></p><% } %>
|
|---|
| 144 | </div>
|
|---|
| 145 | </div>
|
|---|
| 146 | <% if (_showFollow) { %>
|
|---|
| 147 | <%# Follow-via-fediverse modal — replaces the native prompt() (which looked ugly). %>
|
|---|
| 148 | <div class="pf-follow">
|
|---|
| 149 | <div class="pf-follow-card" role="dialog" aria-label="<%= t('fedi.follow_heading') %>">
|
|---|
| 150 | <button type="button" class="pf-follow-cancel pf-follow-x" aria-label="Sluiten">×</button>
|
|---|
| 151 | <h3 class="pf-follow-title"><%= t('fedi.follow_heading') %></h3>
|
|---|
| 152 | <p class="pf-follow-sub"><%= t('fedi.remote_prompt') %></p>
|
|---|
| 153 | <input type="text" class="pf-follow-input" inputmode="url" autocomplete="off" autocapitalize="none" spellcheck="false"
|
|---|
| 154 | placeholder="<%= t('fedi.remote_ph') %>">
|
|---|
| 155 | <div class="pf-follow-actions">
|
|---|
| 156 | <button type="button" class="pf-follow-cancel"><%= t('fedi.cancel') %></button>
|
|---|
| 157 | <button type="button" class="pf-follow-go"><%= t('fedi.follow_btn') %></button>
|
|---|
| 158 | </div>
|
|---|
| 159 | </div>
|
|---|
| 160 | </div>
|
|---|
| 161 | <% } %>
|
|---|
| 162 | <script>
|
|---|
| 163 | (function () {
|
|---|
| 164 | if (window.__pcmsFediFollowWired) return;
|
|---|
| 165 | window.__pcmsFediFollowWired = true;
|
|---|
| 166 | function modal() { return document.querySelector('.pf-follow'); }
|
|---|
| 167 | function closeM() { var m = modal(); if (m) m.classList.remove('is-open'); }
|
|---|
| 168 | function go() {
|
|---|
| 169 | var m = modal(); if (!m) return;
|
|---|
| 170 | var inp = m.querySelector('.pf-follow-input'), raw = inp ? inp.value : '';
|
|---|
| 171 | // Strip a full @user@host handle (and any scheme/path) down to the server host.
|
|---|
| 172 | var server = String(raw || '').trim().replace(/^@?[^@\s]*@/, '').replace(/^https?:\/\//i, '').replace(/\/.*$/, '').trim();
|
|---|
| 173 | if (!server) { if (inp) inp.focus(); return; }
|
|---|
| 174 | try { localStorage.setItem('pcmsFediServer', server); } catch (e) {}
|
|---|
| 175 | var actor = location.origin + '/ap/users/' + encodeURIComponent(m.getAttribute('data-actor-slug') || '');
|
|---|
| 176 | location.href = 'https://' + server + '/authorize_interaction?uri=' + encodeURIComponent(actor);
|
|---|
| 177 | }
|
|---|
| 178 | document.addEventListener('click', function (e) {
|
|---|
| 179 | var b = e.target.closest && e.target.closest('.profile-fedi-link');
|
|---|
| 180 | if (b) { e.preventDefault();
|
|---|
| 181 | var m = modal(); if (!m) return;
|
|---|
| 182 | m.setAttribute('data-actor-slug', b.getAttribute('data-fedi-actor-slug') || '');
|
|---|
| 183 | var inp = m.querySelector('.pf-follow-input');
|
|---|
| 184 | try { if (inp && !inp.value) inp.value = localStorage.getItem('pcmsFediServer') || ''; } catch (e2) {}
|
|---|
| 185 | m.classList.add('is-open');
|
|---|
| 186 | setTimeout(function () { if (inp) inp.focus(); }, 30);
|
|---|
| 187 | return;
|
|---|
| 188 | }
|
|---|
| 189 | if (e.target.closest && e.target.closest('.pf-follow-go')) { e.preventDefault(); go(); return; }
|
|---|
| 190 | if (e.target.closest && e.target.closest('.pf-follow-cancel')) { e.preventDefault(); closeM(); return; }
|
|---|
| 191 | var open = document.querySelector('.pf-follow.is-open');
|
|---|
| 192 | if (open && e.target === open) closeM(); /* click on backdrop */
|
|---|
| 193 | });
|
|---|
| 194 | document.addEventListener('keydown', function (e) {
|
|---|
| 195 | var m = document.querySelector('.pf-follow.is-open'); if (!m) return;
|
|---|
| 196 | if (e.key === 'Escape') { closeM(); }
|
|---|
| 197 | else if (e.key === 'Enter' && e.target.closest && e.target.closest('.pf-follow')) { e.preventDefault(); go(); }
|
|---|
| 198 | });
|
|---|
| 199 | })();
|
|---|
| 200 |
|
|---|
| 201 | /* Profile summary: click the avatar to open a modal with photo + details. */
|
|---|
| 202 | (function () {
|
|---|
| 203 | if (window.__pcmsLightboxWired) return; window.__pcmsLightboxWired = true;
|
|---|
| 204 | function close() { var m = document.querySelector('.pf-summary.is-open'); if (m) m.classList.remove('is-open'); }
|
|---|
| 205 | document.addEventListener('click', function (e) {
|
|---|
| 206 | if (e.target.closest && e.target.closest('.pf-summary-close')) { e.preventDefault(); close(); return; }
|
|---|
| 207 | var open = document.querySelector('.pf-summary.is-open');
|
|---|
| 208 | if (open && e.target === open) { close(); return; } /* click on backdrop */
|
|---|
| 209 | var t = e.target.closest && e.target.closest('.profile-photo[data-pf-summary]');
|
|---|
| 210 | if (!t) return;
|
|---|
| 211 | e.preventDefault();
|
|---|
| 212 | var root = (t.closest && t.closest('#pcms-chrome')) || document;
|
|---|
| 213 | var modal = root.querySelector('.pf-summary') || document.querySelector('.pf-summary');
|
|---|
| 214 | if (modal) modal.classList.add('is-open');
|
|---|
| 215 | });
|
|---|
| 216 | document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
|
|---|
| 217 | })();
|
|---|
| 218 | </script>
|
|---|
| 219 | <% } %>
|
|---|
| 220 |
|
|---|
| 221 | <style>
|
|---|
| 222 | /* Profile header (v9 collapse pattern) */
|
|---|
| 223 | .profile-header {
|
|---|
| 224 | border-bottom: 1px solid var(--rule);
|
|---|
| 225 | background: var(--paper);
|
|---|
| 226 | padding: 1.5rem 0;
|
|---|
| 227 | transition: padding 250ms cubic-bezier(.4,0,.2,1);
|
|---|
| 228 | }
|
|---|
| 229 | .profile-header-inner {
|
|---|
| 230 | max-width: 800px;
|
|---|
| 231 | margin: 0 auto;
|
|---|
| 232 | padding: 0 1rem;
|
|---|
| 233 | display: flex;
|
|---|
| 234 | align-items: center;
|
|---|
| 235 | gap: 1.25rem;
|
|---|
| 236 | transition: gap 250ms;
|
|---|
| 237 | }
|
|---|
| 238 | .profile-photo {
|
|---|
| 239 | flex-shrink: 0;
|
|---|
| 240 | display: block;
|
|---|
| 241 | width: 80px;
|
|---|
| 242 | height: 80px;
|
|---|
| 243 | padding: 0;
|
|---|
| 244 | border-radius: 50%;
|
|---|
| 245 | overflow: hidden;
|
|---|
| 246 | background: var(--paper-2);
|
|---|
| 247 | border: 2px solid var(--rule);
|
|---|
| 248 | transition: width 250ms, height 250ms;
|
|---|
| 249 | cursor: pointer;
|
|---|
| 250 | font: inherit;
|
|---|
| 251 | -webkit-appearance: none;
|
|---|
| 252 | appearance: none;
|
|---|
| 253 | }
|
|---|
| 254 | .profile-photo[data-lightbox] { cursor: zoom-in; }
|
|---|
| 255 | .profile-photo:hover {
|
|---|
| 256 | border-color: var(--accent);
|
|---|
| 257 | }
|
|---|
| 258 | .profile-photo img {
|
|---|
| 259 | width: 100%;
|
|---|
| 260 | height: 100%;
|
|---|
| 261 | object-fit: cover;
|
|---|
| 262 | pointer-events: none;
|
|---|
| 263 | }
|
|---|
| 264 | .profile-photo-fallback {
|
|---|
| 265 | display: flex;
|
|---|
| 266 | align-items: center;
|
|---|
| 267 | justify-content: center;
|
|---|
| 268 | width: 100%;
|
|---|
| 269 | height: 100%;
|
|---|
| 270 | font-family: var(--font-display, serif);
|
|---|
| 271 | font-size: 2rem;
|
|---|
| 272 | font-weight: 700;
|
|---|
| 273 | color: var(--ink-soft);
|
|---|
| 274 | background: var(--paper-2);
|
|---|
| 275 | pointer-events: none;
|
|---|
| 276 | }
|
|---|
| 277 | .profile-photo-fallback--music {
|
|---|
| 278 | color: var(--accent);
|
|---|
| 279 | }
|
|---|
| 280 | .profile-photo-fallback--music svg {
|
|---|
| 281 | width: 50%;
|
|---|
| 282 | height: 50%;
|
|---|
| 283 | }
|
|---|
| 284 | .profile-info {
|
|---|
| 285 | flex: 1;
|
|---|
| 286 | min-width: 0;
|
|---|
| 287 | }
|
|---|
| 288 | .profile-name {
|
|---|
| 289 | font-family: var(--font-display, serif);
|
|---|
| 290 | font-size: 1.75rem;
|
|---|
| 291 | margin: 0 0 0.25rem;
|
|---|
| 292 | line-height: 1.2;
|
|---|
| 293 | }
|
|---|
| 294 | .profile-name a {
|
|---|
| 295 | color: var(--ink);
|
|---|
| 296 | text-decoration: none;
|
|---|
| 297 | }
|
|---|
| 298 | .profile-bio {
|
|---|
| 299 | margin: 0;
|
|---|
| 300 | color: var(--ink-soft);
|
|---|
| 301 | font-size: 0.95rem;
|
|---|
| 302 | line-height: 1.4;
|
|---|
| 303 | }
|
|---|
| 304 |
|
|---|
| 305 | /* Compact mode on post / special pages */
|
|---|
| 306 | .on-post .profile-header,
|
|---|
| 307 | .on-special .profile-header,
|
|---|
| 308 | .on-search .profile-header,
|
|---|
| 309 | .on-archive .profile-header {
|
|---|
| 310 | padding: 0.75rem 0;
|
|---|
| 311 | }
|
|---|
| 312 | .on-post .profile-photo,
|
|---|
| 313 | .on-special .profile-photo,
|
|---|
| 314 | .on-search .profile-photo,
|
|---|
| 315 | .on-archive .profile-photo {
|
|---|
| 316 | width: 40px;
|
|---|
| 317 | height: 40px;
|
|---|
| 318 | border-width: 1px;
|
|---|
| 319 | }
|
|---|
| 320 | .on-post .profile-photo-fallback,
|
|---|
| 321 | .on-special .profile-photo-fallback,
|
|---|
| 322 | .on-search .profile-photo-fallback,
|
|---|
| 323 | .on-archive .profile-photo-fallback {
|
|---|
| 324 | font-size: 1rem;
|
|---|
| 325 | }
|
|---|
| 326 | .on-post .profile-name,
|
|---|
| 327 | .on-special .profile-name,
|
|---|
| 328 | .on-search .profile-name,
|
|---|
| 329 | .on-archive .profile-name {
|
|---|
| 330 | font-size: 1.1rem;
|
|---|
| 331 | margin: 0;
|
|---|
| 332 | }
|
|---|
| 333 | .on-post .profile-bio,
|
|---|
| 334 | .on-special .profile-bio,
|
|---|
| 335 | .on-search .profile-bio,
|
|---|
| 336 | .on-archive .profile-bio {
|
|---|
| 337 | display: none;
|
|---|
| 338 | }
|
|---|
| 339 |
|
|---|
| 340 | /* Hide on admin pages */
|
|---|
| 341 | .on-admin .profile-header { display: none; }
|
|---|
| 342 |
|
|---|
| 343 | /* Mobile tweaks */
|
|---|
| 344 | @media (max-width: 600px) {
|
|---|
| 345 | .profile-photo { width: 64px; height: 64px; }
|
|---|
| 346 | .profile-photo-fallback { font-size: 1.5rem; }
|
|---|
| 347 | .profile-name { font-size: 1.4rem; }
|
|---|
| 348 | }
|
|---|
| 349 |
|
|---|
| 350 | /* Social / streaming icon row */
|
|---|
| 351 | .profile-links {
|
|---|
| 352 | list-style: none;
|
|---|
| 353 | margin: 0.5rem 0 0;
|
|---|
| 354 | padding: 0;
|
|---|
| 355 | display: flex;
|
|---|
| 356 | gap: 0.5rem;
|
|---|
| 357 | flex-wrap: wrap;
|
|---|
| 358 | }
|
|---|
| 359 | .profile-link {
|
|---|
| 360 | display: inline-flex;
|
|---|
| 361 | align-items: center;
|
|---|
| 362 | justify-content: center;
|
|---|
| 363 | width: 36px;
|
|---|
| 364 | height: 36px;
|
|---|
| 365 | border-radius: 50%;
|
|---|
| 366 | background: var(--paper-2);
|
|---|
| 367 | color: var(--ink-soft);
|
|---|
| 368 | text-decoration: none;
|
|---|
| 369 | transition: background 120ms, color 120ms, transform 100ms ease;
|
|---|
| 370 | }
|
|---|
| 371 | .profile-link:hover {
|
|---|
| 372 | background: var(--brand, var(--accent));
|
|---|
| 373 | color: white;
|
|---|
| 374 | transform: translateY(-1px);
|
|---|
| 375 | }
|
|---|
| 376 | .profile-link svg { width: 18px; height: 18px; display: block; }
|
|---|
| 377 |
|
|---|
| 378 | /* Compact mode collapses social links too (post pages) */
|
|---|
| 379 | .on-post .profile-links,
|
|---|
| 380 | .on-special .profile-links,
|
|---|
| 381 | .on-archive .profile-links { display: none; }
|
|---|
| 382 |
|
|---|
| 383 | /* Follow-via-fediverse: compact icon button, sits in the links row */
|
|---|
| 384 | .profile-fedi-link { border: 0; padding: 0; background: var(--paper-2); cursor: pointer; -webkit-appearance: none; appearance: none; }
|
|---|
| 385 | /* The fediverse logo is an open line-network, so it reads smaller than a solid
|
|---|
| 386 | glyph at 18px — render it larger INSIDE the same 36px circle (circle unchanged). */
|
|---|
| 387 | .profile-fedi-link svg { width: 22px; height: 22px; }
|
|---|
| 388 |
|
|---|
| 389 | /* Profile-summary modal (click the avatar) */
|
|---|
| 390 | .profile-photo[data-pf-summary] { cursor: zoom-in; }
|
|---|
| 391 | .pf-summary { position: fixed; inset: 0; z-index: 2147483600; display: none;
|
|---|
| 392 | align-items: center; justify-content: center; padding: 4vmin;
|
|---|
| 393 | background: rgba(0,0,0,.7); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
|
|---|
| 394 | .pf-summary.is-open { display: flex; }
|
|---|
| 395 | .pf-summary-card { position: relative; width: 100%; max-width: 380px; max-height: 90vh; overflow-y: auto;
|
|---|
| 396 | background: var(--paper); color: var(--ink); border: 1px solid var(--rule); border-radius: 20px;
|
|---|
| 397 | padding: 1.75rem 1.5rem; box-shadow: 0 20px 60px rgba(0,0,0,.4); text-align: center; }
|
|---|
| 398 | .pf-summary-close { position: absolute; top: .6rem; right: .7rem; width: 36px; height: 36px; border: 0;
|
|---|
| 399 | border-radius: 50%; background: var(--paper-2); color: var(--ink-soft); font-size: 1.5rem; line-height: 1;
|
|---|
| 400 | cursor: pointer; display: flex; align-items: center; justify-content: center; }
|
|---|
| 401 | .pf-summary-close:hover { color: var(--ink); }
|
|---|
| 402 | .pf-summary-photo { width: 110px; height: 110px; border-radius: 50%; object-fit: cover; margin: 0 auto .9rem;
|
|---|
| 403 | display: block; border: 3px solid var(--paper-2); background: #fff; }
|
|---|
| 404 | .pf-summary-photo--ph { display: flex; align-items: center; justify-content: center; background: var(--paper-2); }
|
|---|
| 405 | .pf-summary-photo--ph svg { width: 46px; height: 46px; color: var(--accent); }
|
|---|
| 406 | .pf-summary-photo--ph span { font-family: var(--font-display, serif); font-size: 2.6rem; font-weight: 700; color: var(--ink-soft); }
|
|---|
| 407 | .pf-summary-name { font-family: var(--font-display, serif); font-size: 1.4rem; margin: 0 0 .35rem; }
|
|---|
| 408 | .pf-summary-prem { display: inline-block; margin: 0 0 .7rem; padding: .15rem .6rem; border-radius: 999px;
|
|---|
| 409 | font-size: .75rem; font-weight: 600; background: var(--paper-2); color: var(--ink-soft); }
|
|---|
| 410 | .pf-summary-prem.is-prem { background: color-mix(in srgb, #e8b04b 22%, transparent); color: #b8860b; }
|
|---|
| 411 | .pf-summary-bio { color: var(--ink-soft); font-size: .92rem; line-height: 1.5; margin: 0 0 1rem; }
|
|---|
| 412 | .pf-summary-links { list-style: none; padding: 0; margin: .25rem 0 1rem; display: flex; flex-direction: column; gap: .4rem; text-align: left; }
|
|---|
| 413 | .pf-summary-links a { display: flex; align-items: center; gap: .7rem; padding: .5rem .7rem; border-radius: 12px;
|
|---|
| 414 | text-decoration: none; color: var(--ink); background: var(--paper-2); transition: background .12s; }
|
|---|
| 415 | .pf-summary-links a:hover { background: color-mix(in srgb, var(--brand, var(--accent)) 16%, var(--paper-2)); }
|
|---|
| 416 | .pf-summary-ico { flex: 0 0 22px; width: 22px; height: 22px; color: var(--brand, var(--ink-soft)); display: inline-flex; }
|
|---|
| 417 | .pf-summary-ico svg { width: 22px; height: 22px; }
|
|---|
| 418 | .pf-summary-rowtext { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
|
|---|
| 419 | .pf-summary-lbl { font-size: .72rem; font-weight: 600; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .03em; }
|
|---|
| 420 | .pf-summary-val { font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|---|
| 421 | .pf-summary-since { color: var(--ink-soft); font-size: .8rem; margin: 0; }
|
|---|
| 422 | .pf-summary-follow { display: inline-flex; align-items: center; gap: .5rem; margin: .2rem auto 1rem; padding: .5rem 1.15rem;
|
|---|
| 423 | border: 1.5px solid var(--accent); border-radius: 999px; background: transparent; color: var(--accent);
|
|---|
| 424 | font: inherit; font-weight: 600; font-size: .88rem; cursor: pointer; transition: background .15s, color .15s; }
|
|---|
| 425 | .pf-summary-follow:hover { background: var(--accent); color: var(--paper); }
|
|---|
| 426 | .pf-summary-follow-ico { width: 18px; height: 18px; flex: 0 0 auto; }
|
|---|
| 427 | .pf-follow { position: fixed; inset: 0; z-index: 2147483601; display: none; align-items: center; justify-content: center; padding: 1rem; background: rgba(0,0,0,.55); }
|
|---|
| 428 | .pf-follow.is-open { display: flex; }
|
|---|
| 429 | .pf-follow-card { position: relative; width: 100%; max-width: 380px; text-align: left;
|
|---|
| 430 | background: var(--paper); color: var(--ink); border: 1px solid var(--rule); border-radius: 16px;
|
|---|
| 431 | padding: 1.5rem 1.4rem 1.3rem; box-shadow: 0 18px 50px rgba(0,0,0,.4); }
|
|---|
| 432 | .pf-follow-x { position: absolute; top: .55rem; right: .65rem; width: 2rem; height: 2rem; border: 0; border-radius: 999px;
|
|---|
| 433 | background: transparent; color: var(--ink-soft); font-size: 1.4rem; line-height: 1; cursor: pointer; }
|
|---|
| 434 | .pf-follow-title { margin: 0 0 .35rem; font-size: 1.15rem; }
|
|---|
| 435 | .pf-follow-sub { margin: 0 0 .8rem; color: var(--ink-soft); font-size: .86rem; line-height: 1.45; }
|
|---|
| 436 | .pf-follow-input { width: 100%; box-sizing: border-box; padding: .6rem .8rem; border: 1.5px solid var(--rule);
|
|---|
| 437 | border-radius: 10px; background: var(--paper-2); color: var(--ink); font: inherit; font-size: .95rem; }
|
|---|
| 438 | .pf-follow-input:focus { outline: none; border-color: var(--accent); }
|
|---|
| 439 | .pf-follow-actions { display: flex; justify-content: flex-end; gap: .6rem; margin-top: 1rem; }
|
|---|
| 440 | .pf-follow-actions button { padding: .5rem 1.1rem; border-radius: 999px; font: inherit; font-weight: 600; font-size: .88rem; cursor: pointer; border: 0; }
|
|---|
| 441 | .pf-follow-actions .pf-follow-cancel { background: transparent; border: 1.5px solid var(--rule); color: var(--ink); }
|
|---|
| 442 | .pf-follow-actions .pf-follow-go { background: var(--accent); color: var(--paper); }
|
|---|
| 443 | .pf-follow-actions .pf-follow-go:hover { filter: brightness(1.06); }
|
|---|
| 444 | </style>
|
|---|