From 0dee7bd832b50305d786a47b44fa37ae156d7e36 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:40:45 +0000 Subject: [PATCH 1/3] Wave 3: modernize Sass (@use, math.div, ::ng-deep) and align browserslist with Angular 21 Co-Authored-By: Toby Drinkall --- browserslist | 11 +++++++---- src/app/app.component.scss | 4 ++-- src/app/core/footer/footer.component.scss | 4 ++-- src/app/core/header/header.component.scss | 4 ++-- src/app/core/settings/settings.component.scss | 4 ++-- src/app/feeds/feed/feed.component.scss | 4 ++-- src/app/feeds/item/item.component.scss | 4 ++-- src/app/item-details/comment/comment.component.scss | 6 +++--- src/app/item-details/item-details.component.scss | 4 ++-- .../error-message/error-message.component.scss | 13 +++++++------ .../shared/components/loader/loader.component.scss | 4 ++-- src/app/shared/scss/_themes.scss | 12 +++++++----- src/app/user/user.component.scss | 6 +++--- src/styles.scss | 2 +- 14 files changed, 44 insertions(+), 38 deletions(-) diff --git a/browserslist b/browserslist index 80848532e..93dd46280 100644 --- a/browserslist +++ b/browserslist @@ -5,8 +5,11 @@ # You can see what browsers were selected by your queries by running: # npx browserslist -> 0.5% -last 2 versions +# Aligned with the browsers supported by Angular. +# https://angular.dev/reference/versions#browser-support +last 2 Chrome versions +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss index c0b93891e..68eb5c52d 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,5 +1,5 @@ -@import "./shared/scss/media"; -@import "./shared/scss/theme_variables"; +@use "./shared/scss/media" as *; +@use "./shared/scss/theme_variables" as *; .body-cover { width: 100%; diff --git a/src/app/core/footer/footer.component.scss b/src/app/core/footer/footer.component.scss index 8adac775d..d77e88865 100644 --- a/src/app/core/footer/footer.component.scss +++ b/src/app/core/footer/footer.component.scss @@ -1,5 +1,5 @@ -@import "../../shared/scss/media"; -@import "../../shared/scss/theme_variables"; +@use "../../shared/scss/media" as *; +@use "../../shared/scss/theme_variables" as *; #footer { position: relative; diff --git a/src/app/core/header/header.component.scss b/src/app/core/header/header.component.scss index 75a262e76..530749709 100644 --- a/src/app/core/header/header.component.scss +++ b/src/app/core/header/header.component.scss @@ -1,5 +1,5 @@ -@import "../../shared/scss/media"; -@import "../../shared/scss/theme_variables"; +@use "../../shared/scss/media" as *; +@use "../../shared/scss/theme_variables" as *; #header { color: #fff; diff --git a/src/app/core/settings/settings.component.scss b/src/app/core/settings/settings.component.scss index 689da6584..06d9eec5a 100644 --- a/src/app/core/settings/settings.component.scss +++ b/src/app/core/settings/settings.component.scss @@ -1,5 +1,5 @@ -@import "../../shared/scss/media"; -@import "../../shared/scss/theme_variables"; +@use "../../shared/scss/media" as *; +@use "../../shared/scss/theme_variables" as *; .overlay { position: fixed; diff --git a/src/app/feeds/feed/feed.component.scss b/src/app/feeds/feed/feed.component.scss index febcd8cdd..f370e73a3 100644 --- a/src/app/feeds/feed/feed.component.scss +++ b/src/app/feeds/feed/feed.component.scss @@ -1,5 +1,5 @@ -@import "../../shared/scss/media"; -@import "../../shared/scss/theme_variables"; +@use "../../shared/scss/media" as *; +@use "../../shared/scss/theme_variables" as *; a { text-decoration: none; diff --git a/src/app/feeds/item/item.component.scss b/src/app/feeds/item/item.component.scss index 7f985c9c7..7d8a8e342 100644 --- a/src/app/feeds/item/item.component.scss +++ b/src/app/feeds/item/item.component.scss @@ -1,5 +1,5 @@ -@import "../../shared/scss/media"; -@import "../../shared/scss/theme_variables"; +@use "../../shared/scss/media" as *; +@use "../../shared/scss/theme_variables" as *; p { margin: 2px 0; diff --git a/src/app/item-details/comment/comment.component.scss b/src/app/item-details/comment/comment.component.scss index 83992b13c..a7e677f4f 100644 --- a/src/app/item-details/comment/comment.component.scss +++ b/src/app/item-details/comment/comment.component.scss @@ -1,7 +1,7 @@ -@import "../../shared/scss/media"; -@import "../../shared/scss/theme_variables"; +@use "../../shared/scss/media" as *; +@use "../../shared/scss/theme_variables" as *; -:host >>> { +:host ::ng-deep { a { font-weight: bold; text-decoration: none; diff --git a/src/app/item-details/item-details.component.scss b/src/app/item-details/item-details.component.scss index adde0bd7c..6da9a69c1 100644 --- a/src/app/item-details/item-details.component.scss +++ b/src/app/item-details/item-details.component.scss @@ -1,5 +1,5 @@ -@import "../shared/scss/media"; -@import "../shared/scss/theme_variables"; +@use "../shared/scss/media" as *; +@use "../shared/scss/theme_variables" as *; .main-content { position: relative; diff --git a/src/app/shared/components/error-message/error-message.component.scss b/src/app/shared/components/error-message/error-message.component.scss index eb5cc01e8..4597d7956 100644 --- a/src/app/shared/components/error-message/error-message.component.scss +++ b/src/app/shared/components/error-message/error-message.component.scss @@ -1,5 +1,6 @@ -@import "../../scss/media"; -@import "../../scss/theme_variables"; +@use "sass:math"; +@use "../../scss/media" as *; +@use "../../scss/theme_variables" as *; .error-section { height: 300px; @@ -65,9 +66,9 @@ content: ""; position: absolute; top: 100%; - left: $skull-size / 15; - border-right: $skull-size / 20 solid transparent; - border-left: $skull-size / 40 solid transparent; + left: math.div($skull-size, 15); + border-right: math.div($skull-size, 20) solid transparent; + border-left: math.div($skull-size, 40) solid transparent; } } } @@ -77,7 +78,7 @@ position: absolute; top: 75%; left: 30%; - border-radius: 0 0 $skull-size / 10 $skull-size / 10; + border-radius: 0 0 math.div($skull-size, 10) math.div($skull-size, 10); &:before { content: ""; position: absolute; diff --git a/src/app/shared/components/loader/loader.component.scss b/src/app/shared/components/loader/loader.component.scss index 625d0fe8b..c23880f59 100644 --- a/src/app/shared/components/loader/loader.component.scss +++ b/src/app/shared/components/loader/loader.component.scss @@ -1,5 +1,5 @@ -@import "../../scss/media"; -@import "../../scss/theme_variables"; +@use "../../scss/media" as *; +@use "../../scss/theme_variables" as *; .loader { -webkit-animation: load1 1s infinite ease-in-out; diff --git a/src/app/shared/scss/_themes.scss b/src/app/shared/scss/_themes.scss index 231ed7cf9..f2cab79e1 100644 --- a/src/app/shared/scss/_themes.scss +++ b/src/app/shared/scss/_themes.scss @@ -1,5 +1,7 @@ -@import "./media"; -@import "./theme_variables"; +@use "sass:color"; +@use "sass:math"; +@use "./media" as *; +@use "./theme_variables" as *; /* ---------------------------------- @@ -142,10 +144,10 @@ } &:before { - border-top: $skull-size / 8 solid $wrapper-background-color; + border-top: math.div($skull-size, 8) solid $wrapper-background-color; @media #{$mobile-only} { - border-top: $skull-size / 8 solid $wrapper-mobile-background-color; + border-top: math.div($skull-size, 8) solid $wrapper-mobile-background-color; } } } @@ -230,7 +232,7 @@ $theme-amoledblack-body-background-color, $theme-amoledblack-text-color, $theme-amoledblack-text-color, - darken($theme-amoledblack-text-color, 33%), + color.adjust($theme-amoledblack-text-color, $lightness: -33%), $theme-amoledblack-body-background-color, $theme-amoledblack-subtext-color, $theme-amoledblack-secondary-color, diff --git a/src/app/user/user.component.scss b/src/app/user/user.component.scss index c5fc9af57..3bfc72d0d 100644 --- a/src/app/user/user.component.scss +++ b/src/app/user/user.component.scss @@ -1,7 +1,7 @@ -@import "../shared/scss/media"; -@import "../shared/scss/theme_variables"; +@use "../shared/scss/media" as *; +@use "../shared/scss/theme_variables" as *; -:host >>> pre { +:host ::ng-deep pre { white-space: pre-wrap; } diff --git a/src/styles.scss b/src/styles.scss index 3e06b9378..88dbe5716 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,4 +1,4 @@ -@import "./app/shared/scss/themes"; +@use "./app/shared/scss/themes"; html { height: 100%; From d7af3be83eafebce5e9e887aa99f633f31b4c954 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:46:42 +0000 Subject: [PATCH 2/3] Provide zone change detection explicitly for Angular 21 zoneless default Co-Authored-By: Toby Drinkall --- src/app/app.module.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5753df619..5551e1e78 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,5 +1,5 @@ import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import { NgModule, provideZoneChangeDetection } from '@angular/core'; import { routing } from './app.routes'; @@ -26,7 +26,7 @@ import { SettingsService } from './shared/services/settings.service'; enabled: environment.production, }), ], - providers: [HackerNewsAPIService, SettingsService], + providers: [provideZoneChangeDetection(), HackerNewsAPIService, SettingsService], bootstrap: [AppComponent], }) export class AppModule {} From 17de9dcf2af72dd340aa81caa56523f27c7e9e11 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:50:45 +0000 Subject: [PATCH 3/3] Enable event coalescing for zone change detection Co-Authored-By: Toby Drinkall --- src/app/app.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5551e1e78..a2c13d74e 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -26,7 +26,7 @@ import { SettingsService } from './shared/services/settings.service'; enabled: environment.production, }), ], - providers: [provideZoneChangeDetection(), HackerNewsAPIService, SettingsService], + providers: [provideZoneChangeDetection({ eventCoalescing: true }), HackerNewsAPIService, SettingsService], bootstrap: [AppComponent], }) export class AppModule {}