feat: add light mode support across all templates
This commit is contained in:
@@ -6,17 +6,19 @@
|
||||
@source "../web/**/*.templ";
|
||||
|
||||
@theme {
|
||||
--color-background: #080808;
|
||||
--color-background-sidebar: #0f0f0f;
|
||||
--color-background-header: #141414;
|
||||
--color-background-surface: #202020;
|
||||
--color-background-button: #1a1a1a;
|
||||
--color-background-button-hover: #252525;
|
||||
--color-background: light-dark(#ffffff, #080808);
|
||||
--color-background-sidebar: light-dark(#fafaf9, #0f0f0f);
|
||||
--color-background-header: light-dark(#ffffff, #141414);
|
||||
--color-background-surface: light-dark(#f5f5f4, #202020);
|
||||
--color-background-button: light-dark(#ffffff, #1a1a1a);
|
||||
--color-background-button-hover: light-dark(#f5f5f4, #252525);
|
||||
|
||||
--color-foreground-muted: #6a6b70;
|
||||
--color-foreground: #f8f9fa;
|
||||
--color-foreground-muted: light-dark(#6b7280, #6a6b70);
|
||||
--color-foreground: light-dark(#1f2937, #f8f9fa);
|
||||
|
||||
--color-accent: #0466c8;
|
||||
--color-border: light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.08));
|
||||
--color-surface-hover: light-dark(rgba(0, 0, 0, 0.04), rgba(255, 255, 255, 0.04));
|
||||
}
|
||||
|
||||
:root {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{{define "anime_characters"}}
|
||||
<div class="mt-12 w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-neutral-300">Characters & Cast</h2>
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Characters & Cast</h2>
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
|
||||
{{range (slice . 0 (min (len .) 10))}}
|
||||
<div class="flex gap-3 bg-white/2 p-3 ring-1 ring-white/5">
|
||||
<div class="h-16 w-12 shrink-0 overflow-hidden bg-white/5">
|
||||
<div class="flex gap-3 bg-background-surface p-3 ring-1 ring-border">
|
||||
<div class="h-16 w-12 shrink-0 overflow-hidden bg-background-surface">
|
||||
<img src="{{.Character.Images.Jpg.ImageURL}}" alt="{{.Character.Name}}" class="h-full w-full object-cover" loading="lazy" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-center overflow-hidden">
|
||||
<span class="truncate text-sm font-medium text-neutral-200">{{.Character.Name}}</span>
|
||||
<span class="truncate text-xs text-neutral-500">{{.Role}}</span>
|
||||
<span class="truncate text-sm font-medium text-foreground">{{.Character.Name}}</span>
|
||||
<span class="truncate text-xs text-foreground-muted">{{.Role}}</span>
|
||||
{{if .VoiceActors}}
|
||||
<span class="mt-1 truncate text-[11px] text-neutral-400">{{(index .VoiceActors 0).Person.Name}}</span>
|
||||
<span class="mt-1 truncate text-[11px] text-foreground-muted">{{(index .VoiceActors 0).Person.Name}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,14 +23,14 @@
|
||||
{{define "anime_recommendations"}}
|
||||
{{if .}}
|
||||
<div class="w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-neutral-300">Recommendations</h2>
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Recommendations</h2>
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8">
|
||||
{{range (slice . 0 (min (len .) 8))}}
|
||||
<a href="/anime/{{.Entry.MalID}}" class="group flex flex-col gap-2">
|
||||
<div class="aspect-2/3 overflow-hidden bg-white/5 shadow-md">
|
||||
<div class="aspect-2/3 overflow-hidden bg-background-surface shadow-md">
|
||||
<img src="{{.Entry.Images.Webp.LargeImageURL}}" alt="{{.Entry.Title}}" class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" loading="lazy" />
|
||||
</div>
|
||||
<span class="truncate text-xs font-medium text-neutral-400 transition-colors group-hover:text-white">{{.Entry.Title}}</span>
|
||||
<span class="truncate text-xs font-medium text-foreground-muted transition-colors group-hover:text-foreground">{{.Entry.Title}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -46,7 +46,7 @@
|
||||
<div class="flex flex-col gap-10 pr-0 lg:pr-80">
|
||||
<div class="flex flex-col gap-8 md:flex-row lg:gap-12">
|
||||
<div class="flex w-64 shrink-0 flex-col items-center gap-6 md:w-80 md:items-start lg:w-96">
|
||||
<div class="aspect-2/3 w-full overflow-hidden bg-white/5 shadow-lg">
|
||||
<div class="aspect-2/3 w-full overflow-hidden bg-background-surface shadow-lg">
|
||||
{{$imageUrl := "https://placehold.co/400x600?text=No+Image"}}
|
||||
{{if $anime.Images.Webp.LargeImageURL}}
|
||||
{{$imageUrl = $anime.Images.Webp.LargeImageURL}}
|
||||
@@ -59,17 +59,17 @@
|
||||
|
||||
<div class="flex grow flex-col">
|
||||
<div class="mb-4">
|
||||
<h1 class="text-2xl font-normal text-white md:text-4xl">
|
||||
<h1 class="text-2xl font-normal text-foreground md:text-4xl">
|
||||
{{$anime.DisplayTitle}}
|
||||
</h1>
|
||||
{{if and $anime.TitleEnglish (ne $anime.Title $anime.TitleEnglish)}}
|
||||
<h2 class="mt-1 text-sm text-neutral-400">{{$anime.Title}}</h2>
|
||||
<h2 class="mt-1 text-sm text-foreground-muted">{{$anime.Title}}</h2>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="mb-6 flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-neutral-400">
|
||||
<div class="mb-6 flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-foreground-muted">
|
||||
{{if $anime.Score}}
|
||||
<div class="flex items-center gap-1.5 font-medium text-white">
|
||||
<div class="flex items-center gap-1.5 font-medium text-foreground">
|
||||
<svg class="h-3.5 w-3.5 fill-current" viewBox="0 0 20 20"><path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/></svg>
|
||||
{{$anime.Score}}
|
||||
</div>
|
||||
@@ -90,10 +90,10 @@
|
||||
<div class="flex flex-col gap-12 lg:flex-row">
|
||||
<div class="grow lg:max-w-4xl">
|
||||
<section>
|
||||
<h2 class="mb-4 mt-2 text-lg font-normal text-neutral-300">Synopsis</h2>
|
||||
<p id="synopsis-container" class="text-neutral-400 text-base leading-relaxed line-clamp-6 md:line-clamp-none">{{if $anime.Synopsis}}{{$anime.Synopsis}}{{else}}No synopsis available.{{end}}</p>
|
||||
<h2 class="mb-4 mt-2 text-lg font-normal text-foreground">Synopsis</h2>
|
||||
<p id="synopsis-container" class="text-foreground-muted text-base leading-relaxed line-clamp-6 md:line-clamp-none">{{if $anime.Synopsis}}{{$anime.Synopsis}}{{else}}No synopsis available.{{end}}</p>
|
||||
{{if and $anime.Synopsis (gt (len $anime.Synopsis) 400)}}
|
||||
<button id="synopsis-toggle" class="mt-2 text-sm font-normal text-neutral-400 transition-colors hover:text-white md:hidden" onclick="
|
||||
<button id="synopsis-toggle" class="mt-2 text-sm font-normal text-foreground-muted transition-colors hover:text-foreground md:hidden" onclick="
|
||||
const container = document.getElementById('synopsis-container');
|
||||
const btn = document.getElementById('synopsis-toggle');
|
||||
if (container.classList.contains('line-clamp-6')) {
|
||||
@@ -111,8 +111,8 @@
|
||||
|
||||
{{if $anime.Trailer.YoutubeID}}
|
||||
<section class="mt-12">
|
||||
<h2 class="mb-6 text-lg font-normal text-neutral-300">Trailer</h2>
|
||||
<div class="aspect-video w-full bg-white/5 ring-1 ring-white/10">
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Trailer</h2>
|
||||
<div class="aspect-video w-full bg-background-surface ring-1 ring-border">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/{{$anime.Trailer.YoutubeID}}"
|
||||
class="h-full w-full"
|
||||
@@ -125,62 +125,62 @@
|
||||
|
||||
{{if $anime.Background}}
|
||||
<section class="mt-12">
|
||||
<h2 class="mb-4 text-lg font-normal text-neutral-300">Background</h2>
|
||||
<div class="border-l border-white/5 pl-6 text-sm italic leading-relaxed text-neutral-400 whitespace-pre-line">
|
||||
<h2 class="mb-4 text-lg font-normal text-foreground">Background</h2>
|
||||
<div class="border-l border-border pl-6 text-sm italic leading-relaxed text-foreground-muted whitespace-pre-line">
|
||||
{{$anime.Background}}
|
||||
</div>
|
||||
</section>
|
||||
{{end}}
|
||||
</div>
|
||||
<aside class="fixed right-0 top-0 hidden h-screen w-80 shrink-0 flex-col overflow-y-auto border-l border-white/5 bg-neutral-950 p-10 lg:flex">
|
||||
<aside class="fixed right-0 top-0 hidden h-screen w-80 shrink-0 flex-col overflow-y-auto border-l border-border bg-background-sidebar p-10 lg:flex">
|
||||
<div class="flex flex-col gap-10">
|
||||
<section>
|
||||
<h3 class="mb-8 text-lg font-normal text-neutral-300">Information</h3>
|
||||
<h3 class="mb-8 text-lg font-normal text-foreground">Information</h3>
|
||||
<div class="flex flex-col gap-8 text-sm">
|
||||
{{if $anime.Studios}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Studios</dt>
|
||||
<dd class="text-neutral-300">{{range $i, $s := $anime.Studios}}{{if $i}}, {{end}}{{$s.Name}}{{end}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Studios</dt>
|
||||
<dd class="text-foreground">{{range $i, $s := $anime.Studios}}{{if $i}}, {{end}}{{$s.Name}}{{end}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.Producers}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Producers</dt>
|
||||
<dd class="text-neutral-300 text-xs leading-relaxed">{{range $i, $p := $anime.Producers}}{{if $i}}, {{end}}{{$p.Name}}{{end}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Producers</dt>
|
||||
<dd class="text-foreground text-xs leading-relaxed">{{range $i, $p := $anime.Producers}}{{if $i}}, {{end}}{{$p.Name}}{{end}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.Licensors}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Licensors</dt>
|
||||
<dd class="text-neutral-300 text-xs leading-relaxed">{{range $i, $l := $anime.Licensors}}{{if $i}}, {{end}}{{$l.Name}}{{end}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Licensors</dt>
|
||||
<dd class="text-foreground text-xs leading-relaxed">{{range $i, $l := $anime.Licensors}}{{if $i}}, {{end}}{{$l.Name}}{{end}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.Genres}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Genres</dt>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Genres</dt>
|
||||
<dd class="flex flex-wrap gap-2 pt-1">
|
||||
{{range $anime.Genres}}
|
||||
<a href="/browse?genres={{.MalID}}" class="bg-white/5 px-2.5 py-1 text-[11px] font-normal text-neutral-400 ring-1 ring-white/5 transition-colors hover:bg-white/10 hover:text-white">{{.Name}}</a>
|
||||
<a href="/browse?genres={{.MalID}}" class="bg-background-surface px-2.5 py-1 text-[11px] font-normal text-foreground-muted ring-1 ring-border transition-colors hover:bg-background-button-hover hover:text-foreground">{{.Name}}</a>
|
||||
{{end}}
|
||||
</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.Themes}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Themes</dt>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Themes</dt>
|
||||
<dd class="flex flex-wrap gap-2 pt-1">
|
||||
{{range $anime.Themes}}
|
||||
<a href="/browse?genres={{.MalID}}" class="bg-white/5 px-2.5 py-1 text-[11px] font-normal text-neutral-400 ring-1 ring-white/5 transition-colors hover:bg-white/10 hover:text-white">{{.Name}}</a>
|
||||
<a href="/browse?genres={{.MalID}}" class="bg-background-surface px-2.5 py-1 text-[11px] font-normal text-foreground-muted ring-1 ring-border transition-colors hover:bg-background-button-hover hover:text-foreground">{{.Name}}</a>
|
||||
{{end}}
|
||||
</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.Demographics}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Demographics</dt>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Demographics</dt>
|
||||
<dd class="flex flex-wrap gap-2 pt-1">
|
||||
{{range $anime.Demographics}}
|
||||
<a href="/browse?genres={{.MalID}}" class="bg-white/5 px-2.5 py-1 text-[11px] font-normal text-neutral-400 ring-1 ring-white/5 transition-colors hover:bg-white/10 hover:text-white">{{.Name}}</a>
|
||||
<a href="/browse?genres={{.MalID}}" class="bg-background-surface px-2.5 py-1 text-[11px] font-normal text-foreground-muted ring-1 ring-border transition-colors hover:bg-background-button-hover hover:text-foreground">{{.Name}}</a>
|
||||
{{end}}
|
||||
</dd>
|
||||
</div>
|
||||
@@ -188,49 +188,49 @@
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{{if $anime.Source}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Source</dt>
|
||||
<dd class="text-neutral-300">{{$anime.Source}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Source</dt>
|
||||
<dd class="text-foreground">{{$anime.Source}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.Duration}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Duration</dt>
|
||||
<dd class="text-neutral-300">{{$anime.Duration}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Duration</dt>
|
||||
<dd class="text-foreground">{{$anime.Duration}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{{if $anime.Rank}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Rank</dt>
|
||||
<dd class="text-neutral-300">#{{$anime.Rank}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Rank</dt>
|
||||
<dd class="text-foreground">#{{$anime.Rank}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.Popularity}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Popularity</dt>
|
||||
<dd class="text-neutral-300">#{{$anime.Popularity}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Popularity</dt>
|
||||
<dd class="text-foreground">#{{$anime.Popularity}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
{{if $anime.MembersFormatted}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Members</dt>
|
||||
<dd class="text-neutral-300">{{$anime.MembersFormatted}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Members</dt>
|
||||
<dd class="text-foreground">{{$anime.MembersFormatted}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $anime.FavoritesFormatted}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Favorites</dt>
|
||||
<dd class="text-neutral-300">{{$anime.FavoritesFormatted}}</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Favorites</dt>
|
||||
<dd class="text-foreground">{{$anime.FavoritesFormatted}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if $anime.ScoredByFormatted}}
|
||||
<div>
|
||||
<dt class="mb-1 text-xs font-normal text-neutral-500">Scored By</dt>
|
||||
<dd class="text-neutral-300">{{$anime.ScoredByFormatted}} users</dd>
|
||||
<dt class="mb-1 text-xs font-normal text-foreground-muted">Scored By</dt>
|
||||
<dd class="text-foreground">{{$anime.ScoredByFormatted}} users</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -243,14 +243,14 @@
|
||||
|
||||
<div hx-get="/anime/{{$anime.MalID}}?section=characters" hx-trigger="load" hx-swap="outerHTML">
|
||||
<div class="mt-12 w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-neutral-300">Characters & Cast</h2>
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Characters & Cast</h2>
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 animate-pulse">
|
||||
{{range (seq 5)}}
|
||||
<div class="flex gap-3 bg-white/2 p-3 ring-1 ring-white/5 h-20">
|
||||
<div class="h-16 w-12 shrink-0 bg-white/5"></div>
|
||||
<div class="flex gap-3 bg-background-surface p-3 ring-1 ring-border h-20">
|
||||
<div class="h-16 w-12 shrink-0 bg-background-button"></div>
|
||||
<div class="flex flex-col justify-center gap-2 grow">
|
||||
<div class="h-3 w-2/3 bg-white/5 rounded"></div>
|
||||
<div class="h-2 w-1/2 bg-white/5 rounded"></div>
|
||||
<div class="h-3 w-2/3 bg-background-button rounded"></div>
|
||||
<div class="h-2 w-1/2 bg-background-button rounded"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -260,8 +260,8 @@
|
||||
|
||||
<div class="w-full">
|
||||
<div hx-get="/api/watch-order?animeId={{$anime.MalID}}" hx-trigger="load">
|
||||
<div class="mt-8 flex items-center gap-3 text-neutral-400">
|
||||
<div class="border-t-accent size-5 animate-spin rounded-full border-2 border-neutral-600"></div>
|
||||
<div class="mt-8 flex items-center gap-3 text-foreground-muted">
|
||||
<div class="border-t-accent size-5 animate-spin rounded-full border-2 border-border"></div>
|
||||
<span class="text-sm">Loading watch order sequence...</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -269,12 +269,12 @@
|
||||
|
||||
<div hx-get="/anime/{{$anime.MalID}}?section=recommendations" hx-trigger="load" hx-swap="outerHTML">
|
||||
<div class="w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-neutral-300">Recommendations</h2>
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Recommendations</h2>
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 animate-pulse">
|
||||
{{range (seq 8)}}
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="aspect-2/3 bg-white/5"></div>
|
||||
<div class="h-3 w-full bg-white/5 rounded"></div>
|
||||
<div class="aspect-2/3 bg-background-surface"></div>
|
||||
<div class="h-3 w-full bg-background-surface rounded"></div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@@ -184,26 +184,23 @@ if (window.showToast) showToast({ message: 'Something went wrong' })
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-background text-neutral-200">
|
||||
<body class="bg-background text-foreground">
|
||||
<div class="flex min-h-screen flex-col">
|
||||
{{if .User}}
|
||||
<div class="sticky top-0 z-50">
|
||||
{{block "header" .}}
|
||||
{{template "header" .}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-1">
|
||||
<div class="flex flex-1 overflow-hidden">
|
||||
<button id="mobile-overlay" class="hidden fixed inset-0 z-40 w-full cursor-default border-none bg-black/60 backdrop-blur-sm outline-none lg:hidden" onclick="toggleMobileMenu()" aria-label="Close mobile menu"></button>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div id="mobile-menu" class="fixed inset-y-0 left-0 z-50 shrink-0 overflow-hidden transform lg:sticky lg:top-16 lg:z-auto lg:h-[calc(100vh-4rem)] -translate-x-full lg:shadow-none lg:w-64 lg:translate-x-0 w-64 shadow-2xl">
|
||||
<div id="mobile-menu" class="fixed inset-y-0 left-0 z-50 shrink-0 overflow-hidden transform lg:relative lg:z-auto lg:translate-x-0 w-64 shadow-2xl transition-transform duration-300 -translate-x-full lg:block">
|
||||
{{block "sidebar" .}}
|
||||
{{template "navigation" dict "CurrentPath" .CurrentPath}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<main class="w-full flex-1 overflow-x-hidden flex flex-col">
|
||||
<main class="w-full flex-1 overflow-x-hidden flex flex-col h-screen overflow-y-auto">
|
||||
<div class="sticky top-0 z-40 w-full">
|
||||
{{template "header" .}}
|
||||
</div>
|
||||
<div class="flex-1 p-4 md:p-8 lg:p-12">
|
||||
{{template "content" .}}
|
||||
</div>
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
{{if .WatchlistIDs}}<script>initWatchlist({{.WatchlistIDs}})</script>{{end}}
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="flex items-end justify-between">
|
||||
<h1 class="text-xl font-semibold text-white">Browse</h1>
|
||||
<h1 class="text-xl font-semibold text-foreground">Browse</h1>
|
||||
</div>
|
||||
|
||||
{{template "filter_bar" .}}
|
||||
|
||||
<main class="w-full">
|
||||
{{if eq (len .Animes) 0}}
|
||||
<div class="flex h-64 flex-col items-center justify-center gap-4 text-neutral-400">
|
||||
<div class="flex h-64 flex-col items-center justify-center gap-4 text-foreground-muted">
|
||||
<svg class="h-12 w-12 opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="11" cy="11" r="8" /><line x1="21" y1="21" x2="16.65" y2="16.65" /></svg>
|
||||
<p class="text-neutral-300">No anime found</p>
|
||||
<p class="text-foreground">No anime found</p>
|
||||
<div class="flex gap-2">
|
||||
<a href="/browse" class="px-4 py-2 text-sm bg-white/10 hover:bg-white/20 text-neutral-200 transition-colors">Clear filters</a>
|
||||
<a href="/browse" class="px-4 py-2 text-sm bg-background-surface hover:bg-background-button-hover text-foreground ring-1 ring-border transition-colors">Clear filters</a>
|
||||
<a href="/browse?order_by=popularity&sort=desc" class="px-4 py-2 text-sm bg-accent/20 hover:bg-accent/30 text-accent transition-colors">Browse popular</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{{$displayTitle := $anime.DisplayTitle}}
|
||||
|
||||
<div class="flex w-full flex-col gap-2" data-id="{{$dataId}}">
|
||||
<a href="/anime/{{$anime.MalID}}" class="group relative flex aspect-2/3 w-full flex-col overflow-hidden bg-white/5 after:absolute after:inset-0 {{if $withActions}}after:bg-black/80 after:opacity-0 hover:after:opacity-100{{else}}after:bg-linear-to-t after:from-black/80 after:via-black/20 after:to-transparent after:opacity-80 hover:after:opacity-100{{end}} after:transition-opacity">
|
||||
<a href="/anime/{{$anime.MalID}}" class="group relative flex aspect-2/3 w-full flex-col overflow-hidden bg-background-surface after:absolute after:inset-0 {{if $withActions}}after:bg-black/80 after:opacity-0 hover:after:opacity-100{{else}}after:bg-linear-to-t after:from-black/80 after:via-black/20 after:to-transparent after:opacity-80 hover:after:opacity-100{{end}} after:transition-opacity">
|
||||
<img src="{{$imageUrl}}" alt="{{$displayTitle}}" class="h-full w-full object-cover" loading="lazy" />
|
||||
|
||||
{{if $withActions}}
|
||||
@@ -67,7 +67,7 @@
|
||||
{{end}}
|
||||
</a>
|
||||
{{if and $withActions (not $hideTitle)}}
|
||||
<h3 class="line-clamp-2 text-sm font-medium text-neutral-200">
|
||||
<h3 class="line-clamp-2 text-sm font-medium text-foreground">
|
||||
{{$displayTitle}}
|
||||
</h3>
|
||||
{{end}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{{define "filter_bar"}}
|
||||
{{$selectedGenreIDs := .Genres}}
|
||||
{{$selectedCount := len $selectedGenreIDs}}
|
||||
<div class="flex flex-wrap items-center gap-3 bg-white/5 p-3">
|
||||
<div class="flex flex-wrap items-center gap-3 bg-background-surface p-3 ring-1 ring-border">
|
||||
<div class="min-w-50 flex-1">
|
||||
<form action="/browse" method="GET" id="browse-search-form">
|
||||
<input
|
||||
@@ -10,7 +10,7 @@
|
||||
type="text"
|
||||
value="{{.Query}}"
|
||||
placeholder="Search anime..."
|
||||
class="focus:ring-accent w-full bg-black/20 px-3 py-2 text-sm text-white placeholder-neutral-500 outline-none focus:ring-1"
|
||||
class="focus:ring-accent w-full bg-background-button px-3 py-2 text-sm text-foreground placeholder-foreground-muted outline-none focus:ring-1"
|
||||
onkeydown="if(event.key === 'Enter'){this.form.submit()}"
|
||||
/>
|
||||
{{if .Type}}<input type="hidden" name="type" value="{{.Type}}">{{end}}
|
||||
@@ -22,11 +22,11 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 px-3 py-2 text-sm text-white bg-black/20">
|
||||
<div class="flex items-center gap-2 px-3 py-2 text-sm text-foreground bg-background-button ring-1 ring-border">
|
||||
<label class="flex cursor-pointer items-center gap-2">
|
||||
<div class="flex h-4 w-4 items-center justify-center border-2 transition-colors {{if .SFW}}border-accent bg-accent{{else}}border-zinc-500 bg-transparent{{end}}">
|
||||
<div class="flex h-4 w-4 items-center justify-center border-2 transition-colors {{if .SFW}}border-accent bg-accent{{else}}border-border bg-transparent{{end}}">
|
||||
{{if .SFW}}
|
||||
<svg class="h-3 w-3 text-black" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M20 6 9 17l-5-5" /></svg>
|
||||
<svg class="h-3 w-3 text-on-accent" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M20 6 9 17l-5-5" /></svg>
|
||||
{{end}}
|
||||
</div>
|
||||
<input type="checkbox" class="sr-only" name="sfw" value="true" {{if .SFW}}checked{{end}}
|
||||
@@ -37,12 +37,12 @@
|
||||
|
||||
<ui-dropdown class="relative block" data-align="left" data-width="w-48">
|
||||
<div data-trigger class="cursor-pointer">
|
||||
<button class="flex items-center gap-2 bg-black/20 px-3 py-2 text-sm text-white hover:bg-black/30">
|
||||
<button class="flex items-center gap-2 bg-background-button ring-1 ring-border px-3 py-2 text-sm text-foreground hover:bg-background-button-hover transition-colors">
|
||||
{{if $selectedCount}}Genres ({{$selectedCount}}){{else}}Genres{{end}}
|
||||
<svg class="h-4 w-4 opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m6 9 6 6 6-6" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div data-content class="hidden absolute z-50 w-48 max-h-80 overflow-y-auto bg-background-button rounded-none shadow-2xl left-0 top-full mt-2">
|
||||
<div data-content class="hidden absolute z-50 w-48 max-h-80 overflow-y-auto bg-background-button rounded-none shadow-2xl left-0 top-full mt-2 ring-1 ring-border">
|
||||
<form action="/browse" method="GET" class="flex flex-col py-1">
|
||||
<input type="hidden" name="q" value="{{.Query}}">
|
||||
{{if .Type}}<input type="hidden" name="type" value="{{.Type}}">{{end}}
|
||||
@@ -53,10 +53,10 @@
|
||||
{{range .GenresList}}
|
||||
{{$genreID := .MalID}}
|
||||
{{$isSelected := hasGenre $genreID $selectedGenreIDs}}
|
||||
<label class="flex cursor-pointer items-center gap-3 rounded-sm px-2 py-1.5 text-sm text-neutral-300 hover:bg-white/5 hover:text-white">
|
||||
<div class="flex h-4 w-4 items-center justify-center border-2 transition-colors {{if $isSelected}}border-accent bg-accent{{else}}border-zinc-500 bg-transparent{{end}}">
|
||||
<label class="flex cursor-pointer items-center gap-3 rounded-sm px-2 py-1.5 text-sm text-foreground-muted hover:bg-surface-hover hover:text-foreground">
|
||||
<div class="flex h-4 w-4 items-center justify-center border-2 transition-colors {{if $isSelected}}border-accent bg-accent{{else}}border-border bg-transparent{{end}}">
|
||||
{{if $isSelected}}
|
||||
<svg class="h-3 w-3 text-black" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M20 6 9 17l-5-5" /></svg>
|
||||
<svg class="h-3 w-3 text-on-accent" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M20 6 9 17l-5-5" /></svg>
|
||||
{{end}}
|
||||
</div>
|
||||
<input type="checkbox" class="sr-only" name="genres" value="{{.MalID}}" {{if $isSelected}}checked{{end}} onchange="this.form.submit()">
|
||||
@@ -69,36 +69,36 @@
|
||||
|
||||
<ui-dropdown class="relative block" data-align="left" data-width="w-40">
|
||||
<div data-trigger class="cursor-pointer">
|
||||
<button class="flex items-center gap-2 bg-black/20 px-3 py-2 text-sm text-white hover:bg-black/30">
|
||||
<button class="flex items-center gap-2 bg-background-button ring-1 ring-border px-3 py-2 text-sm text-foreground hover:bg-background-button-hover transition-colors">
|
||||
{{if .Status}}{{.Status}}{{else}}Any Status{{end}}
|
||||
<svg class="h-4 w-4 opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m6 9 6 6 6-6" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div data-content class="hidden absolute z-50 w-40 bg-background-button rounded-none shadow-2xl left-0 top-full mt-2">
|
||||
<div data-content class="hidden absolute z-50 w-40 bg-background-button rounded-none shadow-2xl left-0 top-full mt-2 ring-1 ring-border">
|
||||
<div class="flex flex-col py-1">
|
||||
<a href="?status=&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Any Status</a>
|
||||
<a href="?status=airing&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Airing</a>
|
||||
<a href="?status=complete&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Complete</a>
|
||||
<a href="?status=upcoming&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Upcoming</a>
|
||||
<a href="?status=&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Any Status</a>
|
||||
<a href="?status=airing&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Airing</a>
|
||||
<a href="?status=complete&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Complete</a>
|
||||
<a href="?status=upcoming&q={{.Query}}&type={{.Type}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Upcoming</a>
|
||||
</div>
|
||||
</div>
|
||||
</ui-dropdown>
|
||||
|
||||
<ui-dropdown class="relative block" data-align="left" data-width="w-40">
|
||||
<div data-trigger class="cursor-pointer">
|
||||
<button class="flex items-center gap-2 bg-black/20 px-3 py-2 text-sm text-white hover:bg-black/30">
|
||||
<button class="flex items-center gap-2 bg-background-button ring-1 ring-border px-3 py-2 text-sm text-foreground hover:bg-background-button-hover transition-colors">
|
||||
{{if .Type}}{{.Type}}{{else}}Any Type{{end}}
|
||||
<svg class="h-4 w-4 opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m6 9 6 6 6-6" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div data-content class="hidden absolute z-50 w-40 bg-background-button rounded-none shadow-2xl left-0 top-full mt-2">
|
||||
<div data-content class="hidden absolute z-50 w-40 bg-background-button rounded-none shadow-2xl left-0 top-full mt-2 ring-1 ring-border">
|
||||
<div class="flex flex-col py-1">
|
||||
<a href="?type=&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Any Type</a>
|
||||
<a href="?type=tv&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">TV</a>
|
||||
<a href="?type=movie&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Movie</a>
|
||||
<a href="?type=ova&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">OVA</a>
|
||||
<a href="?type=special&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Special</a>
|
||||
<a href="?type=ona&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">ONA</a>
|
||||
<a href="?type=&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Any Type</a>
|
||||
<a href="?type=tv&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">TV</a>
|
||||
<a href="?type=movie&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Movie</a>
|
||||
<a href="?type=ova&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">OVA</a>
|
||||
<a href="?type=special&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Special</a>
|
||||
<a href="?type=ona&q={{.Query}}&status={{.Status}}&order_by={{.OrderBy}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">ONA</a>
|
||||
</div>
|
||||
</div>
|
||||
</ui-dropdown>
|
||||
@@ -106,24 +106,24 @@
|
||||
<div class="flex items-center gap-1">
|
||||
<ui-dropdown class="relative block" data-align="left" data-width="w-48">
|
||||
<div data-trigger class="cursor-pointer">
|
||||
<button class="flex items-center gap-2 bg-black/20 px-3 py-2 text-sm text-white hover:bg-black/30">
|
||||
<button class="flex items-center gap-2 bg-background-button ring-1 ring-border px-3 py-2 text-sm text-foreground hover:bg-background-button-hover transition-colors">
|
||||
Sort: {{if .OrderBy}}{{.OrderBy}}{{else}}Default{{end}}
|
||||
<svg class="h-4 w-4 opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m6 9 6 6 6-6" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div data-content class="hidden absolute z-50 w-48 bg-background-button rounded-none shadow-2xl left-0 top-full mt-2">
|
||||
<div data-content class="hidden absolute z-50 w-48 bg-background-button rounded-none shadow-2xl left-0 top-full mt-2 ring-1 ring-border">
|
||||
<div class="flex flex-col py-1">
|
||||
<a href="?order_by=&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Default</a>
|
||||
<a href="?order_by=popularity&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Popularity</a>
|
||||
<a href="?order_by=score&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Score</a>
|
||||
<a href="?order_by=title&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Title</a>
|
||||
<a href="?order_by=start_date&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Start Date</a>
|
||||
<a href="?order_by=episodes&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-white/10 text-sm text-white">Episodes</a>
|
||||
<a href="?order_by=&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Default</a>
|
||||
<a href="?order_by=popularity&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Popularity</a>
|
||||
<a href="?order_by=score&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Score</a>
|
||||
<a href="?order_by=title&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Title</a>
|
||||
<a href="?order_by=start_date&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Start Date</a>
|
||||
<a href="?order_by=episodes&q={{.Query}}&status={{.Status}}&type={{.Type}}&sort={{.Sort}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-surface-hover text-sm text-foreground">Episodes</a>
|
||||
</div>
|
||||
</div>
|
||||
</ui-dropdown>
|
||||
|
||||
<a href="?sort={{if eq .Sort "asc"}}desc{{else}}asc{{end}}&q={{.Query}}&status={{.Status}}&type={{.Type}}&order_by={{.OrderBy}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex h-9 w-9 items-center justify-center bg-black/20 text-neutral-300 hover:text-white">
|
||||
<a href="?sort={{if eq .Sort "asc"}}desc{{else}}asc{{end}}&q={{.Query}}&status={{.Status}}&type={{.Type}}&order_by={{.OrderBy}}&sfw={{.SFW}}{{ if .Genres }}&{{ genresParams .Genres }}{{ end }}" class="flex h-9 w-9 items-center justify-center bg-background-button ring-1 ring-border text-foreground-muted hover:text-foreground transition-colors">
|
||||
{{if eq .Sort "asc"}}
|
||||
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5M5 12l7-7 7 7" /></svg>
|
||||
{{else}}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{{define "footer"}}
|
||||
<footer class="mt-auto border-t border-neutral-800 bg-background-sidebar py-8 px-6 md:px-12">
|
||||
<footer class="mt-auto border-t border-border bg-background-sidebar py-8 px-6 md:px-12">
|
||||
<div class="flex flex-col items-center justify-between gap-6 sm:flex-row">
|
||||
<div class="flex items-center gap-3">
|
||||
<img src="/static/readme-logo-light.svg" alt="MAL" class="h-6 w-6" />
|
||||
<span class="text-neutral-300 font-semibold text-lg tracking-tight">MyAnimeList</span>
|
||||
<span class="text-foreground-muted font-semibold text-lg tracking-tight">MyAnimeList</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-6">
|
||||
<button
|
||||
id="footer-theme-toggle"
|
||||
class="text-neutral-500 transition-colors hover:text-neutral-300 focus:outline-none"
|
||||
class="text-neutral-500 transition-colors hover:text-foreground focus:outline-none"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
<svg class="theme-icon-dark size-5" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2">
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
{{define "header"}}
|
||||
<header class="bg-background-header flex flex-col border-b border-white/5 relative z-50">
|
||||
<header class="bg-background-header flex flex-col border-b border-border relative z-50">
|
||||
<div class="flex h-16 items-center justify-between px-4 md:px-6">
|
||||
<div class="flex items-center gap-4 lg:w-72">
|
||||
<button onclick="toggleMobileMenu()" class="block text-neutral-400 transition-colors hover:text-white focus:outline-none md:hidden">
|
||||
<div class="flex items-center gap-4">
|
||||
<button onclick="toggleMobileMenu()" class="block text-neutral-400 transition-colors hover:text-foreground focus:outline-none md:hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
|
||||
</button>
|
||||
<button onclick="toggleSidebar()" class="hidden text-neutral-400 transition-colors hover:text-white focus:outline-none lg:block">
|
||||
<button onclick="toggleSidebar()" class="hidden text-neutral-400 transition-colors hover:text-foreground focus:outline-none lg:block">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" x2="21" y1="12" y2="12"/><line x1="3" x2="21" y1="6" y2="6"/><line x1="3" x2="21" y1="18" y2="18"/></svg>
|
||||
</button>
|
||||
<a href="/" class="group flex items-center gap-2.5 focus:outline-none">
|
||||
<img src="/static/readme-logo-light.svg" alt="MAL" class="h-8 w-8 transition-transform group-hover:scale-110" />
|
||||
<span class="text-xl font-bold tracking-tight text-white hidden sm:block">MyAnime<span class="text-accent">List</span></span>
|
||||
<span class="text-xl font-bold tracking-tight text-foreground">MyAnime<span class="text-accent">List</span></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="hidden max-w-3xl flex-1 items-center justify-center px-4 md:flex">
|
||||
<div class="hidden max-w-2xl flex-1 items-center justify-center px-4 md:flex">
|
||||
<form action="/browse" method="GET" class="w-full max-w-lg">
|
||||
<div class="focus-within:border-accent bg-background-surface flex h-10 w-full items-center overflow-hidden border border-transparent transition-colors">
|
||||
<div class="focus-within:border-accent bg-background-surface flex h-10 w-full items-center overflow-hidden border border-border transition-colors">
|
||||
<div class="pr-2 pl-4 text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
|
||||
</div>
|
||||
<input type="text" name="q" placeholder="Search..." class="h-full w-full bg-transparent px-1 text-sm text-white focus:outline-none" />
|
||||
<input type="text" name="q" placeholder="Search..." class="h-full w-full bg-transparent px-1 text-sm text-foreground focus:outline-none" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 lg:w-72 relative">
|
||||
<div class="flex items-center gap-2 relative justify-end">
|
||||
<button
|
||||
id="theme-toggle"
|
||||
class="rounded-full p-1.5 text-neutral-400 transition-colors hover:bg-white/5 hover:text-white focus:outline-none"
|
||||
aria-label="Toggle theme"
|
||||
class="rounded-full p-1.5 text-neutral-400 transition-colors hover:bg-surface-hover hover:text-foreground focus:outline-none"
|
||||
>
|
||||
<svg class="theme-icon-dark size-5" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2">
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
||||
@@ -41,7 +40,7 @@
|
||||
</button>
|
||||
<ui-dropdown class="relative block">
|
||||
<div data-trigger class="cursor-pointer">
|
||||
<button class="flex items-center gap-1 rounded-full p-1 transition-colors hover:bg-white/5 focus:outline-none">
|
||||
<button class="flex items-center gap-1 rounded-full p-1 transition-colors hover:bg-surface-hover focus:outline-none">
|
||||
{{if .User}}
|
||||
<div class="bg-accent flex h-8 w-8 items-center justify-center overflow-hidden rounded-full text-sm font-semibold text-white">
|
||||
{{slice .User.Username 0 1}}
|
||||
@@ -64,9 +63,9 @@
|
||||
</div>
|
||||
</a>
|
||||
{{else}}
|
||||
<a href="/login" class="flex w-full items-center px-5 py-3.5 transition-colors focus:outline-none hover:bg-white/10 focus:bg-white/10">
|
||||
<a href="/login" class="flex w-full items-center px-5 py-3.5 transition-colors focus:outline-none hover:bg-surface-hover focus:bg-surface-hover">
|
||||
<div class="flex w-full items-center justify-between text-left">
|
||||
<span class="font-medium text-[15px] text-white">Log in</span>
|
||||
<span class="font-medium text-[15px] text-foreground">Log in</span>
|
||||
</div>
|
||||
</a>
|
||||
{{end}}
|
||||
@@ -76,14 +75,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex border-t border-white/5 p-3 md:hidden">
|
||||
<div class="flex border-t border-border p-3 md:hidden">
|
||||
<form action="/browse" method="GET" class="w-full">
|
||||
<div class="focus-within:border-accent bg-background-surface flex h-10 w-full items-center overflow-hidden border border-transparent transition-colors">
|
||||
<div class="pr-2 pl-4 text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
|
||||
<div class="focus-within:border-accent bg-background-surface flex h-10 w-full items-center overflow-hidden border border-border transition-colors">
|
||||
<div class="pr-2 pl-4 text-neutral-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
|
||||
</div>
|
||||
<input type="text" name="q" placeholder="Search..." class="h-full w-full bg-transparent px-1 text-sm text-foreground focus:outline-none" />
|
||||
</div>
|
||||
<input type="text" name="q" placeholder="Search..." class="h-full w-full bg-transparent px-1 text-sm text-white focus:outline-none" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -8,32 +8,32 @@
|
||||
"watchlist" (dict "href" "/watchlist" "label" "Watchlist")
|
||||
}}
|
||||
|
||||
<nav class="bg-background-sidebar h-full py-6">
|
||||
<nav class="bg-background-sidebar h-full py-6 border-r border-border">
|
||||
<div class="flex flex-col">
|
||||
{{/* Home */}}
|
||||
{{$isActive := eq $currentPath "/"}}
|
||||
<a href="/" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-white/5" {{if $isCollapsed}}title="Home"{{end}}>
|
||||
<a href="/" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Home"{{end}}>
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_rgba(163,230,53,0.6)]"></div>
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_var(--color-accent)]"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||
<polyline points="9 22 9 12 15 12 15 22" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}">Home</span>
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Home</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{/* Browse */}}
|
||||
{{$isActive := eq $currentPath "/browse"}}
|
||||
<a href="/browse" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-white/5" {{if $isCollapsed}}title="Browse"{{end}}>
|
||||
<a href="/browse" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Browse"{{end}}>
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_rgba(163,230,53,0.6)]"></div>
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_var(--color-accent)]"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="2" y="2" width="20" height="20" rx="2" ry="2" />
|
||||
<line x1="7" y1="2" x2="7" y2="22" />
|
||||
<line x1="17" y1="2" x2="17" y2="22" />
|
||||
@@ -45,40 +45,40 @@
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}">Browse</span>
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Browse</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{/* Discover */}}
|
||||
{{$isActive := eq $currentPath "/discover"}}
|
||||
<a href="/discover" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-white/5" {{if $isCollapsed}}title="Discover"{{end}}>
|
||||
<a href="/discover" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Discover"{{end}}>
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_rgba(163,230,53,0.6)]"></div>
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_var(--color-accent)]"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}">Discover</span>
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Discover</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{{/* Watchlist */}}
|
||||
{{$isActive := eq $currentPath "/watchlist"}}
|
||||
<a href="/watchlist" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-white/5" {{if $isCollapsed}}title="Watchlist"{{end}}>
|
||||
<a href="/watchlist" class="group relative flex items-center px-7 py-3 transition-colors hover:bg-surface-hover" {{if $isCollapsed}}title="Watchlist"{{end}}>
|
||||
{{if $isActive}}
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_rgba(163,230,53,0.6)]"></div>
|
||||
<div class="bg-accent absolute top-1/2 left-0 h-8 w-0.5 -translate-y-1/2 rounded-r-sm shadow-[0_0_8px_var(--color-accent)]"></div>
|
||||
{{end}}
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}" viewBox="0 0 24 24" fill="currentColor">
|
||||
<svg class="size-6 shrink-0 transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M17 18.113l-3.256-2.326A2.989 2.989 0 0 0 12 15.228c-.629 0-1.232.194-1.744.559L7 18.113V4h10v14.113zM18 2H6a1 1 0 0 0-1 1v17.056c0 .209.065.412.187.581a.994.994 0 0 0 1.394.233l4.838-3.455a1 1 0 0 1 1.162 0l4.838 3.455A1 1 0 0 0 19 20.056V3a1 1 0 0 0-1-1z" />
|
||||
</svg>
|
||||
<div class="nav-label-container grid grid-cols-[1fr] opacity-100 ml-4">
|
||||
<div class="overflow-hidden min-w-0">
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted{{end}}">Watchlist</span>
|
||||
<span class="whitespace-nowrap text-sm font-medium transition-colors duration-200 {{if $isActive}}text-accent{{else}}text-foreground-muted group-hover:text-foreground{{end}}">Watchlist</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -27,21 +27,21 @@
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-12 pb-12">
|
||||
<section class="relative flex flex-col items-center justify-center overflow-hidden rounded-2xl bg-neutral-900 px-6 py-24 text-center">
|
||||
<section class="relative flex flex-col items-center justify-center overflow-hidden rounded-2xl bg-background-surface px-6 py-24 text-center ring-1 ring-border">
|
||||
<div class="from-accent/10 absolute inset-0 bg-linear-to-b to-transparent opacity-50"></div>
|
||||
<div class="relative z-10 flex max-w-2xl flex-col items-center gap-6">
|
||||
<h1 class="text-4xl font-bold tracking-tight text-white sm:text-5xl">
|
||||
<h1 class="text-4xl font-bold tracking-tight text-foreground sm:text-5xl">
|
||||
Don't know what to watch?
|
||||
</h1>
|
||||
<p class="text-lg text-neutral-400">
|
||||
<p class="text-lg text-foreground-muted">
|
||||
Let us pick something for you from our vast collection of anime.
|
||||
</p>
|
||||
<button
|
||||
id="surprise-btn"
|
||||
class="group bg-accent relative inline-flex items-center justify-center gap-2 overflow-hidden rounded-full px-8 py-4 font-medium text-black transition-transform hover:scale-105 active:scale-95 disabled:opacity-70 disabled:hover:scale-100"
|
||||
class="group bg-accent relative inline-flex items-center justify-center gap-2 overflow-hidden rounded-full px-8 py-4 font-medium text-on-accent transition-transform hover:scale-105 active:scale-95 disabled:opacity-70 disabled:hover:scale-100"
|
||||
onclick="handleSurpriseMe()"
|
||||
>
|
||||
<span id="surprise-spinner" class="hidden h-5 w-5 animate-spin rounded-full border-2 border-black border-t-transparent"></span>
|
||||
<span id="surprise-spinner" class="hidden h-5 w-5 animate-spin rounded-full border-2 border-on-accent border-t-transparent"></span>
|
||||
<svg id="surprise-icon" class="h-5 w-5 transition-transform group-hover:rotate-12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
|
||||
</svg>
|
||||
@@ -53,7 +53,7 @@
|
||||
{{/* Trending Section */}}
|
||||
<section class="flex flex-col gap-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white">Trending This Season</h2>
|
||||
<h2 class="text-xl font-semibold text-foreground">Trending This Season</h2>
|
||||
<a href="/browse?order_by=popularity&sort=desc" class="text-accent text-sm hover:underline">View all</a>
|
||||
</div>
|
||||
<div hx-get="/api/discover/trending" hx-trigger="load" hx-swap="outerHTML">
|
||||
@@ -64,7 +64,7 @@
|
||||
{{/* Upcoming Section */}}
|
||||
<section class="flex flex-col gap-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white">Highly Anticipated</h2>
|
||||
<h2 class="text-xl font-semibold text-foreground">Highly Anticipated</h2>
|
||||
<a href="/browse?status=upcoming&order_by=members&sort=desc" class="text-accent text-sm hover:underline">View all</a>
|
||||
</div>
|
||||
<div hx-get="/api/discover/upcoming" hx-trigger="load" hx-swap="outerHTML">
|
||||
@@ -75,7 +75,7 @@
|
||||
{{/* Top Section */}}
|
||||
<section class="flex flex-col gap-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white">All-Time Greats</h2>
|
||||
<h2 class="text-xl font-semibold text-foreground">All-Time Greats</h2>
|
||||
<a href="/browse?order_by=score&sort=desc" class="text-accent text-sm hover:underline">View all</a>
|
||||
</div>
|
||||
<div hx-get="/api/discover/top" hx-trigger="load" hx-swap="outerHTML">
|
||||
@@ -91,7 +91,10 @@
|
||||
gap: 1rem;
|
||||
}
|
||||
.skeleton {
|
||||
background: linear-gradient(90deg, #1f1f1f 25%, #2a2a2a 50%, #1f1f1f 75%);
|
||||
background: light-dark(
|
||||
linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%),
|
||||
linear-gradient(90deg, #1f1f1f 25%, #2a2a2a 50%, #1f1f1f 75%)
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s infinite;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
<section class="w-full">
|
||||
<div class="mb-4 flex items-end justify-between">
|
||||
<h2 class="text-lg font-semibold text-neutral-200">Currently Airing</h2>
|
||||
<a href="/browse?status=airing&order_by=popularity&sort=desc" class="group flex items-center gap-1 text-sm text-neutral-400 transition-colors hover:text-white">
|
||||
<h2 class="text-lg font-semibold text-foreground">Currently Airing</h2>
|
||||
<a href="/browse?status=airing&order_by=popularity&sort=desc" class="group flex items-center gap-1 text-sm text-foreground-muted transition-colors hover:text-foreground">
|
||||
See more
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="transition-transform group-hover:translate-x-0.5"><path d="m9 18 6-6-6-6"/></svg>
|
||||
</a>
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
<section class="w-full">
|
||||
<div class="mb-4 flex items-end justify-between">
|
||||
<h2 class="text-lg font-semibold text-neutral-200">Most Popular</h2>
|
||||
<a href="/browse?order_by=popularity&sort=desc" class="group flex items-center gap-1 text-sm text-neutral-400 transition-colors hover:text-white">
|
||||
<h2 class="text-lg font-semibold text-foreground">Most Popular</h2>
|
||||
<a href="/browse?order_by=popularity&sort=desc" class="group flex items-center gap-1 text-sm text-foreground-muted transition-colors hover:text-foreground">
|
||||
See more
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="transition-transform group-hover:translate-x-0.5"><path d="m9 18 6-6-6-6"/></svg>
|
||||
</a>
|
||||
@@ -34,7 +34,10 @@
|
||||
|
||||
<style>
|
||||
.skeleton {
|
||||
background: linear-gradient(90deg, #1f1f1f 25%, #2a2a2a 50%, #1f1f1f 75%);
|
||||
background: light-dark(
|
||||
linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%),
|
||||
linear-gradient(90deg, #1f1f1f 25%, #2a2a2a 50%, #1f1f1f 75%)
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s infinite;
|
||||
}
|
||||
|
||||
@@ -2,34 +2,34 @@
|
||||
{{define "content"}}
|
||||
{{if .WatchlistIDs}}<script>initWatchlist({{.WatchlistIDs}})</script>{{end}}
|
||||
<div id="watchlist-content" class="flex w-full flex-col gap-6 mt-6">
|
||||
<h1 class="text-xl font-semibold text-white">Watchlist</h1>
|
||||
<h1 class="text-xl font-semibold text-foreground">Watchlist</h1>
|
||||
|
||||
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||
<div class="flex flex-wrap items-center gap-6">
|
||||
<button class="text-sm transition-colors text-white" onclick="filterWatchlist('all', this)">All</button>
|
||||
<button class="text-sm transition-colors text-neutral-400 hover:text-white" onclick="filterWatchlist('watching', this)">Watching</button>
|
||||
<button class="text-sm transition-colors text-neutral-400 hover:text-white" onclick="filterWatchlist('plan_to_watch', this)">Plan to Watch</button>
|
||||
<button class="text-sm transition-colors text-neutral-400 hover:text-white" onclick="filterWatchlist('completed', this)">Completed</button>
|
||||
<button class="text-sm transition-colors text-neutral-400 hover:text-white" onclick="filterWatchlist('dropped', this)">Dropped</button>
|
||||
<button class="text-sm transition-colors text-foreground" onclick="filterWatchlist('all', this)">All</button>
|
||||
<button class="text-sm transition-colors text-foreground-muted hover:text-foreground" onclick="filterWatchlist('watching', this)">Watching</button>
|
||||
<button class="text-sm transition-colors text-foreground-muted hover:text-foreground" onclick="filterWatchlist('plan_to_watch', this)">Plan to Watch</button>
|
||||
<button class="text-sm transition-colors text-foreground-muted hover:text-foreground" onclick="filterWatchlist('completed', this)">Completed</button>
|
||||
<button class="text-sm transition-colors text-foreground-muted hover:text-foreground" onclick="filterWatchlist('dropped', this)">Dropped</button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4">
|
||||
<ui-dropdown class="relative block" data-align="right" data-width="min-w-[150px]">
|
||||
<div data-trigger>
|
||||
<button type="button" class="flex items-center gap-2 text-sm text-neutral-400 transition-colors hover:text-white">
|
||||
<button type="button" class="flex items-center gap-2 text-sm text-foreground-muted transition-colors hover:text-foreground">
|
||||
<span>Sort by: <span id="sort-by-display">Date Added</span></span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div data-content class="hidden absolute z-50 min-w-[150px] bg-background-button rounded-none shadow-2xl right-0 top-full mt-2">
|
||||
<div data-content class="hidden absolute z-50 min-w-[150px] bg-background-button rounded-none shadow-2xl right-0 top-full mt-2 ring-1 ring-border">
|
||||
<div class="flex flex-col py-1">
|
||||
<button class="flex w-full items-center px-4 py-2 text-sm text-white transition-colors hover:bg-white/10" onclick="setSortBy('date', this)">Date Added</button>
|
||||
<button class="flex w-full items-center px-4 py-2 text-sm text-neutral-400 transition-colors hover:bg-white/10 hover:text-white" onclick="setSortBy('title', this)">Title</button>
|
||||
<button class="flex w-full items-center px-4 py-2 text-sm text-foreground transition-colors hover:bg-surface-hover" onclick="setSortBy('date', this)">Date Added</button>
|
||||
<button class="flex w-full items-center px-4 py-2 text-sm text-foreground-muted transition-colors hover:bg-surface-hover hover:text-foreground" onclick="setSortBy('title', this)">Title</button>
|
||||
</div>
|
||||
</div>
|
||||
</ui-dropdown>
|
||||
|
||||
<button type="button" id="sort-order-btn" class="text-neutral-400 transition-colors hover:text-white" onclick="toggleSortOrder(this)">
|
||||
<button type="button" id="sort-order-btn" class="text-foreground-muted transition-colors hover:text-foreground" onclick="toggleSortOrder(this)">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="transition-transform duration-200 rotate-0"><path d="m21 16-4 4-4-4"></path><path d="M17 20V4"></path><path d="m3 8 4-4 4 4"></path><path d="M7 4v16"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
<div id="watchlist-items" class="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4 2xl:grid-cols-6 mt-6">
|
||||
{{range $.AllEntries}}
|
||||
<div class="watchlist-item flex w-full flex-col gap-2" data-status="{{.Status}}" data-updated-at="{{.UpdatedAt.Unix}}" data-episode="{{.CurrentEpisode.Int64}}" data-time="{{.CurrentTimeSeconds}}" data-title="{{.DisplayTitle}}">
|
||||
<div class="group relative flex aspect-2/3 w-full flex-col overflow-hidden bg-white/5 after:absolute after:inset-0 after:bg-black/80 after:opacity-0 hover:after:opacity-100 after:transition-opacity">
|
||||
<div class="group relative flex aspect-2/3 w-full flex-col overflow-hidden bg-background-surface ring-1 ring-border after:absolute after:inset-0 after:bg-black/80 after:opacity-0 hover:after:opacity-100 after:transition-opacity">
|
||||
<a href="/anime/{{.AnimeID}}" class="absolute inset-0 z-10"></a>
|
||||
<img src="{{.ImageUrl}}" alt="{{.DisplayTitle}}" class="h-full w-full object-cover" loading="lazy" />
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<a href="/anime/{{.AnimeID}}" class="group/title">
|
||||
<h3 class="line-clamp-2 text-sm font-medium text-white group-hover/title:text-neutral-300 transition-colors">
|
||||
<h3 class="line-clamp-2 text-sm font-medium text-foreground group-hover/title:text-foreground-muted transition-colors">
|
||||
{{.DisplayTitle}}
|
||||
</h3>
|
||||
</a>
|
||||
@@ -60,13 +60,13 @@
|
||||
{{end}}
|
||||
|
||||
{{if eq (len $.AllEntries) 0}}
|
||||
<div class="col-span-full flex flex-col items-center justify-center gap-4 py-24 text-neutral-400">
|
||||
<div class="col-span-full flex flex-col items-center justify-center gap-4 py-24 text-foreground-muted">
|
||||
<svg class="h-16 w-16 opacity-30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /></svg>
|
||||
<p class="text-lg text-neutral-300 font-medium">Your watchlist is empty</p>
|
||||
<p class="text-sm text-neutral-500">Start adding anime to keep track of what you want to watch</p>
|
||||
<p class="text-lg text-foreground font-medium">Your watchlist is empty</p>
|
||||
<p class="text-sm text-foreground-muted">Start adding anime to keep track of what you want to watch</p>
|
||||
<div class="flex gap-3 mt-2">
|
||||
<a href="/" class="px-5 py-2.5 text-sm font-medium bg-accent-warm/20 hover:bg-accent-warm/30 text-accent-warm transition-colors">Browse anime</a>
|
||||
<a href="/discover" class="px-5 py-2.5 text-sm font-medium bg-white/10 hover:bg-white/20 text-neutral-200 transition-colors">Discover new</a>
|
||||
<a href="/" class="px-5 py-2.5 text-sm font-medium bg-accent/20 hover:bg-accent/30 text-accent transition-colors">Browse anime</a>
|
||||
<a href="/discover" class="px-5 py-2.5 text-sm font-medium bg-background-surface hover:bg-background-button-hover text-foreground ring-1 ring-border transition-colors">Discover new</a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -81,11 +81,11 @@
|
||||
// Update active tab styling
|
||||
const parent = btn.parentElement
|
||||
parent.querySelectorAll('button').forEach(function(b) {
|
||||
b.classList.remove('text-white')
|
||||
b.classList.add('text-neutral-400')
|
||||
b.classList.remove('text-foreground')
|
||||
b.classList.add('text-foreground-muted')
|
||||
})
|
||||
btn.classList.remove('text-neutral-400')
|
||||
btn.classList.add('text-white')
|
||||
btn.classList.remove('text-foreground-muted')
|
||||
btn.classList.add('text-foreground')
|
||||
|
||||
// Show/hide items
|
||||
document.querySelectorAll('.watchlist-item').forEach(function(item) {
|
||||
@@ -107,11 +107,11 @@
|
||||
// Update button colors in dropdown
|
||||
const dropdown = btn.closest('[data-content]')
|
||||
dropdown.querySelectorAll('button').forEach(function(b) {
|
||||
b.classList.remove('text-white')
|
||||
b.classList.add('text-neutral-400')
|
||||
b.classList.remove('text-foreground')
|
||||
b.classList.add('text-foreground-muted')
|
||||
})
|
||||
btn.classList.remove('text-neutral-400')
|
||||
btn.classList.add('text-white')
|
||||
btn.classList.remove('text-foreground-muted')
|
||||
btn.classList.add('text-foreground')
|
||||
|
||||
sortItems()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user