refactor: replace custom css utilities with tailwind arbitrary

This commit is contained in:
2026-05-24 20:06:32 +02:00
parent da9bb56d80
commit cfaf6e6640
12 changed files with 47 additions and 142 deletions

View File

@@ -16,7 +16,6 @@
--color-foreground: light-dark(#111111, #f3f4f6);
--color-accent: #216a97;
--color-border: light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.1));
--color-surface-hover: light-dark(rgba(0, 0, 0, 0.04), rgba(255, 255, 255, 0.05));
}
@@ -72,97 +71,3 @@ body {
background-color: var(--color-background);
color: var(--text);
}
button:not([data-unstyled-button]) {
border: 1px solid var(--color-border);
}
@layer utilities {
.shadow-soft {
box-shadow: var(--shadow-card);
}
.shadow-soft-hover:hover {
box-shadow: var(--shadow-card-hover);
}
.border-hairline {
border: 1px solid var(--color-border);
}
.heading-serif {
font-family: var(--font-serif);
letter-spacing: -0.03em;
line-height: 1.15;
}
.mono {
font-family: var(--font-mono);
}
}
/* Default to square corners; opt back in selectively (e.g. inputs). */
:where(input, textarea, select) {
border-radius: 6px !important;
}
:where(.rounded-keep) {
border-radius: 6px !important;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
@media (min-width: 1024px) {
.scrollbar-hide::-webkit-scrollbar {
display: block;
height: 8px;
}
.scrollbar-hide::-webkit-scrollbar-track {
background: var(--scrollbar-track);
border-radius: 0;
}
.scrollbar-hide::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb);
border-radius: 0;
}
.scrollbar-hide::-webkit-scrollbar-thumb:hover {
background: var(--scrollbar-thumb-hover);
}
button.in-watchlist .watchlist-icon {
fill: currentColor !important;
}
.scrollbar-hide {
-ms-overflow-style: auto;
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
}
}
.show-controls [data-video-overlay] {
opacity: 1;
}
[data-video-player].fullscreen:not(.show-controls) [data-video-overlay] {
opacity: 0 !important;
pointer-events: none;
}
[data-video-player].fullscreen:not(.show-controls) {
cursor: none;
}
[data-video-player].fullscreen:not(.show-controls) video {
cursor: none;
}

View File

