Discover books, shows, and movies at your level. Track your progress by filling your Shelf with what you find, and share with other language learners. *No dusting required. shlf.space
4
fork

Configure Feed

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

refactor: minimize tailwind dependency

Signed-off-by: brookjeynes <me@brookjeynes.dev>

authored by

brookjeynes and committed by
Tangled
a7048c08 04203581

+140 -52
+17 -9
input.css
··· 1 1 @import "tailwindcss"; 2 2 @import "./internal/ui/views/shelf/shelf.css"; 3 3 @import "./internal/ui/views/login/login.css"; 4 + @import "./internal/ui/components/header/header.css"; 4 5 5 6 @font-face { 6 7 font-family: 'Epilogue'; ··· 33 34 body { 34 35 display: flex; 35 36 flex-direction: column; 37 + min-height: 100vh; 36 38 font-family: var(--font-primary); 37 39 background-color: var(--color-canvas); 38 40 color: var(--color-ink); 39 41 } 40 42 43 + main { 44 + flex: 1; 45 + display: flex; 46 + flex-direction: column; 47 + } 48 + 41 49 .container { 42 50 margin-inline: auto; 43 51 max-width: 80rem; ··· 51 59 gap: theme(spacing.2); 52 60 cursor: pointer; 53 61 padding: theme(spacing.3) theme(spacing.2); 62 + font-weight: bold; 63 + font-family: var(--font-primary); 54 64 55 65 &:hover { 56 66 background-color: var(--color-hover); ··· 66 76 cursor: not-allowed; 67 77 pointer-events: none; 68 78 } 69 - } 70 79 71 - .button-primary { 72 - background-color: var(--color-ink); 73 - color: var(--color-canvas); 74 - font-weight: bold; 75 - font-family: var(--font-primary); 80 + &.button-primary { 81 + background-color: var(--color-ink); 82 + color: var(--color-canvas); 76 83 77 - &:hover { 78 - background-color: var(--color-dim); 79 - color: var(--color-canvas); 84 + &:hover { 85 + background-color: var(--color-dim); 86 + color: var(--color-canvas); 87 + } 80 88 } 81 89 } 82 90
+89
internal/ui/components/header/header.css
··· 1 + header { 2 + position: sticky; 3 + top: 0; 4 + z-index: 50; 5 + padding-inline: 1rem; 6 + margin-bottom: 2rem; 7 + } 8 + 9 + .header-nav { 10 + display: flex; 11 + justify-content: space-between; 12 + align-items: center; 13 + margin-inline: auto; 14 + max-width: 80rem; 15 + height: 4rem; 16 + } 17 + 18 + .header-logo { 19 + font-size: 1.25rem; 20 + font-weight: 500; 21 + text-decoration: none; 22 + color: inherit; 23 + 24 + span { 25 + font-size: 0.75rem; 26 + font-weight: 400; 27 + font-style: italic; 28 + } 29 + } 30 + 31 + .header-dropdown { 32 + position: relative; 33 + display: inline-block; 34 + 35 + summary { 36 + cursor: pointer; 37 + list-style: none; 38 + display: flex; 39 + gap: 0.375rem; 40 + align-items: center; 41 + } 42 + 43 + & > div { 44 + position: absolute; 45 + right: 0; 46 + margin-top: 0.5rem; 47 + padding: 0.25rem; 48 + display: flex; 49 + flex-direction: column; 50 + width: 12rem; 51 + background: var(--color-tonal); 52 + border: 1px solid color-mix(in srgb, var(--color-ink) 10%, transparent); 53 + 54 + hr { 55 + border: none; 56 + border-top: 1px solid color-mix(in srgb, var(--color-ink) 10%, transparent); 57 + margin: 0.25rem 0; 58 + } 59 + } 60 + } 61 + 62 + .header-avatar { 63 + display: flex; 64 + align-items: center; 65 + justify-content: center; 66 + width: 1.5rem; 67 + height: 1.5rem; 68 + border-radius: 9999px; 69 + background: var(--color-dim); 70 + } 71 + 72 + .header-dropdown-btn { 73 + display: block; 74 + width: 100%; 75 + padding: 0.4rem 0.75rem; 76 + font-size: 0.8125rem; 77 + font-family: var(--font-primary); 78 + color: var(--color-dim); 79 + text-decoration: none; 80 + text-align: left; 81 + background: none; 82 + border: none; 83 + cursor: pointer; 84 + 85 + &:hover { 86 + background: var(--color-hover); 87 + color: var(--color-ink); 88 + } 89 + }
+27 -20
internal/ui/components/header/header.templ
··· 3 3 import "fmt" 4 4 5 5 templ Header(params HeaderParams) { 6 - <header class="w-full sticky top-0 z-50 px-4 mb-8"> 7 - <nav class="flex justify-between items-center mx-auto max-w-7xl h-16"> 8 - <a class="text-xl font-medium" href="/">shlf.space <span class="text-xs font-normal italic">alpha</span></a> 9 - <div class="flex gap-2 items-center"> 6 + <header role="banner"> 7 + <nav class="header-nav" aria-label="Main navigation"> 8 + <a class="header-logo" href="/">shlf.space <span>alpha</span></a> 9 + <div style="display:flex; gap:0.5rem; align-items:center"> 10 10 if params.User != nil { 11 - <details class="relative inline-block text-left"> 12 - <summary class="cursor-pointer list-none flex gap-2 items-center"> 13 - <div class="flex items-center justify-center w-7 h-7 rounded-full bg-dim"> 14 - <i class="w-4 h-4" data-lucide="user"></i> 11 + <details class="header-dropdown"> 12 + <summary aria-label="User menu"> 13 + <div class="header-avatar"> 14 + <i data-lucide="user" aria-hidden="true"></i> 15 15 </div> 16 - <span class="text-sm">{ params.User.Account.Handle }</span> 16 + <span style="font-size:0.875rem">{ params.User.Account.Handle }</span> 17 17 </summary> 18 - <div class="absolute flex flex-col right-0 mt-2 p-1 gap-1 w-48 bg-tonal drop-shadow-sm"> 18 + <div role="menu"> 19 19 <a 20 20 href={ templ.SafeURL(fmt.Sprintf("/%s/shelf", params.User.Account.Did)) } 21 - class="button p-2 justify-start text-sm w-full" 21 + class="header-dropdown-btn" 22 + role="menuitem" 22 23 > 23 24 My shelf 24 25 </a> 25 - <hr/> 26 - <button type="button" hx-post="/logout" hx-swap="none" class="button p-2 justify-start text-sm w-full"> 27 - <i class="w-4 h-4" data-lucide="log-out"></i> 26 + <hr role="separator"/> 27 + <button 28 + type="button" 29 + hx-post="/logout" 30 + hx-swap="none" 31 + class="header-dropdown-btn" 32 + role="menuitem" 33 + > 28 34 Log out 29 35 </button> 30 36 </div> 31 37 </details> 32 - <details class="relative inline-block text-left"> 33 - <summary class="cursor-pointer list-none flex gap-2 items-center"> 34 - <span>🇰🇷</span> 38 + <details class="header-dropdown"> 39 + <summary aria-label="Language selector"> 40 + <span role="img" aria-label="South Korea flag">🇰🇷</span> 35 41 </summary> 36 - <div class="absolute flex flex-col right-0 mt-2 p-1 gap-1 w-48 bg-tonal drop-shadow-sm"> 42 + <div role="menu"> 37 43 <button 38 44 type="button" 39 45 @click="localStorage.setItem('shlf-language', 'ko');" 40 46 hx-swap="none" 41 - class="button border-none text-sm w-full" 47 + class="header-dropdown-btn" 48 + role="menuitem" 42 49 > 43 - <span>🇰🇷 Korean</span> 50 + 🇰🇷 Korean 44 51 </button> 45 52 </div> 46 53 </details>
+2 -2
internal/ui/layouts/base/base.templ
··· 14 14 <script src="/static/js/alpinejs.min.js" defer></script> 15 15 <link rel="stylesheet" href="/static/style.css" type="text/css"/> 16 16 </head> 17 - <body class="min-h-screen"> 18 - <main class="flex-1 flex flex-col text-ink"> 17 + <body> 18 + <main> 19 19 { children... } 20 20 </main> 21 21 </body>
+5 -21
internal/ui/views/login/login.css
··· 57 57 } 58 58 } 59 59 60 - .spinner { 61 - width: 1rem; 62 - height: 1rem; 63 - display: none; 64 - animation: spin 1s linear infinite; 65 - } 66 - 67 - @keyframes spin { 68 - from { rotate: 0deg; } 69 - to { rotate: 360deg; } 70 - } 71 - 72 - .htmx-request .spinner { 73 - display: inline; 74 - } 75 - 76 60 .explainer-panel { 77 61 background: var(--color-tonal); 78 62 display: none; ··· 134 118 display: flex; 135 119 gap: 0.75rem; 136 120 137 - i { 121 + svg { 138 122 margin-top: 0.125rem; 139 123 flex-shrink: 0; 140 124 width: 1.25rem; ··· 163 147 &:hover { 164 148 background: var(--color-hover); 165 149 166 - i { 150 + svg { 167 151 color: var(--color-ink); 168 152 translate: 0.125rem 0; 169 153 } ··· 175 159 flex-shrink: 0; 176 160 } 177 161 178 - i { 162 + svg { 179 163 width: 1rem; 180 164 height: 1rem; 181 165 color: var(--color-dim); ··· 228 212 cursor: not-allowed; 229 213 } 230 214 231 - i { 215 + svg { 232 216 width: 1rem; 233 217 height: 1rem; 234 218 } ··· 271 255 color: var(--color-ink); 272 256 } 273 257 274 - i { 258 + svg { 275 259 width: 1.25rem; 276 260 height: 1.25rem; 277 261 }