diff --git a/content/system/navigation.json b/content/system/navigation.json
new file mode 100644
index 0000000..1d4bb5e
--- /dev/null
+++ b/content/system/navigation.json
@@ -0,0 +1,142 @@
+{
+ "items": [
+ {
+ "name": "Metatron",
+ "path": "/meta",
+ "gridPosition": "area_1",
+ "variant": "meta",
+ "sublinks": {
+ "discriminant": false
+ },
+ "subtitle": {
+ "discriminant": false
+ }
+ },
+ {
+ "name": "Kitchensink",
+ "path": "/",
+ "gridPosition": "area_2",
+ "variant": "kitchensink",
+ "sublinks": {
+ "discriminant": true,
+ "value": [
+ {
+ "name": "The Pomarj",
+ "path": "/kitchensink/the-pomarj"
+ },
+ {
+ "name": "Burning Pavis",
+ "path": "/kitchensink/burning-pavis"
+ },
+ {
+ "name": "SLA Armies",
+ "path": "/kitchensink/sla-armies"
+ }
+ ]
+ },
+ "subtitle": {
+ "discriminant": false
+ }
+ },
+ {
+ "name": "AWQ",
+ "path": "/awq",
+ "gridPosition": "area_3",
+ "variant": "awq",
+ "sublinks": {
+ "discriminant": true,
+ "value": [
+ {
+ "name": "The Crunch",
+ "path": "/awq/core-rules"
+ },
+ {
+ "name": "Sigmar's Heirs",
+ "path": "/awq/character"
+ },
+ {
+ "name": "Armory",
+ "path": "/awq/equipment"
+ },
+ {
+ "name": "The Winds of Magic",
+ "path": "/awq/magic"
+ },
+ {
+ "name": "Beastiary",
+ "path": "/awq/bestiary"
+ },
+ {
+ "name": "Duveldal",
+ "path": "/awq/pregens"
+ },
+ {
+ "name": "Plundered Vaults",
+ "path": "/awq/expansions"
+ },
+ {
+ "name": "Tools",
+ "path": "/awq/tools"
+ }
+ ]
+ },
+ "subtitle": {
+ "discriminant": false
+ }
+ },
+ {
+ "name": "Worldburner",
+ "path": "/worldburner",
+ "gridPosition": "area_4",
+ "variant": "worldburner",
+ "sublinks": {
+ "discriminant": true,
+ "value": [
+ {
+ "name": "Burning Lands",
+ "path": "/worldburner/geography"
+ },
+ {
+ "name": "Burning People",
+ "path": "/worldburner/cultures"
+ },
+ {
+ "name": "Burning Faiths",
+ "path": "/worldburner/religion"
+ },
+ {
+ "name": "Burning Witches",
+ "path": "/worldburner/magic"
+ },
+ {
+ "name": "Burning Realms",
+ "path": "/worldburner/states"
+ }
+ ]
+ },
+ "subtitle": {
+ "discriminant": false
+ }
+ },
+ {
+ "name": "Chainbreaker",
+ "path": "/chainbreaker",
+ "gridPosition": "area_5",
+ "variant": "chainbreaker",
+ "background": "/images/categories/items/4/background.png",
+ "sublinks": {
+ "discriminant": false
+ },
+ "subtitle": {
+ "discriminant": true,
+ "value": {
+ "content": "Spear & Animism",
+ "divider": {
+ "discriminant": true,
+ "value": "⎊"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/keystatic.config.ts b/keystatic.config.ts
index aa6a5db..3243832 100644
--- a/keystatic.config.ts
+++ b/keystatic.config.ts
@@ -1,8 +1,11 @@
import { config } from '@keystatic/core';
+import navigation from '@/keystatic/singletons/navigation';
+
export default config({
storage: {
kind: 'local',
},
collections: {},
+ singletons: { navigation },
});
diff --git a/postcss.config.mjs b/postcss.config.mjs
index 364ddaf..6d7265c 100644
--- a/postcss.config.mjs
+++ b/postcss.config.mjs
@@ -14,7 +14,7 @@ import customFunctions from './src/lib/postcss/functions';
const plugins = [
postcssGlobalData({
- files: ['./src/styles/variables/custom-media.css'],
+ files: ['./src/styles/globals/custom-media.css'],
}),
postcssMixins({
mixinsDir: './src/styles/mixins/',
diff --git a/public/images/categories/items/4/background.png b/public/images/categories/items/4/background.png
new file mode 100644
index 0000000..feb1e55
Binary files /dev/null and b/public/images/categories/items/4/background.png differ
diff --git a/src/app/(site)/layout.tsx b/src/app/(site)/layout.tsx
index 09a1641..6864755 100644
--- a/src/app/(site)/layout.tsx
+++ b/src/app/(site)/layout.tsx
@@ -1,5 +1,6 @@
import { MenuProvider } from '@/contexts/MenuContext';
import PageHeader from '@/components/Page/Header';
+import PageMenu from '@/components/Page/Menu';
export default function SiteLayout({
children,
@@ -7,6 +8,7 @@ export default function SiteLayout({
return (
+
{children}
);
diff --git a/src/app/(site)/page.module.css b/src/app/(site)/page.module.css
index 736b891..4fd1f88 100644
--- a/src/app/(site)/page.module.css
+++ b/src/app/(site)/page.module.css
@@ -1,3 +1,82 @@
.wrapper {
@mixin responsive-wrapper;
+
+ & body {
+ margin: 0;
+ padding: 2rem;
+
+ font-family: monospace;
+ color: #1a1a1d;
+
+ background: #f7f9fb;
+ }
+
+ & h1 {
+ margin-bottom: 2rem;
+ font-weight: 900;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ }
+
+ & .grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 2rem;
+ margin-bottom: 3rem;
+ }
+
+ & .demoCard {
+ border: 3px solid #1a1a1d;
+ background: white;
+ }
+
+ & .demoTitle {
+ margin: 0;
+ padding: 0.5rem 1rem;
+
+ font-size: 0.875rem;
+ font-weight: bold;
+ color: white;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+
+ background: #1a1a1d;
+ }
+
+ & .imageContainer {
+ cursor: pointer;
+
+ position: relative;
+
+ overflow: hidden;
+
+ width: 100%;
+ height: 200px;
+ }
+
+ & .demoImage {
+ width: 100%;
+ height: 100%;
+
+ object-fit: cover;
+ filter: grayscale(100) contrast(150) brightness(100);
+
+ transition: none;
+ }
+
+ & .instructions {
+ margin-top: 2rem;
+ padding: 1rem;
+
+ font-family: monospace;
+ color: white;
+
+ background: #1a1a1d;
+ }
+
+ & .instructions h2 {
+ margin-top: 0;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ }
}
\ No newline at end of file
diff --git a/src/app/(site)/page.tsx b/src/app/(site)/page.tsx
index 2006168..208a92a 100644
--- a/src/app/(site)/page.tsx
+++ b/src/app/(site)/page.tsx
@@ -3,9 +3,491 @@ import styles from './page.module.css';
export default function Home() {
return (
-
+
DAVE! DAVE! Do Not Let Us Die In The Dark Night Of This Cold Winter!
-
+
+
Background / Image effects
+
+
+
Overexposure Blast
+
+
+
+
+
+
+
Contrast Slam
+
+
+
+
+
+
+
Colorbleed
+
+
+
+
+
+
+
Film Burn
+
+
+
+
+
+
+
Photocopier Malfunction
+
+
+
+
+
+
+
Toner Starvation
+
+
+
+
+
+
+
Digital Corruption
+
+
+
+
+
+
+
Stark Flash
+
+
+
+
+
+
+
+
Instructions
+
+ Hover over each image to see the effect. These are designed to work
+ with your base filter:
+
+
filter: grayscale(1) contrast(150%) brightness(120%)
+
+ You can replace the demo images with your own by changing the src
+ attributes. All effects use stepped animations or sharp transitions to
+ maintain that industrial, non-digital feel.
+
+
+ The effects range from subtle (Contrast Slam) to more dramatic
+ (Digital Corruption). Choose based on how aggressive you want the
+ interaction to feel.
+
+
+
Link Effects
+
+ {/* Your Ideas */}
+
+
Strikethrough Mark (Marker)
+
+ This is some text with a{' '}
+
+ strikethrough link
+ {' '}
+ in the middle of it.
+
+
+
+
Strikethrough Mark (Industrial)
+
+ This is some text with a{' '}
+
+ strikethrough link
+ {' '}
+ in the middle of it.
+
+
+
+
Marker Highlight [Industrial]
+
+ This is some text with a{' '}
+
+ marker highlight link
+ {' '}
+ in the middle of it.
+
+
+
+ {/* Stamping/Punching Effects */}
+
+
Label Maker
+
+ This is some text with a{' '}
+
+ label maker link
+ {' '}
+ in the middle of it.
+
+
+
+
+
Rubber Stamp
+
+ This is some text with a{' '}
+
+ rubber stamp link
+ {' '}
+ in the middle of it.
+
+
+
+ {/* Industrial/Mechanical */}
+
+
Press/Stamp
+
+ This is some text with a{' '}
+
+ pressed link
+ {' '}
+ in the middle of it.
+
+
+
+
+
Typewriter Underline
+
+ This is some text with a{' '}
+
+ typewriter link
+ {' '}
+ in the middle of it.
+
+
+
+
+
Hard Invert
+
+ This is some text with a{' '}
+
+ hard invert link
+ {' '}
+ in the middle of it.
+
+
+
+ {/* Marking/Annotation */}
+
+
Bracket Annotation
+
+ This is some text with a{' '}
+
+ bracket link
+ {' '}
+ in the middle of it.
+
+
+
+
+
Corner Box
+
+ This is some text with a{' '}
+
+ corner box link
+ {' '}
+ in the middle of it.
+
+
+
+ {/* Glitch/Digital */}
+
+
Character Glitch
+
+ This is some text with a{' '}
+
+ glitch link
+ {' '}
+ in the middle of it.
+
+
+
+
+
Pixel Shift
+
+ This is some text with a{' '}
+
+ shifting link
+ {' '}
+ in the middle of it.
+
+
+
+ {/* Extra Ideas */}
+
+
Redacted/Censored
+
+ This is some text with a{' '}
+
+ redacted link
+ {' '}
+ in the middle of it.
+
+
+
+
+
X-Ray/Negative
+
+ This is some text with an{' '}
+
+ x-ray link
+ {' '}
+ in the middle of it.
+
+
+
+
+
+ Successful Isildur's brink again throttle flank tightening splash.
+
+
+ Help illusion embrace liquor tightening intelligence Maggot's whips
+ bit forests. 17 sing impassable helps Southrons beheading. What's the
+ Elvish word for 'friend'?
+
+
Give Hobbitses lend yours lads picking uniting sometime.
+
+ Inferno shaken skin undo wars close circles verse suck Dwarves. I gave
+ you the chance of aiding me willingly, but you have elected the way of
+ pain! Precautions tower tied Rivendell everyone agents wouldn't?
+
+
Doorway Mithrandir clearing wielder strengths floor?
+
+ Pillaged pointy-eared mix charm Grond confounded able-bodied tact
+ glimpse instruction open dear. Suffering powerful capable gulls
+ famousest stroke breathes Bilbo squeaked pace chances. Let the
+ Ring-bearer decide.
+
+
+ Mirkwood.
+ Tom.
+ Bilbo's.
+ Gandalf's.
+ Dwarvish.
+
+
+ Queen wants Oin loose heads decay piety!
+ Large happening arrived owes legends wit war bled Durin's.
+
+ Pursuit exactly during relief mission meats cause Noldorin ablaze
+ tracked.
+
+ Darken knife midday meat Goblinses.
+
+ Your Rabble-rousers greatest could beast thirty-four t wizards
+ slumbers reforge.
+
+
+
Late vagabond knowing Ent legends there flattened cultured?
+
+ Swords are no more use here. Deny Chubbs restored. Scare rebuild
+ Argonath tracked day's large.
+
+
+ Easterlings!
+ Bill.
+ Dúnedain!
+ Gandalf.
+ Orcrist.
+
+
+ Answers feelings Elrond conjurer runs.
+ Sul nudge powerless jelly dumping hair grows log forgave?
+
+ Retaken succumbed funeral courtyard Glóin incident mere somewhere
+ commander assistance?
+
+ Bore outrun stead fight Athelas guardroom willing contains.
+ Hunted Angmar wager noose arguing?
+
+
Elros next own wisp whence cakehole right!
+
+ Thank hid its lessened lined tells prefers were Stone-Giants thousand
+ troubles. Earendil staff pines bog finest mushroom consumption.
+ Mistaken streaming fates paths arts puppet Barad-dûr uniting? You
+ shall not pass!
+
+
+
+
+
+ Ales
+ Deeply
+ Mortality
+ Open
+ Single-handedly
+
+
+
+
+ Band
+ appeared
+ waited
+ whose
+ plate
+ marshaling
+
+
+ Meat
+ nest
+ thatched
+ rallying
+ claimed
+ hungers
+
+
+ Mouse
+ also
+ birdses
+ moons
+ strain
+ brightest
+
+
+ Hate
+ different
+ arrangements
+ chiefest
+ think
+ try
+
+
+ Something's
+ task
+ here's
+ decent
+ someone
+ uses
+
+
+ Shirt
+ tonight
+ bay
+ beautifully
+ tad
+ cloaks
+
+
+
+
+ revenge
+ teaching
+ mischief
+ shores
+ dreams
+ tested
+
+
+
+
Stage dishcloth 20 horses Tooks souls crawl crime.
+
+ Approve Sul wilderness grave embellishment greatly over these rack
+ struggle. End ringing bell Anor halls pairs thirst fortress curtain
+ cleared? Dwelt language 1296 Underhill nasty. I gave you the chance of
+ aiding me willingly, but you have elected the way of pain!
+
+
+ You are full of surprises, Master Baggins.
+
+ —Girion, warmongering appears
+
+
+
+ Sung outscoring fingers Fundin reaction inquiries buggers deadliest.
+
+
+ Mustn't powerless pierces Muil sorry crossing diamond brandy. Rip
+ rockets hinder Braga go had web ought sakes hail. A wizard is never
+ late, Frodo Baggins. Nor is he early. He arrives precisely when he
+ means to. Ashes tie Gamgee dicky!
+
+
+ Rhudaur fancy tilled heart beggars. Dwarf nothing talked foot club.
+ Slaughtered flatten Hobbit journey's four-day?
+
+
Pearl tact tomb bits Arwen Evenstar worry?
+
+ Times unspoiled defenses Silvan.{' '}
+ Sigrid Pippin Gandalf thin stubbornness noises easily
+ spread. Eldar warriors won answered filth yourself
+ pocket. Showing store consistency M crevice. Decision
+ feverfew giving Misty Mountain lord supplant. Gorgoroth{' '}
+ load born fulfilled plenty fates serpent. Doorstep Pippin's{' '}
+ pity bridge long weak weep? Brightest Chubbs {' '}
+ jewels understand. Somewhat Erebor noise squealing moved?
+ Pippin's feels overrun hours brown burns. Anor {' '}
+ turning pick prophecy. Surrounded entered needlessly weary vile
+ hmm Bagshot Row. Consent outwitted dotage slug Homely hear.
+ Parapet protected favored defied roam quiet Dori sick
+ bent. Homage store hurricane prove ferret Helm's Deep
+ lately? Excellent regret fun often returned Wood-elves
+ apocalypse. Théodred's rights rat drawing{' '}
+ examine dared bygone residence deeply .{' '}
+ Greenway Girion Rohirrim trammel waiting edge.
+
+
+
+ Turn
+
+ Bare protuberance arrived forging funny salvage Cair except first
+ banners.
+
+ Foes
+ Bore river large house shadows it's Tuckborough warn.
+
+ Stirring Greenwood nest sapphire grant gob flagon famous mean!
+
+ Unprepared
+
+ Single-handed wriggling creatures lock canopy anytime horses defense
+ Hobbit's?
+
+
+ Nûmenor dungeons achieving encourage fretting dines believes
+ understand.
+
+ Ease love shine legs wee harbor Udùn adventure tumble stays.
+
+
);
}
diff --git a/src/app/globals.css b/src/app/globals.css
index 1e03b83..da26779 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,4 +1,6 @@
-@import url("../styles/variables.css");
-@import url("../styles/utilities.css");
-@import url("../styles/foundation.css");
-@import url("../styles/base.css");
\ No newline at end of file
+@layer reset, tokens, base, layout, content, components, utilities, animations;
+
+@import url("../styles/tokens.css");
+@import url("../styles/globals/foundation.css");
+@import url("../styles/globals/base.css");
+@import url("../styles/globals/content.css");
\ No newline at end of file
diff --git a/src/components/Page/Header/Header.module.css b/src/components/Page/Header/Header.module.css
index e8ac92b..b5f7ecd 100644
--- a/src/components/Page/Header/Header.module.css
+++ b/src/components/Page/Header/Header.module.css
@@ -1,93 +1,77 @@
-.header {
- @mixin py var(--spacing-tight);
+@layer components {
+ .header {
+ @mixin py var(--el-header-paddingY);
- width: var(--dim-full);
- color: var(--color-text-inverse);
- background-color: var(--color-surface-inverse);
-}
+ position: sticky;
+ z-index: 9;
+ top: 0;
-.inner {
- @mixin responsive-wrapper;
+ width: var(--dim-full);
- display: flex;
- flex-direction: row;
- gap: var(--spacing-cozy);
- align-items: center;
- justify-content: flex-start;
-}
+ color: var(--color-text-inverse);
-.logo {
- font-family: var(--font-mono);
- animation:
- logo-pulse 5s cubic-bezier(0.4, 0, 0.6, 1) infinite,
- logo-glitch 15s linear infinite;
- animation-delay: 0s, 3s;
-
- &:hover {
- transform: translate(0, 0);
-
- color: var(--color-secondary);
-
- opacity: 1;
-
- transition: all 0.2s ease;
- animation: none;
+ background-color: var(--color-surface-inverse);
}
-}
-.pagename {
- font-family: var(--font-mono);
+ .inner {
+ @mixin responsive-wrapper;
+
+ display: flex;
+ flex-direction: row;
+ gap: var(--spacing-cozy);
+ align-items: center;
+ justify-content: flex-start;
+
+ font-size: var(--el-header-font-size);
+ line-height: var(--el-header-line-height);
- & .bracket {
- color: var(--color-secondary);
}
-}
-.menutoggle {
- @mixin ml auto;
+ .logo {
+ @mixin anim-txt-characterglitch;
- & button {
- cursor: pointer;
font-family: var(--font-mono);
- transition: color 0.2s ease-out;
+ animation:
+ logo-pulse 5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
&:hover {
- color: var(--color-primary);
- }
-
- &:active {
- transform: scale(0.95);
- transition: transform 0.1s ease-out;
+ transform: translate(0, 0);
+ color: var(--color-secondary);
}
}
-}
-@keyframes logo-pulse {
- 0% { opacity: 1; }
- 25% { opacity: 0.66; }
- 50% { opacity: 0.33; }
- 75% { opacity: 0.66; }
- 100% { opacity: 1; }
-}
+ .pagename {
+ font-family: var(--font-mono);
-@keyframes logo-glitch {
- 0% {
- transform: translate(0, 0);
- color: inherit;
+ & .bracket {
+ color: var(--color-secondary);
+ }
}
- 2% {
- transform: translate(-2px, -2px);
- color: var(--color-primary);
+ .menutoggle {
+ @mixin ml auto;
+
+ & button {
+ cursor: pointer;
+ font-family: var(--font-mono);
+ transition: color 0.2s ease-out;
+
+ &:hover {
+ color: var(--color-primary);
+ }
+
+ &:active {
+ transform: scale(0.95);
+ transition: transform 0.1s ease-out;
+ }
+ }
}
- 4% {
- transform: translate(0, 0);
- color: inherit;
- }
-
- 100% {
- transform: translate(0, 0);
- color: inherit;
+ @keyframes logo-pulse {
+ 0% { opacity: 1; }
+ 25% { opacity: 0.66; }
+ 50% { opacity: 0.33; }
+ 75% { opacity: 0.66; }
+ 100% { opacity: 1; }
}
}
\ No newline at end of file
diff --git a/src/components/Page/Menu/Menu.module.css b/src/components/Page/Menu/Menu.module.css
new file mode 100644
index 0000000..adeeaf9
--- /dev/null
+++ b/src/components/Page/Menu/Menu.module.css
@@ -0,0 +1,403 @@
+@layer components {
+ /* === MenuGrid === */
+
+ .menu {
+ pointer-events: none;
+
+ position: fixed;
+ z-index: 9;
+ top: var(--el-header-height);
+ left: 0;
+
+ display: grid;
+ grid-auto-columns: 1fr;
+ grid-template-areas:
+ "area_1"
+ "area_2"
+ "area_3"
+ "area_4"
+ "area_5";
+ grid-template-columns: 1fr;
+ grid-template-rows: repeat(5, auto);
+ gap: 0;
+ gap: var(--spacing-cozy);
+
+ width: 100vw;
+ height: 100%;
+ max-height: calc(100vh - var(--el-header-height));
+
+ visibility: hidden;
+ opacity: 0;
+ background-color: var(--color-palette-charcoal-gray);
+
+ transition: opacity 0.3s ease-out, visibility 0.3s ease-out;
+
+ &.isOpen {
+ pointer-events: auto;
+ visibility: visible;
+ opacity: 1;
+ }
+
+ @media screen and (--bp-tablet) {
+ @mixin px var(--spacing-comfortable);
+
+ grid-template-areas:
+ "area_1"
+ "area_2"
+ "area_3"
+ "area_4"
+ "area_5";
+ grid-template-columns: repeat(3, 1fr);
+ grid-template-rows: repeat(2, 1fr);
+ gap: var(--spacing-comfortable);
+ }
+
+ @media screen and (--bp-desktop) {
+ display: grid;
+ grid-template-areas:
+ "area_4 area_4 area_3 area_3 area_3 area_3 area_2"
+ "area_4 area_4 area_3 area_3 area_3 area_3 area_2"
+ "area_5 area_5 area_3 area_3 area_3 area_3 area_2"
+ "area_5 area_5 area_3 area_3 area_3 area_3 area_1"
+ "area_5 area_5 area_3 area_3 area_3 area_3 area_1";
+ grid-template-columns: 2.5fr 1fr 3fr 1.5fr 1fr 1fr 4fr;
+ grid-template-rows: 3fr 1fr 2.5fr 1.5fr 2fr;
+ }
+ }
+
+ /* === MenuArea === */
+ .area {
+ /* === AREA VARIABLES === */
+ --area-bg: transparent;
+ --area-border: transparent;
+ --area-animation-keyframe: none;
+ --area-animation-duration: 0s;
+ --area-animation-timing: linear;
+ --area-bg-filter: grayscale(100%) contrast(150) brightness(150);
+
+ /** === TITLE VARIABLES === */
+ --title-color: var(--color-palette-light-silver);
+ --title-font: var(--font-header);
+ --title-font-size: var(--typo-size-2xl);
+ --title-font-weight: var(--typo-weight-black);
+ --title-line-height: 1;
+ --title-transform: uppercase;
+ --title-spacing: var(--typo-spacing-comfortable);
+ --title-hover-color: var(--color-tertiary);
+ --title-current-color: var(--color-primary);
+ --title-current-bg: var(--color-primary);
+
+ /** === SUBLINK VARIABLES === */;
+ --sublink-color: var(--color-palette-light-silver);
+ --sublink-font: var(--font-header);
+ --sublink-font-size: var(--typo-size-2xl);
+ --sublink-font-weight: var(--typo-weight-black);
+ --sublink-transform: uppercase;
+ --sublink-spacing: var(--typo-spacing-relaxed);
+ --sublink-line-height: var(--typo-leading-relaxed);
+ --sublink-letter-spacing: var(--typo-spacing-relaxed);
+ --sublink-current-color: var(--color-primary);
+ --sublink-current-bg: var(--color-primary);
+
+ /** === SUBTITLE VARIABLES === **/
+ --divider-color: var(--color-palette-light-silver);
+ --divider-width: var(--size-6);
+ --divider-height: var(--size-2);
+ --divider-font: var(--font-mono);
+ --divider-symbol: ⯆;
+ --divider-font-size: var(--typo-size-2xl);
+ --divider-padding: 0 var(--typo-spacing-cozy);
+ --subtitle-color: var(--color-palette-light-silver);
+ --subtitle-font: var(--font-mono);
+ --subtitle-font-size: var(--typo-size-2xl);
+ --subtitle-text-transform: uppercase;
+ --subtitle-letter-spacing: var(--typo-spacing-cozy);
+
+ position: relative;
+
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ border: var(--size-1) solid var(--area-border);
+
+ text-align: center;
+
+ background: var(--area-bg);
+
+ transition: all 0.2s ease-in-out;
+
+ &:not(.current) {
+ &:hover {
+ animation: var(--area-animation-keyframe) var(--area-animation-duration) var(--area-animation-timing);
+ }
+ }
+ }
+
+ .area_1 { grid-area: area_1; }
+ .area_2 { grid-area: area_2; }
+ .area_3 { grid-area: area_3; }
+ .area_4 { grid-area: area_4; }
+ .area_5 { grid-area: area_5; }
+
+ .hasBGImg {
+ &:hover {
+ .bgImg {
+ animation: var(--area-animation-keyframe) var(--area-animation-duration) var(--area-animation-timing);
+ }
+ }
+ }
+
+ .bgImg {
+ position: absolute;
+ z-index: -1;
+
+ width: 100%;
+ height: 100%;
+
+ object-fit: cover;
+ filter: var(--area-bg-filter);
+
+ @media screen and (--bp-tablet-down) {
+ display: none;
+ }
+ }
+
+ /* === MenuTitle === */
+ .title {
+ position: relative;
+ }
+
+ .mainlink {
+ position: relative;
+
+ font-family: var(--title-font);
+ font-size: var(--title-font-size);
+ font-weight: var(--title-font-weight);
+ line-height: var(--title-line-height);
+ color: var(--title-color);
+ text-transform: var(--title-transform);
+ letter-spacing: var(--title-spacing);
+
+ transition: any 0.5s ease-in-out;
+
+ &:focus {
+ &:hover {
+ color: var(--title-current-color);
+ }
+
+ @media screen and (--bp-tablet-down) {
+ outline: none;
+
+ &:hover {
+ color: var(--title-current-color);
+ }
+ }
+ }
+
+ &.current {
+ pointer-events: none;
+
+ @media screen and (--bp-tablet-down) {
+ &:hover {
+ color: var(--title-current-color);
+ }
+ }
+
+ @media screen and (--bp-desktop) {
+ }
+ }
+
+ @media screen and (--bp-tablet-down) {
+ transition: border 0.5s ease-in-out;
+ }
+ }
+
+ /* === MenuSublinks === */
+ .list {
+ @media screen and (--bp-tablet-down) {
+ display: none;
+ }
+ }
+
+ .item {
+ position: relative;
+ }
+
+ .sublink {
+ position: relative;
+
+ font-family: var(--sublink-font);
+ font-size: var(--sublink-font-size);
+ font-weight: var(--sublink-font-weight);
+ line-height: var(--sublink-line-height);
+ color: var(--sublink-color);
+ text-transform: var(--sublink-transform);
+ letter-spacing: var(--sublink-spacing);;
+
+ &:not(.current),
+ &:not(.focus) {
+ transition: var(--sublink-hover-transition);
+
+ &::after,
+ &::before {
+ position: absolute;
+ font-family: var(--sublink-hover-decorator-font);
+ opacity: 0;
+ transition: var(--sublink-hover-decorator-transition);
+ }
+
+ &::before {
+ content: var(--sublink-hover-decorator-left-symbol);
+ left: 0;
+ }
+
+ &::after {
+ content: var(--sublink-hover-decorator-right-symbol);
+ right: 0;
+ }
+
+ &:hover {
+ color: var(--sublink-hover-color);
+
+ &::before {
+ top: var(--sublink-hover-decorator-left-pos-y);
+ left: var(--sublink-hover-decorator-left-pos-x);
+ transform: var(--sublink-hover-decorator-left-transform);
+ opacity: 1;
+ }
+
+ &::after {
+ top: var(--sublink-hover-decorator-right-pos-y);
+ right: var(--sublink-hover-decorator-rightt-pos-x);
+ transform: var(--sublink-hover-decorator-right-transform);
+ opacity: 1;
+ }
+ }
+
+ &:focus {
+ &:hover {
+ color: var(--sublink-current-color);
+ }
+ }
+
+ &.current {
+ pointer-events: none;
+ }
+ }
+ }
+
+ /* === MenuSubtitle === */
+ .wrapper {
+ position: relative;
+
+ @media screen and (--bp-tablet-down) {
+ display: none;
+ }
+ }
+
+ /* === UTILITY Classes */
+ @media screen and (--bp-desktop) {
+ .pos_tr {
+ position: absolute;
+ top: 1em;
+ right: 1em;
+ }
+
+ .pos_tc {
+ position: absolute;
+ top: 1em;
+ left: 50%;
+ transform: translateX(-50%);
+ }
+
+ .pos_tl {
+ position: absolute;
+ top: 1em;
+ left: 1em;
+ }
+
+ .pos_cr {
+ position: absolute;
+ top: 50%;
+ right: 1em;
+ transform: translateY(-50%);
+ }
+
+ .pos_c {
+ position: absolute;
+ bottom: 50%;
+ left: 50%;
+ transform: translate(-50%, 50%);
+ }
+
+ .pos_cl {
+ position: absolute;
+ top: 50%;
+ right: 1em;
+ transform: translateY(-50%);
+ }
+
+ .pos_br {
+ position: absolute;
+ right: 1em;
+ bottom: 1em;
+ }
+
+ .pos_bc {
+ position: absolute;
+ bottom: 1em;
+ left: 50%;
+ transform: translateX(-50%);
+ }
+
+ .pos_bl {
+ position: absolute;
+ bottom: 1em;
+ left: 1em;
+ }
+
+ .vertical-rl {
+ writing-mode: vertical-rl;
+
+ & * {
+ writing-mode: vertical-rl;
+ }
+ }
+
+ .vertical-lr {
+ writing-mode: vertical-lr;
+
+ & * {
+ writing-mode: vertical-lr;
+ }
+ }
+
+ .sideways-rl {
+ writing-mode: sideways-rl;
+
+ & * {
+ writing-mode: sideways-rl;
+ }
+ }
+
+ .sideways-lr {
+ writing-mode: sideways-lr;
+
+ & * {
+ writing-mode: sideways-lr;
+ }
+ }
+ }
+
+ /* === CATEGORY Variants === */
+ @media screen and (--bp-desktop) {
+ .meta {}
+ .kitchensink {}
+ .awq {}
+ .worldburner {}
+ .chainbreaker {}
+ }
+}
\ No newline at end of file
diff --git a/src/components/Page/Menu/MenuArea/MenuArea.module.css b/src/components/Page/Menu/MenuArea/MenuArea.module.css
new file mode 100644
index 0000000..d43f901
--- /dev/null
+++ b/src/components/Page/Menu/MenuArea/MenuArea.module.css
@@ -0,0 +1,121 @@
+@layer components {
+ .area {
+ --area-bg: transparent;
+
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ text-align: center;
+
+ background: var(--area-bg);
+
+ @media screen and (--bp-tablet-down) {
+ border-bottom: var(--size-1) solid var(--color-palette-gunmetal);
+
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+ }
+
+ .area_1 {
+ position: relative;
+ grid-area: area_1;
+ }
+
+ .area_2 {
+ position: relative;
+ grid-area: area_2;
+ }
+
+ .area_3 {
+ position: relative;
+ grid-area: area_3;
+ }
+
+ .area_4 {
+ position: relative;
+ grid-area: area_4;
+ }
+
+ .area_5 {
+ position: relative;
+ grid-area: area_5;
+ }
+
+ .hasBGImg {
+ position: relative;
+
+ &:hover {
+ & .bgImg {
+ animation: var(--area-animation-keyframe) var(--area-animation-duration) var(--area-animation-timing);
+ }
+ }
+ }
+
+ .bgImg {
+ --area-bg-animation-keyframe: none;
+ --area-bg--animation-duration: 0s;
+ --area-bg--animation-timing: linear;
+ --area-bg-filter: grayscale(100%) contrast(150) brightness(150);
+
+ position: absolute;
+ z-index: -1;
+
+ width: 100%;
+ height: 100%;
+
+ object-fit: cover;
+ filter: var(--area-bg-filter);
+
+ @media screen and (--bp-tablet-down) {
+ display: none;
+ }
+ }
+
+ @media screen and (--bp-desktop) {
+ .chainbreaker {
+ --area-animation-keyframe: var(--kf-color-bleed);
+ --area-animation-duration: var(--img-colorbleed-duration);
+ --area-animation-timing: var(--img-colorbleed-timing);
+
+ & .bgImg {
+ z-index: -2;
+ }
+
+ &.hasBGImg {
+ --divider-color: transparent;
+ --title-color: transparent;
+ --subtitle-color: transparent;
+ --subtitle-transition: all 0.3s ease-in-out;
+ --title-transition: color 0.3s ease-in-out;
+
+ &::before {
+ content: "";
+
+ position: absolute;
+ z-index: -1;
+
+ width: 100%;
+ height: 100%;
+
+ opacity: 0;
+ background: alpharize(var(--grid-bg), 0.66);
+ }
+
+ &:hover {
+ --divider-color: var(--color-tertiary);
+ --title-color: var(--color-tertiary);
+ --subtitle-color: var(--color-tertiary);
+
+ &::before {
+ opacity: 1;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/Page/Menu/MenuArea/index.tsx b/src/components/Page/Menu/MenuArea/index.tsx
new file mode 100644
index 0000000..ec21f9c
--- /dev/null
+++ b/src/components/Page/Menu/MenuArea/index.tsx
@@ -0,0 +1,46 @@
+import React from 'react';
+
+import MenuItem from '@/components/Page/Menu//MenuItem/';
+import { useCurrentPath } from '@/hooks/useCurrentPath';
+
+import styles from './MenuArea.module.css';
+
+import { NavigationItem } from '@/lib/types/navigation';
+
+interface MenuAreaProps {
+ item: NavigationItem;
+}
+
+const MenuArea = React.memo(({ item }: MenuAreaProps) => {
+ const hasBGImg = !!item.background;
+ const { isCurrentPath } = useCurrentPath();
+
+ const areaClasses = React.useMemo(() => {
+ return [
+ styles.area,
+ styles[item.gridPosition],
+ styles[item.variant],
+ isCurrentPath(item.path) ? styles.current : '',
+ item.background ? styles.hasBGImg : null,
+ ]
+ .filter(Boolean)
+ .join(' ');
+ }, [item.background, isCurrentPath]);
+
+ return (
+
+ {hasBGImg && (
+
+ )}
+
+
+ );
+});
+
+MenuArea.displayName = 'MenuArea';
+
+export default MenuArea;
diff --git a/src/components/Page/Menu/MenuGrid/MenuGrid.module.css b/src/components/Page/Menu/MenuGrid/MenuGrid.module.css
new file mode 100644
index 0000000..937ec81
--- /dev/null
+++ b/src/components/Page/Menu/MenuGrid/MenuGrid.module.css
@@ -0,0 +1,97 @@
+@layer components {
+ .menu {
+ --grid-bg: var(--color-palette-charcoal-gray);
+ --grid-fg: var(--color-palette-light-silver);
+
+ /* === MenuTitle Vars === */
+ --title-color: var(--grid-fg);
+ --title-font: var(--font-mono);
+ --title-font-size: var(--typo-size-2xl);
+ --title-font-weight: var(--typo-weight-black);
+ --title-line-height: 1;
+ --title-transform: uppercase;
+ --title-spacing: var(--typo-spacing-comfortable);
+ --title-hover-fg: var(--primary);
+ --title-hover-bg: transparent;
+ --title-current-bg: var(--color-tertiary);
+ --title-current-fg: var(--grid-bg);
+ --title-focus-fg: var(--color-secondary);
+ --title-focus-bg: var(--grid-bg);
+ --title-transition: none;
+
+ /* === MenuSublinks Vars === */
+ --sublink-color: var(--grid-fg);
+ --sublink-font: var(--font-mono);
+ --sublink-font-size: var(--typo-size-xl);
+ --sublink-font-weight: var(--typo-weight-light);
+ --sublink-transform: uppercase;
+ --sublink-line-height: var(--typo-leading-relaxed);
+ --sublink-spacing: var(--typo-spacing-loosest);
+ --sublink-hover-fg: var(--color-tertiary);
+ --sublink-hover-bg: transparent;
+ --sublink-current-fg: var(--grid-bg);
+ --sublink-current-bg: var(--color-primary);
+ --sublink-focus-fg: var(--color-secondary);
+ --sublink-focus-bg: var(--grid-bg);
+ --sublink-transition: none;
+
+ /* === MenuSubtitle Vars === */
+ --divider-color: var(--grid-fg);
+ --divider-width: var(--size-12);
+ --divider-height: var(--size-2);
+ --divider-font: var(--font-mono);
+ --divider-font-size: var(--typo-size-2xl);
+ --divider-padding: 0 var(--typo-spacing-cozy);
+ --subtitle-font: var(--font-mono);
+ --subtitle-color: var(--grid-fg);
+ --subtitle-font-size: var(--typo-size-xl);
+ --subtitle-text-transform: uppercase;
+ --subtitle-letter-spacing: var(--typo-spacing-cozy);
+ --subtitle-transition: none;
+
+ pointer-events: none;
+
+ position: fixed;
+ z-index: 9;
+ top: var(--el-header-height);
+ left: 0;
+
+ display: grid;
+ grid-auto-columns: 1fr;
+ grid-template-areas:
+ "area_1"
+ "area_2"
+ "area_3"
+ "area_4"
+ "area_5";
+ grid-template-columns: 1fr;
+ grid-template-rows: repeat(5, auto);
+
+ width: 100vw;
+ height: calc(100vh - var(--el-header-height));
+
+ color: var(--grid-fg);
+
+ visibility: hidden;
+ opacity: 0;
+ background-color: var(--grid-bg);
+
+ &.isOpen {
+ pointer-events: auto;
+ visibility: visible;
+ opacity: 1;
+ }
+
+ @media screen and (--bp-desktop) {
+ display: grid;
+ grid-template-areas:
+ "area_4 area_4 area_3 area_3 area_3 area_3 area_2"
+ "area_4 area_4 area_3 area_3 area_3 area_3 area_2"
+ "area_5 area_5 area_3 area_3 area_3 area_3 area_2"
+ "area_5 area_5 area_3 area_3 area_3 area_3 area_1"
+ "area_5 area_5 area_3 area_3 area_3 area_3 area_1";
+ grid-template-columns: 2.5fr 1fr 3fr 1.5fr 1fr 1fr 4fr;
+ grid-template-rows: 3fr 1fr 2.5fr 1.5fr 2fr;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/Page/Menu/MenuGrid/index.tsx b/src/components/Page/Menu/MenuGrid/index.tsx
new file mode 100644
index 0000000..99c5717
--- /dev/null
+++ b/src/components/Page/Menu/MenuGrid/index.tsx
@@ -0,0 +1,67 @@
+'use client';
+
+import React from 'react';
+
+import { useMenu } from '@/contexts/MenuContext';
+import MenuArea from '@/components/Page/Menu/MenuArea/';
+
+import styles from './MenuGrid.module.css';
+
+interface MenuGridProps {
+ navigationData: Awaited<
+ ReturnType<
+ typeof import('@/lib/readers/system/navigation').getNavigationData
+ >
+ >;
+}
+
+export default function MenuGrid({ navigationData }: MenuGridProps) {
+ const { isMenuOpen, closeMenu } = useMenu();
+ const menuRef = React.useRef(null);
+ const [isClosing, setIsClosing] = React.useState(false);
+
+ const handleClose = React.useCallback(() => {
+ setIsClosing(true);
+ setTimeout(() => {
+ closeMenu();
+ setIsClosing(false);
+ }, 800);
+ }, [closeMenu]);
+
+ React.useEffect(() => {
+ const handleEscape = (e: KeyboardEvent) => {
+ if (e.key === 'Escape' && isMenuOpen) {
+ handleClose();
+ }
+ };
+
+ document.addEventListener('keydown', handleEscape);
+ return () => document.removeEventListener('keydown', handleEscape);
+ }, [isMenuOpen, handleClose]);
+
+ React.useEffect(() => {
+ if (isMenuOpen && menuRef.current) {
+ const initialFocus = menuRef.current.querySelector(
+ 'a, button'
+ ) as HTMLElement;
+ initialFocus?.focus();
+ }
+ }, [isMenuOpen]);
+
+ if (!navigationData) return null;
+
+ const { items } = navigationData;
+
+ return (
+
+ {items.map((item, index) => (
+
+ ))}
+
+ );
+}
diff --git a/src/components/Page/Menu/MenuItem/index.tsx b/src/components/Page/Menu/MenuItem/index.tsx
new file mode 100644
index 0000000..ff69c54
--- /dev/null
+++ b/src/components/Page/Menu/MenuItem/index.tsx
@@ -0,0 +1,24 @@
+import { hasSublinks, hasSubtitle } from '@/lib/types/navigation';
+import MenuTitle from '@/components/Page/Menu/MenuTitle/';
+import MenuSublinks from '@/components/Page/Menu/MenuSublinks/';
+import MenuSubtitle from '@/components/Page/Menu/MenuSubtitle/';
+
+import { NavigationItem } from '@/lib/types/navigation';
+
+interface MenuItem {
+ item: NavigationItem;
+}
+
+export default function MenuItem({ item }: MenuItem) {
+ return (
+ <>
+
+ {hasSublinks(item) && (
+
+ )}
+ {hasSubtitle(item) && (
+
+ )}
+ >
+ );
+}
diff --git a/src/components/Page/Menu/MenuSublinks/MenuSublinks.module.css b/src/components/Page/Menu/MenuSublinks/MenuSublinks.module.css
new file mode 100644
index 0000000..4b36fc1
--- /dev/null
+++ b/src/components/Page/Menu/MenuSublinks/MenuSublinks.module.css
@@ -0,0 +1,57 @@
+@layer components {
+ .list {
+ @media screen and (--bp-tablet-down) {
+ @util hide-visually;
+ }
+ }
+
+ .item {
+ position: relative;
+ }
+
+ .sublink {
+ font-family: var(--sublink-font);
+ font-size: var(--sublink-font-size);
+ font-weight: var(--sublink-font-weight);
+ line-height: var(--sublink-line-height);
+ color: var(--sublink-color);
+ text-transform: var(--sublink-transform);
+ letter-spacing: var(--sublink-spacing);
+
+ &.current {
+ padding: var(--spacing-snug) var(--spacing-tight);
+ color: var(--title-current-fg);
+ animation: var(--kf-text-glitch) 5s infinite;
+
+ &::before {
+ content: "⟩";
+ }
+ }
+
+ &:not(.current) {
+ --pointer-left-symbol: "▶";
+ --pointer-right-symbol: "◀";
+ --pointer-distance: 1em;
+
+ @mixin anim-txt-pointer_focus;
+ @mixin px var(--spacing-tight);
+
+ &:focus {
+ color: var(--sublink-focus-fg);
+ outline: none;
+ }
+
+ &:not(:focus) {
+ --pointer-left-symbol: "{";
+ --pointer-right-symbol: "}";
+ --pointer-distance: 0.5em;
+
+ @mixin anim-txt-pointer;
+
+ &:hover {
+ --sublink-color: var(--color-primary);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/Page/Menu/MenuSublinks/index.tsx b/src/components/Page/Menu/MenuSublinks/index.tsx
new file mode 100644
index 0000000..e917fb9
--- /dev/null
+++ b/src/components/Page/Menu/MenuSublinks/index.tsx
@@ -0,0 +1,29 @@
+import Link from 'next/link';
+
+import styles from './MenuSublinks.module.css';
+
+import { SubNavigationItem } from '@/lib/types/navigation';
+import { useCurrentPath } from '@/hooks/useCurrentPath';
+
+interface MenuSublinks {
+ sublinks: readonly SubNavigationItem[];
+ variant: string;
+}
+
+export default function MenuSublinks({ sublinks, variant }: MenuSublinks) {
+ const { isCurrentPath } = useCurrentPath();
+ return (
+
+ {sublinks.map((sublink: SubNavigationItem) => (
+
+
+ {sublink.name}
+
+
+ ))}
+
+ );
+}
diff --git a/src/components/Page/Menu/MenuSubtitle/MenuSubtitle.module.css b/src/components/Page/Menu/MenuSubtitle/MenuSubtitle.module.css
new file mode 100644
index 0000000..d527720
--- /dev/null
+++ b/src/components/Page/Menu/MenuSubtitle/MenuSubtitle.module.css
@@ -0,0 +1,57 @@
+@layer components {
+ .claim {
+
+ @media screen and (--bp-tablet-down) {
+ display: none;
+ }
+ }
+
+ .divider {
+ position: relative;
+ width: 100%;
+ text-align: center;
+ }
+
+ .dividersymbol {
+ position: relative;
+
+ font-family: var(--divider-font);
+ font-size: var(--divider-font-size);
+ line-height: var(--divider-line-height);
+ color: var(--divider-color);
+
+ transition: var(--subtitle-transition);
+
+ &::before,
+ &::after {
+ content: '';
+
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+
+ width: var(--divider-width);
+ height: var(--divider-height);
+
+ background-color: var(--divider-color);
+ }
+
+ &::before {
+ left: calc(var(--divider-width) *-1);
+ }
+
+ &::after {
+ right: calc(var(--divider-width) *-1);
+ }
+ }
+
+ .subtitle {
+ font-family: var(--subtitle-font);
+ font-size: var(--subtitle-font-size);
+ color: var(--subtitle-color);
+ text-transform: var(--subtitle-text-transform);
+ letter-spacing: var(--subtitle-letter-spacing);
+
+ transition: var(--subtitle-transition);
+ }
+}
\ No newline at end of file
diff --git a/src/components/Page/Menu/MenuSubtitle/index.tsx b/src/components/Page/Menu/MenuSubtitle/index.tsx
new file mode 100644
index 0000000..c238b06
--- /dev/null
+++ b/src/components/Page/Menu/MenuSubtitle/index.tsx
@@ -0,0 +1,26 @@
+import { Subtitle, hasDivider } from '@/lib/types/navigation';
+import styles from './MenuSubtitle.module.css';
+
+interface MenuSubtitleProps {
+ subtitle: Subtitle;
+ variant: string;
+}
+
+export default function MenuSubtitle({ subtitle, variant }: MenuSubtitleProps) {
+ const divider = hasDivider(subtitle) ? (
+
+
+ {subtitle.divider.value}
+
+
+ ) : (
+ ''
+ );
+
+ return (
+
+ {divider}
+
{subtitle.content}
+
+ );
+}
diff --git a/src/components/Page/Menu/MenuTitle/MenuTitle.module.css b/src/components/Page/Menu/MenuTitle/MenuTitle.module.css
new file mode 100644
index 0000000..f325277
--- /dev/null
+++ b/src/components/Page/Menu/MenuTitle/MenuTitle.module.css
@@ -0,0 +1,63 @@
+@layer components {
+ .heading {
+ position: relative;
+
+ &:has(+ ul) {
+ @mixin my var(--spacing-comfortable);
+ }
+ }
+
+ .mainlink {
+ position: relative;
+
+ border: none;
+
+ font-family: var(--title-font);
+ font-size: var(--title-font-size);
+ font-weight: var(--title-font-weight);
+ line-height: var(--title-line-height);
+ color: var(--title-color);
+ text-transform: var(--title-transform);
+ letter-spacing: var(--title-spacing);
+
+ background: transparent;
+
+ transition: var(--title-transition);
+
+ &.current {
+ padding: var(--spacing-snug) var(--spacing-tight);
+ color: var(--title-current-fg);
+ animation: var(--kf-text-glitch) 5s infinite;
+
+ &::before {
+ content: "⟩";
+ }
+ }
+
+ &:not(.current) {
+ --pointer-left-symbol: "▶";
+ --pointer-right-symbol: "◀";
+ --pointer-distance: 1em;
+
+ @mixin anim-txt-pointer_focus;
+ @mixin px var(--spacing-tight);
+
+ &:focus {
+ color: var(--title-focus-fg);
+ outline: none;
+ }
+
+ &:not(:focus) {
+ --pointer-left-symbol: "{";
+ --pointer-right-symbol: "}";
+ --pointer-distance: 0.5em;
+
+ @mixin anim-txt-pointer;
+
+ &:hover {
+ --title-color: var(--color-primary);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/Page/Menu/MenuTitle/index.tsx b/src/components/Page/Menu/MenuTitle/index.tsx
new file mode 100644
index 0000000..82763a6
--- /dev/null
+++ b/src/components/Page/Menu/MenuTitle/index.tsx
@@ -0,0 +1,25 @@
+import Link from 'next/link';
+
+import styles from './MenuTitle.module.css';
+
+import { useCurrentPath } from '@/hooks/useCurrentPath';
+
+interface MenuTitleProps {
+ name: string;
+ path: string;
+ variant: string;
+}
+
+export default function MenuTitle({ name, path, variant }: MenuTitleProps) {
+ const { isCurrentPath } = useCurrentPath();
+ return (
+
+
+ {name}
+
+
+ );
+}
diff --git a/src/components/Page/Menu/index.tsx b/src/components/Page/Menu/index.tsx
new file mode 100644
index 0000000..4a1dceb
--- /dev/null
+++ b/src/components/Page/Menu/index.tsx
@@ -0,0 +1,7 @@
+import { getNavigationData } from '@/lib/readers/system/navigation';
+import MenuGrid from '@/components/Page/Menu/MenuGrid';
+
+export default async function Menu() {
+ const navigation = await getNavigationData();
+ return ;
+}
diff --git a/src/contexts/MenuContext.tsx b/src/contexts/MenuContext.tsx
index 8d4729c..ba6b948 100644
--- a/src/contexts/MenuContext.tsx
+++ b/src/contexts/MenuContext.tsx
@@ -16,7 +16,7 @@ interface MenuProviderProps {
}
export const MenuProvider = ({ children }: MenuProviderProps) => {
- const [isMenuOpen, setIsMenuOpen] = React.useState(false);
+ const [isMenuOpen, setIsMenuOpen] = React.useState(true);
const toggleMenu = () => setIsMenuOpen(!isMenuOpen);
const closeMenu = () => setIsMenuOpen(false);
@@ -33,16 +33,6 @@ export const MenuProvider = ({ children }: MenuProviderProps) => {
};
}, [isMenuOpen]);
- useEffect(() => {
- const handleEscape = (e: KeyboardEvent) => {
- if (e.key === 'Escape' && isMenuOpen) {
- closeMenu();
- }
- };
- document.addEventListener('keydown', handleEscape);
- return () => document.removeEventListener('keydown', handleEscape);
- }, [isMenuOpen]);
-
return (
{
+ const pathname = usePathname();
+ const isCurrentPath = (path: string) => path === pathname;
+
+ return { isCurrentPath, pathname };
+};
diff --git a/src/keystatic/singletons/navigation.ts b/src/keystatic/singletons/navigation.ts
new file mode 100644
index 0000000..7a00e5c
--- /dev/null
+++ b/src/keystatic/singletons/navigation.ts
@@ -0,0 +1,116 @@
+// ============= KEYSTATIC SCHEMA =============
+
+import { fields, singleton } from '@keystatic/core';
+
+export default singleton({
+ label: 'Navigation',
+ path: 'content/system/navigation',
+ format: 'json',
+ schema: {
+ items: fields.array(
+ fields.object({
+ name: fields.text({
+ label: 'Name',
+ validation: { isRequired: true },
+ }),
+
+ path: fields.url({
+ label: 'Path',
+ description: 'Omit starting slash (/)',
+ validation: { isRequired: true },
+ }),
+
+ gridPosition: fields.select({
+ label: 'Grid Position',
+ defaultValue: '',
+ options: [
+ { label: 'None', value: '' },
+ { label: 'Area 1', value: 'area_1' },
+ { label: 'Area 2', value: 'area_2' },
+ { label: 'Area 3', value: 'area_3' },
+ { label: 'Area 4', value: 'area_4' },
+ { label: 'Area 5', value: 'area_5' },
+ ],
+ }),
+
+ variant: fields.select({
+ label: 'Style Variant',
+ description: 'Visual style and animations for this menu item',
+ defaultValue: 'default',
+ options: [
+ { label: 'Default', value: 'default' },
+ { label: 'Advanced Warhammer Quest', value: 'awq' },
+ { label: 'The Metatron', value: 'meta' },
+ { label: 'Kitchensink', value: 'kitchensink' },
+ { label: 'Worldburner', value: 'worldburner' },
+ { label: 'Chainbreaker', value: 'chainbreaker' },
+ ],
+ }),
+
+ background: fields.image({
+ label: 'Background Image',
+ description: 'Optional background image for this menu area',
+ directory: 'public/images/categories',
+ publicPath: '/images/categories',
+ }),
+
+ sublinks: fields.conditional(
+ fields.checkbox({ label: 'Show Sublinks' }),
+ {
+ false: fields.empty(),
+ true: fields.array(
+ fields.object({
+ name: fields.text({
+ label: 'Name',
+ validation: { isRequired: true },
+ }),
+ path: fields.url({
+ label: 'Path',
+ validation: { isRequired: true },
+ }),
+ }),
+ {
+ label: 'Sub Navigation Items',
+ itemLabel: (props) =>
+ props.fields.name.value || 'Untitled Sub Item',
+ }
+ ),
+ }
+ ),
+
+ subtitle: fields.conditional(
+ fields.checkbox({ label: 'Show Subtitle' }),
+ {
+ false: fields.empty(),
+ true: fields.object({
+ content: fields.text({
+ label: 'Subtitle Text',
+ validation: { isRequired: true },
+ }),
+
+ divider: fields.conditional(
+ fields.checkbox({
+ label: 'Show Divider',
+ defaultValue: false,
+ }),
+ {
+ true: fields.text({
+ label: 'Symbol',
+ description: 'Decorative symbol (e.g., ⚡, ◆, ▲)',
+ defaultValue: '◆',
+ }),
+ false: fields.empty(),
+ }
+ ),
+ }),
+ }
+ ),
+ }),
+ {
+ label: 'Menu Items',
+ itemLabel: (props) =>
+ `${props.fields.name.value || 'Untitled'} (${props.fields.gridPosition.value || 'No Position'})`,
+ }
+ ),
+ },
+});
diff --git a/src/lib/postcss/functions/index.ts b/src/lib/postcss/functions/index.ts
index 55de2ad..bf4e31a 100644
--- a/src/lib/postcss/functions/index.ts
+++ b/src/lib/postcss/functions/index.ts
@@ -1,5 +1,5 @@
module.exports = {
alpharize: (color: string, opacity: number) => {
- return `oklch(from ${color} l c h / ${opacity}`;
+ return `oklch(from ${color} l c h / ${opacity})`;
},
};
diff --git a/src/lib/readers/base.ts b/src/lib/readers/base.ts
new file mode 100644
index 0000000..efcfba7
--- /dev/null
+++ b/src/lib/readers/base.ts
@@ -0,0 +1,6 @@
+import { createReader } from '@keystatic/core/reader';
+import { cache } from 'react';
+import keystaticConfig from '~/keystatic.config';
+
+export const reader = createReader(process.cwd(), keystaticConfig);
+export { cache };
diff --git a/src/lib/readers/system/navigation.ts b/src/lib/readers/system/navigation.ts
new file mode 100644
index 0000000..bc738f5
--- /dev/null
+++ b/src/lib/readers/system/navigation.ts
@@ -0,0 +1,5 @@
+import { cache, reader } from '../base';
+
+export const getNavigationData = cache(async () => {
+ return await reader.singletons.navigation.read();
+});
diff --git a/src/lib/types/navigation.ts b/src/lib/types/navigation.ts
new file mode 100644
index 0000000..c7fb3f8
--- /dev/null
+++ b/src/lib/types/navigation.ts
@@ -0,0 +1,70 @@
+export type MenuVariant =
+ | 'default'
+ | 'awq'
+ | 'meta'
+ | 'kitchensink'
+ | 'worldburner'
+ | 'chainbreaker';
+
+export type GridPosition =
+ | 'area_1'
+ | 'area_2'
+ | 'area_3'
+ | 'area_4'
+ | 'area_5'
+ | '';
+
+export interface SubNavigationItem {
+ readonly name: string;
+ readonly path: string;
+}
+
+export interface Subtitle {
+ readonly content: string;
+ readonly divider:
+ | { readonly discriminant: true; readonly value: string }
+ | { readonly discriminant: false };
+}
+
+export interface NavigationItem {
+ readonly name: string;
+ readonly path: string;
+ readonly gridPosition: GridPosition;
+ readonly variant: MenuVariant;
+ readonly background: string | null;
+ readonly sublinks:
+ | { readonly discriminant: false }
+ | {
+ readonly discriminant: true;
+ readonly value: readonly SubNavigationItem[];
+ };
+ readonly subtitle:
+ | { readonly discriminant: false }
+ | { readonly discriminant: true; readonly value: Subtitle };
+}
+
+export interface Navigation {
+ readonly items: readonly NavigationItem[];
+}
+
+// Type guards for conditional fields
+export function hasSublinks(item: NavigationItem): item is NavigationItem & {
+ readonly sublinks: {
+ readonly discriminant: true;
+ readonly value: readonly SubNavigationItem[];
+ };
+} {
+ return item.sublinks.discriminant === true;
+}
+
+export function hasSubtitle(item: NavigationItem): item is NavigationItem & {
+ readonly subtitle: { readonly discriminant: true; readonly value: Subtitle };
+} {
+ return item.subtitle.discriminant === true;
+}
+
+export function hasDivider(subtitle: Subtitle): subtitle is Subtitle & {
+ readonly divider: { readonly discriminant: true; readonly value: string };
+} {
+ return subtitle.divider.discriminant === true;
+}
diff --git a/src/lib/utils/classnames.ts b/src/lib/utils/classnames.ts
new file mode 100644
index 0000000..63c7643
--- /dev/null
+++ b/src/lib/utils/classnames.ts
@@ -0,0 +1,8 @@
+export const mapClassnames = (
+ classnames: readonly string[],
+ styles: Record
+) =>
+ classnames
+ .map((cn) => styles[cn])
+ .filter(Boolean)
+ .join(' ');
diff --git a/src/styles/base.css b/src/styles/base.css
deleted file mode 100644
index 94011cb..0000000
--- a/src/styles/base.css
+++ /dev/null
@@ -1,13 +0,0 @@
-html {
- font-size: var(--font-size-base);
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-body {
- font-family: var(--font-geist-sans);
- font-weight: var(--typo-weight-normal);
- color: var(--color-text-primary);
- background-color: var(--color-surface-base);
-}
-
diff --git a/src/styles/foundation.css b/src/styles/foundation.css
deleted file mode 100644
index 3e78ac4..0000000
--- a/src/styles/foundation.css
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
-Foundation inspired by Tailwind CSS Preflight. (https://tailwindcss.com/docs/preflight)
-*/
-
-/*
-1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
-2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
-*/
-
-*,
-::before,
-::after {
- box-sizing: border-box; /* 1 */
- border-style: solid; /* 2 */
- border-width: 0; /* 2 */
-}
-
-/*
-1. Use a consistent sensible line-height in all browsers.
-2. Prevent adjustments of font size after orientation changes in iOS.
-3. Use a more readable tab size.
-4. Use the system's `sans` font-family by default.
-*/
-
-html {
- font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
- "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
- "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
-
- line-height: 1.5; /* 1 */
- text-size-adjust: 100%; /* 2 */
- tab-size: 4; /* 3 */
-}
-
-/*
-1. Remove the margin in all browsers.
-2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
-*/
-
-body {
- margin: 0; /* 1 */
- line-height: inherit; /* 2 */
-}
-
-/*
-1. Add the correct height in Firefox.
-2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
-3. Ensure horizontal rules are visible by default.
-*/
-
-hr {
- height: 0; /* 1 */
- border-top-width: 1px; /* 3 */
- color: inherit; /* 2 */
-}
-
-/*
-Add the correct text decoration in Chrome, Edge, and Safari.
-*/
-
-abbr:where([title]) {
- text-decoration: underline dotted;
-}
-
-/*
-Remove the default font size and weight for headings.
-*/
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-size: inherit;
- font-weight: inherit;
-}
-
-/*
-Reset links to optimize for opt-in styling instead of opt-out.
-*/
-
-a {
- color: inherit;
- text-decoration: inherit;
-}
-
-/*
-Add the correct font weight in Edge and Safari.
-*/
-
-b,
-strong {
- font-weight: bolder;
-}
-
-/*
-1. Use the system's `mono` font family by default.
-2. Correct the odd `em` font sizing in all browsers.
-*/
-
-code,
-kbd,
-samp,
-pre {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
- "Liberation Mono", "Courier New", monospace; /* 1 */
-
- font-size: 1em; /* 2 */
-}
-
-/*
-Add the correct font size in all browsers.
-*/
-
-small {
- font-size: 80%;
-}
-
-/*
-Prevent `sub` and `sup` elements from affecting the line height in all browsers.
-*/
-
-sub,
-sup {
- position: relative;
- font-size: 75%;
- line-height: 0;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-sup {
- top: -0.5em;
-}
-
-/*
-1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
-2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
-3. Remove gaps between table borders by default.
-*/
-
-table {
- border-collapse: collapse; /* 3 */
- border-color: inherit; /* 2 */
- text-indent: 0; /* 1 */
-}
-
-/*
-1. Change the font styles in all browsers.
-2. Remove the margin in Firefox and Safari.
-3. Remove default padding in all browsers.
-*/
-
-button,
-input,
-optgroup,
-select,
-textarea {
- margin: 0; /* 2 */
- padding: 0; /* 3 */
-
- font-family: inherit; /* 1 */
- font-size: 100%; /* 1 */
- font-weight: inherit; /* 1 */
- line-height: inherit; /* 1 */
- color: inherit; /* 1 */
-}
-
-/*
-Remove the inheritance of text transform in Edge and Firefox.
-*/
-
-button,
-select {
- text-transform: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Remove default button styles.
-*/
-
-button,
-[type="button"],
-[type="reset"],
-[type="submit"] {
- appearance: auto; /* 1 */
- background-color: transparent; /* 2 */
- background-image: none; /* 2 */
-}
-
-/*
-Use the modern Firefox focus style for all focusable elements.
-*/
-
-:-moz-focusring {
- outline: auto;
-}
-
-/*
-Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
-*/
-
-:-moz-ui-invalid {
- box-shadow: none;
-}
-
-/*
-Add the correct vertical alignment in Chrome and Firefox.
-*/
-
-progress {
- vertical-align: baseline;
-}
-
-/*
-Correct the cursor style of increment and decrement buttons in Safari.
-*/
-
-::-webkit-inner-spin-button,
-::-webkit-outer-spin-button {
- height: auto;
-}
-
-/*
-1. Correct the odd appearance in Chrome and Safari.
-2. Correct the outline style in Safari.
-*/
-
-[type="search"] {
- appearance: textfield; /* 1 */
- outline-offset: -2px; /* 2 */
-}
-
-/*
-Remove the inner padding in Chrome and Safari on macOS.
-*/
-
-::-webkit-search-decoration {
- appearance: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Change font properties to `inherit` in Safari.
-*/
-
-::-webkit-file-upload-button {
- font: inherit; /* 2 */
- appearance: auto; /* 1 */
-}
-
-/*
-Add the correct display in Chrome and Safari.
-*/
-
-summary {
- display: list-item;
-}
-
-/*
-Removes the default spacing and border for appropriate elements.
-*/
-
-blockquote,
-dl,
-dd,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-hr,
-figure,
-p,
-pre {
- margin: 0;
-}
-
-fieldset {
- margin: 0;
- padding: 0;
-}
-
-legend {
- padding: 0;
-}
-
-ol,
-ul,
-menu {
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-/*
-Prevent resizing textareas horizontally by default.
-*/
-
-textarea {
- resize: vertical;
-}
-
-/*
-1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
-*/
-
-input::placeholder,
-textarea::placeholder {
- opacity: 1; /* 1 */
-}
-
-/*
-Set the default cursor for buttons.
-*/
-
-button,
-[role="button"] {
- cursor: pointer;
-}
-
-/*
-Make sure disabled buttons don't get the pointer cursor.
-*/
-
-:disabled {
- cursor: default;
-}
-
-/*
-1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
-2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
- This can trigger a poorly considered lint error in some tools but is included by design.
-*/
-
-img,
-svg,
-video,
-canvas,
-audio,
-iframe,
-embed,
-object {
- display: block; /* 1 */
- vertical-align: middle; /* 2 */
-}
-
-/*
-Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
-*/
-
-img,
-video {
- max-width: 100%;
- height: auto;
-}
-
-/*
-Make elements with the HTML hidden attribute stay hidden by default.
-*/
-
-[hidden] {
- display: none;
-}
diff --git a/src/styles/globals/animations.css b/src/styles/globals/animations.css
new file mode 100644
index 0000000..62c8b02
--- /dev/null
+++ b/src/styles/globals/animations.css
@@ -0,0 +1,418 @@
+@layer animations {
+ :root {
+ /* === IMAGE ANIMATION VARIABLES === */
+ --img-overexposure-duration: 0.3s;
+ --img-overexposure-timing: ease-out forwards;
+ --img-contrastslam-duration: 0.1s;
+ --img-contrastslam-timing: steps(3, end);
+ --img-colorbleed-duration: 0.5s;
+ --img-colorbleed-timing: steps(6, end) forwards;
+ --img-filmburn-duration: 0.4s;
+ --img-filmburn-timing: steps(4, end) forwards;
+ --img-malfunction-duration: 0.6s;
+ --img-malfunction-timing: steps(6, end) forwards;
+ --img-tonerstarvation-duration: 0.5s;
+ --img-tonerstarvation-timing: steps(5, end) forwards;
+ --img-corruption-duration: 0.4s;
+ --img-corruption-timing: steps(8, end) forwards;
+ --img-starkflash-duration: 0.2s;
+ --img-starkflash-timing: linear forwards;
+
+ /* == Base filter values == */
+ --base-grayscale: 100;
+ --base-contrast: 150;
+ --base-brightness: 120;
+
+ /* === TEXT ANIMATION VARIABLES === */
+
+ /* == Strike Variables == */
+ --strike-color: var(--color-primary);
+ --strike-duration: 0.3s;
+ --strike-timing: cubic-bezier(0.4, 0, 0.2, 1);
+ --strike-radius: 50% / 0.25em 0.5em 0.9em 0.7em;
+ --strike-border-width: 0.25em;
+ --strike-height: 0.1875em;
+
+ /* == Marker Highlight Variables == */
+ --marker-bg: var(--color-surface-inverse);
+ --marker-fg: var(--color-text-inverse);
+ --marker-duration: 0.4s;
+ --marker-timing: cubic-bezier(0.68, -0.55, 0.265, 1.55);
+
+ /* == Label Maker Variables == */
+ --label-duration: 0.1s;
+ --label-timing: cubic-bezier(0.68, -0.55, 0.265, 1.55);
+ --label-bg: var(--color-surface-inverse);
+ --label-fg: var(--color-text-inverse);
+ --label-margin: -0.2em -0.4em;
+ --label-padding: 0.2em 0.4em;
+ --label-border-width: 0.125em;
+ --label-weight: bold;
+ --label-transform: uppercase;
+ --label-spacing: 0.05em;
+ --label-shadow-offset: 0.125em 0.125em;
+ --label-shadow-color: alpharize(var(--label-bg), 0.3);
+
+ /* == Rubber Stamp Variables == */
+ --stamp-duration: 0.08s;
+ --stamp-timing: steps(2, end);
+ --stamp-bg: var(--color-surface-inverse);
+ --stamp-fg: var(--color-text-inverse);
+ --stamp-rotate: -2deg;
+ --stamp-scale: 0.95;
+ --stamp-translate: 1px;
+ --stamp-margin: -0.2em -0.4em;
+ --stamp-padding: 0.2em 0.4em;
+ --stamp-border-width: 0.25em;
+ --stamp-weight: 900;
+ --stamp-transform: uppercase;
+ --stamp-spacing: 0.2em;
+ --stamp-shadow-offset: 0.125em 0.125em;
+ --stamp-shadow-color: alpharize(var(--stamp-fg), 0.8);
+
+ /* Press Stamp Variables */
+ --press-duration: 0.06s;
+ --press-timing: c linear;
+ --press-bg: var(--color-surface-elevated-4);
+ --press-fg: var(--color-text-inverse);
+ --press-scale-y: 0.85;
+ --press-scale-x: 1.05;
+ --press-translate: 3px;
+ --press-margin: -0.05em -0.15em;
+ --press-padding: 0.05em 0.15em;
+ --press-weight: 900;
+ --press-spacing: 0.1em;
+ --press-border-color: var(--color-surface-elevated-4);
+ --press-shadow-1: var(--color-surface-inverse);
+ --press-shadow-2: alpharize(var(--stamp-fg), 0.7);
+
+ /* Typewriter Variables */
+ --typewriter-color: var(--color-text-primary);
+ --typewriter-duration: 0.6s;
+ --typewriter-timing: steps(15, end);
+ --typewriter-offset: -3px;
+ --typewriter-height: 2px;
+ --typewriter-dash-length: 0.4em;
+ --typewriter-gap-length: 0.45em;
+
+ /* Hard Invert Variables */
+ --invert-duration: 0.8s;
+ --invert-timing: steps(2, end);
+ --invert-bg: var(--color-surface-inverse);
+ --invert-fg: var(--color-text-inverse);
+ --invert-scale: 1.02;
+ --invert-weight: 900;
+ --invert-spacing: 0.05em;
+
+ /* Pointer Variables */
+ --pointer-color: inherit;
+ --pointer-transition: all 0.3s ease-out;
+ --pointer-left-symbol: '[';
+ --pointer-right-symbol: ']';
+ --pointer-distance: 0.375em;
+
+ /* Corner Box Variables */
+ --corner-margin: -0.3em;
+ --corner-padding: 0.3em;
+ --corner-size: 0.5em;
+ --corner-border: 2px solid var(--color-text-primary);
+ --corner-transition: all 0.75s ease-out;
+ --corner-font-weight: 600;
+
+ /* Character Glitch Variables */
+ --glitch-duration: 0.3s;
+ --glitch-timing: steps(8, end);
+ --glitch-text-shadow-1: 2px 0 var(--color-palette-heliotrope), -2px 0 var(--color-palette-electric-blue);
+ --glitch-text-shadow-2: 1px 0 var(--color-palette-ruby), -1px 0 var(--color-palette-electric-green);
+ --glitch-fg-step: var(--color-text-inverse);
+ --glitch-bg-step: var(--color-surface-inverse);
+
+ /* Pixel Shift Variables */
+ --pixel-bg: var(--color-surface-inverse);
+ --pixel-fg: var(--color-text-inverse);
+ --pixel-duration: 0.5s;
+ --pixel-timing: steps(2, start) forwards;
+ --pixel-line-height: 0.5em;
+ --pixel-text-shadow: 2px 0 var(--color-primary), -1px 0 var(--color-secondary);
+ --pixel-line-color-step: var(--color-primary);
+ --pixel-line-color-end: var(--color-text-inverse);
+
+ /* Redacted Variables */
+ --redacted-bg: var(--color-text-primary);
+ --redacted-duration: 0.4s;
+ --redacted-timing: steps(3, end);
+ --redacted-shadow: 0 0 8px alpharize(var(--color-palette-woodsmoke), 0.5);
+
+ /* X-Ray Variables */
+ --xray-duration: 0.2s;
+ --xray-timing: steps(3, end);
+ --xray-bg: var(--color-palette-ice-blue);
+ --xray-fg: var(--color-text-inverse);
+ --xray-weight: 900;
+ --xray-glow: var(--color-surface-inverse);
+ --xray-invert: 1;
+ --xray-contrast: 300%;
+ --xray-brightness: 150%;
+ --xray-saturate: 0;
+ --xray-border: var(--color-surface-inverse);
+ --xray-outer-glow: alpharize(var(--color-palette-ice-blue), 0.5);
+
+ /* === KEYFRAME NAME VARIABLES === */
+ --kf-overexposure: overexposure;
+ --kf-color-bleed: color-bleed;
+ --kf-film-burn: film-burn;
+ --kf-malfunction: malfunction;
+ --kf-toner-fade: toner-fade;
+ --kf-digital-corrupt: digital-corrupt;
+ --kf-stark-flash: stark-flash;
+ --kf-bd-overexposure: bd-overexposure;
+ --kf-bd-color-bleed: bd-color-bleed;
+ --kf-bd-film-burn: bd-film-burn;
+ --kf-bd-malfunction: bd-malfunction;
+ --kf-bd-toner-fade: bd-toner-fade;
+ --kf-bd-digital-corrupt: bd-digital-corrupt;
+ --kf-bd-stark-flash: bd-stark-flash;
+ --kf-strike-slam: strike-slam;
+ --kf-text-glitch: text-glitch;
+ --kf-char-scramble: char-scramble;
+ --kf-glitch-line: glitch-line;
+ --kf-text-entry-glitch: text-entry-glitch;
+ }
+
+ /* === IMAGE KEYFRAMES === */
+
+ @keyframes overexposure {
+ 0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
+ 50% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(350%); }
+ 100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(180%); }
+ }
+
+ @keyframes color-bleed {
+ 0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
+ 16% { filter: grayscale(0.7) contrast(200%) brightness(180%) saturate(300); }
+ 33% { filter: grayscale(0.4) contrast(300%) brightness(150%) saturate(500) hue-rotate(15deg); }
+ 50% { filter: grayscale(0.8) contrast(250%) brightness(200%) saturate(400) hue-rotate(-10deg); }
+ 66% { filter: grayscale(0.3) contrast(400%) brightness(160%) saturate(600) hue-rotate(25deg); }
+ 83% { filter: grayscale(0.6) contrast(300%) brightness(180%) saturate(300) hue-rotate(-5deg); }
+ 100% { filter: grayscale(0.5) contrast(250%) brightness(170%) saturate(400); }
+ }
+
+ @keyframes film-burn {
+ 0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
+ 25% { filter: invert(1) contrast(200%) brightness(150%); }
+ 50% { filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(80%); }
+ 75% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(250%); }
+ 100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(160%); }
+ }
+
+ @keyframes malfunction {
+ 0% {
+ transform: scaleX(1);
+ filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness));
+ }
+
+ 16% {
+ transform: scaleX(0.95) translateX(2px);
+ filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(200%);
+ }
+
+ 33% {
+ transform: scaleX(1.05) translateX(-2px);
+ filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(80%);
+ }
+
+ 50% {
+ transform: scaleX(0.98) translateX(1px);
+ filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(250%);
+ }
+
+ 66% {
+ transform: scaleX(1.02) translateX(-1px);
+ filter: grayscale(var(--base-grayscale)) contrast(250%) brightness(100%);
+ }
+
+ 100% {
+ transform: scaleX(1) translateX(0);
+ filter: grayscale(var(--base-grayscale)) contrast(180%) brightness(140%);
+ }
+ }
+
+ @keyframes toner-fade {
+ 0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
+ 20% { filter: grayscale(var(--base-grayscale)) contrast(80%) brightness(180%); }
+ 40% { filter: grayscale(var(--base-grayscale)) contrast(50%) brightness(220%); }
+ 60% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(160%); }
+ 80% { filter: grayscale(var(--base-grayscale)) contrast(120%) brightness(140%); }
+ 100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(130%); }
+ }
+
+ @keyframes digital-corrupt {
+ 0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
+ 12.5% { filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(50%) blur(1px); }
+ 25% { filter: grayscale(var(--base-grayscale)) contrast(80%) brightness(300%) saturate(2); }
+ 37.5% { filter: grayscale(var(--base-grayscale)) contrast(400%) brightness(80%) hue-rotate(180deg); }
+ 50% { filter: grayscale(var(--base-grayscale)) contrast(100%) brightness(400%) invert(0.3); }
+ 62.5% { filter: grayscale(var(--base-grayscale)) contrast(500%) brightness(60%); }
+ 75% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(200%) blur(0.5px); }
+ 87.5% { filter: grayscale(var(--base-grayscale)) contrast(180%) brightness(150%); }
+ 100% { filter: grayscale(var(--base-grayscale)) contrast(200%) brightness(140%); }
+ }
+
+ @keyframes stark-flash {
+ 0% { filter: grayscale(var(--base-grayscale)) contrast(var(--base-contrast)) brightness(var(--base-brightness)); }
+ 30% { filter: grayscale(var(--base-grayscale)) contrast(800%) brightness(800%) invert(1); }
+ 70% { filter: grayscale(var(--base-grayscale)) contrast(600%) brightness(600%); }
+ 100% { filter: grayscale(var(--base-grayscale)) contrast(300%) brightness(180%); }
+ }
+
+ /* === TEXT KEYFRAMES === */
+
+ @keyframes strike-slam {
+ 0% {
+ left: 0;
+ width: 0%;
+ }
+
+ 100% {
+ left: -0.125em;
+ width: calc(100% + 0.25em);
+ }
+ }
+
+ @keyframes text-glitch {
+ 0% {
+ transform: translateX(0);
+ color: var(--color-palette-light-silver);
+ }
+
+ 50% {
+ transform: translateX(-2px);
+ color: var(--pixel-fg);
+ text-shadow: var(--pixel-text-shadow);
+ }
+
+ 100% {
+ transform: translateX(0);
+ color: var(--pixel-fg);
+ }
+ }
+
+ @keyframes char-scramble {
+ 0% {
+ transform: translateX(0);
+ text-shadow: none;
+ filter: none;
+ }
+
+ 12.5% {
+ font-family: monospace;
+ text-shadow: var(--glitch-text-shadow-1);
+ }
+
+ 25% {
+ transform: translateX(2px);
+ filter: contrast(200%) brightness(150%);
+ }
+
+ 37.5% {
+ transform: translateX(-1px) scaleY(1.1);
+ letter-spacing: 0.2em;
+ }
+
+ 50% {
+ transform: translateX(1px) scaleX(0.9);
+ color: var(--glitch-fg-step);
+ background: var(--glitch-bg-step);
+ }
+
+ 62.5% {
+ transform: translateX(-2px);
+ filter: invert(1) contrast(300%);
+ }
+
+ 75% {
+ transform: translateX(1px);
+ text-shadow: var(--glitch-text-shadow-2);
+ }
+
+ 87.5% {
+ letter-spacing: 0.1em;
+ filter: contrast(150%) brightness(120%);
+ }
+
+ 100% {
+ transform: translateX(0);
+ color: var(--color-text-primary);
+ text-shadow: none;
+ filter: none;
+ }
+ }
+
+ @keyframes glitch-line {
+ 0% {
+ transform: translateX(0) scaleX(1);
+ opacity: 0;
+ }
+
+ 50% {
+ transform: translateX(3px) scaleX(0.7);
+ opacity: 1;
+ background: var(--pixel-line-color-step);
+ }
+
+ 100% {
+ transform: translateX(0) scaleX(1);
+ opacity: 1;
+ background: var(--pixel-line-color-end);
+ }
+ }
+}
+
+@keyframes text-entry-glitch {
+ 0% {
+ transform: translateX(-10px) scale(0.8);
+ color: transparent;
+ opacity: 0;
+ filter: blur(2px);
+ }
+
+ 25% {
+ transform: translateX(3px) scale(1.05);
+
+ color: var(--color-palette-light-silver);
+ text-shadow: 2px 0 var(--color-primary), -1px 0 var(--color-secondary);
+
+ opacity: 0.7;
+ filter: blur(1px);
+ }
+
+ 50% {
+ transform: translateX(-2px) scale(0.95);
+
+ color: var(--pixel-fg);
+ text-shadow: var(--pixel-text-shadow);
+
+ opacity: 0.9;
+ filter: blur(0.5px);
+ }
+
+ 75% {
+ transform: translateX(1px) scale(1.02);
+
+ color: var(--color-text-inverse);
+ text-shadow: 1px 0 var(--color-primary);
+
+ opacity: 1;
+ filter: none;
+ }
+
+ 100% {
+ transform: translateX(0) scale(1);
+
+ color: var(--pixel-line-color-end);
+ text-shadow: none;
+
+ opacity: 1;
+ filter: none;
+ }
+}
\ No newline at end of file
diff --git a/src/styles/globals/base.css b/src/styles/globals/base.css
new file mode 100644
index 0000000..cc29197
--- /dev/null
+++ b/src/styles/globals/base.css
@@ -0,0 +1,16 @@
+@layer base {
+ html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+
+ body {
+ font-family: var(--font-geist-sans);
+ font-weight: var(--typo-weight-normal);
+ color: var(--color-text-primary);
+ background-color: var(--color-surface-base);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/styles/globals/colors.css b/src/styles/globals/colors.css
new file mode 100644
index 0000000..08cdbe3
--- /dev/null
+++ b/src/styles/globals/colors.css
@@ -0,0 +1,155 @@
+@layer tokens {
+ :root {
+ /* === Default Palette === */
+
+ /* == Blacks, Grays & Off-Whites == */
+ --color-palette-woodsmoke: oklch(15.5% 0.009 274.276deg); /* Woodsmoke: #0B0C10 */
+ --color-palette-black-ink: oklch(21.9% 0.006 285.911deg); /* Shark: #1A1A1D */
+ --color-palette-charcoal: oklch(26.6% 0.008 240.166deg); /* Shark2: #222629 */
+ --color-palette-charcoal-gray: oklch(33.7% 0.026 266.801deg); /* Bright Gray: #313745 */
+ --color-palette-slate-gray: oklch(33.3% 0 89.876deg); /* Mineshaft: #363636 */
+ --color-palette-gunmetal: oklch(41.1% 0.008 248.035deg); /* Abbey2: #474B4F */
+ --color-palette-carbon: oklch(39.8% 0 89.876deg); /* Tundora: #474747 */
+ --color-palette-steel-gray: oklch(42.5% 0.003 286.26deg); /* Abbey: #4e4e50 */
+ --color-palette-dusty-black: oklch(43.7% 0.013 17.672deg); /* DonJuan: #594F4F */
+ --color-palette-stone: oklch(64.3% 0.005 91.471deg); /* Natural Gray: #8E8D8A */
+ --color-palette-cloud-gray: oklch(53.6% 0.005 236.565deg); /* Nevada: #6B6E70 */
+ --color-palette-silver: oklch(72.9% 0.001 17.185deg); /* Silver Chalice: #A8A7A7 */
+ --color-palette-light-silver: oklch(82.6% 0.002 247.844deg); /* Silversand: #C5C6C7 */
+ --color-palette-pale-gray: oklch(91.3% 0.004 91.449deg); /* Westar: #E3E2DF */
+ --color-palette-pale-stone: oklch(89.7% 0.004 106.481deg); /* Quillgray: #DDDDDA */
+ --color-palette-very-pale-gray: oklch(94.3% 0 89.876deg); /* Gallery: #ECECEC */
+ --color-palette-off-white: oklch(98.1% 0.003 247.858deg); /* Catskill White: #F7F9fB */
+ --color-palette-cat-squeeze: oklch(98.3% 0.004 236.496deg); /* Cat Squeeze: #F7FAFC */
+
+ /* == Reds == */
+ --color-palette-oxblood: oklch(30.5% 0.122 12.109deg); /* Bordeaux: #5D001E */
+ --color-palette-deep-maroon: oklch(37.6% 0.109 11.682deg); /* Crown of Thorns: #6F2232 */
+ --color-palette-crimson: oklch(43.2% 0.169 7.14deg); /* Monarch: #950740 */
+ --color-palette-cherry-red: oklch(45.4% 0.168 1.454deg); /* Disco: #9A1750 */
+ --color-palette-ruby: oklch(52.1% 0.206 15.782deg); /* Shiraz: #C3073F */
+ --color-palette-red-clay: oklch(65.1% 0.178 27.507deg); /* Burnt Sienna: #E85A4F */
+ --color-palette-lava: oklch(63.6% 0.193 17.075deg); /* Mandy: #E84A5F */
+ --color-palette-vivid-scarlet: oklch(66.6% 0.221 15.669deg); /* Radical Red: #FE4365 */
+
+ /* == Pinks & Magentas == */
+ --color-palette-heliotrope: oklch(68.3% 0.217 353.666deg); /* Heliotrope: #F74FA3 */
+ --color-palette-hot-pink: oklch(65.4% 0.2 6.69deg); /* French Rose: #EE4C7C */
+ --color-palette-cerise: oklch(60.7% 0.23 18.554deg); /* Amaranth: #EC2049 */
+ --color-palette-fuchsia: oklch(49.6% 0.181 351.176deg); /* Hibiscus: #A7226E */
+ --color-palette-dusty-rose: oklch(63.2% 0.11 2.384deg); /* Turkish Rose: #C06C84 */
+ --color-palette-berry: oklch(60.8% 0.159 2.621deg); /* Mulberry: #CC527A */
+ --color-palette-petal-pink: oklch(80.5% 0.063 1.992deg); /* Rose Fog: #E3AFBC */
+ --color-palette-coral-pink: oklch(71.2% 0.162 15.607deg); /* Froly: #F67280 */
+ --color-palette-sweet-pink: oklch(79.2% 0.114 21.911deg); /* Sweet Pink: #FC9D9A */
+
+ /* == Oranges & Browns == */
+ --color-palette-persimmon: oklch(68.6% 0.179 40.01deg); /* Flamingo: #F26B38 */
+ --color-palette-terracotta: oklch(71.3% 0.131 27.646deg); /* Apricot: #E98074 */
+ --color-palette-tan: oklch(82.7% 0.047 76.752deg); /* Akaroa: #D8C3A5 */
+ --color-palette-peach: oklch(88.5% 0.072 57.746deg); /* Flesh: #FECEAB */
+ --color-palette-pastel-orange: oklch(82.1% 0.092 42.408deg); /* Rosebud: #F8B195 */
+ --color-palette-light-apricot: oklch(87.8% 0.066 57.778deg); /* Vivid Tangerine: #F9CDAD */
+ --color-palette-bone-white: oklch(92.7% 0.015 94.206deg); /* Satin Linen: #EAE7DC */
+
+ /* == Yellows == */
+ --color-palette-ripe-lemon: oklch(83.9% 0.167 91.469deg); /* Ripe Lemon: #F2C51D */
+ --color-palette-bright-canary: oklch(89% 0.157 97.726deg); /* Energy Yellow: #F7DB4F */
+ --color-palette-pale-lemon: oklch(95.6% 0.104 121.573deg); /* Mimosa: #E5FCAD */
+
+ /* == Greens == */
+ --color-palette-forest-green: oklch(58.1% 0.127 130.001deg); /* Crete: #61892F */
+ --color-palette-lime-green: oklch(74.6% 0.18 129.939deg); /* Atlantis: #86C232 */
+ --color-palette-electric-green: oklch(87.7% 0.227 137.099deg); /* Screaming Green: #87f74f */
+ --color-palette-sage: oklch(75.1% 0.056 144.175deg); /* Norway: #87f74f */
+ --color-palette-mint-green: oklch(84.8% 0.098 151.333deg); /* Chinook: #9de0ad */
+ --color-palette-olive-drab: oklch(82.5% 0.042 107.285deg); /* Olive Drap: #C8C8A9 */
+ --color-palette-seafoam: oklch(71.6% 0.056 165.214deg); /* Acapulco: #83AF9B */
+
+ /* == Blues & Teals == */
+ --color-palette-dark-navy: oklch(27.3% 0.024 253.693deg); /* Ebony Clay: #1F2833 */
+ --color-palette-deep-teal: oklch(32.4% 0.018 225.132deg); /* Outer Space: #2A363B */
+ --color-palette-royal-blue: oklch(46.1% 0.07 245.64deg); /* Ming: #355C7D */
+ --color-palette-sky-blue: oklch(76.3% 0.129 233.891deg); /* Picton Blue: #4FBFF7 */
+ --color-palette-slate-blue: oklch(55.1% 0.043 210.602deg); /* Cutty Sark: #547980 */
+ --color-palette-turquoise: oklch(61.5% 0.091 198.865deg); /* Lochinvar: #2F9599 */
+ --color-palette-aqua: oklch(68.6% 0.095 190.758deg); /* Keppel: #45ADA8 */
+ --color-palette-electric-blue: oklch(90.8% 0.128 188.419deg); /* Aquamarine: #66FCF1 */
+ --color-palette-powder-blue: oklch(88.2% 0.062 187.276deg); /* Powder Blue: #a9e6df */
+ --color-palette-ice-blue: oklch(99.9% 0.001 197.139deg); /* Twilight Blue: #feffff */
+
+ /* === Semantic Colors === */
+
+ /* == Primary Colors == */
+ --color-primary: var(--color-palette-lava);
+ --color-primary-surface: oklch(from var(--color-primary) calc(l + 0.1) c h);
+ --color-primary-emphasis: oklch(from var(--color-primary) calc(l - 0.15) c h);
+
+ /* == Secondary Colors == */
+ --color-secondary: var(--color-palette-slate-blue);
+ --color-secondary-surface: oklch(from var(--color-secondary) calc(l + 0.1) c h);
+ --color-secondary-emphasis: oklch(from var(--color-secondary) calc(l - 0.15) c h);
+
+ /* == Tertiary Colors == */
+ --color-tertiary: var(--color-palette-bright-canary);
+ --color-tertiary-surface: oklch(from var(--color-tertiary) calc(l + 0.1) c h);
+ --color-tertiary-emphasis: oklch(from var(--color-tertiary) calc(l - 0.15) c h);
+
+ /* == Text Base Colors == */
+ --color-text-primary: var(--color-palette-black-ink); /* Main Body Texts, headlines */
+ --color-text-secondary: var(--color-palette-charcoal); /* Subheading, Secondary Info */
+ --color-text-tertiary: var(--color-palette-charcoal-gray); /* Captions, Meta Text */
+ --color-text-quarternary: var(--color-palette-carbon); /* Placeholder Text */
+ --color-text-inverse: var(--color-palette-ice-blue); /* Text on dark backgrounds */
+ --color-text-disabled: var(--color-palette-cloud-gray); /* Disabled form labels, inactive text */
+
+ /* == Surface Base Colors == */
+ --color-surface-base: var(--color-palette-ice-blue); /* Main page background */
+ --color-surface-elevated-1: var(--color-palette-off-white); /* Cards, Panels */
+ --color-surface-elevated-2: var(--color-palette-very-pale-gray); /* Modals, Dropdowns */
+ --color-surface-elevated-3: var(--color-palette-pale-gray); /* Tooltips, popovers */
+ --color-surface-elevated-4: var(--color-palette-light-silver); /* Highest Elevation */
+ --color-surface-inverse: var(--color-palette-black-ink); /* Darkest Surface for Contrast */
+
+ /* == Border Base Colors == */
+ --color-border-subtle: var(--color-palette-silver); /* Subtle Dividers, Card Borders */
+ --color-border-normal: var(--color-palette-stone); /* Standard Borders, form fields */
+ --color-border-strong: var(--color-palette-charcoal-gray); /* Emphasized Borders */
+
+ /* == State Colors == */
+ --color-state-error: var(--color-palette-cerise); /* Error Text, Container, icons */
+ --color-state-warning: var(--color-palette-persimmon); /* Warning Text, Container, Icons */
+ --color-state-success: var(--color-palette-lime-green); /* Success Text, Container, Icons */
+ --color-state-info: var(--color-palette-royal-blue); /* Info Text, Container, Icons */
+
+ /* == Link Colors == */
+ --color-text-link: var(--color-text-tertiary);
+ --color-text-link-hover: var(--color-secondary);
+ --color-text-link-visited: var(--color-palette-fuchsia);
+
+ /* == Focus States == */
+ --color-focus-ring: var(--color-primary);
+ --color-focus-ring-offset: var(--color-primary);
+ --color-focus-indicator: var(--color-primary-emphasis)
+
+ /* == Overlays == */;
+ --color-utility-overlay-light: oklch(15.5% 0.009 274.276deg / 10%); /* Light overlays */
+ --color-utility-overlay-medium: oklch(15.5% 0.009 274.276deg / 30%); /* Medium overlays */
+ --color-utility-overlay-heavy: oklch(15.5% 0.009 274.276deg / 60%); /* Heavy overlays, modal backdrops */
+ --color-surface-overlay: var(--color-utility-overlay-medium); /* Modal overlays, backdrop */
+ --color-surface-backdrop: var(--color-utility-overlay-heavy); /* Full screen overlays */
+
+ /* == Dividers == */
+ --color-utility-divider: var(--color-border-subtle); /* Section dividers, HR elements */
+ --color-utility-divider-strong: var(--color-border-normal); /* Emphasized dividers */
+
+ /* == Shadows == */
+ --color-utility-shadow-light: oklch(15.5% 0.009 274.276deg / 10%); /* Drop shadows */
+ --color-utility-shadow-medium: oklch(15.5% 0.009 274.276deg / 20%); /* Drop shadows */
+ --color-utility-shadow-strong: oklch(15.5% 0.009 274.276deg / 25%); /* Strong shadows */
+
+ /* == Highlights == */
+ --color-utility-highlight: var(--color-tertiary-surface); /* Text highlighting, search results */
+ --color-utility-highlight-strong: var(--color-tertiary); /* Strong highlighting */
+ }
+}
\ No newline at end of file
diff --git a/src/styles/globals/content.css b/src/styles/globals/content.css
new file mode 100644
index 0000000..3911e3b
--- /dev/null
+++ b/src/styles/globals/content.css
@@ -0,0 +1,555 @@
+@layer content {
+ .content {
+ & h1 {
+ margin-block: var(--el-h1-vspace-top) var(--el-h1-vspace-bottom);
+ padding-bottom: var(--spacing-snug);
+ border-bottom: var(--size-4) solid var(--el-h1-color);
+
+ font-family: var(--el-h1-font-family), serif;
+ font-size: var(--el-h1-font-size);
+ font-weight: var(--el-h1-font-weight);
+ line-height: var(--el-h1-line-height);
+ color: var(--el-h1-color);
+ text-transform: var(--el-h1-text-transform);
+ letter-spacing: var(--el-h1-letter-spacing);
+
+ & + p,
+ & + ul,
+ & + ol,
+ & + blockquote {
+ margin-block:
+ calc(1em * var(--typo-leading-normal) * var(--vspace-tight))
+ calc(1em * var(--typo-leading-normal) * var(--vspace-snug));
+ }
+
+ & + h2 {
+ margin-block:
+ calc(1em * var(--el-h1-line-height) * var(--vspace-snug))
+ calc(1em * var(--el-h1-line-height) * var(--vspace-normal));
+ }
+ }
+
+ & h2 {
+ margin-block: var(--el-h2-vspace-top) var(--el-h2-vspace-bottom);
+ padding-left: var(--spacing-snug);
+ border-left: var(--size-4) solid var(--el-h2-color);
+
+ font-family: var(--el-h2-font-family), serif;
+ font-size: var(--el-h2-font-size);
+ font-weight: var(--el-h2-font-weight);
+ line-height: var(--el-h2-line-height);
+ color: var(--el-h2-color);
+ text-transform: var(--el-h2-text-transform);
+ letter-spacing: var(--el-h2-letter-spacing);
+
+ & + p,
+ & + ul,
+ & + ol,
+ & + blockquote {
+ margin-block:
+ calc(1em * var(--typo-leading-normal) * var(--vspace-tight))
+ calc(1em * var(--typo-leading-normal) * var(--vspace-snug));
+ }
+
+ & + h3 {
+ margin-block:
+ calc(1em * var(--el-h1-line-height) * var(--vspace-compressed))
+ calc(1em * var(--el-h1-line-height) * var(--vspace-snug));
+ }
+ }
+
+ & h3 {
+ margin-block: var(--el-h3-vspace-top) var(--el-h3-vspace-bottom);
+ padding: var(--spacing-tight) var(--spacing-snug);
+
+ font-family: var(--el-h3-font-family), serif;
+ font-size: var(--el-h3-font-size);
+ font-weight: var(--el-h3-font-weight);
+ line-height: var(--el-h3-line-height);
+ color: var(--color-surface-base);
+ text-transform: var(--el-h3-text-transform);
+ letter-spacing: var(--el-h3-letter-spacing);
+
+ background: var(--el-h3-color);
+ }
+
+ & h4 {
+ margin-block: var(--el-h4-vspace-top) var(--el-h4-vspace-bottom);
+ padding: var(--spacing-tight) var(--spacing-snug);
+ border-top: var(--size-3 ) solid var(--el-h4-color);
+ border-bottom: var(--size-3 ) solid var(--el-h4-color);
+
+ font-family: var(--el-h4-font-family), serif;
+ font-size: var(--el-h4-font-size);
+ font-weight: var(--el-h4-font-weight);
+ line-height: var(--el-h4-line-height);
+ text-transform: var(--el-h4-text-transform);
+ letter-spacing: var(--el-h4-letter-spacing);
+ }
+
+ & h5 {
+ margin-block: var(--el-h5-vspace-top) var(--el-h5-vspace-bottom);
+ padding: var(--spacing-tight) var(--spacing-snug);
+
+ font-family: var(--el-h5-font-family), serif;
+ font-size: var(--el-h5-font-size);
+ font-weight: var(--el-h5-font-weight);
+ line-height: var(--el-h5-line-height);
+ color: var(--el-h5-color);
+ text-transform: var(--el-h5-text-transform);
+ letter-spacing: var(--el-h5-letter-spacing);
+
+ &::before,
+ &::after {
+ content: "";
+ padding-right: var(--spacing-tight);
+ line-height: 1;
+ }
+
+ &::before {
+ content: "❭";
+ }
+
+ &::after {
+ content: "";
+ }
+ }
+
+ & h6 {
+ margin-block: var(--el-h6-vspace-top) var(--el-h6-vspace-bottom);
+
+ font-family: var(--el-h6-font-family), serif;
+ font-size: var(--el-h6-font-size);
+ font-weight: var(--el-h6-font-weight);
+ line-height: var(--el-h6-line-height);
+ color: var(--el-h6-color);
+ text-transform: var(--el-h6-text-transform);
+ letter-spacing: var(--el-h6-letter-spacing);
+ }
+
+ & h3,
+ & h4,
+ & h5,
+ & h6 {
+ & + p,
+ & + ul,
+ & + ol,
+ & + blockquote {
+ margin-block:
+ calc(1em * var(--typo-leading-normal) * var(--vspace-compressed))
+ calc(1em * var(--typo-leading-normal) * var(--vspace-snug));
+ }
+ }
+
+ & p {
+ margin-block: var(--el-p-vspace-top) var(--el-p-vspace-bottom);
+
+ font-family: var(--el-p-font-family), sans-serif;
+ font-size: var(--el-p-font-size);
+ font-weight: var(--el-p-font-weight);
+ line-height: var(--el-p-line-height);
+ color: var(--el-p-color);
+ text-align: var(--el-p-text-align);
+ }
+
+ & blockquote {
+ margin-block: var(--el-p-vspace-top) var(--el-p-vspace-bottom);
+ padding: var(--spacing-snug) 0 var(--spacing-snug) var(--spacing-comfortable);
+ border-left: var(--size-4) solid var(--color-text-tertiary);
+
+ font-family: var(--el-blockquote-font-family), serif;
+ font-size: var(--el-blockquote-font-size);
+ font-weight: var(--el-blockquote-font-weight);
+ font-style: var(--el-blockquote-font-style);
+ line-height: var(--el-blockquote-line-height);
+ color: var(--el-blockquote-color);
+ }
+
+ & pre {
+ margin-block: var(--el-pre-vspace-top) var(--el-pre-vspace-bottom);
+ padding: var(--spacing-comfortable);
+
+ font-family: var(--el-pre-font-family), monospace;
+ font-size: var(--el-pre-font-size);
+ line-height: var(--el-pre-line-height);
+ color: var(--el-pre-color);
+
+ background: var(--el-pre-background);
+ }
+
+ & ul,
+ & ol {
+ margin-block: var(--el-list-vspace-top) var(--el-list-vspace-bottom);
+ font-size: var(--el-list-font-size);
+ line-height: var(--el-list-line-height);
+ color: var(--el-list-color);
+
+ & ul,
+ & ol {
+ margin-block: var(--el-list-nested-vspace-top) var(--el-list-nested-vspace-bottom);
+ }
+
+ & li {
+ margin-block: var(--el-li-vspace-top) var(--el-li-vspace-bottom);
+ list-style-position: outside;
+
+ & li {
+ margin-block: var(--el-li-nested-vspace-top) var(--el-li-nested-vspace-bottom);
+ }
+ }
+ }
+
+ & ul {
+ padding-left: var(--el-ul-indent-l1);
+ list-style: none;
+
+ & li {
+ padding-left: var(--el-ul-item-padding);
+
+ &::marker {
+ content: var(--el-ul-symbol-l1);
+ color: var(--el-ul-symbol-l1-color);
+ }
+ }
+
+ & ul,
+ & ol {
+ padding-left: var(--el-ul-indent-l2);
+
+ & li::marker {
+ content: var(--el-ul-symbol-l2);
+ color: var(--el-ul-symbol-l2-color);
+ }
+
+ & ul,
+ & ol {
+ padding-left: var(--el-ul-indent-l3);
+
+ & li::marker {
+ content: var(--el-ul-symbol-l3);
+ color: var(--el-ul-symbol-l3-color);
+ }
+
+ & ul,
+ & ol {
+ padding-left: var(--el-ul-indent-l4);
+
+ & li::marker {
+ content: var(--el-ul-symbol-l4);
+ color: var(--el-ul-symbol-l4-color);
+ }
+ }
+ }
+ }
+ }
+
+ ol {
+ counter-reset: ol-l1;
+ contain: style;
+ padding-left: var(--el-ol-indent-l1);
+ list-style: none;
+
+ & > li {
+ counter-increment: ol-l1;
+ margin-left: var(--el-ol-item-indent-l1);
+ padding-left: var(--el-ol-item-padding);
+
+ &::marker {
+ content: var(--el-ol-prefix-l1) counter(ol-l1, var(--el-ol-style-l1)) var(--el-ol-suffix-l1);
+ color: var(--el-ol-marker-color-l1);
+ }
+
+ & > ol {
+ counter-reset: ol-l2;
+ padding-left: var(--el-ol-indent-l2);
+
+ & > li {
+ counter-increment: ol-l2;
+ margin-left: var(--el-ol-item-indent-l2);
+
+ &::marker {
+ content: var(--el-ol-prefix-l2) counter(ol-l2, var(--el-ol-style-l2)) var(--el-ol-suffix-l2);
+ color: var(--el-ol-marker-color-l2);
+ }
+
+ & > ol {
+ counter-reset: ol-l3;
+ margin-left: var(--el-ol-item-indent-l3);
+ padding-left: var(--el-ol-indent-l3);
+
+ & > li {
+ counter-increment: ol-l3;
+
+ &::marker {
+ content: var(--el-ol-prefix-l3) counter(ol-l3, var(--el-ol-style-l3)) var(--el-ol-suffix-l3);
+ color: var(--el-ol-marker-color-l3);
+ }
+
+ & > ol {
+ counter-reset: ol-l4;
+ margin-left: var(--el-ol-item-indent-l4);
+ padding-left: var(--el-ol-indent-l4);
+
+ & > li {
+ counter-increment: ol-l4;
+
+ &::marker {
+ content: var(--el-ol-prefix-l4) counter(ol-l4, var(--el-ol-style-l4)) var(--el-ol-suffix-l4);
+ color: var(--el-ol-marker-color-l4);
+ }
+ }
+ }
+
+ & > ul {
+ padding-left: var(--el-ol-indent-l4);
+ }
+ }
+ }
+
+ & > ul {
+ padding-left: var(--el-ol-indent-l3);
+ }
+ }
+ }
+
+ & > ul {
+ padding-left: var(--el-ol-indent-l2);
+ }
+ }
+ }
+
+ & dl {
+ margin-block: var(--el-dl-vspace-top) var(--el-dl-vspace-bottom);
+ font-size: var(--el-dl-font-size);
+ line-height: var(--el-dl-line-height);
+ }
+
+ & dt {
+ margin-block: var(--el-dt-vspace-top) var(--el-dt-vspace-bottom);
+ padding: var(--el-dt-padding);
+
+ font-family: var(--el-dt-font-family), serif;
+ font-size: var(--el-dt-font-size);
+ font-weight: var(--el-dt-font-weight);
+ line-height: var(--el-dt-line-height);
+ color: var(--el-dt-color);
+ text-transform: var(--el-dt-text-transform);
+ letter-spacing: var(--el-dt-letter-spacing);
+
+ background: var(--el-dt-background);
+ }
+
+ & dd {
+ margin-block: var(--el-dd-vspace-top) var(--el-dd-vspace-bottom);
+ padding: var(--el-dd-indent);
+
+ font-family: var(--el-dd-font-family), sans-serif;
+ font-size: var(--el-dd-font-size);
+ line-height: var(--el-dd-line-height);
+ color: var(--el-dd-color);
+ }
+
+ & table {
+ border-collapse: collapse;
+
+ width: 100%;
+ margin-block: var(--el-table-vspace-top) var(--el-table-vspace-bottom);
+ border: var(--el-table-border);
+
+ font-size: var(--el-table-font-size);
+ line-height: var(--el-table-line-height);
+
+ & thead th,
+ & th {
+ padding: var(--el-th-padding);
+
+ font-family: var(--el-th-font-family), serif;
+ font-size: var(--el-th-font-size);
+ font-weight: var(--el-th-font-weight);
+ line-height: var(--el-th-line-height);
+ color: var(--el-th-color);
+ text-transform: var(--el-th-text-transform);
+
+ background: var(--el-th-background);
+ }
+
+ & tbody td,
+ & td {
+ padding: var(--el-td-padding);
+ border: var(--el-td-border);
+
+ font-family: var(--el-td-font-family), monospace;
+ font-size: var(--el-td-font-size);
+ line-height: var(--el-td-line-height);
+ color: var(--el-td-color);
+ text-align: center;
+ }
+ }
+
+ & hr{
+ position: relative;
+
+ overflow: visible;
+
+ height: var(--hr-height);
+ margin-block: var(--hr-margin);
+ border: none;
+
+ background: var(--hr-color);
+
+ &::after {
+ content: var(--hr-symbol-content);
+
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+
+ padding: var(--hr-symbol-space);
+
+ font-size: var(--hr-symbol-size);
+ line-height: var(--hr-symbol-line-height);
+ color: var(--hr-symbol-color);
+
+ background: var(--hr-symbol-background);
+ }
+ }
+
+ & em,
+ & i {
+ padding: 0.1em 0.2em;
+ font-style: normal;
+ color: var(--color-text-inverse);
+ background: var(--color-surface-inverse);
+ }
+
+ & strong,
+ & b {
+ font-weight: var(--typo-weight-black);
+ letter-spacing: var(--typo-spacing-relaxed);
+ }
+
+ a {
+ @mixin anim-txt-pixelshift 0.6s steps(15, end), var(--color-primary);
+
+ color: var(--color-text-tertiary);
+ transition: color 0.2s ease-in-out;
+
+ &:hover {
+ cursor: pointer;
+ color: var(--color-primary);
+ }
+
+ &:visited,
+ &:active {
+ color: var(--color-primary-emphasis);
+ }
+ }
+
+ & code {
+ padding: 0.1em 0.3em;
+
+ font-family: var(--font-mono), monospace;
+ font-size: var(--typo-size-sm);
+ color: var(--color-text-inverse);
+
+ background: var(--color-surface-inverse);
+ }
+
+ & kbd {
+ padding: 0.1em 0.3em;
+ border: 1px solid var(--color-text-primary);
+ border-radius: 2px;
+
+ font-family: var(--font-mono), monospace;
+ font-size: var(--typo-size-xs);
+ color: var(--color-text-inverse);
+ text-transform: uppercase;
+
+ background: var(--color-surface-inverse);
+ }
+
+ & samp {
+ padding: 0.1em 0.3em;
+ border-left: var(--size-1) solid var(--color-text-tertiary);
+
+ font-family: var(--font-mono), monospace;
+ font-size: var(--typo-size-sm);
+ color: var(--color-text-primary);
+
+ background: var(--color-surface-elevated-2);
+ }
+
+ & var {
+ font-family: var(--font-mono), monospace;
+ font-weight: var(--typo-weight-semibold);
+ font-style: normal;
+ color: var(--color-text-secondary);
+ }
+
+ & small {
+ font-size: var(--typo-size-xs);
+ color: var(--color-text-tertiary);
+ }
+
+ & sub,
+ & sup {
+ font-size: var(--typo-size-2xs);
+ font-weight: var(--typo-weight-semibold);
+ color: var(--color-text-secondary);
+ }
+
+ & del,
+ & s {
+ color: var(--color-text-disabled);
+ text-decoration: line-through;
+ text-decoration-thickness: var(--size-1);
+ }
+
+ & ins {
+ font-weight: var(--typo-weight-semibold);
+ color: var(--color-text-primary);
+ text-decoration: underline;
+ text-decoration-color: var(--color-primary);
+ text-decoration-thickness: var(--size-1);
+
+ background: transparent;
+ }
+
+ & abbr {
+ cursor: help;
+ text-decoration: underline dotted;
+ text-underline-offset: var(--size-1);
+ }
+
+ & dfn {
+ font-weight: var(--typo-weight-bold);
+ font-style: normal;
+ color: var(--color-text-primary);
+ }
+
+ & cite {
+ font-weight: var(--typo-weight-semibold);
+ font-style: normal;
+ color: var(--color-text-secondary);
+ }
+
+ & q {
+ font-style: normal;
+
+ &::before {
+ content: "»";
+ }
+
+ &::after {
+ content: "«";
+ }
+ }
+
+ & time {
+ font-family: var(--font-mono), monospace;
+ font-size: var(--typo-size-sm);
+ color: var(--color-text-secondary);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/styles/globals/custom-media.css b/src/styles/globals/custom-media.css
new file mode 100644
index 0000000..cddf695
--- /dev/null
+++ b/src/styles/globals/custom-media.css
@@ -0,0 +1,7 @@
+@layer tokens {
+ @custom-media --bp-mobile (width < 48rem);
+ @custom-media --bp-tablet (width >= 48rem) and (width < 80rem);
+ @custom-media --bp-tablet-up (width >= 48rem);
+ @custom-media --bp-tablet-down (width < 80rem);
+ @custom-media --bp-desktop (width >= 80rem);
+}
\ No newline at end of file
diff --git a/src/styles/globals/dimensions.css b/src/styles/globals/dimensions.css
new file mode 100644
index 0000000..c9d69b8
--- /dev/null
+++ b/src/styles/globals/dimensions.css
@@ -0,0 +1,95 @@
+@layer tokens {
+ :root {
+ /* === DIMENSIONS === */
+
+ /* == Base Size Units == */
+ --size-0: 0;
+ --size-px: 1px;
+ --size-05: 0.125rem;
+ --size-1: 0.25rem;
+ --size-2: 0.5rem;
+ --size-3: 0.75rem;
+ --size-4: 1rem;
+ --size-5: 1.25rem;
+ --size-6: 1.5rem;
+ --size-8: 2rem;
+ --size-10: 2.5rem;
+ --size-12: 3rem;
+ --size-16: 4rem;
+ --size-20: 5rem;
+ --size-24: 6rem;
+ --size-32: 8rem;
+ --size-40: 10rem;
+ --size-48: 12rem;
+ --size-64: 16rem;
+ --size-80: 20rem;
+ --size-96: 24rem;
+ --size-128: 32rem;
+ --size-160: 40rem;
+ --size-192: 48rem;
+ --size-256: 64rem;
+ --size-320: 80rem;
+ --size-384: 96rem;
+ --size-360: 90rem;
+ --size-400: 100rem;
+ --size-480: 120rem;
+
+ /* == Flexible Dimensions == */
+ --dim-full: 100%;
+ --dim-1-2: 50%;
+ --dim-1-3: 33.3333%;
+ --dim-2-3: 66.6667%;
+ --dim-1-4: 25%;
+ --dim-2-4: var(--dim-1-2);
+ --dim-3-4: 75%;
+ --dim-1-5: 20%;
+ --dim-2-5: 40%;
+ --dim-3-5: 60%;
+ --dim-4-5: 80%;
+ --dim-1-6: 16.6667%;
+ --dim-2-6: var(--dim-1-3);
+ --dim-3-6: var(--dim-1-2);
+ --dim-4-6: var(--dim-2-3);
+ --dim-5-6: 83.3333%;
+ --dim-1-8: 12.5%;
+ --dim-2-8: var(--dim-1-4);
+ --dim-3-8: 37.5%;
+ --dim-4-8: var(--dim-1-2);
+ --dim-5-8: 62.5%;
+ --dim-6-8: var(--dim-3-4);
+ --dim-7-8: 87.5%;
+ --dim-1-10: 10%;
+ --dim-2-10: var(--dim-1-5);
+ --dim-3-10: 30%;
+ --dim-4-10: var(--dim-2-5);
+ --dim-5-10: var(--dim-1-2);
+ --dim-6-10: var(--dim-3-5);
+ --dim-7-10: 70%;
+ --dim-8-10: var(--dim-4-5);
+ --dim-9-10: 90%;
+ --dim-1-12: 8.3333%;
+ --dim-2-12: var(--dim-1-6);
+ --dim-3-12: var(--dim-1-4);
+ --dim-4-12: var(--dim-1-3);
+ --dim-5-12: 41.6667%;
+ --dim-6-12: var(--dim-1-2);
+ --dim-7-12: 58.3333%;
+ --dim-8-12: var(--dim-2-3);
+ --dim-9-12: var(--dim-3-4);
+ --dim-10-12: 83.3333%;
+ --dim-11-12: 91.6667%;
+
+ /* == Semantic Spacing == */;
+ --spacing-none: var(--size-0);
+ --spacing-hairline: var(--size-px);
+ --spacing-tight: var(--size-1);
+ --spacing-snug: var(--size-2);
+ --spacing-cozy: var(--size-4);
+ --spacing-comfortable: var(--size-6);
+ --spacing-relaxed: var(--size-8);
+ --spacing-spacious: var(--size-12);
+ --spacing-generous: var(--size-16);
+ --spacing-luxurious: var(--size-24);
+ --spacing-expansive: var(--size-32);
+ }
+}
\ No newline at end of file
diff --git a/src/styles/globals/elements.css b/src/styles/globals/elements.css
new file mode 100644
index 0000000..cfb3ef6
--- /dev/null
+++ b/src/styles/globals/elements.css
@@ -0,0 +1,266 @@
+@layer tokens {
+ :root {
+ /* === H1 VARIABLES === */
+ --el-h1-color: var(--color-text-primary);
+ --el-h1-font-family: var(--font-display);
+ --el-h1-font-size: var(--typo-size-7xl);
+ --el-h1-font-weight: var(--typo-weight-black);
+ --el-h1-letter-spacing: -0.0137em;
+ --el-h1-line-height: 1.125;
+ --el-h1-text-transform: uppercase;
+ --el-h1-vspace-base: calc(1em * var(--el-h1-line-height));
+ --el-h1-vspace-top: calc(var(--el-h1-vspace-base) * var(--vspace-spacious));
+ --el-h1-vspace-bottom: calc(var(--el-h1-vspace-base) * var(--vspace-comfortable));
+
+ /* === H2 VARIABLES === */
+ --el-h2-color: var(--color-text-primary);
+ --el-h2-font-family: var(--font-header);
+ --el-h2-font-size: var(--typo-size-5xl);
+ --el-h2-font-weight: var(--typo-weight-black);
+ --el-h2-letter-spacing: -0.0096em;;
+ --el-h2-line-height: 1.1765;
+ --el-h2-text-transform: uppercase;
+ --el-h2-vspace-base: calc(1em * var(--el-h2-line-height));
+ --el-h2-vspace-top: calc(var(--el-h2-vspace-base) * var(--vspace-snug));
+ --el-h2-vspace-bottom: calc(var(--el-h2-vspace-base) * var(--vspace-compressed));
+
+ /* === H3 VARIABLES === */
+ --el-h3-color: var(--color-text-secondary);
+ --el-h3-font-family: var(--font-header);
+ --el-h3-font-size: var(--typo-size-4xl);
+ --el-h3-font-weight: var(--typo-weight-extrabold);
+ --el-h3-letter-spacing: -0.004em;
+ --el-h3-line-height: 1.2;
+ --el-h3-text-transform: uppercase;
+ --el-h3-vspace-base: calc(1em * var(--el-h3-line-height));
+ --el-h3-vspace-top: calc(var(--el-h3-vspace-base) * var(--vspace-cozy));
+ --el-h3-vspace-bottom: calc(var(--el-h3-vspace-base) * var(--vspace-snug));
+
+ /* === H4 VARIABLES === */
+ --el-h4-color: var(--color-text-secondary);
+ --el-h4-font-family: var(--font-header);
+ --el-h4-font-size: var(--typo-size-3xl);
+ --el-h4-font-weight: var(--typo-weight-extrabold);
+ --el-h4-letter-spacing: 0.0025em;
+ --el-h4-line-height: 1.125;
+ --el-h4-text-transform: uppercase;
+ --el-h4-vspace-base: calc(1em * var(--el-h4-line-height));
+ --el-h4-vspace-top: calc(var(--el-h4-vspace-base) * var(--vspace-normal));
+ --el-h4-vspace-bottom: calc(var(--el-h4-vspace-base) * var(--vspace-tight));
+
+ /* === H5 VARIABLES === */
+ --el-h5-color: var(--color-text-secondary);
+ --el-h5-font-family: var(--font-header);
+ --el-h5-font-size: var(--typo-size-2xl);
+ --el-h5-font-weight: var(--typo-weight-extrabold);
+ --el-h5-letter-spacing: 0.05em;
+ --el-h5-line-height: 1.28;
+ --el-h5-text-transform: uppercase;
+ --el-h5-vspace-base: calc(1em * var(--el-h5-line-height));
+ --el-h5-vspace-top: calc(var(--el-h5-vspace-base) * var(--vspace-cozy));
+ --el-h5-vspace-bottom: calc(var(--el-h5-vspace-base) * var(--vspace-tight));
+
+ /* === H6 VARIABLES === */
+ --el-h6-color: var(--color-text-secondary);
+ --el-h6-font-family: var(--font-header);
+ --el-h6-font-size: var(--typo-size-xl);
+ --el-h6-font-weight: var(--typo-weight-black);
+ --el-h6-letter-spacing: 0.035em;
+ --el-h6-line-height: 1.4;
+ --el-h6-text-transform: uppercase;
+ --el-h6-vspace-base: calc(1em * var(--el-h6-line-height));
+ --el-h6-vspace-top: calc(var(--el-h6-vspace-base) * var(--vspace-snug));
+ --el-h6-vspace-bottom: calc(var(--el-h6-vspace-base) * var(--vspace-compressed));
+
+ /* === PARAGRAPH VARIABLES === */
+ --el-p-color: var(--color-text-primary);
+ --el-p-font-family: var(--font-body);
+ --el-p-font-size: var(--typo-size-md);
+ --el-p-font-weight: var(--typo-weight-regular);
+ --el-p-line-height: var(--typo-leading-normal);
+ --el-p-text-align: justify;
+ --el-p-vspace-base: calc(1em * var(--el-p-line-height));
+ --el-p-vspace-top: calc(var(--el-p-vspace-base) * var(--vspace-snug));
+ --el-p-vspace-bottom: calc(var(--el-p-vspace-base) * var(--vspace-snug));
+
+ /* === BLOCKQUOTE VARIABLES === */
+ --el-blockquote-color: var(--color-text-tertiary);
+ --el-border-color: var(--color-text-tertiary);
+ --el-blockquote-font-family: var(--font-body);
+ --el-blockquote-font-size: var(--typo-size-md);
+ --el-blockquote-font-style: var(--typo-weight-regular);
+ --el-blockquote-font-weight: var(--typo-weight-medium);
+ --el-blockquote-line-height: var(--typo-leading-comfortable);
+ --el-blockquote-vspace-base: calc(1em * var(--el-blockquote-line-height));
+ --el-blockquote-vspace-top: calc(var(--el-blockquote-vspace-base) * var(--vspace-snug));
+ --el-blockquote-vspace-bottom: calc(var(--el-blockquote-vspace-base) * var(--vspace-snug));
+
+ /* === PRE VARIABLES === */
+ --el-pre-color: var(--color-text-inverse);
+ --el-pre-background: var(--color-surface-inverse);
+ --el-pre-font-family: var(--font-mono);
+ --el-pre-font-size: var(--typo-size-sm);
+ --el-pre-line-height: 1.5385;
+ --el-pre-vspace-base: calc(1em * var(--el-pre-line-height));
+ --el-pre-vspace-top: calc(var(--el-pre-vspace-base) * var(--vspace-normal));
+ --el-pre-vspace-bottom: calc(var(--el-pre-vspace-base) * var(--vspace-normal));
+
+ /* === CODE VARIABLES === */
+ --el-code-color: var(--color-text-inverse);
+ --el-code-background: var(--color-surface-inverse);
+ --el-code-font-family: var(--font-mono);
+ --el-code-font-size: var(--typo-size-sm);
+
+ /* === List Variables (For UL/OL) === */
+ --el-list-color: var(--color-text-primary);
+ --el-list-line-height: var(--typo-leading-normal);
+ --el-list-font-size: var(--typo-size-md);
+ --el-list-vspace-base: calc(1em * var(--el-list-line-height));
+ --el-list-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-snug));
+ --el-list-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-snug));
+ --el-list-nested-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-snug));
+ --el-list-nested-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-snug));
+ --el-li-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-snug));
+ --el-li-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-snug));
+ --el-li-nested-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-tight));
+ --el-li-nested-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-tight));
+
+ /* === UL VARIABLES === */
+ --el-ul-indent-l1: var(--spacing-cozy);
+ --el-ul-indent-l2: var(--spacing-cozy);
+ --el-ul-indent-l3: var(--spacing-cozy);
+ --el-ul-indent-l4: var(--spacing-cozy);
+ --el-ul-item-padding: var(--spacing-cozy);
+ --el-ul-symbol-l1: '⯃';
+ --el-ul-symbol-l1-color: var(--color-text-primary);
+ --el-ul-symbol-l2: '⯁';
+ --el-ul-symbol-l2-color: var(--color-text-primary);
+ --el-ul-symbol-l3: '⯆';
+ --el-ul-symbol-l3-color: var(--color-text-primary);
+ --el-ul-symbol-l4: '⯀';
+ --el-ul-symbol-l4-color: var(--color-text-primary);
+
+ /* === OL VARIABLES === */
+ --el-ol-indent-l1: var(--spacing-cozy);
+ --el-ol-item-indent-l1: 1.5em;
+ --el-ol-indent-l2: var(--spacing-cozy);
+ --el-ol-item-indent-l2: 0.825em;
+ --el-ol-indent-l3: var(--spacing-cozy);
+ --el-ol-item-indent-l3: 0;
+ --el-ol-indent-l4: var(--spacing-cozy);
+ --el-ol-item-indent-l4: 0;
+ --el-ol-item-padding: var(--spacing-cozy);
+ --el-ol-line-height: var(--typo-leading-normal);
+ --el-ol-marker-color-l1: var(--color-text-primary);
+ --el-ol-prefix-l1: '';
+ --el-ol-style-l1: decimal-leading-zero;
+ --el-ol-suffix-l1: '.)';
+ --el-ol-marker-color-l2: var(--color-text-primary);
+ --el-ol-prefix-l2: '';
+ --el-ol-style-l2: lower-alpha;
+ --el-ol-suffix-l2: '.)';
+ --el-ol-marker-color-l3: var(--color-text-primary);
+ --el-ol-prefix-l3: '';
+ --el-ol-style-l3: upper-roman;
+ --el-ol-suffix-l3: '.)';
+ --el-ol-marker-color-l4: var(--color-text-primary);
+ --el-ol-prefix-l4: '';
+ --el-ol-style-l4: lower-greek;
+ --el-ol-suffix-l4: '.)';
+
+ /* === DL VARIABLES === */
+ --el-dl-font-size: var(--typo-size-md);
+ --el-dl-line-height: var(--typo-leading-normal);
+ --el-dl-vspace-base: calc(1em * var(--el-dl-line-height));
+ --el-dl-vspace-top: calc(var(--el-dl-vspace-base) * var(--vspace-snug));
+ --el-dl-vspace-bottom: calc(var(--el-dl-vspace-base) * var(--vspace-compressed));
+
+ /* === DT VARIABLES === */
+ --el-dt-color: var(--color-text-inverse);
+ --el-dt-background: var(--color-surface-inverse);
+ --el-dt-font-family: var(--font-header);
+ --el-dt-font-size: var(--typo-size-lg);
+ --el-dt-font-weight: var(--typo-weight-bold);
+ --el-dt-line-height: 1.4;
+ --el-dt-text-transform: uppercase;
+ --el-dt-letter-spacing: 0.035em;
+ --el-dt-padding: var(--spacing-snug);
+ --el-dt-vspace-base: calc(1em * var(--el-dt-line-height));
+ --el-dt-vspace-top: calc(var(--el-dt-vspace-base) * var(--vspace-snug));
+ --el-dt-vspace-bottom: calc(var(--el-dt-vspace-base) * var(--vspace-compressed));
+
+ /* === DD VARIABLES === */
+ --el-dd-color: var(--color-text-primary);
+ --el-dd-font-family: var(--font-body);
+ --el-dd-font-size: var(--typo-size-md);
+ --el-dd-line-height: var(--typo-leading-normal);
+ --el-dd-indent: 0 var(--spacing-comfortable);
+ --el-dd-vspace-base: calc(1em * var(--el-dd-line-height));
+ --el-dd-vspace-top: calc(var(--el-dd-vspace-base) * var(--vspace-compressed));
+ --el-dd-vspace-bottom: calc(var(--el-dd-vspace-base) * var(--vspace-tight));
+
+ /* === TABLE VARIABLES === */
+ --el-table-font-size: var(--typo-size-sm);
+ --el-table-line-height: 1.2;
+ --el-table-border: var(--size-2) solid var(--color-text-primary);
+ --el-table-vspace-top: var(--spacing-tight);
+ --el-table-vspace-bottom: var(--spacing-tight);
+
+ /* === TH VARIABLES === */
+ --el-th-color: var(--color-text-inverse);
+ --el-th-background: var(--color-surface-inverse);
+ --el-th-font-family: var(--font-header);
+ --el-th-font-size: var(--typo-size-sm);
+ --el-th-font-weight: var(--typo-weight-black);
+ --el-th-text-transform: uppercase;
+ --el-th-line-height: var(--el-table-line-height);
+ --el-th-padding: 0 var(--spacing-snug) var(--spacing-snug);
+
+ /* === TD VARIABLES === */
+ --el-td-color: var(--color-text-primary);
+ --el-td-font-family: var(--font-mono);
+ --el-td-font-size: var(--typo-size-sm);
+ --el-td-line-height: var(--el-table-line-height);
+ --el-td-padding: var(--spacing-snug);
+ --el-td-border: var(--size-1) solid var(--color-text-secondary);
+
+ /* === CAPTION VARIABLES === */
+ --el-caption-color: var(--color-text-tertiary);
+ --el-caption-font-family: var(--font-body);
+ --el-caption-font-size: var(--typo-size-sm);
+ --el-caption-font-style: italic;
+ --el-caption-text-align: center;
+
+ /* === FIGCAPTION VARIABLES === */
+ --el-figcaption-color: var(--color-text-tertiary);
+ --el-figcaption-font-family: var(--font-body);
+ --el-figcaption-font-size: var(--typo-size-xs);
+ --el-figcaption-font-style: italic;
+ --el-figcaption-text-align: center;
+
+ /* === SMALL VARIABLES === */
+ --el-small-color: var(--color-text-tertiary);
+ --el-small-font-family: var(--font-body);
+ --el-small-font-size: var(--typo-size-xs);
+
+ /* HR */
+ --hr-height: var(--size-3);
+ --hr-margin: var(--spacing-relaxed) 0;
+ --hr-color: var(--color-text-tertiary);
+ --hr-symbol-content: "▼";
+ --hr-symbol-size: var(--typo-size-4xl);
+ --hr-symbol-space: 0 0.25em;
+ --hr-symbol-line-height: var(--typo-leading-compressed);
+ --hr-symbol-color: var(--color-text-tertiary);
+ --hr-symbol-background: var(--color-surface-base);
+
+ /* Header */
+ --el-header-font-size: var(--typo-size-responsive);
+ --el-header-line-height: var(--typo-leading-snug);
+ --el-header-paddingY: var(--spacing-snug);
+ --el-header-height: calc(
+ (var(--typo-size-responsive) * var(--el-header-line-height)) +
+ (var(--el-header-paddingY) * 2)
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/styles/globals/foundation.css b/src/styles/globals/foundation.css
new file mode 100644
index 0000000..2328308
--- /dev/null
+++ b/src/styles/globals/foundation.css
@@ -0,0 +1,373 @@
+@layer reset {
+ /*
+Foundation inspired by Tailwind CSS Preflight. (https://tailwindcss.com/docs/preflight)
+*/
+
+ /*
+ 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+ 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+ */
+
+ *,
+ ::before,
+ ::after {
+ box-sizing: border-box; /* 1 */
+ border-style: solid; /* 2 */
+ border-width: 0; /* 2 */
+ }
+
+ /*
+ 1. Use a consistent sensible line-height in all browsers.
+ 2. Prevent adjustments of font size after orientation changes in iOS.
+ 3. Use a more readable tab size.
+ 4. Use the system's `sans` font-family by default.
+ */
+
+ html {
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
+ "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
+
+ line-height: 1.5; /* 1 */
+ text-size-adjust: 100%; /* 2 */
+ tab-size: 4; /* 3 */
+ }
+
+ /*
+ 1. Remove the margin in all browsers.
+ 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+ */
+
+ body {
+ margin: 0; /* 1 */
+ line-height: inherit; /* 2 */
+ }
+
+ /*
+ 1. Add the correct height in Firefox.
+ 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+ 3. Ensure horizontal rules are visible by default.
+ */
+
+ hr {
+ height: 0; /* 1 */
+ border-top-width: 1px; /* 3 */
+ color: inherit; /* 2 */
+ }
+
+ /*
+ Add the correct text decoration in Chrome, Edge, and Safari.
+ */
+
+ abbr:where([title]) {
+ text-decoration: underline dotted;
+ }
+
+ /*
+ Remove the default font size and weight for headings.
+ */
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ font-size: inherit;
+ font-weight: inherit;
+ }
+
+ /*
+ Reset links to optimize for opt-in styling instead of opt-out.
+ */
+
+ a {
+ color: inherit;
+ text-decoration: inherit;
+ }
+
+ /*
+ Add the correct font weight in Edge and Safari.
+ */
+
+ b,
+ strong {
+ font-weight: bolder;
+ }
+
+ /*
+ 1. Use the system's `mono` font family by default.
+ 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+ code,
+ kbd,
+ samp,
+ pre {
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
+ "Liberation Mono", "Courier New", monospace; /* 1 */
+
+ font-size: 1em; /* 2 */
+ }
+
+ /*
+ Add the correct font size in all browsers.
+ */
+
+ small {
+ font-size: 80%;
+ }
+
+ /*
+ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+ */
+
+ sub,
+ sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+ }
+
+ sub {
+ bottom: -0.25em;
+ }
+
+ sup {
+ top: -0.5em;
+ }
+
+ /*
+ 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+ 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+ 3. Remove gaps between table borders by default.
+ */
+
+ table {
+ border-collapse: collapse; /* 3 */
+ border-color: inherit; /* 2 */
+ text-indent: 0; /* 1 */
+ }
+
+ /*
+ 1. Change the font styles in all browsers.
+ 2. Remove the margin in Firefox and Safari.
+ 3. Remove default padding in all browsers.
+ */
+
+ button,
+ input,
+ optgroup,
+ select,
+ textarea {
+ margin: 0; /* 2 */
+ padding: 0; /* 3 */
+
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 1 */
+ font-weight: inherit; /* 1 */
+ line-height: inherit; /* 1 */
+ color: inherit; /* 1 */
+ }
+
+ /*
+ Remove the inheritance of text transform in Edge and Firefox.
+ */
+
+ button,
+ select {
+ text-transform: none;
+ }
+
+ /*
+ 1. Correct the inability to style clickable types in iOS and Safari.
+ 2. Remove default button styles.
+ */
+
+ button,
+ [type="button"],
+ [type="reset"],
+ [type="submit"] {
+ appearance: auto; /* 1 */
+ background-color: transparent; /* 2 */
+ background-image: none; /* 2 */
+ }
+
+ /*
+ Use the modern Firefox focus style for all focusable elements.
+ */
+
+ :-moz-focusring {
+ outline: auto;
+ }
+
+ /*
+ Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+ */
+
+ :-moz-ui-invalid {
+ box-shadow: none;
+ }
+
+ /*
+ Add the correct vertical alignment in Chrome and Firefox.
+ */
+
+ progress {
+ vertical-align: baseline;
+ }
+
+ /*
+ Correct the cursor style of increment and decrement buttons in Safari.
+ */
+
+ ::-webkit-inner-spin-button,
+ ::-webkit-outer-spin-button {
+ height: auto;
+ }
+
+ /*
+ 1. Correct the odd appearance in Chrome and Safari.
+ 2. Correct the outline style in Safari.
+ */
+
+ [type="search"] {
+ appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
+ }
+
+ /*
+ Remove the inner padding in Chrome and Safari on macOS.
+ */
+
+ ::-webkit-search-decoration {
+ appearance: none;
+ }
+
+ /*
+ 1. Correct the inability to style clickable types in iOS and Safari.
+ 2. Change font properties to `inherit` in Safari.
+ */
+
+ ::-webkit-file-upload-button {
+ font: inherit; /* 2 */
+ appearance: auto; /* 1 */
+ }
+
+ /*
+ Add the correct display in Chrome and Safari.
+ */
+
+ summary {
+ display: list-item;
+ }
+
+ /*
+ Removes the default spacing and border for appropriate elements.
+ */
+
+ blockquote,
+ dl,
+ dd,
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6,
+ hr,
+ figure,
+ p,
+ pre {
+ margin: 0;
+ }
+
+ fieldset {
+ margin: 0;
+ padding: 0;
+ }
+
+ legend {
+ padding: 0;
+ }
+
+ ol,
+ ul,
+ menu {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ }
+
+ /*
+ Prevent resizing textareas horizontally by default.
+ */
+
+ textarea {
+ resize: vertical;
+ }
+
+ /*
+ 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+ */
+
+ input::placeholder,
+ textarea::placeholder {
+ opacity: 1; /* 1 */
+ }
+
+ /*
+ Set the default cursor for buttons.
+ */
+
+ button,
+ [role="button"] {
+ cursor: pointer;
+ }
+
+ /*
+ Make sure disabled buttons don't get the pointer cursor.
+ */
+
+ :disabled {
+ cursor: default;
+ }
+
+ /*
+ 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+ 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+ This can trigger a poorly considered lint error in some tools but is included by design.
+ */
+
+ img,
+ svg,
+ video,
+ canvas,
+ audio,
+ iframe,
+ embed,
+ object {
+ display: block; /* 1 */
+ vertical-align: middle; /* 2 */
+ }
+
+ /*
+ Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+ */
+
+ img,
+ video {
+ max-width: 100%;
+ height: auto;
+ }
+
+ /*
+ Make elements with the HTML hidden attribute stay hidden by default.
+ */
+
+ [hidden] {
+ display: none;
+ }
+
+}
\ No newline at end of file
diff --git a/src/styles/globals/typography.css b/src/styles/globals/typography.css
new file mode 100644
index 0000000..dd245eb
--- /dev/null
+++ b/src/styles/globals/typography.css
@@ -0,0 +1,73 @@
+@layer tokens {
+ :root {
+ /* === TYPOGRAPHY === */
+
+ /* == Font Families == */
+ --font-header: var(--font-geist-sans);
+ --font-display: var(--font-blaka);
+ --font-body: var(--font-iosevka-slab);
+ --font-mono: var(--font-iosevka-mono);
+
+ /* == Font Sizes == */
+ --typo-size-responsive: clamp(1rem, 2.5vw, 1.25rem);
+ --typo-size-base: 16px;
+ --typo-size-8xl: 8em;
+ --typo-size-7xl: 6.375em;
+ --typo-size-6xl: 5.0625em;
+ --typo-size-5xl: 4em;
+ --typo-size-4xl: 3.1875em;
+ --typo-size-3xl: 2.5em;
+ --typo-size-2xl: 2em;
+ --typo-size-xl: 1.5625em;
+ --typo-size-lg: 1.25em;
+ --typo-size-md: 1em;
+ --typo-size-sm: 0.8125em;
+ --typo-size-xs: 0.625em;
+ --typo-size-2xs: 0.5em;
+
+ /* == Font Weights == */
+ --typo-weight-thin: 100;
+ --typo-weight-extralight: 200;
+ --typo-weight-light: 300;
+ --typo-weight-normal: 400;
+ --typo-weight-medium: 500;
+ --typo-weight-semibold: 600;
+ --typo-weight-bold: 700;
+ --typo-weight-extrabold: 800;
+ --typo-weight-black: 900;
+
+ /* == Letter Spacing == */
+ --typo-spacing-tightest: -0.05em;
+ --typo-spacing-tighter: -0.025em;
+ --typo-spacing-tight: -0.0125em;
+ --typo-spacing-normal: 0em;
+ --typo-spacing-relaxed: 0.025em;
+ --typo-spacing-comfortable: 0.05em;
+ --typo-spacing-loose: 0.1em;
+ --typo-spacing-looser: 0.15em;
+ --typo-spacing-loosest: 0.2em;
+
+ /* == Line Height == */
+ --typo-leading-compressed: 1.0;
+ --typo-leading-tight: 1.125;
+ --typo-leading-snug: 1.25;
+ --typo-leading-cozy: 1.375;
+ --typo-leading-normal: 1.5;
+ --typo-leading-relaxed: 1.625;
+ --typo-leading-comfortable: 1.75;
+ --typo-leading-loose: 1.875;
+ --typo-leading-spacious: 2.0;
+
+ /* == Vertical Spacing == */
+ --vspace-compressed: 0.25;
+ --vspace-tight: 0.5;
+ --vspace-snug: 0.75;
+ --vspace-cozy: 1;
+ --vspace-normal: 1.25;
+ --vspace-relaxed: 1.5;
+ --vspace-comfortable: 1.75;
+ --vspace-loose: 2;
+ --vspace-spacious: 2.5;
+
+ }
+}
\ No newline at end of file
diff --git a/src/styles/mixins/animations.css b/src/styles/mixins/animations.css
new file mode 100644
index 0000000..e7e060c
--- /dev/null
+++ b/src/styles/mixins/animations.css
@@ -0,0 +1,688 @@
+@define-mixin anim-img-overexposure {
+ &:hover {
+ animation: var(--kf-overexposure) var(--img-overexposure-timing);
+ }
+}
+
+@define-mixin anim-img-contrastslam {
+ &:hover {
+ filter: grayscale(var(--base-grayscale)) contrast(var(--contrast-amount)) brightness(var(--brightness-amount));
+ transition: filter var(--img-contrastslam-duration) var(--img-contrastslam-timing);
+ }
+}
+
+@define-mixin anim-img-colorbleed {
+ &:hover {
+ animation: var(--kf-color-bleed) var(--img-colorbleed-duration) var(--img-colorbleed-timing);
+ }
+}
+
+@define-mixin anim-img-filmburn {
+ &:hover {
+ animation: var(--kf-film-burn) var(--img-filmburn-duration) var(--img-filmburn-timing);
+ }
+}
+
+@define-mixin anim-img-malfunction {
+ &:hover {
+ animation: var(--kf-malfunction) var(--img-malfunction-duration) var(--img-malfunction-timing);
+ }
+}
+
+@define-mixin anim-img-tonerstarvation {
+ &:hover {
+ animation: var(--kf-toner-fade) var(--img-tonerstarvation-duration) var(--img-tonerstarvation-timing);
+ }
+}
+
+@define-mixin anim-img-corruption {
+ &:hover {
+ animation: var(--kf-digital-corrupt) var(--img-corruption-duration) var(--img-corruption-timing);
+ }
+}
+
+@define-mixin anim-img-starkflash {
+ &:hover {
+ animation: var(--kf-stark-flash) var(--img-starkflash-duration) var(--img-starkflash-timing);
+ }
+}
+
+/* === TEXT ANIMATION MIXINS === */
+
+@define-mixin anim-txt-strikethrough-marker {
+ position: relative;
+
+ &::after {
+ content: '';
+
+ position: absolute;
+ top: 50%;
+ left: 0;
+ transform: translateY(-50%);
+
+ width: 0%;
+ height: 1px;
+ border: 0 solid var(--strike-color);
+ border-radius: var(--strike-radius);
+ border-bottom-right-radius: 16px;
+
+ background: var(--strike-color);
+
+ transition: width var(--strike-duration) var(--strike-timing), border-width var(--strike-duration) var(--strike-timing);
+
+ corner-shape: bevel;
+ }
+
+ &:hover::after {
+ width: 100%;
+ border-width: var(--strike-border-width);
+ }
+}
+
+@define-mixin anim-txt-strikethrough-industrial {
+ position: relative;
+
+ &:hover::after {
+ content: '';
+
+ position: absolute;
+ top: 50%;
+ right: -0.125em;
+ left: -0.125em;
+ transform: translateY(-50%);
+
+ height: var(--strike-height);
+
+ background: var(--strike-color);
+
+ animation: var(--kf-strike-slam) var(--strike-duration) var(--strike-timing);
+ }
+}
+
+@define-mixin anim-txt-markerhighlight {
+ background: linear-gradient(to right, var(--marker-bg) 0%, var(--marker-bg) 0%);
+ background-repeat: no-repeat;
+ background-size: 0% 100%;
+ transition: background-size var(--marker-duration) var(--marker-timing) , color var(--marker-duration) var(--marker-timing) ;
+
+ &:hover {
+ color: var(--marker-fg);
+ background-size: 100% 100%;
+ }
+}
+
+@define-mixin anim-txt-labelmaker {
+ transition: all var(--label-duration) var(--label-timing);
+
+ &:hover {
+ margin: var(--label-margin);
+ padding: var(--label-padding);
+ border: var(--label-border-width) solid var(--label-bg);
+
+ font-weight: var(--label-weight);
+ color: var(--label-fg);
+ text-transform: var(--label-transform);
+ letter-spacing: var(--label-spacing);
+
+ background: var(--label-bg);
+ box-shadow: var(--label-shadow-offset) 0 var(--label-shadow-color);
+ }
+}
+
+@define-mixin anim-txt-rubberstamp {
+ transition: all var(--stamp-duration) var(--stamp-timing);
+
+ &:hover {
+ transform: rotate(var(--stamp-rotate)) scale(var(--stamp-scale)) translateY(var(--stamp-translate));
+
+ margin: var(--stamp-margin);
+ padding: var(--stamp-padding);
+ border: var(--stamp-border-width) solid var(--stamp-bg);
+
+ font-weight: var(--stamp-weight);
+ color: var(--stamp-fg);
+ text-transform: var(--stamp-transform);
+ letter-spacing: var(--stamp-spacing);
+
+ background: var(--stamp-bg);
+ box-shadow: inset 0 0 0 2px var(--stamp-fg), var(--stamp-shadow-offset) 0 var(--stamp-shadow-color);
+ }
+}
+
+@define-mixin anim-txt-pressstamp {
+ transition: all var(--press-duration) var(--press-timing);
+
+ &:hover {
+ transform: scaleY(var(--press-scale-y)) scaleX(var(--press-scale-x)) translateY(var(--press-translate));
+
+ margin: var(--press-margin);
+ padding: var(--press-padding);
+
+ font-weight: var(--press-weight);
+ color: var(--press-fg);
+ letter-spacing: var(--press-spacing);
+
+ background: var(--press-bg);
+ box-shadow: 0 0 0 1px var(--press-border-color), 0 2px 0 var(--press-shadow-1), 0 4px 0 var(--press-shadow-2);
+ }
+}
+
+@define-mixin anim-txt-typewriter {
+ position: relative;
+
+ &::after {
+ content: '';
+
+ position: absolute;
+ bottom: var(--typewriter-offset);
+ left: 0;
+
+ width: 0%;
+ height: var(--typewriter-height);
+
+ background: repeating-linear-gradient(to right, var(--typewriter-color) 0, var(--typewriter-color) var(--typewriter-dash-length), transparent var(--typewriter-dash-length), transparent var(--typewriter-gap-length));
+
+ transition: width var(--typewriter-duration) var(--typewriter-timing);
+ }
+
+ &:hover::after {
+ width: 100%;
+ }
+}
+
+@define-mixin anim-txt-hardinvert {
+ transition: all var(--invert-duration) var(--invert-timing);
+
+ &:hover {
+ transform: scale(var(--invert-scale));
+
+ font-weight: var(--invert-weight);
+ color: var(--invert-fg);
+ letter-spacing: var(--invert-spacing);
+
+ background: var(--invert-bg);
+ }
+}
+
+@define-mixin anim-txt-pointer {
+ position: relative;
+
+ &::before,
+ &::after {
+ position: absolute;
+ color: var(--pointer-color);
+ opacity: 0;
+ transition: var(--pointer-transition);
+ }
+
+ &::before {
+ content: var(--pointer-left-symbol);
+ left: 0;
+ }
+
+ &::after {
+ content: var(--pointer-right-symbol);
+ right: 0;
+ }
+
+ &:hover::before {
+ transform: translateX(calc(var(--pointer-distance) * -1));
+ opacity: 1;
+ }
+
+ &:hover::after {
+ transform: translateX(var(--pointer-distance));
+ opacity: 1;
+ }
+}
+
+@define-mixin anim-txt-cornerbox {
+ position: relative;
+ margin: var(--corner-margin);
+ padding: var(--corner-padding);
+
+ &::before,
+ &::after {
+ content: '';
+
+ position: absolute;
+
+ width: var(--corner-size);
+ height: var(--corner-size);
+ border: var(--corner-border);
+
+ opacity: 0;
+
+ transition: var(--corner-transition);
+ }
+
+ &::before {
+ top: 0;
+ left: 0;
+ border-right: none;
+ border-bottom: none;
+ }
+
+ &::after {
+ right: 0;
+ bottom: 0;
+ border-top: none;
+ border-left: none;
+ }
+
+ &:hover {
+ &::before,
+ &::after {
+ opacity: 1;
+ }
+ }
+}
+
+@define-mixin anim-txt-characterglitch {
+ &:hover {
+ animation: var(--kf-char-scramble) var(--glitch-duration) var(--glitch-timing);
+ }
+}
+
+@define-mixin anim-txt-pixelshift {
+ position: relative;
+
+ &::before {
+ content: '';
+
+ position: absolute;
+ top: 100%;
+ left: 0;
+
+ width: 100%;
+ height: var(--pixel-line-height);
+
+ opacity: 0;
+ background: var(--pixel-bg);
+ }
+
+ &:hover {
+ color: var(--pixel-fg);
+ animation: var(--kf-text-glitch) var(--pixel-duration) var(--pixel-timing);
+
+ &::before {
+ opacity: 1;
+ animation: var(--kf-glitch-line) var(--pixel-duration) var(--pixel-timing);
+ }
+ }
+}
+
+@define-mixin anim-txt-redacted {
+ transition: all var(--redacted-duration) var(--redacted-timing);
+
+ &::after {
+ content: '';
+
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ width: 0%;
+ height: 100%;
+
+ background: var(--redacted-bg);
+
+ transition: width var(--redacted-duration) var(--redacted-timing);
+ }
+
+ &:hover {
+ color: transparent;
+ text-shadow: var(--redacted-shadow);
+
+ &::after {
+ width: 100%;
+ }
+ }
+}
+
+@define-mixin anim-txt-xray {
+ transition: all var(--xray-duration) var(--xray-timing);
+
+ &:hover {
+ font-weight: var(--xray-weight);
+ color: var(--xray-fg);
+ text-shadow: 0 0 2px var(--xray-glow);
+
+ background: var(--xray-bg);
+ filter: invert(var(--xray-invert)) contrast(var(--xray-contrast)) brightness(var(--xray-brightness)) saturate(var(--xray-saturate));
+ box-shadow: inset 0 0 0 1px var(--xray-border), 0 0 15px var(--xray-outer-glow);
+ }
+}
+
+@define-mixin anim-txt-strikethrough-marker_focus {
+ position: relative;
+
+ &::after {
+ content: '';
+
+ position: absolute;
+ top: 50%;
+ left: 0;
+ transform: translateY(-50%);
+
+ width: 0%;
+ height: 1px;
+ border: 0 solid var(--strike-color);
+ border-radius: var(--strike-radius);
+ border-bottom-right-radius: 16px;
+
+ background: var(--strike-color);
+
+ transition: width var(--strike-duration) var(--strike-timing), border-width var(--strike-duration) var(--strike-timing);
+
+ corner-shape: bevel;
+ }
+
+ &:focus::after {
+ width: 100%;
+ border-width: var(--strike-border-width);
+ }
+}
+
+@define-mixin anim-txt-strikethrough-industrial_focus {
+ position: relative;
+
+ &:focus::after {
+ content: '';
+
+ position: absolute;
+ top: 50%;
+ right: -0.125em;
+ left: -0.125em;
+ transform: translateY(-50%);
+
+ height: var(--strike-height);
+
+ background: var(--strike-color);
+
+ animation: var(--kf-strike-slam) var(--strike-duration) var(--strike-timing);
+ }
+}
+
+@define-mixin anim-txt-markerhighlight_focus {
+ background: linear-gradient(to right, var(--marker-bg) 0%, var(--marker-bg) 0%);
+ background-repeat: no-repeat;
+ background-size: 0% 100%;
+ transition: background-size var(--marker-duration) var(--marker-timing) , color var(--marker-duration) var(--marker-timing) ;
+
+ &:focus {
+ color: var(--marker-fg);
+ background-size: 100% 100%;
+ }
+}
+
+@define-mixin anim-txt-labelmaker_focus {
+ transition: all var(--label-duration) var(--label-timing);
+
+ &:focus {
+ margin: var(--label-margin);
+ padding: var(--label-padding);
+ border: var(--label-border-width) solid var(--label-bg);
+
+ font-weight: var(--label-weight);
+ color: var(--label-fg);
+ text-transform: var(--label-transform);
+ letter-spacing: var(--label-spacing);
+
+ background: var(--label-bg);
+ box-shadow: var(--label-shadow-offset) 0 var(--label-shadow-color);
+ }
+}
+
+@define-mixin anim-txt-rubberstamp_focus {
+ transition: all var(--stamp-duration) var(--stamp-timing);
+
+ &:focus {
+ transform: rotate(var(--stamp-rotate)) scale(var(--stamp-scale)) translateY(var(--stamp-translate));
+
+ margin: var(--stamp-margin);
+ padding: var(--stamp-padding);
+ border: var(--stamp-border-width) solid var(--stamp-bg);
+
+ font-weight: var(--stamp-weight);
+ color: var(--stamp-fg);
+ text-transform: var(--stamp-transform);
+ letter-spacing: var(--stamp-spacing);
+
+ background: var(--stamp-bg);
+ box-shadow: inset 0 0 0 2px var(--stamp-fg), var(--stamp-shadow-offset) 0 var(--stamp-shadow-color);
+ }
+}
+
+@define-mixin anim-txt-pressstamp_focus {
+ transition: all var(--press-duration) var(--press-timing);
+
+ &:focus {
+ transform: scaleY(var(--press-scale-y)) scaleX(var(--press-scale-x)) translateY(var(--press-translate));
+
+ margin: var(--press-margin);
+ padding: var(--press-padding);
+
+ font-weight: var(--press-weight);
+ color: var(--press-fg);
+ letter-spacing: var(--press-spacing);
+
+ background: var(--press-bg);
+ box-shadow: 0 0 0 1px var(--press-border-color), 0 2px 0 var(--press-shadow-1), 0 4px 0 var(--press-shadow-2);
+ }
+}
+
+@define-mixin anim-txt-typewriter_focus {
+ position: relative;
+
+ &::after {
+ content: '';
+
+ position: absolute;
+ bottom: var(--typewriter-offset);
+ left: 0;
+
+ width: 0%;
+ height: var(--typewriter-height);
+
+ background: repeating-linear-gradient(to right, var(--typewriter-color) 0, var(--typewriter-color) var(--typewriter-dash-length), transparent var(--typewriter-dash-length), transparent var(--typewriter-gap-length));
+
+ transition: width var(--typewriter-duration) var(--typewriter-timing);
+ }
+
+ &:focus::after {
+ width: 100%;
+ }
+}
+
+@define-mixin anim-txt-hardinvert_focus {
+ transition: all var(--invert-duration) var(--invert-timing);
+
+ &:focus {
+ transform: scale(var(--invert-scale));
+
+ font-weight: var(--invert-weight);
+ color: var(--invert-fg);
+ letter-spacing: var(--invert-spacing);
+
+ background: var(--invert-bg);
+ }
+}
+
+@define-mixin anim-txt-pointer_focus {
+ position: relative;
+
+ &::before,
+ &::after {
+ position: absolute;
+ color: var(--pointer-color);
+ opacity: 0;
+ transition: var(--pointer-transition);
+ }
+
+ &::before {
+ content: var(--pointer-left-symbol);
+ left: 0;
+ }
+
+ &::after {
+ content: var(--pointer-right-symbol);
+ right: 0;
+ }
+
+ &:focus::before {
+ transform: translateX(calc(var(--pointer-distance) * -1));
+ opacity: 1;
+ }
+
+ &:focus::after {
+ transform: translateX(var(--pointer-distance));
+ opacity: 1;
+ }
+}
+
+@define-mixin anim-txt-cornerbox_focus {
+ position: relative;
+ margin: var(--corner-margin);
+ padding: var(--corner-padding);
+
+ &::before,
+ &::after {
+ content: '';
+
+ position: absolute;
+
+ width: var(--corner-size);
+ height: var(--corner-size);
+ border: var(--corner-border);
+
+ opacity: 0;
+
+ transition: var(--corner-transition);
+ }
+
+ &::before {
+ top: 0;
+ left: 0;
+ border-right: none;
+ border-bottom: none;
+ }
+
+ &::after {
+ right: 0;
+ bottom: 0;
+ border-top: none;
+ border-left: none;
+ }
+
+ &:focus {
+ &::before,
+ &::after {
+ opacity: 1;
+ }
+ }
+}
+
+@define-mixin anim-txt-characterglitch_focus {
+ &:focus {
+ animation: var(--kf-char-scramble) var(--glitch-duration) var(--glitch-timing);
+ }
+}
+
+@define-mixin anim-txt-pixelshift {
+ position: relative;
+
+ &::before {
+ content: '';
+
+ position: absolute;
+ top: 100%;
+ left: 0;
+
+ width: 100%;
+ height: var(--pixel-line-height);
+
+ opacity: 0;
+ background: var(--pixel-bg);
+ }
+
+ &:hover {
+ color: var(--pixel-fg);
+ animation: var(--kf-text-glitch) var(--pixel-duration) var(--pixel-timing);
+
+ &::before {
+ opacity: 1;
+ animation: var(--kf-glitch-line) var(--pixel-duration) var(--pixel-timing);
+ }
+ }
+}
+
+@define-mixin anim-txt-pixelshift_focus {
+ position: relative;
+
+ &::before {
+ content: '';
+
+ position: absolute;
+ top: 100%;
+ left: 0;
+
+ width: 100%;
+ height: var(--pixel-line-height);
+
+ opacity: 0;
+ background: var(--pixel-bg);
+ }
+
+ &:focus {
+ color: var(--pixel-fg);
+ animation: var(--kf-text-glitch) var(--pixel-duration) var(--pixel-timing);
+
+ &::before {
+ opacity: 1;
+ animation: var(--kf-glitch-line) var(--pixel-duration) var(--pixel-timing);
+ }
+ }
+}
+
+@define-mixin anim-txt-redacted_focus {
+ transition: all var(--redacted-duration) var(--redacted-timing);
+
+ &::after {
+ content: '';
+
+ position: absolute;
+ top: 0;
+ left: 0;
+
+ width: 0%;
+ height: 100%;
+
+ background: var(--redacted-bg);
+
+ transition: width var(--redacted-duration) var(--redacted-timing);
+ }
+
+ &:focus {
+ color: transparent;
+ text-shadow: var(--redacted-shadow);
+
+ &::after {
+ width: 100%;
+ }
+ }
+}
+
+@define-mixin anim-txt-xray_focus {
+ transition: all var(--xray-duration) var(--xray-timing);
+
+ &:focus {
+ font-weight: var(--xray-weight);
+ color: var(--xray-fg);
+ text-shadow: 0 0 2px var(--xray-glow);
+
+ background: var(--xray-bg);
+ filter: invert(var(--xray-invert)) contrast(var(--xray-contrast)) brightness(var(--xray-brightness)) saturate(var(--xray-saturate));
+ box-shadow: inset 0 0 0 1px var(--xray-border), 0 0 15px var(--xray-outer-glow);
+ }
+}
diff --git a/src/styles/mixins/containers.css b/src/styles/mixins/containers.css
index d79bedc..20e4145 100644
--- a/src/styles/mixins/containers.css
+++ b/src/styles/mixins/containers.css
@@ -1,8 +1,8 @@
-@define-mixin responsive-wrapper $vspacing: 0, $hspacing: var(--spacing-cozy) {
+@define-mixin responsive-wrapper $vspacing: 0, $hspacing: var(--spacing-cozy), $fontSize: var(--typo-size-responsive) {
@mixin mx auto;
max-width: clamp(60ch, 90vw, 90ch);
padding: $vspacing $hspacing;
font-family: var(--font-body);
- font-size: var(--typo-size-responsive);
+ font-size: $fontSize;
}
\ No newline at end of file
diff --git a/src/styles/mixins/decorators.css b/src/styles/mixins/decorators.css
new file mode 100644
index 0000000..f20a632
--- /dev/null
+++ b/src/styles/mixins/decorators.css
@@ -0,0 +1,49 @@
+@define-mixin decorator-bb {
+ padding: var(--bb-spacing, 0);
+ border: var(--bb-border, var(--size-1) solid var(--color-primary));
+ border-top-left-radius: var(--bb-radius-tl, var(--size-1));
+ border-top-right-radius: var(--bb-radius-tr, 0);
+ border-bottom-right-radius: var(--bb-radius-br, 0);
+ border-bottom-left-radius: var(--bb-radius-bl, 0);
+
+ color: var(--bb-fg, var(--color-text-primary));
+
+ background-color: var(--bb-bg, var(--color-primary));
+
+ corner-shape: var(--bb-shapes, bevel);
+}
+
+@define-mixin decorator-torn {
+ position: relative;
+ transform: rotate(1.5deg);
+
+ display: block;
+
+ padding: 0.4em 0.8em;
+ border-radius: 0.3em 0.6em 0.4em 0.5em / 0.5em 0.4em 0.6em 0.3em;
+
+ color: var(--torn-fg);
+
+ background: var(--torn-bg);
+ clip-path: polygon(
+ 8px 0%,
+ 12px 8%,
+ 6px 18%,
+ 14px 32%,
+ 4px 45%,
+ 12px 58%,
+ 7px 72%,
+ 15px 85%,
+ 8px 100%,
+ calc(100% - 8px) 100%,
+ calc(100% - 15px) 85%,
+ calc(100% - 7px) 72%,
+ calc(100% - 12px) 58%,
+ calc(100% - 4px) 45%,
+ calc(100% - 14px) 32%,
+ calc(100% - 6px) 18%,
+ calc(100% - 12px) 8%,
+ calc(100% - 8px) 0%
+ );
+ box-shadow: 2px 2px 4px rgb(0 0 0 / 30%);
+}
\ No newline at end of file
diff --git a/src/styles/mixins/grids.css b/src/styles/mixins/grids.css
index 837753d..190b6de 100644
--- a/src/styles/mixins/grids.css
+++ b/src/styles/mixins/grids.css
@@ -1,11 +1,11 @@
-@define-mixin grid-col $col $spacing {
+@define-mixin grid-col $col, $spacing {
display: grid;
grid-template-columns: repeat($col, minmax(0, 1fr));
gap: $spacing;
}
-@define-mixin grid-rows $row $spacing {
+@define-mixin grid-rows $row, $spacing {
display: grid;
grid-template-rows: repeat(1, minmax(0, 1fr));
gap: $spacing;
diff --git a/src/styles/mixins/position.css b/src/styles/mixins/position.css
new file mode 100644
index 0000000..3ffc414
--- /dev/null
+++ b/src/styles/mixins/position.css
@@ -0,0 +1,4 @@
+@define-mixin position $position: absolute, $inset-values {
+ position: $position;
+ inset: $inset-values;
+}
\ No newline at end of file
diff --git a/src/styles/mixins/spacing.css b/src/styles/mixins/spacing.css
index 013c23e..5bcb086 100644
--- a/src/styles/mixins/spacing.css
+++ b/src/styles/mixins/spacing.css
@@ -1,4 +1,4 @@
-@∂efine-mixin m $spacing {
+@∂efine-mixin ma $spacing {
margin: $spacing;
}
@@ -41,7 +41,7 @@
}
}
-@∂efine-mixin p $spacing {
+@∂efine-mixin pa $spacing {
padding: $spacing;
}
@@ -77,7 +77,7 @@
padding-line-end: $spacing;
}
-@define-mixin space-y $spacing $reverse: 0 {
+@define-mixin space-y $spacing, $reverse: 0 {
& > :not(:last-child) {
margin-block-start: calc($spacing * $reverse);
margin-block-end: calc($spacing * (1 - $reverse));
diff --git a/src/styles/mixins/typography.css b/src/styles/mixins/typography.css
index 4e6f2cd..3ef2b0e 100644
--- a/src/styles/mixins/typography.css
+++ b/src/styles/mixins/typography.css
@@ -40,37 +40,37 @@
letter-spacing: 0.0025em;
}
-@define-mixin text-xl {
+@define-mixin text-xl $leading:1{
font-size: var(--typo-size-xl);
line-height: calc($leading * 1.28);
letter-spacing: 0.0116em;
}
-@define-mixin text-lg {
+@define-mixin text-lg $leading:1 {
font-size: var(--typo-size-lg);
line-height: calc($leading * 1.4);
letter-spacing: 0.022em;
}
-@define-mixin text-md {
+@define-mixin text-md $leading:1 {
font-size: var(--typo-size-md);
line-height: calc($leading * 1.5);
letter-spacing: 0.035em;
}
-@define-mixin text-sm {
+@define-mixin text-sm $leading:1 {
font-size: var(--typo-size-sm);
line-height: calc($leading * 1.5385);
letter-spacing: 0.05em;
}
-@define-mixin text-xs {
+@define-mixin text-xs $leading:1 {
font-size: var(--typo-size-xs);
line-height: calc($leading * 2);
letter-spacing: 0.074em;
}
-@define-mixin text-2xs {
+@define-mixin text-2xs $leading:1 {
font-size: var(--typo-size-2xs);
line-height: calc($leading * 2);
letter-spacing: 0.1em;
diff --git a/src/styles/tokens.css b/src/styles/tokens.css
new file mode 100644
index 0000000..c598797
--- /dev/null
+++ b/src/styles/tokens.css
@@ -0,0 +1,6 @@
+@import url('globals/custom-media.css');
+@import url('globals/typography.css');
+@import url('globals/colors.css');
+@import url('globals/dimensions.css');
+@import url('globals/elements.css');
+@import url('globals/animations.css');
\ No newline at end of file
diff --git a/src/styles/utilities.css b/src/styles/utilities.css
deleted file mode 100644
index e69de29..0000000
diff --git a/src/styles/variables.css b/src/styles/variables.css
deleted file mode 100644
index 25eee5d..0000000
--- a/src/styles/variables.css
+++ /dev/null
@@ -1,5 +0,0 @@
-@import url('./variables/custom-media.css');
-@import url('./variables/typography.css');
-@import url('./variables/colors.css');
-@import url('./variables/dimensions.css');
-@import url('./variables/elements.css');
\ No newline at end of file
diff --git a/src/styles/variables/colors.css b/src/styles/variables/colors.css
deleted file mode 100644
index 2ee4931..0000000
--- a/src/styles/variables/colors.css
+++ /dev/null
@@ -1,156 +0,0 @@
-:root {
- /* === Default Palette === */
-
- /* == Blacks, Grays & Off-Whites == */
- --color-palette-woodsmoke: oklch(15.5% 0.009 274.276deg); /* Woodsmoke: #0B0C10 */
- --color-palette-black-ink: oklch(21.9% 0.006 285.911deg); /* Shark: #1A1A1D */
- --color-palette-charcoal: oklch(26.6% 0.008 240.166deg); /* Shark2: #222629 */
- --color-palette-charcoal-gray: oklch(33.7% 0.026 266.801deg); /* Bright Gray: #313745 */
- --color-palette-slate-gray: oklch(33.3% 0 89.876deg); /* Mineshaft: #363636 */
- --color-palette-gunmetal: oklch(41.1% 0.008 248.035deg); /* Abbey2: #474B4F */
- --color-palette-carbon: oklch(39.8% 0 89.876deg); /* Tundora: #474747 */
- --color-palette-steel-gray: oklch(42.5% 0.003 286.26deg); /* Abbey: #4e4e50 */
- --color-palette-dusty-black: oklch(43.7% 0.013 17.672deg); /* DonJuan: #594F4F */
- --color-palette-stone: oklch(64.3% 0.005 91.471deg); /* Natural Gray: #8E8D8A */
- --color-palette-cloud-gray: oklch(53.6% 0.005 236.565deg); /* Nevada: #6B6E70 */
- --color-palette-silver: oklch(72.9% 0.001 17.185deg); /* Silver Chalice: #A8A7A7 */
- --color-palette-light-silver: oklch(82.6% 0.002 247.844deg); /* Silversand: #C5C6C7 */
- --color-palette-pale-gray: oklch(91.3% 0.004 91.449deg); /* Westar: #E3E2DF */
- --color-palette-pale-stone: oklch(89.7% 0.004 106.481deg); /* Quillgray: #DDDDDA */
- --color-palette-very-pale-gray: oklch(94.3% 0 89.876deg); /* Gallery: #ECECEC */
- --color-palette-off-white: oklch(98.1% 0.003 247.858deg); /* Catskill White: #F7F9fB */
- --color-palette-cat-squeeze: oklch(98.3% 0.004 236.496deg); /* Cat Squeeze: #F7FAFC */
-
- /* == Reds == */
- --color-palette-oxblood: oklch(30.5% 0.122 12.109deg); /* Bordeaux: #5D001E */
- --color-palette-deep-maroon: oklch(37.6% 0.109 11.682deg); /* Crown of Thorns: #6F2232 */
- --color-palette-crimson: oklch(43.2% 0.169 7.14deg); /* Monarch: #950740 */
- --color-palette-cherry-red: oklch(45.4% 0.168 1.454deg); /* Disco: #9A1750 */
- --color-palette-ruby: oklch(52.1% 0.206 15.782deg); /* Shiraz: #C3073F */
- --color-palette-red-clay: oklch(65.1% 0.178 27.507deg); /* Burnt Sienna: #E85A4F */
- --color-palette-lava: oklch(63.6% 0.193 17.075deg); /* Mandy: #E84A5F */
- --color-palette-vivid-scarlet: oklch(66.6% 0.221 15.669deg); /* Radical Red: #FE4365 */
-
- /* == Pinks & Magentas == */
- --color-palette-heliotrope: oklch(68.3% 0.217 353.666deg); /* Heliotrope: #F74FA3 */
- --color-palette-hot-pink: oklch(65.4% 0.2 6.69deg); /* French Rose: #EE4C7C */
- --color-palette-cerise: oklch(60.7% 0.23 18.554deg); /* Amaranth: #EC2049 */
- --color-palette-fuchsia: oklch(49.6% 0.181 351.176deg); /* Hibiscus: #A7226E */
- --color-palette-dusty-rose: oklch(63.2% 0.11 2.384deg); /* Turkish Rose: #C06C84 */
- --color-palette-berry: oklch(60.8% 0.159 2.621deg); /* Mulberry: #CC527A */
- --color-palette-petal-pink: oklch(80.5% 0.063 1.992deg); /* Rose Fog: #E3AFBC */
- --color-palette-coral-pink: oklch(71.2% 0.162 15.607deg); /* Froly: #F67280 */
- --color-palette-sweet-pink: oklch(79.2% 0.114 21.911deg); /* Sweet Pink: #FC9D9A */
-
- /* == Oranges & Browns == */
- --color-palette-persimmon: oklch(68.6% 0.179 40.01deg); /* Flamingo: #F26B38 */
- --color-palette-terracotta: oklch(71.3% 0.131 27.646deg); /* Apricot: #E98074 */
- --color-palette-tan: oklch(82.7% 0.047 76.752deg); /* Akaroa: #D8C3A5 */
- --color-palette-peach: oklch(88.5% 0.072 57.746deg); /* Flesh: #FECEAB */
- --color-palette-pastel-orange: oklch(82.1% 0.092 42.408deg); /* Rosebud: #F8B195 */
- --color-palette-light-apricot: oklch(87.8% 0.066 57.778deg); /* Vivid Tangerine: #F9CDAD */
- --color-palette-bone-white: oklch(92.7% 0.015 94.206deg); /* Satin Linen: #EAE7DC */
-
- /* == Yellows == */
- --color-palette-ripe-lemon: oklch(83.9% 0.167 91.469deg); /* Ripe Lemon: #F2C51D */
- --color-palette-bright-canary: oklch(89% 0.157 97.726deg); /* Energy Yellow: #F7DB4F */
- --color-palette-pale-lemon: oklch(95.6% 0.104 121.573deg); /* Mimosa: #E5FCAD */
-
- /* == Greens == */
- --color-palette-forest-green: oklch(58.1% 0.127 130.001deg); /* Crete: #61892F */
- --color-palette-lime-green: oklch(74.6% 0.18 129.939deg); /* Atlantis: #86C232 */
- --color-palette-electric-green: oklch(87.7% 0.227 137.099deg); /* Screaming Green: #87f74f */
- --color-palette-sage: oklch(75.1% 0.056 144.175deg); /* Norway: #87f74f */
- --color-palette-mint-green: oklch(84.8% 0.098 151.333deg); /* Chinook: #9de0ad */
- --color-palette-olive-drab: oklch(82.5% 0.042 107.285deg); /* Olive Drap: #C8C8A9 */
- --color-palette-seafoam: oklch(71.6% 0.056 165.214deg); /* Acapulco: #83AF9B */
-
- /* == Blues & Teals == */
- --color-palette-dark-navy: oklch(27.3% 0.024 253.693deg); /* Ebony Clay: #1F2833 */
- --color-palette-deep-teal: oklch(32.4% 0.018 225.132deg); /* Outer Space: #2A363B */
- --color-palette-royal-blue: oklch(46.1% 0.07 245.64deg); /* Ming: #355C7D */
- --color-palette-sky-blue: oklch(76.3% 0.129 233.891deg); /* Picton Blue: #4FBFF7 */
- --color-palette-slate-blue: oklch(55.1% 0.043 210.602deg); /* Cutty Sark: #547980 */
- --color-palette-turquoise: oklch(61.5% 0.091 198.865deg); /* Lochinvar: #2F9599 */
- --color-palette-aqua: oklch(68.6% 0.095 190.758deg); /* Keppel: #45ADA8 */
- --color-palette-electric-blue: oklch(90.8% 0.128 188.419deg); /* Aquamarine: #66FCF1 */
- --color-palette-powder-blue: oklch(88.2% 0.062 187.276deg); /* Powder Blue: #a9e6df */
- --color-palette-ice-blue: oklch(99.9% 0.001 197.139deg); /* Twilight Blue: #feffff */
-
- /* === Semantic Colors === */
-
- /* == Primary Colors == */
- --color-primary: var(--color-palette-lava);
- --color-primary-surface: oklch(from var(--color-primary) calc(l + 0.1) c h);
- --color-primary-emphasis: oklch(from var(--color-primary) calc(l - 0.15) c h);
-
- /* == Secondary Colors == */
- --color-secondary: var(--color-palette-olive-drab);
- --color-secondary-surface: oklch(from var(--color-secondary) calc(l + 0.1) c h);
- --color-secondary-emphasis: oklch(from var(--color-secondary) calc(l - 0.15) c h);
-
- /* == Tertiary Colors == */
- --color-tertiary: var(--color-palette-bright-canary);
- --color-tertiary-surface: oklch(from var(--color-tertiary) calc(l + 0.1) c h);
- --color-tertiary-emphasis: oklch(from var(--color-tertiary) calc(l - 0.15) c h);
-
- /* == Text Base Colors == */
- --color-text-primary: var(--color-palette-black-ink); /* Main Body Texts, headlines */
- --color-text-secondary: var(--color-palette-charcoal); /* Subheading, Secondary Info */
- --color-text-tertiary: var(--color-palette-charcoal-gray); /* Captions, Meta Text */
- --color-text-quarternary: var(--color-palette-carbon); /* Placeholder Text */
- --color-text-inverse: var(--color-palette-ice-blue); /* Text on dark backgrounds */
- --color-text-disabled: var(--color-palette-cloud-gray); /* Disabled form labels, inactive text */
-
- /* == Surface Base Colors == */
- --color-surface-base: var(--color-palette-ice-blue); /* Main page background */
- --color-surface-elevated-1: var(--color-palette-off-white); /* Cards, Panels */
- --color-surface-elevated-2: var(--color-palette-very-pale-gray); /* Modals, Dropdowns */
- --color-surface-elevated-3: var(--color-palette-pale-gray); /* Tooltips, popovers */
- --color-surface-elevated-4: var(--color-palette-light-silver); /* Highest Elevation */
- --color-surface-inverse: var(--color-palette-black-ink); /* Darkest Surface for Contrast */
-
- /* == Border Base Colors == */
- --color-border-subtle: var(--color-palette-silver); /* Subtle Dividers, Card Borders */
- --color-border-normal: var(--color-palette-stone); /* Standard Borders, form fields */
- --color-border-strong: var(--color-palette-charcoal-gray); /* Emphasized Borders */
-
- /* == State Colors == */
- --color-state-error: var(--color-palette-cerise); /* Error Text, Container, icons */
- --color-state-warning: var(--color-palette-persimmon); /* Warning Text, Container, Icons */
- --color-state-success: var(--color-palette-lime-green); /* Success Text, Container, Icons */
- --color-state-info: var(--color-palette-royal-blue); /* Info Text, Container, Icons */
-
- /* == Link Colors == */
- --color-text-link: var(--color-text-tertiary);
- --color-text-link-hover: var(--color-secondary);
- --color-text-link-visited: var(--color-palette-fuchsia);
-
- /* == Focus States == */
- --color-focus-ring: var(--color-primary);
- --color-focus-ring-offset: var(--color-primary);
- --color-focus-indicator: var(--color-primary-emphasis)
-
- /* == Overlays == */;
- --color-utility-overlay-light: oklch(0% 0 0deg / 10%); /* Light overlays */
- --color-utility-overlay-medium: oklch(0% 0 0deg / 30%); /* Medium overlays */
- --color-utility-overlay-heavy: oklch(0% 0 0deg / 60%); /* Heavy overlays, modal backdrops */
- --color-surface-overlay: var(--color-utility-overlay-medium); /* Modal overlays, backdrop */
- --color-surface-backdrop: var(--color-utility-overlay-heavy); /* Full screen overlays */
-
- /* == Loading/Skeleton == */
- --color-utility-skeleton-base: var(--color-surface-elevated-2); /* Skeleton loader base */
- --color-utility-skeleton-shimmer: var(--color-surface-elevated-1); /* Skeleton shimmer effect */
-
- /* == Dividers == */
- --color-utility-divider: var(--color-border-subtle); /* Section dividers, HR elements */
- --color-utility-divider-strong: var(--color-border-normal); /* Emphasized dividers */
-
- /* == Shadows == */
- --color-utility-shadow: oklch(0% 0 0deg / 10%); /* Drop shadows */
- --color-utility-shadow-strong: oklch(0% 0 0deg / 25%); /* Strong shadows */
-
- /* == Highlights == */
- --color-utility-highlight: var(--color-tertiary-surface); /* Text highlighting, search results */
- --color-utility-highlight-strong: var(--color-tertiary); /* Strong highlighting */
-}
\ No newline at end of file
diff --git a/src/styles/variables/custom-media.css b/src/styles/variables/custom-media.css
deleted file mode 100644
index a70ea2c..0000000
--- a/src/styles/variables/custom-media.css
+++ /dev/null
@@ -1,5 +0,0 @@
-@custom-media --bp-mobile (width < 48rem);
-@custom-media --bp-tablet (width >= 48rem) and (width < 80rem);
-@custom-media --bp-tablet-up (width >= 48rem);
-@custom-media --bp-tablet-down (width < 80rem);
-@custom-media --bp-desktop (width >= 80rem);
\ No newline at end of file
diff --git a/src/styles/variables/dimensions.css b/src/styles/variables/dimensions.css
deleted file mode 100644
index 8309be2..0000000
--- a/src/styles/variables/dimensions.css
+++ /dev/null
@@ -1,93 +0,0 @@
-:root {
- /* === DIMENSIONS === */
-
- /* == Base Size Units == */
- --size-0: 0;
- --size-px: 1px;
- --size-05: 0.125rem;
- --size-1: 0.25rem;
- --size-2: 0.5rem;
- --size-3: 0.75rem;
- --size-4: 1rem;
- --size-5: 1.25rem;
- --size-6: 1.5rem;
- --size-8: 2rem;
- --size-10: 2.5rem;
- --size-12: 3rem;
- --size-16: 4rem;
- --size-20: 5rem;
- --size-24: 6rem;
- --size-32: 8rem;
- --size-40: 10rem;
- --size-48: 12rem;
- --size-64: 16rem;
- --size-80: 20rem;
- --size-96: 24rem;
- --size-128: 32rem;
- --size-160: 40rem;
- --size-192: 48rem;
- --size-256: 64rem;
- --size-320: 80rem;
- --size-384: 96rem;
- --size-360: 90rem;
- --size-400: 100rem;
- --size-480: 120rem;
-
- /* == Flexible Dimensions == */
- --dim-full: 100%;
- --dim-1-2: 50%;
- --dim-1-3: 33.3333%;
- --dim-2-3: 66.6667%;
- --dim-1-4: 25%;
- --dim-2-4: var(--dim-1-2);
- --dim-3-4: 75%;
- --dim-1-5: 20%;
- --dim-2-5: 40%;
- --dim-3-5: 60%;
- --dim-4-5: 80%;
- --dim-1-6: 16.6667%;
- --dim-2-6: var(--dim-1-3);
- --dim-3-6: var(--dim-1-2);
- --dim-4-6: var(--dim-2-3);
- --dim-5-6: 83.3333%;
- --dim-1-8: 12.5%;
- --dim-2-8: var(--dim-1-4);
- --dim-3-8: 37.5%;
- --dim-4-8: var(--dim-1-2);
- --dim-5-8: 62.5%;
- --dim-6-8: var(--dim-3-4);
- --dim-7-8: 87.5%;
- --dim-1-10: 10%;
- --dim-2-10: var(--dim-1-5);
- --dim-3-10: 30%;
- --dim-4-10: var(--dim-2-5);
- --dim-5-10: var(--dim-1-2);
- --dim-6-10: var(--dim-3-5);
- --dim-7-10: 70%;
- --dim-8-10: var(--dim-4-5);
- --dim-9-10: 90%;
- --dim-1-12: 8.3333%;
- --dim-2-12: var(--dim-1-6);
- --dim-3-12: var(--dim-1-4);
- --dim-4-12: var(--dim-1-3);
- --dim-5-12: 41.6667%;
- --dim-6-12: var(--dim-1-2);
- --dim-7-12: 58.3333%;
- --dim-8-12: var(--dim-2-3);
- --dim-9-12: var(--dim-3-4);
- --dim-10-12: 83.3333%;
- --dim-11-12: 91.6667%;
-
- /* == Semantic Spacing == */;
- --spacing-none: var(--size-0);
- --spacing-hairline: var(--size-px);
- --spacing-tight: var(--size-1);
- --spacing-snug: var(--size-2);
- --spacing-cozy: var(--size-4);
- --spacing-comfortable: var(--size-6);
- --spacing-relaxed: var(--size-8);
- --spacing-spacious: var(--size-12);
- --spacing-generous: var(--size-16);
- --spacing-luxurious: var(--size-24);
- --spacing-expansive: var(--size-32);
-}
\ No newline at end of file
diff --git a/src/styles/variables/elements.css b/src/styles/variables/elements.css
deleted file mode 100644
index 4cb0a32..0000000
--- a/src/styles/variables/elements.css
+++ /dev/null
@@ -1,255 +0,0 @@
-:root {
- /* === H1 VARIABLES === */
- --el-h1-color: var(--color-text-primary);
- --el-h1-font-family: var(--font-display);
- --el-h1-font-size: var(--typo-size-7xl);
- --el-h1-font-weight: var(--typo-weight-black);
- --el-h1-letter-spacing: -0.0137em;
- --el-h1-line-height: 1.125;
- --el-h1-text-transform: uppercase;
- --el-h1-vspace-base: calc(1em * var(--el-h1-line-height));
- --el-h1-vspace-top: calc(var(--el-h1-vspace-base) * var(--vspace-spacious));
- --el-h1-vspace-bottom: calc(var(--el-h1-vspace-base) * var(--vspace-comfortable));
-
- /* === H2 VARIABLES === */
- --el-h2-color: var(--color-text-primary);
- --el-h2-font-family: var(--font-heading);
- --el-h2-font-size: var(--typo-size-5xl);
- --el-h2-font-weight: var(--typo-weight-black);
- --el-h2-letter-spacing: -0.0096em;;
- --el-h2-line-height: 1.1765;
- --el-h2-text-transform: uppercase;
- --el-h2-vspace-base: calc(1em * var(--el-h2-line-height));
- --el-h2-vspace-top: calc(var(--el-h2-vspace-base) * var(--vspace-snug));
- --el-h2-vspace-bottom: calc(var(--el-h2-vspace-base) * var(--vspace-compressed));
-
- /* === H3 VARIABLES === */
- --el-h3-color: var(--color-text-secondary);
- --el-h3-font-family: var(--font-heading);
- --el-h3-font-size: var(--typo-size-4xl);
- --el-h3-font-weight: var(--typo-weight-extrabold);
- --el-h3-letter-spacing: -0.004em;
- --el-h3-line-height: 1.2;
- --el-h3-text-transform: uppercase;
- --el-h3-vspace-base: calc(1em * var(--el-h3-line-height));
- --el-h3-vspace-top: calc(var(--el-h3-vspace-base) * var(--vspace-cozy));
- --el-h3-vspace-bottom: calc(var(--el-h3-vspace-base) * var(--vspace-snug));
-
- /* === H4 VARIABLES === */
- --el-h4-color: var(--color-text-secondary);
- --el-h4-font-family: var(--font-heading);
- --el-h4-font-size: var(--typo-size-3xl);
- --el-h4-font-weight: var(--typo-weight-extrabold);
- --el-h4-letter-spacing: 0.0025em;
- --el-h4-line-height: 1.125;
- --el-h4-text-transform: uppercase;
- --el-h4-vspace-base: calc(1em * var(--el-h4-line-height));
- --el-h4-vspace-top: calc(var(--el-h4-vspace-base) * var(--vspace-normal));
- --el-h4-vspace-bottom: calc(var(--el-h4-vspace-base) * var(--vspace-tight));
-
- /* === H5 VARIABLES === */
- --el-h5-color: var(--color-text-secondary);
- --el-h5-font-family: var(--font-heading);
- --el-h5-font-size: var(--typo-size-2xl);
- --el-h5-font-weight: var(--typo-weight-extrabold);
- --el-h5-letter-spacing: 0.05em;
- --el-h5-line-height: 1.28;
- --el-h5-text-transform: uppercase;
- --el-h5-vspace-base: calc(1em * var(--el-h5-line-height));
- --el-h5-vspace-top: calc(var(--el-h5-vspace-base) * var(--vspace-cozy));
- --el-h5-vspace-bottom: calc(var(--el-h5-vspace-base) * var(--vspace-tight));
-
- /* === H6 VARIABLES === */
- --el-h6-color: var(--color-text-secondary);
- --el-h6-font-family: var(--font-heading);
- --el-h6-font-size: var(--typo-size-xl);
- --el-h6-font-weight: var(--typo-weight-black);
- --el-h6-letter-spacing: 0.035em;
- --el-h6-line-height: 1.4;
- --el-h6-text-transform: uppercase;
- --el-h6-vspace-base: calc(1em * var(--el-h6-line-height));
- --el-h6-vspace-top: calc(var(--el-h6-vspace-base) * var(--vspace-snug));
- --el-h6-vspace-bottom: calc(var(--el-h6-vspace-base) * var(--vspace-compressed));
-
- /* === PARAGRAPH VARIABLES === */
- --el-p-color: var(--color-text-primary);
- --el-p-font-family: var(--font-body);
- --el-p-font-size: var(--typo-size-md);
- --el-p-font-weight: var(--typo-weight-regular);
- --el-p-line-height: var(--typo-leading-normal);
- --el-p-text-align: justify;
- --el-p-vspace-base: calc(1em * var(--el-p-line-height));
- --el-p-vspace-top: calc(var(--el-p-vspace-base) * var(--vspace-snug));
- --el-p-vspace-bottom: calc(var(--el-p-vspace-base) * var(--vspace-snug));
-
- /* === BLOCKQUOTE VARIABLES === */
- --el-blockquote-color: var(--color-text-tertiary);
- --el-border-color: var(--color-text-tertiary);
- --el-blockquote-font-family: var(--font-body);
- --el-blockquote-font-size: var(--typo-size-md);
- --el-blockquote-font-style: var(--typo-weight-regular);
- --el-blockquote-font-weight: var(--typo-weight-medium);
- --el-blockquote-line-height: var(--typo-leading-comfortable);
- --el-blockquote-vspace-base: calc(1em * var(--el-blockquote-line-height));
- --el-blockquote-vspace-top: calc(var(--el-blockquote-vspace-base) * var(--vspace-snug));
- --el-blockquote-vspace-bottom: calc(var(--el-blockquote-vspace-base) * var(--vspace-snug));
-
- /* === PRE VARIABLES === */
- --el-pre-color: var(--color-text-inverse);
- --el-pre-background: var(--color-surface-inverse);
- --el-pre-font-family: var(--font-mono);
- --el-pre-font-size: var(--typo-size-sm);
- --el-pre-line-height: 1.5385;
- --el-pre-vspace-base: calc(1em * var(--el-pre-line-height));
- --el-pre-vspace-top: calc(var(--el-pre-vspace-base) * var(--vspace-normal));
- --el-pre-vspace-bottom: calc(var(--el-pre-vspace-base) * var(--vspace-normal));
-
- /* === CODE VARIABLES === */
- --el-code-color: var(--color-text-inverse);
- --el-code-background: var(--color-surface-inverse);
- --el-code-font-family: var(--font-mono);
- --el-code-font-size: var(--typo-size-sm);
-
- /* === List Variables (For UL/OL) === */
- --el-list-color: var(--color-text-primary);
- --el-list-line-height: var(--typo-leading-normal);
- --el-list-font-size: var(--typo-size-md);
- --el-list-vspace-base: calc(1em * var(--el-list-line-height));
- --el-list-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-snug));
- --el-list-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-snug));
- --el-list-nested-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-snug));
- --el-list-nested-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-snug));
- --el-li-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-snug));
- --el-li-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-snug));
- --el-li-nested-vspace-top: calc(var(--el-list-vspace-base) * var(--vspace-tight));
- --el-li-nested-vspace-bottom: calc(var(--el-list-vspace-base) * var(--vspace-tight));
-
- /* === UL VARIABLES === */
- --el-ul-indent-l1: var(--spacing-cozy);
- --el-ul-indent-l2: var(--spacing-cozy);
- --el-ul-indent-l3: var(--spacing-cozy);
- --el-ul-indent-l4: var(--spacing-cozy);
- --el-ul-item-padding: var(--spacing-cozy);
- --el-ul-symbol-l1: '⯃';
- --el-ul-symbol-l1-color: var(--color-text-primary);
- --el-ul-symbol-l2: '⯁';
- --el-ul-symbol-l2-color: var(--color-text-primary);
- --el-ul-symbol-l3: '⯆';
- --el-ul-symbol-l3-color: var(--color-text-primary);
- --el-ul-symbol-l4: '⯀';
- --el-ul-symbol-l4-color: var(--color-text-primary);
-
- /* === OL VARIABLES === */
- --el-ol-indent-l1: var(--spacing-cozy);
- --el-ol-item-indent-l1: 1.5em;
- --el-ol-indent-l2: var(--spacing-cozy);
- --el-ol-item-indent-l2: 0.825em;
- --el-ol-indent-l3: var(--spacing-cozy);
- --el-ol-item-indent-l3: 0;
- --el-ol-indent-l4: var(--spacing-cozy);
- --el-ol-item-indent-l4: 0;
- --el-ol-item-padding: var(--spacing-cozy);
- --el-ol-line-height: var(--typo-leading-normal);
- --el-ol-marker-color-l1: var(--color-text-primary);
- --el-ol-prefix-l1: '';
- --el-ol-style-l1: decimal-leading-zero;
- --el-ol-suffix-l1: '.)';
- --el-ol-marker-color-l2: var(--color-text-primary);
- --el-ol-prefix-l2: '';
- --el-ol-style-l2: lower-alpha;
- --el-ol-suffix-l2: '.)';
- --el-ol-marker-color-l3: var(--color-text-primary);
- --el-ol-prefix-l3: '';
- --el-ol-style-l3: upper-roman;
- --el-ol-suffix-l3: '.)';
- --el-ol-marker-color-l4: var(--color-text-primary);
- --el-ol-prefix-l4: '';
- --el-ol-style-l4: lower-greek;
- --el-ol-suffix-l4: '.)';
-
- /* === DL VARIABLES === */
- --el-dl-font-size: var(--typo-size-md);
- --el-dl-line-height: var(--typo-leading-normal);
- --el-dl-vspace-base: calc(1em * var(--el-dl-line-height));
- --el-dl-vspace-top: calc(var(--el-dl-vspace-base) * var(--vspace-snug));
- --el-dl-vspace-bottom: calc(var(--el-dl-vspace-base) * var(--vspace-compressed));
-
- /* === DT VARIABLES === */
- --el-dt-color: var(--color-text-inverse);
- --el-dt-background: var(--color-surface-inverse);
- --el-dt-font-family: var(--font-heading);
- --el-dt-font-size: var(--typo-size-lg);
- --el-dt-font-weight: var(--typo-weight-bold);
- --el-dt-line-height: 1.4;
- --el-dt-text-transform: uppercase;
- --el-dt-letter-spacing: 0.035em;
- --el-dt-padding: var(--spacing-snug);
- --el-dt-vspace-base: calc(1em * var(--el-dt-line-height));
- --el-dt-vspace-top: calc(var(--el-dt-vspace-base) * var(--vspace-snug));
- --el-dt-vspace-bottom: calc(var(--el-dt-vspace-base) * var(--vspace-compressed));
-
- /* === DD VARIABLES === */
- --el-dd-color: var(--color-text-primary);
- --el-dd-font-family: var(--font-body);
- --el-dd-font-size: var(--typo-size-md);
- --el-dd-line-height: var(--typo-leading-normal);
- --el-dd-indent: 0 var(--spacing-comfortable);
- --el-dd-vspace-base: calc(1em * var(--el-dd-line-height));
- --el-dd-vspace-top: calc(var(--el-dd-vspace-base) * var(--vspace-compressed));
- --el-dd-vspace-bottom: calc(var(--el-dd-vspace-base) * var(--vspace-tight));
-
- /* === TABLE VARIABLES === */
- --el-table-font-size: var(--typo-size-sm);
- --el-table-line-height: 1.2;
- --el-table-border: var(--size-2) solid var(--color-text-primary);
- --el-table-vspace-top: var(--spacing-tight);
- --el-table-vspace-bottom: var(--spacing-tight);
-
- /* === TH VARIABLES === */
- --el-th-color: var(--color-text-inverse);
- --el-th-background: var(--color-surface-inverse);
- --el-th-font-family: var(--font-heading);
- --el-th-font-size: var(--typo-size-sm);
- --el-th-font-weight: var(--typo-weight-black);
- --el-th-text-transform: uppercase;
- --el-th-line-height: var(--el-table-line-height);
- --el-th-padding: 0 var(--spacing-snug) var(--spacing-snug);
-
- /* === TD VARIABLES === */
- --el-td-color: var(--color-text-primary);
- --el-td-font-family: var(--font-mono);
- --el-td-font-size: var(--typo-size-sm);
- --el-td-line-height: var(--el-table-line-height);
- --el-td-padding: var(--spacing-snug);
- --el-td-border: var(--size-1) solid var(--color-text-secondary);
-
- /* === CAPTION VARIABLES === */
- --el-caption-color: var(--color-text-tertiary);
- --el-caption-font-family: var(--font-body);
- --el-caption-font-size: var(--typo-size-sm);
- --el-caption-font-style: italic;
- --el-caption-text-align: center;
-
- /* === FIGCAPTION VARIABLES === */
- --el-figcaption-color: var(--color-text-tertiary);
- --el-figcaption-font-family: var(--font-body);
- --el-figcaption-font-size: var(--typo-size-xs);
- --el-figcaption-font-style: italic;
- --el-figcaption-text-align: center;
-
- /* === SMALL VARIABLES === */
- --el-small-color: var(--color-text-tertiary);
- --el-small-font-family: var(--font-body);
- --el-small-font-size: var(--typo-size-xs);
-
- /* HR */
- --hr-height: var(--size-3);
- --hr-margin: var(--spacing-relaxed) 0;
- --hr-color: var(--color-text-tertiary);
- --hr-symbol-content: "▼";
- --hr-symbol-size: var(--typo-size-4xl);
- --hr-symbol-space: 0 0.25em;
- --hr-symbol-line-height: var(--typo-leading-compressed);
- --hr-symbol-color: var(--color-text-tertiary);
- --hr-symbol-background: var(--color-surface-base);
-}
\ No newline at end of file
diff --git a/src/styles/variables/typography.css b/src/styles/variables/typography.css
deleted file mode 100644
index aa5e8ae..0000000
--- a/src/styles/variables/typography.css
+++ /dev/null
@@ -1,71 +0,0 @@
-:root {
- /* === TYPOGRAPHY === */
-
- /* == Font Families == */
- --font-header: var(--font-geist-sans);
- --font-display: var(--font-blaka);
- --font-body: var(--font-iosevka-slab);
- --font-mono: var(--font-iosevka-mono);
-
- /* == Font Sizes == */
- --typo-size-responsive: clamp(1rem, 2.5vw, 1.25rem);
- --typo-size-base: 16px;
- --typo-size-8xl: 8em;
- --typo-size-7xl: 6.375em;
- --typo-size-6xl: 5.0625em;
- --typo-size-5xl: 4em;
- --typo-size-4xl: 3.1875em;
- --typo-size-3xl: 2.5em;
- --typo-size-2xl: 2em;
- --typo-size-xl: 1.5625em;
- --typo-size-lg: 1.25em;
- --typo-size-md: 1em;
- --typo-size-sm: 0.8125em;
- --typo-size-xs: 0.625em;
- --typo-size-2xs: 0.5em;
-
- /* == Font Weights == */
- --typo-weight-thin: 100;
- --typo-weight-extralight: 200;
- --typo-weight-light: 300;
- --typo-weight-normal: 400;
- --typo-weight-medium: 500;
- --typo-weight-semibold: 600;
- --typo-weight-bold: 700;
- --typo-weight-extrabold: 800;
- --typo-weight-black: 900;
-
- /* == Letter Spacing == */
- --typo-spacing-tightest: -0.05em;
- --typo-spacing-tighter: -0.025em;
- --typo-spacing-tight: -0.0125em;
- --typo-spacing-normal: 0em;
- --typo-spacing-relaxed: 0.025em;
- --typo-spacing-comfortable: 0.05em;
- --typo-spacing-loose: 0.1em;
- --typo-spacing-looser: 0.15em;
- --typo-spacing-loosest: 0.2em;
-
- /* == Line Height == */
- --typo-leading-compressed: 1.0;
- --typo-leading-tight: 1.125;
- --typo-leading-snug: 1.25;
- --typo-leading-cozy: 1.375;
- --typo-leading-normal: 1.5;
- --typo-leading-relaxed: 1.625;
- --typo-leading-comfortable: 1.75;
- --typo-leading-loose: 1.875;
- --typo-leading-spacious: 2.0;
-
- /* == Vertical Spacing == */
- --vspace-compressed: 0.25;
- --vspace-tight: 0.5;
- --vspace-snug: 0.75;
- --vspace-cozy: 1;
- --vspace-normal: 1.25;
- --vspace-relaxed: 1.5;
- --vspace-comfortable: 1.75;
- --vspace-loose: 2;
- --vspace-spacious: 2.5;
-
-}
\ No newline at end of file