@@ -3,7 +3,7 @@
<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 .Items 0 (min (len .Items) 10))}}
<div class="flex gap-3 bg-background-surface p-3 ring-1 ring-border">
<div class="flex gap-3 bg-background-surface p-3">
<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>
@@ -98,7 +98,7 @@
<div class="flex w-full flex-col gap-10 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 border-hairline bg-background-surface shadow-soft">
<div class="aspect-2/3 w-full overflow-hidden bg-background-surface shadow-[var(--shadow-card)]">
{{$imageUrl := "https://placehold.co/400x600?text=No+Image"}}
{{if $anime.Images.Webp.LargeImageURL}}
{{$imageUrl = $anime.Images.Webp.LargeImageURL}}
@@ -111,7 +111,7 @@
<div class="flex grow flex-col">
<div class="mb-4">
<h1 class="heading-serif text-2xl font-normal text-foreground md:text-4xl">
<h1 class="font-[family:var(--font-serif)] tracking-[-0.03em] leading-[1.15] text-2xl font-normal text-foreground md:text-4xl">
{{$anime.DisplayTitle}}
</h1>
{{if and $anime.TitleEnglish (ne $anime.Title $anime.TitleEnglish)}}
@@ -161,7 +161,7 @@
{{end}}
</section>
</div>
<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">
<aside class="fixed right-0 top-0 hidden h-screen w-80 shrink-0 flex-col overflow-y-auto bg-background-sidebar p-10 lg:flex">
<div class="flex flex-col gap-10">
<section>
<h3 class="mb-8 text-lg font-normal text-foreground">Information</h3>
@@ -189,7 +189,7 @@
<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-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>
<a href="/browse?genres={{.MalID}}" class="bg-background-surface px-2.5 py-1 text-[11px] font-normal text-foreground-muted transition-colors hover:bg-background-button-hover hover:text-foreground">{{.Name}}</a>
{{end}}
</dd>
</div>
@@ -199,7 +199,7 @@
<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-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>
<a href="/browse?genres={{.MalID}}" class="bg-background-surface px-2.5 py-1 text-[11px] font-normal text-foreground-muted transition-colors hover:bg-background-button-hover hover:text-foreground">{{.Name}}</a>
{{end}}
</dd>
</div>
@@ -209,7 +209,7 @@
<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-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>
<a href="/browse?genres={{.MalID}}" class="bg-background-surface px-2.5 py-1 text-[11px] font-normal text-foreground-muted transition-colors hover:bg-background-button-hover hover:text-foreground">{{.Name}}</a>
{{end}}
</dd>
</div>
@@ -270,7 +270,7 @@
<div hx-get="/anime/{{$anime.MalID}}?section=statistics" hx-trigger="load" hx-swap="innerHTML">
<div class="flex flex-col gap-3 pt-1 animate-pulse">
{{range (seq 5)}}
<div class="h-4 rounded bg-background-surface ring-1 ring-border"></div>
<div class="h-4 rounded bg-background-surface"></div>
{{end}}
</div>
</div>
@@ -307,7 +307,7 @@
<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-background-surface p-3 ring-1 ring-border h-20">
<div class="flex gap-3 bg-background-surface p-3 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-background-button rounded"></div>
@@ -322,7 +322,7 @@
<div class="w-full">
<div hx-get="/api/watch-order?animeId={{$anime.MalID}}" hx-trigger="revealed">
<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>
<div class="size-5 animate-spin rounded-full border-2 border-t-transparent border-accent"></div>
<span class="text-sm">Loading watch order sequence...</span>
</div>
</div>
@@ -344,10 +344,10 @@
</div>
<div class="fixed inset-0 z-50 hidden items-start justify-center bg-black/50 px-4 pt-[12vh]" data-themes-dialog aria-hidden="true">
<div class="w-full max-w-2xl overflow-hidden bg-background-button shadow-soft ring-1 ring-border">
<div class="flex items-center justify-between border-b border-border px-6 py-4">
<div class="w-full max-w-2xl overflow-hidden bg-background-button shadow-[var(--shadow-card)]">
<div class="flex items-center justify-between px-6 py-4">
<h2 class="text-base font-normal text-foreground">Theme Songs</h2>
<button type="button" data-themes-close class="px-2 py-1 text-xs text-foreground-muted ring-1 ring-border transition-colors hover:text-foreground">Close</button>
<button type="button" data-themes-close class="px-2 py-1 text-xs text-foreground-muted transition-colors hover:text-foreground">Close</button>
</div>
<div data-themes-content class="max-h-[60vh] overflow-y-auto"></div>
</div>

View File

