mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:41:09 +02:00
Commit Message feat: implement comprehensive shared packages architecture for monorepo SUMMARY: Introduce 10 shared packages to unify common code across all 4 web apps, reducing ~3,000 lines of duplicated code and establishing consistent patterns for authentication, UI components, theming, and utilities. NEW SHARED PACKAGES: - @manacore/shared-auth: Unified auth logic (token management, JWT utils, fetch interceptor, storage/device/network adapters) - @manacore/shared-auth-ui: Reusable auth UI (LoginPage, RegisterPage, OAuth buttons for Google/Apple) - @manacore/shared-tailwind: Unified Tailwind config with 4 themes (lume, nature, stone, ocean) and light/dark mode support - @manacore/shared-icons: Phosphor-based icon library (40+ icons) - @manacore/shared-ui: Atomic design system (Text, Button, Badge, Toggle, Input, Modal) - @manacore/shared-i18n: Unified i18n setup with locale detection - @manacore/shared-config: Environment validation with Zod - @manacore/shared-subscriptio n-types: Subscription type definitions - @manacore/shared-subscriptio n-ui: Subscription UI components (planned) EXTENDED PACKAGES: - @manacore/shared-types: Added auth.ts, theme.ts, ui.ts, common.ts - @manacore/shared-utils: Added format.ts, validation.ts APP MIGRATIONS: - memoro/web: Migrated login (549→46 LOC), tailwind (165→12 LOC), removed 15+ duplicate components - manacore/web: Migrated to client-side auth with shared-auth, added new components (Icon, ThemeToggle, Logo) - manadeck/web: Replaced local authService/tokenManager with shared-auth, migrated auth pages - maerchenzauber/web: Added auth setup, stores, components, routes DELETED FILES (migrated to shared packages): - OAuth buttons (Google/Apple) from memoro, manacore, manadeck - Local authService, tokenManager, deviceManager, jwt utils - Duplicate Modal, Toggle, Text components - iconPaths and ManaIcon components - Subscription-related components (CostCard, PackageCard, etc.) BENEFITS: - 92% reduction in login page code - 93% reduction in tailwind config code - Consistent theming across all apps - Single source of truth for auth logic - Easier maintenance and updates BREAKING CHANGES: - Icon imports now from @manacore/shared-icons - Modal imports from @manacore/shared-ui - OAuth config via setGoogleCl ientId()/setAppleConfig()
This commit is contained in:
parent
725db638ea
commit
ef70a1af0b
198 changed files with 11113 additions and 3656 deletions
20
packages/shared-tailwind/package.json
Normal file
20
packages/shared-tailwind/package.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "@manacore/shared-tailwind",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.js",
|
||||
"exports": {
|
||||
".": "./src/index.js",
|
||||
"./preset": "./src/preset.js",
|
||||
"./colors": "./src/colors.js",
|
||||
"./theme.css": "./src/theme-variables.css",
|
||||
"./components.css": "./src/components.css"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.19"
|
||||
}
|
||||
}
|
||||
243
packages/shared-tailwind/src/colors.js
Normal file
243
packages/shared-tailwind/src/colors.js
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/**
|
||||
* Shared color palette for all ManaCore apps
|
||||
*
|
||||
* Theme structure:
|
||||
* - Each theme has light and dark variants
|
||||
* - Semantic color tokens for consistent UI
|
||||
*/
|
||||
|
||||
export const colors = {
|
||||
// Brand color used across subscription/pricing
|
||||
mana: '#4287f5',
|
||||
|
||||
// App-specific primary colors
|
||||
brand: {
|
||||
memoro: '#f8d62b', // Gold
|
||||
manacore: '#6366f1', // Indigo
|
||||
manadeck: '#6366f1', // Indigo
|
||||
storyteller: '#6366f1', // Indigo
|
||||
},
|
||||
|
||||
// Primary color scale (for general use)
|
||||
primary: {
|
||||
50: '#eff6ff',
|
||||
100: '#dbeafe',
|
||||
200: '#bfdbfe',
|
||||
300: '#93c5fd',
|
||||
400: '#60a5fa',
|
||||
500: '#3b82f6',
|
||||
600: '#2563eb',
|
||||
700: '#1d4ed8',
|
||||
800: '#1e40af',
|
||||
900: '#1e3a8a',
|
||||
950: '#172554'
|
||||
},
|
||||
|
||||
// Lume Theme - Modern Gold & Dark
|
||||
lume: {
|
||||
light: {
|
||||
primary: '#f8d62b',
|
||||
primaryButton: '#f8d62b',
|
||||
primaryButtonText: '#000000',
|
||||
secondary: '#D4B200',
|
||||
secondaryButton: '#FFE9A3',
|
||||
contentBackground: '#ffffff',
|
||||
contentBackgroundHover: '#f5f5f5',
|
||||
contentPageBackground: '#ffffff',
|
||||
menuBackground: '#dddddd',
|
||||
menuBackgroundHover: '#cccccc',
|
||||
pageBackground: '#dddddd',
|
||||
text: '#2c2c2c',
|
||||
textSecondary: '#666666',
|
||||
borderLight: '#f2f2f2',
|
||||
border: '#e6e6e6',
|
||||
borderStrong: '#cccccc',
|
||||
error: '#e74c3c',
|
||||
success: '#27ae60',
|
||||
warning: '#f39c12'
|
||||
},
|
||||
dark: {
|
||||
primary: '#f8d62b',
|
||||
primaryButton: '#7C6B16',
|
||||
primaryButtonText: '#ffffff',
|
||||
secondary: '#D4B200',
|
||||
secondaryButton: '#1E1E1E',
|
||||
contentBackground: '#1E1E1E',
|
||||
contentBackgroundHover: '#333333',
|
||||
contentPageBackground: '#121212',
|
||||
menuBackground: '#101010',
|
||||
menuBackgroundHover: '#333333',
|
||||
pageBackground: '#101010',
|
||||
text: '#ffffff',
|
||||
textSecondary: '#a0a0a0',
|
||||
borderLight: '#333333',
|
||||
border: '#424242',
|
||||
borderStrong: '#616161',
|
||||
error: '#e74c3c',
|
||||
success: '#2ecc71',
|
||||
warning: '#f1c40f'
|
||||
}
|
||||
},
|
||||
|
||||
// Nature Theme - Soothing Green
|
||||
nature: {
|
||||
light: {
|
||||
primary: '#4CAF50',
|
||||
primaryButton: '#A08500',
|
||||
primaryButtonText: '#ffffff',
|
||||
secondary: '#81C784',
|
||||
secondaryButton: '#F1F8E9',
|
||||
contentBackground: '#F1F8E9',
|
||||
contentBackgroundHover: '#E8F5E9',
|
||||
contentPageBackground: '#ffffff',
|
||||
menuBackground: '#E8F5E9',
|
||||
menuBackgroundHover: '#C8E6C9',
|
||||
pageBackground: '#FBFDF8',
|
||||
text: '#1B5E20',
|
||||
textSecondary: '#388E3C',
|
||||
borderLight: '#E8F5E9',
|
||||
border: '#C8E6C9',
|
||||
borderStrong: '#A5D6A7',
|
||||
error: '#E57373',
|
||||
success: '#66BB6A',
|
||||
warning: '#FFB74D'
|
||||
},
|
||||
dark: {
|
||||
primary: '#4CAF50',
|
||||
primaryButton: '#FF9500',
|
||||
primaryButtonText: '#000000',
|
||||
secondary: '#81C784',
|
||||
secondaryButton: '#1E1E1E',
|
||||
contentBackground: '#1E1E1E',
|
||||
contentBackgroundHover: '#2E7D32',
|
||||
contentPageBackground: '#121212',
|
||||
menuBackground: '#252525',
|
||||
menuBackgroundHover: '#2E7D32',
|
||||
pageBackground: '#121212',
|
||||
text: '#FFFFFF',
|
||||
textSecondary: '#A5D6A7',
|
||||
borderLight: '#1B5E20',
|
||||
border: '#2E7D32',
|
||||
borderStrong: '#388E3C',
|
||||
error: '#CF6679',
|
||||
success: '#81C784',
|
||||
warning: '#FFD54F'
|
||||
}
|
||||
},
|
||||
|
||||
// Stone Theme - Elegant Slate
|
||||
stone: {
|
||||
light: {
|
||||
primary: '#607D8B',
|
||||
primaryButton: '#FF9500',
|
||||
primaryButtonText: '#000000',
|
||||
secondary: '#90A4AE',
|
||||
secondaryButton: '#ECEFF1',
|
||||
contentBackground: '#ECEFF1',
|
||||
contentBackgroundHover: '#E0E6EA',
|
||||
contentPageBackground: '#ffffff',
|
||||
menuBackground: '#E0E6EA',
|
||||
menuBackgroundHover: '#CFD8DC',
|
||||
pageBackground: '#F5F7F9',
|
||||
text: '#263238',
|
||||
textSecondary: '#546E7A',
|
||||
borderLight: '#ECEFF1',
|
||||
border: '#CFD8DC',
|
||||
borderStrong: '#B0BEC5',
|
||||
error: '#EF5350',
|
||||
success: '#66BB6A',
|
||||
warning: '#FFA726'
|
||||
},
|
||||
dark: {
|
||||
primary: '#78909C',
|
||||
primaryButton: '#FF9500',
|
||||
primaryButtonText: '#000000',
|
||||
secondary: '#90A4AE',
|
||||
secondaryButton: '#1E1E1E',
|
||||
contentBackground: '#1E1E1E',
|
||||
contentBackgroundHover: '#37474F',
|
||||
contentPageBackground: '#121212',
|
||||
menuBackground: '#252525',
|
||||
menuBackgroundHover: '#37474F',
|
||||
pageBackground: '#121212',
|
||||
text: '#FFFFFF',
|
||||
textSecondary: '#B0BEC5',
|
||||
borderLight: '#37474F',
|
||||
border: '#455A64',
|
||||
borderStrong: '#546E7A',
|
||||
error: '#CF6679',
|
||||
success: '#81C784',
|
||||
warning: '#FFD54F'
|
||||
}
|
||||
},
|
||||
|
||||
// Ocean Theme - Tranquil Blue
|
||||
ocean: {
|
||||
light: {
|
||||
primary: '#039BE5',
|
||||
primaryButton: '#FF9500',
|
||||
primaryButtonText: '#000000',
|
||||
secondary: '#4FC3F7',
|
||||
secondaryButton: '#E1F5FE',
|
||||
contentBackground: '#E1F5FE',
|
||||
contentBackgroundHover: '#B3E5FC',
|
||||
contentPageBackground: '#ffffff',
|
||||
menuBackground: '#E1F5FE',
|
||||
menuBackgroundHover: '#B3E5FC',
|
||||
pageBackground: '#F5FCFF',
|
||||
text: '#01579B',
|
||||
textSecondary: '#0277BD',
|
||||
borderLight: '#E1F5FE',
|
||||
border: '#B3E5FC',
|
||||
borderStrong: '#81D4FA',
|
||||
error: '#EF5350',
|
||||
success: '#66BB6A',
|
||||
warning: '#FFA726'
|
||||
},
|
||||
dark: {
|
||||
primary: '#039BE5',
|
||||
primaryButton: '#FF9500',
|
||||
primaryButtonText: '#000000',
|
||||
secondary: '#4FC3F7',
|
||||
secondaryButton: '#1E1E1E',
|
||||
contentBackground: '#1E1E1E',
|
||||
contentBackgroundHover: '#0277BD',
|
||||
contentPageBackground: '#121212',
|
||||
menuBackground: '#252525',
|
||||
menuBackgroundHover: '#0277BD',
|
||||
pageBackground: '#121212',
|
||||
text: '#FFFFFF',
|
||||
textSecondary: '#81D4FA',
|
||||
borderLight: '#01579B',
|
||||
border: '#0277BD',
|
||||
borderStrong: '#0288D1',
|
||||
error: '#CF6679',
|
||||
success: '#81C784',
|
||||
warning: '#FFD54F'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Flat theme colors for direct use in Tailwind configs
|
||||
export const themeColors = {
|
||||
mana: colors.mana,
|
||||
primary: colors.primary,
|
||||
lume: {
|
||||
...colors.lume.light,
|
||||
dark: colors.lume.dark,
|
||||
},
|
||||
nature: {
|
||||
...colors.nature.light,
|
||||
dark: colors.nature.dark,
|
||||
},
|
||||
stone: {
|
||||
...colors.stone.light,
|
||||
dark: colors.stone.dark,
|
||||
},
|
||||
ocean: {
|
||||
...colors.ocean.light,
|
||||
dark: colors.ocean.dark,
|
||||
},
|
||||
};
|
||||
|
||||
export default colors;
|
||||
236
packages/shared-tailwind/src/components.css
Normal file
236
packages/shared-tailwind/src/components.css
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/* Shared Component Styles for Manacore Apps
|
||||
* Import this in your app.css: @import '@manacore/shared-tailwind/components.css';
|
||||
*
|
||||
* Requires theme-variables.css to be imported first for CSS variable support
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--font-body);
|
||||
}
|
||||
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
h1 {
|
||||
@apply text-3xl font-bold;
|
||||
color: var(--color-text);
|
||||
}
|
||||
h2 {
|
||||
@apply text-2xl font-semibold;
|
||||
color: var(--color-text);
|
||||
}
|
||||
h3 {
|
||||
@apply text-xl font-semibold;
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.btn-primary {
|
||||
@apply rounded-lg px-4 py-2 font-semibold transition-colors;
|
||||
background-color: var(--color-primary-button);
|
||||
color: var(--color-primary-button-text);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply rounded-lg px-4 py-2 font-semibold transition-colors;
|
||||
background-color: var(--color-secondary-button);
|
||||
color: var(--color-text);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: var(--color-content-bg-hover);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
@apply rounded-lg px-4 py-2 font-semibold transition-colors;
|
||||
background-color: var(--color-error);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
@apply w-full rounded-lg px-4 py-2 transition-colors;
|
||||
background-color: var(--color-content-bg);
|
||||
color: var(--color-text);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.input-field:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 20%, transparent);
|
||||
}
|
||||
|
||||
.card {
|
||||
@apply rounded-lg p-6 shadow-sm;
|
||||
background-color: var(--color-content-bg);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* Header & Navigation */
|
||||
.header-style {
|
||||
background-color: var(--color-menu-bg);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
@apply text-2xl font-bold;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
@apply transition-colors;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.user-email {
|
||||
@apply text-sm;
|
||||
color: var(--color-text);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Main Content Area */
|
||||
.main-content {
|
||||
background-color: var(--color-page-bg);
|
||||
}
|
||||
|
||||
/* Selected/Active State */
|
||||
.bg-selected {
|
||||
background-color: color-mix(in srgb, var(--color-primary) 10%, transparent);
|
||||
}
|
||||
|
||||
/* Status Badge Colors */
|
||||
.status-completed {
|
||||
background-color: rgba(76, 175, 80, 0.15);
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.status-processing {
|
||||
background-color: color-mix(in srgb, var(--color-primary) 15%, transparent);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.status-failed {
|
||||
background-color: color-mix(in srgb, var(--color-error) 15%, transparent);
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
.status-default {
|
||||
background-color: color-mix(in srgb, var(--color-text) 10%, transparent);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* Info/Alert Boxes */
|
||||
.info-box {
|
||||
background-color: color-mix(in srgb, var(--color-primary) 10%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent);
|
||||
}
|
||||
|
||||
/* Loading Spinner */
|
||||
.spinner-border {
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
/* Focus Ring */
|
||||
.focus\:ring-primary:focus {
|
||||
--tw-ring-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.focus\:ring-2:focus {
|
||||
box-shadow: 0 0 0 2px var(--tw-ring-color, var(--color-primary));
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
/* Theme Color Utilities - in utilities layer for @apply support */
|
||||
.bg-content {
|
||||
background-color: var(--color-content-bg);
|
||||
}
|
||||
|
||||
.bg-content-hover {
|
||||
background-color: var(--color-content-bg-hover);
|
||||
}
|
||||
|
||||
.hover\:bg-content-hover:hover {
|
||||
background-color: var(--color-content-bg-hover);
|
||||
}
|
||||
|
||||
.bg-menu {
|
||||
background-color: var(--color-menu-bg);
|
||||
}
|
||||
|
||||
.bg-menu-hover {
|
||||
background-color: var(--color-menu-bg-hover);
|
||||
}
|
||||
|
||||
.hover\:bg-menu-hover:hover {
|
||||
background-color: var(--color-menu-bg-hover);
|
||||
}
|
||||
|
||||
.bg-panel {
|
||||
background-color: var(--color-panel-bg);
|
||||
}
|
||||
|
||||
.bg-page {
|
||||
background-color: var(--color-page-bg);
|
||||
}
|
||||
|
||||
.border-theme {
|
||||
border-color: var(--color-border);
|
||||
}
|
||||
|
||||
.border-theme-light {
|
||||
border-color: var(--color-border-light);
|
||||
}
|
||||
|
||||
.text-theme {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.text-theme-secondary {
|
||||
color: var(--color-text);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.text-theme-muted {
|
||||
color: var(--color-text);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.bg-primary-button {
|
||||
background-color: var(--color-primary-button);
|
||||
}
|
||||
|
||||
.text-primary-button-text {
|
||||
color: var(--color-primary-button-text);
|
||||
}
|
||||
|
||||
.bg-secondary-button {
|
||||
background-color: var(--color-secondary-button);
|
||||
}
|
||||
}
|
||||
15
packages/shared-tailwind/src/index.js
Normal file
15
packages/shared-tailwind/src/index.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* @manacore/shared-tailwind
|
||||
*
|
||||
* Shared Tailwind CSS configuration for all ManaCore apps.
|
||||
*
|
||||
* Exports:
|
||||
* - preset: Tailwind preset with colors, themes, and design tokens
|
||||
* - colors: Color palette definitions
|
||||
*
|
||||
* Also available:
|
||||
* - @manacore/shared-tailwind/themes.css: CSS custom properties for runtime theming
|
||||
*/
|
||||
|
||||
export { default as preset } from './preset.js';
|
||||
export { colors, default as defaultColors } from './colors.js';
|
||||
158
packages/shared-tailwind/src/preset.js
Normal file
158
packages/shared-tailwind/src/preset.js
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* Shared Tailwind CSS preset for all ManaCore apps
|
||||
*
|
||||
* Usage in tailwind.config.js:
|
||||
* ```
|
||||
* import sharedPreset from '@manacore/shared-tailwind/preset';
|
||||
*
|
||||
* export default {
|
||||
* presets: [sharedPreset],
|
||||
* content: ['./src/**\/*.{html,js,svelte,ts}'],
|
||||
* // app-specific overrides...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
import { colors } from './colors.js';
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
const preset = {
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// Brand colors
|
||||
mana: colors.mana,
|
||||
|
||||
// Primary scale
|
||||
primary: colors.primary,
|
||||
|
||||
// Semantic colors using CSS custom properties
|
||||
// These can be changed at runtime via themes.css
|
||||
background: 'var(--color-background)',
|
||||
foreground: 'var(--color-foreground)',
|
||||
|
||||
// Content areas
|
||||
content: {
|
||||
DEFAULT: 'var(--color-content)',
|
||||
hover: 'var(--color-content-hover)',
|
||||
page: 'var(--color-content-page)',
|
||||
},
|
||||
|
||||
// Menu/sidebar
|
||||
menu: {
|
||||
DEFAULT: 'var(--color-menu)',
|
||||
hover: 'var(--color-menu-hover)',
|
||||
},
|
||||
|
||||
// Text
|
||||
theme: {
|
||||
DEFAULT: 'var(--color-text)',
|
||||
secondary: 'var(--color-text-secondary)',
|
||||
},
|
||||
|
||||
// Borders
|
||||
border: {
|
||||
light: 'var(--color-border-light)',
|
||||
DEFAULT: 'var(--color-border)',
|
||||
strong: 'var(--color-border-strong)',
|
||||
},
|
||||
|
||||
// Buttons
|
||||
'primary-btn': {
|
||||
DEFAULT: 'var(--color-primary-button)',
|
||||
text: 'var(--color-primary-button-text)',
|
||||
},
|
||||
'secondary-btn': 'var(--color-secondary-button)',
|
||||
|
||||
// Feedback colors
|
||||
error: 'var(--color-error)',
|
||||
success: 'var(--color-success)',
|
||||
warning: 'var(--color-warning)',
|
||||
|
||||
// Direct theme colors (for apps that don't use CSS vars)
|
||||
lume: {
|
||||
...colors.lume.light,
|
||||
dark: colors.lume.dark,
|
||||
},
|
||||
nature: {
|
||||
...colors.nature.light,
|
||||
dark: colors.nature.dark,
|
||||
},
|
||||
stone: {
|
||||
...colors.stone.light,
|
||||
dark: colors.stone.dark,
|
||||
},
|
||||
ocean: {
|
||||
...colors.ocean.light,
|
||||
dark: colors.ocean.dark,
|
||||
},
|
||||
},
|
||||
|
||||
// Border radius tokens
|
||||
borderRadius: {
|
||||
'none': '0',
|
||||
'sm': '0.25rem',
|
||||
DEFAULT: '0.375rem',
|
||||
'md': '0.5rem',
|
||||
'lg': '0.75rem',
|
||||
'xl': '1rem',
|
||||
'2xl': '1.5rem',
|
||||
'3xl': '2rem',
|
||||
'full': '9999px',
|
||||
},
|
||||
|
||||
// Box shadow tokens
|
||||
boxShadow: {
|
||||
'sm': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
||||
DEFAULT: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
|
||||
'md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
|
||||
'lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
|
||||
'xl': '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
|
||||
'2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
|
||||
'inner': 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
|
||||
'none': 'none',
|
||||
},
|
||||
|
||||
// Font family
|
||||
fontFamily: {
|
||||
sans: [
|
||||
'Inter',
|
||||
'system-ui',
|
||||
'-apple-system',
|
||||
'BlinkMacSystemFont',
|
||||
'Segoe UI',
|
||||
'Roboto',
|
||||
'Helvetica Neue',
|
||||
'Arial',
|
||||
'sans-serif',
|
||||
],
|
||||
mono: [
|
||||
'JetBrains Mono',
|
||||
'Fira Code',
|
||||
'Menlo',
|
||||
'Monaco',
|
||||
'Consolas',
|
||||
'monospace',
|
||||
],
|
||||
},
|
||||
|
||||
// Animation
|
||||
animation: {
|
||||
'spin-slow': 'spin 3s linear infinite',
|
||||
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
|
||||
'bounce-slow': 'bounce 2s infinite',
|
||||
},
|
||||
|
||||
// Transition
|
||||
transitionDuration: {
|
||||
'250': '250ms',
|
||||
'350': '350ms',
|
||||
'400': '400ms',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
export default preset;
|
||||
183
packages/shared-tailwind/src/theme-variables.css
Normal file
183
packages/shared-tailwind/src/theme-variables.css
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/* Shared Theme CSS Variables for Manacore Apps
|
||||
* Import this in your app.css: @import '@manacore/shared-tailwind/theme.css';
|
||||
*
|
||||
* Features:
|
||||
* - 4 Theme Variants: Lume (default), Nature, Stone, Ocean
|
||||
* - Light and Dark mode for each theme
|
||||
* - Uses data-theme attribute for variant switching
|
||||
* - Uses .dark class for dark mode
|
||||
*/
|
||||
|
||||
:root {
|
||||
--font-body: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
|
||||
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
--font-mono: 'Fira Mono', monospace;
|
||||
}
|
||||
|
||||
/* Default Theme: Lume Light */
|
||||
:root {
|
||||
--color-primary: #f8d62b;
|
||||
--color-primary-button: #f8d62b;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #d4b200;
|
||||
--color-secondary-button: #ffe9a3;
|
||||
--color-content-bg: #ffffff;
|
||||
--color-content-bg-hover: #f5f5f5;
|
||||
--color-content-page-bg: #ffffff;
|
||||
--color-menu-bg: #dddddd;
|
||||
--color-menu-bg-hover: #cccccc;
|
||||
--color-panel-bg: #e8e8e8;
|
||||
--color-page-bg: #dddddd;
|
||||
--color-text: #2c2c2c;
|
||||
--color-border-light: #f2f2f2;
|
||||
--color-border: #999999;
|
||||
--color-border-strong: #cccccc;
|
||||
--color-error: #e74c3c;
|
||||
}
|
||||
|
||||
/* Lume Dark */
|
||||
:root.dark {
|
||||
--color-primary: #f8d62b;
|
||||
--color-primary-button: #7c6b16;
|
||||
--color-primary-button-text: #ffffff;
|
||||
--color-secondary: #d4b200;
|
||||
--color-secondary-button: #1e1e1e;
|
||||
--color-content-bg: #1e1e1e;
|
||||
--color-content-bg-hover: #333333;
|
||||
--color-content-page-bg: #121212;
|
||||
--color-menu-bg: #101010;
|
||||
--color-menu-bg-hover: #333333;
|
||||
--color-panel-bg: #1a1a1a;
|
||||
--color-page-bg: #101010;
|
||||
--color-text: #ffffff;
|
||||
--color-border-light: #333333;
|
||||
--color-border: #424242;
|
||||
--color-border-strong: #616161;
|
||||
--color-error: #e74c3c;
|
||||
}
|
||||
|
||||
/* Nature Light */
|
||||
:root[data-theme='nature'] {
|
||||
--color-primary: #4caf50;
|
||||
--color-primary-button: #a08500;
|
||||
--color-primary-button-text: #ffffff;
|
||||
--color-secondary: #81c784;
|
||||
--color-secondary-button: #f1f8e9;
|
||||
--color-content-bg: #f1f8e9;
|
||||
--color-content-bg-hover: #e8f5e9;
|
||||
--color-content-page-bg: #ffffff;
|
||||
--color-menu-bg: #e8f5e9;
|
||||
--color-menu-bg-hover: #c8e6c9;
|
||||
--color-panel-bg: #eff8f0;
|
||||
--color-page-bg: #fbfdf8;
|
||||
--color-text: #1b5e20;
|
||||
--color-border-light: #e8f5e9;
|
||||
--color-border: #c8e6c9;
|
||||
--color-border-strong: #a5d6a7;
|
||||
--color-error: #e57373;
|
||||
}
|
||||
|
||||
/* Nature Dark */
|
||||
:root[data-theme='nature'].dark {
|
||||
--color-primary: #4caf50;
|
||||
--color-primary-button: #ff9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #81c784;
|
||||
--color-secondary-button: #1e1e1e;
|
||||
--color-content-bg: #1e1e1e;
|
||||
--color-content-bg-hover: #2e7d32;
|
||||
--color-content-page-bg: #121212;
|
||||
--color-menu-bg: #252525;
|
||||
--color-menu-bg-hover: #2e7d32;
|
||||
--color-panel-bg: #2a2a2a;
|
||||
--color-page-bg: #121212;
|
||||
--color-text: #ffffff;
|
||||
--color-border-light: #1b5e20;
|
||||
--color-border: #2e7d32;
|
||||
--color-border-strong: #388e3c;
|
||||
--color-error: #cf6679;
|
||||
}
|
||||
|
||||
/* Stone Light */
|
||||
:root[data-theme='stone'] {
|
||||
--color-primary: #607d8b;
|
||||
--color-primary-button: #ff9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #90a4ae;
|
||||
--color-secondary-button: #eceff1;
|
||||
--color-content-bg: #eceff1;
|
||||
--color-content-bg-hover: #e0e6ea;
|
||||
--color-content-page-bg: #ffffff;
|
||||
--color-menu-bg: #e0e6ea;
|
||||
--color-menu-bg-hover: #cfd8dc;
|
||||
--color-panel-bg: #e8edf0;
|
||||
--color-page-bg: #f5f7f9;
|
||||
--color-text: #263238;
|
||||
--color-border-light: #eceff1;
|
||||
--color-border: #cfd8dc;
|
||||
--color-border-strong: #b0bec5;
|
||||
--color-error: #ef5350;
|
||||
}
|
||||
|
||||
/* Stone Dark */
|
||||
:root[data-theme='stone'].dark {
|
||||
--color-primary: #78909c;
|
||||
--color-primary-button: #ff9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #90a4ae;
|
||||
--color-secondary-button: #1e1e1e;
|
||||
--color-content-bg: #1e1e1e;
|
||||
--color-content-bg-hover: #37474f;
|
||||
--color-content-page-bg: #121212;
|
||||
--color-menu-bg: #252525;
|
||||
--color-menu-bg-hover: #37474f;
|
||||
--color-panel-bg: #2a2a2a;
|
||||
--color-page-bg: #121212;
|
||||
--color-text: #ffffff;
|
||||
--color-border-light: #37474f;
|
||||
--color-border: #455a64;
|
||||
--color-border-strong: #546e7a;
|
||||
--color-error: #cf6679;
|
||||
}
|
||||
|
||||
/* Ocean Light */
|
||||
:root[data-theme='ocean'] {
|
||||
--color-primary: #039be5;
|
||||
--color-primary-button: #ff9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #4fc3f7;
|
||||
--color-secondary-button: #e1f5fe;
|
||||
--color-content-bg: #e1f5fe;
|
||||
--color-content-bg-hover: #b3e5fc;
|
||||
--color-content-page-bg: #ffffff;
|
||||
--color-menu-bg: #e1f5fe;
|
||||
--color-menu-bg-hover: #b3e5fc;
|
||||
--color-panel-bg: #ecf8fe;
|
||||
--color-page-bg: #f5fcff;
|
||||
--color-text: #01579b;
|
||||
--color-border-light: #e1f5fe;
|
||||
--color-border: #b3e5fc;
|
||||
--color-border-strong: #81d4fa;
|
||||
--color-error: #ef5350;
|
||||
}
|
||||
|
||||
/* Ocean Dark */
|
||||
:root[data-theme='ocean'].dark {
|
||||
--color-primary: #039be5;
|
||||
--color-primary-button: #ff9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #4fc3f7;
|
||||
--color-secondary-button: #1e1e1e;
|
||||
--color-content-bg: #1e1e1e;
|
||||
--color-content-bg-hover: #0277bd;
|
||||
--color-content-page-bg: #121212;
|
||||
--color-menu-bg: #252525;
|
||||
--color-menu-bg-hover: #0277bd;
|
||||
--color-panel-bg: #2a2a2a;
|
||||
--color-page-bg: #121212;
|
||||
--color-text: #ffffff;
|
||||
--color-border-light: #01579b;
|
||||
--color-border: #0277bd;
|
||||
--color-border-strong: #0288d1;
|
||||
--color-error: #cf6679;
|
||||
}
|
||||
265
packages/shared-tailwind/src/themes.css
Normal file
265
packages/shared-tailwind/src/themes.css
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
/**
|
||||
* CSS Custom Properties for ManaCore themes
|
||||
*
|
||||
* Usage:
|
||||
* 1. Import in your app.css: @import '@manacore/shared-tailwind/themes.css';
|
||||
* 2. Set theme with data-theme attribute: <html data-theme="lume">
|
||||
* 3. Dark mode is automatic with .dark class or prefers-color-scheme
|
||||
*/
|
||||
|
||||
/* Default: Lume Light Theme */
|
||||
:root,
|
||||
[data-theme="lume"] {
|
||||
--color-primary: #f8d62b;
|
||||
--color-primary-button: #f8d62b;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #D4B200;
|
||||
--color-secondary-button: #FFE9A3;
|
||||
|
||||
--color-background: #dddddd;
|
||||
--color-foreground: #2c2c2c;
|
||||
--color-content: #ffffff;
|
||||
--color-content-hover: #f5f5f5;
|
||||
--color-content-page: #ffffff;
|
||||
--color-menu: #dddddd;
|
||||
--color-menu-hover: #cccccc;
|
||||
|
||||
--color-text: #2c2c2c;
|
||||
--color-text-secondary: #666666;
|
||||
|
||||
--color-border-light: #f2f2f2;
|
||||
--color-border: #e6e6e6;
|
||||
--color-border-strong: #cccccc;
|
||||
|
||||
--color-error: #e74c3c;
|
||||
--color-success: #27ae60;
|
||||
--color-warning: #f39c12;
|
||||
}
|
||||
|
||||
/* Lume Dark */
|
||||
.dark,
|
||||
[data-theme="lume"].dark,
|
||||
[data-theme="lume"] .dark {
|
||||
--color-primary: #f8d62b;
|
||||
--color-primary-button: #7C6B16;
|
||||
--color-primary-button-text: #ffffff;
|
||||
--color-secondary: #D4B200;
|
||||
--color-secondary-button: #1E1E1E;
|
||||
|
||||
--color-background: #101010;
|
||||
--color-foreground: #ffffff;
|
||||
--color-content: #1E1E1E;
|
||||
--color-content-hover: #333333;
|
||||
--color-content-page: #121212;
|
||||
--color-menu: #101010;
|
||||
--color-menu-hover: #333333;
|
||||
|
||||
--color-text: #ffffff;
|
||||
--color-text-secondary: #a0a0a0;
|
||||
|
||||
--color-border-light: #333333;
|
||||
--color-border: #424242;
|
||||
--color-border-strong: #616161;
|
||||
|
||||
--color-error: #e74c3c;
|
||||
--color-success: #2ecc71;
|
||||
--color-warning: #f1c40f;
|
||||
}
|
||||
|
||||
/* Nature Theme */
|
||||
[data-theme="nature"] {
|
||||
--color-primary: #4CAF50;
|
||||
--color-primary-button: #A08500;
|
||||
--color-primary-button-text: #ffffff;
|
||||
--color-secondary: #81C784;
|
||||
--color-secondary-button: #F1F8E9;
|
||||
|
||||
--color-background: #FBFDF8;
|
||||
--color-foreground: #1B5E20;
|
||||
--color-content: #F1F8E9;
|
||||
--color-content-hover: #E8F5E9;
|
||||
--color-content-page: #ffffff;
|
||||
--color-menu: #E8F5E9;
|
||||
--color-menu-hover: #C8E6C9;
|
||||
|
||||
--color-text: #1B5E20;
|
||||
--color-text-secondary: #388E3C;
|
||||
|
||||
--color-border-light: #E8F5E9;
|
||||
--color-border: #C8E6C9;
|
||||
--color-border-strong: #A5D6A7;
|
||||
|
||||
--color-error: #E57373;
|
||||
--color-success: #66BB6A;
|
||||
--color-warning: #FFB74D;
|
||||
}
|
||||
|
||||
[data-theme="nature"].dark,
|
||||
[data-theme="nature"] .dark {
|
||||
--color-primary: #4CAF50;
|
||||
--color-primary-button: #FF9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #81C784;
|
||||
--color-secondary-button: #1E1E1E;
|
||||
|
||||
--color-background: #121212;
|
||||
--color-foreground: #FFFFFF;
|
||||
--color-content: #1E1E1E;
|
||||
--color-content-hover: #2E7D32;
|
||||
--color-content-page: #121212;
|
||||
--color-menu: #252525;
|
||||
--color-menu-hover: #2E7D32;
|
||||
|
||||
--color-text: #FFFFFF;
|
||||
--color-text-secondary: #A5D6A7;
|
||||
|
||||
--color-border-light: #1B5E20;
|
||||
--color-border: #2E7D32;
|
||||
--color-border-strong: #388E3C;
|
||||
|
||||
--color-error: #CF6679;
|
||||
--color-success: #81C784;
|
||||
--color-warning: #FFD54F;
|
||||
}
|
||||
|
||||
/* Stone Theme */
|
||||
[data-theme="stone"] {
|
||||
--color-primary: #607D8B;
|
||||
--color-primary-button: #FF9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #90A4AE;
|
||||
--color-secondary-button: #ECEFF1;
|
||||
|
||||
--color-background: #F5F7F9;
|
||||
--color-foreground: #263238;
|
||||
--color-content: #ECEFF1;
|
||||
--color-content-hover: #E0E6EA;
|
||||
--color-content-page: #ffffff;
|
||||
--color-menu: #E0E6EA;
|
||||
--color-menu-hover: #CFD8DC;
|
||||
|
||||
--color-text: #263238;
|
||||
--color-text-secondary: #546E7A;
|
||||
|
||||
--color-border-light: #ECEFF1;
|
||||
--color-border: #CFD8DC;
|
||||
--color-border-strong: #B0BEC5;
|
||||
|
||||
--color-error: #EF5350;
|
||||
--color-success: #66BB6A;
|
||||
--color-warning: #FFA726;
|
||||
}
|
||||
|
||||
[data-theme="stone"].dark,
|
||||
[data-theme="stone"] .dark {
|
||||
--color-primary: #78909C;
|
||||
--color-primary-button: #FF9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #90A4AE;
|
||||
--color-secondary-button: #1E1E1E;
|
||||
|
||||
--color-background: #121212;
|
||||
--color-foreground: #FFFFFF;
|
||||
--color-content: #1E1E1E;
|
||||
--color-content-hover: #37474F;
|
||||
--color-content-page: #121212;
|
||||
--color-menu: #252525;
|
||||
--color-menu-hover: #37474F;
|
||||
|
||||
--color-text: #FFFFFF;
|
||||
--color-text-secondary: #B0BEC5;
|
||||
|
||||
--color-border-light: #37474F;
|
||||
--color-border: #455A64;
|
||||
--color-border-strong: #546E7A;
|
||||
|
||||
--color-error: #CF6679;
|
||||
--color-success: #81C784;
|
||||
--color-warning: #FFD54F;
|
||||
}
|
||||
|
||||
/* Ocean Theme */
|
||||
[data-theme="ocean"] {
|
||||
--color-primary: #039BE5;
|
||||
--color-primary-button: #FF9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #4FC3F7;
|
||||
--color-secondary-button: #E1F5FE;
|
||||
|
||||
--color-background: #F5FCFF;
|
||||
--color-foreground: #01579B;
|
||||
--color-content: #E1F5FE;
|
||||
--color-content-hover: #B3E5FC;
|
||||
--color-content-page: #ffffff;
|
||||
--color-menu: #E1F5FE;
|
||||
--color-menu-hover: #B3E5FC;
|
||||
|
||||
--color-text: #01579B;
|
||||
--color-text-secondary: #0277BD;
|
||||
|
||||
--color-border-light: #E1F5FE;
|
||||
--color-border: #B3E5FC;
|
||||
--color-border-strong: #81D4FA;
|
||||
|
||||
--color-error: #EF5350;
|
||||
--color-success: #66BB6A;
|
||||
--color-warning: #FFA726;
|
||||
}
|
||||
|
||||
[data-theme="ocean"].dark,
|
||||
[data-theme="ocean"] .dark {
|
||||
--color-primary: #039BE5;
|
||||
--color-primary-button: #FF9500;
|
||||
--color-primary-button-text: #000000;
|
||||
--color-secondary: #4FC3F7;
|
||||
--color-secondary-button: #1E1E1E;
|
||||
|
||||
--color-background: #121212;
|
||||
--color-foreground: #FFFFFF;
|
||||
--color-content: #1E1E1E;
|
||||
--color-content-hover: #0277BD;
|
||||
--color-content-page: #121212;
|
||||
--color-menu: #252525;
|
||||
--color-menu-hover: #0277BD;
|
||||
|
||||
--color-text: #FFFFFF;
|
||||
--color-text-secondary: #81D4FA;
|
||||
|
||||
--color-border-light: #01579B;
|
||||
--color-border: #0277BD;
|
||||
--color-border-strong: #0288D1;
|
||||
|
||||
--color-error: #CF6679;
|
||||
--color-success: #81C784;
|
||||
--color-warning: #FFD54F;
|
||||
}
|
||||
|
||||
/* Dark mode via media query */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme]) {
|
||||
--color-primary: #f8d62b;
|
||||
--color-primary-button: #7C6B16;
|
||||
--color-primary-button-text: #ffffff;
|
||||
--color-secondary: #D4B200;
|
||||
--color-secondary-button: #1E1E1E;
|
||||
|
||||
--color-background: #101010;
|
||||
--color-foreground: #ffffff;
|
||||
--color-content: #1E1E1E;
|
||||
--color-content-hover: #333333;
|
||||
--color-content-page: #121212;
|
||||
--color-menu: #101010;
|
||||
--color-menu-hover: #333333;
|
||||
|
||||
--color-text: #ffffff;
|
||||
--color-text-secondary: #a0a0a0;
|
||||
|
||||
--color-border-light: #333333;
|
||||
--color-border: #424242;
|
||||
--color-border-strong: #616161;
|
||||
|
||||
--color-error: #e74c3c;
|
||||
--color-success: #2ecc71;
|
||||
--color-warning: #f1c40f;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue