Changes to styling and font

This commit is contained in:
Aleksi Lassila
2023-08-02 22:55:00 +03:00
parent 353121dcf3
commit 4646883dff
8 changed files with 154 additions and 268 deletions

View File

@@ -12,5 +12,5 @@ a {
}
.selectable {
@apply focus-within:outline outline-2 outline-lighten outline-offset-2;
@apply focus-within:outline outline-2 outline-[#FDEA8A88] outline-offset-2;
}

View File

@@ -6,16 +6,23 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=Inter:wght@100;200;300;400;500;600;700;800;900&family=Nunito+Sans:wght@200;300;400;500;600;700;800;900;1000&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=Inter:wght@100;200;300;400;500;600;700;800;900&family=Nunito+Sans:wght@200;300;400;500;600;700;800;900;1000&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=Inter:wght@100;200;300;400;500;600;700;800;900&family=Montserrat:wght@100;200;300;400;500;600;700;800;900&display=swap"
rel="stylesheet"
/>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" class="bg-stone-900 min-h-screen text-white">
<body data-sveltekit-preload-data="hover" class="bg-stone-950 min-h-screen text-white">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -5,24 +5,39 @@
const dispatch = createEventDispatcher();
export let size: 'md' | 'sm' | 'lg' = 'md';
export let type: 'primary' | 'secondary' | 'tertiary' = 'primary';
export let type: 'primary' | 'secondary' | 'tertiary' = 'secondary';
export let disabled = false;
export let href: string | undefined = undefined;
export let target: string | undefined = undefined;
let buttonStyle: string;
// $: buttonStyle = classNames(
// 'border-2 border-white transition-all uppercase tracking-widest text-xs whitespace-nowrap',
// {
// 'bg-white text-zinc-900 font-extrabold': type === 'primary',
// 'hover:bg-amber-400 hover:border-amber-400': type === 'primary' && !disabled,
// 'font-semibold': type === 'secondary',
// 'hover:bg-white hover:text-black': type === 'secondary' && !disabled,
// 'px-8 py-3.5': size === 'lg',
// 'px-6 py-2.5': size === 'md',
// 'px-5 py-2': size === 'sm',
// 'opacity-70': disabled,
// 'cursor-pointer': !disabled
// }
// );
$: buttonStyle = classNames(
'border-2 border-white transition-all uppercase tracking-widest text-xs whitespace-nowrap',
'flex items-center gap-1 py-3 px-6 rounded-xl font-medium select-none cursor-pointer selectable transition-all backdrop-blur-lg',
{
'bg-white text-zinc-900 font-extrabold': type === 'primary',
'hover:bg-amber-400 hover:border-amber-400': type === 'primary' && !disabled,
'font-semibold': type === 'secondary',
'hover:bg-white hover:text-black': type === 'secondary' && !disabled,
'px-8 py-3.5': size === 'lg',
'px-6 py-2.5': size === 'md',
'text-zinc-200 bg-stone-800 bg-opacity-30': type === 'secondary',
'focus-visible:bg-zinc-200 focus-visible:text-zinc-800 hover:bg-zinc-200 hover:text-zinc-800':
type === 'secondary' && !disabled,
'py-3 px-6': size === 'lg',
// 'py-3 px-6': size === 'md',
'px-5 py-2': size === 'sm',
'opacity-70': disabled,
'opacity-50': disabled,
'cursor-pointer': !disabled
}
);
@@ -37,7 +52,14 @@
};
</script>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<button class={buttonStyle} on:click={handleClick} on:mouseover on:mouseleave {disabled}>
<button
class={buttonStyle}
on:click={handleClick}
on:focus
on:mouseover
on:mouseleave
on:blur
{disabled}
>
<slot />
</button>

View File

@@ -6,7 +6,7 @@
<a
href={`/discover/network/${network.name}`}
class="border rounded-xl h-52 w-96 bg-stone-800 border-stone-700 cursor-pointer p-12 text-zinc-300 hover:text-amber-200 transition-all relative group selectable"
class="block border rounded-xl h-52 w-96 bg-stone-900 border-stone-700 cursor-pointer p-12 text-zinc-300 hover:text-amber-200 transition-all relative group selectable flex-shrink-0"
>
<div
class="absolute inset-10 bg-zinc-300 hover:bg-amber-200 group-hover:scale-105 transition-all"

