From 5ec8ba82ccdbc918ec0de6d57b15b46240d888cc Mon Sep 17 00:00:00 2001 From: Somrat <58769763+tfsomrat@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:25:40 +0600 Subject: [PATCH] added tailwind v4, remove sass dependency --- astro.config.mjs | 27 +--- package.json | 10 +- postcss.config.js | 6 - src/config/theme.json | 17 +-- src/layouts/Base.astro | 2 +- src/styles/{base.scss => base.css} | 4 +- src/styles/{buttons.scss => buttons.css} | 0 src/styles/components.css | 170 ++++++++++++++++++++++ src/styles/components.scss | 176 ----------------------- src/styles/main.css | 24 ++++ src/styles/main.scss | 19 --- src/styles/navigation.css | 70 +++++++++ src/styles/navigation.scss | 79 ---------- src/styles/safe.css | 10 ++ src/styles/search.css | 97 +++++++++++++ src/styles/search.scss | 96 ------------- src/styles/utilities.css | 29 ++++ src/styles/utilities.scss | 20 --- src/tailwind-plugin/tw-bs-grid.js | 103 +++++++++++++ src/tailwind-plugin/tw-theme.js | 94 ++++++++++++ tailwind.config.js | 94 ------------ 21 files changed, 612 insertions(+), 535 deletions(-) delete mode 100755 postcss.config.js rename src/styles/{base.scss => base.css} (77%) rename src/styles/{buttons.scss => buttons.css} (100%) create mode 100755 src/styles/components.css delete mode 100755 src/styles/components.scss create mode 100755 src/styles/main.css delete mode 100755 src/styles/main.scss create mode 100755 src/styles/navigation.css delete mode 100755 src/styles/navigation.scss create mode 100644 src/styles/safe.css create mode 100644 src/styles/search.css delete mode 100644 src/styles/search.scss create mode 100755 src/styles/utilities.css delete mode 100755 src/styles/utilities.scss create mode 100644 src/tailwind-plugin/tw-bs-grid.js create mode 100644 src/tailwind-plugin/tw-theme.js delete mode 100755 tailwind.config.js diff --git a/astro.config.mjs b/astro.config.mjs index dbb8620..4b296e8 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,28 +1,24 @@ import mdx from "@astrojs/mdx"; import react from "@astrojs/react"; import sitemap from "@astrojs/sitemap"; -import tailwind from "@astrojs/tailwind"; +import tailwindcss from "@tailwindcss/vite"; import AutoImport from "astro-auto-import"; import { defineConfig } from "astro/config"; import remarkCollapse from "remark-collapse"; import remarkToc from "remark-toc"; -import config from "./src/config/config.json"; import sharp from "sharp"; +import config from "./src/config/config.json"; // https://astro.build/config export default defineConfig({ site: config.site.base_url ? config.site.base_url : "http://examplesite.com", base: config.site.base_path ? config.site.base_path : "/", trailingSlash: config.site.trailing_slash ? "always" : "never", - image: { - service: sharp(), - }, + image: { service: sharp() }, + vite: { plugins: [tailwindcss()] }, integrations: [ react(), sitemap(), - tailwind({ - applyBaseStyles: false, - }), AutoImport({ imports: [ "@/shortcodes/Button", @@ -37,19 +33,8 @@ export default defineConfig({ mdx(), ], markdown: { - remarkPlugins: [ - remarkToc, - [ - remarkCollapse, - { - test: "Table of contents", - }, - ], - ], - shikiConfig: { - theme: "one-dark-pro", - wrap: true, - }, + remarkPlugins: [remarkToc, [remarkCollapse, { test: "Table of contents" }]], + shikiConfig: { theme: "one-dark-pro", wrap: true }, extendDefaultPlugins: true, }, }); diff --git a/package.json b/package.json index 6715bdd..3091594 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "astroplate", - "version": "5.0.0", + "version": "5.1.0", "description": "Astro and Tailwindcss boilerplate", "author": "zeon.studio", "license": "MIT", @@ -20,7 +20,6 @@ "@astrojs/react": "4.1.2", "@astrojs/rss": "4.0.11", "@astrojs/sitemap": "3.2.1", - "@astrojs/tailwind": "5.1.4", "astro": "5.1.2", "astro-auto-import": "^0.4.4", "astro-font": "^0.1.81", @@ -29,8 +28,6 @@ "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", "marked": "^15.0.5", - "prettier-plugin-astro": "^0.14.1", - "prettier-plugin-tailwindcss": "^0.6.9", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -43,11 +40,11 @@ "devDependencies": { "@tailwindcss/forms": "^0.5.9", "@tailwindcss/typography": "^0.5.15", + "@tailwindcss/vite": "^4.0.6", "@types/marked": "^5.0.2", "@types/node": "22.10.5", "@types/react": "19.0.2", "@types/react-dom": "19.0.2", - "autoprefixer": "^10.4.20", "eslint": "^9.17.0", "postcss": "^8.4.49", "prettier": "^3.4.2", @@ -55,8 +52,7 @@ "prettier-plugin-tailwindcss": "^0.6.9", "sass": "^1.83.1", "sharp": "0.33.5", - "tailwind-bootstrap-grid": "^5.1.0", - "tailwindcss": "^3.4.17", + "tailwindcss": "^4.0.6", "typescript": "^5.7.2" } } diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100755 index 12a703d..0000000 --- a/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/src/config/theme.json b/src/config/theme.json index a17716f..0352ca2 100755 --- a/src/config/theme.json +++ b/src/config/theme.json @@ -8,11 +8,7 @@ "theme_light": "#f6f6f6", "theme_dark": "" }, - "text_color": { - "default": "#444444", - "dark": "#040404", - "light": "#717171" - } + "text_color": { "text": "#444444", "dark": "#040404", "light": "#717171" } }, "darkmode": { "theme_color": { @@ -22,11 +18,7 @@ "theme_light": "#222222", "theme_dark": "" }, - "text_color": { - "default": "#B4AFB6", - "dark": "#fff", - "light": "#B4AFB6" - } + "text_color": { "text": "#B4AFB6", "dark": "#fff", "light": "#B4AFB6" } } }, "fonts": { @@ -36,9 +28,6 @@ "secondary": "Signika:wght@500;700", "secondary_type": "sans-serif" }, - "font_size": { - "base": "16", - "scale": "1.2" - } + "font_size": { "base": "16", "scale": "1.2" } } } diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index 3e80aee..cc7ac47 100755 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -5,7 +5,7 @@ import theme from "@/config/theme.json"; import { plainify } from "@/lib/utils/textConverter"; import Footer from "@/partials/Footer.astro"; import Header from "@/partials/Header.astro"; -import "@/styles/main.scss"; +import "@/styles/main.css"; import { AstroFont } from "astro-font"; import { ClientRouter } from "astro:transitions"; import SearchModal from "./helpers/SearchModal"; diff --git a/src/styles/base.scss b/src/styles/base.css similarity index 77% rename from src/styles/base.scss rename to src/styles/base.css index b568330..3d96dca 100755 --- a/src/styles/base.scss +++ b/src/styles/base.css @@ -3,7 +3,7 @@ html { } body { - @apply bg-body dark:bg-darkmode-body font-primary font-normal leading-relaxed text-text dark:text-darkmode-text; + @apply bg-body text-base dark:bg-darkmode-body font-primary font-normal leading-relaxed text-text dark:text-darkmode-text; } h1, @@ -55,5 +55,5 @@ code { } blockquote > p { - @apply my-0 #{!important}; + @apply my-0!; } diff --git a/src/styles/buttons.scss b/src/styles/buttons.css similarity index 100% rename from src/styles/buttons.scss rename to src/styles/buttons.css diff --git a/src/styles/components.css b/src/styles/components.css new file mode 100755 index 0000000..4067bc7 --- /dev/null +++ b/src/styles/components.css @@ -0,0 +1,170 @@ +/* section style */ +.section { + @apply py-24 xl:py-28; +} + +.section-sm { + @apply py-16 xl:py-20; +} + +/* container */ +.container { + @apply mx-auto xl:!max-w-[1320px] px-4; +} + +/* social icons */ +.social-icons { + @apply space-x-4; +} +.social-icons li { + @apply inline-block; +} +.social-icons li a { + @apply flex h-9 w-9 items-center justify-center rounded-sm bg-primary text-center leading-9 text-white dark:bg-darkmode-primary dark:text-dark; +} +.social-icons li a svg { + @apply h-5 w-5; +} + +/* notice */ +.notice { + @apply mb-6 rounded-lg border px-8 py-6; +} + +.notice-head { + @apply flex items-center; +} + +.notice-head svg { + @apply mr-3; +} + +.notice-head p { + @apply font-secondary text-xl font-semibold text-dark dark:text-darkmode-light; +} + +.notice-body { + @apply mt-3; +} + +.notice-body p { + @apply my-0; +} + +.notice.note { + @apply text-[#1B83E2]; + @apply border-current; +} + +.notice.tip { + @apply text-[#40D294]; + @apply border-current; +} + +.notice.info { + @apply text-[#E3A72C]; + @apply border-current; +} + +.notice.warning { + @apply text-[#DB2C23]; + @apply border-current; +} + +/* tab */ +.tab { + @apply overflow-hidden rounded-lg border border-border dark:border-darkmode-border; +} + +.tab-nav { + @apply flex border-b border-border bg-theme-light dark:border-darkmode-border dark:bg-darkmode-theme-light !m-0 !list-none; +} + +.tab-nav-item { + @apply cursor-pointer border-b-[3px] border-border py-2 text-lg text-dark opacity-80 dark:border-light !my-0 !px-8; +} + +.tab-nav-item.active { + @apply border-b-[3px] border-dark opacity-100 dark:border-darkmode-primary; +} + +.tab-content { + @apply px-5; +} + +.tab-content-panel { + @apply p-8; +} + +.tab-content-panel p { + @apply mb-0; +} + +.tab-content-panel.active { + @apply block; +} + +/* accordion */ +.accordion { + @apply mb-6 overflow-hidden rounded-lg border border-border bg-theme-light dark:border-darkmode-border dark:bg-darkmode-theme-light; +} + +.accordion-header { + @apply flex w-full cursor-pointer items-center justify-between px-8 py-4 text-lg text-dark dark:bg-darkmode-theme-light dark:text-darkmode-light; +} + +.accordion-icon { + @apply h-[.8em] w-[.8em] rotate-[-90deg] transition-transform duration-200; +} + +.accordion-content { + @apply max-h-0 overflow-hidden px-8 py-0; +} + +.accordion.active .accordion-icon { + @apply rotate-0; +} + +.accordion.active .accordion-content { + @apply max-h-screen; +} + +/* modal */ +.modal { + @apply fixed inset-0 z-40 hidden h-full w-full overflow-auto; +} + +.modal-overlay { + @apply fixed inset-0 z-40 hidden h-full w-full bg-black/40; +} + +.modal-content { + @apply relative top-1/2 z-50 mx-auto max-w-[90%] -translate-y-1/2 rounded-lg bg-body p-8 dark:bg-darkmode-body; +} + +.modal-close { + @apply absolute right-3 top-3 h-8 w-8 rounded-full bg-theme-light text-center leading-8 text-dark dark:bg-darkmode-theme-light dark:text-darkmode-dark; +} + +/* content style */ +.content { + @apply prose max-w-none; + @apply prose-headings:mb-[.3em] prose-headings:mt-[.6em] prose-headings:text-dark dark:prose-headings:text-darkmode-dark; + @apply prose-h1:text-h1-sm md:prose-h1:text-h1; + @apply prose-h2:text-h2-sm md:prose-h2:text-h2; + @apply prose-h3:text-h3-sm md:prose-h3:text-h3; + @apply prose-img:max-w-full prose-img:rounded; + @apply prose-hr:border-border dark:prose-hr:border-darkmode-border; + @apply prose-p:text-base prose-p:text-text dark:prose-p:text-darkmode-text; + @apply prose-blockquote:rounded-lg prose-blockquote:border prose-blockquote:border-l-[10px] prose-blockquote:border-primary prose-blockquote:bg-theme-light prose-blockquote:px-8 prose-blockquote:py-10 prose-blockquote:font-secondary prose-blockquote:text-2xl prose-blockquote:not-italic prose-blockquote:text-dark dark:prose-blockquote:border-darkmode-primary dark:prose-blockquote:bg-darkmode-theme-light dark:prose-blockquote:text-darkmode-light; + @apply prose-pre:rounded-lg prose-pre:bg-theme-light dark:prose-pre:bg-darkmode-theme-light; + @apply prose-code:px-1 prose-code:text-primary dark:prose-code:text-darkmode-primary; + @apply prose-strong:text-dark dark:prose-strong:text-darkmode-text; + @apply prose-a:text-text prose-a:underline prose-a:hover:text-primary dark:prose-a:text-darkmode-text dark:prose-a:hover:text-darkmode-primary; + @apply prose-li:text-text dark:prose-li:text-darkmode-text; + @apply prose-table:relative prose-table:overflow-hidden prose-table:rounded-lg prose-table:before:absolute prose-table:before:left-0 prose-table:before:top-0 prose-table:before:h-full prose-table:before:w-full prose-table:before:rounded-[inherit] prose-table:before:border prose-table:before:content-[""] dark:prose-table:before:border-darkmode-border; + @apply prose-thead:border-border prose-thead:bg-theme-light dark:prose-thead:border-darkmode-border dark:prose-thead:bg-darkmode-theme-light; + @apply prose-th:relative prose-th:z-10 prose-th:px-4 prose-th:py-[18px] prose-th:text-dark dark:prose-th:text-darkmode-text; + @apply prose-tr:border-border dark:prose-tr:border-darkmode-border; + @apply prose-td:relative prose-td:z-10 prose-td:px-3 prose-td:py-[18px] dark:prose-td:text-darkmode-text; +} diff --git a/src/styles/components.scss b/src/styles/components.scss deleted file mode 100755 index 777e9e5..0000000 --- a/src/styles/components.scss +++ /dev/null @@ -1,176 +0,0 @@ -// section style -.section { - @apply py-24 xl:py-28; - &-sm { - @apply py-16 xl:py-20; - } -} - -// container -.container { - @apply mx-auto max-w-[1320px] px-4; -} - -// form style -.form-input { - @apply w-full rounded border-transparent bg-theme-light px-6 py-4 text-dark placeholder:text-light focus:border-primary focus:ring-transparent dark:border-darkmode-border dark:bg-darkmode-theme-light dark:text-darkmode-light; -} - -.form-label { - @apply mb-4 block font-secondary text-xl font-normal text-dark dark:text-darkmode-light; -} - -// social icons -.social-icons { - @apply space-x-4; - li { - @apply inline-block; - a { - @apply flex h-9 w-9 items-center justify-center rounded bg-primary text-center leading-9 text-white dark:bg-darkmode-primary dark:text-dark; - svg { - @apply h-5 w-5; - } - } - } -} - -// notice -.notice { - @apply mb-6 rounded-lg border px-8 py-6; - &-head { - @apply flex items-center; - svg { - @apply mr-3; - } - p { - @apply font-secondary text-xl font-semibold text-dark dark:text-darkmode-light; - } - } - .notice-body { - @apply mt-3; - p { - @apply my-0; - } - } - - &.note { - @apply text-[#1B83E2]; - @apply border-current; - } - - &.tip { - @apply text-[#40D294]; - @apply border-current; - } - - &.info { - @apply text-[#E3A72C]; - @apply border-current; - } - - &.warning { - @apply text-[#DB2C23]; - @apply border-current; - } -} - -// swiper pagination -.testimonial-slider-pagination { - .swiper-pagination-bullet { - @apply h-2.5 w-2.5 bg-theme-light opacity-100 dark:bg-darkmode-theme-light; - - &-active { - @apply h-4 w-4 bg-primary dark:bg-darkmode-primary; - } - } -} - -// tab -.tab { - @apply overflow-hidden rounded-lg border border-border dark:border-darkmode-border; - &-nav { - @apply flex border-b border-border bg-theme-light dark:border-darkmode-border dark:bg-darkmode-theme-light; - @apply m-0 #{!important}; - @apply list-none #{!important}; - - &-item { - @apply cursor-pointer border-b-[3px] border-border py-2 text-lg text-dark opacity-80 dark:border-light; - @apply my-0 #{!important}; - @apply px-8 #{!important}; - - &.active { - @apply border-b-[3px] border-dark opacity-100 dark:border-darkmode-primary; - } - } - } - &-content { - &-panel { - @apply p-8; - p { - @apply mb-0; - } - &.active { - @apply block; - } - } - } -} - -// accordion -.accordion { - @apply mb-6 overflow-hidden rounded-lg border border-border bg-theme-light dark:border-darkmode-border dark:bg-darkmode-theme-light; - &-header { - @apply flex w-full cursor-pointer items-center justify-between px-8 py-4 text-lg text-dark dark:bg-darkmode-theme-light dark:text-darkmode-light; - } - &-icon { - @apply ml-auto h-[.8em] w-[.8em] rotate-[-90deg] transition-transform duration-200; - } - &-content { - @apply max-h-0 overflow-hidden px-8 py-0; - } - &.active { - .accordion-icon { - @apply rotate-0; - } - .accordion-content { - @apply max-h-screen; - } - } -} - -// modal -.modal { - @apply fixed inset-0 z-40 hidden h-full w-full overflow-auto; - &-overlay { - @apply fixed inset-0 z-40 hidden h-full w-full bg-black bg-opacity-40; - } - &-content { - @apply relative top-1/2 z-50 mx-auto max-w-[90%] -translate-y-1/2 rounded-lg bg-body p-8 dark:bg-darkmode-body; - } - &-close { - @apply absolute right-3 top-3 h-8 w-8 rounded-full bg-theme-light text-center leading-8 text-dark dark:bg-darkmode-theme-light dark:text-darkmode-dark; - } -} - -// content style -.content { - @apply prose max-w-none; - @apply prose-headings:mb-[.3em] prose-headings:mt-[.6em] prose-headings:text-dark prose-headings:dark:text-darkmode-dark; - @apply prose-h1:text-h1-sm md:prose-h1:text-h1; - @apply prose-h2:text-h2-sm md:prose-h2:text-h2; - @apply prose-h3:text-h3-sm md:prose-h3:text-h3; - @apply prose-img:max-w-full prose-img:rounded; - @apply prose-hr:border-border prose-hr:dark:border-darkmode-border; - @apply prose-p:text-base prose-p:text-text prose-p:dark:text-darkmode-text; - @apply prose-blockquote:rounded-lg prose-blockquote:border prose-blockquote:border-l-[10px] prose-blockquote:border-primary prose-blockquote:bg-theme-light prose-blockquote:px-8 prose-blockquote:py-10 prose-blockquote:font-secondary prose-blockquote:text-2xl prose-blockquote:not-italic prose-blockquote:text-dark prose-blockquote:dark:border-darkmode-primary prose-blockquote:dark:bg-darkmode-theme-light prose-blockquote:dark:text-darkmode-light; - @apply prose-pre:rounded-lg prose-pre:bg-theme-light prose-pre:dark:bg-darkmode-theme-light; - @apply prose-code:px-1 prose-code:text-primary prose-code:dark:text-darkmode-primary; - @apply prose-strong:text-dark prose-strong:dark:text-darkmode-text; - @apply prose-a:text-text prose-a:underline hover:prose-a:text-primary prose-a:dark:text-darkmode-text hover:prose-a:dark:text-darkmode-primary; - @apply prose-li:text-text prose-li:dark:text-darkmode-text; - @apply prose-table:relative prose-table:overflow-hidden prose-table:rounded-lg prose-table:before:absolute prose-table:before:left-0 prose-table:before:top-0 prose-table:before:h-full prose-table:before:w-full prose-table:before:rounded-[inherit] prose-table:before:border prose-table:before:content-[""] prose-table:before:dark:border-darkmode-border; - @apply prose-thead:border-border prose-thead:bg-theme-light prose-thead:dark:border-darkmode-border prose-thead:dark:bg-darkmode-theme-light; - @apply prose-th:relative prose-th:z-10 prose-th:px-4 prose-th:py-[18px] prose-th:text-dark prose-th:dark:text-darkmode-text; - @apply prose-tr:border-border prose-tr:dark:border-darkmode-border; - @apply prose-td:relative prose-td:z-10 prose-td:px-3 prose-td:py-[18px] prose-td:dark:text-darkmode-text; -} diff --git a/src/styles/main.css b/src/styles/main.css new file mode 100755 index 0000000..ba38a1d --- /dev/null +++ b/src/styles/main.css @@ -0,0 +1,24 @@ +@import "tailwindcss"; +@plugin "../tailwind-plugin/tw-theme"; +@plugin "../tailwind-plugin/tw-bs-grid"; +@plugin "@tailwindcss/forms"; +@plugin "@tailwindcss/typography"; + +@custom-variant dark (&:where(.dark, .dark *)); + +@import "./safe.css"; + +@layer base { + @import "./base.css"; +} + +@layer components { + @import "./components.css"; + @import "./navigation.css"; + @import "./buttons.css"; + @import "./search.css"; +} + +@layer utilities { + @import "./utilities.css"; +} diff --git a/src/styles/main.scss b/src/styles/main.scss deleted file mode 100755 index 1e27c0f..0000000 --- a/src/styles/main.scss +++ /dev/null @@ -1,19 +0,0 @@ -@use "sass:meta"; -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - @include meta.load-css("base"); -} - -@layer components { - @include meta.load-css("components"); - @include meta.load-css("navigation"); - @include meta.load-css("buttons"); - @include meta.load-css("search"); -} - -@layer utilities { - @include meta.load-css("utilities"); -} diff --git a/src/styles/navigation.css b/src/styles/navigation.css new file mode 100755 index 0000000..1ffbf28 --- /dev/null +++ b/src/styles/navigation.css @@ -0,0 +1,70 @@ +.header { + @apply bg-body dark:bg-darkmode-body py-6; +} + +/* navbar items */ +.navbar { + @apply relative flex flex-wrap items-center justify-between; +} + +.navbar-brand { + @apply text-dark dark:text-darkmode-dark text-xl font-semibold; + image { + @apply max-h-full max-w-full; + } +} + +.navbar-nav { + @apply text-center lg:text-left; +} + +.nav-link { + @apply text-dark hover:text-primary dark:text-darkmode-dark dark:hover:text-darkmode-primary block p-3 cursor-pointer font-semibold transition lg:px-2 lg:py-3; +} + +.nav-dropdown { + @apply mr-0; +} + +.nav-dropdown > svg { + @apply pointer-events-none; +} + +.nav-dropdown.active .nav-dropdown-list { + @apply block; +} + +.nav-dropdown-list { + @apply bg-body dark:bg-darkmode-body z-10 min-w-[180px] rounded p-4 shadow hidden lg:invisible lg:absolute lg:block lg:opacity-0; +} + +.nav-dropdown-item { + @apply [&:not(:last-child)]:mb-2; +} + +.nav-dropdown-link { + @apply text-dark hover:text-primary dark:text-darkmode-text dark:hover:text-darkmode-primary block py-1 font-semibold transition; +} + +/* theme-switcher */ +.theme-switcher { + @apply inline-flex; + + label { + @apply bg-border relative inline-block h-4 w-6 cursor-pointer rounded-2xl lg:w-10; + } + + input { + @apply absolute opacity-0; + } + + span { + @apply bg-dark absolute -top-1 left-0 flex h-6 w-6 items-center justify-center rounded-full transition-all duration-300 dark:bg-white; + } + + input:checked + label { + span { + @apply lg:left-4; + } + } +} diff --git a/src/styles/navigation.scss b/src/styles/navigation.scss deleted file mode 100755 index b410de0..0000000 --- a/src/styles/navigation.scss +++ /dev/null @@ -1,79 +0,0 @@ -// navbar toggler -input#nav-toggle:checked + label #show-button { - @apply hidden; -} - -input#nav-toggle:checked + label #hide-button { - @apply block; -} - -input#nav-toggle:checked ~ #nav-menu { - @apply block; -} - -.header { - @apply bg-body py-6 dark:bg-darkmode-body; -} - -// navbar items -.navbar { - @apply relative flex flex-wrap items-center justify-between; -} - -.navbar-brand { - @apply text-xl font-semibold text-dark dark:text-darkmode-dark; - image { - @apply max-h-full max-w-full; - } -} - -.navbar-nav { - @apply text-center lg:text-left; -} - -// .nav-item { -// @apply mx-3; -// } - -.nav-link { - @apply text-dark hover:text-primary dark:text-darkmode-dark dark:hover:text-darkmode-primary block p-3 font-semibold transition lg:px-2 lg:py-3; -} - -.nav-dropdown { - @apply mr-0; -} - -.nav-dropdown-list { - @apply z-10 min-w-[180px] rounded bg-body p-4 shadow dark:bg-darkmode-body; -} - -.nav-dropdown-item { - @apply mb-2; -} - -.nav-dropdown-link { - @apply block py-1 font-semibold text-dark transition hover:text-primary dark:text-darkmode-text dark:hover:text-darkmode-primary; -} - -//theme-switcher -.theme-switcher { - @apply inline-flex; - - label { - @apply relative inline-block h-4 w-6 cursor-pointer rounded-2xl bg-border lg:w-10; - } - - input { - @apply absolute opacity-0; - } - - span { - @apply absolute -top-1 left-0 flex h-6 w-6 items-center justify-center rounded-full bg-dark transition-all duration-300 dark:bg-white; - } - - input:checked + label { - span { - @apply lg:left-4; - } - } -} diff --git a/src/styles/safe.css b/src/styles/safe.css new file mode 100644 index 0000000..bb50352 --- /dev/null +++ b/src/styles/safe.css @@ -0,0 +1,10 @@ +/* swiper pagination */ +.testimonial-slider-pagination { + .swiper-pagination-bullet { + @apply h-2.5 w-2.5 bg-theme-light opacity-100 dark:bg-darkmode-theme-light; + } + + .swiper-pagination-bullet-active { + @apply h-4 w-4 bg-primary dark:bg-darkmode-primary; + } +} diff --git a/src/styles/search.css b/src/styles/search.css new file mode 100644 index 0000000..5906ca0 --- /dev/null +++ b/src/styles/search.css @@ -0,0 +1,97 @@ +.search-modal { + @apply z-50 fixed top-0 left-0 w-full h-full flex items-start justify-center invisible opacity-0; +} +.search-modal.show { + @apply visible opacity-100; +} +.search-modal-overlay { + @apply fixed top-0 left-0 w-full h-full bg-black opacity-50; +} +.search-wrapper { + @apply bg-white dark:bg-darkmode-body w-[660px] max-w-[96%] mt-24 rounded shadow-lg relative z-10; +} +.search-wrapper-header { + @apply p-4 relative; +} +.search-wrapper-header-input { + @apply border border-solid w-full focus:ring-0 focus:border-dark border-border rounded-[4px] h-12 pr-4 pl-10 transition duration-200 outline-none dark:bg-darkmode-theme-light dark:text-darkmode-text dark:border-darkmode-border dark:focus:border-darkmode-primary; +} +.search-wrapper-body { + @apply dark:bg-darkmode-theme-light dark:shadow-none max-h-[calc(100vh-350px)] overflow-y-auto bg-theme-light shadow-[inset_0_2px_18px_#ddd] p-4 rounded; +} +.search-wrapper-footer { + @apply text-xs select-none leading-none md:flex items-center px-3.5 py-2 hidden; +} +.search-wrapper-footer kbd { + @apply bg-theme-light dark:bg-darkmode-theme-light text-xs leading-none text-center mr-[3px] px-1 py-0.5 rounded-[3px]; +} +.search-wrapper-footer span:not(:last-child) { + @apply mr-4; +} +.search-wrapper-footer span:last-child { + @apply ml-auto; +} +.search-result-empty { + @apply text-center cursor-text select-none px-0 py-8; +} +.search-result-group { + @apply mb-4; +} +.search-result-group-title { + @apply text-lg text-dark dark:text-darkmode-dark mb-[5px] px-3; +} +.search-result-item { + @apply rounded border bg-white dark:bg-darkmode-body dark:border-darkmode-border flex items-start mb-1 p-4 scroll-my-[30px] border-solid border-border relative; +} +.search-result-item mark { + @apply bg-yellow-200 rounded-[2px]; +} +.search-result-item-title { + @apply text-lg font-bold text-dark dark:text-darkmode-dark leading-none; +} +.search-result-item-link::after { + @apply absolute top-0 right-0 bottom-0 left-0 z-10 content-[""]; +} +.search-result-item-image { + @apply shrink-0 mr-3.5; +} +.search-result-item-image img { + @apply w-[60px] h-[60px] md:w-[100px] md:h-[100px] rounded-[4px] object-cover; +} +.search-result-item-description { + @apply text-sm line-clamp-1 mt-1; +} +.search-result-item-content { + @apply mx-0 my-1.5 empty:hidden line-clamp-1; +} +.search-result-item-taxonomies { + @apply text-sm flex flex-wrap items-center text-light dark:text-darkmode-light; +} +.search-result-item-taxonomies svg { + @apply inline-block mr-1; +} +.search-result-item-active, +.search-result-item:focus, +.search-result-item:hover { + @apply bg-dark dark:bg-dark; +} +.search-result-item-active .search-result-item-title, +.search-result-item:focus .search-result-item-title, +.search-result-item:hover .search-result-item-title { + @apply text-white; +} +.search-result-item-active .search-result-item-description, +.search-result-item:focus .search-result-item-description, +.search-result-item:hover .search-result-item-description { + @apply text-white/80; +} +.search-result-item-active .search-result-item-content, +.search-result-item:focus .search-result-item-content, +.search-result-item:hover .search-result-item-content { + @apply text-white/90; +} +.search-result-item-active .search-result-item-taxonomies, +.search-result-item:focus .search-result-item-taxonomies, +.search-result-item:hover .search-result-item-taxonomies { + @apply text-white/90; +} diff --git a/src/styles/search.scss b/src/styles/search.scss deleted file mode 100644 index b7c0f4d..0000000 --- a/src/styles/search.scss +++ /dev/null @@ -1,96 +0,0 @@ -.search { - &-modal { - @apply z-50 fixed -top-10 left-0 w-full h-full flex items-start justify-center invisible opacity-0; - &.show { - @apply visible opacity-100; - } - &-overlay { - @apply fixed top-0 left-0 w-full h-full bg-black opacity-50; - } - } - &-wrapper { - @apply bg-white dark:bg-darkmode-body w-[660px] max-w-[96%] mt-24 rounded shadow-lg relative z-10; - &-header { - @apply p-4 relative; - &-input { - @apply border border-solid w-full focus:ring-0 focus:border-dark border-border rounded-[4px] h-12 pr-4 pl-10 transition duration-200 outline-none dark:bg-darkmode-theme-light dark:text-darkmode-text dark:border-darkmode-border dark:focus:border-darkmode-primary; - } - } - &-body { - @apply dark:bg-darkmode-theme-light dark:shadow-none max-h-[calc(100vh-350px)] overflow-y-auto bg-theme-light shadow-[inset_0_2px_18px_#ddd] p-4 rounded; - } - &-footer { - @apply text-xs select-none leading-none md:flex items-center px-3.5 py-2 hidden; - kbd { - @apply bg-theme-light dark:bg-darkmode-theme-light text-xs leading-none text-center mr-[3px] px-1 py-0.5 rounded-[3px]; - } - span:not(:last-child) { - @apply mr-4; - } - span:last-child { - @apply ml-auto; - } - } - } - &-result { - &-empty { - @apply text-center cursor-text select-none px-0 py-8; - } - &-group { - @apply mb-4; - &-title { - @apply text-lg text-dark dark:text-darkmode-dark mb-[5px] px-3; - } - } - &-item { - @apply rounded border bg-white dark:bg-darkmode-body dark:border-darkmode-border flex items-start mb-1 p-4 scroll-my-[30px] border-solid border-border relative; - mark { - @apply bg-yellow-200 rounded-[2px]; - } - &-title { - @apply text-lg font-bold text-dark dark:text-darkmode-dark leading-none; - } - &-link::after { - @apply absolute top-0 right-0 bottom-0 left-0 z-10 content-[""]; - } - &-image { - @apply shrink-0 mr-3.5; - img { - @apply w-[60px] h-[60px] md:w-[100px] md:h-[100px] rounded-[4px] object-cover; - } - } - &-description { - @apply text-sm line-clamp-1 mt-1; - } - &-content { - @apply mx-0 my-1.5 empty:hidden line-clamp-1; - } - &-taxonomies { - @apply text-sm flex flex-wrap items-center text-light dark:text-darkmode-light; - svg { - @apply inline-block mr-1; - } - } - - &-active, - &:focus, - &:hover { - @apply bg-dark dark:bg-dark; - .search-result-item { - &-title { - @apply text-white; - } - &-description { - @apply text-white/80; - } - &-content { - @apply text-white/90; - } - &-taxonomies { - @apply text-white/90; - } - } - } - } - } -} diff --git a/src/styles/utilities.css b/src/styles/utilities.css new file mode 100755 index 0000000..f8db083 --- /dev/null +++ b/src/styles/utilities.css @@ -0,0 +1,29 @@ +/* navbar toggler */ +input#nav-toggle:checked + label #show-button { + @apply hidden; +} + +input#nav-toggle:checked + label #hide-button { + @apply block; +} + +input#nav-toggle:checked ~ #nav-menu { + @apply block; +} + +.bg-gradient { + @apply bg-linear-to-b from-[rgba(249,249,249,1)] from-[0.53%] to-white to-[83.28%] dark:from-darkmode-theme-light dark:to-darkmode-body; +} + +.shadow { + @apply shadow-[0px_4px_40px_rgba(0,0,0,0.05)]; +} + +/* form style */ +.form-input { + @apply w-full rounded border-transparent bg-theme-light px-6 py-4 text-dark placeholder:text-light focus:border-primary dark:focus:border-darkmode-primary focus:ring-transparent dark:border-darkmode-border dark:bg-darkmode-theme-light dark:text-darkmode-light; +} + +.form-label { + @apply mb-4 block font-secondary text-xl font-normal text-dark dark:text-darkmode-light; +} diff --git a/src/styles/utilities.scss b/src/styles/utilities.scss deleted file mode 100755 index 52b1186..0000000 --- a/src/styles/utilities.scss +++ /dev/null @@ -1,20 +0,0 @@ -.bg-gradient { - @apply bg-gradient-to-b from-[rgba(249,249,249,1)] from-[0.53%] to-white to-[83.28%] dark:from-darkmode-theme-light dark:to-darkmode-body; -} - -.rounded-sm { - @apply rounded-[4px]; -} -.rounded { - @apply rounded-[6px]; -} -.rounded-lg { - @apply rounded-[12px]; -} -.rounded-xl { - @apply rounded-[16px]; -} - -.shadow { - box-shadow: 0px 4px 40px rgba(0, 0, 0, 0.05); -} diff --git a/src/tailwind-plugin/tw-bs-grid.js b/src/tailwind-plugin/tw-bs-grid.js new file mode 100644 index 0000000..1aef32d --- /dev/null +++ b/src/tailwind-plugin/tw-bs-grid.js @@ -0,0 +1,103 @@ +import plugin from "tailwindcss/plugin"; + +module.exports = plugin.withOptions(() => { + return ({ addComponents }) => { + const gridColumns = 12; + const gridGutterWidth = "1.5rem"; + const gridGutters = { + 0: "0", + 1: "0.25rem", + 2: "0.5rem", + 3: "1rem", + 4: "1.5rem", + 5: "3rem", + }; + const respectImportant = true; + const columns = Array.from({ length: gridColumns }, (_, i) => i + 1); + const rowColsSteps = columns.slice(0, Math.floor(gridColumns / 2)); + + // row + addComponents( + { + ".row": { + "--bs-gutter-x": gridGutterWidth, + "--bs-gutter-y": 0, + display: "flex", + flexWrap: "wrap", + marginTop: "calc(var(--bs-gutter-y) * -1)", + marginRight: "calc(var(--bs-gutter-x) / -2)", + marginLeft: "calc(var(--bs-gutter-x) / -2)", + "& > *": { + boxSizing: "border-box", + flexShrink: 0, + width: "100%", + maxWidth: "100%", + paddingRight: "calc(var(--bs-gutter-x) / 2)", + paddingLeft: "calc(var(--bs-gutter-x) / 2)", + marginTop: "var(--bs-gutter-y)", + }, + }, + }, + { respectImportant }, + ); + + // columns + addComponents( + [ + { + ".col": { flex: "1 0 0%" }, + ".row-cols-auto": { "& > *": { flex: "0 0 auto", width: "auto" } }, + }, + ...rowColsSteps.map((num) => ({ + [`.row-cols-${num}`]: { + "& > *": { flex: "0 0 auto", width: `${100 / num}%` }, + }, + })), + { ".col-auto": { flex: "0 0 auto", width: "auto" } }, + ...columns.map((num) => ({ + [`.col-${num}`]: { + flex: "0 0 auto", + width: `${(100 / gridColumns) * num}%`, + }, + })), + ], + { respectImportant }, + ); + + // offset + addComponents( + [0, ...columns.slice(0, -1)].map((num) => ({ + [`.offset-${num}`]: { marginLeft: `${(100 / gridColumns) * num}%` }, + })), + { respectImportant }, + ); + + // gutters + if (Object.keys(gridGutters).length) { + const gutterComponents = Object.entries(gridGutters).reduce( + (acc, [key, value]) => { + acc[`.g-${key}`] = { "--bs-gutter-x": value, "--bs-gutter-y": value }; + acc[`.gx-${key}`] = { "--bs-gutter-x": value }; + acc[`.gy-${key}`] = { "--bs-gutter-y": value }; + return acc; + }, + {}, + ); + addComponents(gutterComponents, { respectImportant }); + } + + // order + addComponents( + [ + { + ".order-first": { order: "-1" }, + ".order-last": { order: gridColumns + 1 }, + }, + ...[0, ...columns].map((num) => ({ + [`.order-${num}`]: { order: String(num) }, + })), + ], + { respectImportant }, + ); + }; +}); diff --git a/src/tailwind-plugin/tw-theme.js b/src/tailwind-plugin/tw-theme.js new file mode 100644 index 0000000..f1b872f --- /dev/null +++ b/src/tailwind-plugin/tw-theme.js @@ -0,0 +1,94 @@ +import plugin from "tailwindcss/plugin"; +import themeConfig from "../config/theme.json"; + +// Find font name from font string +const findFont = (fontStr) => + fontStr.replace(/\+/g, " ").replace(/:[^:]+/g, ""); + +// Set font families dynamically, filtering out 'type' keys +const fontFamilies = Object.entries(themeConfig.fonts.font_family) + .filter(([key]) => !key.includes("type")) + .reduce((acc, [key, font]) => { + acc[key] = + `${findFont(font)}, ${themeConfig.fonts.font_family[`${key}_type`] || "sans-serif"}`; + return acc; + }, {}); + +module.exports = plugin.withOptions(() => { + return ({ addBase, addUtilities }) => { + const rootVars = {}; + + const baseSize = Number(themeConfig.fonts.font_size.base); + const scale = Number(themeConfig.fonts.font_size.scale); + + // Set font sizes + const fontSizes = { + base: `${baseSize}px`, + "base-sm": `${baseSize * 0.8}px`, + h1: `${scale ** 5}rem`, + "h1-sm": `${scale ** 5 * 0.9}rem`, + h2: `${scale ** 4}rem`, + "h2-sm": `${scale ** 4 * 0.9}rem`, + h3: `${scale ** 3}rem`, + "h3-sm": `${scale ** 3 * 0.9}rem`, + h4: `${scale ** 2}rem`, + h5: `${scale}rem`, + h6: `${scale}rem`, + }; + Object.entries(fontSizes).forEach(([k, v]) => { + rootVars[`--text-${k}`] = v; + }); + + Object.entries(fontFamilies).forEach(([key, font]) => { + rootVars[`--font-${key}`] = font; + }); + + // Define color groups + const groups = [ + { colors: themeConfig.colors.default.theme_color, prefix: "" }, + { colors: themeConfig.colors.default.text_color, prefix: "" }, + { colors: themeConfig.colors.darkmode.theme_color, prefix: "darkmode-" }, + { colors: themeConfig.colors.darkmode.text_color, prefix: "darkmode-" }, + ]; + + // Set color variables + groups.forEach(({ colors, prefix }) => { + Object.entries(colors).forEach(([k, v]) => { + rootVars[`--color-${prefix}${k.replace(/_/g, "-")}`] = v; + }); + }); + + // Add variables to root + addBase({ ":root": rootVars }); + + // Generate color utilities + const colorUtils = {}; + groups.forEach(({ colors, prefix }) => { + Object.keys(colors).forEach((k) => { + const cls = k.replace(/_/g, "-"); + const varRef = `var(--color-${prefix}${cls})`; + colorUtils[`.bg-${prefix}${cls}`] = { backgroundColor: varRef }; + colorUtils[`.text-${prefix}${cls}`] = { color: varRef }; + colorUtils[`.border-${prefix}${cls}`] = { borderColor: varRef }; + colorUtils[`.fill-${prefix}${cls}`] = { fill: varRef }; + colorUtils[`.from-${prefix}${cls}`] = { "--tw-gradient-from": varRef }; + colorUtils[`.to-${prefix}${cls}`] = { "--tw-gradient-to": varRef }; + colorUtils[`.via-${prefix}${cls}`] = { "--tw-gradient-stops": varRef }; + }); + }); + + // Generate font utilities dynamically + const fontUtils = {}; + Object.keys(fontFamilies).forEach((key) => { + fontUtils[`.font-${key}`] = { fontFamily: `var(--font-${key})` }; + }); + Object.keys(fontSizes).forEach((k) => { + fontUtils[`.text-${k}`] = { fontSize: `var(--text-${k})` }; + }); + + addUtilities( + { ...colorUtils, ...fontUtils }, + { variants: ["responsive", "hover", "focus", "active", "disabled"] }, + ); + }; +}); diff --git a/tailwind.config.js b/tailwind.config.js deleted file mode 100755 index 04004f5..0000000 --- a/tailwind.config.js +++ /dev/null @@ -1,94 +0,0 @@ -const theme = require("./src/config/theme.json"); - -let font_base = Number(theme.fonts.font_size.base.replace("px", "")); -let font_scale = Number(theme.fonts.font_size.scale); -let h6 = font_scale; -let h5 = h6 * font_scale; -let h4 = h5 * font_scale; -let h3 = h4 * font_scale; -let h2 = h3 * font_scale; -let h1 = h2 * font_scale; - -let fontPrimaryType, fontSecondaryType; -if (theme.fonts.font_family.primary) { - fontPrimaryType = theme.fonts.font_family.primary_type; -} -if (theme.fonts.font_family.secondary) { - fontSecondaryType = theme.fonts.font_family.secondary_type; -} - -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"], - safelist: [{ pattern: /^swiper-/ }], - darkMode: "class", - theme: { - screens: { - sm: "540px", - md: "768px", - lg: "1024px", - xl: "1280px", - "2xl": "1536px", - }, - container: { - center: true, - padding: "2rem", - }, - extend: { - colors: { - text: theme.colors.default.text_color.default, - light: theme.colors.default.text_color.light, - dark: theme.colors.default.text_color.dark, - primary: theme.colors.default.theme_color.primary, - secondary: theme.colors.default.theme_color.secondary, - body: theme.colors.default.theme_color.body, - border: theme.colors.default.theme_color.border, - "theme-light": theme.colors.default.theme_color.theme_light, - "theme-dark": theme.colors.default.theme_color.theme_dark, - darkmode: { - text: theme.colors.darkmode.text_color.default, - light: theme.colors.darkmode.text_color.light, - dark: theme.colors.darkmode.text_color.dark, - primary: theme.colors.darkmode.theme_color.primary, - secondary: theme.colors.darkmode.theme_color.secondary, - body: theme.colors.darkmode.theme_color.body, - border: theme.colors.darkmode.theme_color.border, - "theme-light": theme.colors.darkmode.theme_color.theme_light, - "theme-dark": theme.colors.darkmode.theme_color.theme_dark, - }, - }, - fontSize: { - base: font_base + "px", - "base-sm": font_base * 0.8 + "px", - h1: h1 + "rem", - "h1-sm": h1 * 0.9 + "rem", - h2: h2 + "rem", - "h2-sm": h2 * 0.9 + "rem", - h3: h3 + "rem", - "h3-sm": h3 * 0.9 + "rem", - h4: h4 + "rem", - h5: h5 + "rem", - h6: h6 + "rem", - }, - fontFamily: { - primary: ["var(--font-primary)", fontPrimaryType], - secondary: ["var(--font-secondary)", fontSecondaryType], - }, - }, - }, - plugins: [ - require("@tailwindcss/typography"), - require("@tailwindcss/forms"), - require("tailwind-bootstrap-grid")({ - generateContainer: false, - gridGutterWidth: "2rem", - gridGutters: { - 1: "0.25rem", - 2: "0.5rem", - 3: "1rem", - 4: "1.5rem", - 5: "3rem", - }, - }), - ], -};