- {inv.email}
- {inv.isExisting ? inv.username : ''}
+ {inv.email || '—'}
+
+ {inv.username || ''}
+
{inv.roleIds.length > 0
? roles.filter(r => inv.roleIds.includes(r.id)).map(r => r.roleLabel).join(', ')
: '-'}
- {inv.isExisting ? 'Bestehend' : 'Neu'}
+ {inv.isExisting ? 'Bestehend' : 'Neu (Einladung)'}
removeInvitee(idx)}
@@ -654,7 +678,8 @@ export const AdminInvitationWizardPage: React.FC = () => {
{invitees.map((inv, i) => (
- {inv.email}{inv.isExisting && inv.username ? ` (${inv.username})` : ''}
+ {[inv.email || null, inv.username ? `@${inv.username}` : null].filter(Boolean).join(' · ')
+ || '—'}
{inv.roleIds.length > 0 && ` – ${roles.filter(r => inv.roleIds.includes(r.id)).map(r => r.roleLabel).join(', ')}`}
))}
@@ -680,7 +705,7 @@ export const AdminInvitationWizardPage: React.FC = () => {
- E-Mail
+ E-Mail / Benutzer
Status
E-Mail gesendet
@@ -688,7 +713,11 @@ export const AdminInvitationWizardPage: React.FC = () => {
{dispatchResults.map((r, idx) => (
- {r.email}{r.username ? ` (${r.username})` : ''}
+
+ {(r.email || '').trim() && r.username
+ ? `${(r.email || '').trim()} (@${r.username})`
+ : (r.email || '').trim() || (r.username ? `@${r.username}` : '—')}
+
{
// Use the consolidated hook
const {
@@ -190,8 +193,9 @@ export const ConnectionsPage: React.FC = () => {
}
};
- // Handle create ClickUp connection
+ // Handle create ClickUp connection (UI kann per Flag abgeschaltet sein)
const handleCreateClickup = async () => {
+ if (!isClickupConnectionUiEnabled) return;
try {
await createClickupConnectionAndAuth();
refetch();
@@ -245,7 +249,8 @@ export const ConnectionsPage: React.FC = () => {
Verbindungen
- Persönliche Datenanbindungen verwalten (OAuth: Google, Microsoft, ClickUp)
+ Persönliche Datenanbindungen verwalten (OAuth: Google, Microsoft
+ {isClickupConnectionUiEnabled ? ', ClickUp' : ''})
@@ -280,14 +285,17 @@ export const ConnectionsPage: React.FC = () => {
>
Microsoft
-
- ClickUp
-
+ {isClickupConnectionUiEnabled && (
+
+ ClickUp
+
+ )}
>
)}
@@ -304,7 +312,9 @@ export const ConnectionsPage: React.FC = () => {
Keine Verbindungen vorhanden
- Verbinden Sie Ihr Google-, Microsoft- oder ClickUp-Konto, um loszulegen.
+ {isClickupConnectionUiEnabled
+ ? 'Verbinden Sie Ihr Google-, Microsoft- oder ClickUp-Konto, um loszulegen.'
+ : 'Verbinden Sie Ihr Google- oder Microsoft-Konto, um loszulegen.'}
{canCreate && (
@@ -322,13 +332,16 @@ export const ConnectionsPage: React.FC = () => {
>
Mit Microsoft verbinden
-
- Mit ClickUp verbinden
-
+ {isClickupConnectionUiEnabled && (
+
+ Mit ClickUp verbinden
+
+ )}
)}
@@ -362,7 +375,9 @@ export const ConnectionsPage: React.FC = () => {
icon: ,
onClick: handleConnect,
title: 'Verbinden',
- visible: (row: Connection) => row.status !== 'active',
+ visible: (row: Connection) =>
+ row.status !== 'active' &&
+ (isClickupConnectionUiEnabled || row.authority !== 'clickup'),
loading: () => isConnecting,
},
{
diff --git a/src/pages/basedata/FilesPage.tsx b/src/pages/basedata/FilesPage.tsx
index fe984e9..c315aac 100644
--- a/src/pages/basedata/FilesPage.tsx
+++ b/src/pages/basedata/FilesPage.tsx
@@ -381,7 +381,7 @@ export const FilesPage: React.FC = () => {
style={{
width: 6,
cursor: 'col-resize',
- background: isDragging ? 'var(--color-primary, #1976d2)' : 'transparent',
+ background: isDragging ? 'var(--primary-dark-bg, rgba(242, 88, 67, 0.2))' : 'transparent',
transition: isDragging ? 'none' : 'background 0.15s',
flexShrink: 0,
zIndex: 10,
diff --git a/src/pages/billing/BillingAdmin.tsx b/src/pages/billing/BillingAdmin.tsx
index 6d72866..01f8039 100644
--- a/src/pages/billing/BillingAdmin.tsx
+++ b/src/pages/billing/BillingAdmin.tsx
@@ -676,7 +676,7 @@ export const BillingAdmin: React.FC = () => {
padding: '8px 16px',
textDecoration: 'none',
borderRadius: '4px',
- backgroundColor: isActive ? 'var(--color-primary, #3b82f6)' : 'transparent',
+ backgroundColor: isActive ? 'var(--primary-color, #F25843)' : 'transparent',
color: isActive ? 'white' : 'var(--color-text, #e0e0e0)',
fontWeight: isActive ? 600 : 400,
cursor: 'pointer',
diff --git a/src/pages/billing/BillingDataView.tsx b/src/pages/billing/BillingDataView.tsx
index 65501a0..81172eb 100644
--- a/src/pages/billing/BillingDataView.tsx
+++ b/src/pages/billing/BillingDataView.tsx
@@ -128,7 +128,7 @@ const TabNav: React.FC = ({ activeTab, onTabChange }) => {
padding: '8px 16px',
textDecoration: 'none',
borderRadius: '4px',
- backgroundColor: isActive ? 'var(--color-primary, #3b82f6)' : 'transparent',
+ backgroundColor: isActive ? 'var(--primary-color, #F25843)' : 'transparent',
color: isActive ? 'white' : 'var(--color-text, #e0e0e0)',
fontWeight: isActive ? 600 : 400,
cursor: 'pointer',
@@ -646,7 +646,7 @@ export const BillingDataView: React.FC = () => {
? 'var(--color-error, #ef4444)'
: pct >= 70
? 'var(--color-warning, #f59e0b)'
- : 'var(--primary-color, #3b82f6)';
+ : 'var(--primary-color, #F25843)';
return (
{sv.mandateName}
@@ -726,7 +726,7 @@ export const BillingDataView: React.FC = () => {
? 'var(--color-error, #ef4444)'
: pct >= 70
? 'var(--color-warning, #f59e0b)'
- : 'var(--primary-color, #3b82f6)';
+ : 'var(--primary-color, #F25843)';
return (
= {
PENDING: { label: 'Zahlung ausstehend', color: '#f59e0b' },
SCHEDULED: { label: 'Geplant', color: '#8b5cf6' },
ACTIVE: { label: 'Aktiv', color: '#22c55e' },
- TRIALING: { label: 'Testphase', color: '#3b82f6' },
+ TRIALING: { label: 'Testphase', color: '#38bdf8' },
PAST_DUE: { label: 'Zahlung ausstehend', color: '#f59e0b' },
EXPIRED: { label: 'Abgelaufen', color: '#6b7280' },
};
@@ -75,13 +75,13 @@ const PlanCard: React.FC
= ({ plan, isCurrent, onActivate, activa
return (
@@ -89,12 +89,12 @@ const PlanCard: React.FC
= ({ plan, isCurrent, onActivate, activa
{isCurrent && (
Aktuell
)}
-
+
{_t(plan.description)}
@@ -102,7 +102,7 @@ const PlanCard: React.FC
= ({ plan, isCurrent, onActivate, activa
User: {_formatCurrency(plan.pricePerUserCHF)} / {_periodLabel[plan.billingPeriod] || plan.billingPeriod}
Instanz: {_formatCurrency(plan.pricePerFeatureInstanceCHF)} / {_periodLabel[plan.billingPeriod] || plan.billingPeriod}
-
+
AI-Budget (inkl.):
{_formatCurrency(plan.budgetAiCHF ?? 0)} / Periode
{' · '}
Speicher (inkl.):{' '}
@@ -112,7 +112,7 @@ const PlanCard: React.FC
= ({ plan, isCurrent, onActivate, activa
: formatBinaryDataSizeFromMebibytes(plan.maxDataVolumeMB)}
-
+
Speicher über Plan: {_formatCurrency(storageOverageChfPerGbMonth)} / GB / Monat
@@ -140,7 +140,7 @@ const PlanCard: React.FC
= ({ plan, isCurrent, onActivate, activa
disabled={!!activatingPlanKey}
style={{
marginTop: 'auto', padding: '8px 16px', borderRadius: '6px', border: 'none',
- background: 'var(--color-primary, #3b82f6)', color: '#fff', fontWeight: 600,
+ background: 'var(--primary-color, #F25843)', color: '#fff', fontWeight: 600,
cursor: activatingPlanKey ? 'wait' : 'pointer',
opacity: activatingPlanKey ? 0.6 : 1,
}}
@@ -177,15 +177,15 @@ const SubInfoCard: React.FC = ({ sub, plan, label, onCancel, onRea
return (
-
+
{label}
@@ -229,7 +229,7 @@ const SubInfoCard: React.FC
= ({ sub, plan, label, onCancel, onRea
{!isPending && !isScheduled && (
Gestartet: {_formatDate(sub.startedAt)}
@@ -263,7 +263,7 @@ const SubInfoCard: React.FC
= ({ sub, plan, label, onCancel, onRea
disabled={reactivating}
style={{
padding: '6px 14px', borderRadius: '6px', border: 'none',
- background: 'var(--color-primary, #3b82f6)', color: '#fff',
+ background: 'var(--primary-color, #F25843)', color: '#fff',
fontWeight: 600, cursor: reactivating ? 'wait' : 'pointer', fontSize: '0.85rem',
}}
>
@@ -443,9 +443,9 @@ export const SubscriptionTab: React.FC = ({ mandateId }) =
{checkoutMessage && (
{checkoutMessage.text}
diff --git a/src/pages/views/workspace/ChatStream.tsx b/src/pages/views/workspace/ChatStream.tsx
index a66bc3b..7f7f8cb 100644
--- a/src/pages/views/workspace/ChatStream.tsx
+++ b/src/pages/views/workspace/ChatStream.tsx
@@ -125,7 +125,7 @@ export const ChatStream: React.FC = ({
),
a: ({ href, children }) => (
-
+
{children}
),
@@ -222,7 +222,7 @@ export const ChatStream: React.FC = ({
onClick={onOpenEditor}
style={{
padding: '5px 14px', borderRadius: 4, border: 'none',
- background: 'var(--primary-color, #1976d2)', color: '#fff',
+ background: 'var(--primary-color, #F25843)', color: '#fff',
cursor: 'pointer', fontSize: 12, fontWeight: 600,
}}
>
@@ -280,7 +280,7 @@ export const ChatStream: React.FC = ({
}}>
Processing...
@@ -373,7 +373,7 @@ function _FileCard({ doc }: { doc: MessageDocument }) {
{ext.toUpperCase()}{sizeLabel ? ` \u00b7 ${sizeLabel}` : ''}
- ⬇
+ ⬇
);
}
@@ -455,7 +455,7 @@ function _AudioPlayer({ url, language }: { url: string; language?: string; charC
onClick={_togglePlay}
style={{
width: 32, height: 32, borderRadius: '50%', border: 'none',
- background: 'var(--primary-color, #1976d2)', color: '#fff',
+ background: 'var(--primary-color, #F25843)', color: '#fff',
cursor: 'pointer', fontSize: 14,
display: 'flex', alignItems: 'center', justifyContent: 'center',
flexShrink: 0,
@@ -473,7 +473,7 @@ function _AudioPlayer({ url, language }: { url: string; language?: string; charC
}}>
diff --git a/src/pages/views/workspace/WorkspaceEditorPage.tsx b/src/pages/views/workspace/WorkspaceEditorPage.tsx
index 7629520..83cf9ee 100644
--- a/src/pages/views/workspace/WorkspaceEditorPage.tsx
+++ b/src/pages/views/workspace/WorkspaceEditorPage.tsx
@@ -236,7 +236,7 @@ const _EditorTab: React.FC<{
padding: '6px 16px',
fontSize: 13,
border: 'none',
- borderBottom: isActive ? '2px solid var(--primary-color, #1976d2)' : '2px solid transparent',
+ borderBottom: isActive ? '2px solid var(--primary-color, #F25843)' : '2px solid transparent',
background: isActive ? 'var(--bg-primary, #fff)' : 'transparent',
cursor: 'pointer',
whiteSpace: 'nowrap',
diff --git a/src/pages/views/workspace/WorkspaceInput.tsx b/src/pages/views/workspace/WorkspaceInput.tsx
index affed12..a2a3a22 100644
--- a/src/pages/views/workspace/WorkspaceInput.tsx
+++ b/src/pages/views/workspace/WorkspaceInput.tsx
@@ -324,8 +324,8 @@ export const WorkspaceInput: React.FC = ({
borderTop: '1px solid var(--border-color, #e0e0e0)',
position: 'relative',
flexShrink: 0,
- outline: treeDropOver ? '2px dashed #1976d2' : 'none',
- background: treeDropOver ? 'rgba(25, 118, 210, 0.04)' : undefined,
+ outline: treeDropOver ? '2px dashed var(--primary-color, #F25843)' : 'none',
+ background: treeDropOver ? 'var(--primary-dark-bg, rgba(242, 88, 67, 0.08))' : undefined,
transition: 'background 0.15s, outline 0.15s',
}}
onDragOver={_handlePromptDragOver}
@@ -534,7 +534,7 @@ export const WorkspaceInput: React.FC = ({
style={{
width: _controlSize, height: _controlSize, borderRadius: 8, border: '1px solid var(--border-color, #ddd)',
background: 'var(--secondary-bg, #f5f5f5)',
- color: uploading ? '#1976d2' : '#666',
+ color: uploading ? 'var(--primary-color, #F25843)' : 'var(--text-secondary, #666)',
cursor: uploading || isProcessing ? 'not-allowed' : 'pointer',
fontSize: 16, display: 'flex', alignItems: 'center', justifyContent: 'center',
opacity: isProcessing ? 0.5 : 1,
@@ -706,10 +706,10 @@ export const WorkspaceInput: React.FC = ({
}}
style={{
padding: '8px 12px', cursor: 'pointer', fontSize: 13,
- background: lang.code === voiceLanguage ? 'var(--primary-color, #1976d2)' : 'transparent',
+ background: lang.code === voiceLanguage ? 'var(--primary-color, #F25843)' : 'transparent',
color: lang.code === voiceLanguage ? '#fff' : 'var(--text-primary, #333)',
}}
- onMouseEnter={e => { if (lang.code !== voiceLanguage) e.currentTarget.style.background = '#f5f5f5'; }}
+ onMouseEnter={e => { if (lang.code !== voiceLanguage) e.currentTarget.style.background = 'var(--bg-secondary, #f5f5f5)'; }}
onMouseLeave={e => { if (lang.code !== voiceLanguage) e.currentTarget.style.background = ''; }}
>
{lang.label} ({lang.code})
@@ -751,7 +751,7 @@ export const WorkspaceInput: React.FC = ({
disabled={!prompt.trim()}
style={{
padding: '10px 20px', borderRadius: 8, border: 'none',
- background: prompt.trim() ? 'var(--primary-color, #1976d2)' : '#ccc',
+ background: prompt.trim() ? 'var(--primary-color, #F25843)' : 'var(--color-gray-disabled, #ccc)',
color: '#fff', cursor: prompt.trim() ? 'pointer' : 'default', fontWeight: 600,
minWidth: isMobile ? 84 : undefined,
}}
diff --git a/src/pages/views/workspace/WorkspacePage.tsx b/src/pages/views/workspace/WorkspacePage.tsx
index 9a11ed9..84abd12 100644
--- a/src/pages/views/workspace/WorkspacePage.tsx
+++ b/src/pages/views/workspace/WorkspacePage.tsx
@@ -220,12 +220,12 @@ export const WorkspacePage: React.FC = ({ persistentInstance
flex: 1,
padding: '6px 0',
border: 'none',
- borderBottom: active ? '2px solid var(--primary-color, #1976d2)' : '2px solid transparent',
+ borderBottom: active ? '2px solid var(--primary-color, #F25843)' : '2px solid transparent',
background: 'none',
cursor: 'pointer',
fontSize: 11,
fontWeight: active ? 600 : 400,
- color: active ? 'var(--primary-color, #1976d2)' : '#888',
+ color: active ? 'var(--primary-color, #F25843)' : 'var(--text-tertiary, #888)',
textTransform: 'uppercase' as const,
});
@@ -326,7 +326,7 @@ export const WorkspacePage: React.FC = ({ persistentInstance
_leftResize.onMouseDown(e, 1)}
style={{ width: 4, cursor: 'col-resize', background: 'transparent', flexShrink: 0 }}
- onMouseEnter={e => (e.currentTarget.style.background = '#1976d2')}
+ onMouseEnter={e => (e.currentTarget.style.background = 'var(--primary-color, #F25843)')}
onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}
/>
)}
@@ -377,7 +377,7 @@ export const WorkspacePage: React.FC
= ({ persistentInstance
padding: '6px 10px',
borderRadius: 8,
border: '1px solid var(--border-color, #ddd)',
- background: rightTab === 'activity' ? '#e8f3ff' : '#f7f7f7',
+ background: rightTab === 'activity' ? 'var(--primary-dark-bg, rgba(242, 88, 67, 0.1))' : '#f7f7f7',
cursor: 'pointer',
fontSize: 12,
}}
@@ -390,7 +390,7 @@ export const WorkspacePage: React.FC = ({ persistentInstance
padding: '6px 10px',
borderRadius: 8,
border: '1px solid var(--border-color, #ddd)',
- background: rightTab === 'preview' ? '#e8f3ff' : '#f7f7f7',
+ background: rightTab === 'preview' ? 'var(--primary-dark-bg, rgba(242, 88, 67, 0.1))' : '#f7f7f7',
cursor: 'pointer',
fontSize: 12,
}}
@@ -402,10 +402,10 @@ export const WorkspacePage: React.FC = ({ persistentInstance
{isDragOver && (
Dateien hier ablegen
@@ -452,7 +452,7 @@ export const WorkspacePage: React.FC
= ({ persistentInstance
_rightResize.onMouseDown(e, -1)}
style={{ width: 4, cursor: 'col-resize', background: 'transparent', flexShrink: 0 }}
- onMouseEnter={e => (e.currentTarget.style.background = '#1976d2')}
+ onMouseEnter={e => (e.currentTarget.style.background = 'var(--primary-color, #F25843)')}
onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}
/>
)}
diff --git a/src/pages/views/workspace/WorkspaceSettingsPage.tsx b/src/pages/views/workspace/WorkspaceSettingsPage.tsx
index 644f253..60cef32 100644
--- a/src/pages/views/workspace/WorkspaceSettingsPage.tsx
+++ b/src/pages/views/workspace/WorkspaceSettingsPage.tsx
@@ -46,14 +46,14 @@ export const WorkspaceSettingsPage: React.FC = () => {
padding: '10px 20px',
border: 'none',
borderBottom: activeTab === tab.key
- ? '2px solid var(--primary-color, #1976d2)'
+ ? '2px solid var(--primary-color, #F25843)'
: '2px solid transparent',
background: 'none',
cursor: 'pointer',
fontSize: 14,
fontWeight: activeTab === tab.key ? 600 : 400,
color: activeTab === tab.key
- ? 'var(--primary-color, #1976d2)'
+ ? 'var(--primary-color, #F25843)'
: 'var(--text-secondary, #888)',
}}
>
diff --git a/src/styles/themes/light.css b/src/styles/themes/light.css
index cb113f9..80deceb 100644
--- a/src/styles/themes/light.css
+++ b/src/styles/themes/light.css
@@ -82,6 +82,15 @@
/* Error color */
--error-color: #dc2626;
+
+ /* Legacy / inline-style aliases (override :root beige --color-primary) */
+ --color-primary: var(--primary-color);
+ --color-primary-hover: var(--primary-color-dark);
+ --color-primary-disabled: var(--primary-color-light);
+ --color-border: var(--border-color);
+ --bg-card: var(--bg-primary);
+ --bg-input: #ffffff;
+ --bg-hover: var(--hover-bg);
}
/* ============================================== */
@@ -92,9 +101,9 @@
--color-surface: #1E1D1A;
--color-text: #E5E7EB;
- --color-primary: #C7C5B2;
- --color-primary-hover: #E0DECC;
- --color-primary-disabled: #59584F;
+ --color-primary: var(--primary-color);
+ --color-primary-hover: var(--primary-color-dark);
+ --color-primary-disabled: rgba(242, 88, 67, 0.35);
--color-secondary: #F25843;
--color-secondary-hover: #FF715C;
@@ -108,9 +117,10 @@
--color-secondary-red-hover: #E17683;
--color-secondary-red-disabled: #70363C;
- --color-gray: #181818;
- --color-gray-hover: #2E2E2E;
- --color-gray-disabled: #505050;
+ /* Readable neutrals on dark (was #181818 — same as bg, illegible) */
+ --color-gray: #9ca3af;
+ --color-gray-hover: #d1d5db;
+ --color-gray-disabled: #57534e;
/* Background colors */
--bg-primary: #181818;
@@ -146,4 +156,9 @@
/* Error color */
--error-color: #ef4444;
+
+ --color-border: var(--border-color);
+ --bg-card: #252422;
+ --bg-input: #2c2926;
+ --bg-hover: rgba(255, 255, 255, 0.08);
}