commit 40810118bd057b15a89367c2a4b7fcd2b4016e20 Author: MiTHRAL Date: Sun Apr 26 23:36:40 2026 -0400 feat: initial commit of Mithral design system extracted from Portal, Shelvarr, and Support Page diff --git a/README.md b/README.md new file mode 100644 index 0000000..e849f55 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# Mithral Design System (Themepo) + +A consistent, arcane-inspired design system used across The Mithral Archive applications. + +## Core Palette + +- **Obsidian**: `#08090C` (Primary Background) +- **Mithral**: `#E2E8F0` (Primary Text / Silver) +- **Mithral Dim**: `#94A3B8` (Secondary Text) +- **Mithral Dark**: `#334155` (Borders / Muted) +- **Arcane Blue**: `#38BDF8` (Accent / Glow) + +## Typography + +- **Runic/Heading**: 'Cinzel Decorative', serif +- **Body**: 'Inter', sans-serif +- **Mono**: 'JetBrains Mono', monospace + +## Usage + +### CSS Variables +Import `variables.css` into your global styles: +```css +@import 'variables.css'; +``` + +### Tailwind CSS +Add the `tailwind.preset.js` to your `tailwind.config.js`: +```javascript +module.exports = { + presets: [require('./tailwind.preset.js')], + // ... rest of config +} +``` + +### Base & Components +Include `base.css` and `components.css` for standard animations, scrollbars, and UI components like the `arcane-circle` or `ledger-row`. + +## Key Components + +- **.arcane-circle**: Rotating background rings. +- **.ledger-row**: Interactive links with the "Mithral Vein" hover effect. +- **.stat-card**: Glowing cards for display metrics. +- **.portal-divider**: Ornamental dividers with gradient lines. +- **.bg-noise**: Film grain overlay effect. diff --git a/base.css b/base.css new file mode 100644 index 0000000..95483c4 --- /dev/null +++ b/base.css @@ -0,0 +1,47 @@ +@import url("https://fonts.googleapis.com/css2?family=Cinzel+Decorative:wght@400;700;900&family=Inter:wght@300;400;500&family=JetBrains+Mono&display=swap"); + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + background-color: var(--obsidian); + color: var(--mithral); + font-family: var(--font-body); + min-height: 100vh; + line-height: 1.6; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Scrollbar */ +::-webkit-scrollbar { + width: 6px; +} +::-webkit-scrollbar-track { + background: transparent; +} +::-webkit-scrollbar-thumb { + background: var(--mithral-dark); + border-radius: 3px; +} +::-webkit-scrollbar-thumb:hover { + background: var(--arcane-blue); +} + +/* Animations */ +@keyframes spin { 100% { transform: rotate(360deg); } } +@keyframes spin-reverse { 100% { transform: rotate(-360deg); } } +@keyframes reveal { to { opacity: 1; transform: translateY(0); } } + +/* Film grain overlay */ +.bg-noise::before { + content: ""; + position: fixed; + inset: 0; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E"); + pointer-events: none; + z-index: 0; +} diff --git a/components.css b/components.css new file mode 100644 index 0000000..e12d8ab --- /dev/null +++ b/components.css @@ -0,0 +1,144 @@ +/* Arcane Background Circle */ +.arcane-circle { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 120vw; + height: 120vw; + max-width: 1400px; + max-height: 1400px; + border: 1px solid rgba(56, 189, 248, 0.05); + border-radius: 50%; + z-index: -1; + pointer-events: none; + animation: spin 120s linear infinite; +} + +.arcane-circle::before, .arcane-circle::after { + content: ''; + position: absolute; + top: 50%; left: 50%; + transform: translate(-50%, -50%); + border-radius: 50%; +} + +.arcane-circle::before { + width: 80%; height: 80%; + border: 1px dashed rgba(226, 232, 240, 0.03); + animation: spin-reverse 80s linear infinite; +} + +.arcane-circle::after { + width: 60%; height: 60%; + border: 1px solid rgba(56, 189, 248, 0.02); + border-top-color: rgba(56, 189, 248, 0.1); + border-bottom-color: rgba(56, 189, 248, 0.1); +} + +.rune-marker { + position: absolute; + width: 8px; height: 8px; + background: var(--arcane-blue); + border-radius: 50%; + box-shadow: 0 0 10px var(--arcane-blue); + top: 0; left: 50%; + transform: translate(-50%, -50%); +} + +/* Ledger Rows / Interactive Links */ +.ledger-row { + display: flex; + justify-content: space-between; + align-items: baseline; + padding: 1.2rem 0; + border-bottom: 1px solid rgba(226, 232, 240, 0.05); + text-decoration: none; + color: inherit; + position: relative; + transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); +} + +.ledger-row::before { + content: ''; + position: absolute; + bottom: -1px; left: 0; + width: 0%; + height: 1px; + background: linear-gradient(90deg, var(--arcane-blue), var(--mithral), transparent); + transition: width 0.6s cubic-bezier(0.16, 1, 0.3, 1); + box-shadow: 0 0 10px var(--arcane-glow); +} + +.ledger-row:hover::before { + width: 100%; +} + +.ledger-row:hover { + padding-left: 1.5rem; + background: linear-gradient(90deg, rgba(56, 189, 248, 0.03), transparent); +} + +/* Title & Header Text */ +.title-rune { + font-family: var(--font-rune); + text-transform: uppercase; + letter-spacing: 0.1em; + text-shadow: 0 0 20px var(--mithral-glow); +} + +.title-glow { + text-shadow: 0 0 20px var(--mithral-glow); +} + +/* Stat Cards */ +.stat-card { + background: var(--surface-card); + border: 1px solid var(--border-arcane); + border-radius: 4px; + padding: 1.5rem 1rem; + text-align: center; + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.stat-card::after { + content: ''; + position: absolute; + bottom: 0; left: 0; right: 0; height: 1px; + background: linear-gradient(90deg, transparent, var(--arcane-blue), transparent); + opacity: 0; + transition: opacity 0.3s; +} + +.stat-card:hover { + background: var(--surface-card-hover); + border-color: var(--arcane-blue); + box-shadow: 0 0 15px rgba(56, 189, 248, 0.15); + transform: translateY(-2px); +} + +.stat-card:hover::after { + opacity: 1; +} + +/* Ornamental Divider */ +.portal-divider { + display: flex; + align-items: center; + gap: 1rem; + color: var(--mithral-dim); + font-family: var(--font-rune); + font-size: 0.9rem; + letter-spacing: 0.15em; + text-transform: uppercase; +} + +.portal-divider::before, +.portal-divider::after { + content: ""; + flex: 1; + height: 1px; + background: linear-gradient(to right, transparent, var(--mithral-dark), transparent); +} diff --git a/tailwind.preset.js b/tailwind.preset.js new file mode 100644 index 0000000..ab9da3e --- /dev/null +++ b/tailwind.preset.js @@ -0,0 +1,50 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + theme: { + extend: { + colors: { + obsidian: "var(--obsidian)", + mithral: { + DEFAULT: "var(--mithral)", + dim: "var(--mithral-dim)", + dark: "var(--mithral-dark)", + glow: "var(--mithral-glow)", + }, + arcane: { + blue: "var(--arcane-blue)", + glow: "var(--arcane-glow)", + }, + surface: { + card: "var(--surface-card)", + "card-hover": "var(--surface-card-hover)", + }, + border: { + arcane: "var(--border-arcane)", + } + }, + fontFamily: { + rune: ["var(--font-rune)", "serif"], + body: ["var(--font-body)", "sans-serif"], + mono: ["var(--font-mono)", "monospace"], + }, + animation: { + "spin-slow": "spin 120s linear infinite", + "spin-reverse-slow": "spin-reverse 80s linear infinite", + "reveal": "reveal 1s ease-out forwards", + "pulse-dot": "pulse-dot 2s infinite", + }, + keyframes: { + "spin-reverse": { + "100%": { transform: "rotate(-360deg)" }, + }, + "reveal": { + "to": { opacity: "1", transform: "translateY(0)" }, + }, + "pulse-dot": { + "0%, 100%": { opacity: "0.5", boxShadow: "0 0 5px var(--arcane-blue)" }, + "50%": { opacity: "1", boxShadow: "0 0 15px var(--arcane-blue)" }, + } + } + }, + }, +}; diff --git a/variables.css b/variables.css new file mode 100644 index 0000000..4a89bc2 --- /dev/null +++ b/variables.css @@ -0,0 +1,25 @@ +:root { + /* Colors */ + --obsidian: #08090C; + --mithral: #E2E8F0; + --mithral-dim: #94A3B8; + --mithral-dark: #334155; + --arcane-blue: #38BDF8; + --arcane-glow: rgba(56, 189, 248, 0.4); + --mithral-glow: rgba(226, 232, 240, 0.2); + + /* Status Colors */ + --success: #10B981; + --danger: #EF4444; + --warning: #F59E0B; + + /* Surfaces */ + --surface-card: rgba(226, 232, 240, 0.02); + --surface-card-hover: rgba(56, 189, 248, 0.05); + --border-arcane: rgba(56, 189, 248, 0.1); + + /* Typography */ + --font-rune: 'Cinzel Decorative', serif; + --font-body: 'Inter', sans-serif; + --font-mono: 'JetBrains Mono', monospace; +}