fix: smaller UI fixes

This commit is contained in:
Ida Dittrich 2026-01-26 10:46:38 +01:00
parent 3827d8cc07
commit b142b93666
12 changed files with 453 additions and 119 deletions

View file

@ -133,11 +133,16 @@ const SidebarItem: React.FC<SidebarItemProps> = React.memo(({
buttonZIndex: buttonComputed?.zIndex, buttonZIndex: buttonComputed?.zIndex,
buttonPosition: buttonComputed?.position, buttonPosition: buttonComputed?.position,
buttonRect: button ? button.getBoundingClientRect() : null, buttonRect: button ? button.getBoundingClientRect() : null,
elementsAtIconCenter: elementsAtPoint.slice(0, 5).map(el => ({ elementsAtIconCenter: elementsAtPoint.slice(0, 5).map(el => {
tag: el.tagName, const className = typeof el.className === 'string'
class: el.className?.split(' ')[0] || 'no-class', ? el.className
zIndex: window.getComputedStyle(el).zIndex : (el.className?.baseVal || el.className?.toString() || '');
})), return {
tag: el.tagName,
class: className?.split(' ')[0] || 'no-class',
zIndex: window.getComputedStyle(el).zIndex
};
}),
wrapperInElements: wrapperInElements, wrapperInElements: wrapperInElements,
parentLiOverflow: parentLiComputed?.overflow, parentLiOverflow: parentLiComputed?.overflow,
parentLiClipPath: parentLiComputed?.clipPath, parentLiClipPath: parentLiComputed?.clipPath,
@ -180,23 +185,200 @@ const SidebarItem: React.FC<SidebarItemProps> = React.memo(({
if (!hasSubItems || !item.submenu) return null; if (!hasSubItems || !item.submenu) return null;
if (isMinimized) { if (isMinimized) {
// Horizontal layout for minimized sidebar // Horizontal layout for minimized sidebar - recursive for all levels
return ( return (
<AnimatePresence> <AnimatePresence>
{isOpen && ( {isOpen && (
<motion.div <motion.div
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { delay: 0.3, duration: 0.25 } }} animate={{
exit={{ opacity: 0, transition: { duration: 0.25, delay: 0 } }} opacity: 1,
transition: {
duration: 0.4,
ease: [0.25, 0.1, 0.25, 1],
delay: depth > 0 ? 0.05 : 0.1
}
}}
exit={{
opacity: 0,
transition: {
duration: 0.3,
ease: [0.25, 0.1, 0.25, 1]
}
}}
className={styles.submenuHorizontalContainer} className={styles.submenuHorizontalContainer}
> >
<ul className={styles.submenuHorizontalList}> <ul className={styles.submenuHorizontalList}>
{item.submenu.map(subitem => { {item.submenu.map((subitem, index) => {
const SubIcon = subitem.icon as React.ComponentType<React.SVGProps<SVGSVGElement>>; const SubIcon = subitem.icon as React.ComponentType<React.SVGProps<SVGSVGElement>>;
const subIsActive = isSubmenuItemActive(subitem.link); const subIsActive = isSubmenuItemActive(subitem.link);
const hasNestedSubmenu = subitem.submenu && subitem.submenu.length > 0;
const subIsOpen = nestedOpenStates[subitem.id] || false;
const subDepth = subitem.depth !== undefined ? subitem.depth : (depth === 0 ? 1 : depth + 1);
// In minimized mode, items with nested submenus should render as icon buttons
// Their submenu will expand below them when clicked
if (hasNestedSubmenu) {
return (
<motion.li
key={subitem.id}
className={`${styles.submenuHorizontalItem} ${subIsActive ? styles.active : ''}`}
style={{ position: 'relative' }}
initial={{ opacity: 0 }}
animate={{
opacity: 1,
transition: {
duration: 0.35,
ease: [0.25, 0.1, 0.25, 1],
delay: (depth > 0 ? 0.05 : 0.1) + (index * 0.02)
}
}}
exit={{
opacity: 0,
transition: {
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1]
}
}}
>
<button
onClick={() => toggleNestedSubmenu(subitem.id)}
className={`${styles.submenuHorizontalLink} ${subIsActive ? styles.activeLink : ''}`}
title={subitem.name}
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '40px',
height: '40px',
borderRadius: '12px',
background: subIsActive ? 'var(--color-secondary)' : 'none',
border: 'none',
cursor: 'pointer',
padding: 0,
margin: 0
}}
>
{SubIcon && (
<SubIcon
className={styles.submenuHorizontalIcon}
style={{
width: '16px',
height: '16px',
color: subIsActive ? 'white' : '#181818',
display: 'block'
}}
/>
)}
</button>
{/* Render nested submenu horizontally when expanded */}
{subIsOpen && (
<AnimatePresence>
<motion.div
initial={{ opacity: 0 }}
animate={{
opacity: 1,
transition: {
duration: 0.35,
ease: [0.25, 0.1, 0.25, 1]
}
}}
exit={{
opacity: 0,
transition: {
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1]
}
}}
className={styles.submenuHorizontalContainer}
style={{
position: 'absolute',
top: '100%',
left: 0,
marginTop: '4px',
zIndex: 100,
background: 'var(--color-bg)',
borderRadius: '8px',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
padding: '4px'
}}
>
<ul className={styles.submenuHorizontalList}>
{subitem.submenu?.map(nestedSubitem => {
const NestedIcon = nestedSubitem.icon as React.ComponentType<React.SVGProps<SVGSVGElement>>;
const nestedIsActive = isSubmenuItemActive(nestedSubitem.link);
return (
<motion.li
key={nestedSubitem.id}
className={`${styles.submenuHorizontalItem} ${nestedIsActive ? styles.active : ''}`}
initial={{ opacity: 0 }}
animate={{
opacity: 1,
transition: {
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1],
delay: 0.05
}
}}
exit={{
opacity: 0,
transition: {
duration: 0.2,
ease: [0.25, 0.1, 0.25, 1]
}
}}
>
<Link
to={nestedSubitem.link || '#'}
title={nestedSubitem.name}
className={`${styles.submenuHorizontalLink} ${nestedIsActive ? styles.activeLink : ''}`}
>
{NestedIcon && (
<NestedIcon
className={styles.submenuHorizontalIcon}
style={{
width: '16px',
height: '16px',
color: nestedIsActive ? 'white' : '#181818',
display: 'block'
}}
/>
)}
</Link>
</motion.li>
);
})}
</ul>
</motion.div>
</AnimatePresence>
)}
</motion.li>
);
}
// Regular item without nested submenu - render as icon link with smooth animation
return ( return (
<li key={subitem.id} className={`${styles.submenuHorizontalItem} ${subIsActive ? styles.active : ''}`}> <motion.li
key={subitem.id}
className={`${styles.submenuHorizontalItem} ${subIsActive ? styles.active : ''}`}
initial={{ opacity: 0 }}
animate={{
opacity: 1,
transition: {
duration: 0.35,
ease: [0.25, 0.1, 0.25, 1],
delay: (depth > 0 ? 0.05 : 0.1) + (index * 0.02)
}
}}
exit={{
opacity: 0,
transition: {
duration: 0.25,
ease: [0.25, 0.1, 0.25, 1]
}
}}
>
<Link <Link
to={subitem.link || '#'} to={subitem.link || '#'}
title={subitem.name} title={subitem.name}
@ -214,7 +396,7 @@ const SidebarItem: React.FC<SidebarItemProps> = React.memo(({
/> />
)} )}
</Link> </Link>
</li> </motion.li>
); );
})} })}
</ul> </ul>

View file

@ -519,6 +519,57 @@
list-style: none; list-style: none;
opacity: 1 !important; opacity: 1 !important;
visibility: visible !important; visibility: visible !important;
position: relative; /* Allow nested submenus to position correctly */
}
/* Nested SidebarItem in horizontal list - ensure it renders correctly when minimized */
.submenuHorizontalItem .menu.minimized {
width: 40px !important;
min-width: 40px !important;
max-width: 40px !important;
height: 40px !important;
display: inline-flex !important;
flex-direction: row !important;
align-items: center !important;
justify-content: center !important;
padding: 0 !important;
margin: 0 !important;
}
.submenuHorizontalItem .menu.minimized li {
width: 40px !important;
min-width: 40px !important;
max-width: 40px !important;
height: 40px !important;
padding: 0 !important;
margin: 0 !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
/* Nested horizontal submenu should appear below the parent item */
.submenuHorizontalItem .submenuHorizontalContainer {
position: absolute;
top: 100%;
left: 0;
margin-top: 4px;
z-index: 100;
background: var(--color-bg);
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 4px;
transform-origin: top left;
will-change: transform, opacity;
}
/* Smooth transitions for horizontal submenu items */
.submenuHorizontalItem {
transition: opacity 0.2s ease;
}
.submenuHorizontalLink {
transition: background-color 0.2s ease;
} }
.submenuHorizontalLink { .submenuHorizontalLink {

View file

@ -205,6 +205,42 @@
font-family: monospace; font-family: monospace;
} }
.zoneDetails {
margin-top: 0.5rem;
padding: 0.5rem;
background-color: var(--color-bg-secondary, #f9fafb);
border: 1px solid var(--color-border, #e5e7eb);
border-radius: 4px;
}
.zoneSummary {
cursor: pointer;
font-size: 0.875rem;
color: var(--color-primary, #3b82f6);
font-weight: 500;
user-select: none;
}
.zoneSummary:hover {
color: var(--color-primary-dark, #2563eb);
text-decoration: underline;
}
.zoneData {
margin-top: 0.5rem;
padding: 0.75rem;
background-color: var(--color-bg, #ffffff);
border: 1px solid var(--color-border, #e5e7eb);
border-radius: 4px;
font-size: 0.75rem;
font-family: monospace;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-word;
max-height: 300px;
overflow-y: auto;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.panel { .panel {
width: 100vw; width: 100vw;

View file

@ -142,6 +142,46 @@ const ParcelInfoPanel: React.FC<ParcelInfoPanelProps> = ({
<span className={styles.value}>{parcelData.parcel.realestate_type}</span> <span className={styles.value}>{parcelData.parcel.realestate_type}</span>
</div> </div>
)} )}
{parcelData.parcel.bauzone && (
<div className={styles.infoItem}>
<span className={styles.label}>Bauzone:</span>
<span className={styles.value}>{parcelData.parcel.bauzone}</span>
</div>
)}
{parcelData.parcel.zone && Array.isArray(parcelData.parcel.zone) && parcelData.parcel.zone.length > 0 && (
<div className={styles.infoItem}>
<span className={styles.label}>Zone:</span>
<span className={styles.value}>
{parcelData.parcel.zone.length} Zone{parcelData.parcel.zone.length !== 1 ? 'n' : ''} gefunden
{(() => {
// Extract zone types from zone array
const zoneTypes = parcelData.parcel.zone
.map((z: any) => {
const attrs = z.attributes || {};
return attrs.typ || attrs.zone_typ || attrs.bauzone || attrs.zone || attrs.label || null;
})
.filter((t: string | null) => t !== null);
if (zoneTypes.length > 0) {
return (
<span className={styles.subValue}>
{' '}({zoneTypes.join(', ')})
</span>
);
}
return null;
})()}
{import.meta.env.DEV && (
<details className={styles.zoneDetails}>
<summary className={styles.zoneSummary}>Details anzeigen</summary>
<pre className={styles.zoneData}>
{JSON.stringify(parcelData.parcel.zone, null, 2)}
</pre>
</details>
)}
</span>
</div>
)}
{parcelData.parcel.centroid && ( {parcelData.parcel.centroid && (
<div className={styles.infoItem}> <div className={styles.infoItem}>
<span className={styles.label}>Zentrum (LV95):</span> <span className={styles.label}>Zentrum (LV95):</span>

View file

@ -28,6 +28,8 @@ export interface ParcelSearchResponse {
centroid?: { x: number; y: number }; centroid?: { x: number; y: number };
geoportal_url?: string; geoportal_url?: string;
realestate_type?: string | null; realestate_type?: string | null;
bauzone?: string | null;
zone?: Array<any> | null;
}; };
map_view: { map_view: {
center: { x: number; y: number }; center: { x: number; y: number };
@ -569,6 +571,8 @@ export function usePek() {
centroid: firstParcel.parcel.centroid, centroid: firstParcel.parcel.centroid,
geoportal_url: firstParcel.parcel.geoportal_url, geoportal_url: firstParcel.parcel.geoportal_url,
realestate_type: firstParcel.parcel.realestate_type, realestate_type: firstParcel.parcel.realestate_type,
bauzone: firstParcel.parcel.bauzone,
zone: firstParcel.parcel.zone,
// Include geometry data if available // Include geometry data if available
geometry_geojson: firstParcel.map_view?.geometry_geojson, geometry_geojson: firstParcel.map_view?.geometry_geojson,
perimeter: firstParcel.parcel.perimeter perimeter: firstParcel.parcel.perimeter
@ -588,6 +592,8 @@ export function usePek() {
centroid: p.parcel.centroid, centroid: p.parcel.centroid,
geoportal_url: p.parcel.geoportal_url, geoportal_url: p.parcel.geoportal_url,
realestate_type: p.parcel.realestate_type, realestate_type: p.parcel.realestate_type,
bauzone: p.parcel.bauzone,
zone: p.parcel.zone,
geometry_geojson: p.map_view?.geometry_geojson, geometry_geojson: p.map_view?.geometry_geojson,
perimeter: p.parcel.perimeter perimeter: p.parcel.perimeter
})); }));
@ -650,6 +656,8 @@ export function usePek() {
centroid: selectedParcel.parcel.centroid, centroid: selectedParcel.parcel.centroid,
geoportal_url: selectedParcel.parcel.geoportal_url, geoportal_url: selectedParcel.parcel.geoportal_url,
realestate_type: selectedParcel.parcel.realestate_type, realestate_type: selectedParcel.parcel.realestate_type,
bauzone: selectedParcel.parcel.bauzone,
zone: selectedParcel.parcel.zone,
geometry_geojson: selectedParcel.map_view?.geometry_geojson, geometry_geojson: selectedParcel.map_view?.geometry_geojson,
perimeter: selectedParcel.parcel.perimeter perimeter: selectedParcel.parcel.perimeter
} }
@ -722,6 +730,8 @@ export function usePek() {
centroid: selectedParcel.parcel.centroid, centroid: selectedParcel.parcel.centroid,
geoportal_url: selectedParcel.parcel.geoportal_url, geoportal_url: selectedParcel.parcel.geoportal_url,
realestate_type: selectedParcel.parcel.realestate_type, realestate_type: selectedParcel.parcel.realestate_type,
bauzone: selectedParcel.parcel.bauzone,
zone: selectedParcel.parcel.zone,
// Include geometry data // Include geometry data
geometry_geojson: selectedParcel.map_view?.geometry_geojson, geometry_geojson: selectedParcel.map_view?.geometry_geojson,
perimeter: selectedParcel.parcel.perimeter perimeter: selectedParcel.parcel.perimeter

View file

@ -3,7 +3,7 @@
min-height: 100vh; min-height: 100vh;
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #181818; color: var(--color-bg);
} }
.mainContent { .mainContent {
@ -11,7 +11,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 3rem; padding: 3rem;
background-color: #181818; background-color: var(--color-bg);
} }
.loginSection { .loginSection {
@ -31,11 +31,11 @@
} }
.logoPower { .logoPower {
color: #E5E7EB; color: var(--color-text);
} }
.logoOn { .logoOn {
color: #F25843; color: var(--color-secondary);
font-weight: 700; font-weight: 700;
} }
@ -46,7 +46,7 @@
.loginBox { .loginBox {
background-color: #181818; background-color: var(--color-bg);
width: 25%; width: 25%;
height: auto; height: auto;
@ -54,14 +54,14 @@
padding: 2rem; padding: 2rem;
border-radius: 25px; border-radius: 25px;
border: 1px solid rgba(199, 197, 178, 0.15); /* washed-out color */ border: 1px solid color-mix(in srgb, var(--color-primary) 15%, transparent);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02), box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02),
0 0 10px rgba(0, 0, 0, 0.1); 0 0 10px rgba(0, 0, 0, 0.1);
} }
.title { .title {
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #E5E7EB; color: var(--color-text);
} }
.loginForm { .loginForm {
@ -79,7 +79,7 @@
left: 16px; left: 16px;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
color: #C7C5B2; color: var(--color-primary);
font-size: 1rem; font-size: 1rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -92,11 +92,11 @@
left: 12px; left: 12px;
top: -8px; top: -8px;
transform: translateY(0); transform: translateY(0);
color: #F25843; color: var(--color-secondary);
font-size: 0.85rem; font-size: 0.85rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
background-color: #181818; background-color: var(--color-bg);
padding: 0 4px; padding: 0 4px;
font-family: var(--font-family); font-family: var(--font-family);
font-weight: 500; font-weight: 500;
@ -111,15 +111,15 @@
font-size: 1rem; font-size: 1rem;
transition: all 0.2s ease; transition: all 0.2s ease;
background-color: #181818; background-color: var(--color-bg);
color: #C7C5B2; color: var(--color-text);
font-family: var(--font-family); font-family: var(--font-family);
} }
.input:focus { .input:focus {
outline: none; outline: none;
border-color: #F25843; border-color: var(--color-secondary);
box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.1); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-secondary) 10%, transparent);
} }
.input::placeholder { .input::placeholder {
@ -131,21 +131,21 @@
.input:-webkit-autofill:hover, .input:-webkit-autofill:hover,
.input:-webkit-autofill:focus, .input:-webkit-autofill:focus,
.input:-webkit-autofill:active { .input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 30px #181818 inset !important; -webkit-box-shadow: 0 0 0 30px var(--color-bg) inset !important;
-webkit-text-fill-color: #E5E7EB !important; -webkit-text-fill-color: var(--color-text) !important;
background-color: #181818 !important; background-color: var(--color-bg) !important;
transition: background-color 5000s ease-in-out 0s; transition: background-color 5000s ease-in-out 0s;
} }
/* Ensure label background matches when autofilled */ /* Ensure label background matches when autofilled */
.input:-webkit-autofill + .label, .input:-webkit-autofill + .label,
.input:-webkit-autofill + .focusedLabel { .input:-webkit-autofill + .focusedLabel {
background-color: #181818 !important; background-color: var(--color-bg) !important;
} }
.disclaimer { .disclaimer {
font-size: 0.8rem; font-size: 0.8rem;
color: #E5E7EB; color: var(--color-text);
text-align: center; text-align: center;
} }
@ -176,8 +176,8 @@
} }
.loginButton { .loginButton {
background-color: #F25843; background-color: var(--color-secondary);
color: #E5E7EB; color: var(--color-text);
} }
.loginButton:hover { .loginButton:hover {
@ -185,21 +185,21 @@
} }
.microsoftButton { .microsoftButton {
background-color: #C7C5B2; background-color: var(--color-primary);
color: #181818; color: var(--color-bg);
} }
.microsoftButton:hover { .microsoftButton:hover {
background-color: #D9D7C6; background-color: var(--color-primary-hover);
} }
.googleButton { .googleButton {
background-color: #C7C5B2; background-color: var(--color-primary);
color: #181818; color: var(--color-bg);
} }
.googleButton:hover { .googleButton:hover {
background-color: #D9D7C6; background-color: var(--color-primary-hover);
} }
.divider { .divider {
@ -217,7 +217,7 @@
.divider span { .divider span {
padding: 0 1rem; padding: 0 1rem;
color: #E5E7EB; color: var(--color-text);
font-size: 0.8rem; font-size: 0.8rem;
} }
@ -229,7 +229,7 @@
} }
.registerLink span { .registerLink span {
color: #E5E7EB; color: var(--color-text);
font-size: 0.8rem; font-size: 0.8rem;
} }
@ -271,10 +271,10 @@ button:disabled {
} }
.passwordResetLink .textButton { .passwordResetLink .textButton {
color: #9CA3AF; color: var(--color-gray-disabled);
font-size: 0.85rem; font-size: 0.85rem;
} }
.passwordResetLink .textButton:hover { .passwordResetLink .textButton:hover {
color: #F25843; color: var(--color-secondary);
} }

View file

@ -3,7 +3,7 @@
min-height: 100vh; min-height: 100vh;
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #181818; color: var(--color-bg);
} }
.mainContent { .mainContent {
@ -11,7 +11,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 3rem; padding: 3rem;
background-color: #181818; background-color: var(--color-bg);
} }
.loginSection { .loginSection {
@ -31,11 +31,11 @@
} }
.logoPower { .logoPower {
color: #E5E7EB; color: var(--color-text);
} }
.logoOn { .logoOn {
color: #F25843; color: var(--color-secondary);
font-weight: 700; font-weight: 700;
} }
@ -46,7 +46,7 @@
.loginBox { .loginBox {
background-color: #181818; background-color: var(--color-bg);
width: 25%; width: 25%;
height: auto; height: auto;
@ -54,14 +54,14 @@
padding: 2rem; padding: 2rem;
border-radius: 25px; border-radius: 25px;
border: 1px solid rgba(199, 197, 178, 0.15); /* washed-out color */ border: 1px solid color-mix(in srgb, var(--color-primary) 15%, transparent);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02), box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02),
0 0 10px rgba(0, 0, 0, 0.1); 0 0 10px rgba(0, 0, 0, 0.1);
} }
.title { .title {
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #E5E7EB; color: var(--color-text);
font-size: 1.5rem; font-size: 1.5rem;
font-weight: 500; font-weight: 500;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
@ -83,7 +83,7 @@
left: 16px; left: 16px;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
color: #C7C5B2; color: var(--color-primary);
font-size: 1rem; font-size: 1rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -96,11 +96,11 @@
left: 12px; left: 12px;
top: -8px; top: -8px;
transform: translateY(0); transform: translateY(0);
color: #F25843; color: var(--color-secondary);
font-size: 0.85rem; font-size: 0.85rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
background-color: #181818; background-color: var(--color-bg);
padding: 0 4px; padding: 0 4px;
font-family: var(--font-family); font-family: var(--font-family);
font-weight: 500; font-weight: 500;
@ -122,8 +122,8 @@
.input:focus { .input:focus {
outline: none; outline: none;
border-color: #F25843; border-color: var(--color-secondary);
box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.1); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-secondary) 10%, transparent);
} }
.input::placeholder { .input::placeholder {
@ -135,16 +135,16 @@
.input:-webkit-autofill:hover, .input:-webkit-autofill:hover,
.input:-webkit-autofill:focus, .input:-webkit-autofill:focus,
.input:-webkit-autofill:active { .input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 30px #181818 inset !important; -webkit-box-shadow: 0 0 0 30px var(--color-bg) inset !important;
-webkit-text-fill-color: #E5E7EB !important; -webkit-text-fill-color: var(--color-text) !important;
background-color: #181818 !important; background-color: var(--color-bg) !important;
transition: background-color 5000s ease-in-out 0s; transition: background-color 5000s ease-in-out 0s;
} }
/* Ensure label background matches when autofilled */ /* Ensure label background matches when autofilled */
.input:-webkit-autofill + .label, .input:-webkit-autofill + .label,
.input:-webkit-autofill + .focusedLabel { .input:-webkit-autofill + .focusedLabel {
background-color: #181818 !important; background-color: var(--color-bg) !important;
} }
.button { .button {
@ -162,8 +162,8 @@
} }
.loginButton { .loginButton {
background-color: #F25843; background-color: var(--color-secondary);
color: #E5E7EB; color: var(--color-text);
} }
.loginButton:hover { .loginButton:hover {
@ -178,7 +178,7 @@
} }
.registerLink span { .registerLink span {
color: #E5E7EB; color: var(--color-text);
font-size: 0.8rem; font-size: 0.8rem;
} }
@ -215,9 +215,9 @@ button:disabled {
} }
.success { .success {
color: #10b981; color: var(--color-success);
background-color: rgba(16, 185, 129, 0.1); background-color: color-mix(in srgb, var(--color-success) 10%, transparent);
border: 1px solid #10b981; border: 1px solid var(--color-success);
border-radius: 25px; border-radius: 25px;
padding: 12px; padding: 12px;
font-size: 0.9rem; font-size: 0.9rem;
@ -227,12 +227,12 @@ button:disabled {
} }
.infoMessage { .infoMessage {
background-color: rgba(59, 130, 246, 0.1); background-color: color-mix(in srgb, var(--color-primary) 10%, transparent);
border: 1px solid rgba(59, 130, 246, 0.3); border: 1px solid color-mix(in srgb, var(--color-primary) 100%, transparent);
border-radius: 12px; border-radius: 12px;
padding: 12px; padding: 12px;
font-size: 0.85rem; font-size: 0.85rem;
color: #93c5fd; color: var(--color-gray);
text-align: center; text-align: center;
font-family: var(--font-family); font-family: var(--font-family);
} }

View file

@ -3,7 +3,7 @@
min-height: 100vh; min-height: 100vh;
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #181818; color: var(--color-bg);
} }
.mainContent { .mainContent {
@ -11,7 +11,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 3rem; padding: 3rem;
background-color: #181818; background-color: var(--color-bg);
} }
.loginSection { .loginSection {
@ -31,11 +31,11 @@
} }
.logoPower { .logoPower {
color: #E5E7EB; color: var(--color-text);
} }
.logoOn { .logoOn {
color: #F25843; color: var(--color-secondary);
font-weight: 700; font-weight: 700;
} }
@ -46,7 +46,7 @@
.loginBox { .loginBox {
background-color: #181818; background-color: var(--color-bg);
width: 25%; width: 25%;
height: auto; height: auto;
@ -54,14 +54,14 @@
padding: 2rem; padding: 2rem;
border-radius: 25px; border-radius: 25px;
border: 1px solid rgba(199, 197, 178, 0.15); /* washed-out color */ border: 1px solid color-mix(in srgb, var(--color-primary) 15%, transparent);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02), box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02),
0 0 10px rgba(0, 0, 0, 0.1); 0 0 10px rgba(0, 0, 0, 0.1);
} }
.title { .title {
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #E5E7EB; color: var(--color-text);
} }
.loginForm { .loginForm {
@ -79,7 +79,7 @@
left: 16px; left: 16px;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
color: #C7C5B2; color: var(--color-primary);
font-size: 1rem; font-size: 1rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -92,11 +92,11 @@
left: 12px; left: 12px;
top: -8px; top: -8px;
transform: translateY(0); transform: translateY(0);
color: #F25843; color: var(--color-secondary);
font-size: 0.85rem; font-size: 0.85rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
background-color: #181818; background-color: var(--color-bg);
padding: 0 4px; padding: 0 4px;
font-family: var(--font-family); font-family: var(--font-family);
font-weight: 500; font-weight: 500;
@ -118,13 +118,13 @@
.input:focus { .input:focus {
outline: none; outline: none;
border-color: #F25843; border-color: var(--color-secondary);
box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.1); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-secondary) 10%, transparent);
} }
.usernameError { .usernameError {
border-color: #F25843 !important; border-color: var(--color-secondary) !important;
box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.2) !important; box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-secondary) 20%, transparent) !important;
} }
.input::placeholder { .input::placeholder {
@ -136,21 +136,21 @@
.input:-webkit-autofill:hover, .input:-webkit-autofill:hover,
.input:-webkit-autofill:focus, .input:-webkit-autofill:focus,
.input:-webkit-autofill:active { .input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 30px #181818 inset !important; -webkit-box-shadow: 0 0 0 30px var(--color-bg) inset !important;
-webkit-text-fill-color: #E5E7EB !important; -webkit-text-fill-color: var(--color-text) !important;
background-color: #181818 !important; background-color: var(--color-bg) !important;
transition: background-color 5000s ease-in-out 0s; transition: background-color 5000s ease-in-out 0s;
} }
/* Ensure label background matches when autofilled */ /* Ensure label background matches when autofilled */
.input:-webkit-autofill + .label, .input:-webkit-autofill + .label,
.input:-webkit-autofill + .focusedLabel { .input:-webkit-autofill + .focusedLabel {
background-color: #181818 !important; background-color: var(--color-bg) !important;
} }
.disclaimer { .disclaimer {
font-size: 0.8rem; font-size: 0.8rem;
color: #E5E7EB; color: var(--color-text);
text-align: center; text-align: center;
} }
@ -176,8 +176,8 @@
} }
.loginButton { .loginButton {
background-color: #F25843; background-color: var(--color-secondary);
color: #E5E7EB; color: var(--color-text);
} }
.loginButton:hover { .loginButton:hover {
@ -192,7 +192,7 @@
} }
.registerLink span { .registerLink span {
color: #E5E7EB; color: var(--color-text);
font-size: 0.8rem; font-size: 0.8rem;
} }
@ -229,9 +229,9 @@ button:disabled {
} }
.success { .success {
color: #10b981; color: var(--color-success);
background-color: rgba(16, 185, 129, 0.1); background-color: color-mix(in srgb, var(--color-success) 10%, transparent);
border: 1px solid #10b981; border: 1px solid var(--color-success);
border-radius: 25px; border-radius: 25px;
padding: 12px; padding: 12px;
font-size: 0.9rem; font-size: 0.9rem;
@ -241,12 +241,12 @@ button:disabled {
} }
.infoMessage { .infoMessage {
background-color: rgba(59, 130, 246, 0.1); background-color: color-mix(in srgb, var(--color-primary) 10%, transparent);
border: 1px solid rgba(59, 130, 246, 0.3); border: 1px solid color-mix(in srgb, var(--color-primary) 100%, transparent);
border-radius: 12px; border-radius: 12px;
padding: 12px; padding: 12px;
font-size: 0.85rem; font-size: 0.85rem;
color: #93c5fd; color: var(--color-gray);
text-align: center; text-align: center;
font-family: var(--font-family); font-family: var(--font-family);
} }

View file

@ -3,7 +3,7 @@
min-height: 100vh; min-height: 100vh;
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #181818; color: var(--color-bg);
} }
.mainContent { .mainContent {
@ -11,7 +11,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 3rem; padding: 3rem;
background-color: #181818; background-color: var(--color-bg);
} }
.loginSection { .loginSection {
@ -31,11 +31,11 @@
} }
.logoPower { .logoPower {
color: #E5E7EB; color: var(--color-text);
} }
.logoOn { .logoOn {
color: #F25843; color: var(--color-secondary);
font-weight: 700; font-weight: 700;
} }
@ -46,7 +46,7 @@
.loginBox { .loginBox {
background-color: #181818; background-color: var(--color-bg);
width: 25%; width: 25%;
height: auto; height: auto;
@ -54,14 +54,14 @@
padding: 2rem; padding: 2rem;
border-radius: 25px; border-radius: 25px;
border: 1px solid rgba(199, 197, 178, 0.15); /* washed-out color */ border: 1px solid color-mix(in srgb, var(--color-primary) 15%, transparent);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02), box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.02),
0 0 10px rgba(0, 0, 0, 0.1); 0 0 10px rgba(0, 0, 0, 0.1);
} }
.title { .title {
font-family: "DM Sans", sans-serif; font-family: "DM Sans", sans-serif;
color: #E5E7EB; color: var(--color-text);
font-size: 1.5rem; font-size: 1.5rem;
font-weight: 500; font-weight: 500;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
@ -76,6 +76,7 @@
.floatingLabelInput { .floatingLabelInput {
position: relative; position: relative;
margin-top:1rem;
} }
.label { .label {
@ -83,7 +84,7 @@
left: 16px; left: 16px;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
color: #C7C5B2; color: var(--color-primary);
font-size: 1rem; font-size: 1rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -96,11 +97,11 @@
left: 12px; left: 12px;
top: -8px; top: -8px;
transform: translateY(0); transform: translateY(0);
color: #F25843; color: var(--color-secondary);
font-size: 0.85rem; font-size: 0.85rem;
pointer-events: none; pointer-events: none;
transition: all 0.3s ease; transition: all 0.3s ease;
background-color: #181818; background-color: var(--color-bg);
padding: 0 4px; padding: 0 4px;
font-family: var(--font-family); font-family: var(--font-family);
font-weight: 500; font-weight: 500;
@ -122,8 +123,8 @@
.input:focus { .input:focus {
outline: none; outline: none;
border-color: #F25843; border-color: var(--color-secondary);
box-shadow: 0 0 0 2px rgba(242, 88, 67, 0.1); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-secondary) 10%, transparent);
} }
.input::placeholder { .input::placeholder {
@ -135,21 +136,21 @@
.input:-webkit-autofill:hover, .input:-webkit-autofill:hover,
.input:-webkit-autofill:focus, .input:-webkit-autofill:focus,
.input:-webkit-autofill:active { .input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 30px #181818 inset !important; -webkit-box-shadow: 0 0 0 30px var(--color-bg) inset !important;
-webkit-text-fill-color: #E5E7EB !important; -webkit-text-fill-color: var(--color-text) !important;
background-color: #181818 !important; background-color: var(--color-bg) !important;
transition: background-color 5000s ease-in-out 0s; transition: background-color 5000s ease-in-out 0s;
} }
/* Ensure label background matches when autofilled */ /* Ensure label background matches when autofilled */
.input:-webkit-autofill + .label, .input:-webkit-autofill + .label,
.input:-webkit-autofill + .focusedLabel { .input:-webkit-autofill + .focusedLabel {
background-color: #181818 !important; background-color: var(--color-bg) !important;
} }
.passwordHint { .passwordHint {
font-size: 0.8rem; font-size: 0.8rem;
color: #9CA3AF; color: var(--color-gray-disabled);
margin-top: -0.5rem; margin-top: -0.5rem;
padding-left: 16px; padding-left: 16px;
} }
@ -169,8 +170,9 @@
} }
.loginButton { .loginButton {
background-color: #F25843; background-color: var(--color-secondary);
color: #E5E7EB; color: var(--color-text);
margin-top: 1rem;
} }
.loginButton:hover { .loginButton:hover {
@ -185,7 +187,7 @@
} }
.registerLink span { .registerLink span {
color: #E5E7EB; color: var(--color-text);
font-size: 0.8rem; font-size: 0.8rem;
} }
@ -222,9 +224,9 @@ button:disabled {
} }
.success { .success {
color: #10b981; color: var(--color-success);
background-color: rgba(16, 185, 129, 0.1); background-color: color-mix(in srgb, var(--color-success) 10%, transparent);
border: 1px solid #10b981; border: 1px solid var(--color-success);
border-radius: 25px; border-radius: 25px;
padding: 12px; padding: 12px;
font-size: 0.9rem; font-size: 0.9rem;

View file

@ -154,6 +154,7 @@ function Reset() {
{!successMessage && ( {!successMessage && (
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className={styles.passwordHint}>Mindestens 8 Zeichen</div>
<div className={styles.floatingLabelInput}> <div className={styles.floatingLabelInput}>
<input <input
type="password" type="password"
@ -170,7 +171,7 @@ function Reset() {
/> />
<label className={passwordFocused || password ? styles.focusedLabel : styles.label}>Neues Passwort</label> <label className={passwordFocused || password ? styles.focusedLabel : styles.label}>Neues Passwort</label>
</div> </div>
<div className={styles.passwordHint}>Mindestens 8 Zeichen</div>
<div className={styles.floatingLabelInput}> <div className={styles.floatingLabelInput}>
<input <input

View file

@ -22,6 +22,10 @@
--color-gray: #A0A4AA; --color-gray: #A0A4AA;
--color-gray-hover: #C4C8CD; --color-gray-hover: #C4C8CD;
--color-gray-disabled: #505357; --color-gray-disabled: #505357;
--color-success: #10b981;
--color-success-hover: #059669;
--color-success-disabled: #a7f3d0;
--font-family: "Trebuchet MS", sans-serif; --font-family: "Trebuchet MS", sans-serif;
--object-radius-large: 30px; --object-radius-large: 30px;

View file

@ -30,6 +30,10 @@
--color-highlight-gray: #F5F3ED; --color-highlight-gray: #F5F3ED;
--color-highlight-gray-hover: #E6E3DC; --color-highlight-gray-hover: #E6E3DC;
--color-highlight-gray-disabled: #F5F3ED80; --color-highlight-gray-disabled: #F5F3ED80;
--color-success: #10b981;
--color-success-hover: #059669;
--color-success-disabled: #a7f3d0;
--font-family: "DM Sans", sans-serif; --font-family: "DM Sans", sans-serif;
--object-radius-large: 30px; --object-radius-large: 30px;
@ -62,5 +66,9 @@
--color-gray: #181818; --color-gray: #181818;
--color-gray-hover: #2E2E2E; --color-gray-hover: #2E2E2E;
--color-gray-disabled: #505050; --color-gray-disabled: #505050;
--color-success: #10b981;
--color-success-hover: #059669;
--color-success-disabled: #a7f3d0;
} }