Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com
at main 81 lines 3.8 kB view raw
1{{define "base"}} 2<!DOCTYPE html> 3<html lang="en"> 4<head> 5 <meta charset="utf-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <link rel="icon" href="/favicon.ico" sizes="any"> 8 <link rel="icon" href="/favicon.svg" type="image/svg+xml"> 9 <link rel="apple-touch-icon" href="/favicon/apple-touch-icon.png"> 10 <link rel="manifest" href="/favicon/site.webmanifest"> 11 <title>{{.Title}} — Diffdown</title> 12 <meta name="description" content="{{if .Description}}{{.Description}}{{else}}Diffdown — collaborative Markdown editing on AT Protocol.{{end}}"> 13 <!-- Open Graph --> 14 <meta property="og:type" content="website"> 15 <meta property="og:site_name" content="Diffdown"> 16 <meta property="og:title" content="{{.Title}} — Diffdown"> 17 <meta property="og:description" content="{{if .Description}}{{.Description}}{{else}}Diffdown — collaborative Markdown editing on AT Protocol.{{end}}"> 18 <meta property="og:image" content="{{if .OGImage}}{{.OGImage}}{{else}}/favicon/android-chrome-512x512.png{{end}}"> 19 <!-- Twitter Card --> 20 <meta name="twitter:card" content="summary"> 21 <meta name="twitter:title" content="{{.Title}} — Diffdown"> 22 <meta name="twitter:description" content="{{if .Description}}{{.Description}}{{else}}Diffdown — collaborative markdown editing on AT Protocol.{{end}}"> 23 <meta name="twitter:image" content="{{if .OGImage}}{{.OGImage}}{{else}}/favicon/android-chrome-512x512.png{{end}}"> 24 <link rel="stylesheet" href="/static/css/style.css"> 25 {{block "head" .}}{{end}} 26 <script> 27 (function() { 28 var stored = localStorage.getItem('theme'); 29 if (stored) document.documentElement.setAttribute('data-theme', stored); 30 })(); 31 </script> 32</head> 33<body> 34 <nav class="navbar"> 35 <a href="/" class="logo"> 36 <img src="/static/img/dd-logo.svg" alt="" width="22" height="28" style="vertical-align:middle;margin-right:0.4rem">Diffdown 37 </a> 38 <div class="nav-right"> 39 {{if .User}} 40 <a href="/">Documents</a> 41 <a href="/about">About</a> 42 <span class="nav-user">{{.UserHandle}}</span> 43 <form method="post" action="/auth/logout" style="display:inline"> 44 <button type="submit" class="btn-link">Log out</button> 45 </form> 46 {{else}} 47 <a href="/auth/atproto" class="btn btn-sm">Log in</a> 48 <a href="/about">About</a> 49 {{end}} 50 <button id="theme-toggle" class="btn-link" aria-label="Toggle dark mode" onclick="toggleTheme()" style="font-size:1.1rem;padding:0.25rem"></button> 51 </div> 52 </nav> 53 <main> 54 {{if .Error}} 55 <div class="alert alert-error">{{.Error}}</div> 56 {{end}} 57 {{block "content" .}}{{end}} 58 </main> 59 {{block "scripts" .}}{{end}} 60 <script> 61 function getEffectiveTheme() { 62 var stored = localStorage.getItem('theme'); 63 if (stored) return stored; 64 return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; 65 } 66 function applyThemeIcon(theme) { 67 document.getElementById('theme-toggle').textContent = theme === 'dark' ? '☀' : '🌙'; 68 } 69 function toggleTheme() { 70 var current = getEffectiveTheme(); 71 var next = current === 'dark' ? 'light' : 'dark'; 72 localStorage.setItem('theme', next); 73 document.documentElement.setAttribute('data-theme', next); 74 applyThemeIcon(next); 75 if (window.__cmSetTheme) window.__cmSetTheme(next); 76 } 77 applyThemeIcon(getEffectiveTheme()); 78 </script> 79</body> 80</html> 81{{end}}