| [7bc636b] | 1 | <div class="container admin-site-edit-page">
|
|---|
| [bbf9d1a] | 2 | <p><a href="/admin" class="btn">← <%= t('asite.back_admin') %></a></p>
|
|---|
| 3 | <h1><%= isNew ? t('asite.title_new') : t('asite.title_edit') + ': ' + site.title %></h1>
|
|---|
| [7bc636b] | 4 |
|
|---|
| 5 | <% if (typeof success !== 'undefined' && success) { %><div class="audio-flash audio-flash--ok"><%= success %></div><% } %>
|
|---|
| 6 | <% if (error) { %><div class="audio-flash audio-flash--err"><%= error %></div><% } %>
|
|---|
| 7 |
|
|---|
| 8 | <form method="post" action="<%= isNew ? '/admin/sites/create' : '/admin/sites/' + site.slug + '/save' %>" class="site-form">
|
|---|
| 9 |
|
|---|
| 10 | <fieldset>
|
|---|
| [bbf9d1a] | 11 | <legend><%= t('asite.identity') %></legend>
|
|---|
| [7bc636b] | 12 | <label>
|
|---|
| [bbf9d1a] | 13 | <span><%= t('asite.slug') %> <% if (!isNew) { %><em><%= t('asite.slug_fixed') %></em><% } %></span>
|
|---|
| [3068cc0] | 14 | <span class="slug-url">
|
|---|
| 15 | <span class="slug-url-host" id="slug-host"
|
|---|
| [72ec6a4] | 16 | data-prefix="/">website.com/</span><input
|
|---|
| [3068cc0] | 17 | type="text" name="slug" id="slug-input" class="slug-url-input" value="<%= site.slug %>" required <% if (!isNew) { %>readonly<% } %>
|
|---|
| [bbf9d1a] | 18 | pattern="[a-z0-9_-]{2,40}" placeholder="<%= t('asite.slug_placeholder') %>"
|
|---|
| [3068cc0] | 19 | autocapitalize="none" autocorrect="off" spellcheck="false">
|
|---|
| 20 | </span>
|
|---|
| [7bc636b] | 21 | </label>
|
|---|
| 22 | <label>
|
|---|
| [bbf9d1a] | 23 | <span><%= t('asite.field_title') %> <small class="form-hint-inline"><%= t('asite.field_title_hint') %></small></span>
|
|---|
| [7bc636b] | 24 | <input type="text" name="title" value="<%= site.title || '' %>" required maxlength="200">
|
|---|
| 25 | </label>
|
|---|
| 26 | <label>
|
|---|
| [bbf9d1a] | 27 | <span><%= t('asite.tagline') %> <small class="form-hint-inline"><%= t('asite.tagline_hint') %></small></span>
|
|---|
| [7bc636b] | 28 | <input type="text" name="tagline" value="<%= site.tagline || '' %>" maxlength="200">
|
|---|
| 29 | </label>
|
|---|
| 30 | <label>
|
|---|
| [bbf9d1a] | 31 | <span><%= t('asite.bio') %> <small class="form-hint-inline"><%= t('asite.bio_hint') %></small></span>
|
|---|
| [7bc636b] | 32 | <textarea name="description" rows="3" maxlength="500"><%= site.description || '' %></textarea>
|
|---|
| 33 | </label>
|
|---|
| 34 | <label>
|
|---|
| [bbf9d1a] | 35 | <span><%= t('asite.profile_photo') %></span>
|
|---|
| [7bc636b] | 36 | <div class="photo-picker" id="photo-picker">
|
|---|
| 37 | <div class="photo-thumb" id="photo-thumb" <%= site.profile_photo ? '' : 'data-empty' %>>
|
|---|
| [99989f9] | 38 | <img id="photo-preview" src="<%= avatar(site.profile_photo || '', 128) %>" alt="" <%= site.profile_photo ? '' : 'hidden' %>>
|
|---|
| [7bc636b] | 39 | <span class="photo-empty" aria-hidden="true">
|
|---|
| 40 | <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
|---|
| 41 | </span>
|
|---|
| 42 | </div>
|
|---|
| 43 | <div class="photo-controls">
|
|---|
| [bbf9d1a] | 44 | <input type="text" name="profile_photo" id="photo-url" value="<%= site.profile_photo || '' %>" placeholder="<%= t('asite.photo_url_placeholder') %>">
|
|---|
| [7bc636b] | 45 | <div class="photo-actions">
|
|---|
| [bbf9d1a] | 46 | <button type="button" class="btn" id="photo-upload-trigger"><%= t('asite.photo_upload') %></button>
|
|---|
| 47 | <button type="button" class="btn" id="photo-clear" <%= site.profile_photo ? '' : 'hidden' %>><%= t('asite.photo_clear') %></button>
|
|---|
| [7bc636b] | 48 | <small id="photo-status" class="form-hint photo-status"></small>
|
|---|
| 49 | </div>
|
|---|
| 50 | <input type="file" id="photo-upload-field" accept="image/jpeg,image/png,image/webp,image/gif" hidden>
|
|---|
| 51 | </div>
|
|---|
| 52 | </div>
|
|---|
| 53 | </label>
|
|---|
| 54 | <label>
|
|---|
| [bbf9d1a] | 55 | <span><%= t('asite.language') %></span>
|
|---|
| [7bc636b] | 56 | <input type="text" name="language" value="<%= site.language || 'nl' %>" maxlength="8">
|
|---|
| 57 | </label>
|
|---|
| 58 | <label class="cb">
|
|---|
| 59 | <input type="checkbox" name="profile_enabled" value="1" <%= site.profile_enabled ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 60 | <span><%= t('asite.profile_enabled') %></span>
|
|---|
| [7bc636b] | 61 | </label>
|
|---|
| 62 | </fieldset>
|
|---|
| 63 |
|
|---|
| 64 | <fieldset>
|
|---|
| [bbf9d1a] | 65 | <legend><%= t('asite.appearance') %></legend>
|
|---|
| [7bc636b] | 66 |
|
|---|
| 67 | <%# ── Curated accent picker ───────────────────────────────────────
|
|---|
| 68 | Was a free-form <input type="color">; now a fixed set of 8 hand-
|
|---|
| 69 | picked colors that work in both light and dark themes. The hex is
|
|---|
| 70 | still what's stored in the DB — we just constrain WHICH hex. %>
|
|---|
| 71 | <fieldset class="accent-grid">
|
|---|
| [bbf9d1a] | 72 | <legend><%= t('asite.accent_color') %></legend>
|
|---|
| [7bc636b] | 73 | <% const _curAccent = (site.accent || '#c2410c').toLowerCase(); %>
|
|---|
| 74 | <% accents.forEach(function(a) { %>
|
|---|
| 75 | <label class="accent-swatch" title="<%= a.name %>">
|
|---|
| 76 | <input type="radio" name="accent" value="<%= a.color %>" <%= a.color.toLowerCase() === _curAccent ? 'checked' : '' %>>
|
|---|
| 77 | <span class="accent-dot" style="background: <%= a.color %>;" aria-hidden="true"></span>
|
|---|
| 78 | <span class="accent-swatch-name"><%= a.name %></span>
|
|---|
| 79 | </label>
|
|---|
| 80 | <% }); %>
|
|---|
| 81 | </fieldset>
|
|---|
| 82 |
|
|---|
| 83 | <%# ── Default theme for new visitors ───────────────────────────
|
|---|
| 84 | 'auto' (empty value) lets the browser/OS decide via prefers-color-scheme.
|
|---|
| 85 | 'light' / 'dark' force the site default for visitors who haven't picked
|
|---|
| 86 | their own preference yet. Logged-in users with users.theme set, and
|
|---|
| 87 | visitors with a localStorage override, still win over this default. %>
|
|---|
| 88 | <fieldset class="theme-default">
|
|---|
| [bbf9d1a] | 89 | <legend><%= t('asite.theme_default') %></legend>
|
|---|
| [7bc636b] | 90 | <% const td = site.theme_override || ''; %>
|
|---|
| 91 | <label class="cb">
|
|---|
| 92 | <input type="radio" name="theme_override" value="" <%= td === '' ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 93 | <span><%= t('asite.theme_auto') %></span>
|
|---|
| [7bc636b] | 94 | </label>
|
|---|
| 95 | <label class="cb">
|
|---|
| 96 | <input type="radio" name="theme_override" value="light" <%= td === 'light' ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 97 | <span><%= t('asite.theme_light') %></span>
|
|---|
| [7bc636b] | 98 | </label>
|
|---|
| 99 | <label class="cb">
|
|---|
| 100 | <input type="radio" name="theme_override" value="dark" <%= td === 'dark' ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 101 | <span><%= t('asite.theme_dark') %></span>
|
|---|
| [7bc636b] | 102 | </label>
|
|---|
| 103 | </fieldset>
|
|---|
| 104 |
|
|---|
| 105 | <fieldset class="palette-grid">
|
|---|
| [bbf9d1a] | 106 | <legend><%= t('asite.palette') %></legend>
|
|---|
| [7bc636b] | 107 | <% palettes.forEach(function(p) { %>
|
|---|
| 108 | <label class="palette-swatch">
|
|---|
| [34076d7] | 109 | <input type="radio" name="palette" value="<%= p.key %>" <%= (site.palette || 'klonkt') === p.key ? 'checked' : '' %>>
|
|---|
| [7bc636b] | 110 | <span class="palette-preview" aria-hidden="true">
|
|---|
| 111 | <span class="pp-half pp-light" style="background: <%= p.light.paper %>; color: <%= p.light.ink %>;">
|
|---|
| 112 | <span class="pp-letter">Aa</span>
|
|---|
| 113 | <span class="pp-accent" style="background: <%= p.light.accent %>;"></span>
|
|---|
| 114 | </span>
|
|---|
| 115 | <span class="pp-half pp-dark" style="background: <%= p.dark.paper %>; color: <%= p.dark.ink %>;">
|
|---|
| 116 | <span class="pp-letter">Aa</span>
|
|---|
| 117 | <span class="pp-accent" style="background: <%= p.dark.accent %>;"></span>
|
|---|
| 118 | </span>
|
|---|
| 119 | </span>
|
|---|
| 120 | <span class="palette-swatch-name"><%= p.name %></span>
|
|---|
| 121 | </label>
|
|---|
| 122 | <% }); %>
|
|---|
| 123 | </fieldset>
|
|---|
| 124 | </fieldset>
|
|---|
| 125 |
|
|---|
| [34076d7] | 126 | <%# Live preview: selecting an accent / theme / palette re-themes this page
|
|---|
| 127 | instantly (reverts on reload; persists on save). %>
|
|---|
| [0475b13] | 128 | <%# Het script van deze pagina staat in assets/js/mod/admin-site-edit.js (shaer-bqr). %>
|
|---|
| [34076d7] | 129 |
|
|---|
| [7bc636b] | 130 | <fieldset>
|
|---|
| [bbf9d1a] | 131 | <legend><%= t('asite.behavior') %></legend>
|
|---|
| [7bc636b] | 132 | <label class="cb">
|
|---|
| 133 | <input type="checkbox" name="is_public" value="1" <%= site.is_public ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 134 | <span><%= t('asite.is_public') %></span>
|
|---|
| [7bc636b] | 135 | </label>
|
|---|
| 136 | <label class="cb">
|
|---|
| 137 | <input type="checkbox" name="robots_index" value="1" <%= site.robots_index ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 138 | <span><%= t('asite.robots_index') %></span>
|
|---|
| [7bc636b] | 139 | </label>
|
|---|
| [cb01666] | 140 | <% if (typeof audioEnabled === 'undefined' || audioEnabled) { %>
|
|---|
| [7bc636b] | 141 | <label class="cb">
|
|---|
| 142 | <input type="checkbox" name="enable_audio_player" value="1" <%= site.enable_audio_player ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 143 | <span><%= t('asite.enable_audio') %></span>
|
|---|
| [7bc636b] | 144 | </label>
|
|---|
| [cb01666] | 145 | <% } %>
|
|---|
| [acbc9fc] | 146 | <label class="cb">
|
|---|
| 147 | <input type="checkbox" name="approve_followers" value="1" <%= site.approve_followers ? 'checked' : '' %>>
|
|---|
| 148 | <span><%= t('asite.approve_followers') %></span>
|
|---|
| 149 | </label>
|
|---|
| [7bc636b] | 150 | </fieldset>
|
|---|
| 151 |
|
|---|
| 152 | <fieldset class="profile-links-fieldset">
|
|---|
| [bbf9d1a] | 153 | <legend><%= t('asite.links') %></legend>
|
|---|
| 154 | <p class="form-hint"><%= t('asite.links_hint') %></p>
|
|---|
| [7bc636b] | 155 |
|
|---|
| 156 | <div id="profile-links-rows">
|
|---|
| 157 | <% (parsedLinks || []).forEach(function(l) { %>
|
|---|
| 158 | <div class="profile-link-row">
|
|---|
| 159 | <select name="profile_link_platform[]">
|
|---|
| 160 | <% platforms.forEach(function(p) { %>
|
|---|
| 161 | <option value="<%= p.key %>" <%= l.platform === p.key ? 'selected' : '' %>><%= p.label %></option>
|
|---|
| 162 | <% }); %>
|
|---|
| 163 | </select>
|
|---|
| 164 | <input type="text" name="profile_link_url[]" value="<%= l.url %>" placeholder="https://…" required>
|
|---|
| 165 | <button type="button" class="btn btn-danger pl-remove">×</button>
|
|---|
| 166 | </div>
|
|---|
| 167 | <% }); %>
|
|---|
| 168 | </div>
|
|---|
| 169 |
|
|---|
| 170 | <template id="profile-link-template">
|
|---|
| 171 | <div class="profile-link-row">
|
|---|
| 172 | <select name="profile_link_platform[]">
|
|---|
| 173 | <% platforms.forEach(function(p) { %>
|
|---|
| 174 | <option value="<%= p.key %>"><%= p.label %></option>
|
|---|
| 175 | <% }); %>
|
|---|
| 176 | </select>
|
|---|
| 177 | <input type="text" name="profile_link_url[]" placeholder="https://…" required>
|
|---|
| 178 | <button type="button" class="btn btn-danger pl-remove">×</button>
|
|---|
| 179 | </div>
|
|---|
| 180 | </template>
|
|---|
| 181 |
|
|---|
| [bbf9d1a] | 182 | <button type="button" id="profile-link-add" class="btn"><%= t('asite.link_add') %></button>
|
|---|
| [7bc636b] | 183 | </fieldset>
|
|---|
| 184 |
|
|---|
| [e9128bc] | 185 | <%# Aliassen en verhuizen staan sinds 14-8 op /admin/migrate, bij elkaar met
|
|---|
| 186 | exporteren, importeren en ophalen (Robin: alle migratie-opties op de
|
|---|
| 187 | migrate-pagina). Ze hoorden hier ook niet thuis: dit scherm gaat over hoe
|
|---|
| 188 | je site eruitziet, en een verhuizing is geen uiterlijk. Alleen de
|
|---|
| 189 | wegwijzer blijft, want wie ze hier zocht moet ze kunnen vinden. %>
|
|---|
| [ccaa530] | 190 | <fieldset>
|
|---|
| 191 | <legend><%= t('asite.aliases') %></legend>
|
|---|
| [e9128bc] | 192 | <p class="form-hint"><%= t('asite.moved_to_migrate') %></p>
|
|---|
| 193 | <p><a href="/admin/migrate" class="btn"><%= t('admin.b_migrate') %></a></p>
|
|---|
| [ccaa530] | 194 | </fieldset>
|
|---|
| 195 |
|
|---|
| [7bc636b] | 196 | <fieldset>
|
|---|
| [bbf9d1a] | 197 | <legend><%= t('asite.feed_view') %></legend>
|
|---|
| [e46ebaa] | 198 | <%# Twee vragen, en ze zijn niet hetzelfde: WELKE tweede weergave je site
|
|---|
| 199 | aanbiedt naast Grid, en waarin hij opent. %>
|
|---|
| 200 | <label>
|
|---|
| 201 | <span><%= t('asite.feed_alt') %></span>
|
|---|
| 202 | <select name="feed_alt_view">
|
|---|
| 203 | <% var _a = ['timeline','auto'].indexOf(site.feed_alt_view) >= 0 ? site.feed_alt_view : 'reader'; %>
|
|---|
| 204 | <option value="reader" <%= _a === 'reader' ? 'selected' : '' %>><%= t('asite.feed_alt_reader') %></option>
|
|---|
| 205 | <option value="timeline" <%= _a === 'timeline' ? 'selected' : '' %>><%= t('asite.feed_alt_timeline') %></option>
|
|---|
| 206 | <option value="auto" <%= _a === 'auto' ? 'selected' : '' %>><%= t('asite.feed_alt_auto') %></option>
|
|---|
| 207 | </select>
|
|---|
| 208 | </label>
|
|---|
| [7bc636b] | 209 | <label>
|
|---|
| [bbf9d1a] | 210 | <span><%= t('asite.feed_default') %></span>
|
|---|
| [7bc636b] | 211 | <select name="feed_view_default">
|
|---|
| [e46ebaa] | 212 | <option value="reader" <%= site.feed_view_default !== 'grid' ? 'selected' : '' %>><%= t('asite.feed_alt_' + _a) %></option>
|
|---|
| [bbf9d1a] | 213 | <option value="grid" <%= site.feed_view_default === 'grid' ? 'selected' : '' %>><%= t('asite.feed_grid') %></option>
|
|---|
| [7bc636b] | 214 | </select>
|
|---|
| 215 | </label>
|
|---|
| 216 | <label class="cb">
|
|---|
| 217 | <input type="checkbox" name="feed_view_switch" value="1" <%= site.feed_view_switch ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 218 | <span><%= t('asite.feed_switch') %></span>
|
|---|
| [7bc636b] | 219 | </label>
|
|---|
| 220 | <label class="cb">
|
|---|
| 221 | <input type="checkbox" name="show_search" value="1" <%= site.show_search ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 222 | <span><%= t('asite.show_search') %></span>
|
|---|
| [7bc636b] | 223 | </label>
|
|---|
| 224 | <label class="cb">
|
|---|
| 225 | <input type="checkbox" name="show_archive_link" value="1" <%= site.show_archive_link ? 'checked' : '' %>>
|
|---|
| [bbf9d1a] | 226 | <span><%= t('asite.show_archive') %></span>
|
|---|
| [7bc636b] | 227 | </label>
|
|---|
| 228 | </fieldset>
|
|---|
| 229 |
|
|---|
| [6623453] | 230 | <fieldset class="seo-pointer">
|
|---|
| [bbf9d1a] | 231 | <legend><%= t('asite.seo') %></legend>
|
|---|
| 232 | <p><%= t('asite.seo_pointer') %> <a href="/admin/seo"><%= t('asite.seo_link') %></a>.</p>
|
|---|
| [7bc636b] | 233 | </fieldset>
|
|---|
| 234 |
|
|---|
| 235 | <fieldset>
|
|---|
| [bbf9d1a] | 236 | <legend><%= t('asite.custom_legend') %> <em><%= t('asite.optional') %></em></legend>
|
|---|
| [7bc636b] | 237 | <label>
|
|---|
| [bbf9d1a] | 238 | <span><%= t('asite.custom_css') %></span>
|
|---|
| [7bc636b] | 239 | <textarea name="custom_css" rows="3" placeholder=".foo { color: red; }"><%= site.custom_css || '' %></textarea>
|
|---|
| 240 | </label>
|
|---|
| 241 | <label>
|
|---|
| [bbf9d1a] | 242 | <span><%= t('asite.custom_head') %></span>
|
|---|
| [7bc636b] | 243 | <textarea name="custom_head_html" rows="3" placeholder="<meta name="...">"><%= site.custom_head_html || '' %></textarea>
|
|---|
| 244 | </label>
|
|---|
| 245 | <label>
|
|---|
| [bbf9d1a] | 246 | <span><%= t('asite.custom_foot') %></span>
|
|---|
| [7bc636b] | 247 | <textarea name="custom_foot_html" rows="3"><%= site.custom_foot_html || '' %></textarea>
|
|---|
| 248 | </label>
|
|---|
| 249 | </fieldset>
|
|---|
| 250 |
|
|---|
| [bbf9d1a] | 251 | <button type="submit" class="btn btn-primary"><%= isNew ? t('asite.submit_create') : t('asite.submit_save') %></button>
|
|---|
| [7bc636b] | 252 | </form>
|
|---|
| [0ca7e9a4] | 253 |
|
|---|
| [7bc636b] | 254 | </div>
|
|---|
| 255 |
|
|---|
| 256 |
|
|---|
| 257 |
|
|---|
| 258 | <style>
|
|---|
| 259 | .admin-site-edit-page { max-width: 760px; margin: 3rem auto; padding: 0 1rem; }
|
|---|
| 260 | .admin-site-edit-page h1 { font-family: var(--font-display, serif); font-size: 1.8rem; margin: 0 0 1.5rem; }
|
|---|
| 261 |
|
|---|
| [75c6919] | 262 | .site-form { display: flex; flex-direction: column; gap: 1.5rem; min-width: 0; }
|
|---|
| [834bcc3] | 263 | /* Mobile: a <fieldset> has a browser-default min-inline-size:min-content and
|
|---|
| 264 | therefore does NOT shrink → the entire form became wider than the screen. min-width:0
|
|---|
| 265 | forces it to shrink; form fields get max-width:100% + border-box so they
|
|---|
| 266 | never overflow their fieldset. */
|
|---|
| [75c6919] | 267 | .site-form fieldset { min-width: 0; }
|
|---|
| 268 | .site-form input, .site-form select, .site-form textarea { min-width: 0; max-width: 100%; box-sizing: border-box; }
|
|---|
| [7bc636b] | 269 | .site-form fieldset {
|
|---|
| 270 | border: 1px solid var(--rule);
|
|---|
| 271 | border-radius: 8px;
|
|---|
| 272 | padding: 1rem 1.25rem;
|
|---|
| 273 | background: var(--paper-2);
|
|---|
| 274 | display: flex;
|
|---|
| 275 | flex-direction: column;
|
|---|
| 276 | gap: 0.75rem;
|
|---|
| 277 | }
|
|---|
| 278 | .site-form fieldset.palette-grid {
|
|---|
| 279 | display: grid;
|
|---|
| 280 | grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
|---|
| 281 | background: var(--paper);
|
|---|
| 282 | margin-top: 0.5rem;
|
|---|
| 283 | }
|
|---|
| 284 | /* Theme default radios — horizontal, sits between accent + palette */
|
|---|
| 285 | .site-form fieldset.theme-default {
|
|---|
| 286 | display: flex; flex-direction: row; flex-wrap: wrap; gap: 1rem;
|
|---|
| 287 | background: var(--paper);
|
|---|
| 288 | margin-top: 0.5rem;
|
|---|
| 289 | }
|
|---|
| 290 | .site-form fieldset.theme-default label.cb { font-size: 0.9rem; color: var(--ink); }
|
|---|
| 291 | .site-form fieldset legend { font-family: var(--font-display, serif); font-size: 1rem; padding: 0 0.4rem; }
|
|---|
| 292 | .site-form label { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.85rem; color: var(--ink-muted, var(--ink-soft)); }
|
|---|
| 293 | .site-form label.cb { flex-direction: row; align-items: center; gap: 0.5rem; }
|
|---|
| 294 | .site-form input[type="text"], .site-form input[type="color"], .site-form textarea {
|
|---|
| 295 | padding: 0.55rem 0.85rem;
|
|---|
| 296 | border: 1px solid var(--rule);
|
|---|
| 297 | border-radius: 5px;
|
|---|
| 298 | background: var(--paper);
|
|---|
| 299 | color: var(--ink);
|
|---|
| 300 | font-family: inherit;
|
|---|
| 301 | font-size: 0.95rem;
|
|---|
| 302 | }
|
|---|
| 303 | .site-form input[type="color"] { padding: 0.2rem; height: 38px; }
|
|---|
| 304 | .site-form textarea { resize: vertical; min-height: 60px; font-family: var(--font-mono, monospace); font-size: 0.85rem; }
|
|---|
| 305 | .site-form input[readonly] { opacity: 0.6; cursor: not-allowed; background: var(--paper-2); }
|
|---|
| 306 |
|
|---|
| [834bcc3] | 307 | /* Slug as URL field: dimmed host prefix + the slug itself in the accent colour. */
|
|---|
| [3068cc0] | 308 | .slug-url {
|
|---|
| 309 | display: flex; align-items: stretch;
|
|---|
| 310 | border: 1px solid var(--rule); border-radius: 5px;
|
|---|
| 311 | background: var(--paper); overflow: hidden;
|
|---|
| 312 | transition: border-color 120ms;
|
|---|
| 313 | }
|
|---|
| 314 | .slug-url:focus-within { border-color: var(--accent); }
|
|---|
| 315 | .slug-url-host {
|
|---|
| 316 | display: inline-flex; align-items: center;
|
|---|
| 317 | padding-left: 0.85rem;
|
|---|
| 318 | color: var(--ink-muted, var(--ink-soft));
|
|---|
| 319 | white-space: nowrap; user-select: none;
|
|---|
| 320 | font-size: 0.95rem;
|
|---|
| 321 | }
|
|---|
| 322 | .site-form .slug-url-input {
|
|---|
| 323 | flex: 1 1 auto; min-width: 0;
|
|---|
| 324 | border: none !important; border-radius: 0 !important;
|
|---|
| 325 | background: transparent !important;
|
|---|
| 326 | color: var(--accent) !important; font-weight: 700;
|
|---|
| 327 | padding: 0.55rem 0.85rem 0.55rem 0.1rem;
|
|---|
| 328 | }
|
|---|
| 329 | .site-form .slug-url-input:focus { outline: none; }
|
|---|
| 330 | .site-form .slug-url-input[readonly] {
|
|---|
| 331 | opacity: 1; cursor: default; background: transparent !important;
|
|---|
| 332 | }
|
|---|
| 333 |
|
|---|
| [834bcc3] | 334 | /* Selects: same look as the inputs, with a custom chevron instead of the bare
|
|---|
| 335 | native arrow. The open option list is still rendered by the browser. */
|
|---|
| [974de34] | 336 | .site-form select {
|
|---|
| 337 | appearance: none;
|
|---|
| 338 | -webkit-appearance: none;
|
|---|
| 339 | padding: 0.55rem 2.2rem 0.55rem 0.85rem;
|
|---|
| 340 | border: 1px solid var(--rule);
|
|---|
| 341 | border-radius: 5px;
|
|---|
| 342 | background-color: var(--paper);
|
|---|
| 343 | color: var(--ink);
|
|---|
| 344 | font-family: inherit;
|
|---|
| 345 | font-size: 0.95rem;
|
|---|
| 346 | cursor: pointer;
|
|---|
| 347 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
|---|
| 348 | background-repeat: no-repeat;
|
|---|
| 349 | background-position: right 0.7rem center;
|
|---|
| 350 | transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|---|
| 351 | }
|
|---|
| 352 | .site-form select:hover { border-color: var(--ink-soft, #888); }
|
|---|
| 353 | .site-form select:focus,
|
|---|
| 354 | .site-form input[type="text"]:focus,
|
|---|
| 355 | .site-form textarea:focus {
|
|---|
| 356 | outline: none;
|
|---|
| 357 | border-color: var(--accent, #c2410c);
|
|---|
| 358 | box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #c2410c) 22%, transparent);
|
|---|
| 359 | }
|
|---|
| 360 |
|
|---|
| [7bc636b] | 361 | /* Reuse the palette-swatch styles from account.ejs */
|
|---|
| 362 | .palette-swatch {
|
|---|
| 363 | display: flex; flex-direction: column; gap: 0.4rem;
|
|---|
| 364 | padding: 0.5rem;
|
|---|
| 365 | border: 1px solid var(--rule); border-radius: 6px; background: var(--paper);
|
|---|
| 366 | cursor: pointer; font-size: 0.85rem; transition: border-color 120ms;
|
|---|
| 367 | }
|
|---|
| 368 | .palette-swatch:hover { border-color: var(--accent); }
|
|---|
| 369 | .palette-swatch input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
|
|---|
| 370 | .palette-swatch:has(input[type="radio"]:checked) { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
|
|---|
| 371 | .palette-preview {
|
|---|
| 372 | display: grid; grid-template-columns: 1fr 1fr;
|
|---|
| 373 | width: 100%; height: 44px; border-radius: 4px; overflow: hidden;
|
|---|
| 374 | border: 1px solid var(--rule);
|
|---|
| 375 | }
|
|---|
| 376 | .pp-half {
|
|---|
| 377 | position: relative;
|
|---|
| 378 | display: flex; align-items: center; justify-content: center;
|
|---|
| 379 | font-family: var(--font-display, serif); font-weight: 600; font-size: 1rem;
|
|---|
| 380 | }
|
|---|
| 381 | .pp-letter { line-height: 1; }
|
|---|
| 382 | .pp-accent {
|
|---|
| 383 | position: absolute; bottom: 4px; right: 4px;
|
|---|
| 384 | width: 9px; height: 9px; border-radius: 50%;
|
|---|
| 385 | border: 1px solid rgba(0,0,0,0.12);
|
|---|
| 386 | }
|
|---|
| 387 | .palette-swatch-name { font-weight: 500; color: var(--ink); text-align: center; }
|
|---|
| 388 |
|
|---|
| 389 | /* Accent picker: row of small colored swatches */
|
|---|
| 390 | .site-form fieldset.accent-grid {
|
|---|
| 391 | display: grid;
|
|---|
| 392 | grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
|
|---|
| 393 | gap: 0.5rem;
|
|---|
| 394 | background: var(--paper);
|
|---|
| 395 | margin-top: 0.5rem;
|
|---|
| 396 | }
|
|---|
| 397 | .accent-swatch {
|
|---|
| 398 | display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
|
|---|
| 399 | padding: 0.55rem 0.4rem;
|
|---|
| 400 | border: 1px solid var(--rule); border-radius: 6px; background: var(--paper);
|
|---|
| 401 | cursor: pointer; font-size: 0.78rem;
|
|---|
| 402 | transition: border-color 120ms, box-shadow 120ms;
|
|---|
| 403 | }
|
|---|
| 404 | .accent-swatch:hover { border-color: var(--accent); }
|
|---|
| 405 | .accent-swatch input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
|
|---|
| 406 | .accent-swatch:has(input[type="radio"]:checked) {
|
|---|
| 407 | border-color: var(--accent);
|
|---|
| 408 | box-shadow: 0 0 0 2px var(--accent);
|
|---|
| 409 | }
|
|---|
| 410 | .accent-dot {
|
|---|
| 411 | width: 28px; height: 28px; border-radius: 50%;
|
|---|
| 412 | border: 1px solid rgba(0,0,0,0.1);
|
|---|
| 413 | box-shadow: inset 0 -2px 4px rgba(0,0,0,0.12);
|
|---|
| 414 | }
|
|---|
| 415 | .accent-swatch-name { color: var(--ink); text-align: center; font-weight: 500; }
|
|---|
| 416 |
|
|---|
| 417 | .audio-flash { padding: 0.75rem 1rem; border-radius: 6px; margin-bottom: 1rem; font-size: 0.9rem; }
|
|---|
| 418 | .audio-flash--ok { background: rgba(40, 160, 90, 0.15); color: #2a9d5e; border: 1px solid rgba(40, 160, 90, 0.3); }
|
|---|
| 419 | .audio-flash--err { background: rgba(200, 60, 60, 0.15); color: #c33; border: 1px solid rgba(200, 60, 60, 0.3); }
|
|---|
| 420 |
|
|---|
| 421 | .form-hint { font-size: 0.8rem; color: var(--ink-muted, var(--ink-soft)); margin: 0; }
|
|---|
| 422 | .form-hint-inline { font-size: 0.78rem; color: var(--ink-muted, var(--ink-soft)); font-weight: 400; margin-left: .25rem; }
|
|---|
| 423 |
|
|---|
| 424 | /* P63 — Profile photo picker
|
|---|
| 425 | Mobile-first: thumb stacks above input/buttons. ≥520px the thumb floats
|
|---|
| 426 | to the left and the controls fill the remaining width. */
|
|---|
| 427 | .photo-picker {
|
|---|
| 428 | display: flex;
|
|---|
| 429 | flex-direction: column;
|
|---|
| 430 | gap: .65rem;
|
|---|
| 431 | align-items: stretch;
|
|---|
| 432 | }
|
|---|
| 433 | .photo-thumb {
|
|---|
| 434 | position: relative;
|
|---|
| 435 | width: 88px; height: 88px;
|
|---|
| 436 | border-radius: 50%;
|
|---|
| 437 | border: 1px solid var(--rule);
|
|---|
| 438 | background: var(--paper-2);
|
|---|
| 439 | overflow: hidden;
|
|---|
| 440 | flex-shrink: 0;
|
|---|
| 441 | display: flex; align-items: center; justify-content: center;
|
|---|
| 442 | }
|
|---|
| 443 | .photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|---|
| 444 | .photo-thumb .photo-empty {
|
|---|
| 445 | display: flex; color: var(--ink-muted, var(--ink-soft)); opacity: .55;
|
|---|
| 446 | }
|
|---|
| 447 | .photo-thumb .photo-empty svg { width: 36px; height: 36px; }
|
|---|
| 448 | .photo-thumb:not([data-empty]) .photo-empty { display: none; }
|
|---|
| 449 | .photo-thumb[data-empty] img { display: none; }
|
|---|
| 450 |
|
|---|
| 451 | .photo-controls {
|
|---|
| 452 | display: flex;
|
|---|
| 453 | flex-direction: column;
|
|---|
| 454 | gap: .5rem;
|
|---|
| 455 | flex: 1;
|
|---|
| 456 | min-width: 0;
|
|---|
| 457 | }
|
|---|
| 458 | .photo-controls input[type="text"] { width: 100%; }
|
|---|
| 459 | .photo-actions {
|
|---|
| 460 | display: flex; align-items: center; flex-wrap: wrap;
|
|---|
| 461 | gap: .4rem;
|
|---|
| 462 | }
|
|---|
| 463 | .photo-actions .btn { padding: .45rem .75rem; font-size: .85rem; }
|
|---|
| 464 | .photo-status { margin-left: .25rem; }
|
|---|
| 465 | .photo-status.is-error { color: #c2410c; }
|
|---|
| 466 |
|
|---|
| 467 | @media (min-width: 520px) {
|
|---|
| 468 | .photo-picker { flex-direction: row; align-items: flex-start; gap: 1rem; }
|
|---|
| 469 | .photo-controls { gap: .55rem; }
|
|---|
| 470 | }
|
|---|
| [834bcc3] | 471 | /* Mobile-first: platform selector on its own line (full width), URL input + remove
|
|---|
| 472 | button below. Prevents horizontal overflow on phones (fixed 160px column +
|
|---|
| 473 | non-shrinkable input together ~447px > screen width). */
|
|---|
| [7bc636b] | 474 | .profile-link-row {
|
|---|
| [1664f31] | 475 | display: grid; grid-template-columns: 1fr auto; gap: 0.5rem; margin-bottom: 0.5rem;
|
|---|
| 476 | }
|
|---|
| 477 | .profile-link-row select { padding: 0.45rem 0.6rem; grid-column: 1 / -1; }
|
|---|
| 478 | .profile-link-row input { min-width: 0; }
|
|---|
| 479 | @media (min-width: 520px) {
|
|---|
| 480 | .profile-link-row { grid-template-columns: 160px 1fr auto; }
|
|---|
| 481 | .profile-link-row select { grid-column: auto; }
|
|---|
| [7bc636b] | 482 | }
|
|---|
| 483 | .profile-links-fieldset details > label { margin-top: 0.4rem; }
|
|---|
| 484 | </style>
|
|---|