Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d52b3b1
Reapply "feat: enable light mode (#255)" (#443)
marcin-hoa May 13, 2025
956f02b
feat: light mode improvements
marcin-hoa May 19, 2025
c8ace7e
chore: clean-up
marcin-hoa May 19, 2025
38ca2d3
fix: hamburger-button color
marcin-hoa May 19, 2025
e97641f
feat: added theme switcher - wip
marcin-hoa May 19, 2025
9329dcd
feat: added theme switch and fixed cookies consent logic
marcin-hoa May 29, 2025
0445dc3
feat: added theme in gh-giscus component
marcin-hoa May 29, 2025
e0a2694
feat: enhance theming support with light/dark variants and gradient o…
marcin-hoa Jun 4, 2025
5fccbda
fix: typo
marcin-hoa Jun 5, 2025
e957263
fix(client): fixed issue with author card in article
DamianBrzezinskiHoA Aug 12, 2025
18a4c96
fix(client): fixed issue after rebasing to main
DamianBrzezinskiHoA Aug 12, 2025
097903d
feat(client): appended lightmode for roadmap section
DamianBrzezinskiHoA Aug 14, 2025
44ba780
feat(client): changed roadmap lightmode
DamianBrzezinskiHoA Aug 19, 2025
102f365
feat(client): changed primary tile color
DamianBrzezinskiHoA Aug 20, 2025
c04b42c
feat: add footer light mode support
dmaduzia Oct 2, 2025
6f217ab
Merge branch 'main' into feature/light-mode
dmaduzia Oct 2, 2025
564f72d
fix: update code block background color
dmaduzia Oct 2, 2025
7d2e0d2
fix: prevent images from jumping when switching theme
dmaduzia Oct 2, 2025
1bc2613
feat: use dark mode as default
dmaduzia Oct 3, 2025
2764f48
chore: update roadmap colors
dmaduzia Oct 3, 2025
0323183
Merge branch 'main' into feature/light-mode
dmaduzia Oct 6, 2025
e7281ca
chore: pr cleanup
dmaduzia Oct 6, 2025
4b86026
chore: remove unused import
dmaduzia Oct 6, 2025
169c1cd
refactor: address pr comments
dmaduzia Oct 7, 2025
6013a04
refactor: address pr comment
dmaduzia Oct 7, 2025
097b62d
feat: footer tweaks (#476)
dmaduzia Oct 15, 2025
1a57dc8
fix: address ai comments
dmaduzia Oct 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/blog/src/assets/icons/arrow-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/blog/src/assets/icons/moon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/blog/src/assets/icons/sun.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<ng-container *transloco="let t; read: 'aboutUsPage'">
<h2 class="py-4 text-[40px] font-bold">
<h2 class="text-al-primary-foreground py-4 text-[40px] font-bold">
{{ t('title') }}
</h2>

<al-card>
<al-card class="bg-transparent">
<section
alCardContent
aria-labelledby="angular-love"
Expand Down Expand Up @@ -35,13 +35,18 @@ <h2 class="py-4 text-[40px] font-bold">
<al-newsletter alCardContent />
</al-card>

<h2 class="mb-8 mt-10 text-[40px] font-bold">
<h2 class="text-al-primary-foreground mb-8 mt-10 text-[40px] font-bold">
{{ t('authorsTitle') }}
</h2>
</ng-container>

@for (author of authorsCards(); track author.slug) {
<al-author-card class="mb-6 block" [author]="author" [linkable]="true" />
<al-author-card
class="mb-6 block"
[author]="author"
[linkable]="true"
[hideGradient]="hideGradientInAuthorCards()"
/>

@if ($index === noAuthorsInView() - 2) {
@defer (on viewport) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '@angular-love/blog/shared/ui-card';
import { InfiniteScrollTriggerDirective } from '@angular-love/blog/shared/ui-pagination';
import { SocialMediaIconsComponent } from '@angular-love/blog/shared/ui-social-media-icons';
import { AppThemeStore } from '@angular-love/data-access-app-theme';

@Component({
selector: 'al-about-us',
Expand All @@ -41,6 +42,10 @@ export class FeatureAboutUsComponent implements OnInit {
return this.authorsCards()?.length || 0;
});

readonly theme = inject(AppThemeStore).theme;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be private


readonly hideGradientInAuthorCards = computed(() => this.theme() === 'light');

private readonly _skip = this._authorListStore.skip;
private readonly _total = this._authorListStore.total;
private readonly _pageSize = this._authorListStore.pageSize;
Expand Down
37 changes: 24 additions & 13 deletions libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { isPlatformBrowser } from '@angular/common';
import { inject, Injectable, PLATFORM_ID } from '@angular/core';
import { signalStore, withMethods, withState } from '@ngrx/signals';
import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';

type Theme = 'dark' | 'light';
export type Theme = 'dark' | 'light';

interface AppThemeStore {
theme: Theme;
}

export const AppThemeStore = signalStore(
{ providedIn: 'root' },
withState<AppThemeStore>({ theme: 'light' }),
withState<AppThemeStore>({ theme: 'dark' }),
withMethods(
(
store,
Expand All @@ -19,7 +19,18 @@ export const AppThemeStore = signalStore(
) => ({
syncWithSystemTheme: () => {
if (isPlatformBrowser(platformId)) {
ccConsumer.setThemeClass(getSystemTheme());
const theme =
(localStorage.getItem('theme') as Theme) ?? getSystemTheme();
ccConsumer.setThemeAttribute(theme);
patchState(store, { theme: theme });
}
},
toggleTheme: () => {
if (isPlatformBrowser(platformId)) {
const newTheme = store.theme() === 'dark' ? 'light' : 'dark';
ccConsumer.setThemeAttribute(newTheme);
localStorage.setItem('theme', newTheme);
patchState(store, { theme: newTheme });
}
},
}),
Expand All @@ -35,15 +46,15 @@ function getSystemTheme(): Theme {
/* todo: create consumer interface and decouple AppThemeStore from CCAppThemeConsumer*/
@Injectable({ providedIn: 'root' })
export class CCAppThemeConsumer {
setThemeClass(theme: Theme): void {
const htmlElement = document.documentElement;
switch (theme) {
case 'dark':
htmlElement.classList.add('cc--darkmode');
break;
case 'light':
htmlElement.classList.remove('cc--darkmode');
break;
setThemeAttribute(theme: Theme): void {
document.documentElement.setAttribute('data-theme', theme);

const classList = document.documentElement.classList;

if (theme === 'dark') {
classList.add('cc--darkmode');
} else {
classList.remove('cc--darkmode');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <h1 id="article-title" class="flex text-[40px] font-bold">
</section>
<aside class="order-3 col-span-12 lg:col-span-4">
<al-author-card
[articleCard]="true"
[author]="articleDetails().author"
[clampText]="true"
[linkable]="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[attr.strict]="config.strict ? '1' : '0'"
[attr.emitmetadata]="config.emitMetadata ? '1' : '0'"
[attr.inputposition]="config.inputPosition"
[attr.theme]="config.theme"
[attr.theme]="theme()"
src="https://giscus.app/client.js"
crossorigin="anonymous"
async
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {
GISCUS_CONFIG,
provideComments,
} from '@angular-love/blog/articles/data-access';
import { AppThemeStore } from '@angular-love/data-access-app-theme';

@Component({
selector: 'al-giscus-comments',
imports: [],
templateUrl: './giscus-comments.component.html',
styleUrl: './giscus-comments.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
Expand All @@ -30,6 +30,7 @@ import {
export class GiscusCommentsComponent {
readonly config = inject(GISCUS_CONFIG);
readonly translocoService = inject(TranslocoService);
readonly theme = inject(AppThemeStore).theme;

readonly lang = toSignal(this.translocoService.langChanges$, {
initialValue: this.translocoService.getActiveLang(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</section>

<div class="flex justify-center gap-3">
<button al-button role="link" [routerLink]="selected().link">
<button al-button role="link" [routerLink]="selected().link" size="medium">
{{ t('categories.showAll', { category: t(selected().translationPath) }) }}
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import { CategoryListItem, injectCategories } from './categories.const';
NgClass,
TranslocoDirective,
ArticleRegularCardSkeletonComponent,
CardComponent,
RepeatDirective,
RouterLink,
ButtonComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<a [routerLink]="['/', article().slug] | alLocalize">
<article
class="h-full rounded-lg bg-cover bg-no-repeat transition-transform hover:scale-105 motion-reduce:transition-none motion-reduce:hover:scale-100"
[style.background-image]="
'url(' +
(article().featuredImageUrl || 'assets/article-placeholder.webp') +
')'
"
class="relative h-full overflow-hidden rounded-lg bg-black bg-cover bg-no-repeat transition-transform hover:scale-105 motion-reduce:transition-none motion-reduce:hover:scale-100"
[attr.aria-labelledby]="article().slug"
>
<div
class="bg-al-background relative flex h-full flex-col justify-between opacity-85"
>
<img
alt="Post featured image"
class="absolute h-auto w-full bg-contain opacity-20"
[ngSrc]="article().featuredImageUrl || 'assets/article-placeholder.webp'"
[priority]="imagePriority()"
width="1215"
height="750"
/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Absolute image needs correct positioning and object-fit; fix wrong Tailwind class; clarify accessibility; ensure priority boolean

  • The absolute img lacks positioning (top/left/inset), so it may not anchor to the container’s top-left.
  • bg-contain is a background-image utility; for use object-contain/object-cover.
  • The image appears decorative (background), so alt="" with aria-hidden is more appropriate to avoid noisy SR output.
  • [priority] expects boolean (NgOptimizedImage). Passing number|null relies on coercion. Be explicit.

Apply this diff:

-    <img
-      alt="Post featured image"
-      class="absolute h-auto w-full bg-contain opacity-20"
-      [ngSrc]="article().featuredImageUrl || 'assets/article-placeholder.webp'"
-      [priority]="imagePriority()"
-      width="1215"
-      height="750"
-    />
+    <img
+      alt=""
+      aria-hidden="true"
+      class="absolute inset-0 z-0 h-full w-full object-cover opacity-20"
+      [ngSrc]="article().featuredImageUrl || 'assets/article-placeholder.webp'"
+      [priority]="!!imagePriority()"
+      width="1215"
+      height="750"
+    />

Notes:

  • If you prefer to keep the image informative, bind alt to the title instead: alt="{{ article().title }}" (but avoid duplicating the visible title for SRs).
  • If cropping is undesirable, use object-contain object-center instead of object-cover.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img
alt="Post featured image"
class="absolute h-auto w-full bg-contain opacity-20"
[ngSrc]="article().featuredImageUrl || 'assets/article-placeholder.webp'"
[priority]="imagePriority()"
width="1215"
height="750"
/>
<img
alt=""
aria-hidden="true"
class="absolute inset-0 z-0 h-full w-full object-cover opacity-20"
[ngSrc]="article().featuredImageUrl || 'assets/article-placeholder.webp'"
[priority]="!!imagePriority()"
width="1215"
height="750"
/>
🤖 Prompt for AI Agents
In
libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.html
around lines 6-13, the <img> is absolute but lacks positioning and uses a
background utility; change the Tailwind classes to include explicit positioning
(e.g. top-0 left-0 w-full h-full) and use an object-fit utility (object-cover or
object-contain object-center) instead of bg-contain; mark the image as purely
decorative by setting alt="" and aria-hidden="true" (or if you want it
informative bind alt to article().title instead), and make the priority binding
an explicit boolean (e.g. [priority]="!!imagePriority()" or
[priority]="imagePriority() === true") so NgOptimizedImage receives a boolean.

<div class="relative flex h-full flex-col justify-between text-[#fff]">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Text color hard-coded; add stacking safety for content layer

  • text-[#fff] bypasses theme tokens and may clash in light mode.
  • Ensure content is layered above the overlay/image explicitly.

Apply this diff to enforce stacking (and drop hard-coded hex if tokens exist):

-    <div class="relative flex h-full flex-col justify-between text-[#fff]">
+    <div class="relative z-20 flex h-full flex-col justify-between text-al-foreground">

If text-al-foreground is unavailable, use your theme variant equivalents (e.g., text-gray-900 [data-theme=dark]:text-white).
Additionally, update the overlay (outside this range) to sit between image and content and ignore pointer events:

<!-- Line 16 update example -->
<div class="absolute inset-0 z-10 h-full w-full pointer-events-none hover:bg-al-bottom-radial-gradient"></div>

<div
class="hover:bg-al-bottom-radial-gradient absolute h-full w-full"
></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { NgOptimizedImage } from '@angular/common';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { RouterLink } from '@angular/router';
import { FastSvgComponent } from '@push-based/ngx-fast-svg';
Expand All @@ -9,9 +10,17 @@ import { AvatarComponent } from '@angular-love/blog/shared/ui-avatar';
@Component({
selector: 'al-article-compact-card',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [AvatarComponent, RouterLink, AlLocalizePipe, FastSvgComponent],
standalone: true,
imports: [
AvatarComponent,
RouterLink,
AlLocalizePipe,
FastSvgComponent,
NgOptimizedImage,
],
templateUrl: './article-compact-card.component.html',
})
export class ArticleCompactCardComponent {
readonly article = input.required<ArticleCard>();
readonly imagePriority = input<number | null>(null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CardComponent } from '@angular-love/blog/shared/ui-card';
selector: 'al-article-hero-card-skeleton',
imports: [NgxSkeletonLoaderModule, CardComponent],
template: `
<al-card>
<al-card class="bg-transparent">
<div alCardContent class="p-2">
<div class="flex flex-row items-center">
<!-- avatar -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<a [routerLink]="['/', article().slug] | alLocalize">
<article
class="group relative flex h-full w-full flex-row rounded-lg shadow-none max-h-52"
class="light:border group relative flex h-full w-full flex-row rounded-lg shadow-none"
[attr.aria-labelledby]="article().slug"
>
<img
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<a [routerLink]="['/', article().slug] | alLocalize">
<article
class="bg-al-card md:hover:shadow-al-primary group relative h-full w-full rounded-lg border border-transparent shadow-none transition-transform motion-reduce:transition-none lg:hover:scale-105 lg:motion-reduce:hover:scale-100"
class="bg-al-card md:hover:shadow-al-primary group relative h-full w-full rounded-lg border shadow-none transition-transform motion-reduce:transition-none lg:hover:scale-105 lg:motion-reduce:hover:scale-100 dark:border-transparent"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Inconsistent border approach between themes.

The border styling uses border with dark:border-transparent, but this conflicts with the theme-scoped approach established in the main.scss file. Consider using the --border CSS variable consistently across both themes instead of overriding with Tailwind's dark variant.

-    class="bg-al-card md:hover:shadow-al-primary group relative h-full w-full rounded-lg border shadow-none transition-transform motion-reduce:transition-none lg:hover:scale-105 lg:motion-reduce:hover:scale-100 dark:border-transparent"
+    class="bg-al-card md:hover:shadow-al-primary group relative h-full w-full rounded-lg border-al-border shadow-none transition-transform motion-reduce:transition-none lg:hover:scale-105 lg:motion-reduce:hover:scale-100"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class="bg-al-card md:hover:shadow-al-primary group relative h-full w-full rounded-lg border shadow-none transition-transform motion-reduce:transition-none lg:hover:scale-105 lg:motion-reduce:hover:scale-100 dark:border-transparent"
class="bg-al-card md:hover:shadow-al-primary group relative h-full w-full rounded-lg border-al-border shadow-none transition-transform motion-reduce:transition-none lg:hover:scale-105 lg:motion-reduce:hover:scale-100"
🤖 Prompt for AI Agents
In
libs/blog/articles/ui-article-card/src/lib/components/article-regular-card/article-regular-card.component.html
around line 3, the element uses Tailwind's generic border class plus
dark:border-transparent which conflicts with the theme-scoped border variable;
replace the hard-coded border classes with the theme-aware border variable
approach (use the --border CSS variable for border color/width via an
appropriate utility or inline style and remove the dark: override) so both light
and dark themes rely on the main.scss --border value; ensure the element no
longer uses the plain "border" and "dark:border-transparent" classes and instead
applies the border using the --border variable consistent with the rest of the
app.

[attr.aria-labelledby]="article().slug"
>
<div
Expand All @@ -18,8 +18,12 @@
<div class="rounded-b-lg">
<div class="flex items-center justify-between px-4 pt-4">
<div class="flex items-center gap-2">
<al-avatar [imageSrc]="article().author.avatarUrl" size="32" />
<span class="text-sm/[14px] font-medium">
<al-avatar
[imageSrc]="article().author.avatarUrl"
[priority]="imagePriority()"
size="32"
/>
<span class="text-al-primary-foreground text-sm/[14px] font-medium">
{{ article().author.name }}
</span>
</div>
Expand All @@ -34,10 +38,14 @@
</div>
</div>
<div class="flex flex-col gap-3 px-4 pb-4 pt-3">
<h3 class="text-2xl font-bold" [id]="article().slug">
<h3
class="*:text-al-primary-foreground text-2xl font-bold *:not-italic"
[id]="article().slug"
style="word-break: break-word"
>
{{ article().title }}
</h3>
<p class="line-clamp-2">
<p class="*:text-al-pink line-clamp-2 *:font-medium *:not-italic">
{{ article().excerpt }}
</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
/>
}
@case ('compact') {
<al-article-compact-card [article]="article()" />
<al-article-compact-card
[article]="article()"
[imagePriority]="imagePriority()"
/>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
margin-top: 1.6rem;
}

@media (prefers-color-scheme: dark) {
:root[data-theme='dark'] {
.shiki,
.shiki span {
color: var(--shiki-dark) !important;
Expand Down Expand Up @@ -53,6 +53,7 @@
code:not(pre code) {
padding: 0.2em 0.4em;
background: #2e2f3b;
color: white;
border-radius: 4px;
font-size: 0.85rem;
font-weight: 600;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { DomSanitizer } from '@angular/platform-browser';
selector: 'al-article-content',
templateUrl: './article-content.component.html',
styleUrl: './article-content.component.scss',
imports: [],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="my-5 flex flex-row items-center justify-between gap-6">
<h2
data-testId="article-list-title"
class="line-clamp-2 max-w-[160px] text-xl font-bold md:line-clamp-1 md:max-w-full lg:text-3xl"
class="text-al-primary-foreground line-clamp-2 max-w-[160px] text-xl font-bold md:line-clamp-1 md:max-w-full lg:text-3xl"
>
{{ title() }}
</h2>
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import { Component, computed, input } from '@angular/core';

import {
CardComponent,
Expand All @@ -13,29 +13,43 @@ import {
class: 'block @container',
},
template: `
<al-card alGradientCard>
<al-card alGradientCard [hideGradient]="hideGradient()">
<div alCardContent>
<div
class="@3xl:flex-row @3xl:border-none flex w-full flex-col items-center rounded-lg border"
class="flex w-full flex-col items-center rounded-lg border"
[class]="cardWrapper()"
>
<div
class="@3xl:border @3xl:!bg-al-radial-gradient @3xl:bg-al-background @3xl:min-w-[260px] min-w-fit rounded-lg pb-4 pt-6"
class="min-w-fit rounded-lg pt-6 md:min-w-[260px]"
[class]="authorInfoCardClass()"
>
<div
class="@3xl:max-w-[360px] flex w-full flex-col items-center gap-4"
class="flex w-full flex-col items-center gap-4 md:max-w-[360px]"
Expand
Down
>
<ng-content select="[author-info-card]"></ng-content>
</div>
</div>

<div
class="@3xl:pt-6 w-full flex-1 hyphens-auto break-words p-6 pt-0"
>
<div class="w-full flex-1 hyphens-auto break-words p-6 pt-0 md:pt-6">
<ng-content select="[author-info-description]"></ng-content>
</div>
</div>
</div>
</al-card>
`,
})
export class AuthorCardTemplateComponent {}
export class AuthorCardTemplateComponent {
readonly hideGradient = input<boolean>(true);
readonly articleCard = input<boolean>(false);
Comment on lines +41 to +42
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent default values between parent and template components.

The hideGradient input defaults to true here but defaults to false in the parent AuthorCardComponent (line 47 of author-card.component.ts). This mismatch could lead to unexpected behavior when the parent doesn't explicitly pass the value.

Align the defaults to match the parent component:

-  readonly hideGradient = input<boolean>(true);
+  readonly hideGradient = input<boolean>(false);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
readonly hideGradient = input<boolean>(true);
readonly articleCard = input<boolean>(false);
readonly hideGradient = input<boolean>(false);
readonly articleCard = input<boolean>(false);
🤖 Prompt for AI Agents
In
libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts
around lines 41 to 42, the hideGradient input currently defaults to true which
mismatches the parent AuthorCardComponent (author-card.component.ts line 47)
that defaults it to false; change the hideGradient input default to false so
both components share the same default behavior, and verify there are no other
input default mismatches between the template and parent.


protected readonly cardWrapper = computed(() =>
!this.articleCard() ? 'md:flex-row md:border-none' : '',
);

protected readonly authorInfoCardClass = computed(() =>
!this.articleCard()
? 'md:border dark:!bg-al-radial-gradient dark:bg-al-background md:light:bg-[#f2f2f2] pb-6'
: '',
);
Comment on lines +48 to +52
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify Tailwind configuration for light mode variant and avoid !important.

Line 50 contains two potential issues:

  1. The !important flag in dark:!bg-al-radial-gradient might indicate a specificity issue that should be resolved through proper CSS architecture rather than forcing precedence.
  2. The md:light:bg-[#f2f2f2] uses a light: variant that may not be a standard Tailwind feature. Verify this variant is properly configured in your Tailwind setup.

Run the following script to check your Tailwind configuration:

Additionally, search the web to confirm whether light: is a valid Tailwind CSS variant in your version:


🏁 Script executed:

#!/bin/bash
# Description: Check Tailwind configuration for light mode variant

# Search for Tailwind config files
fd -e js -e ts 'tailwind.config'

# Search for light mode variant configuration
rg -nP --type=ts --type=js -C5 'variant.*light|darkMode|class.*strategy' 

# Check if light: is used elsewhere in the codebase
rg -nP --type=ts --type=html 'light:' -g '!node_modules'

Length of output: 1856


🌐 Web query:

Is "light:" a valid Tailwind CSS variant for light mode styling? How should light mode be implemented with Tailwind's dark mode class strategy?

💡 Result:

Short answer: No — Tailwind does not include a built‑in light: variant. Tailwind exposes a dark: variant (and the unprefixed classes act as the “light” / default styles). Configure dark mode with darkMode: 'media' or darkMode: 'class' and toggle by adding/removing a .dark parent (commonly on ). Example:

  • tailwind.config.js

    • darkMode: 'class' // or 'media'. [1]
  • HTML usage (class strategy)

If you want an explicit light: variant, add a custom variant (Tailwind v4 supports @custom-variant) or use a selector like html:not(.dark) with an arbitrary selector utility. Example custom variant pattern shown in community answers:

  • @custom-variant light (html:not(.dark) &); /* then use light:bg-red-500 */. [2]

Sources: Tailwind dark mode docs and community examples. [1][2]

References:
[1] Tailwind CSS — Dark Mode docs.
[2] StackOverflow: “TailwindCSS: How to do a light mode only modification?”


Avoid !important and define or remove light: variant
Remove the ! in dark:!bg-al-radial-gradient and handle specificity via Tailwind utilities or CSS. Since Tailwind has no built-in light: variant, add a custom light variant in your config (e.g., using @custom-variant or html:not(.dark)) or revert to unprefixed classes for light mode.

🤖 Prompt for AI Agents
In
libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts
around lines 48 to 52, remove the `!` (important) from
`dark:!bg-al-radial-gradient` and replace it with a normal
`dark:bg-al-radial-gradient` (or refactor to use a higher-specificity
utility/CSS rule) and either remove the unsupported `light:` prefix from the
light-mode class or add a custom `light` variant in the Tailwind config (e.g.,
define a `light` variant using `html:not(.dark)` or `@custom-variant`) so
light-mode styles are applied correctly; ensure specificity is handled via
Tailwind utilities or custom CSS rather than using `!important`.

}
Loading