View File

@@ -1,20 +1,19 @@
<script lang="ts">
import { getJellyfinEpisodes } from '$lib/apis/jellyfin/jellyfinApi';
import { getTmdbSeriesSeasons, type CastMember, type Video } from '$lib/apis/tmdb/tmdbApi';
import type { CastMember, Video } from '$lib/apis/tmdb/tmdbApi';
import Button from '$lib/components/Button.svelte';
import { TMDB_IMAGES_ORIGINAL } from '$lib/constants';
import { library } from '$lib/stores/library.store';
import { settings } from '$lib/stores/settings.store';
import { formatMinutesToTime } from '$lib/utils';
import classNames from 'classnames';
import { ChevronDown, Clock } from 'radix-icons-svelte';
import { ChevronDown, ChevronRight, Clock } from 'radix-icons-svelte';
import type { ComponentProps } from 'svelte';
import { fade, fly } from 'svelte/transition';
import EpisodeCard from '../EpisodeCard/EpisodeCard.svelte';
import HeightHider from '../HeightHider.svelte';
import { playerState } from '../VideoPlayer/VideoPlayer';
import LibraryDetails from './LibraryDetails.svelte';
import SeasonsDetails from './SeasonsDetails.svelte';
import type { ComponentProps } from 'svelte';
export let tmdbId: number;
export let type: 'movie' | 'tv';
@@ -99,229 +98,6 @@
}
}
// async function fetchPlayDetails(tmdbId: number, numberOfSeasons?: number) {
// const libraryData = await $library;
// const jellyfinItem = libraryData.items[tmdbId]?.jellyfinItem;
// const movieData = type === 'movie' ? await fetchMovieData() : undefined;
// const showData =
// type === 'tv' && numberOfSeasons ? await fetchShowData(tmdbId, numberOfSeasons) : undefined;
// return {
// jellyfinItem,
// ...movieData,
// ...showData
// };
// }
// async function fetchMovieData() {
// const radarrMoviePromise = getRadarrMovieByTmdbId(String(tmdbId));
// const radarrMovieQueuedPromise = radarrMoviePromise.then((movie) =>
// movie?.id ? getRadarrDownloadsById(movie.id) : undefined
// );
// const libraryData = await $library;
// return {
// playableMovie: libraryData.getMovie(tmdbId),
// radarrMovie: await radarrMoviePromise,
// radarrDownloads: await radarrMovieQueuedPromise
// };
// }
// async function fetchShowData(tmdbId: number, numberOfSeasons: number) {
// const tmdbSeasonsPromises = getTmdbSeriesSeasons(tmdbId, numberOfSeasons);
// const libraryData = await $library;
// const librarySeries = libraryData.getSeries(tmdbId);
// const sonarrSeriesPromise = librarySeries?.tmdbId
// ? getSonarrSeriesByTvdbId(librarySeries.tmdbId)
// : undefined;
// const sonarrDownloadsPromise = sonarrSeriesPromise?.then((series) =>
// series?.id ? getSonarrDownloadsById(series.id) : undefined
// );
// const sonarrEpisodePromises = sonarrSeriesPromise?.then((series) =>
// series ? getSonarrEpisodes(series.id) : undefined
// );
// const jellyfinEpisodesPromise = librarySeries?.jellyfinId
// ? getJellyfinEpisodes(librarySeries.jellyfinId)
// : undefined;
// return {
// playableSeries: librarySeries,
// tmdbSeasons: await tmdbSeasonsPromises,
// sonarrSeries: await sonarrSeriesPromise,
// sonarrDownloads: await sonarrDownloadsPromise,
// sonarrEpisodes: await sonarrEpisodePromises,
// jellyfinEpisodes: await jellyfinEpisodesPromise
// };
// }
// async function fetchLibraryData(): Promise<{ isAdded: boolean }> {
// if (type === 'movie') {
// const jellyfinItemPromise = getJellyfinItemByTmdbId(String(tmdbId));
// const radarrMoviePromise = getRadarrMovieByTmdbId(String(tmdbId));
// const radarrMovieQueuedPromise = radarrMoviePromise.then((movie) =>
// movie?.id ? getRadarrDownloadsById(movie.id) : undefined
// );
// const radarrMovie = await radarrMoviePromise;
// const radarrDownloads = await radarrMovieQueuedPromise;
// const jellyfinItem = await jellyfinItemPromise;
// servarrId = radarrMovie?.id;
// if (radarrDownloads) {
// downloadProps = radarrDownloads.map((download) => ({
// status: 'downloading',
// resolution: download.quality?.quality?.resolution || 0,
// sizeOnDisk: download.size || 0,
// qualityType: download.quality?.quality?.source || 'Unknown',
// videoCodec: 'Unknown',
// downloadEta: new Date(download.estimatedCompletionTime || Date.now()),
// cancelDownload: () => {
// if (download.id && !cancelDownloadFetching) cancelDownload(download.id);
// }
// }));
// }
// if (radarrMovie?.movieFile) {
// movieFileProps = [
// {
// status: 'ready',
// resolution: radarrMovie.movieFile.quality?.quality?.resolution || 0,
// sizeOnDisk: radarrMovie.movieFile.size || 0,
// qualityType: radarrMovie.movieFile.quality?.quality?.source || 'Unknown',
// videoCodec: radarrMovie.movieFile.mediaInfo?.videoCodec || 'Unknown',
// downloadEta: undefined,
// deleteFile: () => {
// if (radarrMovie?.movieFile?.id && !deleteMovieFetching)
// deleteFile(radarrMovie.movieFile.id);
// },
// jellyfinStreamDisabled: !jellyfinItem,
// openJellyfinStream: () => {
// if (jellyfinItem?.Id) streamJellyfinId(jellyfinItem.Id);
// }
// }
// ];
// }
// return {
// isAdded: !!radarrMovie
// };
// } else {
// const tvdbId = await getTmdbSeries(tmdbId).then((series) => series?.external_ids?.tvdb_id);
// if (!tvdbId) throw new Error("Couldn't find tvdb id");
// const jellyfinItemPromise = getJellyfinItemByTmdbId(String(tmdbId));
// const sonarrSeriesPromise = getSonarrSeriesByTvdbId(tvdbId);
// const sonarrDownloadsPromise = sonarrSeriesPromise.then((series) =>
// series?.id ? getSonarrDownloadsById(series.id) : undefined
// );
// const sonarrEpisodePromises = sonarrSeriesPromise.then((series) =>
// series ? getSonarrEpisodes(series.id) : undefined
// );
// const sonarrSeries = await sonarrSeriesPromise;
// const sonarrDownloads = await sonarrDownloadsPromise;
// const jellyfinItem = await jellyfinItemPromise;
// const sonarrEpisodes = await sonarrEpisodePromises.then((episodes) =>
// episodes?.filter((episode) => episode.episode.absoluteEpisodeNumber !== undefined)
// );
// sonarrEpisodes?.sort((a, b) => {
// if (!a.episode.absoluteEpisodeNumber || !b.episode.absoluteEpisodeNumber) return -1;
// return a.episode.absoluteEpisodeNumber - b.episode.absoluteEpisodeNumber;
// });
// if (sonarrDownloads) {
// }
// if (sonarrEpisodes) {
// seasonFileProps = [];
// for (const episode of sonarrEpisodes) {
// if (episode.episodeFile) {
// seasonFileProps[(episode.episode.seasonNumber || 1) - 1] = [
// ...(seasonFileProps[(episode.episode.seasonNumber || 1) - 1] || []),
// {
// episodeNumber: episode.episode.episodeNumber,
// status: 'ready',
// resolution: episode.episodeFile.quality?.quality?.resolution || 0,
// sizeOnDisk: episode.episodeFile.size || 0,
// qualityType: episode.episodeFile.quality?.quality?.source || 'Unknown',
// videoCodec: episode.episodeFile.mediaInfo?.videoCodec || 'Unknown',
// downloadEta: undefined,
// deleteFile: () => {
// if (episode?.episodeFile?.id && !deleteMovieFetching)
// deleteFile(episode.episodeFile.id);
// },
// jellyfinStreamDisabled: !jellyfinItem,
// openJellyfinStream: () => {
// if (jellyfinItem?.Id) streamJellyfinId(jellyfinItem.Id);
// }
// }
// ];
// }
// }
// }
// servarrId = sonarrSeries?.id;
// return {
// isAdded: !!sonarrSeries
// };
// }
// async function fetchSeasonDetails() {
// if (seasons > 0 && type === 'tv') {
// const tmdbSeasonsPromises = getTmdbSeriesSeasons(tmdbId, seasons);
// const libraryData = await $library;
// const jellyfinSeriesId = libraryData.getSeries(tmdbId)?.jellyfinId;
// const jellyfinEpisodesPromise = jellyfinSeriesId
// ? getJellyfinEpisodes(jellyfinSeriesId)
// : undefined;
// const tmdbSeasons = await tmdbSeasonsPromises;
// const jellyfinEpisodes = await jellyfinEpisodesPromise;
// jellyfinEpisodes?.sort((a, b) => (a.IndexNumber || 99) - (b.IndexNumber || 99));
// const nextJellyfinEpisode = jellyfinEpisodes?.find((e) => e?.UserData?.Played === false);
// const nextEpisode = {
// jellyfinEpisode: nextJellyfinEpisode,
// tmdbEpisode: nextJellyfinEpisode
// ? tmdbSeasons
// .flatMap((s) => s?.episodes)
// .find(
// (e) =>
// e?.episode_number === nextJellyfinEpisode.IndexNumber &&
// e?.season_number === nextJellyfinEpisode.ParentIndexNumber
// )
// : undefined
// };
// return {
// currentSeason: nextEpisode?.tmdbEpisode?.season_number || 1,
// nextEpisode,
// tmdbSeasons,
// jellyfinEpisodes
// };
// }
// }
async function fetchSeriesData() {
const tmdbSeasonsPromise = getTmdbSeriesSeasons(tmdbId, seasons);
const jellyfinEpisodesPromise = jellyfinId ? getJellyfinEpisodes(jellyfinId) : undefined;
return {
tmdbSeasons: await tmdbSeasonsPromise,
jellyfinEpisodes: await jellyfinEpisodesPromise
};
}
let localDetails: HTMLDivElement;
</script>
@@ -351,6 +127,7 @@
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
tabindex="-1"
/>
{/if}
</div>
@@ -395,11 +172,11 @@
{/if}
</h2>
<h2
class="tracking-wider font-display font-extrabold text-amber-300 absolute opacity-10 text-8xl -ml-6 mt-8"
class="tracking-wider font-display font-bold text-amber-300 absolute opacity-10 text-8xl -ml-6 mt-16"
>
<slot name="reason">{reason}</slot>
</h2>
<h1 class="uppercase text-8xl font-bold font-display z-[1] relative">
<h1 class="uppercase text-9xl font-semibold font-display z-[1] relative">
{title}
</h1>
</div>
@@ -408,15 +185,63 @@
style={opacityStyle}
in:fly={{ x: -20, duration, delay: 600 }}
>
<div class="text-xl font-semibold tracking-wider">{tagline}</div>
<div class="text-lg font-semibold tracking-wider">{tagline}</div>
<div
class="tracking-wider text-zinc-200 font-light leading-6 pl-4 border-l-2 border-zinc-300"
class="tracking-wider text-sm text-zinc-200 font-light leading-6 pl-4 border-l-2 border-zinc-300"
>
{overview}
</div>
</div>
<div class="flex gap-6 mt-10" in:fly={{ x: -20, duration, delay: 600 }}>
<div class="flex gap-1">
<!-- <button
class={classNames(
'flex items-center gap-1 py-3 px-6 rounded-xl font-medium select-none cursor-pointer selectable transition-all backdrop-blur-lg',
'text-zinc-200 bg-stone-800 bg-opacity-30 focus-visible:bg-zinc-200 focus-visible:text-zinc-800 hover:bg-zinc-200 hover:text-zinc-800'
)}
>
<span>Details</span><ChevronRight size={20} />
</button>
<button
class={classNames(
'flex items-center gap-1 py-3 px-6 rounded-xl font-medium select-none cursor-pointer selectable transition-all backdrop-blur-lg',
'text-zinc-200 bg-stone-800 bg-opacity-30 focus-visible:bg-zinc-200 focus-visible:text-zinc-800 hover:bg-zinc-200 hover:text-zinc-800'
)}
>
<span>Watch Trailer</span><ChevronRight size={20} />
</button> -->
<!-- <button
class={classNames(
'flex items-center gap-1 py-2 px-6 rounded-full font-medium select-none cursor-pointer selectable transition-all',
'text-zinc-200 hover:text-zinc-900 border border-zinc-200 border-opacity-50'
)}
>
<span>Details</span><ChevronRight size={20} />
</button>
<button
class={classNames(
'flex items-center gap-1 py-2 px-6 rounded-full font-medium select-none cursor-pointer selectable transition-all',
'text-zinc-200 hover:text-zinc-900 border border-zinc-200 border-opacity-50'
)}
>
<span>Watch Trailer</span><ChevronRight size={20} />
</button> -->
<!-- <button
class={classNames(
'flex items-center gap-1 backdrop-blur-xl py-2.5 px-6 rounded-xl font-medium select-none cursor-pointer selectable transition-all',
'text-zinc-200 bg-stone-700 bg-opacity-50 hover:bg-amber-300 hover:text-zinc-900 hover:bg-opacity-70'
)}
>
<span>Details</span><ChevronRight size={20} />
</button>
<button
class={classNames(
'flex items-center gap-1 backdrop-blur-xl py-2.5 px-6 rounded-xl font-medium select-none cursor-pointer selectable transition-all',
'text-zinc-200 bg-stone-700 bg-opacity-50 hover:bg-amber-300 hover:text-zinc-900 hover:bg-opacity-70'
)}
>
<span>Watch Trailer</span><ChevronRight size={20} />
</button> -->
<!-- <div class="flex gap-1">
<div style={opacityStyle}>
<Button
disabled={streamButtonDisabled}
@@ -447,7 +272,41 @@
on:mouseover={() => (focusTrailer = autoplayTrailer)}
on:mouseleave={() => (focusTrailer = false)}
on:click={openTrailer}>Watch Trailer</Button
> -->
<!-- <div style={opacityStyle}>
<Button
disabled={streamButtonDisabled}
size="lg"
on:click={() => jellyfinId && playerState.streamJellyfinId(jellyfinId)}
>
<span>Stream</span><ChevronRight size={20} />
</Button>
</div> -->
<div style={opacityStyle} class:hidden={showDetails}>
<Button
size="lg"
type="secondary"
on:click={() => {
detailsVisible = true;
localDetails?.scrollIntoView({ behavior: 'smooth', block: 'center' });
}}
>
<span>Details</span>
<ChevronRight size={20} />
</Button>
</div>
<Button
size="lg"
type="secondary"
on:mouseover={() => (focusTrailer = autoplayTrailer)}
on:focus={() => (focusTrailer = autoplayTrailer)}
on:mouseleave={() => (focusTrailer = false)}
on:blur={() => (focusTrailer = false)}
on:click={openTrailer}
>
<span>Watch Trailer</span>
<ChevronRight size={20} />
</Button>
</div>
</div>
<div
@@ -483,17 +342,6 @@
>
<b>{tmdbRating.toFixed(1)}</b> TMDB
</a>
<div class="flex mt-4" in:fade={getFade()}>
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="text-white w-4"
><g
><path d="M0 0h24v24H0z" fill="none" /><path
d="M11.29 3.814l2.02 5.707.395 1.116.007-4.81.01-4.818h4.27L18 11.871c.003 5.98-.003 10.89-.015 10.9-.012.009-.209 0-.436-.027-.989-.118-2.29-.236-3.34-.282a14.57 14.57 0 0 1-.636-.038c-.003-.004-.273-.762-.776-2.184v-.004l-2.144-6.061-.34-.954-.008 4.586c-.006 4.365-.01 4.61-.057 4.61-.163 0-1.57.09-2.04.136-.308.027-.926.09-1.37.145-.446.051-.816.085-.823.078C6.006 22.77 6 17.867 6 11.883V1.002h.005V1h4.288l.028.08c.007.016.065.176.157.437l.641 1.778.173.496-.001.023z"
fill-rule="evenodd"
fill="currentColor"
/></g
></svg
>
</div>
</div>
{#if starring?.length > 0}
<h3 class="text-xs tracking-wide uppercase" in:fade={getFade()}>Starring</h3>

View File

@@ -57,7 +57,7 @@
{#await $library then libraryData}
{#if libraryData.itemsArray.filter((item) => item.continueWatching).length}
{@const continueWatching = libraryData.continueWatching}
<div class="p-8 flex flex-col gap-6 backdrop-blur-xl bg-stone-900">
<div class="p-8 flex flex-col gap-6 backdrop-blur-xl">
<h1 class="uppercase tracking-widest font-bold">Continue Watching</h1>
<div class="flex gap-4 overflow-x-scroll">
{#each continueWatching.slice(0, 5) as item (item.tmdbId)}

View File

@@ -5,6 +5,7 @@
import RadarrStats from '$lib/components/SourceStats/RadarrStats.svelte';
import SonarrStats from '$lib/components/SourceStats/SonarrStats.svelte';
import { library, type PlayableItem } from '$lib/stores/library.store';
import classNames from 'classnames';
import { ChevronDown, MagnifyingGlass, TextAlignBottom, Trash } from 'radix-icons-svelte';
import type { ComponentProps } from 'svelte';
@@ -90,7 +91,7 @@
props = {
size: 'dynamic',
type: 'series',
tmdbId: String(item.tmdbId),
tmdbId: item.tmdbId,
title: series.title || '',
genres: series.genres || [],
backdropUri: item.cardBackdropUrl,
@@ -101,7 +102,7 @@
props = {
size: 'dynamic',
type: 'movie',
tmdbId: String(item.tmdbId),
tmdbId: item.tmdbId,
title: movie.title || '',
genres: movie.genres || [],
backdropUri: item.cardBackdropUrl,
@@ -163,19 +164,27 @@
<div class="py-4 px-2 md:px-8">
<div class="max-w-screen-2xl m-auto backdrop-blur-2xl flex flex-col gap-4">
<div class="flex justify-between gap-2 sm:flex-row flex-col">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="flex gap-2 items-center bg-stone-950 rounded-2xl p-3 px-4 shadow-xl focus-within:outline outline-2 outline-stone-400"
class={classNames(
'flex gap-2 items-center p-3 px-4 shadow-xl selectable rounded-xl',
'text-zinc-200 bg-zinc-700 bg-opacity-40 cursor-text focus-within:bg-opacity-60'
)}
on:click={() => document.activeElement !== searchInput && searchInput?.focus()}
>
<MagnifyingGlass size={24} class="text-zinc-200" />
<MagnifyingGlass size={24} />
<input
type="text"
class="bg-transparent outline-none text-zinc-300"
class="bg-transparent outline-none placeholder:text-zinc-400 font-medium"
placeholder="Search from library"
bind:this={searchInput}
bind:value={searchInputValue}
/>
</div>
<div class="flex items-center gap-2 bg-stone-950 rounded-2xl p-3 px-5 shadow-lg">
<div
class="flex items-center gap-2 p-3 px-5 shadow-xl rounded-xl text-zinc-200 bg-zinc-700 bg-opacity-40"
>
<IconButton>
<TextAlignBottom size={20} />
</IconButton>

View File

@@ -4,8 +4,8 @@ export default {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'sans-serif'],
display: ['Inter', 'system', 'sans-serif']
sans: ['Montserrat', 'sans-serif'],
display: ['Montserrat', 'system', 'sans-serif']
},
colors: {
darken: '#07050199',