@@ -56,7 +56,7 @@
</style>
<script type="module" src="/dist/static/theme.js" defer></script>
<template id="toast-template">
<div class="toast pointer-events-auto w-[22rem] max-w-[calc(100vw-2rem)] bg-background shadow-soft ring-1 ring-black/5 flex items-start gap-3 px-4 py-3 transform transition-all duration-300 translate-y-2 opacity-0">
<div class="toast pointer-events-auto w-[22rem] max-w-[calc(100vw-2rem)] bg-background shadow-[var(--shadow-card)] ring-1 ring-black/5 flex items-start gap-3 px-4 py-3 transform transition-all duration-300 translate-y-2 opacity-0">
<div class="min-w-0 flex-1">
<div class="toast-message text-sm font-medium text-foreground leading-snug"></div>
</div>
@@ -293,7 +293,7 @@ if (window.showToast) showToast({ message: 'Something went wrong' })
<body class="bg-background text-foreground">
<div class="flex min-h-screen flex-col">
{{if .User}}
<header class="fixed inset-x-0 top-0 z-50 flex h-14 items-center border-b border-border bg-background-sidebar px-4 lg:hidden">
<header class="fixed inset-x-0 top-0 z-50 flex h-14 items-center bg-background-sidebar px-4 lg:hidden">
<button type="button" data-unstyled-button data-mobile-menu-toggle class="inline-flex items-center justify-center bg-background-button p-2 text-foreground" aria-label="Open menu" aria-controls="mobile-menu" aria-expanded="false">
<svg class="size-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<path d="M4 6h16"></path>
@@ -315,9 +315,9 @@ if (window.showToast) showToast({ message: 'Something went wrong' })
</div>
<div class="fixed inset-0 z-[60] hidden items-start justify-center bg-black/50 px-4 pt-[12vh]" data-command-palette-dialog aria-hidden="true">
<div class="w-full max-w-2xl overflow-hidden bg-background-button shadow-soft ring-1 ring-border" data-command-palette-root role="dialog" aria-modal="true" aria-label="Command palette">
<div class="w-full max-w-2xl overflow-hidden bg-background-button shadow-[var(--shadow-card)]" data-command-palette-root role="dialog" aria-modal="true" aria-label="Command palette">
<label for="command-palette-input" class="sr-only">Search commands and anime</label>
<div class="flex items-center border-b border-border">
<div class="flex items-center">
<svg class="mx-4 size-5 shrink-0 text-foreground-muted" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8" />
<path d="m21 21-4.35-4.35" />

View File

@@ -7,7 +7,7 @@
{{define "browse_content"}}
<div id="browse-content" class="flex flex-col gap-6">
<div class="flex items-end justify-between">
<h1 class="heading-serif text-xl font-normal text-foreground">Browse</h1>
<h1 class="font-[family:var(--font-serif)] tracking-[-0.03em] leading-[1.15] text-xl font-normal text-foreground">Browse</h1>
</div>
{{template "filter_bar" .}}
@@ -18,7 +18,7 @@
<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-foreground">No anime found</p>
<div class="flex gap-2">
<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" class="px-4 py-2 text-sm bg-background-surface hover:bg-background-button-hover text-foreground 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>

View File

@@ -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 border-hairline 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">
<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}}

View File

@@ -4,7 +4,7 @@
{{template "dropdown_trigger" .}}
</div>
<div data-content class="hidden absolute z-50 {{if .Width}}{{.Width}}{{else}}min-w-[320px]{{end}} bg-background-button rounded-none shadow-soft ring-1 ring-border {{if eq .Align "left"}}left-0{{else}}right-0{{end}} {{if eq .Position "top"}}bottom-full mb-2{{else}}top-full mt-2{{end}}">
<div data-content class="hidden absolute z-50 {{if .Width}}{{.Width}}{{else}}min-w-[320px]{{end}} bg-background-button rounded-none shadow-[var(--shadow-card)] {{if eq .Align "left"}}left-0{{else}}right-0{{end}} {{if eq .Position "top"}}bottom-full mb-2{{else}}top-full mt-2{{end}}">
<div class="flex flex-col py-1">
{{template "dropdown_children" .}}
</div>

View File

