Improve everything
This commit is contained in:
parent
421dc1e614
commit
cd69584b66
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
"editor.rulers": [100],
|
"editor.rulers": [100],
|
||||||
"editor.tabSize": 2
|
"editor.tabSize": 2,
|
||||||
|
"typescript.preferences.importModuleSpecifier": "non-relative"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
- [ ] Check why I'm getting NS_BINDING_ABORTED on fonts when fetched in the network browser dev tool tab
|
||||||
|
- [ ] Add a background when opening menus in mobile mode
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
original light mode
|
|
||||||
color: #fff1e0;
|
|
||||||
color: #ffedd8;
|
|
||||||
color: #f0d1b3;
|
|
||||||
color: #c0845e;
|
|
||||||
color: #9c6644;
|
|
||||||
color: #1b1811; */
|
|
||||||
|
|
||||||
/*
|
|
||||||
original dark mode
|
|
||||||
color: #191914;
|
|
||||||
color: #26221e;
|
|
||||||
color: #2c2803;
|
|
||||||
color: #392d22;
|
|
||||||
color: #c0845e;
|
|
||||||
color: #ebeae7; */
|
|
||||||
|
|
||||||
/* new version using https://leonardocolor.io/theme.html */
|
|
||||||
|
|
||||||
:where(button) {
|
|
||||||
background-color: inherit;
|
|
||||||
color: inherit;
|
|
||||||
border: initial;
|
|
||||||
padding: initial;
|
|
||||||
margin: initial;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
.tippy-box[data-animation="fade"][data-state="hidden"] {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
[data-tippy-root] {
|
||||||
|
max-width: calc(100vw - 10px);
|
||||||
|
}
|
||||||
|
.tippy-box {
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--color-elevation-1);
|
||||||
|
color: var(--color-base-1000);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
box-shadow: 0 20px 25px -5px var(--color-shadow),
|
||||||
|
0 0 10px -6px var(--color-shadow);
|
||||||
|
transition-property: transform, visibility, opacity;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="top"] > .tippy-arrow {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="top"] > .tippy-arrow:before {
|
||||||
|
bottom: -7px;
|
||||||
|
left: 0;
|
||||||
|
border-width: 8px 8px 0;
|
||||||
|
border-top-color: initial;
|
||||||
|
transform-origin: center top;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="bottom"] > .tippy-arrow {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="bottom"] > .tippy-arrow:before {
|
||||||
|
top: -7px;
|
||||||
|
left: 0;
|
||||||
|
border-width: 0 8px 8px;
|
||||||
|
border-bottom-color: initial;
|
||||||
|
transform-origin: center bottom;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="left"] > .tippy-arrow {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="left"] > .tippy-arrow:before {
|
||||||
|
border-width: 8px 0 8px 8px;
|
||||||
|
border-left-color: initial;
|
||||||
|
right: -7px;
|
||||||
|
transform-origin: center left;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="right"] > .tippy-arrow {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="right"] > .tippy-arrow:before {
|
||||||
|
left: -7px;
|
||||||
|
border-width: 8px 8px 8px 0;
|
||||||
|
border-right-color: initial;
|
||||||
|
transform-origin: center right;
|
||||||
|
}
|
||||||
|
.tippy-box[data-inertia][data-state="visible"] {
|
||||||
|
transition-timing-function: cubic-bezier(0.54, 1.5, 0.38, 1.11);
|
||||||
|
}
|
||||||
|
.tippy-arrow {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
color: var(--color-elevation-1);
|
||||||
|
}
|
||||||
|
.tippy-arrow:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
border-color: transparent;
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
.tippy-content {
|
||||||
|
position: relative;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="top"] {
|
||||||
|
transform-origin: bottom;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="bottom"] {
|
||||||
|
transform-origin: top;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="left"] {
|
||||||
|
transform-origin: right;
|
||||||
|
}
|
||||||
|
.tippy-box[data-placement^="right"] {
|
||||||
|
transform-origin: left;
|
||||||
|
}
|
||||||
|
.tippy-box[data-state="hidden"] {
|
||||||
|
transform: scale(0.8);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
|
@ -1,20 +0,0 @@
|
||||||
---
|
|
||||||
import { Icon } from "astro-icon/components";
|
|
||||||
import { getLocalizedUrl } from "utils/urls";
|
|
||||||
interface Props {
|
|
||||||
href: string;
|
|
||||||
isActive?: boolean;
|
|
||||||
text?: string;
|
|
||||||
icon?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { locale } = Astro.params;
|
|
||||||
const { href, text, icon, isActive } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<a href={getLocalizedUrl(href, locale)} class:list={{ active: isActive }}>
|
|
||||||
{text && text}
|
|
||||||
{icon && <Icon name={icon} />}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<style></style>
|
|
|
@ -1,262 +0,0 @@
|
||||||
---
|
|
||||||
import { Icon } from "astro-icon/components";
|
|
||||||
import { getLocalizedUrl } from "utils/urls";
|
|
||||||
import { CookieNames } from "utils/cookies";
|
|
||||||
import NavOption from "./NavOption.astro";
|
|
||||||
|
|
||||||
const { locale = "en" } = Astro.params;
|
|
||||||
const isReduced =
|
|
||||||
Astro.cookies.get(CookieNames.MENU_PANEL_REDUCED)?.boolean() ?? false;
|
|
||||||
const themeColors =
|
|
||||||
Astro.cookies.get(CookieNames.THEME_COLOR)?.value ?? "theme-color-light";
|
|
||||||
---
|
|
||||||
|
|
||||||
<div id="component" class:list={{ reduced: isReduced }}>
|
|
||||||
<a
|
|
||||||
id="accords-logo"
|
|
||||||
data-turbo-confirm="Do you want to leave this page?"
|
|
||||||
href={getLocalizedUrl("/", locale)}
|
|
||||||
>
|
|
||||||
<Icon name="accords" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<p id="title">Accord’s Library</p>
|
|
||||||
|
|
||||||
<button id="reduce-toggle">
|
|
||||||
<Icon name="material-symbols:chevron-left-rounded" width={24} height={24} />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class={themeColors === "theme-color-dark" ? "dark" : "light"}
|
|
||||||
id="theme-toggle"
|
|
||||||
>
|
|
||||||
<Icon class="when-light" name="material-symbols:light-mode" />
|
|
||||||
<Icon class="when-dark" name="material-symbols:dark-mode" />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<NavOption
|
|
||||||
href="/library"
|
|
||||||
icon="material-symbols:auto-stories"
|
|
||||||
title="Library"
|
|
||||||
subtitle="Browse all physical and digital media"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<NavOption
|
|
||||||
href="/contents"
|
|
||||||
icon="material-symbols:workspaces"
|
|
||||||
title="Content"
|
|
||||||
subtitle="Explore all content and filter by type or category"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<NavOption
|
|
||||||
href="/wiki"
|
|
||||||
icon="material-symbols:travel-explore"
|
|
||||||
title="Wiki"
|
|
||||||
subtitle="An encyclopedia for everything related to DrakeNieR"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<NavOption
|
|
||||||
href="/chronicles"
|
|
||||||
icon="material-symbols:schedule"
|
|
||||||
title="Chronicles"
|
|
||||||
subtitle="Experience all events and content in chronological order"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<NavOption href="/news" icon="material-symbols:newspaper" title="News" />
|
|
||||||
|
|
||||||
<NavOption
|
|
||||||
href="https://gallery.accords-library.com/posts/"
|
|
||||||
icon="material-symbols:perm-media"
|
|
||||||
title="Gallery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<NavOption href="/archives" icon="material-symbols:save" title="Archives" />
|
|
||||||
|
|
||||||
<NavOption href="/about-us" icon="material-symbols:info" title="About us" />
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This website’s content is made available under <a
|
|
||||||
href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a
|
|
||||||
> unless otherwise noted.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div id="common-creative">
|
|
||||||
<Icon name="creative-commons-brands" />
|
|
||||||
<Icon name="creative-commons-by-brands" />
|
|
||||||
<Icon name="creative-commons-sa-brands" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Accord’s Library is not affiliated with or endorsed by SQUARE ENIX CO. LTD.
|
|
||||||
All game assets and promotional materials belongs to © SQUARE ENIX CO. LTD.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div id="social-links">
|
|
||||||
<Icon name="github-brands" />
|
|
||||||
<Icon name="x-brands" />
|
|
||||||
<Icon name="discord-brands" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { CookieNames } from "utils/cookies";
|
|
||||||
import { observableWithPersistence } from "utils/micro-observables";
|
|
||||||
import { Elementos } from "utils/Elementos";
|
|
||||||
import { onLoad } from "utils/turbo";
|
|
||||||
|
|
||||||
onLoad(() => {
|
|
||||||
const component = new Elementos("#component");
|
|
||||||
const reduceToggleButton = new Elementos("#reduce-toggle");
|
|
||||||
|
|
||||||
const isReduced = observableWithPersistence(
|
|
||||||
CookieNames.MENU_PANEL_REDUCED,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
reduceToggleButton.onClick(() => {
|
|
||||||
isReduced.update((oldValue) => !oldValue);
|
|
||||||
Turbo.cache.clear();
|
|
||||||
});
|
|
||||||
|
|
||||||
component.setClass("reduced", isReduced);
|
|
||||||
|
|
||||||
// theme-toggle
|
|
||||||
const body = new Elementos("body");
|
|
||||||
const themeToggleButton = new Elementos("#theme-toggle");
|
|
||||||
|
|
||||||
const themeColor = observableWithPersistence(
|
|
||||||
CookieNames.THEME_COLOR,
|
|
||||||
"theme-color-light"
|
|
||||||
);
|
|
||||||
|
|
||||||
const isDarkMode = themeColor.select(
|
|
||||||
(value) => value === "theme-color-dark"
|
|
||||||
);
|
|
||||||
|
|
||||||
themeToggleButton.onClick(() => {
|
|
||||||
themeColor.update((oldValue) =>
|
|
||||||
oldValue === "theme-color-light"
|
|
||||||
? "theme-color-dark"
|
|
||||||
: "theme-color-light"
|
|
||||||
);
|
|
||||||
Turbo.cache.clear();
|
|
||||||
});
|
|
||||||
|
|
||||||
themeToggleButton.setClass(
|
|
||||||
{ ifFalse: "light", ifTrue: "dark" },
|
|
||||||
isDarkMode
|
|
||||||
);
|
|
||||||
|
|
||||||
body.setClass(
|
|
||||||
{ ifFalse: "theme-color-light", ifTrue: "theme-color-dark" },
|
|
||||||
isDarkMode
|
|
||||||
);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#component {
|
|
||||||
--reduced-transition-duration: 5s;
|
|
||||||
display: grid;
|
|
||||||
padding: 2rem;
|
|
||||||
gap: 1rem;
|
|
||||||
|
|
||||||
container-type: inline-size;
|
|
||||||
|
|
||||||
@media (width >= 60rem) {
|
|
||||||
transition:
|
|
||||||
var(--reduced-transition-duration) width,
|
|
||||||
var(--reduced-transition-duration) padding;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
width: 20rem;
|
|
||||||
flex-shrink: 0;
|
|
||||||
border-right: var(--border-style);
|
|
||||||
|
|
||||||
& > #title {
|
|
||||||
font-family: var(--font-headers);
|
|
||||||
font-size: 1.875rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
transition:
|
|
||||||
var(--reduced-transition-duration) font-size,
|
|
||||||
var(--reduced-transition-duration) opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #common-creative,
|
|
||||||
& > #social-links {
|
|
||||||
transition:
|
|
||||||
var(--reduced-transition-duration) transform,
|
|
||||||
var(--reduced-transition-duration) opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.reduced {
|
|
||||||
width: 6rem;
|
|
||||||
|
|
||||||
padding: 2rem 1rem;
|
|
||||||
|
|
||||||
& > p,
|
|
||||||
& > #title {
|
|
||||||
font-size: 0;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #common-creative,
|
|
||||||
& > #social-links {
|
|
||||||
transform: scale(0);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #accords-logo {
|
|
||||||
place-self: center;
|
|
||||||
width: max(50%, 3rem);
|
|
||||||
aspect-ratio: 1/1;
|
|
||||||
color: var(--color-base-1000);
|
|
||||||
transition: 0.1s color;
|
|
||||||
&:hover {
|
|
||||||
color: var(--color-base-600);
|
|
||||||
}
|
|
||||||
|
|
||||||
& > svg {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #theme-toggle.dark > .when-light,
|
|
||||||
& > #theme-toggle.light > .when-dark {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #common-creative {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-flow: column;
|
|
||||||
place-content: center;
|
|
||||||
gap: 0.25rem;
|
|
||||||
|
|
||||||
& > svg {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #social-links {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-flow: column;
|
|
||||||
place-items: center;
|
|
||||||
|
|
||||||
& > svg {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,75 +0,0 @@
|
||||||
---
|
|
||||||
import { Icon } from "astro-icon/components";
|
|
||||||
interface Props {
|
|
||||||
title: string;
|
|
||||||
showSubPanel: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title, showSubPanel } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<div id="component">
|
|
||||||
<button
|
|
||||||
id="toggle-menu-panel"
|
|
||||||
_="on click
|
|
||||||
toggle .opened on #menu-panel
|
|
||||||
remove .opened from #sub-panel
|
|
||||||
remove .on from #toggle-sub-panel
|
|
||||||
toggle .on on me"
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
class="when-off"
|
|
||||||
name="material-symbols:menu-rounded"
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
/>
|
|
||||||
<Icon
|
|
||||||
class="when-on"
|
|
||||||
name="material-symbols:close-rounded"
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<p>{title}</p>
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
showSubPanel && (
|
|
||||||
<button
|
|
||||||
id="toggle-sub-panel"
|
|
||||||
_="on click
|
|
||||||
toggle .opened on #sub-panel
|
|
||||||
remove .opened from #menu-panel
|
|
||||||
remove .on from #toggle-menu-panel
|
|
||||||
toggle .on on me"
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
class="when-off"
|
|
||||||
name="material-symbols:tune-rounded"
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
/>
|
|
||||||
<Icon
|
|
||||||
class="when-on"
|
|
||||||
name="material-symbols:close-rounded"
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
#component {
|
|
||||||
border-top: var(--border-style);
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 5rem 1fr 5rem;
|
|
||||||
place-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.on > .when-off,
|
|
||||||
:not(.on) > .when-on {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
/// <reference types="astro/client" />
|
||||||
|
/// <reference path="../.astro/types.d.ts" />
|
|
@ -1,159 +0,0 @@
|
||||||
---
|
|
||||||
import { CookieNames } from "utils/cookies";
|
|
||||||
interface Props {
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title } = Astro.props;
|
|
||||||
const themeColors =
|
|
||||||
Astro.cookies.get(CookieNames.THEME_COLOR)?.value ?? "theme-color-light";
|
|
||||||
---
|
|
||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
||||||
<title>{title}</title>
|
|
||||||
<script is:inline src="/js/turbo.es2017-umd.js" async defer></script>
|
|
||||||
<link href="/css/sanitize.min.css" rel="stylesheet" />
|
|
||||||
<link href="/css/global.css" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class={themeColors} hx-ext="head-support" hx-boost="true">
|
|
||||||
<slot />
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import tippy from "tippy.js";
|
|
||||||
import "tippy.js/dist/tippy.css";
|
|
||||||
|
|
||||||
tippy("[data-tippy-content]", { allowHTML: true });
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style is:global>
|
|
||||||
.theme-color-light {
|
|
||||||
--color-base-0: #ffffff;
|
|
||||||
--color-base-50: #fffaf3;
|
|
||||||
--color-base-100: #fff4e6;
|
|
||||||
--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-shadow: var(--color-base-500);
|
|
||||||
|
|
||||||
--texture-dots: url(/images/paper-dots.webp);
|
|
||||||
--texture-dots-blend: multiply;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-color-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-150: #27231e;
|
|
||||||
--color-base-100: #1c1b16;
|
|
||||||
--color-base-50: #11110d;
|
|
||||||
--color-base-0: #000000;
|
|
||||||
|
|
||||||
--color-shadow: var(--color-base-0);
|
|
||||||
|
|
||||||
--texture-dots: url(/images/paper-dots-dark.webp);
|
|
||||||
--texture-dots-blend: overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
.texture-dots {
|
|
||||||
background-size: 10cm;
|
|
||||||
background-attachment: local;
|
|
||||||
background-image: var(--texture-dots);
|
|
||||||
background-blend-mode: var(--texture-dots-blend);
|
|
||||||
background-repeat: repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--color-base-150);
|
|
||||||
color: var(--color-base-1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
.turbo-progress-bar {
|
|
||||||
height: 5px;
|
|
||||||
background-color: #b07751;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Vollkorn";
|
|
||||||
src: url("/fonts/Vollkorn-Bold.woff2") format("woff2");
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Noto Sans";
|
|
||||||
src: url("/fonts/NotoSans-Medium.woff2") format("woff2");
|
|
||||||
font-weight: medium;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Noto Sans";
|
|
||||||
src: url("/fonts/NotoSans-Bold.woff2") format("woff2");
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Angelic Agrippa";
|
|
||||||
src: url("/fonts/AngelicAgrippa-Regular.woff2") format("woff2");
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--font-body: "Noto Sans", sans-serif;
|
|
||||||
--font-headers: "Vollkorn", serif;
|
|
||||||
--font-angelic: "Angelic Agrippa", serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: var(--font-body);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6 {
|
|
||||||
font-family: var(--font-headers);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,7 +1,11 @@
|
||||||
---
|
---
|
||||||
import AppLayout from "layouts/AppLayout.astro";
|
import AppLayout from "pages/_components/AppLayout/AppLayout.astro";
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<AppLayout title="Archive">
|
<AppLayout title="Archive">
|
||||||
<div slot="subPanel">
|
<div slot="subPanel">
|
||||||
Besides physical medias, we also archive digital contents such as websites,
|
Besides physical medias, we also archive digital contents such as websites,
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
import AppLayout from "pages/_components/AppLayout/AppLayout.astro";
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<AppLayout title="Library">
|
||||||
|
<main slot="mainPanel"><h1>Contents</h1></main>
|
||||||
|
<div slot="subPanel">
|
||||||
|
All the contents (textual, audio, and video) from the Library or other
|
||||||
|
online sources.
|
||||||
|
</div>
|
||||||
|
</AppLayout>
|
|
@ -1,8 +1,12 @@
|
||||||
---
|
---
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
import AppLayout from "layouts/AppLayout.astro";
|
import AppLayout from "pages/_components/AppLayout/AppLayout.astro";
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<AppLayout title="Accord’s Library">
|
<AppLayout title="Accord’s Library">
|
||||||
<main slot="mainPanel">
|
<main slot="mainPanel">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
|
@ -46,6 +50,10 @@ import AppLayout from "layouts/AppLayout.astro";
|
||||||
</main>
|
</main>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
main {
|
main {
|
||||||
padding-left: 2.5rem;
|
padding-left: 2.5rem;
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
---
|
---
|
||||||
import AppLayout from "layouts/AppLayout.astro";
|
import AppLayout from "pages/_components/AppLayout/AppLayout.astro";
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<AppLayout title="Library">
|
<AppLayout title="Library">
|
||||||
<main slot="mainPanel"><h1>Library</h1></main>
|
<main slot="mainPanel"><h1>Library</h1></main>
|
||||||
<div slot="subPanel">
|
<div slot="subPanel">
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
---
|
---
|
||||||
import Html from "layouts/Html.astro";
|
import Html from "pages/_components/Html.astro";
|
||||||
import Navbar from "components/Navbar.astro";
|
import MenuPanel from "./components/MenuPanel.astro";
|
||||||
import MenuPanel from "components/MenuPanel.astro";
|
import Navbar from "./components/Navbar.astro";
|
||||||
|
import MenuPanelReduced from "./components/MenuPanelReduced.astro";
|
||||||
|
import { parseCookie } from "utils/astro";
|
||||||
|
import { CookieNames } from "utils/cookies";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -11,15 +14,32 @@ const { title } = Astro.props;
|
||||||
|
|
||||||
const turnSubPanelIntoMainPanel =
|
const turnSubPanelIntoMainPanel =
|
||||||
Astro.slots.has("subPanel") && !Astro.slots.has("mainPanel");
|
Astro.slots.has("subPanel") && !Astro.slots.has("mainPanel");
|
||||||
|
|
||||||
|
const isMenuPanelReduced = parseCookie<boolean>(
|
||||||
|
Astro.cookies.get(CookieNames.MENU_PANEL_REDUCED),
|
||||||
|
false
|
||||||
|
);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<Html title={title}>
|
<Html title={title}>
|
||||||
<div
|
<div
|
||||||
id="panels"
|
id="panels"
|
||||||
class:list={{ "turn-sub-into-main": turnSubPanelIntoMainPanel }}
|
class:list={{ "turn-sub-into-main": turnSubPanelIntoMainPanel }}
|
||||||
>
|
>
|
||||||
<div id="menu-panel" class="texture-dots">
|
<div
|
||||||
<MenuPanel />
|
id="menu-panel"
|
||||||
|
class:list={["texture-dots", { reduced: isMenuPanelReduced }]}
|
||||||
|
>
|
||||||
|
<div class="when-reduced">
|
||||||
|
<MenuPanelReduced />
|
||||||
|
</div>
|
||||||
|
<div class="when-not-reduced">
|
||||||
|
<MenuPanel />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sub-panel" class="texture-dots">
|
<div id="sub-panel" class="texture-dots">
|
||||||
|
@ -39,6 +59,10 @@ const turnSubPanelIntoMainPanel =
|
||||||
</div>
|
</div>
|
||||||
</Html>
|
</Html>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -51,39 +75,29 @@ const turnSubPanelIntoMainPanel =
|
||||||
grid-template-rows: 1fr 5rem;
|
grid-template-rows: 1fr 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > #navbar {
|
|
||||||
display: grid;
|
|
||||||
@media (width >= 60rem) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #panels {
|
& > #panels {
|
||||||
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@media (width >= 60rem) {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media (width < 60rem) {
|
@media (width < 60rem) {
|
||||||
&.turn-sub-into-main > #sub-panel {
|
&.turn-sub-into-main > #sub-panel {
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 0;
|
z-index: initial;
|
||||||
transition: initial;
|
transition: initial;
|
||||||
border: initial;
|
border: initial;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width >= 60rem) {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > #sub-panel {
|
& > #sub-panel {
|
||||||
@media (width < 60rem) {
|
@media (width < 60rem) {
|
||||||
right: -100%;
|
right: -100%;
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
transition: 0.2s right;
|
transition: 0.2s right;
|
||||||
z-index: 1;
|
|
||||||
border-left: var(--border-style);
|
border-left: var(--border-style);
|
||||||
|
|
||||||
&.opened {
|
&.opened {
|
||||||
|
@ -92,48 +106,99 @@ const turnSubPanelIntoMainPanel =
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width >= 60rem) {
|
@media (width >= 60rem) {
|
||||||
width: 20rem;
|
|
||||||
flex-shrink: 0;
|
|
||||||
border-right: var(--border-style);
|
border-right: var(--border-style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > #menu-panel {
|
& > #menu-panel {
|
||||||
|
border-right: var(--border-style);
|
||||||
background-position: top right;
|
background-position: top right;
|
||||||
flex-shrink: 0;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
@media (width < 60rem) {
|
@media (width < 60rem) {
|
||||||
left: -100%;
|
left: -100%;
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
transition: 0.2s left;
|
transition: 0.2s left;
|
||||||
z-index: 1;
|
|
||||||
border-right: var(--border-style);
|
|
||||||
|
|
||||||
&.opened {
|
&.opened {
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > .when-reduced {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width >=60rem) {
|
||||||
|
transition: 0.2s width;
|
||||||
|
|
||||||
|
&.reduced {
|
||||||
|
width: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.reduced > .when-not-reduced,
|
||||||
|
&:not(.reduced) > .when-reduced {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
display: grid;
|
||||||
|
align-content: start;
|
||||||
|
justify-items: center;
|
||||||
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > #main-panel {
|
& > #main-panel {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
@media (width < 60rem) {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > #menu-panel,
|
||||||
|
& > #sub-panel {
|
||||||
|
width: 20rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
@media (width < 60rem) {
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: min(30rem, 90%);
|
||||||
|
|
||||||
|
@media (width < 20rem) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
display: grid;
|
display: grid;
|
||||||
background-color: var(--color-base-150);
|
background-color: var(--color-base-150);
|
||||||
|
transition: 0.1s background-color;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 2rem;
|
||||||
|
|
||||||
&:empty {
|
&:empty {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (width < 60rem) {
|
& > #navbar {
|
||||||
position: absolute;
|
display: grid;
|
||||||
width: min(30rem, 90%);
|
place-items: center;
|
||||||
}
|
border-top: var(--border-style);
|
||||||
|
grid-template-columns: 5rem 1fr 5rem;
|
||||||
|
|
||||||
|
@media (width >= 60rem) {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
import { getLocalizedUrl } from "utils/urls";
|
||||||
|
import NavOption from "pages/_components/NavOption.astro";
|
||||||
|
import HorizontalLine from "pages/_components/HorizontalLine.astro";
|
||||||
|
import ReduceToggleButton from "./ReduceToggleButton.astro";
|
||||||
|
import ThemeToggleButton from "./ThemeToggleButton.astro";
|
||||||
|
|
||||||
|
const { locale = "en" } = Astro.params;
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<a
|
||||||
|
id="accords-logo"
|
||||||
|
data-turbo-confirm="Do you want to leave this page?"
|
||||||
|
href={getLocalizedUrl("/", locale)}
|
||||||
|
>
|
||||||
|
<Icon name="accords" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<p id="title">Accord’s Library</p>
|
||||||
|
|
||||||
|
<div id="buttons">
|
||||||
|
<ReduceToggleButton icon="material-symbols:chevron-left-rounded" />
|
||||||
|
<ThemeToggleButton />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
<NavOption
|
||||||
|
href="/library"
|
||||||
|
icon="material-symbols:auto-stories"
|
||||||
|
title="Library"
|
||||||
|
subtitle="Browse all physical and digital media"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOption
|
||||||
|
href="/contents"
|
||||||
|
icon="material-symbols:workspaces"
|
||||||
|
title="Content"
|
||||||
|
subtitle="Explore all content and filter by type or category"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOption
|
||||||
|
href="/wiki"
|
||||||
|
icon="material-symbols:travel-explore"
|
||||||
|
title="Wiki"
|
||||||
|
subtitle="An encyclopedia for everything related to DrakeNieR"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOption
|
||||||
|
href="/chronicles"
|
||||||
|
icon="material-symbols:schedule"
|
||||||
|
title="Chronicles"
|
||||||
|
subtitle="Experience all events and content in chronological order"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
<NavOption href="/news" icon="material-symbols:newspaper" title="News" />
|
||||||
|
|
||||||
|
<NavOption
|
||||||
|
href="https://gallery.accords-library.com/posts/"
|
||||||
|
icon="material-symbols:perm-media"
|
||||||
|
title="Gallery"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOption href="/archives" icon="material-symbols:save" title="Archives" />
|
||||||
|
|
||||||
|
<NavOption href="/about-us" icon="material-symbols:info" title="About us" />
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This website’s content is made available under <a
|
||||||
|
href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a
|
||||||
|
> unless otherwise noted.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="common-creative">
|
||||||
|
<Icon name="creative-commons-brands" />
|
||||||
|
<Icon name="creative-commons-by-brands" />
|
||||||
|
<Icon name="creative-commons-sa-brands" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Accord’s Library is not affiliated with or endorsed by SQUARE ENIX CO. LTD.
|
||||||
|
All game assets and promotional materials belongs to © SQUARE ENIX CO. LTD.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="social-links">
|
||||||
|
<Icon name="github-brands" />
|
||||||
|
<Icon name="x-brands" />
|
||||||
|
<Icon name="discord-brands" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#title {
|
||||||
|
font-family: var(--font-headers);
|
||||||
|
font-size: 1.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#accords-logo {
|
||||||
|
width: max(50%, 3rem);
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
color: var(--color-base-1000);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-base-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#common-creative {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
place-content: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#social-links {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
place-items: center;
|
||||||
|
gap: 2rem;
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,159 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
import { getLocalizedUrl } from "utils/urls";
|
||||||
|
import { CookieNames } from "utils/cookies";
|
||||||
|
import NavOptionIcon from "pages/_components/NavOptionIcon.astro";
|
||||||
|
import { parseCookie } from "utils/astro";
|
||||||
|
import HorizontalLine from "pages/_components/HorizontalLine.astro";
|
||||||
|
import ReduceToggleButton from "./ReduceToggleButton.astro";
|
||||||
|
|
||||||
|
const { locale = "en" } = Astro.params;
|
||||||
|
|
||||||
|
const themeColors = parseCookie<string>(
|
||||||
|
Astro.cookies.get(CookieNames.THEME_COLOR),
|
||||||
|
"theme-color-light"
|
||||||
|
);
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<a
|
||||||
|
id="accords-logo"
|
||||||
|
data-turbo-confirm="Do you want to leave this page?"
|
||||||
|
href={getLocalizedUrl("/", locale)}
|
||||||
|
>
|
||||||
|
<Icon name="accords" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div id="buttons">
|
||||||
|
<ReduceToggleButton icon="material-symbols:chevron-right-rounded" />
|
||||||
|
|
||||||
|
<button
|
||||||
|
class={themeColors === "theme-color-dark" ? "dark" : "light"}
|
||||||
|
id="theme-toggle"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
class="when-light"
|
||||||
|
name="material-symbols:light-mode"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
class="when-dark"
|
||||||
|
name="material-symbols:dark-mode"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
<NavOptionIcon
|
||||||
|
href="/library"
|
||||||
|
icon="material-symbols:auto-stories"
|
||||||
|
title="Library"
|
||||||
|
subtitle="Browse all physical and digital media"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOptionIcon
|
||||||
|
href="/contents"
|
||||||
|
icon="material-symbols:workspaces"
|
||||||
|
title="Content"
|
||||||
|
subtitle="Explore all content and filter by type or category"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOptionIcon
|
||||||
|
href="/wiki"
|
||||||
|
icon="material-symbols:travel-explore"
|
||||||
|
title="Wiki"
|
||||||
|
subtitle="An encyclopedia for everything related to DrakeNieR"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOptionIcon
|
||||||
|
href="/chronicles"
|
||||||
|
icon="material-symbols:schedule"
|
||||||
|
title="Chronicles"
|
||||||
|
subtitle="Experience all events and content in chronological order"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HorizontalLine />
|
||||||
|
|
||||||
|
<NavOptionIcon href="/news" icon="material-symbols:newspaper" title="News" />
|
||||||
|
|
||||||
|
<NavOptionIcon
|
||||||
|
href="https://gallery.accords-library.com/posts/"
|
||||||
|
icon="material-symbols:perm-media"
|
||||||
|
title="Gallery"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<NavOptionIcon href="/archives" icon="material-symbols:save" title="Archives" />
|
||||||
|
|
||||||
|
<NavOptionIcon href="/about-us" icon="material-symbols:info" title="About us" />
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#accords-logo {
|
||||||
|
width: 3rem;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
color: var(--color-base-1000);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-base-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
& > #theme-toggle.dark > .when-light,
|
||||||
|
& > #theme-toggle.light > .when-dark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* -------------------------------------------- JS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import tippy, { createSingleton } from "tippy.js";
|
||||||
|
import { onLoad } from "utils/turbo";
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
createSingleton(
|
||||||
|
tippy(".menu-panel-content > [data-tippy-template]", {
|
||||||
|
content: (reference) => {
|
||||||
|
const templateQuery = reference.getAttribute("data-tippy-template")!;
|
||||||
|
const template = reference.querySelector(templateQuery)!;
|
||||||
|
const container = document.createElement("div");
|
||||||
|
container.append(template.cloneNode(true));
|
||||||
|
container.style.fontSize = "90%";
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
allowHTML: true,
|
||||||
|
placement: "right",
|
||||||
|
delay: 250,
|
||||||
|
moveTransition: "transform 0.2s ease",
|
||||||
|
maxWidth: "18rem",
|
||||||
|
inertia: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,93 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
showSubPanel: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, showSubPanel } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<button id="toggle-menu-panel">
|
||||||
|
<Icon
|
||||||
|
class="when-off"
|
||||||
|
name="material-symbols:menu-rounded"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
class="when-on"
|
||||||
|
name="material-symbols:close-rounded"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<p>{title}</p>
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
showSubPanel && (
|
||||||
|
<button id="toggle-sub-panel">
|
||||||
|
<Icon
|
||||||
|
class="when-off"
|
||||||
|
name="material-symbols:tune-rounded"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
class="when-on"
|
||||||
|
name="material-symbols:close-rounded"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.on > .when-off,
|
||||||
|
:not(.on) > .when-on {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* -------------------------------------------- JS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Elementos } from "utils/Elementos";
|
||||||
|
import { observable } from "utils/micro-observables";
|
||||||
|
import { onLoad } from "utils/turbo";
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
const isMenuPanelOpened = observable(false);
|
||||||
|
const menuPanel = new Elementos("#menu-panel");
|
||||||
|
const menuPanelToggle = new Elementos("#toggle-menu-panel");
|
||||||
|
|
||||||
|
menuPanelToggle.onClick(() => {
|
||||||
|
isMenuPanelOpened.update((current) => !current);
|
||||||
|
isSubPanelOpened.set(false);
|
||||||
|
});
|
||||||
|
menuPanel.setClass("opened", isMenuPanelOpened);
|
||||||
|
menuPanelToggle.setClass("on", isMenuPanelOpened);
|
||||||
|
|
||||||
|
const isSubPanelOpened = observable(false);
|
||||||
|
const subPanel = new Elementos("#sub-panel");
|
||||||
|
const subPanelToggle = new Elementos("#toggle-sub-panel");
|
||||||
|
subPanelToggle.onClick(() => {
|
||||||
|
isSubPanelOpened.update((current) => !current);
|
||||||
|
isMenuPanelOpened.set(false);
|
||||||
|
});
|
||||||
|
subPanel.setClass("opened", isSubPanelOpened);
|
||||||
|
subPanelToggle.setClass("on", isSubPanelOpened);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { icon } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<button id="reduce-toggle">
|
||||||
|
<Icon name={icon} width={24} height={24} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* -------------------------------------------- JS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Elementos } from "utils/Elementos";
|
||||||
|
import { CookieNames } from "utils/cookies";
|
||||||
|
import { observableWithPersistence } from "utils/micro-observables";
|
||||||
|
import { onLoad } from "utils/turbo";
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
const toggleReducedButton = new Elementos("#reduce-toggle");
|
||||||
|
const menuPanel = new Elementos("#menu-panel");
|
||||||
|
|
||||||
|
const isReduced = observableWithPersistence(
|
||||||
|
CookieNames.MENU_PANEL_REDUCED,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
toggleReducedButton.onClick(() => {
|
||||||
|
isReduced.update((oldValue) => !oldValue);
|
||||||
|
Turbo.cache.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
menuPanel.setClass("reduced", isReduced);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,87 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
import { parseCookie } from "utils/astro";
|
||||||
|
import { CookieNames } from "utils/cookies";
|
||||||
|
|
||||||
|
const themeColors = parseCookie<string>(
|
||||||
|
Astro.cookies.get(CookieNames.THEME_COLOR),
|
||||||
|
"theme-color-light"
|
||||||
|
);
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<button
|
||||||
|
class={themeColors === "theme-color-dark" ? "dark" : "light"}
|
||||||
|
id="theme-toggle"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
class="when-light"
|
||||||
|
name="material-symbols:light-mode"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
class="when-dark"
|
||||||
|
name="material-symbols:dark-mode"
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#theme-toggle.dark > .when-light,
|
||||||
|
#theme-toggle.light > .when-dark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* -------------------------------------------- JS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Elementos } from "utils/Elementos";
|
||||||
|
import { CookieNames } from "utils/cookies";
|
||||||
|
import { observableWithPersistence } from "utils/micro-observables";
|
||||||
|
import { onLoad } from "utils/turbo";
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
const body = new Elementos("body");
|
||||||
|
const themeToggleButton = new Elementos("#theme-toggle");
|
||||||
|
|
||||||
|
const themeColor = observableWithPersistence(
|
||||||
|
CookieNames.THEME_COLOR,
|
||||||
|
"theme-color-light"
|
||||||
|
);
|
||||||
|
|
||||||
|
const isDarkMode = themeColor.select(
|
||||||
|
(value) => value === "theme-color-dark"
|
||||||
|
);
|
||||||
|
|
||||||
|
themeToggleButton.onClick(() => {
|
||||||
|
themeColor.update((oldValue) =>
|
||||||
|
oldValue === "theme-color-light"
|
||||||
|
? "theme-color-dark"
|
||||||
|
: "theme-color-light"
|
||||||
|
);
|
||||||
|
Turbo.cache.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
themeToggleButton.setClass(
|
||||||
|
{ ifFalse: "light", ifTrue: "dark" },
|
||||||
|
isDarkMode
|
||||||
|
);
|
||||||
|
|
||||||
|
body.setClass(
|
||||||
|
{ ifFalse: "theme-color-light", ifTrue: "theme-color-dark" },
|
||||||
|
isDarkMode
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
border-top: 3px dotted var(--color-base-1000);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,388 @@
|
||||||
|
---
|
||||||
|
import { parseCookie } from "utils/astro";
|
||||||
|
import { CookieNames } from "utils/cookies";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title } = Astro.props;
|
||||||
|
const themeColors = parseCookie(
|
||||||
|
Astro.cookies.get(CookieNames.THEME_COLOR),
|
||||||
|
"theme-color-light"
|
||||||
|
);
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>{title}</title>
|
||||||
|
<script is:inline src="/js/turbo.es2017-umd.js" async defer></script>
|
||||||
|
<link href="/css/sanitize.min.css" rel="stylesheet" />
|
||||||
|
<link href="/css/tippy.css" rel="stylesheet" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class={themeColors}>
|
||||||
|
<slot />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
/* RESET */
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
div,
|
||||||
|
span,
|
||||||
|
applet,
|
||||||
|
object,
|
||||||
|
iframe,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
blockquote,
|
||||||
|
pre,
|
||||||
|
a,
|
||||||
|
abbr,
|
||||||
|
acronym,
|
||||||
|
address,
|
||||||
|
big,
|
||||||
|
cite,
|
||||||
|
code,
|
||||||
|
del,
|
||||||
|
dfn,
|
||||||
|
em,
|
||||||
|
img,
|
||||||
|
ins,
|
||||||
|
kbd,
|
||||||
|
q,
|
||||||
|
s,
|
||||||
|
samp,
|
||||||
|
small,
|
||||||
|
strike,
|
||||||
|
strong,
|
||||||
|
sub,
|
||||||
|
sup,
|
||||||
|
tt,
|
||||||
|
var,
|
||||||
|
b,
|
||||||
|
u,
|
||||||
|
i,
|
||||||
|
center,
|
||||||
|
dl,
|
||||||
|
dt,
|
||||||
|
dd,
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li,
|
||||||
|
fieldset,
|
||||||
|
form,
|
||||||
|
label,
|
||||||
|
legend,
|
||||||
|
table,
|
||||||
|
caption,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
thead,
|
||||||
|
tr,
|
||||||
|
th,
|
||||||
|
td,
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
canvas,
|
||||||
|
details,
|
||||||
|
embed,
|
||||||
|
figure,
|
||||||
|
figcaption,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
main,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
output,
|
||||||
|
ruby,
|
||||||
|
section,
|
||||||
|
summary,
|
||||||
|
time,
|
||||||
|
mark,
|
||||||
|
audio,
|
||||||
|
video {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu,
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote,
|
||||||
|
q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote:before,
|
||||||
|
blockquote:after,
|
||||||
|
q:before,
|
||||||
|
q:after {
|
||||||
|
content: "";
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:where(button) {
|
||||||
|
background-color: inherit;
|
||||||
|
color: inherit;
|
||||||
|
border: initial;
|
||||||
|
padding: initial;
|
||||||
|
margin: initial;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* THEMING */
|
||||||
|
|
||||||
|
.theme-color-light {
|
||||||
|
--color-base-0: #ffffff;
|
||||||
|
--color-base-50: #fffaf3;
|
||||||
|
--color-base-100: #fff4e6;
|
||||||
|
--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-1: var(--color-base-100);
|
||||||
|
--color-elevation-0: var(--color-base-150);
|
||||||
|
|
||||||
|
--color-shadow: var(--color-base-500);
|
||||||
|
|
||||||
|
--texture-dots: url(/images/paper-dots.webp);
|
||||||
|
--texture-dots-blend: multiply;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-color-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-150: #27231e;
|
||||||
|
--color-base-100: #1c1b16;
|
||||||
|
--color-base-50: #11110d;
|
||||||
|
--color-base-0: #000000;
|
||||||
|
|
||||||
|
--color-elevation-1: var(--color-base-200);
|
||||||
|
--color-elevation-0: var(--color-base-150);
|
||||||
|
|
||||||
|
--color-shadow: var(--color-base-50);
|
||||||
|
|
||||||
|
--texture-dots: url(/images/paper-dots-dark.webp);
|
||||||
|
--texture-dots-blend: overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FONTS */
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Vollkorn";
|
||||||
|
src: url("/fonts/Vollkorn-Bold.woff2") format("woff2");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Noto Sans";
|
||||||
|
src: url("/fonts/NotoSans-Medium.woff2") format("woff2");
|
||||||
|
font-weight: medium;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Noto Sans";
|
||||||
|
src: url("/fonts/NotoSans-Bold.woff2") format("woff2");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Angelic Agrippa";
|
||||||
|
src: url("/fonts/AngelicAgrippa-Regular.woff2") format("woff2");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: var(--font-body);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-family: var(--font-headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-headers {
|
||||||
|
font-family: var(--font-headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-body {
|
||||||
|
font-family: var(--font-body);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-xs {
|
||||||
|
font-size: 0.75rem /* 12px */;
|
||||||
|
line-height: 1rem /* 16px */;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-sm {
|
||||||
|
font-size: 0.875rem /* 14px */;
|
||||||
|
line-height: 1.25rem /* 20px */;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-base {
|
||||||
|
font-size: 1rem /* 16px */;
|
||||||
|
line-height: 1.5rem /* 24px */;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-lg {
|
||||||
|
font-size: 1.125rem /* 18px */;
|
||||||
|
line-height: 1.75rem /* 28px */;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-xl {
|
||||||
|
font-size: 1.25rem /* 20px */;
|
||||||
|
line-height: 1.75rem /* 28px */;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-2xl {
|
||||||
|
font-size: 1.5rem /* 24px */;
|
||||||
|
line-height: 2rem /* 32px */;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-3xl {
|
||||||
|
font-size: 1.875rem /* 30px */;
|
||||||
|
line-height: 2.25rem /* 36px */;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GLOBAL */
|
||||||
|
|
||||||
|
* {
|
||||||
|
scrollbar-color: var(--color-base-600) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
background-color: transparent;
|
||||||
|
width: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--color-base-600);
|
||||||
|
border-radius: 9999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.texture-dots {
|
||||||
|
background-size: 10cm;
|
||||||
|
background-attachment: local;
|
||||||
|
background-image: var(--texture-dots);
|
||||||
|
background-blend-mode: var(--texture-dots-blend);
|
||||||
|
background-repeat: repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--color-base-150);
|
||||||
|
color: var(--color-base-1000);
|
||||||
|
font-size: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
color: var(--color-base-600);
|
||||||
|
border: 1px solid var(--color-base-600);
|
||||||
|
border-radius: 9999px;
|
||||||
|
padding: 0 1rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
transition-property: color, background-color, box-shadow, border-color;
|
||||||
|
transition-duration: 0.1s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-base-600);
|
||||||
|
color: var(--color-base-150);
|
||||||
|
box-shadow:
|
||||||
|
0 10px 15px -3px var(--color-shadow),
|
||||||
|
0 0 6px -4px var(--color-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: var(--color-base-1000);
|
||||||
|
color: var(--color-base-0);
|
||||||
|
border-color: var(--color-base-1000);
|
||||||
|
box-shadow:
|
||||||
|
0 10px 15px -3px var(--color-base-1000),
|
||||||
|
0 0 6px -4px var(--color-base-1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.turbo-progress-bar {
|
||||||
|
height: 5px;
|
||||||
|
background-color: #b07751;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--font-body: "Noto Sans", sans-serif;
|
||||||
|
--font-headers: "Vollkorn", serif;
|
||||||
|
--font-angelic: "Angelic Agrippa", serif;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -18,35 +18,30 @@ const currentPath = new URL(Astro.request.url).pathname.slice(
|
||||||
const isActive = currentPath.startsWith(href);
|
const isActive = currentPath.startsWith(href);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<a
|
<a
|
||||||
id="component"
|
id="component"
|
||||||
href={getLocalizedUrl(href, locale)}
|
href={getLocalizedUrl(href, locale)}
|
||||||
class:list={{ active: isActive }}
|
class:list={{ active: isActive }}
|
||||||
>
|
>
|
||||||
{icon && <Icon name={icon} />}
|
{icon && <Icon name={icon} />}
|
||||||
<div>
|
<div id="text-content">
|
||||||
<p id="title">
|
<p class="font-headers">
|
||||||
{title}
|
{title}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
{subtitle && <p>{subtitle}</p>}
|
||||||
{subtitle}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#component {
|
#component {
|
||||||
@container (max-width: 15rem) {
|
|
||||||
width: 3.5rem;
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
& > #title,
|
|
||||||
& > p {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: inherit;
|
text-decoration: inherit;
|
||||||
|
@ -76,19 +71,26 @@ const isActive = currentPath.startsWith(href);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > div {
|
@container (max-width: 15rem) {
|
||||||
display: grid;
|
width: 3.5rem;
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
& > #title {
|
& > #text-content {
|
||||||
line-height: 1.1;
|
display: none;
|
||||||
font-size: 1.5rem;
|
|
||||||
font-family: var(--font-headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#text-content {
|
||||||
|
display: grid;
|
||||||
|
flex-grow: 1;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
& > .font-headers {
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :not(.font-headers) {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -0,0 +1,93 @@
|
||||||
|
---
|
||||||
|
import { Icon } from "astro-icon/components";
|
||||||
|
import { getLocalizedUrl } from "utils/urls";
|
||||||
|
interface Props {
|
||||||
|
href: string;
|
||||||
|
icon?: string;
|
||||||
|
title: string | null | undefined;
|
||||||
|
subtitle?: string | null | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { locale } = Astro.params;
|
||||||
|
const { href, icon, title, subtitle } = Astro.props;
|
||||||
|
|
||||||
|
const currentPath = new URL(Astro.request.url).pathname.slice(
|
||||||
|
`/${locale}`.length
|
||||||
|
);
|
||||||
|
|
||||||
|
const isActive = currentPath.startsWith(href);
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- HTML ------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<a
|
||||||
|
id="component"
|
||||||
|
href={getLocalizedUrl(href, locale)}
|
||||||
|
class:list={{ active: isActive }}
|
||||||
|
data-tippy-template="#text-content"
|
||||||
|
>
|
||||||
|
{icon && <Icon name={icon} />}
|
||||||
|
<div id="text-content">
|
||||||
|
<p class="font-headers">
|
||||||
|
{title}
|
||||||
|
</p>
|
||||||
|
{subtitle && <p>{subtitle}</p>}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{
|
||||||
|
/* ------------------------------------------- CSS -------------------------------------------- */
|
||||||
|
}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#component {
|
||||||
|
padding: 1rem;
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: inherit;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
gap: 1.25rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
|
||||||
|
transition:
|
||||||
|
0.15s background-color,
|
||||||
|
0.15s box-shadow;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.active {
|
||||||
|
box-shadow: inset 0 1px 4px -2px var(--color-shadow);
|
||||||
|
background-color: var(--color-base-250);
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
box-shadow: inset 0 2px 4px 0 var(--color-shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > #text-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#text-content {
|
||||||
|
display: grid;
|
||||||
|
flex-grow: 1;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
& > .font-headers {
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :not(.font-headers) {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,13 +1,13 @@
|
||||||
import type { Observable } from "./micro-observables";
|
import type { Observable } from "./micro-observables";
|
||||||
|
|
||||||
export class Elementos {
|
export class Elementos {
|
||||||
readonly element: HTMLElement;
|
readonly element: NodeListOf<Element>;
|
||||||
constructor(readonly selector: string) {
|
constructor(readonly selector: string) {
|
||||||
this.element = document.querySelector(selector)!;
|
this.element = document.querySelectorAll(selector)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
onClick(listener: () => void) {
|
onClick(listener: () => void) {
|
||||||
this.element.addEventListener("click", listener);
|
this.element.forEach((e) => e.addEventListener("click", listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
setClass(
|
setClass(
|
||||||
|
@ -15,12 +15,14 @@ export class Elementos {
|
||||||
observable: Observable<boolean>
|
observable: Observable<boolean>
|
||||||
) {
|
) {
|
||||||
observable.subscribe((val) => {
|
observable.subscribe((val) => {
|
||||||
if (typeof className === "string") {
|
this.element.forEach((e) => {
|
||||||
this.element.classList.toggle(className, val);
|
if (typeof className === "string") {
|
||||||
} else {
|
e.classList.toggle(className, val);
|
||||||
this.element.classList.toggle(className.ifFalse, val === false);
|
} else {
|
||||||
this.element.classList.toggle(className.ifTrue, val === true);
|
e.classList.toggle(className.ifFalse, val === false);
|
||||||
}
|
e.classList.toggle(className.ifTrue, val === true);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { type AstroCookies } from "astro";
|
||||||
|
|
||||||
|
type AstroCookie = ReturnType<AstroCookies["get"]>;
|
||||||
|
|
||||||
|
export const parseCookie = <T>(cookies: AstroCookie, defaultValue: T): T => {
|
||||||
|
const value: T | null = JSON.parse(cookies?.value ?? "null");
|
||||||
|
return value ?? defaultValue;
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const customEvents = {
|
||||||
|
mainPanel: {
|
||||||
|
reduce: { toggle: "mainPanel.reduce.toggle" },
|
||||||
|
},
|
||||||
|
};
|
|
@ -5,8 +5,10 @@ export const observableWithPersistence = <T>(
|
||||||
cookieKey: string,
|
cookieKey: string,
|
||||||
defaultValue: T
|
defaultValue: T
|
||||||
): WritableObservable<T> => {
|
): WritableObservable<T> => {
|
||||||
const valueFromCookie = Cookies.get(cookieKey) as T | undefined;
|
const valueFromCookie: T | null = JSON.parse(
|
||||||
|
Cookies.get(cookieKey) ?? "null"
|
||||||
|
);
|
||||||
const obs = observable(valueFromCookie ?? defaultValue);
|
const obs = observable(valueFromCookie ?? defaultValue);
|
||||||
obs.subscribe((val) => Cookies.set(cookieKey, val as string));
|
obs.subscribe((val) => Cookies.set(cookieKey, JSON.stringify(val)));
|
||||||
return obs;
|
return obs;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue