Completely replaced theming. Now using arbitrary theming

This commit is contained in:
DrMint 2022-02-24 02:06:25 +01:00
parent 6d1bbc6ecb
commit 6604fa2929
18 changed files with 120 additions and 485 deletions

View File

@ -69,10 +69,10 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
const turnSubIntoContent = props.subPanel && !props.contentPanel;
return (
<div className={appLayout.darkMode ? "dark" : ""}>
<div className={appLayout.darkMode ? "set-theme-dark" : "set-theme-light"}>
<div
{...handlers}
className="fixed inset-0 touch-pan-y p-0 m-0 bg-light dark:bg-dark-light text-black dark:text-dark-black"
className="fixed inset-0 touch-pan-y p-0 m-0 bg-light text-black"
>
<Head>
<title>
@ -81,7 +81,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
</Head>
{/* Navbar */}
<div className="fixed inset-0 top-auto h-20 border-t-[1px] border-black dark:border-dark-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light dark:bg-dark-light texture-paper-dots">
<div className="fixed inset-0 top-auto h-20 border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots">
<span
className="material-icons mt-[.1em] cursor-pointer"
onClick={() => appLayout.setMainPanelOpen(true)}
@ -103,13 +103,13 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
{/* Content panel */}
<div
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light dark:bg-dark-light texture-paper-dots ${contentPanelClass}`}
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light texture-paper-dots ${contentPanelClass}`}
>
{props.contentPanel ? (
props.contentPanel
) : (
<div className="grid place-content-center h-full">
<div className="text-dark dark:text-dark-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40">
<div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40">
<p className="text-4xl"></p>
<p className="text-2xl w-64">
Select one of the options in the sidebar
@ -121,12 +121,12 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
{/* Background when navbar is opened */}
<div
className={`fixed bg-shade dark:bg-dark-shade inset-0 transition-opacity duration-500
className={`fixed bg-shade inset-0 transition-opacity duration-500
${turnSubIntoContent ? "z-10" : ""}
${
(appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile
? "opacity-60 dark:opacity-60"
: "opacity-0 dark:opacity-0 pointer-events-none touch-none"
? "opacity-60"
: "opacity-0 pointer-events-none touch-none"
}`}
onClick={() => {
appLayout.setMainPanelOpen(false);
@ -137,7 +137,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
{/* Sub panel */}
{props.subPanel ? (
<div
className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black dark:border-dark-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light dark:bg-dark-light texture-paper-dots
className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
${
turnSubIntoContent
? "mobile:translate-x-0 mobile:bottom-20 mobile:left-0 mobile:border-l-0"
@ -154,7 +154,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
{/* Main panel */}
<div
className={`${mainPanelClass} border-r-[1px] border-black dark:border-dark-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light dark:bg-dark-light texture-paper-dots
className={`${mainPanelClass} border-r-[1px] border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light texture-paper-dots
${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
>
<MainPanel langui={props.langui} />
@ -169,24 +169,24 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
appLayout.setMainPanelReduced(!appLayout.mainPanelReduced)
}
>
<Button className="material-icons bg-light dark:bg-dark-light !px-2">
<Button className="material-icons bg-light !px-2">
{appLayout.mainPanelReduced ? "chevron_right" : "chevron_left"}
</Button>
</div>
{/* Language selection background */}
<div
className={`fixed bg-shade dark:bg-dark-shade inset-0 transition-all duration-500 z-20 grid place-content-center ${
className={`fixed bg-shade inset-0 transition-all duration-500 z-20 grid place-content-center ${
appLayout.languagePanelOpen
? "bg-opacity-60 dark:bg-opacity-60"
: "bg-opacity-0 dark:bg-opacity-0 pointer-events-none touch-none"
? "bg-opacity-60"
: "bg-opacity-0 pointer-events-none touch-none"
}`}
onClick={() => {
appLayout.setLanguagePanelOpen(false);
}}
>
<div
className={`p-10 bg-light dark:bg-dark-light rounded-lg shadow-2xl shadow-shade dark:shadow-dark-shade grid gap-4 place-items-center transition-transform ${
className={`p-10 bg-light rounded-lg shadow-2xl shadow-shade grid gap-4 place-items-center transition-transform ${
appLayout.languagePanelOpen ? "scale-100" : "scale-0"
}`}
>
@ -214,7 +214,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
delayShow={300}
delayHide={100}
disable={!appLayout.mainPanelReduced || isMobile || isCoarse}
className="drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl !opacity-100 !bg-light dark:!bg-dark-light !rounded-lg after:!border-r-light text-left !text-black dark:!text-dark-black"
className="drop-shadow-shade-xl !opacity-100 !bg-light !rounded-lg after:!border-r-light text-left !text-black"
/>
</div>
</div>

View File

@ -16,12 +16,12 @@ export default function Button(props: ButtonProps): JSX.Element {
<div
id={props.id}
onClick={props.onClick}
className={`grid place-content-center place-items-center border-[1px] border-dark text-dark dark:text-dark-dark rounded-full px-4 pt-[0.4rem] pb-[0.5rem] transition-all ${
className={`grid place-content-center place-items-center border-[1px] border-dark text-dark rounded-full px-4 pt-[0.4rem] pb-[0.5rem] transition-all ${
props.className
} ${
props.active
? "text-light dark:text-dark-light bg-black dark:bg-dark-black drop-shadow-black-lg dark:drop-shadow-dark-black-lg !border-black dark:!border-dark-black cursor-not-allowed"
: "cursor-pointer hover:text-light dark:hover:text-dark-light hover:bg-dark dark:hover:bg-dark-dark hover:drop-shadow-shade-lg dark:hover:drop-shadow-dark-shade-lg active:bg-black dark:active:bg-dark-black active:drop-shadow-black-lg dark:active:drop-shadow-dark-black-lg active:border-black dark:active:border-dark-black"
? "text-light bg-black drop-shadow-black-lg !border-black cursor-not-allowed"
: "cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg active:bg-black active:drop-shadow-black-lg active:border-black"
}`}
>
{props.children}

View File

@ -53,7 +53,7 @@ export default function ChronologyItemComponent(
return (
<div
className="grid place-content-start grid-rows-[auto_1fr] grid-cols-[4em] py-4 px-8 rounded-2xl target:bg-mid dark:bg-dark-mid target:py-8 target:my-4"
className="grid place-content-start grid-rows-[auto_1fr] grid-cols-[4em] py-4 px-8 rounded-2xl target:bg-mid target:py-8 target:my-4"
id={generateAnchor(
props.item.attributes.year,
props.item.attributes.month,
@ -71,7 +71,7 @@ export default function ChronologyItemComponent(
""
)}
<p className="col-start-1 text-dark dark:text-dark-dark text-sm">
<p className="col-start-1 text-dark text-sm">
{generateDate(props.item.attributes.month, props.item.attributes.day)}
</p>
@ -86,7 +86,7 @@ export default function ChronologyItemComponent(
<p
className={
event.translations.length > 1
? "before:content-['-'] before:text-dark dark:before:text-dark-dark before:inline-block before:w-4 before:ml-[-1em] mt-2 whitespace-pre-line"
? "before:content-['-'] before:text-dark before:inline-block before:w-4 before:ml-[-1em] mt-2 whitespace-pre-line"
: "whitespace-pre-line"
}
>
@ -103,7 +103,7 @@ export default function ChronologyItemComponent(
</>
))}
<p className="text-dark dark:text-dark-dark text-xs inline-grid place-items-center grid-flow-col gap-1">
<p className="text-dark text-xs inline-grid place-items-center grid-flow-col gap-1">
{event.source.data ? (
"(" + event.source.data.attributes.name + ")"
) : (

View File

@ -11,7 +11,7 @@ export default function ChronologyYearComponent(
): JSX.Element {
return (
<div
className="target:bg-mid dark:bg-dark-mid rounded-2xl target:py-4 target:my-4"
className="target:bg-mid rounded-2xl target:py-4 target:my-4"
id={props.items.length > 1 ? props.year.toString() : undefined}
>
{props.items.map((item, index) => (

View File

@ -26,7 +26,7 @@ export default function ThumbnailHeader(
return (
<>
<div className="grid place-items-center gap-12 mb-12">
<div className="drop-shadow-shade-lg dark:drop-shadow-dark-shade-lg">
<div className="drop-shadow-shade-lg">
{content.thumbnail.data ? (
<Img
className=" rounded-xl"
@ -35,7 +35,7 @@ export default function ThumbnailHeader(
priority
/>
) : (
<div className="w-full aspect-[4/3] bg-light dark:bg-dark-light rounded-xl"></div>
<div className="w-full aspect-[4/3] bg-light rounded-xl"></div>
)}
</div>
<div className="grid place-items-center text-center">

View File

@ -7,7 +7,7 @@ export default function HorizontalLine(
): JSX.Element {
return (
<div
className={`h-0 w-full my-8 border-t-[3px] border-dotted border-black dark:border-dark-black ${props.className}`}
className={`h-0 w-full my-8 border-t-[3px] border-dotted border-black ${props.className}`}
></div>
);
}

View File

@ -8,7 +8,7 @@ export default function InsetBox(props: InsetBoxProps): JSX.Element {
return (
<div
id={props.id}
className={`w-full shadow-inner-sm shadow-shade dark:shadow-dark-shade bg-mid dark:bg-dark-mid rounded-xl p-8 ${props.className}`}
className={`w-full shadow-inner-sm shadow-shade bg-mid rounded-xl p-8 ${props.className}`}
>
{props.children}
</div>

View File

@ -21,7 +21,7 @@ export default function LibraryContentPreview(
return (
<Link href={"/contents/" + item.slug} passHref>
<div className="drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl cursor-pointer grid items-end fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform">
<div className="drop-shadow-shade-xl cursor-pointer grid items-end fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform">
{item.thumbnail.data ? (
<Img
className="rounded-md coarse:rounded-b-none"
@ -29,9 +29,9 @@ export default function LibraryContentPreview(
quality={ImageQuality.Medium}
/>
) : (
<div className="w-full aspect-[3/2] bg-light dark:bg-dark-light rounded-lg"></div>
<div className="w-full aspect-[3/2] bg-light rounded-lg"></div>
)}
<div className="linearbg-obi dark:linearbg-dark-obi fine:drop-shadow-shade-lg dark:fine:drop-shadow-dark-shade-lg fine:absolute coarse:rounded-b-md bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2">
<div className="linearbg-obi fine:drop-shadow-shade-lg fine:absolute coarse:rounded-b-md bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2">
<div className="grid grid-flow-col gap-1 overflow-hidden place-content-start">
{item.type ? (
<Chip>

View File

@ -25,7 +25,7 @@ export default function LibraryItemsPreview(
return (
<Link href={"/library/" + item.slug} passHref>
<div
className={`drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl cursor-pointer grid items-end hover:rounded-3xl fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform ${props.className}`}
className={`drop-shadow-shade-xl cursor-pointer grid items-end hover:rounded-3xl fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform ${props.className}`}
>
{item.thumbnail.data ? (
<Img
@ -33,10 +33,10 @@ export default function LibraryItemsPreview(
quality={ImageQuality.Medium}
/>
) : (
<div className="w-full aspect-[21/29.7] bg-light dark:bg-dark-light rounded-lg"></div>
<div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div>
)}
<div className="linearbg-obi dark:linearbg-dark-obi fine:drop-shadow-shade-lg dark:fine:drop-shadow-dark-shade-lg fine:absolute place-items-start bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2">
<div className="linearbg-obi fine:drop-shadow-shade-lg fine:absolute place-items-start bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2">
{item.metadata && item.metadata.length > 0 ? (
<div className="flex flex-row gap-1">
{item.metadata[0].__typename === "ComponentMetadataOther"

View File

@ -9,7 +9,7 @@ type ScenBreakProps = {
export default function Markdawn(props: ScenBreakProps): JSX.Element {
return (
<Markdown
className={`prose prose-p:text-justify text-black dark:text-dark-black ${props.className}`}
className={`prose prose-p:text-justify text-black ${props.className}`}
options={{
overrides: {
hr: {

View File

@ -6,7 +6,7 @@ export default function SceneBreak(props: ScenBreakProps): JSX.Element {
return (
<div
className={
"h-0 text-center text-3xl text-dark dark:text-dark-dark mt-16 mb-20" + " " + props.className
"h-0 text-center text-3xl text-dark mt-16 mb-20" + " " + props.className
}
>
* * *

View File

@ -16,10 +16,10 @@ type NavOptionProps = {
export default function NavOption(props: NavOptionProps): JSX.Element {
const router = useRouter();
const isActive = router.asPath.startsWith(props.url);
const divActive = "bg-mid dark:bg-dark-mid shadow-inner-sm shadow-shade dark:shadow-dark-shade";
const divActive = "bg-mid shadow-inner-sm shadow-shade";
const border =
"outline outline-mid dark:outline-dark-mid outline-2 outline-offset-[-2px] hover:outline-[transparent]";
const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid dark:hover:bg-dark-mid hover:shadow-inner-sm hover:shadow-shade dark:hover:shadow-dark-shade hover:active:shadow-inner hover:active:shadow-shade dark:hover:active:shadow-dark-shade transition-all ${
"outline outline-mid outline-2 outline-offset-[-2px] hover:outline-[transparent]";
const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid hover:shadow-inner-sm hover:shadow-shade hover:active:shadow-inner hover:active:shadow-shade transition-all ${
props.border ? border : ""
} ${isActive ? divActive : ""}`;

View File

@ -32,13 +32,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
onClick={() => appLayout.setMainPanelOpen(false)}
className={`${
appLayout.mainPanelReduced && isDesktop ? "w-12" : "w-1/2"
} cursor-pointer transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark`}
>
<SVG
src={"/icons/accords.svg"}
alt={"Logo of Accord's Library"}
/>
</div>
} aspect-square cursor-pointer transition-colors [mask:url('/icons/accords.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black hover:bg-dark mb-4`}
></div>
</Link>
{appLayout.mainPanelReduced && isDesktop ? (
@ -49,7 +44,9 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<div
className={`flex ${
appLayout.mainPanelReduced && isDesktop ? "mt-4 flex-col gap-3" : "flex-row"
appLayout.mainPanelReduced && isDesktop
? "flex-col gap-3"
: "flex-row"
} flex-wrap gap-2`}
>
<Button
@ -186,25 +183,13 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
)}
</p>
<a
className="transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark"
className="transition-[filter] colorize-black hover:colorize-dark"
href="https://creativecommons.org/licenses/by-sa/4.0/"
>
<div className="mt-4 mb-8 grid grid-flow-col place-content-center gap-1">
<SVG
className="w-6"
src={"/icons/creative-commons-brands.svg"}
alt={""}
/>
<SVG
className="w-6"
src={"/icons/creative-commons-by-brands.svg"}
alt={""}
/>
<SVG
className="w-6"
src={"/icons/creative-commons-sa-brands.svg"}
alt={""}
/>
<div className="mt-4 mb-8 grid grid-flow-col place-content-center gap-1 hover:[--theme-color-black:var(--theme-color-dark)]">
<div className="w-6 aspect-square [mask:url('/icons/creative-commons-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black" />
<div className="w-6 aspect-square [mask:url('/icons/creative-commons-by-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black" />
<div className="w-6 aspect-square [mask:url('/icons/creative-commons-sa-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black" />
</div>
</a>
<p>
@ -216,21 +201,17 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
</p>
<div className="mt-12 mb-4 grid h-4 grid-flow-col place-content-center gap-8">
<a
className="transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark"
className="transition-colors [mask:url('/icons/github-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] w-10 aspect-square bg-black hover:bg-dark"
href="https://github.com/Accords-Library"
target="_blank"
rel="noopener noreferrer"
>
<SVG className="w-10" src={"/icons/github-brands.svg"} alt={""} />
</a>
></a>
<a
className="transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark"
className="transition-colors [mask:url('/icons/discord-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] w-10 aspect-square bg-black hover:bg-dark"
href="/discord"
target="_blank"
rel="noopener noreferrer"
>
<SVG className="w-10" src={"/icons/discord-brands.svg"} alt={""} />
</a>
></a>
</div>
</div>
</div>

View File

@ -43,7 +43,7 @@ export default function Editor(props: EditorProps): JSX.Element {
<textarea
id="editorTextArea"
onInput={handleInput}
className="bg-mid dark:bg-dark-mid rounded-xl p-8 w-full font-monospace"
className="bg-mid rounded-xl p-8 w-full font-monospace"
value={markdown}
/>
@ -71,12 +71,12 @@ export default function Editor(props: EditorProps): JSX.Element {
target.select();
event.preventDefault();
}}
className="bg-mid dark:bg-dark-mid rounded-xl p-8 w-full font-monospace"
className="bg-mid rounded-xl p-8 w-full font-monospace"
/>
</div>
<div>
<h2>Preview</h2>
<div className="bg-mid dark:bg-dark-mid rounded-xl p-8">
<div className="bg-mid rounded-xl p-8">
<Markdawn className="max-w-full" text={markdown} />
</div>
</div>

View File

@ -13,12 +13,8 @@ export default function Home(props: HomeProps): JSX.Element {
const contentPanel = (
<ContentPanel autoformat>
<div className="grid place-items-center place-content-center w-full gap-5 text-center colorize-black dark:colorize-dark-black">
<SVG
className="w-32 mobile:w-1/2"
src={"/icons/accords.svg"}
alt={"Logo of Accord's Library"}
/>
<div className="grid place-items-center place-content-center w-full gap-5 text-center">
<div className="[mask:url('/icons/accords.svg')] [mask-size:contain] [mask-repeat:no-repeat] [mask-position:center] w-32 aspect-square mobile:w-[50vw] bg-black" />
<h1 className="text-5xl mb-0">Accord&rsquo;s Library</h1>
<h2 className="mt-0">Discover Analyse Translate Archive</h2>
</div>

View File

@ -115,7 +115,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
const contentPanel = (
<ContentPanel width={ContentPanelWidthSizes.large}>
<div className="grid place-items-center gap-12">
<div className="drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl w-full h-[50vh] mobile:h-[80vh] mb-16 relative cursor-pointer">
<div className="drop-shadow-shade-xl w-full h-[50vh] mobile:h-[80vh] mb-16 relative cursor-pointer">
{item.thumbnail.data ? (
<Img
image={item.thumbnail.data.attributes}
@ -125,7 +125,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
priority
/>
) : (
<div className="w-full aspect-[21/29.7] bg-light dark:bg-dark-light rounded-xl"></div>
<div className="w-full aspect-[21/29.7] bg-light rounded-xl"></div>
)}
</div>
@ -172,7 +172,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
key={galleryItem.id}
className="relative aspect-square hover:scale-[1.02] transition-transform cursor-pointer"
>
<div className="bg-light dark:bg-dark-light absolute inset-0 rounded-lg drop-shadow-shade-md dark:drop-shadow-dark-shade-md"></div>
<div className="bg-light absolute inset-0 rounded-lg drop-shadow-shade-md"></div>
<Img
className="rounded-lg"
image={galleryItem.attributes}
@ -374,7 +374,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
<div
id={content.attributes.slug}
key={content.id}
className="grid gap-2 px-4 rounded-lg target:bg-mid dark:target:bg-dark-mid target:shadow-inner-sm target:shadow-shade dark:target:shadow-dark-shade target:h-auto target:py-3 target:my-2 target:[--displaySubContentMenu:grid] [--displaySubContentMenu:none]"
className="grid gap-2 px-4 rounded-lg target:bg-mid target:shadow-inner-sm target:shadow-shade target:h-auto target:py-3 target:my-2 target:[--displaySubContentMenu:grid] [--displaySubContentMenu:none]"
>
<div className="grid gap-4 place-items-center grid-cols-[auto_auto_1fr_auto_12ch] thin:grid-cols-[auto_auto_1fr_auto]">
<a href={`#${content.attributes.slug}`}>
@ -402,7 +402,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
)
)}
</div>
<p className="border-b-2 h-4 w-full border-black dark:border-dark-black border-dotted opacity-30"></p>
<p className="border-b-2 h-4 w-full border-black border-dotted opacity-30"></p>
<p>
{content.attributes.range[0].__typename ===
"ComponentRangePageRange"
@ -425,7 +425,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
)}
</div>
<div className="grid-flow-col place-content-start place-items-center gap-2 [display:var(--displaySubContentMenu)]">
<span className="material-icons text-dark dark:text-dark-dark">
<span className="material-icons text-dark">
subdirectory_arrow_right
</span>

View File

@ -17,17 +17,17 @@
}
a {
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark dark:decoration-dark-dark hover:text-dark dark:hover:text-dark-dark;
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark;
}
*::selection {
@apply bg-dark dark:bg-dark-dark text-light dark:text-dark-light;
@apply bg-dark text-light;
}
/* SCROLLBARS STYLING */
* {
@apply [scrollbar-color:theme(colors.dark)_transparent] dark:[scrollbar-color:theme(colors.dark-dark)_transparent] [scrollbar-width:thin];
@apply [scrollbar-color:theme(colors.dark)_transparent] [scrollbar-width:thin];
}
*::-webkit-scrollbar {
@ -35,11 +35,11 @@
}
*::-webkit-scrollbar-track {
@apply bg-light dark:bg-dark-light;
@apply bg-light;
}
*::-webkit-scrollbar-thumb {
@apply bg-dark dark:bg-dark-dark rounded-full border-[3px] border-solid border-light dark:border-dark-light;
@apply bg-dark rounded-full border-[3px] border-solid border-light;
}
/* CHANGE PROSE DEFAULTS */
@ -54,11 +54,11 @@
.prose h6,
.prose a,
.prose strong {
@apply text-black dark:text-dark-black;
@apply text-black;
}
.prose a {
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark dark:decoration-dark-dark hover:text-dark dark:hover:text-dark-dark;
@apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark;
}
.prose footer {
@ -70,12 +70,12 @@
}
.prose footer > div:target {
@apply bg-mid dark:bg-dark-mid shadow-inner-sm shadow-shade dark:shadow-dark-shade;
@apply bg-mid shadow-inner-sm shadow-shade;
}
}
@layer components {
.texture-paper-dots {
@apply bg-paper-dots dark:bg-dark-paper-dots bg-blend-multiply dark:bg-blend-overlay bg-local bg-[length:10cm];
@apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm];
}
}

View File

@ -20,24 +20,25 @@ const breakThin = { max: "25rem" };
/* END CONFIG */
function withOpacity(variableName) {
return ({ opacityValue }) => {
if (opacityValue) {
return `rgba(var(${variableName}), ${opacityValue})`;
}
return `rgb(var(${variableName}))`;
};
}
module.exports = {
darkMode: "class",
content: ["./src/**/*.{tsx,ts}"],
theme: {
colors: {
light: `rgb(${light.r}, ${light.g}, ${light.b})`,
mid: `rgb(${mid.r}, ${mid.g}, ${mid.b})`,
dark: `rgb(${dark.r}, ${dark.g}, ${dark.b})`,
shade: `rgb(${shade.r}, ${shade.g}, ${shade.b})`,
black: `rgb(${black.r}, ${black.g}, ${black.b})`,
// Dark mode
"dark-light": `rgb(${dark_light.r}, ${dark_light.g}, ${dark_light.b})`,
"dark-mid": `rgb(${dark_mid.r}, ${dark_mid.g}, ${dark_mid.b})`,
"dark-dark": `rgb(${dark_dark.r}, ${dark_dark.g}, ${dark_dark.b})`,
"dark-shade": `rgb(${dark_shade.r}, ${dark_shade.g}, ${dark_shade.b})`,
"dark-black": `rgb(${dark_black.r}, ${dark_black.g}, ${dark_black.b})`,
light: withOpacity("--theme-color-light"),
mid: withOpacity("--theme-color-mid"),
dark: withOpacity("--theme-color-dark"),
shade: withOpacity("--theme-color-shade"),
black: withOpacity("--theme-color-black"),
},
fontFamily: {
body: ["Zen Maru Gothic"],
@ -51,10 +52,6 @@ module.exports = {
coarse: { raw: "(pointer: coarse)" },
fine: { raw: "(pointer: fine)" },
},
backgroundImage: {
"paper-dots": "url('/paper-dots.webp')",
"dark-paper-dots": "url('/paper-dots-dark.webp')",
},
extend: {
boxShadow: {
"inner-sm": "inset 0 1px 4px -2px",
@ -64,6 +61,30 @@ module.exports = {
plugins: [
require("@tailwindcss/typography"),
// Colored Dropshadow
plugin(function ({ addUtilities }) {
addUtilities({
".set-theme-light": {
"--theme-color-light": `${light.r}, ${light.g}, ${light.b}`,
"--theme-color-mid": `${mid.r}, ${mid.g}, ${mid.b}`,
"--theme-color-dark": `${dark.r}, ${dark.g}, ${dark.b}`,
"--theme-color-shade": `${shade.r}, ${shade.g}, ${shade.b}`,
"--theme-color-black": `${black.r}, ${black.g}, ${black.b}`,
"--theme-texture-dots": `url("/paper-dots.webp")`,
"--theme-texture-dots-blend": `multiply`,
},
".set-theme-dark": {
"--theme-color-light": `${dark_light.r}, ${dark_light.g}, ${dark_light.b}`,
"--theme-color-mid": `${dark_mid.r}, ${dark_mid.g}, ${dark_mid.b}`,
"--theme-color-dark": `${dark_dark.r}, ${dark_dark.g}, ${dark_dark.b}`,
"--theme-color-shade": `${dark_shade.r}, ${dark_shade.g}, ${dark_shade.b}`,
"--theme-color-black": `${dark_black.r}, ${dark_black.g}, ${dark_black.b}`,
"--theme-texture-dots": `url("/paper-dots-dark.webp")`,
"--theme-texture-dots-blend": `overlay`,
},
});
}),
plugin(function ({ addVariant, e }) {
addVariant("webkit-scrollbar", ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
@ -74,94 +95,33 @@ module.exports = {
});
}),
// Colorization thanks to https://codepen.io/sosuke/pen/Pjoqqp
plugin(function ({ addUtilities }) {
addUtilities({
".colorize-light": {
filter: getFilterRecipe(light),
},
".colorize-mid": {
filter: getFilterRecipe(mid),
},
".colorize-dark": {
filter: getFilterRecipe(dark),
},
".colorize-black": {
filter: getFilterRecipe(black),
},
// Dark mode
".colorize-dark-light": {
filter: getFilterRecipe(dark_light),
},
".colorize-dark-mid": {
filter: getFilterRecipe(dark_mid),
},
".colorize-dark-dark": {
filter: getFilterRecipe(dark_dark),
},
".colorize-dark-black": {
filter: getFilterRecipe(dark_black),
},
});
}),
// Colored Dropshadow
plugin(function ({ addUtilities }) {
addUtilities({
".drop-shadow-shade-md": {
filter: `drop-shadow(0 4px 3px rgb(${shade.r} ${shade.g} ${shade.b} / 0.15)) drop-shadow(0 2px 2px rgb(${shade.r} ${shade.g} ${shade.b} / 0.2))`,
filter: `drop-shadow(0 4px 3px rgba(var(--theme-color-shade), 0.15)) drop-shadow(0 2px 2px rgba(var(--theme-color-shade), 0.2))`,
},
".drop-shadow-shade-lg": {
filter: `drop-shadow(0 10px 8px rgb(${shade.r} ${shade.g} ${shade.b} / 0.2)) drop-shadow(0 4px 3px rgb(${shade.r} ${shade.g} ${shade.b} / 0.4))`,
filter: `drop-shadow(0 10px 8px rgba(var(--theme-color-shade), 0.2)) drop-shadow(0 4px 3px rgba(var(--theme-color-shade), 0.4))`,
},
".drop-shadow-shade-xl": {
filter: `drop-shadow(0 20px 13px rgb(${shade.r} ${shade.g} ${shade.b} / 0.25)) drop-shadow(0 8px 5px rgb(${shade.r} ${shade.g} ${shade.b} / 0.7))`,
filter: `drop-shadow(0 20px 13px rgba(var(--theme-color-shade), 0.25)) drop-shadow(0 8px 5px rgba(var(--theme-color-shade), 0.7))`,
},
".drop-shadow-shade-2xl": {
filter: `drop-shadow(0 25px 25px rgb(${shade.r} ${shade.g} ${shade.b} / 0.8))`,
filter: `drop-shadow(0 25px 25px rgba(var(--theme-color-shade), 0.8))`,
},
".drop-shadow-black-md": {
filter: `drop-shadow(0 4px 3px rgb(${black.r} ${black.g} ${black.b} / 0.15)) drop-shadow(0 2px 2px rgb(${black.r} ${black.g} ${black.b} / 0.2))`,
filter: `drop-shadow(0 4px 3px rgba(var(--theme-color-black), 0.15)) drop-shadow(0 2px 2px rgba(var(--theme-color-black), 0.2))`,
},
".drop-shadow-black-lg": {
filter: `drop-shadow(0 10px 8px rgb(${black.r} ${black.g} ${black.b} / 0.2)) drop-shadow(0 4px 3px rgb(${black.r} ${black.g} ${black.b} / 0.4))`,
filter: `drop-shadow(0 10px 8px rgba(var(--theme-color-black), 0.2)) drop-shadow(0 4px 3px rgba(var(--theme-color-black), 0.4))`,
},
".drop-shadow-black-xl": {
filter: `drop-shadow(0 20px 13px rgb(${black.r} ${black.g} ${black.b} / 0.25)) drop-shadow(0 8px 5px rgb(${black.r} ${black.g} ${black.b} / 0.7))`,
filter: `drop-shadow(0 20px 13px rgba(var(--theme-color-black), 0.25)) drop-shadow(0 8px 5px rgba(var(--theme-color-black), 0.7))`,
},
".drop-shadow-black-2xl": {
filter: `drop-shadow(0 25px 25px rgb(${black.r} ${black.g} ${black.b} / 0.8))`,
},
// Dark mode
".drop-shadow-dark-shade-md": {
filter: `drop-shadow(0 4px 3px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.15)) drop-shadow(0 2px 2px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.2))`,
},
".drop-shadow-dark-shade-lg": {
filter: `drop-shadow(0 10px 8px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.2)) drop-shadow(0 4px 3px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.4))`,
},
".drop-shadow-dark-shade-xl": {
filter: `drop-shadow(0 20px 13px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.25)) drop-shadow(0 8px 5px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.7))`,
},
".drop-shadow-dark-shade-2xl": {
filter: `drop-shadow(0 25px 25px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.8))`,
},
".drop-shadow-dark-black-md": {
filter: `drop-shadow(0 4px 3px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.15)) drop-shadow(0 2px 2px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.2))`,
},
".drop-shadow-dark-black-lg": {
filter: `drop-shadow(0 10px 8px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.2)) drop-shadow(0 4px 3px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.4))`,
},
".drop-shadow-dark-black-xl": {
filter: `drop-shadow(0 20px 13px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.25)) drop-shadow(0 8px 5px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.7))`,
},
".drop-shadow-dark-black-2xl": {
filter: `drop-shadow(0 25px 25px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.8))`,
filter: `drop-shadow(0 25px 25px rgba(var(--theme-color-black), 0.8))`,
},
});
}),
@ -170,311 +130,9 @@ module.exports = {
addUtilities({
".linearbg-obi": {
background:
"linear-gradient(to right, theme('colors.mid'), theme('colors.light') 3%, theme('colors.light') 97%, theme('colors.mid'))",
},
".linearbg-dark-obi": {
background:
"linear-gradient(to right, theme('colors.dark-mid'), theme('colors.dark-light') 3%, theme('colors.dark-light') 97%, theme('colors.dark-mid'))",
"linear-gradient(to right, rgb(var(--theme-color-mid)), rgb(var(--theme-color-light)) 3%, rgb(var(--theme-color-light)) 97%, rgb(var(--theme-color-mid)))",
},
});
}),
],
};
/*
The following is taken from https://codepen.io/sosuke/pen/Pjoqqp
Used for colorizing any element using filters.
*/
function getFilterRecipe(rgb) {
const color = new FilterColorTransform(rgb.r, rgb.g, rgb.b);
const solver = new Solver(color);
const result = solver.solve();
return result;
}
class FilterColorTransform {
constructor(r, g, b) {
this.set(r, g, b);
}
set(r, g, b) {
this.r = this.clamp(r);
this.g = this.clamp(g);
this.b = this.clamp(b);
}
hueRotate(angle = 0) {
angle = (angle / 180) * Math.PI;
const sin = Math.sin(angle);
const cos = Math.cos(angle);
this.multiply([
0.213 + cos * 0.787 - sin * 0.213,
0.715 - cos * 0.715 - sin * 0.715,
0.072 - cos * 0.072 + sin * 0.928,
0.213 - cos * 0.213 + sin * 0.143,
0.715 + cos * 0.285 + sin * 0.14,
0.072 - cos * 0.072 - sin * 0.283,
0.213 - cos * 0.213 - sin * 0.787,
0.715 - cos * 0.715 + sin * 0.715,
0.072 + cos * 0.928 + sin * 0.072,
]);
}
grayscale(value = 1) {
this.multiply([
0.2126 + 0.7874 * (1 - value),
0.7152 - 0.7152 * (1 - value),
0.0722 - 0.0722 * (1 - value),
0.2126 - 0.2126 * (1 - value),
0.7152 + 0.2848 * (1 - value),
0.0722 - 0.0722 * (1 - value),
0.2126 - 0.2126 * (1 - value),
0.7152 - 0.7152 * (1 - value),
0.0722 + 0.9278 * (1 - value),
]);
}
sepia(value = 1) {
this.multiply([
0.393 + 0.607 * (1 - value),
0.769 - 0.769 * (1 - value),
0.189 - 0.189 * (1 - value),
0.349 - 0.349 * (1 - value),
0.686 + 0.314 * (1 - value),
0.168 - 0.168 * (1 - value),
0.272 - 0.272 * (1 - value),
0.534 - 0.534 * (1 - value),
0.131 + 0.869 * (1 - value),
]);
}
saturate(value = 1) {
this.multiply([
0.213 + 0.787 * value,
0.715 - 0.715 * value,
0.072 - 0.072 * value,
0.213 - 0.213 * value,
0.715 + 0.285 * value,
0.072 - 0.072 * value,
0.213 - 0.213 * value,
0.715 - 0.715 * value,
0.072 + 0.928 * value,
]);
}
multiply(matrix) {
const newR = this.clamp(
this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2]
);
const newG = this.clamp(
this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5]
);
const newB = this.clamp(
this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8]
);
this.r = newR;
this.g = newG;
this.b = newB;
}
brightness(value = 1) {
this.linear(value);
}
contrast(value = 1) {
this.linear(value, -(0.5 * value) + 0.5);
}
linear(slope = 1, intercept = 0) {
this.r = this.clamp(this.r * slope + intercept * 255);
this.g = this.clamp(this.g * slope + intercept * 255);
this.b = this.clamp(this.b * slope + intercept * 255);
}
invert(value = 1) {
this.r = this.clamp((value + (this.r / 255) * (1 - 2 * value)) * 255);
this.g = this.clamp((value + (this.g / 255) * (1 - 2 * value)) * 255);
this.b = this.clamp((value + (this.b / 255) * (1 - 2 * value)) * 255);
}
hsl() {
// Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA.
const r = this.r / 255;
const g = this.g / 255;
const b = this.b / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h,
s,
l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return {
h: h * 100,
s: s * 100,
l: l * 100,
};
}
clamp(value) {
if (value > 255) {
value = 255;
} else if (value < 0) {
value = 0;
}
return value;
}
}
class Solver {
constructor(target) {
this.target = target;
this.targetHSL = target.hsl();
this.reusedColor = new FilterColorTransform(0, 0, 0);
}
solve() {
const result = this.solveNarrow(this.solveWide());
return this.css(result.values);
}
solveWide() {
const A = 5;
const c = 15;
const a = [60, 180, 18000, 600, 1.2, 1.2];
let best = { loss: Infinity };
for (let i = 0; best.loss > 25 && i < 3; i++) {
const initial = [50, 20, 3750, 50, 100, 100];
const result = this.spsa(A, a, c, initial, 1000);
if (result.loss < best.loss) {
best = result;
}
}
return best;
}
solveNarrow(wide) {
const A = wide.loss;
const c = 2;
const A1 = A + 1;
const a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1];
return this.spsa(A, a, c, wide.values, 500);
}
spsa(A, a, c, values, iters) {
const alpha = 1;
const gamma = 0.16666666666666666;
let best = null;
let bestLoss = Infinity;
const deltas = new Array(6);
const highArgs = new Array(6);
const lowArgs = new Array(6);
for (let k = 0; k < iters; k++) {
const ck = c / Math.pow(k + 1, gamma);
for (let i = 0; i < 6; i++) {
deltas[i] = Math.random() > 0.5 ? 1 : -1;
highArgs[i] = values[i] + ck * deltas[i];
lowArgs[i] = values[i] - ck * deltas[i];
}
const lossDiff = this.loss(highArgs) - this.loss(lowArgs);
for (let i = 0; i < 6; i++) {
const g = (lossDiff / (2 * ck)) * deltas[i];
const ak = a[i] / Math.pow(A + k + 1, alpha);
values[i] = fix(values[i] - ak * g, i);
}
const loss = this.loss(values);
if (loss < bestLoss) {
best = values.slice(0);
bestLoss = loss;
}
}
return { values: best, loss: bestLoss };
function fix(value, idx) {
let max = 100;
if (idx === 2 /* saturate */) {
max = 7500;
} else if (idx === 4 /* brightness */ || idx === 5 /* contrast */) {
max = 200;
}
if (idx === 3 /* hue-rotate */) {
if (value > max) {
value %= max;
} else if (value < 0) {
value = max + (value % max);
}
} else if (value < 0) {
value = 0;
} else if (value > max) {
value = max;
}
return value;
}
}
loss(filters) {
// Argument is array of percentages.
const color = this.reusedColor;
color.set(0, 0, 0);
color.invert(filters[0] / 100);
color.sepia(filters[1] / 100);
color.saturate(filters[2] / 100);
color.hueRotate(filters[3] * 3.6);
color.brightness(filters[4] / 100);
color.contrast(filters[5] / 100);
const colorHSL = color.hsl();
return (
Math.abs(color.r - this.target.r) +
Math.abs(color.g - this.target.g) +
Math.abs(color.b - this.target.b) +
Math.abs(colorHSL.h - this.targetHSL.h) +
Math.abs(colorHSL.s - this.targetHSL.s) +
Math.abs(colorHSL.l - this.targetHSL.l)
);
}
css(filters) {
function fmt(idx, multiplier = 1) {
return Math.round(filters[idx] * multiplier);
}
return `
brightness(0)
saturate(100%)
invert(${fmt(0)}%)
sepia(${fmt(1)}%)
saturate(${fmt(2)}%)
hue-rotate(${fmt(3, 3.6)}deg)
brightness(${fmt(4)}%)
contrast(${fmt(5)}%);
`;
}
}