aboutsummaryrefslogtreecommitdiff
path: root/src/lib/LandingHero.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/LandingHero.svelte')
-rw-r--r--src/lib/LandingHero.svelte175
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>