Initial commit

This commit is contained in:
DrMint 2024-01-21 13:28:48 +01:00
commit 740a96d30a
61 changed files with 1588 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

4
.ncurc.yml Normal file
View File

@ -0,0 +1,4 @@
upgrade: true
interactive: true
format: "group"
reject:

4
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"editor.rulers": [100],
"editor.tabSize": 2,
"typescript.preferences.importModuleSpecifier": "non-relative"
}

54
README.md Normal file
View File

@ -0,0 +1,54 @@
# Astro Starter Kit: Basics
```sh
npm create astro@latest -- --template basics
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554)
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
/
├── public/
│ └── favicon.svg
├── src/
│ ├── components/
│ │ └── Card.astro
│ ├── layouts/
│ │ └── Layout.astro
│ └── pages/
│ └── index.astro
└── package.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

26
astro.config.ts Normal file
View File

@ -0,0 +1,26 @@
import icon from "astro-icon";
import { defineConfig } from "astro/config";
import node from "@astrojs/node";
// https://astro.build/config
export default defineConfig({
output: "server",
srcDir: "./src",
publicDir: "./public",
outDir: "./dist",
adapter: node({
mode: "standalone",
}),
integrations: [
icon({
include: {
"material-symbols": ["*"], // Loads entire Material Design Icon set
},
}),
],
server: {
port: 12499,
host: true,
},
});

BIN
bun.lockb Executable file

Binary file not shown.

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "v3.accords-library.com",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro",
"upgrade": "ncu"
},
"dependencies": {
"@astrojs/check": "^0.3.1",
"@astrojs/node": "^6.0.3",
"astro": "^3.5.2",
"astro-icon": "next",
"ua-parser-js": "^1.0.37"
},
"devDependencies": {
"@iconify-json/material-symbols": "^1.1.62",
"@types/ua-parser-js": "^0.7.39",
"autoprefixer": "^10.4.16",
"bun-types": "^1.0.11",
"postcss-preset-env": "^9.3.0",
"ts-node": "^10.9.1",
"typescript": "^5.2.2",
"npm-check-updates": "^16.14.6"
}
}

11
postcss.config.cjs Normal file
View File

@ -0,0 +1,11 @@
const autoprefixer = require("autoprefixer");
const postcssPresetEnv = require("postcss-preset-env");
module.exports = {
plugins: [
autoprefixer,
postcssPresetEnv({
browsers: ["> 0.2% and not dead"],
}),
],
};

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
public/img/bg-home.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
public/img/paper-dots.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

2
public/robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-agent: *
Disallow: /

View File

@ -0,0 +1,96 @@
---
import Html from "./components/Html.astro";
import Topbar from "./components/Topbar.astro";
import Footer from "./components/Footer.astro";
interface Props {
breadcrumb?: { name: string; slug: string }[];
title?: string;
description?: string;
illustration?: string;
}
const {
title = "Accords Library",
description,
illustration,
breadcrumb = [],
} = Astro.props;
---
{
/* ------------------------------------------- HTML ------------------------------------------- */
}
<Html title={title}>
<header>
<Topbar breadcrumb={breadcrumb} />
<div id="header-content">
<div id="header-left">
<slot name="header-title">
<h1>{title}</h1>
</slot>
<slot name="header-description">
<p>{description}</p>
</slot>
</div>
<div id="image-container"></div>
</div>
</header>
<main><slot name="main" /></main>
<Footer withLinks={breadcrumb.length > 0} />
</Html>
{
/* ------------------------------------------- CSS -------------------------------------------- */
}
<style define:vars={{ illustration: `url(${illustration})` }}>
header {
display: flex;
flex-direction: column;
gap: 24px;
& > #header-content {
display: grid;
grid-template-columns: auto 1fr;
& > #header-left {
display: flex;
flex-direction: column;
gap: 32px;
place-items: flex-start;
& > h1 {
font-family: var(--font-serif);
font-size: 48px;
}
& > p {
max-width: 35em;
}
}
& > #image-container {
background-image: var(--illustration);
background-size: contain;
background-repeat: no-repeat;
background-position: right center;
mask-image: linear-gradient(
to left,
rgba(0, 0, 0, 1) 50%,
transparent 80%
);
@media (max-width: 60rem) {
display: none;
}
}
}
}
main {
padding-top: 96px;
padding-bottom: 128px;
}
</style>

View File

@ -0,0 +1,159 @@
---
import { Icon } from "astro-icon/components";
interface Props {
withLinks: boolean;
}
const { withLinks } = Astro.props;
---
<footer>
<div id="nav">
<p class="font-serif">Accords Library</p>
<a href="/"><Icon name="accords" />Home</a>
<a href="/timeline"
><Icon name="material-symbols:calendar-month-outline" />Timeline</a
>
<a href="https://gallery.accords-library.com/posts"
><Icon name="material-symbols:perm-media-outline" />Gallery</a
>
<a href="/videos"><Icon name="material-symbols:movie-outline" />Videos</a>
<a href="/archives"
><Icon name="material-symbols:folder-zip-outline" />Web archives</a
>
</div>
<div id="license">
This websites content is made available under <a
href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a
> unless otherwise noted.
<a
href="https://creativecommons.org/licenses/by-sa/4.0/"
id="common-creative"
aria-label="CC-BY-SA 4.0 License"
>
<Icon name="creative-commons-brands" />
<Icon name="creative-commons-by-brands" />
<Icon name="creative-commons-sa-brands" />
</a>
{
withLinks && (
<div id="socials">
<a href="/discord">
<Icon name="discord-brands" />
</a>
<a href="https://twitter.com/AccordsLibrary">
<Icon name="x-brands" />
</a>
<a href="https://github.com/Accords-Library">
<Icon name="github-brands" />
</a>
<a href="/contact">
<Icon name="material-symbols:mail-outline" />
</a>
</div>
)
}
</div>
<div id="copyright">
<strong>Accords Library</strong> is not affiliated with or endorsed by <strong
>SQUARE ENIX CO. LTD</strong
>. All game assets and promotional materials belongs to <strong
>© SQUARE ENIX CO. LTD</strong
>.
</div>
</footer>
<style>
footer {
border-top: 1px solid var(--color-base-1000);
padding-top: 32px;
display: flex;
place-content: center;
gap: clamp(24px, 12px + 2vw, 64px);
font-size: 14px;
& > div {
max-width: 20em;
}
& > #nav {
display: flex;
flex-direction: row;
& > p {
font-weight: 700;
}
}
& > #license {
border-left: 1px solid var(--color-base-1000);
padding-left: 1em;
& > #common-creative {
display: flex;
justify-content: flex-start;
gap: 0.2em;
margin-top: 8px;
& > svg {
width: 16px;
height: 16px;
}
}
& > #socials {
display: flex;
gap: 24px;
margin-top: 24px;
& > a > svg {
width: 24px;
height: 24px;
}
}
}
& > #copyright {
border-left: 1px solid var(--color-base-1000);
padding-left: 1em;
}
@media (max-width: 35rem) {
flex-direction: column;
text-align: center;
align-items: center;
& > div {
max-width: unset;
}
& > #license {
& > #common-creative {
place-content: center;
gap: clamp(4px, 2vw, 8px);
& > svg {
width: clamp(16px, 6vw, 24px);
height: clamp(16px, 6vw, 24px);
}
}
& > #socials {
place-content: center;
gap: clamp(24px, 8vw, 48px);
& > a > svg {
width: clamp(24px, 8vw, 48px);
height: clamp(24px, 8vw, 48px);
}
}
}
& > #copyright {
border: none;
padding-left: unset;
}
}
}
</style>

View File

@ -0,0 +1,222 @@
---
import UAParser from "ua-parser-js";
interface Props {
title: string;
}
const { title } = Astro.props;
const userAgent = Astro.request.headers.get("user-agent") ?? "";
const parser = new UAParser(userAgent);
const isIOS = parser.getOS().name === "iOS";
/* -------------------------------------------- HTML -------------------------------------------- */
---
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>{title}</title>
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<!-- Fonts google -->
<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=Vollkorn:wght@400;500;600;700;800;900&family=Zen+Maru+Gothic:wght@400;500;700;900&display=swap"
rel="stylesheet"
/>
<noscript>
<style>
.when-js {
display: none !important;
}
.when-no-js {
display: initial !important;
}
</style>
</noscript>
</head>
<body class:list={{ "texture-dots": !isIOS }}>
<slot />
</body>
</html>
{
/* ------------------------------------------- CSS -------------------------------------------- */
}
<style is:global>
:root {
--font-serif: "Vollkorn", serif;
/* Get in between colors with https://colorkit.io/ */
@media (prefers-color-scheme: light) {
--color-base-0: #ffffff;
--color-base-50: #fffaf3;
--color-base-100: #fff4e6;
--color-base-125: #fef0dd;
--color-base-150: #fdebd4;
--color-base-200: #f7ddc2;
--color-base-250: #efcfb0;
--color-base-300: #e5be9e;
--color-base-350: #ddb08e;
--color-base-400: #d3a07c;
--color-base-450: #ca926c;
--color-base-500: #c0835d;
--color-base-550: #b3754f;
--color-base-600: #a26a47;
--color-base-650: #905e3f;
--color-base-700: #805438;
--color-base-750: #6e4a31;
--color-base-800: #5e402b;
--color-base-850: #4d3625;
--color-base-900: #3c2d1e;
--color-base-950: #2f2419;
--color-base-1000: #1f1a13;
--color-elevation-2: var(--color-base-100);
--color-elevation-1: var(--color-base-125);
--color-elevation-0: var(--color-base-150);
--color-shadow: var(--color-base-500);
--color-shadow-1: var(--color-base-350);
--color-shadow-2: var(--color-base-300);
--texture-dots: url(/img/paper-dots.webp);
--texture-dots-blend: multiply;
}
@media (prefers-color-scheme: dark) {
--color-base-1000: #ebeae7;
--color-base-950: #eae5e0;
--color-base-900: #e8dfd8;
--color-base-850: #e4d1c4;
--color-base-800: #e0bfaa;
--color-base-750: #dcb095;
--color-base-700: #d4a07f;
--color-base-650: #cb916c;
--color-base-600: #bf835d;
--color-base-550: #b07751;
--color-base-500: #a06b48;
--color-base-450: #8f5f40;
--color-base-400: #7d5539;
--color-base-350: #6b4a33;
--color-base-300: #5c412e;
--color-base-250: #4a3728;
--color-base-200: #3a2d22;
--color-base-175: #312820;
--color-base-150: #27231e;
--color-base-100: #1c1b16;
--color-base-50: #11110d;
--color-base-0: #000000;
--color-elevation-2: var(--color-base-200);
--color-elevation-1: var(--color-base-175);
--color-elevation-0: var(--color-base-150);
--color-shadow: var(--color-base-0);
--color-shadow-1: var(--color-base-0);
--color-shadow-2: var(--color-base-50);
--texture-dots: url(/img/paper-dots-dark.webp);
--texture-dots-blend: overlay;
}
}
/* THEMING */
html,
body {
padding: 0;
margin: 0;
color: var(--color-base-1000);
background-color: var(--color-base-150);
}
body {
padding-top: clamp(12px, 3vmin, 24px);
padding-left: clamp(24px, 4vw, 64px);
padding-right: clamp(24px, 4vw, 64px);
padding-bottom: clamp(24px, 6vmin, 48px);
}
h1,
h2,
h3,
h4,
h5,
h6,
p,
button {
line-height: 1;
padding: 0;
margin: 0;
}
.font-serif {
font-family: "Vollkorn", serif;
}
button,
body {
font-family: "Zen Maru Gothic", sans-serif;
font-weight: 500;
}
a {
color: var(--color-base-1000);
}
.texture-dots {
background-size: 10cm;
background-attachment: local;
background-image: var(--texture-dots);
background-blend-mode: var(--texture-dots-blend);
background-repeat: repeat;
}
.keycap {
transition-duration: 150ms;
transition-property: translate, box-shadow, background-color;
transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
background-color: var(--color-elevation-0);
box-shadow:
0 7px 15px -5px var(--color-shadow),
inset 0 0 50px var(--color-elevation-2),
inset 0 -7px 1px 5px var(--color-shadow-2);
&:hover {
box-shadow:
0 7px 15px -2px var(--color-shadow),
inset 0 0 50px var(--color-elevation-2),
inset 0 -7px 1px 5px var(--color-shadow-2);
background-color: var(--color-elevation-1);
}
&:active {
transition-duration: 75ms;
translate: 0 5px;
background-color: var(--color-elevation-2);
box-shadow:
0 3px 5px -2px var(--color-shadow),
inset 0 0 50px var(--color-elevation-2),
inset 0 -6px 1px 6px var(--color-shadow-1);
}
}
.hide-scrollbar {
scrollbar-width: none; /* Firefox */
&::-webkit-scrollbar {
display: none;
}
}
</style>

View File

@ -0,0 +1,201 @@
---
import { Icon } from "astro-icon/components";
import Button from "components/Button.astro";
import ButtonGroup from "components/ButtonGroup.astro";
interface Props {
breadcrumb: { name: string; slug: string }[];
}
const { breadcrumb } = Astro.props;
---
{
/* ------------------------------------------- HTML ------------------------------------------- */
}
<nav id="topbar">
<div id="breadcrumb" class="hide-scrollbar">
{
breadcrumb.length > 0 && (
<>
<a href="/">
<Icon name="accords" /> Home
</a>
{breadcrumb.map(({ name, slug }) => (
<>
<Icon name="material-symbols:arrow-forward-ios" />
<a href={slug}>{name}</a>
</>
))}
</>
)
}
</div>
<div id="toolbar">
<Button icon="material-symbols:search" ariaLabel="Search on this website" />
<div class="separator"></div>
<Button
class="xs-not"
icon="material-symbols:sunny-outline"
ariaLabel="Switch between dark/light mode"
/>
<ButtonGroup
buttons={[
{
icon: "material-symbols:text-decrease",
ariaLabel: "Decrease text size",
},
{
icon: "material-symbols:text-increase",
ariaLabel: "Increase text size",
},
]}
/>
<Button
class="s-only"
icon={[
"material-symbols:translate",
"material-symbols:currency-exchange",
]}
ariaLabel="Select preferred language/currency"
/>
<Button
class="m-only s-not"
icon="material-symbols:translate"
ariaLabel="Select preferred language"
/>
<Button
class="m-only s-not"
icon="material-symbols:currency-exchange"
ariaLabel="Select preferred currency"
/>
<Button
class="m-not"
icon="material-symbols:translate"
title="EN"
ariaLabel="Select preferred language"
/>
<Button
class="m-not"
icon="material-symbols:currency-exchange"
title="USD"
ariaLabel="Select preferred currency"
/>
</div>
</nav>
{
/* ------------------------------------------- CSS -------------------------------------------- */
}
<style>
nav {
display: flex;
align-items: center;
flex-wrap: wrap-reverse;
gap: 32px 64px;
& > #breadcrumb {
display: flex;
place-items: center;
overflow-x: scroll;
& > svg {
flex-shrink: 0;
}
& > a {
text-decoration: none;
flex-shrink: 0;
padding: 0.2em 0.5em;
padding-bottom: 0.3em;
border-radius: 12px;
transition: 150ms background-color;
&:hover {
background-color: var(--color-elevation-1);
}
&:active {
background-color: var(--color-elevation-2);
}
&:last-child {
text-decoration: underline;
}
}
}
& > #toolbar {
flex-grow: 1;
display: flex;
gap: clamp(4px, 4px + 1vw, 12px);
place-items: center;
justify-content: flex-end;
@media (max-width: 28rem) {
justify-content: center;
}
@media (max-width: 22rem) {
justify-content: space-between;
gap: 0;
}
& > .separator {
width: 1px;
height: 2em;
background-color: var(--color-base-700);
@media (max-width: 30rem) {
display: none;
}
}
}
}
</style>
<style is:global>
nav#topbar > #toolbar {
& > .m-only,
& > .s-only {
display: none;
}
@media (max-width: 40rem) {
& > .m-only {
display: flex;
}
& > .m-not {
display: none;
}
@media (max-width: 28rem) {
& > .s-only {
display: flex;
}
& > .s-not {
display: none;
}
}
@media (max-width: 25rem) {
& > .xs-not {
display: none;
}
}
}
}
</style>
<script is:inline>
const breadcrumbElem = document.querySelector("nav#topbar > #breadcrumb");
breadcrumbElem.scrollTo({
left: breadcrumbElem.scrollWidth,
behavior: "instant",
});
</script>

View File

@ -0,0 +1,81 @@
---
import { Icon } from "astro-icon/components";
interface Props {
title?: string;
icon?: string | string[];
class?: string;
ariaLabel?: string;
}
const { title, icon, class: className, ariaLabel } = Astro.props;
const icons =
icon === undefined ? [] : typeof icon === "string" ? [icon] : icon;
---
{
/* ------------------------------------------- HTML ------------------------------------------- */
}
<button
class:list={[{ "with-title": !!title }, className]}
aria-label={ariaLabel}
>
{icons.map((cIcon) => <Icon name={cIcon} height={24} width={24} />)}
{title}
</button>
{
/* ------------------------------------------- CSS -------------------------------------------- */
}
<style>
button {
--foreground-color: var(--color-base-650);
color: var(--foreground-color);
border: 1px solid var(--foreground-color);
background-color: var(--color-elevation-0);
border-radius: 9999px;
padding-left: 1em;
padding-right: 1em;
height: 38px;
display: flex;
place-items: center;
place-content: center;
gap: 10px;
font-weight: 700;
font-size: 1em;
cursor: pointer;
transition-duration: 250ms;
transition-property: translate, box-shadow, background-color, color,
border-color;
transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
&:hover {
--foreground-color: var(--color-base-1000);
box-shadow: inset 0 1px 1px 0px var(--color-shadow-2);
}
&:active {
transition-duration: 75ms;
--foreground-color: var(--color-base-1000);
background-color: var(--color-elevation-2);
box-shadow: inset 0 1px 1px 1px var(--color-shadow-2);
& > div {
translate: 0 1px;
}
}
&.with-title {
& > div > svg {
width: 18px;
height: 18px;
}
}
}
</style>

View File

@ -0,0 +1,46 @@
---
import Button from "components/Button.astro";
interface Props {
buttons: Parameters<typeof Button>[0][];
}
const { buttons } = Astro.props;
---
{
/* ------------------------------------------- HTML ------------------------------------------- */
}
<div class="button-group">
{buttons.map((button) => <Button {...button} />)}
</div>
{
/* ------------------------------------------- CSS -------------------------------------------- */
}
<style is:global>
.button-group {
display: flex;
gap: 0;
& > button:first-child {
border-top-left-radius: 9999px;
border-bottom-left-radius: 9999px;
border-right: unset;
padding-right: 0.5em;
}
& > button {
border-radius: 0;
}
& > button:last-child {
border-top-right-radius: 9999px;
border-bottom-right-radius: 9999px;
border-left: unset;
padding-left: 0.5em;
}
}
</style>

2
src/env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

1
src/icons/accords.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M245.8 214.9l-33.22 17.28c-9.43-19.58-25.24-19.93-27.46-19.93-22.13 0-33.22 14.61-33.22 43.84 0 23.57 9.21 43.84 33.22 43.84 14.47 0 24.65-7.09 30.57-21.26l30.55 15.5c-6.17 11.51-25.69 38.98-65.1 38.98-22.6 0-73.96-10.32-73.96-77.05 0-58.69 43-77.06 72.63-77.06 30.72-.01 52.7 11.95 65.99 35.86zm143.1 0l-32.78 17.28c-9.5-19.77-25.72-19.93-27.9-19.93-22.14 0-33.22 14.61-33.22 43.84 0 23.55 9.23 43.84 33.22 43.84 14.45 0 24.65-7.09 30.54-21.26l31 15.5c-2.1 3.75-21.39 38.98-65.09 38.98-22.69 0-73.96-9.87-73.96-77.05 0-58.67 42.97-77.06 72.63-77.06 30.71-.01 52.58 11.95 65.56 35.86zM247.6 8.05C104.7 8.05 0 123.1 0 256c0 138.5 113.6 248 247.6 248C377.5 504 496 403.1 496 256 496 118.1 389.4 8 247.6 8zm.87 450.8c-112.5 0-203.7-93.04-203.7-202.8 0-105.4 85.43-203.3 203.7-203.3 112.5 0 202.8 89.46 202.8 203.3-.01 121.7-99.68 202.8-202.8 202.8z"/></svg>

After

Width:  |  Height:  |  Size: 925 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M314.9 194.4v101.4h-28.3v120.5h-77.1V295.9h-28.3V194.4c0-4.4 1.6-8.2 4.6-11.3 3.1-3.1 6.9-4.7 11.3-4.7H299c4.1 0 7.8 1.6 11.1 4.7 3.1 3.2 4.8 6.9 4.8 11.3zm-101.5-63.7c0-23.3 11.5-35 34.5-35s34.5 11.7 34.5 35c0 23-11.5 34.5-34.5 34.5s-34.5-11.5-34.5-34.5zM247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3z"/></svg>

After

Width:  |  Height:  |  Size: 579 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zM137.7 221c13-83.9 80.5-95.7 108.9-95.7 99.8 0 127.5 82.5 127.5 134.2 0 63.6-41 132.9-128.9 132.9-38.9 0-99.1-20-109.4-97h62.5c1.5 30.1 19.6 45.2 54.5 45.2 23.3 0 58-18.2 58-82.8 0-82.5-49.1-80.6-56.7-80.6-33.1 0-51.7 14.6-55.8 43.8h18.2l-49.2 49.2-49-49.2h19.4z"/></svg>

After

Width:  |  Height:  |  Size: 586 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M524.5 69.84a1.5 1.5 0 00-.764-.7A485.1 485.1 0 00404.1 32.03a1.816 1.816 0 00-1.923.91 337.5 337.5 0 00-14.9 30.6 447.8 447.8 0 00-134.4 0 309.5 309.5 0 00-15.14-30.6 1.89 1.89 0 00-1.924-.91A483.7 483.7 0 00116.1 69.14a1.712 1.712 0 00-.788.676C39.07 183.7 18.19 294.7 28.43 404.4a2.016 2.016 0 00.765 1.375A487.7 487.7 0 00176 479.9a1.9 1.9 0 002.063-.676A348.2 348.2 0 00208.1 430.4a1.86 1.86 0 00-1.019-2.588 321.2 321.2 0 01-45.87-21.85 1.885 1.885 0 01-.185-3.126 251.047 251.047 0 009.109-7.137 1.819 1.819 0 011.9-.256c96.23 43.92 200.4 43.92 295.5 0a1.812 1.812 0 011.924.233 234.533 234.533 0 009.132 7.16 1.884 1.884 0 01-.162 3.126 301.4 301.4 0 01-45.89 21.83 1.875 1.875 0 00-1 2.611 391.1 391.1 0 0030.01 48.81 1.864 1.864 0 002.063.7A486 486 0 00610.7 405.7a1.882 1.882 0 00.765-1.352C623.7 277.6 590.9 167.5 524.5 69.84zm-302 267.76c-28.97 0-52.84-26.59-52.84-59.24s23.44-59.26 52.84-59.26c29.67 0 53.31 26.82 52.84 59.24-.04 31.76-23.44 59.26-52.84 59.26zm195.4 0c-28.97 0-52.84-26.59-52.84-59.24s23.34-59.26 52.84-59.26c29.67 0 53.31 26.82 52.84 59.24-.04 31.76-23.24 59.26-52.84 59.26z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
src/icons/x-brands.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584l-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg>

After

Width:  |  Height:  |  Size: 271 B

View File

@ -0,0 +1,51 @@
---
interface Props {
img?: { light: string; dark: string };
name: string;
href: string;
}
const { img, name, href } = Astro.props;
---
<a href={href} aria-label={name} class="keycap">
{img === undefined ? <p>{name}</p> : <div />}
</a>
<style
define:vars={{
"light-image": `url(${img?.light})`,
"dark-image": `url(${img?.dark})`,
}}
>
a {
font-size: 24px;
font-weight: 400;
text-decoration: none;
display: grid;
place-items: center;
padding: 24px;
padding-bottom: 32px;
border-radius: 12px;
user-select: none;
& > div {
@media (prefers-color-scheme: light) {
background-image: var(--light-image);
}
@media (prefers-color-scheme: dark) {
background-image: var(--dark-image);
}
background-size: contain;
background-position: center;
background-repeat: no-repeat;
aspect-ratio: 2;
height: 100%;
width: 100%;
}
}
</style>

View File

@ -0,0 +1,53 @@
---
import { Icon } from "astro-icon/components";
interface Props {
title: string;
icon: string;
subtitle: string;
href: string;
}
const { icon, subtitle, title, href } = Astro.props;
---
<a href={href} class="keycap">
<Icon name={icon} />
<div id="right">
<h3>{title}</h3>
<p>{subtitle}</p>
</div>
</a>
<style>
a {
display: flex;
place-items: center;
gap: 16px;
color: var(--color-base-1000);
padding: 24px;
padding-top: 12px;
border-radius: 12px;
text-decoration: none;
& > svg {
width: clamp(24px, 6vw + 14px, 48px);
height: clamp(24px, 6vw + 14px, 48px);
}
& > #right {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
& > h3 {
font-size: 24px;
}
& > p {
font-size: 14px;
margin-left: 2px;
}
}
}
</style>

View File

@ -0,0 +1,46 @@
---
import { Icon } from "astro-icon/components";
interface Props {
title: string;
icon: string;
href: string;
}
const { icon, title, href } = Astro.props;
---
<a href={href} class="keycap">
<Icon name={icon} />
<div id="right">
<h3>{title}</h3>
</div>
</a>
<style>
a {
display: flex;
place-items: center;
gap: 16px;
color: var(--color-base-1000);
padding: 24px;
padding-top: 12px;
border-radius: 12px;
text-decoration: none;
& > svg {
width: 24px;
height: 24px;
}
& > #right {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
& > h3 {
font-size: 24px;
}
}
}
</style>

View File

@ -0,0 +1,94 @@
---
import AppLayout from "components/AppLayout/AppLayout.astro";
import FolderCard from "./_components/FolderCard.astro";
---
{
/* ------------------------------------------- HTML ------------------------------------------- */
}
<AppLayout
breadcrumb={[
{ name: "Drakengard", slug: "drakengard" },
{ name: "Testing a long name", slug: "long" },
{ name: "More stuff", slug: "more" },
]}
title="Drakengard"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
illustration="/img/categories/light/dod.png"
>
<div id="main" slot="main">
<FolderCard
title="Games"
icon="material-symbols:stadia-controller-outline"
href="/drakengard/games"
/>
<FolderCard
title="Guidebooks"
icon="material-symbols:menu-book-outline"
href="/drakengard/guidebooks"
/>
<FolderCard
title="Manga"
icon="material-symbols:menu-book-outline"
href="/drakengard/manga"
/>
<FolderCard
title="Novels"
icon="material-symbols:menu-book-outline"
href="/drakengard/novels"
/>
<FolderCard
title="Novellas"
icon="material-symbols:menu-book-outline"
href="/drakengard/novellas "
/>
<FolderCard
title="Characters"
icon="material-symbols:person-outline"
href="/drakengard/characters"
/>
<FolderCard
title="Places"
icon="material-symbols:location-on-outline"
href="/drakengard/places"
/>
<FolderCard
title="Enemies"
icon="material-symbols:sentiment-extremely-dissatisfied-outline"
href="/drakengard/enemies"
/>
<FolderCard
title="Terms"
icon="material-symbols:indeterminate-question-box"
href="/drakengard/terms"
/>
<FolderCard
title="Weapons"
icon="material-symbols:swords-outline"
href="/drakengard/weapons"
/>
<FolderCard
title="Timeline"
icon="material-symbols:calendar-month-outline"
href="/drakengard/timeline"
/>
<FolderCard
title="News"
icon="material-symbols:newspaper"
href="/drakengard/news"
/>
</div>
</AppLayout>
{
/* ------------------------------------------- CSS -------------------------------------------- */
}
<style>
#main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 0.7rem 1rem;
}
</style>

351
src/pages/index.astro Normal file
View File

@ -0,0 +1,351 @@
---
import { Icon } from "astro-icon/components";
import AppLayout from "components/AppLayout/AppLayout.astro";
import Button from "components/Button.astro";
import LinkCard from "./_components/LinkCard.astro";
import CategoryCard from "./_components/CategoryCard.astro";
---
{
/* ------------------------------------------- HTML ------------------------------------------- */
}
<AppLayout title="Accords Library" illustration="/img/bg-home.webp">
<div id="title" slot="header-title">
<Icon name="accords" />
<div>
<h1 class="font-serif">Accords Library</h1>
<p>Discover • Archive • Translate • Analyze</p>
</div>
</div>
<div id="description" slot="header-description">
<p>
We aim at archiving and translating all of <strong>Yoko Taro</strong>s
works.<br />Yoko Taro is a Japanese video game director and scenario
writer. He is best-known for his involvement with the <strong>NieR</strong
> and <strong>Drakengard</strong> series. To complement his games, Yoko
Taro likes to publish side materials in the form of books, anime, manga,
audio books, novellas, even theater plays.<br />These media can be very
difficult to find. His work goes all the way back to 2003. Most of it was
released solely in Japanese, and sometimes in short supply. So this is
what we do here: <strong>discover, archive, translate, and analyze</strong
>.
</p>
<Button title="Read more about us" icon="material-symbols:left-click" />
</div>
<Fragment slot="main">
<div id="main">
<section id="library">
<h2>The Library</h2>
<p>
Here you will find a list of IPs Yoko Taro worked on. Select one to
discover all the media/content/articles that relates to this IP.
<strong>Beware there can be spoilers.</strong>
</p>
<div class="grid">
<CategoryCard
img={{
light: "/img/categories/light/dod.png",
dark: "/img/categories/dark/dod.png",
}}
name="Drakengard"
href="/drakengard"
/>
<CategoryCard
img={{
light: "/img/categories/light/dod2.png",
dark: "/img/categories/dark/dod2.png",
}}
name="Drakengard 2"
href="/drakengard-2"
/>
<CategoryCard
img={{
light: "/img/categories/light/dod3.png",
dark: "/img/categories/dark/dod3.png",
}}
name="Drakengard 3"
href="/drakengard-3"
/>
<CategoryCard
img={{
light: "/img/categories/light/dod1.3.png",
dark: "/img/categories/dark/dod1.3.png",
}}
name="Drakengard 1.3"
href="/drakengard-1-3"
/>
<CategoryCard
img={{
light: "/img/categories/light/nier.png",
dark: "/img/categories/dark/nier.png",
}}
name="NieR"
href="/nier"
/>
<CategoryCard
img={{
light: "/img/categories/light/na.png",
dark: "/img/categories/dark/na.png",
}}
name="NieR:Automata"
href="/nier-automata"
/>
<CategoryCard
img={{
light: "/img/categories/light/nier-rein.png",
dark: "/img/categories/dark/nier-rein.png",
}}
name="NieR Re[in]carnation"
href="/nier-rein"
/>
<CategoryCard
img={{
light: "/img/categories/light/yorha.png",
dark: "/img/categories/dark/yorha.png",
}}
name="YoRHa"
href="/yorha"
/>
<CategoryCard
img={{
light: "/img/categories/light/yorha-boys.png",
dark: "/img/categories/dark/yorha-boys.png",
}}
name="YoRHa Boys"
href="/yorha-boys"
/>
<CategoryCard
img={{
light: "/img/categories/light/sino.png",
dark: "/img/categories/dark/sino.png",
}}
name="SINoALICE"
href="/sinoalice"
/>
<CategoryCard
img={{
light: "/img/categories/light/404gamereset.png",
dark: "/img/categories/dark/404gamereset.png",
}}
name="404 Game Re:Set"
href="/404-game-reset"
/>
<CategoryCard
img={{
light: "/img/categories/light/god-app.png",
dark: "/img/categories/dark/god-app.png",
}}
name="God App"
href="/god-app"
/>
<CategoryCard
img={{
light: "/img/categories/light/voc.png",
dark: "/img/categories/dark/voc.png",
}}
name="Voice of Cards"
href="/voice-of-cards"
/>
<CategoryCard name="Others..." href="others" />
</div>
</section>
<section>
<h2>More content</h2>
<p>
The NieR and Drakengard series share a common timeline which you can
explore it at the link bellow. Also we have gathered thousands of
official artworks, videos, and notable web resources.
<strong>Beware there can be spoilers.</strong>
</p>
<div class="grid">
<LinkCard
icon="material-symbols:calendar-month-outline"
title="Timeline"
subtitle="8 eras, 358 events"
href="/timeline"
/>
<LinkCard
icon="material-symbols:perm-media-outline"
title="Gallery"
subtitle="5,750 images"
href="https://gallery.accords-library.com/posts"
/>
<LinkCard
icon="material-symbols:movie-outline"
title="Videos"
subtitle="2,115 videos"
href="/videos"
/>
<LinkCard
icon="material-symbols:folder-zip-outline"
title="Web archives"
subtitle="20 archives"
href="/archives"
/>
</div>
</section>
<section>
<h2>Links</h2>
<p>
Do you have a <strong>question</strong>? Would like to share something
with our
<strong>community</strong>? Are you interested in <strong
>contributing</strong
> to this project? Whatever it is, you should find what you are
looking for at the following links.
</p>
<div class="grid">
<LinkCard
icon="discord-brands"
title="Discord"
subtitle="Join the community"
href="/discord"
/>
<LinkCard
icon="x-brands"
title="Twitter"
subtitle="Get the latest updates"
href="https://twitter.com/AccordsLibrary"
/>
<LinkCard
icon="github-brands"
title="GitHub"
subtitle="Join the technical side"
href="https://github.com/Accords-Library"
/>
<LinkCard
icon="material-symbols:mail-outline"
title="Contact"
subtitle="Send us an email"
href="/contact"
/>
</div>
</section>
</div>
</Fragment>
</AppLayout>
{
/* ------------------------------------------- CSS -------------------------------------------- */
}
<style>
#description {
display: flex;
flex-direction: column;
gap: 24px;
align-items: flex-start;
& > p {
line-height: 1.4;
max-width: 35em;
}
@media (max-width: 35rem) {
align-items: center;
@media (max-width: 25rem) {
align-items: stretch;
}
}
}
#title {
display: flex;
place-items: center;
gap: 16px;
& > svg {
width: 64px;
height: 64px;
}
& > div {
& > h1 {
margin: 0;
line-height: 1;
font-size: 52px;
font-weight: 800;
}
& > p {
line-height: 1;
margin: 0;
margin-top: -0.5em;
font-size: 21.5px;
font-weight: 700;
}
}
@media (max-width: 35rem) {
flex-direction: column;
width: 100%;
place-items: center;
--container-width: calc((100vw - 48px));
& > svg {
width: calc(var(--container-width) / 3);
height: calc(var(--container-width) / 3);
}
& > div {
& > h1 {
margin: 0;
line-height: 1;
font-size: calc(var(--container-width) / 9);
font-weight: 800;
}
& > p {
line-height: 1;
margin: 0;
margin-top: -0.5em;
font-size: calc(var(--container-width) / 21.8);
font-weight: 700;
}
}
}
}
#main {
display: grid;
gap: 64px;
& > section {
& > h2 {
font-family: var(--font-serif);
font-size: 28px;
}
& > p {
max-width: 35em;
line-height: 1.4;
padding-top: 8px;
padding-bottom: 24px;
}
&#library {
& > .grid {
@media (max-width: 40rem) {
grid-template-columns: 1fr 1fr;
}
@media (max-width: 25rem) {
grid-template-columns: 1fr;
}
}
}
& > .grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
column-gap: clamp(6px, 2vmin, 16px);
row-gap: clamp(6px + 6px, 2vmin + 6px, 16px);
}
}
}
</style>

11
tsconfig.json Normal file
View File

@ -0,0 +1,11 @@
{
"extends": "astro/tsconfigs/strictest",
"compilerOptions": {
"types": ["bun-types"],
"baseUrl": ".",
"paths": {
"pages/*": ["src/pages/*"],
"components/*": ["src/components/*"]
}
}
}