diff --git a/src/app/layout/topbar/topbar.component.html b/src/app/layout/topbar/topbar.component.html
index 19c1a4e..5b3701f 100644
--- a/src/app/layout/topbar/topbar.component.html
+++ b/src/app/layout/topbar/topbar.component.html
@@ -6,10 +6,10 @@
diff --git a/src/app/layout/topbar/topbar.component.scss b/src/app/layout/topbar/topbar.component.scss
index 6055d18..1518279 100644
--- a/src/app/layout/topbar/topbar.component.scss
+++ b/src/app/layout/topbar/topbar.component.scss
@@ -52,6 +52,37 @@
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;
}
diff --git a/src/app/layout/topbar/topbar.component.ts b/src/app/layout/topbar/topbar.component.ts
index 014738d..f1ebb6c 100644
--- a/src/app/layout/topbar/topbar.component.ts
+++ b/src/app/layout/topbar/topbar.component.ts
@@ -1,5 +1,5 @@
import { Component, computed, inject } from '@angular/core';
-import { RouterLink } from '@angular/router';
+import { RouterLink, RouterLinkActive } from '@angular/router';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
@@ -15,7 +15,7 @@ import {RouterConstants} from '../../constants/RouterConstants';
@Component({
selector: 'app-topbar',
imports: [
- RouterLink,
+ RouterLink, RouterLinkActive,
MatToolbarModule, MatIconModule, MatButtonModule, MatMenuModule, MatTooltipModule,
TranslateModule, MatDivider
],
diff --git a/src/app/pages/algorithms/algorithm-category.ts b/src/app/pages/algorithms/algorithm-category.ts
index 15971f6..046b232 100644
--- a/src/app/pages/algorithms/algorithm-category.ts
+++ b/src/app/pages/algorithms/algorithm-category.ts
@@ -3,4 +3,5 @@ export interface AlgorithmCategory {
title: string;
description: string;
routerLink: string;
+ icon: string;
}
diff --git a/src/app/pages/algorithms/algorithms.component.html b/src/app/pages/algorithms/algorithms.component.html
index 2e2efcb..838b550 100644
--- a/src/app/pages/algorithms/algorithms.component.html
+++ b/src/app/pages/algorithms/algorithms.component.html
@@ -1,15 +1,16 @@
-
{{ 'ALGORITHM.TITLE' |translate }}
+ {{ 'ALGORITHM.TITLE' | translate }}
-@for (category of categories; track category.id) {
+ @for (category of categories; track category.id) {
-
- {{ category.title | translate }}
-
- {{ category.description | translate}}
+
+ {{ category.icon }}
+
+ {{ category.title | translate }}
+ {{ category.description | translate }}
}
-
+
diff --git a/src/app/pages/algorithms/algorithms.component.ts b/src/app/pages/algorithms/algorithms.component.ts
index 3dc2ee2..7ebb2a4 100644
--- a/src/app/pages/algorithms/algorithms.component.ts
+++ b/src/app/pages/algorithms/algorithms.component.ts
@@ -3,13 +3,14 @@ import { AlgorithmsService } from './algorithms.service';
import { AlgorithmCategory } from './algorithm-category';
import { RouterLink } from '@angular/router';
import { MatCardModule } from '@angular/material/card';
+import { MatIconModule } from '@angular/material/icon';
import {TranslatePipe} from '@ngx-translate/core';
@Component({
selector: 'app-algorithms',
templateUrl: './algorithms.component.html',
styleUrl: './algorithms.component.scss',
- imports: [RouterLink, MatCardModule, TranslatePipe],
+ imports: [RouterLink, MatCardModule, MatIconModule, TranslatePipe],
})
export class AlgorithmsComponent {
private readonly algorithmsService = inject(AlgorithmsService);
diff --git a/src/app/pages/algorithms/algorithms.service.ts b/src/app/pages/algorithms/algorithms.service.ts
index 83b8cdb..9459254 100644
--- a/src/app/pages/algorithms/algorithms.service.ts
+++ b/src/app/pages/algorithms/algorithms.service.ts
@@ -12,49 +12,57 @@ export class AlgorithmsService {
id: 'pathfinding',
title: 'ALGORITHM.PATHFINDING.TITLE',
description: 'ALGORITHM.PATHFINDING.DESCRIPTION',
- routerLink: RouterConstants.PATHFINDING.LINK
+ routerLink: RouterConstants.PATHFINDING.LINK,
+ icon: 'route'
},
{
id: 'sorting',
title: 'ALGORITHM.SORTING.TITLE',
description: 'ALGORITHM.SORTING.DESCRIPTION',
- routerLink: RouterConstants.SORTING.LINK
+ routerLink: RouterConstants.SORTING.LINK,
+ icon: 'sort'
},
{
id: 'gameOfLife',
title: 'ALGORITHM.GOL.TITLE',
description: 'ALGORITHM.GOL.DESCRIPTION',
- routerLink: RouterConstants.GOL.LINK
+ routerLink: RouterConstants.GOL.LINK,
+ icon: 'grid_on'
},
{
id: 'labyrinth',
title: 'ALGORITHM.LABYRINTH.TITLE',
description: 'ALGORITHM.LABYRINTH.DESCRIPTION',
- routerLink: RouterConstants.LABYRINTH.LINK
+ routerLink: RouterConstants.LABYRINTH.LINK,
+ icon: 'grid_view'
},
{
id: 'fractal',
title: 'ALGORITHM.FRACTAL.TITLE',
description: 'ALGORITHM.FRACTAL.DESCRIPTION',
- routerLink: RouterConstants.FRACTAL.LINK
+ routerLink: RouterConstants.FRACTAL.LINK,
+ icon: 'blur_on'
},
{
id: 'fractal3d',
title: 'ALGORITHM.FRACTAL3D.TITLE',
description: 'ALGORITHM.FRACTAL3D.DESCRIPTION',
- routerLink: RouterConstants.FRACTAL3d.LINK
+ routerLink: RouterConstants.FRACTAL3d.LINK,
+ icon: 'view_in_ar'
},
{
id: 'pendulum',
title: 'ALGORITHM.PENDULUM.TITLE',
description: 'ALGORITHM.PENDULUM.DESCRIPTION',
- routerLink: RouterConstants.PENDULUM.LINK
+ routerLink: RouterConstants.PENDULUM.LINK,
+ icon: 'rotate_right'
},
{
id: 'cloth',
title: 'ALGORITHM.CLOTH.TITLE',
description: 'ALGORITHM.CLOTH.DESCRIPTION',
- routerLink: RouterConstants.CLOTH.LINK
+ routerLink: RouterConstants.CLOTH.LINK,
+ icon: 'texture'
}
];
diff --git a/src/styles.scss b/src/styles.scss
index 7144ca5..14f5545 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -50,6 +50,10 @@ $dark-theme: mat.define-theme((color: (theme-type: dark, primary: mat.$cyan-pale
--link-color-hover: #9ad2ff;
}
+.dark body {
+ background: radial-gradient(ellipse at 50% 0%, #1e2530 0%, #1a1a1a 65%);
+}
+
/* ---- global background and tests ---- */
html,
body {
@@ -287,12 +291,17 @@ a {
}
canvas {
- border: 1px solid lightgray;
+ border: none;
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
display: block;
margin: 0 auto;
max-width: 100%;
}
+.dark canvas {
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
+}
+
.legend {
display: flex;
flex-wrap: wrap;
@@ -518,6 +527,10 @@ app-root {
margin-top: 0;
margin-bottom: 0.5rem;
font-size: clamp(1.5rem, 5vw, 2.5rem);
+ background: linear-gradient(135deg, var(--mat-sys-primary), var(--mat-sys-tertiary));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
}
.hero .intro .lead {
@@ -706,6 +719,57 @@ app-root {
display: flex;
flex-direction: column;
cursor: pointer;
+
+ &:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ }
+}
+
+.algo-card::after, .project-card::after {
+ inset: unset;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--mat-sys-primary), var(--mat-sys-tertiary));
+ border-radius: var(--card-radius) var(--card-radius) 0 0;
+}
+
+.algo-icon-wrap {
+ width: 48px;
+ height: 48px;
+ border-radius: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: color-mix(in oklab, var(--mat-sys-primary) 15%, transparent);
+ color: var(--mat-sys-primary);
+ margin-bottom: 1rem;
+
+ mat-icon {
+ font-size: 26px;
+ width: 26px;
+ height: 26px;
+ }
+}
+
+.algo-page-title {
+ margin: 0 0 0.5rem 0;
+ font-size: clamp(1.4rem, 4vw, 2rem);
+}
+
+.algo-card-title {
+ font-size: 1.05rem;
+ font-weight: 600;
+ margin: 0 0 0.5rem 0;
+}
+
+.algo-card-desc {
+ margin: 0;
+ opacity: 0.75;
+ font-size: 0.9rem;
+ line-height: 1.55;
}
.project-card {