Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
04beab8
chore: upgrade tailwindcss to 4.1.18
Bentroen Jan 16, 2026
9d3b891
fix: properly upgrade project to Tailwind CSS v4
Bentroen Jan 16, 2026
29bfcf7
fix: prevent FontAwesome from injecting CSS after load
Bentroen Jan 16, 2026
7a57548
fix: apply Lato font to theme via CSS variable
Bentroen Jan 16, 2026
b521ae6
fix: make buttons use pointer cursor
Bentroen Jan 19, 2026
98fa6ac
chore: delete tailwind.config.js
Bentroen Jan 19, 2026
a8e11d9
chore: remove `autoprefixer` from PostCSS config
Bentroen Jan 19, 2026
f19d1f9
chore: change `postcss.config.js` extension to `.mjs`
Bentroen Jan 19, 2026
9e93de8
refactor: use modern export syntax in PostCSS config
Bentroen Jan 19, 2026
da7f5f6
chore: remove `@shrutibalasa/tailwind-grid-auto-fit` dependency
Bentroen Jan 19, 2026
d2e349f
fix: change font definition from `@layer theme` to `@theme` directive
Bentroen Jan 19, 2026
5dbf95e
fix: re-add `ease-out-back` CSS transition defition
Bentroen Jan 19, 2026
5e47d3d
fix: change icon set from `lucide` to `fontawesome` in @shadcn/ui config
Bentroen Jan 19, 2026
c9c690c
fix: re-add grid auto-fit utility classes
Bentroen Jan 19, 2026
ea0cb6b
fix: mismatched icon size on social login provider icons
Bentroen Jan 19, 2026
3004290
chore: enable suggestions inside strings on VS Code settings
Bentroen Jan 22, 2026
0bbc259
chore: add `globals.css` as config file for Tailwind CSS extension
Bentroen Jan 22, 2026
bff6137
chore: enable Tailwind CSS Intellisense inside utility functions
Bentroen Jan 22, 2026
6a53b7d
fix: add Lato font variable to root html element
Bentroen Jan 22, 2026
1e54464
fix: revert to old slider component in thumbnail editor
Bentroen Jan 22, 2026
673ac51
fix: adjust custom slider element appearance
Bentroen Jan 22, 2026
29a343c
fix: adjust form elements' slider appearance
Bentroen Jan 25, 2026
afbaa79
refactor: replace unused `size` param in `SongCardGroup` with auto-fit
Bentroen Jan 25, 2026
a3308b3
chore: add TODOs related to component standardization
Bentroen Jan 25, 2026
730041f
fix: simplify form label's font size definition
Bentroen Jan 26, 2026
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
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always"
},
// Enable suggestions inside strings for Tailwind CSS class names
// https://github.com/tailwindlabs/tailwindcss-intellisense#editorquicksuggestions
"editor.quickSuggestions": {
"strings": "on"
},
"tailwindCSS.experimental.configFile": {
"apps/frontend/src/app/globals.css": "apps/frontend/src/**"
},
"tailwindCSS.classFunctions": ["tw", "clsx", "cn"],
"files.associations": {
".css": "tailwindcss",
"*.scss": "tailwindcss"
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"rsc": true,
"tsx": true
},
"iconLibrary": "lucide",
"iconLibrary": "fontawesome",
"aliases": {
"components": "@web/modules/shared/components",
"utils": "@web/lib/utils",
Expand Down
5 changes: 2 additions & 3 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,15 @@
"schema-dts": "^1.1.5",
"sharp": "^0.34.5",
"tailwind-merge": "^3.4.0",
"tailwindcss": "4.1.17",
"tailwindcss": "^4.1.18",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.9.3",
"zod": "^4.1.13",
"zod-validation-error": "^5.0.0",
"zustand": "^5.0.9"
},
"devDependencies": {
"@shrutibalasa/tailwind-grid-auto-fit": "^1.1.0",
"@tailwindcss/postcss": "^4.1.17",
"@tailwindcss/postcss": "^4.1.18",
"@types/mdx": "^2.0.13",
"@types/react-modal": "^3.16.3",
"eslint-config-next": "16.0.8",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
const config = {
plugins: {
'@tailwindcss/postcss': {},
autoprefixer: {},
},
};

export default config;
2 changes: 1 addition & 1 deletion apps/frontend/src/app/(content)/(info)/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const metadata: Metadata = {
const AboutPage = () => {
return (
<>
<article className='max-w-screen-md mx-auto mb-36'>
<article className='max-w-(--breakpoint-md) mx-auto mb-36'>
<NoteBlockWorldLogo
size={112}
orientation='horizontal'
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/app/(content)/(info)/blog/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ const BlogPost = async ({ params }: BlogPageProps) => {
<Image
src={post.image}
alt=''
className='w-full h-[30vh] md:h-[50vh] object-cover mb-8 mt-[-2.5rem] rounded-xl'
className='w-full h-[30vh] md:h-[50vh] object-cover mb-8 -mt-10 rounded-xl'
width={1920}
height={1080}
/>
)}
<article className='max-w-screen-md mx-auto mb-36'>
<article className='max-w-(--breakpoint-md) mx-auto mb-36'>
<Link
href='/blog'
className='text-zinc-500 hover:text-zinc-400 text-sm'
Expand Down
6 changes: 3 additions & 3 deletions apps/frontend/src/app/(content)/(info)/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const BlogPageComponent = ({ posts }: { posts: PostType[] }) => {
{"See what we've been working on!"}
</h2>

<section className='grid grid-auto-fit-xl max-w-screen-md mx-auto justify-center w-full items-center gap-8'>
<section className='grid grid-auto-fit-xl max-w-(--breakpoint-md) mx-auto justify-center w-full items-center gap-8'>
{posts.map((post, i) => (
<Link
key={i}
Expand All @@ -46,10 +46,10 @@ const BlogPageComponent = ({ posts }: { posts: PostType[] }) => {
width={480}
height={360}
alt=''
className='rounded-md aspect-[16/9] w-full object-cover transition-all duration-300 mb-2'
className='rounded-md aspect-video w-full object-cover transition-all duration-300 mb-2'
/>

<h3 className='text-lg font-bold text-opacity-50 mb-2 leading-6 flex-grow'>
<h3 className='text-lg font-bold mb-2 leading-6 grow'>
{post.title}
</h3>
<p className='text-zinc-300 tracking-wide text-sm mb-2'>
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/app/(content)/(info)/contact/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const metadata: Metadata = {
const AboutPage = () => {
return (
<>
<article className='max-w-screen-md mx-auto mb-36'>
<article className='max-w-(--breakpoint-md) mx-auto mb-36'>
<BackButton className='text-zinc-500 hover:text-zinc-400 text-sm'>
{'< Back'}
</BackButton>
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/app/(content)/(info)/help/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const HelpPost = async ({ params }: HelpPageProps) => {

return (
<>
<article className='max-w-screen-md mx-auto mb-36'>
<article className='max-w-(--breakpoint-md) mx-auto mb-36'>
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The CSS variable reference syntax uses parentheses: max-w-(--breakpoint-md). In Tailwind CSS v4, CSS variables in utilities should use bracket notation without the var() wrapper when used as arbitrary values: max-w-[--breakpoint-md].

Suggested change
<article className='max-w-(--breakpoint-md) mx-auto mb-36'>
<article className='max-w-[--breakpoint-md] mx-auto mb-36'>

Copilot uses AI. Check for mistakes.
<Link
href='/help'
className='text-zinc-500 hover:text-zinc-400 text-sm'
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/app/(content)/(info)/help/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ const HelpPageComponent = ({ posts }: { posts: PostType[] }) => {
width={480}
height={360}
alt={post.title}
className='rounded-2xl aspect-[3/2] object-cover brightness-150 transition-all duration-300'
className='rounded-2xl aspect-3/2 object-cover brightness-150 transition-all duration-300'
/>

{/* Gradient over the image */}
<div className='absolute top-0 left-0 w-full h-full hover:bg-white/20 transition-all duration-300 bg-gradient-to-b from-transparent to-black/80 rounded-2xl'>
<div className='absolute top-0 left-0 w-full h-full hover:bg-white/20 transition-all duration-300 bg-linear-to-b from-transparent to-black/80 rounded-2xl'>
<h3 className='relative w-full h-full p-3 sm:p-6 flex justify-center items-end text-xl text-opacity-50'>
{post.shortTitle || post.title}
</h3>
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/app/(external)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default async function LoginLayout({
return (
<>
<div
className="fixed z-[-1] w-full h-full bg-center bg-repeat grayscale-[50%] before:content-[''] before:absolute before:w-full before:h-full before:bg-gradient-to-b before:from-black/20 before:to-black/90"
className="fixed z-[-1] w-full h-full bg-center bg-repeat grayscale-50 before:content-[''] before:absolute before:w-full before:h-full before:bg-linear-to-b before:from-black/20 before:to-black/90"
style={{
backgroundImage: "url('/background-tile-flat.png')",
}}
Expand Down
44 changes: 42 additions & 2 deletions apps/frontend/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
@import 'tailwindcss';
/*---break---*/

@plugin "tailwindcss-animate";
/*---break---*/

@custom-variant dark (&:is(.dark *));

@theme {
--font-sans: var(--font-lato);
--ease-out-back: cubic-bezier(0.34, 1.56, 0.51, 1.2);
}

/************** Grid utilities **************/

@utility grid-auto-fit {
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

@utility grid-auto-fit-xs {
grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

@utility grid-auto-fit-sm {
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}

@utility grid-auto-fit-md {
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

@utility grid-auto-fit-lg {
grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

@utility grid-auto-fit-xl {
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
}

/************** Scrollbar **************/

html {
Expand Down Expand Up @@ -302,3 +333,12 @@ ins.adsbygoogle[data-ad-status='unfilled'] {
}
}
*/

/* Make buttons use pointer cursor */
/* See: https://tailwindcss.com/docs/upgrade-guide#buttons-use-the-default-cursor */
@layer base {
button:not(:disabled),
[role='button']:not(:disabled) {
cursor: pointer;
}
}
13 changes: 11 additions & 2 deletions apps/frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { config } from '@fortawesome/fontawesome-svg-core';
import { GoogleAnalytics } from '@next/third-parties/google';
import type { Metadata } from 'next';
import { Lato } from 'next/font/google';
Expand All @@ -14,9 +15,17 @@ import DetectAdBlock from '../modules/shared/components/client/ads/DetectAdBlock
import GoogleAdSense from '../modules/shared/components/GoogleAdSense';
import { TooltipProvider } from '../modules/shared/components/tooltip';

// Pre-import FontAwesome CSS to avoid FOUC
// See: https://fontawesome.com/docs/web/use-with/react/use-with#nextjs
import '@fortawesome/fontawesome-svg-core/styles.css';

// Prevent FontAwesome from injecting CSS after initial render
config.autoAddCss = false;

const lato = Lato({
subsets: ['latin'],
weight: ['100', '300', '400', '700', '900'],
variable: '--font-lato',
});

export const metadata: Metadata = {
Expand Down Expand Up @@ -50,7 +59,7 @@ export default function RootLayout({
}) {
return (
<ReCaptchaProvider useEnterprise>
<html lang='en'>
<html lang='en' className={lato.variable}>
<head>
<GoogleAdSense pId={process.env.NEXT_PUBLIC_ADSENSE_CLIENT} />
{/* https://nextjs.org/docs/app/building-your-application/optimizing/metadata#json-ld */}
Expand Down Expand Up @@ -102,7 +111,7 @@ export default function RootLayout({
<Toaster
position='bottom-center'
toastOptions={{
className: '!bg-zinc-700 !text-white !max-w-fit',
className: 'bg-zinc-700! text-white! max-w-fit!',
duration: 4000,
}}
/>
Expand Down
6 changes: 3 additions & 3 deletions apps/frontend/src/app/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ export default function NotFound() {
return (
<>
<div
className="fixed w-full h-full bg-center bg-repeat grayscale brightness-50 opacity-30 before:content-[''] before:absolute before:w-full before:h-full before:bg-gradient-to-b before:from-black/20 before:to-black/80"
className="fixed w-full h-full bg-center bg-repeat grayscale brightness-50 opacity-30 before:content-[''] before:absolute before:w-full before:h-full before:bg-linear-to-b before:from-black/20 before:to-black/80"
style={{
backgroundImage: "url('/background-tile-flat.png')",
}}
></div>

<main className='w-full h-screen text-center [&>*]:z-[2] p-2 bg-zinc-900 flex flex-col items-center justify-center gap-8'>
<main className='w-full h-screen text-center *:z-2 p-2 bg-zinc-900 flex flex-col items-center justify-center gap-8'>
{/* Background image */}

<p className='font-light text-zinc-400 text-5xl'>Oops...</p>
Expand All @@ -57,7 +57,7 @@ export default function NotFound() {
width={400}
height={400}
quality={95}
className='object-contain relative md:left-8 top-8 w-64 md:w-full z-[2]'
className='object-contain relative md:left-8 top-8 w-64 md:w-full z-2'
/>
<h1 className='leading-none font-black text-[10rem] md:text-[18rem] z-1 text-zinc-600/30 relative bottom-8 md:right-12 md:bottom-16'>
404
Expand Down
7 changes: 5 additions & 2 deletions apps/frontend/src/modules/auth/components/loginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ export const LoginPage = () => {
<NoteBlockWorldLogo glow={true} orientation='adaptive' size={128} />

{/* Vertical divider (mobile) */}
<div className='w-[1px] min-h-full hidden sm:block bg-zinc-600'></div>
<div className='w-px min-h-full hidden sm:block bg-zinc-600'></div>
{/* Horizontal divider (desktop) */}
<div className='h-[1px] min-w-full block sm:hidden bg-zinc-600'></div>
<div className='h-px min-w-full block sm:hidden bg-zinc-600'></div>

{/* Right half */}
<div className='flex flex-col justify-center items-center gap-5'>
Expand Down Expand Up @@ -87,6 +87,7 @@ export const LoginPage = () => {
<FontAwesomeIcon
icon={faGoogle}
className='align-middle mr-2 h-5'
size='lg'
/>
<span className='flex-1 text-nowrap'>Log in with Google</span>
</Link>
Expand All @@ -99,6 +100,7 @@ export const LoginPage = () => {
<FontAwesomeIcon
icon={faGithub}
className='align-middle mr-2 h-5'
size='lg'
/>
<span className='flex-1'>Log in with GitHub</span>
</Link>
Expand All @@ -111,6 +113,7 @@ export const LoginPage = () => {
<FontAwesomeIcon
icon={faDiscord}
className='align-middle mr-2 h-5'
size='lg'
/>
<span className='flex-1 text-nowrap'>Log in with Discord</span>
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export const LoginWithEmailPage = () => {
<NoteBlockWorldLogo glow={true} orientation='adaptive' size={128} />

{/* Vertical divider (mobile) */}
<div className='w-[1px] min-h-full hidden sm:block bg-zinc-600'></div>
<div className='w-px min-h-full hidden sm:block bg-zinc-600'></div>
{/* Horizontal divider (desktop) */}
<div className='h-[1px] min-w-full block sm:hidden bg-zinc-600'></div>
<div className='h-px min-w-full block sm:hidden bg-zinc-600'></div>

{/* Right half */}
<div className='flex flex-col justify-center items-center gap-5'>
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/modules/browse/EventBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const EventBanner = () => {
};

return (
<div className='flex flex-row mx-auto w-fit justify-between items-center text-pretty gap-6 py-4 px-2 sm:px-8 text-md rounded-xl mb-10 bg-top backdrop-filter backdrop-blur-lg bg-opacity-50 bg-gradient-to-br from-15% from-pink-800 via-rose-900 to-85% to-red-900 relative'>
<div className='flex flex-row mx-auto w-fit justify-between items-center text-pretty gap-6 py-4 px-2 sm:px-8 text-md rounded-xl mb-10 bg-top backdrop-filter backdrop-blur-lg bg-linear-to-br from-15% from-pink-800/50 via-rose-900/50 to-85% to-red-900/50 relative'>
<div
className='absolute h-full w-full top-0 left-0 z-[-1] rounded-xl opacity-50 brightness-[0.3]'
style={{
Expand All @@ -43,7 +43,7 @@ export const EventBanner = () => {
></div>
<Image src='/img/event/maestro-icon.png' alt='' width={64} height={64} />

<div className='flex-1 leading-tight max-w-screen-md w-fit'>
<div className='flex-1 leading-tight max-w-(--breakpoint-md) w-fit'>
<p className='uppercase text-md font-bold tracking-wider text-yellow-300 mb-1 w-fit'>
<FontAwesomeIcon icon={faExclamationCircle} />{' '}
{timeLeft === 0 ? (
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/modules/browse/WelcomeBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Link from 'next/link';

export const WelcomeBanner = () => {
return (
<div className='flex flex-col md:flex-row mx-auto w-fit justify-between items-center text-center text-balance gap-1 py-4 px-2 sm:px-8 text-sm rounded-xl mb-10 bg-top backdrop-filter backdrop-blur-lg bg-opacity-50 bg-gradient-to-br from-15% from-green-700 via-cyan-800 to-85% to-blue-900 border-2 border-white/20'>
<div className='flex flex-col md:flex-row mx-auto w-fit justify-between items-center text-center text-balance gap-1 py-4 px-2 sm:px-8 text-sm rounded-xl mb-10 bg-top backdrop-filter backdrop-blur-lg bg-linear-to-br from-15% from-green-700/50 via-cyan-800/50 to-85% to-blue-900/50 border-2 border-white/20'>
<div
className='absolute h-full w-full top-0 left-0 z-[-1] rounded-xl opacity-20 brightness-50 hue-rotate-90'
style={{
Expand All @@ -19,7 +19,7 @@ export const WelcomeBanner = () => {
width={100}
height={100}
/>
<div className='flex-1 leading-tight max-w-screen-md'>
<div className='flex-1 leading-tight max-w-(--breakpoint-md)'>
<h1 className='text-lg font-bold mb-1 text-green-400'>
Welcome to <strong className='text-teal-300'>Note Block World</strong>
!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const HomePageComponent = () => {

{/* RECENT SONGS */}
<div className='flex flex-row flex-wrap justify-between items-center gap-4 mb-2'>
<h2 className='text-xl uppercase z-[2]'>Recent songs</h2>
<h2 className='text-xl uppercase z-2'>Recent songs</h2>
<CategoryButtonGroup />
</div>
<div className='h-6' />
Expand Down
8 changes: 4 additions & 4 deletions apps/frontend/src/modules/browse/components/SongCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const SongDataDisplay = ({ song }: { song: SongPreviewDtoType | null }) => {
<div className='relative'>
{!song ? (
<Skeleton
className='w-full h-full rounded-lg aspect-[5/3] object-cover'
className='w-full h-full rounded-lg aspect-5/3 object-cover'
containerClassName='block leading-none'
/>
) : (
Expand All @@ -33,9 +33,9 @@ const SongDataDisplay = ({ song }: { song: SongPreviewDtoType | null }) => {
</div>

{/* Song info */}
<div className='flex flex-row justify-between px-4 pt-0.5 text-pretty flex-grow'>
<div className='flex flex-row justify-between px-4 pt-0.5 text-pretty grow'>
{/* Song title */}
<h3 className='text-md font-semibold leading-tight w-full h-10 flex-grow line-clamp-2'>
<h3 className='text-md font-semibold leading-tight w-full h-10 grow line-clamp-2'>
{song?.title || <Skeleton count={2} />}
</h3>
</div>
Expand All @@ -51,7 +51,7 @@ const SongDataDisplay = ({ song }: { song: SongPreviewDtoType | null }) => {
)}
</p>
{/* Play icon & count */}
<div className='text-md flex items-center gap-1 flex-shrink'>
<div className='text-md flex items-center gap-1 shrink'>
{!song ? (
<Skeleton className='min-w-16' />
) : (
Expand Down
Loading
Loading