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.

feat(ui/index): design landing page showcase

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

authored by

brookjeynes and committed by
Tangled
c1157e15 a7048c08

+132 -16
+2 -1
input.css
··· 1 1 @import "tailwindcss"; 2 + @import "./internal/ui/views/index/index.css"; 2 3 @import "./internal/ui/views/shelf/shelf.css"; 3 4 @import "./internal/ui/views/login/login.css"; 4 5 @import "./internal/ui/components/header/header.css"; ··· 58 59 justify-content: center; 59 60 gap: theme(spacing.2); 60 61 cursor: pointer; 61 - padding: theme(spacing.3) theme(spacing.2); 62 + padding: theme(spacing.3) theme(spacing.5); 62 63 font-weight: bold; 63 64 font-family: var(--font-primary); 64 65
+37 -1
internal/ui/components/header/header.css
··· 3 3 top: 0; 4 4 z-index: 50; 5 5 padding-inline: 1rem; 6 - margin-bottom: 2rem; 7 6 } 8 7 9 8 .header-nav { ··· 38 37 display: flex; 39 38 gap: 0.375rem; 40 39 align-items: center; 40 + font-family: var(--font-primary); 41 41 } 42 42 43 43 & > div { ··· 67 67 height: 1.5rem; 68 68 border-radius: 9999px; 69 69 background: var(--color-dim); 70 + 71 + svg { 72 + height: 1rem; 73 + width: 1rem; 74 + } 75 + } 76 + 77 + .header-nav-link { 78 + font-size: 0.75rem; 79 + font-weight: 500; 80 + letter-spacing: 0.08em; 81 + text-transform: uppercase; 82 + text-decoration: none; 83 + color: var(--color-dim); 84 + 85 + &:hover { 86 + color: var(--color-ink); 87 + } 88 + } 89 + 90 + .header-signin { 91 + font-size: 0.8125rem; 92 + font-weight: 600; 93 + letter-spacing: 0.06em; 94 + text-transform: uppercase; 95 + text-decoration: none; 96 + color: var(--color-ink); 97 + 98 + &:hover { 99 + color: var(--color-dim); 100 + } 101 + } 102 + 103 + .header-username { 104 + font-size: 0.875rem; 105 + font-weight: 500; 70 106 } 71 107 72 108 .header-dropdown-btn {
+17 -11
internal/ui/components/header/header.templ
··· 6 6 <header role="banner"> 7 7 <nav class="header-nav" aria-label="Main navigation"> 8 8 <a class="header-logo" href="/">shlf.space <span>alpha</span></a> 9 - <div style="display:flex; gap:0.5rem; align-items:center"> 10 - if params.User != nil { 11 - <details class="header-dropdown"> 12 - <summary aria-label="User menu"> 9 + if params.User != nil { 10 + <div style="display:flex; gap:2rem; align-items:center"> 11 + <a href="#" class="header-nav-link">Library</a> 12 + <a href="#" class="header-nav-link">Progress</a> 13 + <a href="#" class="header-nav-link">Journal</a> 14 + <a href="#" class="header-nav-link">Community</a> 15 + </div> 16 + <div style="display:flex; gap:0.5rem; align-items:center"> 17 + <details class="header-dropdown" x-data @toggle="$el.querySelector('summary').setAttribute('aria-expanded', $el.open)"> 18 + <summary aria-label="User menu" aria-expanded="false" aria-haspopup="menu"> 13 19 <div class="header-avatar"> 14 20 <i data-lucide="user" aria-hidden="true"></i> 15 21 </div> 16 - <span style="font-size:0.875rem">{ params.User.Account.Handle }</span> 22 + <span class="header-username">{ params.User.Account.Handle }</span> 17 23 </summary> 18 24 <div role="menu"> 19 25 <a ··· 35 41 </button> 36 42 </div> 37 43 </details> 38 - <details class="header-dropdown"> 39 - <summary aria-label="Language selector"> 44 + <details class="header-dropdown" x-data @toggle="$el.querySelector('summary').setAttribute('aria-expanded', $el.open)"> 45 + <summary aria-label="Language selector" aria-expanded="false" aria-haspopup="menu"> 40 46 <span role="img" aria-label="South Korea flag">🇰🇷</span> 41 47 </summary> 42 48 <div role="menu"> ··· 51 57 </button> 52 58 </div> 53 59 </details> 54 - } else { 55 - <a href="/login">login</a> 56 - } 57 - </div> 60 + </div> 61 + } else { 62 + <a href="/login" class="header-signin">Sign in <span aria-hidden="true">→</span></a> 63 + } 58 64 </nav> 59 65 </header> 60 66 }
+1 -1
internal/ui/layouts/base/base.templ
··· 6 6 <head> 7 7 <meta charset="UTF-8"/> 8 8 <meta name="viewport" content="width=device-width, initial-scale=1.0"/> 9 - <title>shlf.space - { params.Title }</title> 9 + <title>{ params.Title } - shlf.space</title> 10 10 <link rel="preload" href="/static/fonts/epilogue.woff2" as="font" type="font/woff2" crossorigin/> 11 11 <link rel="preload" href="/static/fonts/caveat.woff2" as="font" type="font/woff2" crossorigin/> 12 12 <script src="/static/js/htmx.min.js" defer></script>
+54
internal/ui/views/index/index.css
··· 1 + .hero { 2 + flex: 1; 3 + display: flex; 4 + align-items: center; 5 + justify-content: center; 6 + padding: 4rem 1.5rem 6rem; 7 + position: relative; 8 + } 9 + 10 + .hero-inner { 11 + position: relative; 12 + max-width: 46rem; 13 + width: 100%; 14 + text-align: center; 15 + } 16 + 17 + .hero-headline { 18 + font-size: clamp(3rem, 7vw, 5.5rem); 19 + font-weight: 900; 20 + line-height: 1.05; 21 + letter-spacing: -0.02em; 22 + margin: 0 0 1.25rem; 23 + 24 + span { 25 + display: block; 26 + } 27 + } 28 + 29 + .hero-subtext { 30 + font-size: 1.0625rem; 31 + line-height: 1.7; 32 + color: var(--color-dim); 33 + max-width: 38rem; 34 + margin: 0 auto 2.5rem; 35 + } 36 + 37 + .hero-cta { 38 + padding: 1rem 2rem; 39 + font-size: 0.8125rem; 40 + letter-spacing: 0.1em; 41 + text-transform: uppercase; 42 + text-decoration: none; 43 + } 44 + 45 + .hero-annotation { 46 + position: absolute; 47 + bottom: -2.5rem; 48 + right: 0; 49 + font-family: var(--font-accent); 50 + font-size: 1.375rem; 51 + color: var(--color-dim); 52 + transform: rotate(-2deg); 53 + pointer-events: none; 54 + }
+20 -1
internal/ui/views/index/index.templ
··· 8 8 templ IndexPage(params IndexPageParams) { 9 9 @layouts.Base(layouts.BaseParams{Title: "home"}) { 10 10 @header.Header(header.HeaderParams{User: params.User}) 11 - <div></div> 11 + <section class="hero" aria-labelledby="hero-headline"> 12 + <div class="hero-inner"> 13 + <h1 id="hero-headline" class="hero-headline"> 14 + Your reading journey, 15 + <br/> 16 + <span>beautifully shelved.</span> 17 + </h1> 18 + <p class="hero-subtext"> 19 + A personal space to log your progress, track your milestones, and curate your personal library. 20 + </p> 21 + <div style="display:flex; align-items:center; justify-content:center"> 22 + <a href="/login" class="button button-primary hero-cta"> 23 + Start your shelf <span aria-hidden="true">→</span> 24 + </a> 25 + </div> 26 + <div class="hero-annotation" aria-hidden="true"> 27 + Keep going! 28 + </div> 29 + </div> 30 + </section> 12 31 } 13 32 }
+1 -1
internal/ui/views/login/login.templ
··· 55 55 aria-label="Login" 56 56 > 57 57 <i class="spinner" data-lucide="loader-circle" aria-hidden="true"></i> 58 - <span aria-hidden="true">Login</span> 58 + <span>Login</span> 59 59 <i data-lucide="arrow-right" aria-hidden="true"></i> 60 60 </button> 61 61 </form>