feat(ui): Terrakotta Nacht replaces Soft, smooth menus and sliding notes on phones
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m21s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m21s
- dark counterpart of Terrakotta; Soft users move to it - add tailwindcss-animate: the existing animate-in/fade/slide classes now run; menus zoom in, sheets slide up, notes slide in on phones - no animations with reduced motion chore(release): v0.13.0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8d93bdc3b8
commit
2c9b4762fc
15 files changed
+148
-89
No files matched your search
@@ -960,7 +960,7 @@ export const App: React.FC = () => {
|
||||
</button>
|
||||
|
||||
{showProfileMenu && (
|
||||
<div className="absolute right-0 top-full mt-1.5 w-64 panel-surface shadow-panel z-50 divide-y divide-border text-xs">
|
||||
<div className="absolute right-0 top-full mt-1.5 w-64 panel-surface shadow-panel z-50 divide-y divide-border text-xs origin-top-right animate-in fade-in zoom-in-95 slide-in-from-top-1 duration-150">
|
||||
{/* User Info Header */}
|
||||
<div className="p-3 bg-canvas flex items-center gap-2.5">
|
||||
<UserAvatar user={user} size="md" className="border border-border/70" />
|
||||
|
||||
@@ -941,7 +941,7 @@ export const DocumentEditor: React.FC<DocumentEditorProps> = ({
|
||||
{showActionsMenu && (
|
||||
<div
|
||||
role="menu"
|
||||
className="absolute right-0 top-full mt-1.5 w-60 rounded-card bg-panel border border-border shadow-lg p-1 z-30 text-xs"
|
||||
className="absolute right-0 top-full mt-1.5 w-60 rounded-card bg-panel border border-border shadow-lg p-1 z-30 text-xs origin-top-right animate-in fade-in zoom-in-95 slide-in-from-top-1 duration-150"
|
||||
>
|
||||
{!inTrash && (
|
||||
<button
|
||||
|
||||
@@ -187,7 +187,7 @@ export const JournalView: React.FC<JournalViewProps> = ({
|
||||
</div>
|
||||
|
||||
{showCalendar && (
|
||||
<div className="lg:hidden shrink-0 px-4 py-3 border-b border-border bg-sidebar">
|
||||
<div className="lg:hidden shrink-0 px-4 py-3 border-b border-border bg-sidebar animate-in fade-in slide-in-from-top-2 duration-200">
|
||||
<JournalCalendar
|
||||
activeDate={activeDate}
|
||||
entryDates={entryDates}
|
||||
|
||||
@@ -1658,7 +1658,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
: mobileShowDetail
|
||||
? 'hidden lg:flex'
|
||||
: 'flex'
|
||||
} w-full lg:w-72 xl:w-80 shrink-0 flex-col bg-sidebar border-r border-border transition-all duration-200`
|
||||
} w-full lg:w-72 xl:w-80 shrink-0 flex-col bg-sidebar border-r border-border transition-all duration-200 max-lg:animate-in max-lg:slide-in-from-left-1/4 max-lg:fade-in max-lg:duration-200`
|
||||
}
|
||||
>
|
||||
{/* Sidebar header: search and the create buttons in one row */}
|
||||
@@ -1925,7 +1925,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
<main
|
||||
className={`${
|
||||
subView !== 'editor' || mobileShowDetail || isSidebarCollapsed || focusMode ? 'flex' : 'hidden lg:flex'
|
||||
} flex-1 flex-col min-w-0 h-full overflow-hidden bg-editor`}
|
||||
} flex-1 flex-col min-w-0 h-full overflow-hidden bg-editor max-lg:animate-in max-lg:slide-in-from-right-1/3 max-lg:fade-in max-lg:duration-200`}
|
||||
>
|
||||
{subView === 'journal' && journalEnabled ? (
|
||||
<JournalView
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
@import './themes/theme-dark.css';
|
||||
@import './themes/theme-light.css';
|
||||
@import './themes/theme-terracotta.css';
|
||||
@import './themes/theme-soft.css';
|
||||
@import './themes/theme-terracotta-night.css';
|
||||
@import './themes/theme-polarized.css';
|
||||
@import './themes/theme-suri.css';
|
||||
|
||||
@@ -595,3 +595,11 @@ fieldset:disabled :is(button, input, select, textarea) {
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.view-enter { animation: none; }
|
||||
}
|
||||
|
||||
/* No sliding or zooming for people who asked their system for less motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.animate-in,
|
||||
.animate-out {
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
@@ -65,3 +65,21 @@ describe('custom themes', () => {
|
||||
expect(document.documentElement.classList.contains('dark')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('built-in themes', () => {
|
||||
beforeEach(() => localStorage.clear());
|
||||
|
||||
it('moves removed themes to their successors', () => {
|
||||
localStorage.setItem('mindsift_active_theme', 'soft');
|
||||
expect(getActiveTheme()).toBe('terracotta-night');
|
||||
localStorage.setItem('mindsift_active_theme', 'high-contrast');
|
||||
expect(getActiveTheme()).toBe('dark');
|
||||
});
|
||||
|
||||
it('treats Terrakotta as a light theme and Terrakotta Nacht as dark', () => {
|
||||
setActiveTheme('terracotta');
|
||||
expect(document.documentElement.classList.contains('dark')).toBe(false);
|
||||
setActiveTheme('terracotta-night');
|
||||
expect(document.documentElement.classList.contains('dark')).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -58,14 +58,14 @@ export const AVAILABLE_THEMES: ThemeOption[] = [
|
||||
isRounded: true,
|
||||
},
|
||||
{
|
||||
id: 'soft',
|
||||
name: 'Soft Slate (Abgerundet)',
|
||||
subtitle: 'Schiefer-Blau mit weichen Radien (10px)',
|
||||
file: 'src/themes/theme-soft.css',
|
||||
previewBg: '#0f172a',
|
||||
previewPanel: '#1e293b',
|
||||
previewAccent: '#3b82f6',
|
||||
previewText: '#f8fafc',
|
||||
id: 'terracotta-night',
|
||||
name: 'Terrakotta Nacht (Glut)',
|
||||
subtitle: 'Espresso, Creme & glühende Terrakotta (12px)',
|
||||
file: 'src/themes/theme-terracotta-night.css',
|
||||
previewBg: '#17110d',
|
||||
previewPanel: '#211913',
|
||||
previewAccent: '#e8794a',
|
||||
previewText: '#f3e8da',
|
||||
isRounded: true,
|
||||
},
|
||||
{
|
||||
@@ -188,8 +188,12 @@ function load(key: string): string | null {
|
||||
}
|
||||
}
|
||||
|
||||
// Removed themes and their successors
|
||||
const RETIRED_THEMES: Record<string, ThemeId> = { soft: 'terracotta-night', 'high-contrast': 'dark' };
|
||||
|
||||
export function getActiveTheme(): ThemeId {
|
||||
const saved = load(THEME_STORAGE_KEY);
|
||||
const stored = load(THEME_STORAGE_KEY);
|
||||
const saved = stored && RETIRED_THEMES[stored] ? RETIRED_THEMES[stored] : stored;
|
||||
if (saved && AVAILABLE_THEMES.some((t) => t.id === saved)) return saved;
|
||||
if (saved && isCustomThemeId(saved) && load(CUSTOM_CSS_CACHE_KEY)) return saved;
|
||||
return 'dark';
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/* ==========================================================================
|
||||
MINDSIFT THEME: SOFT SLATE (Abgerundete Geometrie & Sanftes Schiefer-Blau)
|
||||
Demonstriert, wie über die Rundungs-Variablen in einer einzigen Datei
|
||||
das gesamte App-Layout auf abgerundete Ecken umschaltet.
|
||||
========================================================================== */
|
||||
|
||||
:root[data-theme="soft"] {
|
||||
/* --- 1. AKZENTFARBE --- */
|
||||
--accent-primary: #3b82f6;
|
||||
--accent-hover: #60a5fa;
|
||||
--accent-dim: rgba(59, 130, 246, 0.15);
|
||||
--accent-border: rgba(96, 165, 250, 0.40);
|
||||
--text-on-accent: #ffffff;
|
||||
|
||||
/* --- 2. OBERFLÄCHEN & HINTERGRÜNDE --- */
|
||||
--bg-app: #0f172a;
|
||||
--bg-panel: #1e293b;
|
||||
--bg-panel-elevated: #293548;
|
||||
--bg-panel-hover: #334155;
|
||||
--bg-input: #0f172a;
|
||||
--bg-overlay: rgba(2, 6, 23, 0.72);
|
||||
--bg-code: #090d16;
|
||||
|
||||
/* --- 3. TEXT & KONTRASTE --- */
|
||||
--text-main: #f8fafc;
|
||||
--text-muted: #94a3b8;
|
||||
--text-faint: #64748b;
|
||||
|
||||
/* --- 4. RAHMEN, LINIEN & SCHATTEN --- */
|
||||
--border-color: rgba(148, 163, 184, 0.16);
|
||||
--border-subtle: rgba(148, 163, 184, 0.08);
|
||||
--border-strong: rgba(148, 163, 184, 0.32);
|
||||
--shadow-panel: 0 12px 32px rgba(2, 6, 23, 0.40);
|
||||
--scrollbar-thumb: rgba(148, 163, 184, 0.22);
|
||||
--scrollbar-thumb-hover: rgba(148, 163, 184, 0.38);
|
||||
|
||||
/* --- 5. STATUS- & SIGNALFARBEN --- */
|
||||
--color-success: #10b981;
|
||||
--bg-success: rgba(16, 185, 129, 0.14);
|
||||
--border-success: rgba(16, 185, 129, 0.38);
|
||||
|
||||
--color-danger: #f43f5e;
|
||||
--bg-danger: rgba(244, 63, 94, 0.14);
|
||||
--border-danger: rgba(244, 63, 94, 0.38);
|
||||
|
||||
--color-warning: #f59e0b;
|
||||
--bg-warning: rgba(245, 158, 11, 0.14);
|
||||
--border-warning: rgba(245, 158, 11, 0.38);
|
||||
|
||||
/* --- 6. RUNDUNGEN (Weich abgerundete Ecken überall) --- */
|
||||
--radius-card: 10px;
|
||||
--radius-btn: 6px;
|
||||
--radius-input: 6px;
|
||||
--radius-checkbox: 4px;
|
||||
--radius-pill: 9999px;
|
||||
|
||||
/* --- 7. CODE-SYNTAX-HIGHLIGHTING (VS Code Dark+) --- */
|
||||
--code-keyword: #569cd6;
|
||||
--code-string: #ce9178;
|
||||
--code-number: #b5cea8;
|
||||
--code-comment: #6a9955;
|
||||
--code-property: #9cdcfe;
|
||||
--code-function: #dcdcaa;
|
||||
--code-type: #4ec9b0;
|
||||
--code-punctuation: #d4d4d4;
|
||||
--code-variable: #9cdcfe;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/* ==========================================================================
|
||||
MINDSIFT THEME: TERRAKOTTA NACHT (Espresso & Glut)
|
||||
Das dunkle Gegenstück zu Terrakotta: Espresso-Braun statt Schwarz,
|
||||
warme Creme-Schrift, glühender Terrakotta-Akzent, Salbeigrün, weiche Ecken.
|
||||
========================================================================== */
|
||||
|
||||
:root[data-theme="terracotta-night"] {
|
||||
/* --- 1. AKZENTFARBE (Glühende Terrakotta) --- */
|
||||
--accent-primary: #e8794a;
|
||||
--accent-hover: #f39669;
|
||||
--accent-dim: rgba(232, 121, 74, 0.15);
|
||||
--accent-border: rgba(232, 121, 74, 0.40);
|
||||
--text-on-accent: #1c1410;
|
||||
|
||||
/* --- 2. OBERFLÄCHEN & HINTERGRÜNDE (Espresso, Mokka, Leder) --- */
|
||||
--bg-app: #17110d;
|
||||
--bg-panel: #211913;
|
||||
--bg-panel-elevated: #2c2219;
|
||||
--bg-panel-hover: #382b20;
|
||||
--bg-input: #1a130f;
|
||||
--bg-overlay: rgba(10, 6, 4, 0.72);
|
||||
--bg-code: #120d0a;
|
||||
--bg-editor: #1c1510;
|
||||
--bg-sidebar: #17110d;
|
||||
|
||||
/* --- 3. TEXT & KONTRASTE (Creme auf Espresso) --- */
|
||||
--text-main: #f3e8da;
|
||||
--text-muted: #c4b19c;
|
||||
--text-faint: #8d7a66;
|
||||
|
||||
/* --- 4. RAHMEN, LINIEN & SCHATTEN --- */
|
||||
--border-color: rgba(243, 214, 184, 0.12);
|
||||
--border-subtle: rgba(243, 214, 184, 0.06);
|
||||
--border-strong: rgba(243, 214, 184, 0.24);
|
||||
--shadow-panel: 0 12px 32px rgba(5, 3, 2, 0.55);
|
||||
--scrollbar-thumb: rgba(232, 121, 74, 0.22);
|
||||
--scrollbar-thumb-hover: rgba(232, 121, 74, 0.38);
|
||||
|
||||
/* --- 5. STATUS- & SIGNALFARBEN (Salbei, Ziegel, Honig) --- */
|
||||
--color-success: #8fbf8a;
|
||||
--bg-success: rgba(143, 191, 138, 0.14);
|
||||
--border-success: rgba(143, 191, 138, 0.36);
|
||||
|
||||
--color-danger: #f07a6a;
|
||||
--bg-danger: rgba(240, 122, 106, 0.14);
|
||||
--border-danger: rgba(240, 122, 106, 0.36);
|
||||
|
||||
--color-warning: #e6b450;
|
||||
--bg-warning: rgba(230, 180, 80, 0.14);
|
||||
--border-warning: rgba(230, 180, 80, 0.36);
|
||||
|
||||
/* --- 6. RUNDUNGEN (Weich wie Papierkarten) --- */
|
||||
--radius-card: 12px;
|
||||
--radius-btn: 8px;
|
||||
--radius-input: 8px;
|
||||
--radius-checkbox: 4px;
|
||||
--radius-pill: 9999px;
|
||||
|
||||
/* --- 7. CODE-SYNTAX-HIGHLIGHTING (warme Erdtöne auf Espresso) --- */
|
||||
--code-keyword: #f39669;
|
||||
--code-string: #a9cf9c;
|
||||
--code-number: #e6b450;
|
||||
--code-comment: #8d7a66;
|
||||
--code-property: #f0c9a4;
|
||||
--code-function: #d8b4fe;
|
||||
--code-type: #7fc7b8;
|
||||
--code-punctuation: #c4b19c;
|
||||
--code-variable: #f0c9a4;
|
||||
}
|
||||
Reference in new issue
Block a user