@@ -10,7 +10,7 @@
type="text"
value="{{.Query}}"
placeholder="Search anime..."
class="!rounded-none focus:ring-accent w-full bg-background-button px-3 py-2 text-sm text-foreground placeholder-foreground-muted outline-none focus:ring-1"
class="!rounded-none w-full bg-background-button px-3 py-2 text-sm text-foreground placeholder-foreground-muted outline-none transition-colors hover:bg-background-button-hover focus:ring-1 focus:ring-accent"
/>
{{if .Type}}<input type="hidden" name="type" value="{{.Type}}">{{end}}
{{if .Status}}<input type="hidden" name="status" value="{{.Status}}">{{end}}
@@ -30,9 +30,9 @@
<input type="hidden" name="sfw" value="{{.SFW}}" data-sfw-value>
{{range $g := .Genres}}<input type="hidden" name="genres" value="{{$g}}">{{end}}
<label class="flex cursor-pointer items-center gap-2">
<input id="filter-sfw" type="checkbox" class="sr-only" {{if .SFW}}checked{{end}} onchange="this.form.querySelector('[data-sfw-value]').value = this.checked; const box = this.nextElementSibling; box.classList.toggle('border-accent', this.checked); box.classList.toggle('bg-accent', this.checked); box.classList.toggle('border-border', !this.checked); box.classList.toggle('bg-transparent', !this.checked); box.querySelector('svg').classList.toggle('hidden', !this.checked)">
<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}}">
<svg class="{{if not .SFW}}hidden {{end}}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>
<input id="filter-sfw" type="checkbox" class="sr-only" {{if .SFW}}checked{{end}} onchange="this.form.querySelector('[data-sfw-value]').value = this.checked; const box = this.nextElementSibling; const icon = box.querySelector('svg'); icon.classList.toggle('hidden', !this.checked)">
<div class="flex h-4 w-4 items-center justify-center bg-white transition-colors">
<svg class="{{if not .SFW}}hidden {{end}}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>
</div>
SFW
</label>
@@ -45,7 +45,7 @@
<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-soft ring-1 ring-border 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-[var(--shadow-card)] left-0 top-full mt-2 ">
<form action="/browse" method="GET" hx-get="/browse" hx-trigger="change" hx-target="#browse-content main" hx-select="#browse-content main" hx-swap="outerHTML" class="flex flex-col py-1">
<input type="hidden" name="q" value="{{.Query}}">
{{if .Type}}<input type="hidden" name="type" value="{{.Type}}">{{end}}
@@ -57,8 +57,8 @@
{{$genreID := .MalID}}
{{$isSelected := hasGenre $genreID $selectedGenreIDs}}
<label class="flex cursor-pointer items-center gap-3 px-2 py-1.5 text-sm text-foreground-muted hover:bg-surface-hover hover:text-foreground">
<input id="genre-{{.MalID}}" type="checkbox" class="sr-only" name="genres" value="{{.MalID}}" {{if $isSelected}}checked{{end}} onchange="const box = this.nextElementSibling; box.classList.toggle('border-accent', this.checked); box.classList.toggle('bg-accent', this.checked); box.classList.toggle('border-border', !this.checked); box.classList.toggle('bg-transparent', !this.checked); box.querySelector('svg').classList.toggle('hidden', !this.checked)">
<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}}">
<input id="genre-{{.MalID}}" type="checkbox" class="sr-only" name="genres" value="{{.MalID}}" {{if $isSelected}}checked{{end}} onchange="const box = this.nextElementSibling; box.classList.toggle('bg-accent', this.checked); box.classList.toggle('bg-transparent', !this.checked); box.querySelector('svg').classList.toggle('hidden', !this.checked)">
<div class="flex h-4 w-4 items-center justify-center transition-colors {{if $isSelected}}bg-accent{{else}}bg-transparent{{end}}">
<svg class="{{if not $isSelected}}hidden {{end}}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>
</div>
{{.Name}}
@@ -75,7 +75,7 @@
<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-soft ring-1 ring-border left-0 top-full mt-2 ">
<div data-content class="hidden absolute z-50 w-40 bg-background-button rounded-none shadow-[var(--shadow-card)] left-0 top-full mt-2 ">
<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-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>
@@ -92,7 +92,7 @@
<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-soft ring-1 ring-border left-0 top-full mt-2 ">
<div data-content class="hidden absolute z-50 w-40 bg-background-button rounded-none shadow-[var(--shadow-card)] left-0 top-full mt-2 ">
<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-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>
@@ -112,7 +112,7 @@
<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-soft ring-1 ring-border left-0 top-full mt-2 ">
<div data-content class="hidden absolute z-50 w-48 bg-background-button rounded-none shadow-[var(--shadow-card)] left-0 top-full mt-2 ">
<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-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>
@@ -124,7 +124,7 @@
</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-background-button text-foreground-muted hover:text-foreground transition-colors ring-1 ring-border">
<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 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}}

View File

