atproto pds in zig pds.zat.dev
pds atproto
24

Configure Feed

Select the types of activity you want to include in your feed.

landing: tune motion and add accent hue

zzstoatzz (May 28, 2026, 2:48 AM -0500) acd74fc9 9ab4666a

+55 -15
+51 -15
src/http/landing/assets.zig
··· 12 12 \\ --bg: #070807; --panel: #101210; --panel-2: #151915; --line: #273026; 13 13 \\ --text: #f0f1ec; --muted: #aaa69b; --dim: #69645c; --accent: #91adff; 14 14 \\ --green: #39c178; --pink: #f05f8e; --focus: #c9d7ff; --glass: rgba(255,255,255,.085); 15 + \\ --glass-a: #39c178; --glass-b: #91adff; --glass-c: #f05f8e; --glass-d: #f5d85d; 15 16 \\ color-scheme: dark; 16 17 \\} 17 18 \\html[data-theme="dark"] { 18 19 \\ --bg: #070807; --panel: #101210; --panel-2: #151915; --line: #273026; 19 20 \\ --text: #f0f1ec; --muted: #aaa69b; --dim: #69645c; --accent: #91adff; 20 21 \\ --green: #39c178; --pink: #f05f8e; --focus: #c9d7ff; --glass: rgba(255,255,255,.085); 22 + \\ --glass-a: #39c178; --glass-b: #91adff; --glass-c: #f05f8e; --glass-d: #f5d85d; 21 23 \\ color-scheme: dark; 22 24 \\} 23 25 \\@media (prefers-color-scheme: light) { 24 26 \\ :root { 25 27 \\ --bg: #f6f4ed; --panel: #fffdf7; --panel-2: #ece8dd; --line: #d8d0c0; 26 28 \\ --text: #161412; --muted: #625c53; --dim: #8f8679; --accent: #315dcb; 27 - \\ --green: #1b7340; --pink: #b72e5c; --focus: #163f9f; --glass: rgba(255,255,255,.72); color-scheme: light; 29 + \\ --green: #1b7340; --pink: #b72e5c; --focus: #163f9f; --glass: rgba(255,255,255,.72); 30 + \\ --glass-a: #1b7340; --glass-b: #315dcb; --glass-c: #b72e5c; --glass-d: #b88713; color-scheme: light; 28 31 \\ } 29 32 \\} 30 33 \\html[data-theme="light"] { 31 34 \\ --bg: #f6f4ed; --panel: #fffdf7; --panel-2: #ece8dd; --line: #d8d0c0; 32 35 \\ --text: #161412; --muted: #625c53; --dim: #8f8679; --accent: #315dcb; 33 36 \\ --green: #1b7340; --pink: #b72e5c; --focus: #163f9f; --glass: rgba(255,255,255,.72); 37 + \\ --glass-a: #1b7340; --glass-b: #315dcb; --glass-c: #b72e5c; --glass-d: #b88713; 34 38 \\ color-scheme: light; 35 39 \\} 36 40 \\* { box-sizing: border-box; } ··· 122 126 \\.entropy-bars i { 123 127 \\ position: relative; flex: 1 1 0; min-width: 5px; height: var(--h); min-height: 6px; 124 128 \\ border-radius: 999px 999px 2px 2px; background: 125 - \\ linear-gradient(180deg, #f5d85d 0%, #58e07d 42%, #69b7ff 72%, #f06ca8 100%); 126 - \\ box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 5px 18px rgba(105,183,255,.18); 129 + \\ linear-gradient(180deg, var(--glass-d) 0%, var(--glass-a) 42%, var(--glass-b) 72%, var(--glass-c) 100%); 130 + \\ box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 5px 18px color-mix(in srgb, var(--glass-b) 18%, transparent); 127 131 \\ transform: translateY(var(--y)); opacity: .78; 128 132 \\ transition: opacity .16s ease, transform .16s ease, filter .16s ease; 129 133 \\} ··· 138 142 \\.entropy-axis { display: flex; justify-content: space-between; color: var(--dim); font-size: 9px; } 139 143 \\.signal-empty { color: var(--dim); font-size: 11px; } 140 144 \\@media (prefers-reduced-motion: reduce) { 141 - \\ body::before, body::after, .pulse::before { animation: none; } 145 + \\ body::before, body::after { animation: none; } 142 146 \\ .entropy-label, .entropy-bars i { transition: none; } 143 147 \\} 144 148 \\.pulse { ··· 151 155 \\ overflow: hidden; max-width: 100%; backdrop-filter: blur(24px) saturate(1.18); -webkit-backdrop-filter: blur(24px) saturate(1.18); 152 156 \\ box-shadow: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -24px 60px rgba(255,255,255,.035), 0 20px 54px rgba(0,0,0,.16); 153 157 \\} 154 - \\.pulse::before { 155 - \\ content: ""; position: absolute; inset: 0; pointer-events: none; 156 - \\ background: linear-gradient(100deg, transparent 0 38%, rgba(255,255,255,.16) 47%, transparent 57% 100%); 157 - \\ transform: translateX(-75%); animation: glass-sweep 9s ease-in-out infinite; 158 - \\} 159 - \\@keyframes glass-sweep { 160 - \\ 0%, 18% { transform: translateX(-80%); opacity: 0; } 161 - \\ 38% { opacity: .5; } 162 - \\ 58%, 100% { transform: translateX(85%); opacity: 0; } 163 - \\} 164 158 \\.pulse > div { min-width: 0; } 165 159 \\.pulse-kicker { color: var(--dim); font-size: 11px; text-transform: lowercase; } 166 160 \\.pulse-row { display: flex; align-items: center; gap: 10px; min-width: 0; } ··· 202 196 \\.collection a:hover { color: var(--accent); } 203 197 \\.collection code { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; } 204 198 \\.collection span { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; } 205 - \\.collection i { position: absolute; left: 0; bottom: 0; height: 2px; background: linear-gradient(90deg, #f05f8e 0%, #91adff 48%, #39c178 100%); } 199 + \\.collection i { position: absolute; left: 0; bottom: 0; height: 2px; background: linear-gradient(90deg, var(--glass-c) 0%, var(--glass-b) 48%, var(--glass-a) 100%); } 206 200 \\.empty { color: var(--muted); margin: 0; } 207 201 \\.sheet { position: fixed; inset: 0; z-index: 20; display: none; align-items: center; justify-content: center; padding: 16px; background: rgba(0, 0, 0, 0.42); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); } 208 202 \\.sheet.open { display: flex; } ··· 226 220 \\.client-body { padding: 15px 16px 17px; } 227 221 \\.hint { margin: 0 0 12px; color: var(--dim); font-size: 11px; } 228 222 \\.pref-section { display: grid; gap: 10px; margin-bottom: 16px; } 223 + \\.pref-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; } 229 224 \\.pref-label { color: var(--dim); font-size: 11px; text-transform: lowercase; } 225 + \\#accent-value { color: var(--dim); font-size: 11px; } 226 + \\.hue-slider { width: 100%; margin: 0; accent-color: var(--glass-a); cursor: pointer; } 227 + \\.hue-slider::-webkit-slider-runnable-track { 228 + \\ height: 10px; border: 1px solid color-mix(in srgb, var(--line) 80%, white 8%); border-radius: 999px; 229 + \\ background: linear-gradient(90deg, hsl(0 80% 62%), hsl(60 82% 62%), hsl(120 76% 56%), hsl(180 78% 58%), hsl(240 82% 68%), hsl(300 78% 64%), hsl(360 80% 62%)); 230 + \\} 231 + \\.hue-slider::-webkit-slider-thumb { 232 + \\ appearance: none; width: 20px; height: 20px; margin-top: -6px; border: 1px solid rgba(255,255,255,.42); 233 + \\ border-radius: 999px; background: var(--glass-a); box-shadow: 0 3px 12px rgba(0,0,0,.26), inset 0 1px 0 rgba(255,255,255,.34); 234 + \\} 235 + \\.hue-slider::-moz-range-track { 236 + \\ height: 10px; border: 1px solid color-mix(in srgb, var(--line) 80%, white 8%); border-radius: 999px; 237 + \\ background: linear-gradient(90deg, hsl(0 80% 62%), hsl(60 82% 62%), hsl(120 76% 56%), hsl(180 78% 58%), hsl(240 82% 68%), hsl(300 78% 64%), hsl(360 80% 62%)); 238 + \\} 239 + \\.hue-slider::-moz-range-thumb { 240 + \\ width: 18px; height: 18px; border: 1px solid rgba(255,255,255,.42); border-radius: 999px; 241 + \\ background: var(--glass-a); box-shadow: 0 3px 12px rgba(0,0,0,.26), inset 0 1px 0 rgba(255,255,255,.34); 242 + \\} 230 243 \\.theme-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } 231 244 \\.theme-option { min-height: 42px; border: 1px solid color-mix(in srgb, var(--line) 82%, white 6%); border-radius: 12px; background: color-mix(in srgb, var(--panel) 72%, transparent); color: var(--muted); font: inherit; font-size: 11px; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255,255,255,.10); } 232 245 \\.theme-option:hover, .theme-option.active { color: var(--text); border-color: color-mix(in srgb, var(--signal-a, var(--green)) 62%, var(--line)); } ··· 269 282 \\(function() { 270 283 \\ var key = 'zds.preferredClient'; 271 284 \\ var themeKey = 'zds.theme'; 285 + \\ var accentKey = 'zds.accentHue'; 272 286 \\ var clients = [ 273 287 \\ { value: 'bsky', label: 'Bluesky', icon: 'https://web-cdn.bsky.app/static/apple-touch-icon.png', url: function(handle, did) { return 'https://bsky.app/profile/' + handle; } }, 274 288 \\ { value: 'blacksky', label: 'Blacksky', icon: 'https://blacksky.community/static/apple-touch-icon.png', url: function(handle, did) { return 'https://blacksky.community/profile/' + handle; } }, ··· 281 295 \\ function write(value) { try { localStorage.setItem(key, value); } catch (_) {} } 282 296 \\ function readTheme() { try { return localStorage.getItem(themeKey) || 'system'; } catch (_) { return 'system'; } } 283 297 \\ function writeTheme(value) { try { value === 'system' ? localStorage.removeItem(themeKey) : localStorage.setItem(themeKey, value); } catch (_) {} } 298 + \\ function readAccent() { try { return localStorage.getItem(accentKey) || '154'; } catch (_) { return '154'; } } 299 + \\ function writeAccent(value) { try { localStorage.setItem(accentKey, value); } catch (_) {} } 300 + \\ function clampHue(value) { 301 + \\ var hue = Number(value); 302 + \\ if (!Number.isFinite(hue)) hue = 154; 303 + \\ return ((Math.round(hue) % 360) + 360) % 360; 304 + \\ } 305 + \\ function hsl(hue, saturation, lightness) { return 'hsl(' + clampHue(hue) + ' ' + saturation + '% ' + lightness + '%)'; } 306 + \\ function applyAccent(value) { 307 + \\ var hue = clampHue(value); 308 + \\ document.documentElement.style.setProperty('--glass-a', hsl(hue, 72, 58)); 309 + \\ document.documentElement.style.setProperty('--glass-b', hsl(hue + 76, 84, 72)); 310 + \\ document.documentElement.style.setProperty('--glass-c', hsl(hue + 144, 78, 66)); 311 + \\ document.documentElement.style.setProperty('--glass-d', hsl(hue + 214, 82, 68)); 312 + \\ var slider = document.getElementById('accent-hue'); 313 + \\ var output = document.getElementById('accent-value'); 314 + \\ if (slider) slider.value = String(hue); 315 + \\ if (output) output.textContent = String(hue) + 'deg'; 316 + \\ } 284 317 \\ function applyTheme(value) { 285 318 \\ if (value === 'light' || value === 'dark') document.documentElement.dataset.theme = value; 286 319 \\ else delete document.documentElement.dataset.theme; ··· 308 341 \\ document.querySelectorAll('.theme-option').forEach(function(btn) { 309 342 \\ btn.addEventListener('click', function() { writeTheme(btn.dataset.theme); applyTheme(btn.dataset.theme); }); 310 343 \\ }); 344 + \\ var accent = document.getElementById('accent-hue'); 345 + \\ if (accent) accent.addEventListener('input', function() { writeAccent(accent.value); applyAccent(accent.value); }); 311 346 \\ document.getElementById('settings').addEventListener('click', function() { sheet.classList.add('open'); }); 312 347 \\ document.getElementById('system').addEventListener('click', function() { systemSheet.classList.add('open'); }); 313 348 \\ document.getElementById('close-client').addEventListener('click', function() { sheet.classList.remove('open'); }); ··· 316 351 \\ systemSheet.addEventListener('click', function(event) { if (event.target === systemSheet) systemSheet.classList.remove('open'); }); 317 352 \\ document.addEventListener('keydown', function(event) { if (event.key === 'Escape') { sheet.classList.remove('open'); systemSheet.classList.remove('open'); } }); 318 353 \\ applyTheme(readTheme()); 354 + \\ applyAccent(readAccent()); 319 355 \\ syncLinks(); 320 356 \\})(); 321 357 ;
+4
src/http/landing/mod.zig
··· 140 140 \\ <button class="theme-option" type="button" data-theme="light">light</button> 141 141 \\ </div> 142 142 \\ </div> 143 + \\ <div class="pref-section"> 144 + \\ <div class="pref-row"><label class="pref-label" for="accent-hue">accent hue</label><output id="accent-value" for="accent-hue"></output></div> 145 + \\ <input class="hue-slider" id="accent-hue" type="range" min="0" max="359" step="1"> 146 + \\ </div> 143 147 \\ <div class="pref-label">open profiles with</div> 144 148 \\ <div class="client-grid" id="client-grid"></div> 145 149 \\ </div>