diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/LandingHero.svelte | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/lib/LandingHero.svelte b/src/lib/LandingHero.svelte new file mode 100644 index 00000000..b42b91ac --- /dev/null +++ b/src/lib/LandingHero.svelte @@ -0,0 +1,175 @@ +<script lang="ts"> + import { env } from '$env/dynamic/public'; + import localforage from 'localforage'; + import { onMount } from 'svelte'; + + let visible = $state(false); + + onMount(() => { + visible = true; + }); +</script> + +<section class="hero" class:visible> + <div class="hero-content"> + <p class="tagline">The AniList Companion</p> + + <h1 class="headline">Never miss what's due.</h1> + + <p class="subheadline"> + Track airing episodes, new manga chapters, and subtitle releases—all in one place. + + <br /> + <br /> + + AniList keeps your list. <strong>due.moe</strong> keeps you current. + </p> + + <a + class="cta" + href={`https://anilist.co/api/v2/oauth/authorize?client_id=${env.PUBLIC_ANILIST_CLIENT_ID}&redirect_uri=${env.PUBLIC_ANILIST_REDIRECT_URI}&response_type=code`} + onclick={async () => { + await localforage.setItem( + 'redirect', + window.location.origin + window.location.pathname + window.location.search + ); + }} + > + Connect with AniList + </a> + </div> + + <div class="scroll-indicator"> + <span class="scroll-text">See More</span> + <span class="scroll-arrow">↓</span> + </div> +</section> + +<style> + .hero { + min-height: calc(100vh - 8rem); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + padding: 2rem; + position: relative; + opacity: 0; + transform: translateY(20px); + transition: + opacity 0.6s ease, + transform 0.6s ease; + } + + .hero.visible { + opacity: 1; + transform: translateY(0); + } + + /*.hero-content { + max-width: 640px; + }*/ + + .tagline { + font-size: 0.85rem; + /*text-transform: uppercase;*/ + letter-spacing: 0.15em; + color: var(--base04); + margin: 0 0 1rem 0; + font-weight: 500; + } + + .headline { + font-size: clamp(2.5rem, 8vw, 4.5rem); + font-weight: 700; + margin: 0 0 1.5rem 0; + color: var(--base06); + line-height: 1.1; + letter-spacing: -0.02em; + } + + .subheadline { + font-size: 1.15rem; + color: var(--base04); + margin: 0 0 2.5rem 0; + line-height: 1.6; + } + + .subheadline strong { + color: var(--base06); + font-weight: 600; + } + + .cta { + display: inline-block; + padding: 0.9rem 2rem; + background-color: var(--base06); + color: var(--base00); + font-weight: 600; + font-size: 0.95rem; + border-radius: 6px; + text-decoration: none; + transition: + transform 0.2s ease, + box-shadow 0.2s ease; + } + + .cta:hover { + text-decoration: none; + transform: translateY(-2px); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); + } + + .cta:active { + transform: translateY(0); + } + + .scroll-indicator { + position: absolute; + bottom: 2rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + color: var(--base03); + animation: float 2s ease-in-out infinite; + } + + .scroll-text { + font-size: 0.75rem; + /*text-transform: uppercase;*/ + letter-spacing: 0.1em; + } + + .scroll-arrow { + font-size: 1.25rem; + } + + @keyframes float { + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(6px); + } + } + + @media (max-width: 600px) { + .hero { + min-height: calc(100vh - 6rem); + padding: 1.5rem; + } + + .subheadline { + font-size: 1rem; + } + + .cta { + width: 100%; + text-align: center; + } + } +</style> |