@@ -12,7 +12,7 @@
data-segments='{{json .WatchData.Segments}}'
data-anime-title-english="{{.WatchData.Title}}"
data-anime-image="{{.WatchData.MalID}}"
class="group relative aspect-video w-full overflow-hidden bg-black">
class="group relative aspect-video w-full overflow-hidden bg-black [&.show-controls_[data-video-overlay]]:opacity-100 [&.fullscreen:not(.show-controls)_[data-video-overlay]]:opacity-0 [&.fullscreen:not(.show-controls)_[data-video-overlay]]:pointer-events-none [&.fullscreen:not(.show-controls)]:cursor-none [&.fullscreen:not(.show-controls)_video]:cursor-none">
<video class="h-full w-full cursor-pointer" preload="metadata" playsinline></video>
@@ -73,7 +73,7 @@
<svg class="size-6 transition-transform duration-300" 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="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
</button>
</div>
<div data-content class="hidden absolute z-50 w-64 bg-background-button rounded-none shadow-soft ring-1 ring-border right-0 bottom-full mb-2">
<div data-content class="hidden absolute z-50 w-64 bg-background-button rounded-none shadow-[var(--shadow-card)] right-0 bottom-full mb-2">
<div class="flex flex-col py-1">
<div class="flex items-center justify-between px-5 py-2.5">
<span class="text-[15px] font-medium text-foreground">Autoplay</span>
@@ -101,11 +101,11 @@
</button>
<div class="hidden px-5 py-2 flex flex-col gap-1">
<span class="text-[10px] text-neutral-500 uppercase font-bold tracking-widest">Subtitles</span>
<select id="player-subtitle-select" data-subtitle-select class="w-full bg-white/5 text-white text-xs border border-white/10 px-2 py-1.5 outline-none rounded focus:border-accent"></select>
<select id="player-subtitle-select" data-subtitle-select class="w-full bg-white/5 text-white text-xs px-2 py-1.5 outline-none rounded"></select>
</div>
<div class="hidden px-5 py-2 flex flex-col gap-1">
<span class="text-[10px] text-neutral-500 uppercase font-bold tracking-widest">Quality</span>
<select id="player-quality-select" data-quality-select class="w-full bg-white/5 text-white text-xs border border-white/10 px-2 py-1.5 outline-none rounded focus:border-accent"></select>
<select id="player-quality-select" data-quality-select class="w-full bg-white/5 text-white text-xs px-2 py-1.5 outline-none rounded"></select>
</div>
</div>
</div>

View File

@@ -6,7 +6,7 @@
<div class="flex gap-2">
<ui-dropdown class="relative block" data-align="left" data-width="min-w-[160px]">
<div data-trigger class="cursor-pointer">
<button type="button" class="bg-background-button hover:bg-background-button-hover flex items-center justify-between gap-3 px-4 py-2.5 text-sm font-medium text-foreground transition-colors border border-border disabled:opacity-50">
<button type="button" class="bg-background-button hover:bg-background-button-hover flex items-center justify-between gap-3 px-4 py-2.5 text-sm font-medium text-foreground transition-colors disabled:opacity-50">
<span id="watchlist-status-display-{{$anime.MalID}}">
{{if $status}}
{{if eq $status "watching"}}Watching{{end}}
@@ -21,7 +21,7 @@
</button>
</div>
<div data-content class="hidden absolute z-50 min-w-[160px] bg-background-button rounded-none shadow-soft ring-1 ring-border left-0 top-full mt-2">
<div data-content class="hidden absolute z-50 min-w-[160px] bg-background-button rounded-none shadow-[var(--shadow-card)] left-0 top-full mt-2">
<div class="flex flex-col py-1">
<button data-unstyled-button class="flex w-full items-center px-5 py-2.5 transition-colors focus:outline-none hover:bg-foreground/10 focus:bg-foreground/10" onclick="updateWatchlist({{$anime.MalID}}, 'watching', 'Watching', '{{$anime.DisplayTitle}}', this)">
<span class="font-medium text-sm text-foreground">Watching</span>
@@ -48,7 +48,7 @@
</div>
</ui-dropdown>
<a href="/anime/{{$anime.MalID}}/watch{{if gt .ContinueWatchingEp 0}}?ep={{.ContinueWatchingEp}}{{end}}" class="inline-flex items-center justify-center bg-background-button hover:bg-background-button-hover px-5 py-2.5 text-sm font-medium text-foreground transition-colors border border-border">
<a href="/anime/{{$anime.MalID}}/watch{{if gt .ContinueWatchingEp 0}}?ep={{.ContinueWatchingEp}}{{end}}" class="inline-flex items-center justify-center bg-background-button hover:bg-background-button-hover px-5 py-2.5 text-sm font-medium text-foreground transition-colors">
{{if gt .ContinueWatchingEp 0}}Continue Watching Ep {{.ContinueWatchingEp}}{{else}}Watch Now{{end}}
</a>
</div>

