remind me to never try to handle a 53MB json file again

This commit is contained in:
not-nullptr 2024-03-16 19:00:09 +00:00
parent 99bfc69c64
commit 188e38c6ec
19 changed files with 185 additions and 109 deletions

9
package-lock.json generated
View file

@ -14,6 +14,7 @@
"better-sqlite3": "^9.4.3", "better-sqlite3": "^9.4.3",
"carbon-components-svelte": "^0.84.0", "carbon-components-svelte": "^0.84.0",
"cookie": "^0.6.0", "cookie": "^0.6.0",
"cookiejs": "^2.1.3",
"email-validator": "^2.0.4", "email-validator": "^2.0.4",
"hcaptcha": "^0.1.1", "hcaptcha": "^0.1.1",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
@ -3788,6 +3789,14 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true "dev": true
}, },
"node_modules/cookiejs": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/cookiejs/-/cookiejs-2.1.3.tgz",
"integrity": "sha512-pA/nRQVka2eTXm1/Dq8pNt1PN+e1PJNItah0vL15qwpet81/tUfrAp8e0iiVM8WEAzDcTGK5/1hDyR6BdBZMVg==",
"funding": {
"url": "https://jaywcjlove.github.io/#/sponsor"
}
},
"node_modules/copy-descriptor": { "node_modules/copy-descriptor": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",

View file

@ -54,6 +54,7 @@
"better-sqlite3": "^9.4.3", "better-sqlite3": "^9.4.3",
"carbon-components-svelte": "^0.84.0", "carbon-components-svelte": "^0.84.0",
"cookie": "^0.6.0", "cookie": "^0.6.0",
"cookiejs": "^2.1.3",
"email-validator": "^2.0.4", "email-validator": "^2.0.4",
"hcaptcha": "^0.1.1", "hcaptcha": "^0.1.1",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",

View file

@ -1,60 +1,36 @@
<script lang="ts"> <script lang="ts">
import type { IRoom } from "$types/rooms"; import type { IRoom } from "$types/rooms";
export let icon: string | undefined;
export let room: IRoom; export let room: IRoom;
</script> </script>
<div class="room"> <div class="relative flex h-fit items-center gap-6 rounded-[2.25rem] bg-[#110d10] p-6">
<h3>{room.name} <span class="game">({room.preferredGameName || "No preferred game"})</span></h3> {#if icon}
<p>{room.description}</p> <img src={icon} alt="Icon for '{room.preferredGameName}'" class="h-[100px] rounded-2xl" />
<div class="player-count"> {/if}
{room.players.length} / {room.maxPlayers} | {#if room.players.length > 4} <div>
{#each room.players.slice(0, 4) as player} <h2 class="mb-2 text-[20px] leading-[1.41] md:text-[28px] md:leading-[1.1]">
{player.nickname}{#if player !== room.players[3]},{" "} {room.name}
{/if} <span class="ml-1 text-base font-normal text-gray-500"
{/each} >({room.preferredGameName || "No preferred game"})</span
and {room.players.length - 4} >
{room.players.length - 4 === 1 ? "other" : "others"} </h2>
{:else} <p>{room.description}</p>
{#each room.players as player} <div class="mt-2 text-sm text-gray-600">
{player.nickname}{#if player !== room.players[room.players.length - 1]},{" "} {room.players.length} / {room.maxPlayers} | {#if room.players.length > 4}
{/if} {#each room.players.slice(0, 4) as player}
{/each} {player.nickname}{#if player !== room.players[3]},{" "}
{/if} | {room.hasPassword ? "Private" : "Public"} {/if}
</div> {/each}
<div class="top-right"> and {room.players.length - 4}
{room.address}:{room.port} {room.players.length - 4 === 1 ? "other" : "others"}
{:else}
{#each room.players as player}
{player.nickname}{#if player !== room.players[room.players.length - 1]},{" "}
{/if}
{/each}
{/if} | {room.hasPassword ? "Private" : "Public"} | {room.address}:{room.port}
</div>
</div> </div>
</div> </div>
<style>
.room {
border: solid thin #353e52;
padding: 8px 12px;
background-color: var(--color-primary);
border-radius: 16px;
box-shadow: 0 0 48px 0 rgba(39, 56, 75, 0.5);
position: relative;
}
.player-count {
margin-top: 4px;
}
.game {
margin-left: 4px;
}
.top-right {
position: absolute;
top: 8px;
right: 12px;
}
.top-right,
.player-count,
.game {
opacity: 0.5;
font-size: 16px;
}
</style>

View file

@ -1,5 +0,0 @@
{
"landingHeader": "suyu",
"landingOne": "Suyu is an open-source, Switch compatible emulator with almost full coverage of the game library.",
"landingCardHeader": "We care about preservation"
}

View file

@ -0,0 +1,28 @@
interface SwitchGame {
bannerUrl: string;
category: string[];
description: string;
developer: null;
frontBoxArt: null;
iconUrl: string;
id: string;
intro: null | string;
isDemo: boolean;
key: null;
languages: string[];
name: string;
nsuId: number;
numberOfPlayers: number;
publisher: string;
rating: number;
ratingContent: string[];
region: null;
releaseDate: number;
rightsId: string;
screenshots: string[];
size: number;
version: null;
}
export const globalData: {
games: SwitchGame[];
} = { games: [] };

View file

@ -0,0 +1,7 @@
export function load({ cookies, url }) {
const token = cookies.get("token");
return {
tokenCookie: token,
url: url.pathname,
};
}

View file

@ -21,7 +21,7 @@
href: string; href: string;
} }
const token = writable(""); const token = writable(data.tokenCookie || "");
function transitionIn(node: HTMLElement, { duration = 360 }: TransitionConfig) { function transitionIn(node: HTMLElement, { duration = 360 }: TransitionConfig) {
if ($reducedMotion) if ($reducedMotion)
@ -29,7 +29,7 @@
duration: 0, duration: 0,
}; };
node = node.querySelector(".content") || node; node = node.querySelector(".content") || node;
const intensity = node.dataset.intensity || "160"; const intensity = node.dataset.intensityIn || "160";
const UA = navigator.userAgent; const UA = navigator.userAgent;
const ff = UA.indexOf("Firefox") > -1; const ff = UA.indexOf("Firefox") > -1;
if (!dropdownCloseFinished) { if (!dropdownCloseFinished) {
@ -86,7 +86,7 @@
duration: 0, duration: 0,
}; };
node = node.querySelector(".content") || node; node = node.querySelector(".content") || node;
const intensity = node.dataset.intensity || "160"; const intensity = node.dataset.intensityOut || "240";
if (!dropdownCloseFinished) if (!dropdownCloseFinished)
return { return {
duration: 0, duration: 0,
@ -149,8 +149,8 @@
href: "https://gitlab.com/suyu-emu/", href: "https://gitlab.com/suyu-emu/",
}, },
{ {
name: $token ? "Account" : "Sign up", name: $token || data.tokenCookie ? "Account" : "Sign up",
href: $token ? "/account" : "/signup", href: $token || data.tokenCookie ? "/account" : "/signup",
}, },
] as NavItem[]; ] as NavItem[];
@ -216,10 +216,11 @@
}); });
</script> </script>
<!-- unfortunately, firefox is horrendous at rendering transforms so we can't enable it there -->
{#if navigator.userAgent.indexOf("Firefox") === -1} {#if navigator.userAgent.indexOf("Firefox") === -1}
<div <div
class="opacity-10" class="opacity-5"
style="position: fixed; width: 100vw; height: 100vh; --mask-image: linear-gradient(to bottom, transparent 50px, black 150px); mask-image: var(--mask-image); -webkit-mask-image: var(--mask-image);" style="position: fixed; width: 100vw; height: 100vh; --mask-image: linear-gradient(to bottom, transparent 50px, black 150px, transparent); mask-image: var(--mask-image); -webkit-mask-image: var(--mask-image);"
> >
<BackgroundProvider size={90} gap={16} speed={0.25} /> <BackgroundProvider size={90} gap={16} speed={0.25} />
</div> </div>
@ -318,7 +319,7 @@
<div <div
style="transition: 180ms ease;" style="transition: 180ms ease;"
aria-hidden={!dropdownOpenFinished && !dropdownOpen} aria-hidden={!dropdownOpenFinished && !dropdownOpen}
class={`${navigator.userAgent.indexOf("Firefox") > -1 ? "bg-[#0e0d10]" : "bg-[rgba(0,0,0,0.25)] backdrop-blur-xl"} fixed left-0 z-[99999] h-screen w-full p-9 pt-[120px] ${dropdownOpen ? "pointer-events-auto visible opacity-100" : "pointer-events-none opacity-0"} ${!dropdownOpen && dropdownCloseFinished ? "invisible" : ""}`} class={`fixed left-0 z-[99999] h-screen w-full bg-[#0e0d10] p-9 pt-[120px] ${dropdownOpen ? "pointer-events-auto visible opacity-100" : "pointer-events-none opacity-0"} ${!dropdownOpen && dropdownCloseFinished ? "invisible" : ""}`}
> >
<div class={`flex flex-col gap-8`}> <div class={`flex flex-col gap-8`}>
<!-- <a href="##"><h1 class="w-full text-5xl">Blog</h1></a> <!-- <a href="##"><h1 class="w-full text-5xl">Blog</h1></a>

View file

@ -1,5 +0,0 @@
export function load({ url }) {
return {
url: url.pathname,
};
}

View file

@ -1,5 +1,6 @@
import { building } from "$app/environment"; import { building } from "$app/environment";
import { DISCORD_USER_TOKEN, GITLAB_API_TOKEN } from "$env/static/private"; import { DISCORD_USER_TOKEN, GITLAB_API_TOKEN } from "$env/static/private";
import { globalData } from "$lib/server/other";
let memberCount = 0; let memberCount = 0;
let starCount = 0; let starCount = 0;
@ -40,13 +41,25 @@ async function fetchServerSideData() {
console.log("Stars count:", starCount); console.log("Stars count:", starCount);
} }
if (!building) { async function fetchSlowServerSideData() {
await fetchServerSideData(); console.log("Fetching game data");
setInterval(fetchServerSideData, 1000 * 60 * 10); const res = await fetch("https://raw.githubusercontent.com/blawar/titledb/master/US.en.json");
let gamesText = await res.text();
gamesText = gamesText.replaceAll(/\\u[0-9a-fA-F]{4}/gm, "");
globalData.games = Object.values(JSON.parse(gamesText));
console.log("Fetched game data");
} }
export async function load(opts) { if (!building) {
await Promise.all([await fetchServerSideData(), await fetchSlowServerSideData()]);
setInterval(fetchServerSideData, 1000 * 60 * 10);
setInterval(fetchSlowServerSideData, 1000 * 60 * 60 * 12);
}
export async function load({ cookies }) {
const token = cookies.get("token");
return { return {
tokenCookie: token,
memberCount, memberCount,
starCount, starCount,
roleMembers, roleMembers,

View file

@ -6,9 +6,9 @@
import { Dialog } from "radix-svelte"; import { Dialog } from "radix-svelte";
export let data: PageData; export let data: PageData;
$: memberCount = parseFloat(data.memberCount.toPrecision(2)); $: memberCount = parseFloat(data.memberCount?.toPrecision(2));
$: contributors = parseFloat(data.roleMembers["1214817156420862012"].toPrecision(2)); $: contributors = parseFloat(data.roleMembers["1214817156420862012"]?.toPrecision(2));
$: starCount = parseFloat(data.starCount.toPrecision(2)); $: starCount = parseFloat(data.starCount?.toPrecision(2));
let metadata = { let metadata = {
url: "https://suyu.dev", url: "https://suyu.dev",
title: "suyu - Open-source, non-profit Switch emulator", title: "suyu - Open-source, non-profit Switch emulator",
@ -40,7 +40,7 @@
</svelte:head> </svelte:head>
<div <div
class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] rounded-bl-none rounded-br-none bg-[rgba(0,0,0,0.25)] p-8 backdrop-blur-xl md:p-12 lg:rounded-bl-none lg:rounded-br-[2.25rem]" class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] rounded-bl-none rounded-br-none bg-[#110d10] p-8 md:p-12 lg:rounded-bl-none lg:rounded-br-[2.25rem]"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -88,7 +88,7 @@
</Dialog.Trigger> </Dialog.Trigger>
<Dialog.Portal> <Dialog.Portal>
<Dialog.Overlay <Dialog.Overlay
class="fixed inset-0 z-[9999] bg-black/80 data-[state=open]:animate-[overlayShow_555ms_cubic-bezier(.16,1,.3,1)]" class="fixed inset-0 z-[9999] bg-[#110d10]/80 data-[state=open]:animate-[overlayShow_555ms_cubic-bezier(.16,1,.3,1)]"
/> />
<Dialog.Content <Dialog.Content
class="fixed left-[50%] top-[50%] z-[9999] max-h-[85vh] w-[90vw] max-w-[450px] translate-x-[-50%] class="fixed left-[50%] top-[50%] z-[9999] max-h-[85vh] w-[90vw] max-w-[450px] translate-x-[-50%]
@ -142,7 +142,7 @@
<div class="flex w-full flex-col lg:flex-row"> <div class="flex w-full flex-col lg:flex-row">
<div <div
class="flex w-full flex-shrink-0 flex-col gap-8 rounded-b-[2.25rem] bg-black p-12 lg:w-[35%]" class="flex w-full flex-shrink-0 flex-col gap-8 rounded-b-[2.25rem] bg-[#110d10] p-12 lg:w-[35%]"
> >
<h1 class="text-[48px] leading-[0.9]">By the numbers</h1> <h1 class="text-[48px] leading-[0.9]">By the numbers</h1>
<div class="flex flex-col gap-0"> <div class="flex flex-col gap-0">
@ -200,12 +200,12 @@
<div class="text-[#A6A5A7]">members on Discord</div> <div class="text-[#A6A5A7]">members on Discord</div>
</div> </div>
</div> </div>
<div class="flex w-full flex-1 rounded-[2.25rem] bg-black lg:rounded-tl-none"> <div class="flex w-full flex-1 rounded-[2.25rem] bg-[#110d10] lg:rounded-tl-none">
<div <div
class="flex w-full flex-1 rounded-[2.25rem] rounded-bl-none rounded-tr-none bg-[#131215] pt-8 lg:pl-8" class="flex w-full flex-1 rounded-[2.25rem] rounded-bl-none rounded-tr-none bg-[#131215] pt-8 lg:pl-8"
> >
<div <div
class="h-full w-full overflow-hidden rounded-[2.25rem] bg-black shadow-lg ring ring-[#ffffff11]" class="h-full w-full overflow-hidden rounded-[2.25rem] bg-[#110d10] shadow-lg ring ring-[#ffffff11]"
> >
<img <img
class="h-full max-h-[496px] w-full object-cover" class="h-full max-h-[496px] w-full object-cover"
@ -287,7 +287,7 @@
</div> </div>
<div <div
class="relative mt-48 flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-black p-8 md:p-12" class="relative mt-48 flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-[#110d10] p-8 md:p-12"
> >
<h1 class="text-[24px] leading-[1.41] md:text-[60px] md:leading-[1.1]"> <h1 class="text-[24px] leading-[1.41] md:text-[60px] md:leading-[1.1]">
were passionate about preserving games. were passionate about preserving games.

View file

@ -29,10 +29,10 @@
name: "Lobbies", name: "Lobbies",
href: "/account/lobbies", href: "/account/lobbies",
}, },
{ // {
name: "Friends", // name: "Friends",
href: "/account/friends", // href: "/account/friends",
}, // },
]; ];
function navClick(e: MouseEvent | HTMLAnchorElement) { function navClick(e: MouseEvent | HTMLAnchorElement) {
@ -144,13 +144,11 @@
[ [
{ {
opacity: "1", opacity: "1",
filter: "blur(0px)", marginTop: "0px",
transform: "translateY(0px)",
}, },
{ {
opacity: "0", opacity: "0",
filter: "blur(20px)", marginTop: "40px",
transform: "translateY(-50px)",
}, },
], ],
$reducedMotion $reducedMotion
@ -170,7 +168,7 @@
{#key data.url} {#key data.url}
<div <div
class={`navbar ${data.url} relative z-50 mb-4 flex w-max gap-1 overflow-hidden rounded-full bg-black p-1`} class={`navbar ${data.url} relative z-50 mb-4 flex w-max gap-1 overflow-hidden rounded-full bg-[#110d10] p-1`}
bind:this={navBar} bind:this={navBar}
> >
<div <div
@ -194,7 +192,7 @@
{/key} {/key}
<div class="relative"> <div class="relative">
<div class="content absolute w-full"> <div data-intensity-in={80} data-intensity-out={140} class="content absolute w-full">
<slot /> <slot />
</div> </div>
</div> </div>

View file

@ -32,7 +32,7 @@
<div class="relative h-[calc(100vh-200px)] flex-col gap-6 overflow-hidden"> <div class="relative h-[calc(100vh-200px)] flex-col gap-6 overflow-hidden">
<div <div
class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-black p-8 md:p-12" class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-[#110d10] p-8 md:p-12"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -55,9 +55,9 @@
<h2 class="text-[36px] leading-[1.41] md:text-[48px] md:leading-[1.1]">Multiplayer</h2> <h2 class="text-[36px] leading-[1.41] md:text-[48px] md:leading-[1.1]">Multiplayer</h2>
<p class="text-wrap text-lg leading-relaxed text-[#A6A5A7]"> <p class="text-wrap text-lg leading-relaxed text-[#A6A5A7]">
Hey, <span Hey, <span
class="bg-gradient-to-r from-[#60c7e9] via-[#e06bb3] to-[#f94d4d] bg-clip-text font-bold text-transparent" class="bg-gradient-to-r from-[#60c7e9] via-[#e06bb3] to-[#f94d4d] bg-clip-text font-black tracking-tighter text-transparent"
>{data.user.username}</span >{data.user.username}</span
>! This is your <i>token</i>, used to authenticate your identity within suyu. Your token >! This is your <b>token</b>, used to authenticate your identity within suyu. Your token
should be kept private. If you believe it has been compromised, please contact us should be kept private. If you believe it has been compromised, please contact us
immediately. immediately.
</p> </p>

View file

@ -1,6 +1,6 @@
<div class="relative h-[calc(100vh-200px)] flex-col gap-6 overflow-hidden"> <div class="relative h-[calc(100vh-200px)] flex-col gap-6 overflow-hidden">
<div <div
class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-black p-8 md:p-12" class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-[#110d10] p-8 md:p-12"
> >
<h2 class=" text-[36px] leading-[1.41] md:text-[48px] md:leading-[1.1]">Friends</h2> <h2 class=" text-[36px] leading-[1.41] md:text-[48px] md:leading-[1.1]">Friends</h2>
<p class="text-md text-wrap leading-relaxed text-[#4e4e4e]"> <p class="text-md text-wrap leading-relaxed text-[#4e4e4e]">

View file

@ -1,7 +1,14 @@
import { building } from "$app/environment";
import { RoomManager } from "$lib/server/class/Room.js"; import { RoomManager } from "$lib/server/class/Room.js";
import { globalData } from "$lib/server/other/index.js";
export function load({ request }) { export function load({ request }) {
const rooms = RoomManager.getRooms().map((r) => r.toJSON()) || [];
const requiredGames = rooms
.map((r) => r.preferredGameName.toUpperCase().trim())
.map((r) => globalData.games.find((g) => g.name.toUpperCase().trim() === r));
return { return {
rooms: RoomManager.getRooms().map((r) => r.toJSON()) || [], rooms: rooms,
games: requiredGames,
}; };
} }

View file

@ -1,15 +1,61 @@
<script lang="ts"> <script lang="ts">
import Room from "$components/Room.svelte";
import { reducedMotion } from "$lib/accessibility";
import { transition } from "$lib/util/animation";
import { onMount } from "svelte";
import type { PageData } from "./$types"; import type { PageData } from "./$types";
export let data: PageData; export let data: PageData;
$: console.log(data);
function transitionIn() {
const rooms = document.querySelectorAll<HTMLDivElement>(".room");
rooms.forEach((room, i) => {
const x = parseInt(room.dataset.index!);
room.getAnimations().forEach((animation) => animation.cancel());
room.style.zIndex = ((i + 1) * 5).toString();
room.animate(
[
{
transform: "translateY(-200px)",
opacity: "0",
filter: "blur(20px)",
},
{
transform: "translateY(0px)",
opacity: "1",
filter: "blur(0px)",
},
],
$reducedMotion
? {
duration: 0,
fill: "forwards",
}
: {
duration: 700,
easing: transition,
delay: x * 80,
fill: "forwards",
},
).onfinish = () => {
room.style.opacity = "1";
};
});
}
onMount(() => {
transitionIn();
});
</script> </script>
<div class="relative h-[calc(100vh-200px)] flex-col gap-6 overflow-hidden"> <div class="relative h-[calc(100vh-200px)]">
<div <div class="relative flex w-full flex-col gap-4 pb-6">
class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-black p-8 md:p-12" {#each data.rooms as room, i}
> <div class="room opacity-0" data-index={i}>
{#each data.rooms as room} <Room icon={data.games[i]?.iconUrl} {room} />
<p>{room.name}</p> </div>
{/each} {/each}
</div> </div>
</div> </div>

View file

@ -33,7 +33,7 @@
filter: "blur(0px)", filter: "blur(0px)",
}, },
], ],
reducedMotion $reducedMotion
? { ? {
duration: 0, duration: 0,
fill: "forwards", fill: "forwards",
@ -71,7 +71,7 @@
{#each data.posts as post} {#each data.posts as post}
<a href={`/blog/${post.slug}`}> <a href={`/blog/${post.slug}`}>
<div <div
class="card relative h-[250px] w-full translate-y-[-200px] overflow-hidden rounded-[2.25rem] border-2 border-solid border-zinc-700 bg-black p-8 opacity-0 blur-[20px] lg:h-[400px]" class="card relative h-[250px] w-full translate-y-[-200px] overflow-hidden rounded-[2.25rem] border-2 border-solid border-zinc-700 bg-[#110d10] p-8 opacity-0 blur-[20px] lg:h-[400px]"
> >
<div <div
style="--mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, rgba(0,0,0,0) 100%); mask-image: var(--mask-image); -webkit-mask-image: var(--mask-image);" style="--mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, rgba(0,0,0,0) 100%); mask-image: var(--mask-image); -webkit-mask-image: var(--mask-image);"

View file

@ -29,7 +29,7 @@
<textarea <textarea
id="write" id="write"
bind:value={content} bind:value={content}
class="h-full w-full resize-none rounded-2xl !border-none bg-black p-4 font-[Consolas] !outline-none ring ring-[#ffffff11] focus:ring-[#ffffff44]" class="h-full w-full resize-none rounded-2xl !border-none bg-[#110d10] p-4 font-[Consolas] !outline-none ring ring-[#ffffff11] focus:ring-[#ffffff44]"
></textarea> ></textarea>
</form> </form>
</div> </div>

View file

@ -3,7 +3,7 @@
</svelte:head> </svelte:head>
<div <div
class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-black p-8 md:p-12" class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] bg-[#110d10] md:p-12"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

View file

@ -45,7 +45,7 @@
<div <div
class="align-center relative flex h-[calc(100vh-200px)] flex-col items-center justify-center gap-6 overflow-hidden" class="align-center relative flex h-[calc(100vh-200px)] flex-col items-center justify-center gap-6 overflow-hidden"
> >
<div class="flex h-fit w-full max-w-[500px] flex-col rounded-[2.25rem] bg-black p-10"> <div class="flex h-fit w-full max-w-[500px] flex-col rounded-[2.25rem] bg-[#110d10] p-10">
<h1 class="text-[60px] md:leading-[1.1]">Sign up</h1> <h1 class="text-[60px] md:leading-[1.1]">Sign up</h1>
<div class="mt-4 flex flex-col gap-4"> <div class="mt-4 flex flex-col gap-4">
<p> <p>