Using tailwind instead of scss as much as possible
Build, Test & Push Frontend / docker (pull_request) Has been cancelled
Build, Test & Push Frontend / quality-check (pull_request) Has been cancelled

This commit is contained in:
Andreas Dahm committed 2026-04-16 11:58:16 +02:00
1 parent f9797493ce
commit 9a6e91ea9d
32 files changed
+1185 -1353

No files matched your search

+2 -2
View File
@@ -1,9 +1,9 @@
<app-particles-background></app-particles-background>
<app-topbar />
<main class="app-container app-surface">
<main class="w-full max-w-app mx-auto mt-4 grow text-app-fg transition-colors duration-[220ms]">
<router-outlet />
</main>
<footer class="foot">
<footer class="border-t border-black/[.08] p-fluid-md text-center opacity-80 bg-app-bg">
<small>© {{ currentYear }} Andreas Dahm - {{ `APP.COPYRIGHT` | translate }}</small>
</footer>
+17 -13
View File
@@ -1,23 +1,27 @@
<mat-toolbar class="topbar" color="primary" (keydown)="onKeydown($event)">
<a class="brand" routerLink="/">
<img class="logo-dot" src="{{AssetsConstants.LOGO}}" alt="" aria-hidden="true" draggable="false"
<mat-toolbar class="!flex !items-center !p-[clamp(0.5rem,1vw,1rem)] !backdrop-blur-[8px] !backdrop-saturate-[1.1] !bg-white/80 dark:!bg-[#313131]/80 !border-b !border-black/[.08]" color="primary" (keydown)="onKeydown($event)">
<a class="flex items-center gap-[clamp(0.4rem,1vw,0.6rem)] text-inherit no-underline" routerLink="/">
<img class="w-[clamp(36px,10vw,48px)] h-[clamp(36px,10vw,48px)] rounded-full" src="{{AssetsConstants.LOGO}}" alt="" aria-hidden="true" draggable="false"
oncontextmenu="return false;">
<span class="brand-text">{{ 'APP.TITLE' | translate }}</span>
<span class="font-semibold tracking-[0.2px] text-[clamp(1rem,3vw,1.2rem)]">{{ 'APP.TITLE' | translate }}</span>
</a>
<nav class="nav">
<a [routerLink]="RouterConstants.ABOUT.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.ABOUT' | translate }}</a>
<a [routerLink]="RouterConstants.PROJECTS.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.PROJECTS' | translate }}</a>
<a [routerLink]="RouterConstants.ALGORITHMS.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.ALGORITHMS' | translate }}</a>
<a [routerLink]="RouterConstants.IMPRINT.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.IMPRINT' | translate }}</a>
<nav class="absolute left-1/2 -translate-x-1/2 flex gap-[clamp(0.25rem,1vw,0.5rem)] justify-center mobile:hidden">
<a class="opacity-70 transition-opacity duration-150 hover:opacity-100 relative after:content-[''] after:absolute after:bottom-1 after:left-2.5 after:right-2.5 after:h-0.5 after:bg-current after:rounded-sm after:scale-x-0 after:transition-transform [&.active]:opacity-100 [&.active]:after:scale-x-100"
[routerLink]="RouterConstants.ABOUT.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.ABOUT' | translate }}</a>
<a class="opacity-70 transition-opacity duration-150 hover:opacity-100 relative after:content-[''] after:absolute after:bottom-1 after:left-2.5 after:right-2.5 after:h-0.5 after:bg-current after:rounded-sm after:scale-x-0 after:transition-transform [&.active]:opacity-100 [&.active]:after:scale-x-100"
[routerLink]="RouterConstants.PROJECTS.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.PROJECTS' | translate }}</a>
<a class="opacity-70 transition-opacity duration-150 hover:opacity-100 relative after:content-[''] after:absolute after:bottom-1 after:left-2.5 after:right-2.5 after:h-0.5 after:bg-current after:rounded-sm after:scale-x-0 after:transition-transform [&.active]:opacity-100 [&.active]:after:scale-x-100"
[routerLink]="RouterConstants.ALGORITHMS.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.ALGORITHMS' | translate }}</a>
<a class="opacity-70 transition-opacity duration-150 hover:opacity-100 relative after:content-[''] after:absolute after:bottom-1 after:left-2.5 after:right-2.5 after:h-0.5 after:bg-current after:rounded-sm after:scale-x-0 after:transition-transform [&.active]:opacity-100 [&.active]:after:scale-x-100"
[routerLink]="RouterConstants.IMPRINT.LINK" routerLinkActive="active" mat-button>{{ 'TOPBAR.IMPRINT' | translate }}</a>
</nav>
<!-- Mobile nav menu button -->
<button mat-icon-button class="nav-menu-btn" [matMenuTriggerFor]="navMenu" aria-label="Open navigation">
<button mat-icon-button class="hidden mobile:inline-flex" [matMenuTriggerFor]="navMenu" aria-label="Open navigation">
<mat-icon>menu</mat-icon>
</button>
<span class="spacer"></span>
<span class="flex-1"></span>
<!-- Mobile nav menu -->
<mat-menu #navMenu="matMenu" xPosition="before">
@@ -35,7 +39,7 @@
</button>
</mat-menu>
<span class="spacer"></span>
<span class="flex-1"></span>
<!-- Settings: Sprache + Theme -->
<button mat-icon-button [matMenuTriggerFor]="settingsMenu" aria-label="Open settings"
@@ -75,4 +79,4 @@
</button>
</div>
</mat-menu>
</mat-toolbar>
</mat-toolbar>
+4 -105
View File
@@ -1,107 +1,6 @@
/* ---- Topbar Host & Base ---- */
:host {
position: sticky;
top: 0;
z-index: 100;
display: block;
position: sticky;
top: 0;
z-index: 100;
display: block;
}
.topbar {
/* Erzeugt den Milchglas-Effekt */
backdrop-filter: saturate(1.1) blur(8px);
-webkit-backdrop-filter: saturate(1.1) blur(8px);
/* Safari Support */
/* Mischt die Variable mit Transparenz. !important überschreibt Material-Vorgaben */
background: color-mix(in oklab, var(--app-topbar-bg) 80%, transparent) !important;
border-bottom: 1px solid rgba(0, 0, 0, .08);
display: flex;
align-items: center;
padding: clamp(0.5rem, 1vw, 1rem);
}
/* ---- Branding ---- */
.brand {
display: flex;
align-items: center;
gap: clamp(0.4rem, 1vw, 0.6rem);
color: inherit;
text-decoration: none;
.logo-dot {
width: clamp(36px, 10vw, 48px);
height: clamp(36px, 10vw, 48px);
border-radius: 50%;
}
.brand-text {
font-weight: 600;
letter-spacing: .2px;
font-size: clamp(1rem, 3vw, 1.2rem);
}
}
/* ---- Navigation ---- */
.nav {
position: absolute;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: clamp(0.25rem, 1vw, 0.5rem);
justify-content: center;
}
.nav a {
opacity: 0.72;
transition: opacity 150ms ease;
position: relative;
&::after {
content: '';
position: absolute;
bottom: 4px;
left: 10px;
right: 10px;
height: 2px;
background: currentColor;
border-radius: 2px;
transform: scaleX(0);
transition: transform 200ms ease;
}
&:hover {
opacity: 1;
}
&.active {
opacity: 1;
&::after {
transform: scaleX(1);
}
}
}
.nav-menu-btn {
display: none;
}
.spacer {
flex: 1;
}
/* ---- Mobile Responsiveness ---- */
@media (max-width: 760px) {
.nav {
display: none;
}
.nav-menu-btn {
display: inline-flex;
}
.brand {
flex: unset;
}
}