feat: visual overhaul
This commit is contained in:
parent
2442d891b8
commit
b7565ca255
10 changed files with 1828 additions and 484 deletions
1663
pnpm-lock.yaml
1663
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
19
src/app.html
19
src/app.html
|
@ -10,16 +10,19 @@
|
||||||
href="https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,100..900;1,100..900&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,100..900;1,100..900&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
<meta property="og:type" content="summary">
|
<meta property="og:type" content="summary" />
|
||||||
<meta property="og:site_name" content="suyu">
|
<meta property="og:site_name" content="suyu" />
|
||||||
<meta property="og:title" content="suyu">
|
<meta property="og:title" content="suyu" />
|
||||||
<meta property="og:description" content="suyu, pronounced sue-you (wink wink) is the continuation of the world's most popular, open-source, Nintendo Switch emulator, yuzu. It is written in C++ with portability in mind, and we actively maintain builds for Windows, Linux and Android.">
|
<meta
|
||||||
<meta property="og:image" content="https://suyu.dev/img/suyu.png">
|
property="og:description"
|
||||||
<meta property="og:image:alt" content="suyu">
|
content="suyu, pronounced sue-you (wink wink) is the continuation of the world's most popular, open-source, Nintendo Switch emulator, yuzu. It is written in C++ with portability in mind, and we actively maintain builds for Windows, Linux and Android."
|
||||||
<meta property="og:url" content="https://suyu.dev">
|
/>
|
||||||
|
<meta property="og:image" content="https://suyu.dev/img/suyu.png" />
|
||||||
|
<meta property="og:image:alt" content="suyu" />
|
||||||
|
<meta property="og:url" content="https://suyu.dev" />
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover">
|
<body data-sveltekit-preload-data="hover">
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
%sveltekit.body%
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
45
src/app.pcss
45
src/app.pcss
|
@ -1,4 +1,47 @@
|
||||||
/* Write your global styles here, in PostCSS syntax */
|
@import url("https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap");
|
||||||
|
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Roc Grotesk";
|
||||||
|
src: url("RocGroteskWideMedium.ttf") format("truetype");
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
min-height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
background: #131215;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: "DM Sans", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
|
font-family: "Roc Grotesk", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
background: linear-gradient(0deg, rgba(0, 0, 0, 0.06), rgba(0, 0, 0, 0.06)),
|
||||||
|
radial-gradient(109.26% 109.26% at 49.83% 13.37%, #ffffff 0%, #babaca 100%);
|
||||||
|
color: black;
|
||||||
|
@apply flex w-fit shrink-0 select-none flex-row items-center justify-center gap-4 rounded-xl py-3 pl-7 pr-5 font-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
border: 2px solid #46424d;
|
||||||
|
@apply flex w-fit shrink-0 select-none flex-row items-center justify-center gap-4 rounded-xl py-3 pl-7 pr-5 font-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-sm {
|
||||||
|
border: 2px solid #46424d;
|
||||||
|
@apply flex w-fit shrink-0 select-none flex-row items-center justify-center gap-4 rounded-xl px-4 py-2 text-sm font-bold;
|
||||||
|
}
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { onMount } from "svelte";
|
|
||||||
import OutlinedLogo from "./OutlinedLogo.svelte";
|
|
||||||
|
|
||||||
export let size = 80;
|
|
||||||
export let gap = 12;
|
|
||||||
export let speed = 4;
|
|
||||||
const offsetCount = 2;
|
|
||||||
$: offsetX = (size + gap) * offsetCount;
|
|
||||||
$: speedSecs = (1 / speed) * 4;
|
|
||||||
|
|
||||||
let countX = 0;
|
|
||||||
let countY = 0;
|
|
||||||
|
|
||||||
function onResize() {
|
|
||||||
countX = Math.ceil(window.innerWidth / (gap + size));
|
|
||||||
countY = Math.ceil(window.innerHeight / (gap + size));
|
|
||||||
console.log(countX, countY);
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
onResize();
|
|
||||||
window.addEventListener("resize", onResize);
|
|
||||||
return () => window.removeEventListener("resize", onResize);
|
|
||||||
});
|
|
||||||
|
|
||||||
function getColor(x: number, y: number) {
|
|
||||||
const red = "#FF3A3A";
|
|
||||||
const blue = "#3A99FF";
|
|
||||||
const evenX = x % 2 === 0;
|
|
||||||
const evenY = y % 2 === 0;
|
|
||||||
return evenX === evenY ? red : blue;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="gradient" />
|
|
||||||
|
|
||||||
<div class="background-container">
|
|
||||||
<div
|
|
||||||
class="background"
|
|
||||||
style="--size: {size}px; --gap: {gap}px; --offsetX: {offsetX}px; --speed: {speedSecs || 0}s"
|
|
||||||
>
|
|
||||||
<div class="scroll" style="--gap: {gap}px">
|
|
||||||
{#each Array(countX + offsetCount) as _, x}
|
|
||||||
<div class="group">
|
|
||||||
{#each Array(countY + offsetCount) as _, y}
|
|
||||||
<OutlinedLogo {size} color={getColor(x, y)} />
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
@keyframes scroll {
|
|
||||||
from {
|
|
||||||
transform: rotateZ(-4deg)
|
|
||||||
translate3d(calc(0px - var(--offsetX)), calc(0px - var(--offsetX)), 0);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotateZ(-4deg)
|
|
||||||
translate3d(
|
|
||||||
calc(((var(--size) + var(--gap)) * 2) - var(--offsetX)),
|
|
||||||
calc(0px - var(--offsetX)),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-container {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background {
|
|
||||||
width: calc(100% + var(--offsetX));
|
|
||||||
height: 100%;
|
|
||||||
opacity: 0.5;
|
|
||||||
animation: scroll infinite linear;
|
|
||||||
animation-duration: var(--speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
.gradient {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-image: linear-gradient(
|
|
||||||
180deg,
|
|
||||||
transparent,
|
|
||||||
color-mix(in srgb, var(--page-bg), transparent 20%) 25%,
|
|
||||||
var(--page-bg)
|
|
||||||
);
|
|
||||||
background-size: 100% 100%;
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll {
|
|
||||||
display: flex;
|
|
||||||
gap: var(--gap);
|
|
||||||
}
|
|
||||||
|
|
||||||
.group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: var(--gap);
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,19 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from "svelte";
|
|
||||||
|
|
||||||
export let size = 512;
|
export let size = 512;
|
||||||
|
|
||||||
const dispatcher = createEventDispatcher<{
|
|
||||||
click: void;
|
|
||||||
}>();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
||||||
<svg
|
<svg
|
||||||
class="pointer"
|
|
||||||
on:click={() => dispatcher("click")}
|
|
||||||
width={size * 3.771484375}
|
width={size * 3.771484375}
|
||||||
height={size}
|
height={size}
|
||||||
viewBox="0 0 1931 512"
|
viewBox="0 0 1931 512"
|
||||||
|
@ -45,9 +34,3 @@
|
||||||
fill="#3A99FF"
|
fill="#3A99FF"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<style>
|
|
||||||
.pointer {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,117 +1,55 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import "../app.pcss";
|
import "../app.pcss";
|
||||||
import { goto } from "$app/navigation";
|
import { onMount, onDestroy } from "svelte";
|
||||||
import BackgroundProvider from "$components/BackgroundProvider.svelte";
|
import Logo from "../components/LogoWithTextHorizontal.svelte";
|
||||||
import LogoWithTextHorizontal from "$components/LogoWithTextHorizontal.svelte";
|
import { CodeBranchOutline, DiscordSolid, DownloadOutline } from "flowbite-svelte-icons";
|
||||||
import { page } from "$app/stores";
|
|
||||||
import "$lib/css/index.css";
|
|
||||||
import { Button } from "flowbite-svelte";
|
|
||||||
import { CodeBranchOutline, DiscordSolid, UserCircleSolid } from "flowbite-svelte-icons";
|
|
||||||
|
|
||||||
const excludedRoutesNav = ["/mockup/boot", "/mockup/w11"];
|
let scrolled = false;
|
||||||
const excludedRoutesBg = ["/mockup", "/mockup/w11"];
|
|
||||||
$: isNavExcluded = excludedRoutesNav.some((route) => $page.url?.pathname.startsWith(route));
|
onMount(() => {
|
||||||
$: isBgExcluded = excludedRoutesBg.some((route) => $page.url?.pathname === route);
|
const handleScroll = () => {
|
||||||
|
scrolled = window.scrollY > 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("scroll", handleScroll);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("scroll", handleScroll);
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !isNavExcluded}
|
<main class="min-h-full w-full">
|
||||||
<div class="header panel-blur">
|
<header
|
||||||
<div class="left">
|
style="transition: 180ms ease;"
|
||||||
<LogoWithTextHorizontal on:click={() => goto("/")} size={50} />
|
class={scrolled
|
||||||
</div>
|
? "fixed top-0 z-[9999] w-full border-b-2 border-b-[#ffffff11] bg-[#131215d0]"
|
||||||
<div class="right">
|
: "fixed top-0 z-[9999] w-full border-b-0 border-b-[transparent]"}
|
||||||
<a href="https://git.suyu.dev/explore/organizations" target="_blank">
|
>
|
||||||
<Button class="!p-2" pill={true}>
|
<nav
|
||||||
<CodeBranchOutline />
|
style="transition: 180ms ease;"
|
||||||
</Button>
|
class={scrolled
|
||||||
</a>
|
? "mx-auto flex h-[72px] w-full max-w-[1300px] flex-row items-center justify-between px-8 backdrop-blur-xl"
|
||||||
<a href="https://discord.gg/suyu" target="_blank">
|
: "mx-auto flex h-[120px] w-full max-w-[1300px] flex-row items-center justify-between px-8"}
|
||||||
<Button class="!p-2" pill={true}>
|
>
|
||||||
<DiscordSolid />
|
<div class="flex w-full flex-row items-center justify-start gap-8">
|
||||||
</Button>
|
<Logo size={28} />
|
||||||
</a>
|
</div>
|
||||||
<a href="/account">
|
<div
|
||||||
<Button class="!p-2" pill={true}>
|
class="flex w-full flex-row items-center justify-center gap-2 text-sm font-medium text-[#A6A5A7]"
|
||||||
<UserCircleSolid />
|
>
|
||||||
</Button>
|
<a href="/" class="px-5 py-3 transition hover:text-white">Blog</a>
|
||||||
</a>
|
<a href="/" class="px-5 py-3 transition hover:text-white">Docs</a>
|
||||||
</div>
|
<a href="/" class="px-5 py-3 transition hover:text-white">FAQ</a>
|
||||||
|
</div>
|
||||||
|
<div class="flex w-full flex-row items-center justify-end gap-8 text-[#A6A5A7]">
|
||||||
|
<CodeBranchOutline />
|
||||||
|
<DiscordSolid />
|
||||||
|
<a class="button-sm">Sign in</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<div class="mx-auto flex w-full max-w-[1300px] flex-col px-8 pb-12 pt-[120px]">
|
||||||
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
</main>
|
||||||
|
|
||||||
{#if !isBgExcluded}
|
|
||||||
<BackgroundProvider size={80} gap={12} speed={1}></BackgroundProvider>
|
|
||||||
<div class="below">
|
|
||||||
<div class="page-contents">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
<div class="bullshit-flex-container">
|
|
||||||
<div class="bullshit-flex-placeholder"></div>
|
|
||||||
<div class="bg-below-gradient"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<slot />
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.below {
|
|
||||||
z-index: 5;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
position: sticky;
|
|
||||||
/* on overscroll, stick to the top */
|
|
||||||
overscroll-behavior: contain;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 80px;
|
|
||||||
background-color: color-mix(in srgb, var(--color-primary), transparent 50%);
|
|
||||||
border: none;
|
|
||||||
border-radius: 0;
|
|
||||||
border-bottom: var(--border-primary);
|
|
||||||
z-index: 1000;
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
padding: 0 32px 0 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bullshit-flex-container {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bullshit-flex-placeholder {
|
|
||||||
/* 100vh height */
|
|
||||||
height: calc(100vh - 162px);
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-below-gradient {
|
|
||||||
width: 100%;
|
|
||||||
flex-grow: 1;
|
|
||||||
flex-shrink: 0;
|
|
||||||
background-color: var(--page-bg);
|
|
||||||
background-size: 100% 100%;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 1rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,204 +1,105 @@
|
||||||
<script lang="ts">
|
<svelte:head>
|
||||||
import Logo from "$components/Logo.svelte";
|
<title>suyu - Open-source, non-profit Switch emulator</title>
|
||||||
import { onMount } from "svelte";
|
</svelte:head>
|
||||||
import strings from "$lib/data/strings.json";
|
|
||||||
import odyssey from "$assets/cards/Super-Mario-Odyssey.jpg";
|
|
||||||
import ScrollIcon from "$components/ScrollIcon.svelte";
|
|
||||||
import totk from "$assets/cards/totk.webp";
|
|
||||||
import scarletviolet from "$assets/cards/scarlet-violet.webp";
|
|
||||||
import CardCarousel from "$components/CardCarousel.svelte";
|
|
||||||
import Wordmark from "$components/Wordmark.svelte";
|
|
||||||
|
|
||||||
let logoSizes = {
|
<div
|
||||||
small: 256,
|
class="relative flex w-full flex-col gap-6 overflow-hidden rounded-[2.25rem] rounded-bl-none rounded-br-none bg-black p-8 md:p-12 lg:rounded-bl-none lg:rounded-br-[2.25rem]"
|
||||||
large: 378,
|
>
|
||||||
};
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
let logoSize = logoSizes.large;
|
width="512"
|
||||||
|
height="525"
|
||||||
onMount(() => {
|
viewBox="0 0 512 525"
|
||||||
function onResize() {
|
fill="none"
|
||||||
if (window.innerWidth < 625) {
|
style="animation-duration: 300s; transform-origin: 50% 50%; animation-iteration-count: infinite; animation-timing-function: linear; animation-name: spin; animation-delay: 0s; animation-direction: normal; animation-fill-mode: none; animation-play-state: running;"
|
||||||
logoSize = logoSizes.small;
|
class="absolute -bottom-[18rem] right-0 z-0 animate-spin opacity-20"
|
||||||
} else {
|
>
|
||||||
logoSize = logoSizes.large;
|
<path
|
||||||
}
|
d="M511.5 262.12C511.5 353.613 465.547 434.182 396.019 480.947C408.179 457.937 415.083 431.597 415.083 403.617C415.083 313.723 343.816 240.744 255.992 240.744C191.257 240.744 138.692 186.941 138.692 120.622C138.692 54.3027 191.257 0.5 255.992 0.5C397.026 0.5 511.5 117.695 511.5 262.12ZM255.992 53.5225C243.745 53.5225 233.816 63.7047 233.816 76.2224C233.816 88.7388 243.745 98.9223 255.992 98.9223C268.257 98.9223 278.173 88.7387 278.173 76.2224C278.173 63.7048 268.257 53.5225 255.992 53.5225ZM299.355 97.9223C287.104 97.9223 277.173 108.104 277.173 120.622C277.173 133.139 287.104 143.322 299.355 143.322C311.62 143.322 321.536 133.139 321.536 120.622C321.536 108.104 311.62 97.9223 299.355 97.9223ZM212.635 97.9223C200.382 97.9223 190.455 108.104 190.455 120.622C190.455 133.139 200.382 143.322 212.635 143.322C224.889 143.322 234.816 133.139 234.816 120.622C234.816 108.104 224.888 97.9223 212.635 97.9223ZM255.992 142.322C243.745 142.322 233.816 152.505 233.816 165.021C233.816 177.539 243.745 187.721 255.992 187.721C268.257 187.721 278.173 177.538 278.173 165.021C278.173 152.505 268.257 142.322 255.992 142.322Z"
|
||||||
}
|
stroke="white"
|
||||||
|
/>
|
||||||
onResize();
|
<path
|
||||||
window.addEventListener("resize", onResize);
|
d="M0.5 262.119C0.5 170.626 46.444 90.0553 115.976 43.2909C103.82 66.3019 96.9172 92.6424 96.9172 120.622C96.9172 210.516 168.174 283.495 255.992 283.495C320.735 283.495 373.305 337.298 373.305 403.617C373.305 469.934 320.735 523.739 255.992 523.739C114.974 523.739 0.5 406.544 0.5 262.119ZM255.992 336.517C243.744 336.517 233.816 346.7 233.816 359.217C233.816 371.735 243.745 381.917 255.992 381.917C268.256 381.917 278.173 371.735 278.173 359.217C278.173 346.701 268.256 336.517 255.992 336.517ZM299.355 380.917C287.104 380.917 277.173 391.099 277.173 403.617C277.173 416.135 287.104 426.317 299.355 426.317C311.619 426.317 321.536 416.135 321.536 403.617C321.536 391.099 311.619 380.917 299.355 380.917ZM255.992 425.317C243.745 425.317 233.816 435.499 233.816 448.016C233.816 460.533 243.744 470.717 255.992 470.717C268.256 470.717 278.173 460.533 278.173 448.016C278.173 435.499 268.256 425.317 255.992 425.317ZM212.634 380.917C200.382 380.917 190.454 391.099 190.454 403.617C190.454 416.135 200.382 426.317 212.634 426.317C224.888 426.317 234.816 416.135 234.816 403.617C234.816 391.099 224.888 380.917 212.634 380.917Z"
|
||||||
|
stroke="white"
|
||||||
return () => {
|
/>
|
||||||
window.removeEventListener("resize", onResize);
|
</svg>
|
||||||
};
|
<h1 class="text-[24px] leading-[1.41] md:text-[60px] md:leading-[1.1]">
|
||||||
});
|
suyu is the open-source, non-profit Switch emulator
|
||||||
</script>
|
</h1>
|
||||||
|
<p class="max-w-[36rem] text-lg leading-relaxed text-[#A6A5A7]">
|
||||||
<div class="page">
|
suyu is a C++ based Switch emulator with a focus on compatibility. Completely free and
|
||||||
<div class="contents-container">
|
open-source, forever.
|
||||||
<Logo size={logoSize} />
|
</p>
|
||||||
<div class="hero-text">
|
<div class="flex flex-row gap-4">
|
||||||
<h1 class="hero-header">
|
<div class="cta-button">
|
||||||
<Wordmark size={80} />
|
Download <svg
|
||||||
</h1>
|
class=""
|
||||||
<p>
|
style="--icon-color:#000"
|
||||||
{strings.landingOne}
|
width="16"
|
||||||
</p>
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="#000"
|
||||||
|
role="img"
|
||||||
|
focusable="false"
|
||||||
|
aria-hidden="true"
|
||||||
|
><path
|
||||||
|
d="M5.46967 11.4697C5.17678 11.7626 5.17678 12.2374 5.46967 12.5303C5.76256 12.8232 6.23744 12.8232 6.53033 12.5303L10.5303 8.53033C10.8207 8.23999 10.8236 7.77014 10.5368 7.47624L6.63419 3.47624C6.34492 3.17976 5.87009 3.17391 5.57361 3.46318C5.27713 3.75244 5.27128 4.22728 5.56054 4.52376L8.94583 7.99351L5.46967 11.4697Z"
|
||||||
|
></path></svg
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="button text-[#8A8F98]">
|
||||||
|
Contribute <svg
|
||||||
|
class=""
|
||||||
|
style="--icon-color:#8A8F98"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
fill="#8A8F98"
|
||||||
|
role="img"
|
||||||
|
focusable="false"
|
||||||
|
aria-hidden="true"
|
||||||
|
><path
|
||||||
|
d="M5.46967 11.4697C5.17678 11.7626 5.17678 12.2374 5.46967 12.5303C5.76256 12.8232 6.23744 12.8232 6.53033 12.5303L10.5303 8.53033C10.8207 8.23999 10.8236 7.77014 10.5368 7.47624L6.63419 3.47624C6.34492 3.17976 5.87009 3.17391 5.57361 3.46318C5.27713 3.75244 5.27128 4.22728 5.56054 4.52376L8.94583 7.99351L5.46967 11.4697Z"
|
||||||
|
></path></svg
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="below">
|
</div>
|
||||||
<div class="absolute-center">
|
<div class="flex w-full flex-col lg:flex-row">
|
||||||
<h1>We care about preservation...</h1>
|
<div
|
||||||
<CardCarousel
|
class="flex w-full flex-shrink-0 flex-col gap-8 rounded-b-[2.25rem] bg-black p-12 lg:w-[35%]"
|
||||||
cards={[
|
>
|
||||||
{
|
<h1 class="text-[48px] leading-[0.9]">By the numbers</h1>
|
||||||
title: "Super Mario Odyssey",
|
<div class="flex flex-col gap-0">
|
||||||
compatibility: "goated",
|
<h2 class="text-[40px] leading-[1.1]">30+</h2>
|
||||||
image: odyssey,
|
<div class="text-[#A6A5A7]">dedicated contributors</div>
|
||||||
releaseYear: 2017,
|
</div>
|
||||||
},
|
<div class="flex flex-col gap-0">
|
||||||
{
|
<h2 class="text-[40px] leading-[1.1]">4000+</h2>
|
||||||
title: "The Legend of Zelda: Tears of the Kingdom",
|
<div class="text-[#A6A5A7]">supported games</div>
|
||||||
compatibility: "based",
|
</div>
|
||||||
image: totk,
|
<div class="flex flex-col gap-0">
|
||||||
releaseYear: 2023,
|
<h2 class="text-[40px] leading-[1.1]">14000+</h2>
|
||||||
},
|
<div class="text-[#A6A5A7]">members on Discord</div>
|
||||||
{
|
</div>
|
||||||
title: "Pokémon Scarlet and Pokémon Violet",
|
</div>
|
||||||
compatibility: "cringe",
|
<div class="flex w-full flex-1 rounded-[2.25rem] bg-black lg:rounded-tl-none">
|
||||||
image: scarletviolet,
|
<div
|
||||||
releaseYear: 2022,
|
class="flex w-full flex-1 rounded-[2.25rem] rounded-bl-none rounded-tr-none bg-[#131215] pt-8 lg:pl-8"
|
||||||
},
|
>
|
||||||
]}
|
<div
|
||||||
/>
|
class="h-full w-full overflow-hidden rounded-[2.25rem] bg-black shadow-lg ring ring-[#ffffff11]"
|
||||||
<div class="instructions">
|
>
|
||||||
<div class="key">Shift</div>
|
<img
|
||||||
<span class="plus">+</span>
|
class="h-full max-h-[496px] w-full object-cover"
|
||||||
<ScrollIcon size={48} color="#bebbdd" />
|
alt=""
|
||||||
</div>
|
decoding="async"
|
||||||
<p>
|
loading="lazy"
|
||||||
...so we're setting out to continue the beloved Yuzu emulator, as a non-profit drive
|
src="/img/bettercrophero.png"
|
||||||
for hardware preservation and research.
|
/>
|
||||||
</p>
|
|
||||||
<div class="buttons">
|
|
||||||
<button
|
|
||||||
on:click={() =>
|
|
||||||
window.open("https://git.suyu.dev/explore/organizations", "_blank")}
|
|
||||||
class="download">Git Repos</button
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="discord"
|
|
||||||
on:click={() => window.open("https://discord.gg/suyu", "_blank")}
|
|
||||||
>Discord</button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<div data-spacer-element class="min-h-[400px]"></div>
|
||||||
.buttons {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 16px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instructions {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 24px;
|
|
||||||
opacity: 0.25;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(100% - 162px);
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.plus {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plus,
|
|
||||||
.key {
|
|
||||||
margin-top: -14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.key {
|
|
||||||
font-size: 12px;
|
|
||||||
background-color: rgb(59, 55, 78);
|
|
||||||
border-radius: 4px;
|
|
||||||
border: solid 1px rgb(137, 129, 176);
|
|
||||||
padding: 4px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contents-container {
|
|
||||||
width: calc(100vw - 17px);
|
|
||||||
height: calc(100vh - 160px);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
gap: 96px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-right: 128px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-header {
|
|
||||||
margin-top: -2rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-text {
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 625px) {
|
|
||||||
.contents-container {
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 96px;
|
|
||||||
padding-right: 0;
|
|
||||||
text-align: center;
|
|
||||||
padding-left: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 560px) {
|
|
||||||
.absolute-center {
|
|
||||||
position: relative !important;
|
|
||||||
transform: none !important;
|
|
||||||
left: 0 !important;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instructions {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.below {
|
|
||||||
width: 100%;
|
|
||||||
min-height: calc(106vh - 80px);
|
|
||||||
height: fit-content;
|
|
||||||
padding-bottom: 80px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.absolute-center {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.absolute-center > h1 {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
margin-top: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.absolute-center > p {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 64px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
BIN
static/RocGroteskWideMedium.ttf
Normal file
BIN
static/RocGroteskWideMedium.ttf
Normal file
Binary file not shown.
BIN
static/img/bettercrophero.png
Normal file
BIN
static/img/bettercrophero.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 354 KiB |
BIN
static/img/desktopconceptheroimg.png
Normal file
BIN
static/img/desktopconceptheroimg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 509 KiB |
Loading…
Reference in a new issue