View File

@@ -39,10 +39,10 @@
</script>
<div class="flex flex-col gap-12 pb-12">
<section class="relative flex flex-col items-center justify-center overflow-hidden bg-background-surface px-6 py-24 text-center ring-1 ring-border">
<section class="relative flex flex-col items-center justify-center overflow-hidden bg-background-surface px-6 py-24 text-center">
<div class="absolute inset-0 opacity-40" style="background: radial-gradient(60% 60% at 50% 0%, rgba(0,0,0,0.06), transparent 70%);"></div>
<div class="relative z-10 flex max-w-2xl flex-col items-center gap-6">
<h1 class="heading-serif text-4xl font-normal tracking-tight text-foreground sm:text-5xl">
<h1 class="font-[family:var(--font-serif)] tracking-[-0.03em] leading-[1.15] text-4xl font-normal tracking-tight text-foreground sm:text-5xl">
Don't know what to watch?
</h1>
<p class="text-lg text-foreground-muted">

View File

@@ -2,7 +2,7 @@
{{define "content"}}
{{if .WatchlistIDs}}<script>initWatchlist({{.WatchlistIDs}})</script>{{end}}
<div id="watchlist-content" class="flex w-full flex-col gap-6">
<h1 class="heading-serif text-xl font-normal text-foreground">Watchlist</h1>
<h1 class="font-[family:var(--font-serif)] tracking-[-0.03em] leading-[1.15] text-xl font-normal text-foreground">Watchlist</h1>
<div class="flex flex-wrap items-center justify-between gap-4">
<div class="flex flex-wrap items-center gap-6">
@@ -29,7 +29,7 @@
<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-soft right-0 top-full mt-2 ring-1 ring-border">
<div data-content class="hidden absolute z-50 min-w-[150px] bg-background-button rounded-none shadow-[var(--shadow-card)] right-0 top-full mt-2">
<div class="flex flex-col py-1">
<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>
@@ -47,7 +47,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-mal-id="{{.AnimeID}}" 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-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">
<div class="group relative flex aspect-2/3 w-full flex-col overflow-hidden bg-background-surface 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" />
@@ -74,7 +74,7 @@
<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/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>
<a href="/discover" class="px-5 py-2.5 text-sm font-medium bg-background-surface hover:bg-background-button-hover text-foreground transition-colors">Discover new</a>
</div>
</div>
{{end}}

View File

@@ -1,7 +1,7 @@
{{define "title"}}Watchlist{{end}}
{{define "content"}}
<div id="watchlist-content" class="flex w-full flex-col gap-6">
<h1 class="heading-serif text-lg font-normal text-foreground">Watchlist</h1>
<h1 class="font-[family:var(--font-serif)] tracking-[-0.03em] leading-[1.15] text-lg font-normal text-foreground">Watchlist</h1>
<div class="flex flex-wrap items-center justify-between gap-4">
<div class="flex flex-wrap items-center gap-6">
@@ -20,7 +20,7 @@
<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="M2 5h20"></path><path d="M6 12h12"></path><path d="M9 19h6"></path></svg>
</button>
</div>
<div data-content class="hidden absolute z-50 min-w-[150px] bg-background-button rounded-none shadow-soft ring-1 ring-border right-0 top-full mt-2">
<div data-content class="hidden absolute z-50 min-w-[150px] bg-background-button rounded-none shadow-[var(--shadow-card)] right-0 top-full mt-2">
<div class="flex flex-col py-1">
<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>