
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
Complete source code available till this point of lesson is available at
Put this application theme in app/globals.css file.
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@custom-variant dark (&:is(.dark *));
@theme {
--color-primary-100: #fff1e6;
--color-primary-500: #ff7000;
--color-dark-100: #000000;
--color-dark-200: #0f1117;
--color-dark-300: #151821;
--color-dark-400: #212734;
--color-dark-500: #101012;
--color-light-400: #858ead;
--color-light-500: #7b8ec8;
--color-light-700: #dce3f1;
--color-light-800: #f4f6f8;
--color-light-850: #fdfdfd;
--color-light-900: #ffffff;
--color-link-100: #1da1f2;
--radius-2: 8px;
--radius-1_5: 6px;
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
--shadow-light-100:
0px 12px 20px 0px rgba(184, 184, 184, 0.03),
0px 6px 12px 0px rgba(184, 184, 184, 0.02),
0px 2px 4px 0px rgba(184, 184, 184, 0.03);
--shadow-light-200: 10px 10px 20px 0px rgba(218, 213, 213, 0.1);
--shadow-light-300: -10px 10px 20px 0px rgba(218, 213, 213, 0.1);
--shadow-dark-100: 0px 2px 10px 0px rgba(46, 52, 56, 0.1);
--shadow-dark-200: 2px 0px 20px 0px rgba(39, 36, 36, 0.04);
--background-image-auth-dark: url("/images/auth-dark.png");
--background-image-auth-light: url("/images/auth-light.png");
--breakpoint-xs: 420px;
--font-inter: var(--font-inter);
--font-space-grotesk: var(--font-space-grotesk);
}
/*
The default border color has changed to `currentcolor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}
@utility background-light850_dark100 {
@apply bg-light-850 dark:bg-dark-100;
}
@utility background-light900_dark200 {
@apply bg-light-900 dark:bg-dark-200;
}
@utility background-light900_dark300 {
@apply bg-light-900 dark:bg-dark-300;
}
@utility background-light800_darkgradient {
@apply bg-light-800 dark:dark-gradient;
}
@utility background-light800_dark400 {
@apply bg-light-800! dark:bg-dark-400!;
@apply bg-light-800 dark:bg-dark-400;
}
@utility background-light700_dark400 {
@apply bg-light-700 dark:bg-dark-400;
}
@utility background-light700_dark300 {
@apply bg-light-700 dark:bg-dark-300;
}
@utility background-light800_dark300 {
@apply bg-light-800! dark:bg-dark-300!;
}
@utility background-light800_dark200 {
@apply bg-light-800 dark:bg-dark-200;
}
@utility background-dark400_light900 {
@apply dark:bg-dark-400! bg-light-900!;
}
@utility text-dark100_light900 {
@apply text-dark-100! dark:text-light-900!;
}
@utility text-dark200_light900 {
@apply text-dark-200 dark:text-light-900;
}
@utility text-dark200_light800 {
@apply text-dark-200! dark:text-light-800!;
}
@utility text-dark300_light700 {
@apply text-dark-300 dark:text-light-700;
}
@utility text-dark400_light700 {
@apply text-dark-400 dark:text-light-700;
}
@utility text-dark500_light700 {
@apply text-dark-500! dark:text-light-700!;
}
@utility text-dark500_light500 {
@apply text-dark-500 dark:text-light-500;
}
@utility text-dark500_light400 {
@apply text-dark-500 dark:text-light-400;
}
@utility text-dark300_light900 {
@apply text-dark-300! dark:text-light-900!;
}
@utility text-dark400_light800 {
@apply text-dark-400 dark:text-light-800;
}
@utility text-light400_light500 {
@apply text-light-400! dark:text-light-500!;
@apply text-light-400! dark:text-light-500!;
}
@utility text-dark400_light500 {
@apply text-dark-400 dark:text-light-500;
}
@utility text-dark400_light900 {
@apply text-dark-400! dark:text-light-900!;
}
@utility light-border {
@apply border-light-800 dark:border-dark-300;
}
@utility light-border-2 {
@apply border-light-700! dark:border-dark-400!;
}
@utility h1-bold {
@apply text-[30px] font-bold leading-[42px] tracking-tighter;
}
@utility h2-bold {
@apply text-[24px] font-bold leading-[31.2px];
}
@utility h2-semibold {
@apply text-[24px] font-semibold leading-[31.2px];
}
@utility h3-bold {
@apply text-[20px] font-bold leading-[26px];
}
@utility h3-semibold {
@apply text-[20px] font-semibold leading-[24.8px];
}
@utility base-medium {
@apply text-[18px] font-medium leading-[25.2px];
}
@utility base-semibold {
@apply text-[18px] font-semibold leading-[25.2px];
}
@utility base-bold {
@apply text-[18px] font-bold leading-[140%];
}
@utility paragraph-regular {
@apply text-[16px] font-normal leading-[22.4px];
}
@utility paragraph-medium {
@apply text-[16px] font-medium leading-[22.4px];
}
@utility paragraph-semibold {
@apply text-[16px] font-semibold leading-[20.8px];
}
@utility body-regular {
@apply text-[14px] font-normal leading-[19.6px];
}
@utility body-medium {
@apply text-[14px] font-medium leading-[18.2px];
}
@utility body-semibold {
@apply text-[14px] font-semibold leading-[18.2px];
}
@utility body-bold {
@apply text-[14px] font-bold leading-[18.2px];
}
@utility small-regular {
@apply text-[12px] font-normal leading-[15.6px];
}
@utility small-medium {
@apply text-[12px] font-medium leading-[15.6px];
}
@utility small-semibold {
@apply text-[12px] font-semibold leading-[15.6px];
}
@utility subtle-medium {
@apply text-[10px]! font-medium! leading-[13px]!;
}
@utility subtle-regular {
@apply text-[10px] font-normal leading-[13px];
}
@utility placeholder {
@apply placeholder:text-light-400 dark:placeholder:text-light-500;
}
@utility invert-colors {
@apply invert dark:invert-0;
}
@utility shadow-light100_dark100 {
@apply shadow-light-100 dark:shadow-dark-100;
}
@utility shadow-light100_darknone {
@apply shadow-light-100 dark:shadow-none;
}
@utility primary-gradient {
background: linear-gradient(129deg, #ff7000 0%, #e2995f 100%);
}
@utility dark-gradient {
background: linear-gradient(
232deg,
rgba(23, 28, 35, 0.41) 0%,
rgba(19, 22, 28, 0.7) 100%
);
background: linear-gradient(
232deg,
rgba(23, 28, 35, 0.41) 0%,
rgba(19, 22, 28, 0.7) 100%
);
}
@utility light-gradient {
background: linear-gradient(
132deg,
rgba(247, 249, 255, 0.5) 0%,
rgba(229, 237, 255, 0.25) 100%
);
}
@utility primary-text-gradient {
background: linear-gradient(129deg, #ff7000 0%, #e2995f 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
@utility flex-center {
@apply flex justify-center items-center;
}
@utility flex-between {
@apply flex justify-between items-center;
}
@utility flex-start {
@apply flex justify-start items-center;
}
@utility card-wrapper {
@apply bg-light-900 dark:dark-gradient shadow-light-100 dark:shadow-dark-100;
}
@utility btn {
@apply bg-light-800! dark:bg-dark-300!;
}
@utility btn-secondary {
@apply bg-light-800! dark:bg-dark-400!;
}
@utility btn-tertiary {
@apply bg-light-700! dark:bg-dark-300!;
}
@utility no-focus {
@apply focus-visible:ring-0! focus-visible:ring-transparent! focus-visible:ring-offset-0!;
}
@utility markdown {
@apply !max-w-full prose prose-p:my-2 prose-ol:my-0 prose-ul:my-0 dark:prose-p:text-light-700 dark:prose-ol:text-light-700 dark:prose-ul:text-light-500 dark:prose-strong:text-white dark:prose-headings:text-white prose-headings:text-dark-400 prose-h1:text-dark-300 prose-h2:text-dark-300 prose-p:text-dark-500 prose-ul:text-dark-500 prose-ol:text-dark-500;
}
@utility markdown-editor {
@apply prose !max-w-full prose-p:m-0 dark:prose-headings:text-white prose-headings:text-dark-400 prose-p:text-dark-500 dark:prose-p:text-light-700 prose-ul:text-dark-500 dark:prose-ul:text-light-700 prose-ol:text-dark-500 dark:prose-ol:text-light-700 dark:prose-strong:text-white prose-blockquote:text-dark-500 dark:prose-blockquote:text-light-700;
}
@utility tab {
@apply min-h-full! dark:bg-dark-400! bg-light-800! text-light-500! dark:data-[state=active]:bg-dark-300! data-[state=active]:bg-primary-100! data-[state=active]:text-primary-500!;
}
@layer base {
:root {
--radius: 0.5rem;
}
}
.custom-scrollbar::-webkit-scrollbar {
width: 3px;
height: 3px;
border-radius: 2px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: #ffffff;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #888;
border-radius: 50px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.active-theme {
filter: invert(53%) sepia(98%) saturate(3332%) hue-rotate(0deg)
brightness(104%) contrast(106%) !important;
}
.hash-span {
margin-top: -140px;
padding-bottom: 140px;
display: block;
}
.mdxeditor-toolbar {
background: #ffffff !important;
}
.dark .mdxeditor-toolbar {
background: #151821 !important;
}
.dark .mdxeditor-toolbar button svg {
color: #858ead !important;
}
.dark .mdxeditor-toolbar button:hover svg {
color: #000 !important;
}
.dark .mdxeditor-toolbar [role="separator"] {
border-color: #555 !important;
}
.markdown a {
color: #1da1f2;
}
.markdown a,
code {
/* These are technically the same, but use both */
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
/* This is the dangerous one in WebKit, as it breaks things wherever */
word-break: break-all;
/* Instead use this non-standard one: */
word-break: break-word;
/* Adds a hyphen where the word breaks, if supported (No Blink) */
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
padding: 2px;
color: #ff7000 !important;
}
.markdown pre {
display: grid;
width: 100%;
}
.markdown pre code {
width: 100%;
display: block;
overflow-x: auto;
color: inherit !important;
}
[data-lexical-editor="true"] {
height: 350px !important;
overflow-y: auto !important;
}
/* NESTED CODE BLOCKS: Only apply grid to visible code blocks */
[data-bright-mode="dark"]:not(html.light [data-bright-mode="dark"]),
[data-bright-mode="light"]:not(:not(html.light [data-bright-mode="light"])) {
display: grid !important;
width: 100% !important;
}
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:00 In the previous lesson, we have set up our Tailwind CSS theme, but sometimes having just the theme itself isn't enough, because you might want to have
00:00:08 some parts of the code where the styling is crazy detailed, like this div right here that says Tailwind CSS is fun.
00:00:15 Sure, we have a nice looking centered rectangle card, but this code is a bit of a mess.
00:00:21 And in such cases, to avoid that mess and to keep the code clean, you can either use CSS directives in a CSS file or use the Tailwind layer directive,
00:00:31 which allows you to add base styles to your application by defining how specific elements should look like by default so that you don't have to add everything
00:00:41 to your JSX.
00:00:42 For example, we had a card here, right?
00:00:45 Would be cool that that card was already defined within the CSS file so that whenever we use it, we can just say card.
00:00:52 Pretty cool, right?
00:00:53 There are three main directives.
00:00:56 The first one is atLayerBase, allowing you to define foundational styles like resets for different elements.
00:01:05 Maybe you want to set the margin or padding of a body to zero.
00:01:10 or change the default color of an anchor tag.
00:01:14 Whatever you want to do, most likely changing the headings to immediately be a bit larger and bolded, you can do that here.
00:01:21 And then every single heading across your entire application will have these styles applied to it.
00:01:27 So now if I head back over here, remove this full class and just turn this into an H1 that says, welcome to Next.js, you'll see automatically that it'll
00:01:38 be a bit larger and bolded.
00:01:40 because that's coming directly from this layer.
00:01:42 There's also the atLayer components, which is perfect for defining how specific components like buttons or cards should look like.
00:01:52 Remember this crazy card I created right here?
00:01:55 Well, we can take that class name, remove it from here, and add it as a component by saying .card apply.
00:02:04 And then we can apply all of those class names that we before had in our JSX, or in this case, it's a TSX file.
00:02:12 And now you can just say card right here.
00:02:14 So if you head back to the browser, same output.
00:02:17 but a significantly easier to understand page.tsx file.
00:02:21 And finally, there's the add layer utility, which allows you to define some utility classes like background colors and more,
00:02:30 which you can reuse across all different files and components like margins, paddings, or background colors.
00:02:37 We'll do the same thing in our application by turning the most commonly used styles into custom styles with the help of layer directives.
00:02:44 One of the most common styles that we want to reuse are typography styles.
00:02:50 You can see here that we have a very bold H1.
00:02:53 So if you want to figure out how it works, you can click on it, and then on the right side, you can see that it has a color of 100, it is an H1 bold color,
00:03:04 and it has some different properties attached to it as well.
00:03:08 And then as we go further, you can see the different headings have different properties.
00:03:13 Okay, so how can we do it for all of our heading styles?
00:03:16 Well, I'll delete these layer components and utilities, and we'll focus on layers base because this is where we have our headings.
00:03:23 Instead of just applying text to Excel and font bold, I'll actually beef it up a bit by saying text 30 pixels, font bold,
00:03:32 leading 42 pixels, and the tracking tighter.
00:03:36 Which are some properties that I could have extracted right here from Figma by reading out all the properties about this specific text element.
00:03:44 The leading is available right here.
00:03:46 I think it's 42 and tracking is packed, I think right here, considering that it has a lower letter spacing of minus one pixels.
00:03:53 So it's a bit tighter, right?
00:03:55 Now, you can go ahead and copy these tiles for all of the other headings, but again, to speed things up because this is a lot of repetitive code,
00:04:02 I'll just provide it for you below this lesson.
00:04:05 You can put these as an extension of the Tailwind base utility, or you can also provide them as class names.
00:04:12 So in this case a new utility class because for some you can notice that it's not going to be just one element.
00:04:18 You might have two specific elements for each one of the headings so it's better to have it as a class name rather as an automatic style applied to the H2.
00:04:28 So now if I head back over here If I wanted to get those styles, I'll create an H1 element, put the Tailwind CSS right within it,
00:04:38 at least this text, and then I can give this H1 a class name and just say H1 Bolt.
00:04:45 And you can see how Prettier and ESLint automatically position this for me.
00:04:49 And I'll remove the card because we no longer have that code.
00:04:52 So if I head back, you can see that now it follows the same exact styling that we have right here within our Figma.
00:04:59 Now within this application, there are also many background-related utility classes that we could add.
00:05:05 You can see, for example, that this filter or this tag have some kind of a background.
00:05:11 Same thing for some of the other elements like this sidebar.
00:05:15 So if you show the styles for it, you'll notice that this sidebar is actually a set of different colors.
00:05:21 It has light 100 for the text.
00:05:24 It has a dark 400 as the background and some other gradients as well.
00:05:29 So how would we turn this into a utility class?
00:05:32 Well, it would look something like this.
00:05:34 You could go to the bottom and say Utility, Background, Light 850, Dark 100, and then apply a light background and dark text.
00:05:45 or it could be some other variations of those colors.
00:05:48 But you'll see me use this background light something and then dark something else a lot, because this will allow us to automatically make our application
00:05:56 both light and dark mode capable.
00:05:58 Once again, if you want to check out how to do these things in depth on your own, there's going to be a video somewhere below this lesson that you can
00:06:04 check out.
00:06:05 But I will also leave the entire globals.css so you can just copy and paste it here.
00:06:10 And this will contain a lot of different utility classes that are going to make the styling of our application that much more seamless.
00:06:17 Typically, it will be a pain in the ass to write all of this within JSX, but with new Tailwind, it's much easier.
00:06:24 Oh, and I'm also using a package here for Tailwind CSS dipography.
00:06:28 So to make our code work with it, we need to install it by running npm install dash d.
00:06:34 at tailwind-css forward slash typography.
00:06:38 And of course, don't forget the dash dash legacy dash p or dash depths.
00:06:42 Whenever this happens, don't be scared.
00:06:44 Again, it's just due to the mismatched versions of eslint and other packages in our Next.js application.
00:06:50 So with that in mind, we have successfully not only set up Tailwind, but dove a bit deeper into theming our applications with it.
00:06:57 Great job.