Commit 8a8bf19
Changed files (35)
src
components
comment
search
utils
widgets
layouts
pages
archives
categories
tags
[tag]
posts
plugins
src/components/comment/Twikoo.astro
@@ -1,5 +1,5 @@
---
-import '@/styles/twikoo.scss';
+import '@/styles/twikoo.css';
import { CDN } from '@constants/cdn.mjs';
---
src/components/misc/CategoryBar.astro
@@ -10,7 +10,7 @@ interface Props {
const { categories, currentCategory } = Astro.props;
---
-<div id="category-bar" class="card card-bordered mb-4 w-full border-2">
+<div id="category-bar" class="card card-bordered border-base-300 mb-4 w-full border-2">
<div class="card-body flex flex-row items-center gap-2 overflow-auto px-2 py-3">
<a
href={`/`}
src/components/misc/License.astro
@@ -29,7 +29,7 @@ const infomations = [
];
---
-<div class="card card-bordered my-4 border-2 bg-primary/25">
+<div class="card card-bordered border-base-300 bg-primary/25 my-4 border-2">
<div class="card-body grid grid-cols-2 gap-x-4 p-4">
{
infomations.map((info) => (
src/components/search/Pagefind.astro
@@ -12,13 +12,10 @@ const bundlePath = `${import.meta.env.BASE_URL}pagefind/`;
/>
<template id="pagefind-result-template">
- <a
- class="group w-full rounded-md p-2 duration-150 hover:bg-primary hover:bg-opacity-30"
- href="#"
- >
+ <a class="group hover:bg-primary/30 w-full rounded-md p-2 duration-150" href="#">
<div class="flex flex-row items-center gap-1 text-center">
- <span class="text-lg duration-150 group-hover:text-primary">Fake Result</span>
- <Icon name="material-symbols:chevron-right" class="text-lg text-primary" />
+ <span class="group-hover:text-primary text-lg duration-150">Fake Result</span>
+ <Icon name="material-symbols:chevron-right" class="text-primary text-lg" />
</div>
<div id="pagefind-result-template-excerpt" class="text-sm opacity-60">
This is a fake result.
@@ -81,7 +78,6 @@ const bundlePath = `${import.meta.env.BASE_URL}pagefind/`;
<style is:global>
[data-pagefind-ui] mark {
background-color: transparent;
-
- @apply text-secondary;
+ color: var(--color-secondary);
}
</style>
src/components/utils/Markdown.astro
@@ -1,5 +1,5 @@
---
-import '@/styles/markdown.scss';
+import '@/styles/markdown.css';
import Button from '@components/widgets/Button.astro';
import { isFirstInstance } from '@utils/component-utils';
import { Icon } from 'astro-icon/components';
@@ -23,9 +23,9 @@ const firstHasPre = hasPre && (isFirstInstance('md-has-pre', Astro.url) || impor
firstHasPre && (
<template
id="code-toolbar-template"
- class="code-block-wrapper collapse collapse-open relative my-4"
+ class="code-block-wrapper collapse-open collapse relative my-4"
>
- <div class="z-10 flex items-center justify-between bg-primary/60 text-primary-content">
+ <div class="bg-primary/60 text-primary-content z-10 flex items-center justify-between">
<Button class="toggle-btn btn-ghost rounded-bl-none">
<Icon
name="material-symbols:keyboard-arrow-down-rounded"
src/components/widgets/MetaIcon.astro
@@ -9,7 +9,7 @@ const { class: className, ...rest } = Astro.props;
<Icon {...rest} class:list={['meta-icon', className]} />
-<style lang="scss">
+<style>
.meta-icon {
width: 1.5rem;
height: 1.5rem;
@@ -17,7 +17,6 @@ const { class: className, ...rest } = Astro.props;
margin-right: 0.5rem;
display: flex;
justify-content: center;
-
- @apply text-primary;
+ color: var(--color-text-primary);
}
</style>
src/components/widgets/Pagination.astro
@@ -101,7 +101,7 @@ else {
}
</div>
-<style lang="scss">
+<style>
/* hide arrows from number input */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
src/components/widgets/PostCard.astro
@@ -48,15 +48,13 @@ const metas: ({ icon: string; text: string; link?: string } | undefined)[] = [
<div
class:list={[
- 'card card-bordered flex w-full rounded-xl border-2 md:card-side max-md:flex-col-reverse',
+ 'card card-bordered border-base-300 md:card-side flex w-full rounded-xl border-2 max-md:flex-col-reverse',
className,
]}
>
<div class="card-body">
<a href={url} class="card-title">{title}</a>
- <div
- class="mb-3 flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-base-content text-opacity-60"
- >
+ <div class="text-base-content/60 mb-3 flex flex-wrap items-center gap-x-4 gap-y-2 text-sm">
{
metas.map((meta) => {
return (
src/components/widgets/PostCardCover.astro
@@ -11,23 +11,15 @@ interface Props {
const { url, title, cover } = Astro.props;
---
-<a href={url} title={title} class="group">
- <div class="cover-mask">
- <Icon name="material-symbols:chevron-right-rounded" />
+<a
+ href={url}
+ title={title}
+ class="group relative flex min-h-48 w-full overflow-hidden duration-100 active:brightness-75"
+>
+ <div
+ class="absolute inset-0 z-10 flex h-full w-full items-center justify-center bg-black/60 opacity-0 duration-300 group-hover:opacity-100"
+ >
+ <Icon name="material-symbols:chevron-right-rounded" class="h-24 w-24 text-white" />
</div>
<ImageWrapper src={cover} alt={title} />
</a>
-
-<style>
- a {
- @apply relative flex min-h-48 w-full overflow-hidden duration-100 active:brightness-75;
- }
-
- div.cover-mask {
- @apply absolute inset-0 z-10 flex h-full w-full items-center justify-center bg-black/60 opacity-0 duration-300 group-hover:opacity-100;
- }
-
- svg {
- @apply h-24 w-24 text-white;
- }
-</style>
src/components/widgets/ProfileCard.astro
@@ -5,7 +5,11 @@ import { Icon } from 'astro-icon/components';
import Button from './Button.astro';
---
-<div id="profile-card" transition:name="profile-card" class="card card-bordered border-2">
+<div
+ id="profile-card"
+ transition:name="profile-card"
+ class="card card-bordered border-base-300 border-2"
+>
<figure class="px-4 pt-4">
<a href="/about/">
<ImageWrapper class="rounded-xl" src={profileConfig.avatar} alt={profileConfig.name} />
src/components/widgets/ReadMoreButton.astro
@@ -4,21 +4,19 @@ import { i18n } from '@i18n/translation';
import { Icon } from 'astro-icon/components';
import type { ComponentProps } from 'astro/types';
-type Props = Omit<ComponentProps<typeof Icon>, 'name'>;
+type Props = Omit<ComponentProps<typeof Icon>, 'name' | 'class'>;
const { href, title, ...rest } = Astro.props;
---
-<a href={href} title={title || i18n(I18nKey.more)}>
- <Icon name="material-symbols:chevron-right-rounded" {...rest} />
+<a
+ href={href}
+ title={title || i18n(I18nKey.more)}
+ class="duration-150 hover:brightness-125 active:brightness-75 max-md:hidden"
+>
+ <Icon
+ name="material-symbols:chevron-right-rounded"
+ {...rest}
+ class="bg-primary/40 text-primary h-full min-h-48 w-12"
+ />
</a>
-
-<style>
- a {
- @apply duration-150 hover:brightness-125 active:brightness-75 max-md:hidden;
- }
-
- svg {
- @apply h-full min-h-48 w-12 bg-primary/40 text-primary;
- }
-</style>
src/components/widgets/TOC.astro
@@ -13,7 +13,7 @@ const maxLevel = 3;
<div
id="toc"
- class:list={['card card-bordered border-2 bg-base-100', className]}
+ class:list={['card card-bordered border-base-300 bg-base-100 border-2', className]}
transition:name="toc-card"
>
<div class="card-body p-2">
@@ -29,21 +29,15 @@ const maxLevel = 3;
</div>
</div>
-<style lang="scss">
+<style>
$max-level: 3;
a {
display: block;
padding: 0.5rem 1rem;
- @apply duration-200 ease-in-out;
+ @apply duration-200;
@apply hover:scale-105;
@apply active:scale-95;
-
- @for $i from 1 through $max-level {
- &.level-#{$i} {
- padding-left: #{($i - 1) * 0.5 + 1}rem;
- }
- }
}
</style>
src/components/Search.astro
@@ -7,7 +7,7 @@ import Pagefind from './search/Pagefind.astro';
<dialog id="search_modal" class="modal" transition:persist>
<div class="modal-box border-base-200 bg-base-300">
<form method="dialog">
- <button class="btn btn-circle btn-ghost btn-sm absolute right-2 top-2">✕</button>
+ <button class="btn btn-circle btn-ghost btn-sm absolute top-2 right-2">✕</button>
</form>
<div class="w-full p-4">
{
@@ -21,7 +21,7 @@ import Pagefind from './search/Pagefind.astro';
})()
}
</div>
- <div class="relative mt-auto w-full flex-shrink-0 pt-4 text-center">
+ <div class="relative mt-auto w-full shrink-0 pt-4 text-center">
Powered by {
searchConfig.provider === 'pagefind' ? (
<a href="https://pagefind.app" target="_blank" class="text-primary">
src/components/SideToolBar.astro
@@ -5,7 +5,7 @@ import Button from './widgets/Button.astro';
import DarkModeButton from './widgets/DarkModeButton.astro';
---
-<div id="side-toolbar" class="fixed bottom-10 right-0 z-30 grid grid-cols-1 gap-2">
+<div id="side-toolbar" class="fixed right-0 bottom-10 z-30 grid grid-cols-1 gap-2">
<div
id="stb-hide"
class="grid translate-x-full grid-cols-1 gap-2 pr-4 duration-500 ease-in-out"
@@ -24,7 +24,7 @@ import DarkModeButton from './widgets/DarkModeButton.astro';
{
articleConfig.toc && (
<Fragment>
- <Button id="stb-toc" class="btn-circle btn-primary btn-sm hidden xl:!hidden">
+ <Button id="stb-toc" class="btn-circle btn-primary btn-sm hidden xl:hidden!">
<Icon name="material-symbols:toc-rounded" />
</Button>
<div
src/components/TimeArchives.astro
@@ -25,7 +25,7 @@ const { group } = Astro.props;
<Timeline items={group.months} class="ml-4">
<fragment slot="title">
{(monthGroup: MonthArchives) => (
- <div class="mb-6 ml-6 mt-3 flex items-center justify-between">
+ <div class="mt-3 mb-6 ml-6 flex items-center justify-between">
<h2 class="text-2xl font-bold">{monthGroup.month}</h2>
</div>
)}
src/components/Timeline.astro
@@ -38,36 +38,18 @@ const renderedItems = await Promise.all(
);
---
-<div class:list={['relative flex flex-col', className]}>
+<div class:list={['relative flex flex-col empty:min-h-12', className]}>
<div
- class="timeline absolute left-4 top-0 h-full w-0.5 bg-gradient-to-b from-blue-500 to-purple-500"
+ class="timeline absolute top-0 left-4 h-full w-0.5 bg-linear-to-b from-blue-500 to-purple-500 opacity-60"
>
</div>
{
renderedItems.map((item) => (
<div class="relative mb-12 pl-12">
- <div class="timeline-dot absolute left-2 top-5 h-4 w-4 rounded-full bg-blue-500" />
+ <div class="absolute top-5 left-2 h-4 w-4 rounded-full bg-blue-500 shadow-lg transition-transform duration-300 hover:scale-125" />
<Fragment set:html={item.title} />
<Fragment set:html={item.body} />
</div>
))
}
</div>
-
-<style>
- .flex-col:empty {
- @apply min-h-[3rem];
- }
-
- .timeline {
- @apply opacity-60;
- }
-
- .timeline-dot {
- @apply shadow-lg transition-transform duration-300;
- }
-
- .timeline-dot:hover {
- @apply scale-125;
- }
-</style>
src/layouts/GlobalLayout.astro
@@ -1,5 +1,6 @@
---
import { profileConfig, siteConfig } from '@/config';
+import '@/styles/global.css';
import { ClientRouter } from 'astro:transitions';
interface Props {
@@ -46,7 +47,7 @@ const siteLang = lang.replace('_', '-');
<slot name="head" />
</head>
- <body class="flex min-h-screen flex-col bg-base-100 text-base-content">
+ <body class="bg-base-100 text-base-content flex min-h-screen flex-col">
<slot />
</body>
</html>
@@ -65,7 +66,3 @@ const siteLang = lang.replace('_', '-');
document.addEventListener('astro:after-swap', applyDarkMode);
applyDarkMode();
</script>
-
-<style is:global lang="scss">
- @use '../styles/globals';
-</style>
src/layouts/GridLayout.astro
@@ -10,7 +10,7 @@ const { title, description, lang } = Astro.props;
---
<MainLayout title={title} description={description} lang={lang}>
- <div class="mx-auto flex max-w-screen-xl flex-col gap-4">
+ <div class="mx-auto flex max-w-(--breakpoint-xl) flex-col gap-4">
<slot name="header-content" />
<div class="flex gap-4">
<div id="main-content" class="my-4 w-full">
src/pages/archives/categories/index.astro
@@ -23,7 +23,7 @@ if (uncategorizedPosts.length > 0)
---
<MainLayout title={i18n(I18nKey.categories)}>
- <div class="mx-auto flex max-w-screen-xl flex-col items-center">
+ <div class="mx-auto flex max-w-(--breakpoint-xl) flex-col items-center">
<h1 class="my-8 text-3xl font-bold">{i18n(I18nKey.categories)}</h1>
<Timeline items={Array.from(categoryPosts.keys())}>
<fragment slot="title">
@@ -34,7 +34,7 @@ if (uncategorizedPosts.length > 0)
<Button
href={`/archives/categories/${category === i18n(I18nKey.uncategorized) ? I18nKey.uncategorized : category.replaceAll(/[\\/]/g, '-')}/1/`}
title={category}
- class="!pl-3"
+ class="pl-3!"
>
{i18n(I18nKey.more)}
<Icon name="material-symbols:chevron-right-rounded" class="text-2xl" />
src/pages/posts/[article].astro
@@ -35,7 +35,7 @@ const description = article.data.description || remarkPluginFrontmatter.excerpt;
class="mx-2 mt-4"
/>
</Fragment>
- <div class="card card-bordered rounded-xl border-2 px-6 py-4">
+ <div class="card card-bordered border-base-300 rounded-xl border-2 px-6 py-4">
<Markdown>
<Content />
</Markdown>
src/pages/about.astro
@@ -15,7 +15,7 @@ const { Content } = aboutMd ? await render(aboutMd) : Fragment;
---
<MainLayout title={i18n(I18nKey.about)}>
- <div class="mx-auto flex max-w-screen-xl flex-col items-center justify-center">
+ <div class="mx-auto flex max-w-(--breakpoint-xl) flex-col items-center justify-center">
<div class="hero my-4 w-5/6 md:w-2/3">
<div class="hero-content flex-col-reverse md:flex-row">
<div class="mr-auto flex flex-col">
src/plugins/remark-excerpt.js
@@ -1,16 +1,16 @@
-import { toString } from 'mdast-util-to-string'
+import { toString } from 'mdast-util-to-string';
/* Use the post's first paragraph as the excerpt */
export function remarkExcerpt() {
return (tree, { data }) => {
- let excerpt = ''
+ let excerpt = '';
for (let node of tree.children) {
if (node.type !== 'paragraph') {
- continue
+ continue;
}
- excerpt = toString(node)
- break
+ excerpt = toString(node);
+ break;
}
- data.astro.frontmatter.excerpt = excerpt
- }
+ data.astro.frontmatter.excerpt = excerpt;
+ };
}
src/styles/global.css
@@ -0,0 +1,46 @@
+@import 'tailwindcss';
+
+@plugin 'daisyui' {
+ themes: light --default dark --prefersdark;
+}
+
+@plugin 'daisyui/theme' {
+ name: 'light';
+ default: false;
+
+ --color-primary: #bc4d2e;
+ --color-primary-content: #fefedb;
+ --color-secondary: #efbf89;
+ --color-secondary-content: #111;
+ --color-accent: #742c22;
+ --color-accent-content: #fff;
+ --color-base-100: #fffffd;
+ --color-base-200: #f6e7d2;
+ --color-base-300: #e6c9ac;
+ --color-base-content: #111;
+}
+
+@plugin 'daisyui/theme' {
+ name: dark;
+
+ --color-primary: #88b7dc;
+ --color-primary-content: #fff;
+ --color-secondary: #c47890;
+ --color-secondary-content: #fff;
+ --color-accent: #a343b0;
+ --color-accent-content: #fff;
+ --color-base-100: #272a3c;
+ --color-base-200: #18192a;
+ --color-base-300: #11121f;
+ --color-base-content: #eee;
+}
+
+@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] * ));
+
+@theme {
+ --tracking-extra-wide: 0.25em;
+}
+
+html {
+ scroll-behavior: smooth;
+}
src/styles/globals.scss
@@ -1,11 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-:root {
- font-size: 17px;
-}
-
-html {
- scroll-behavior: smooth;
-}
src/styles/markdown.scss → src/styles/markdown.css
@@ -1,7 +1,7 @@
-@use './globals.scss' as global;
+@reference './global.css';
article {
- // 标题通用样式
+ /* 标题通用样式 */
h1,
h2,
h3,
@@ -18,7 +18,7 @@ article {
padding: 0 0.5rem;
opacity: 0;
text-decoration: none;
- color: theme('colors.primary');
+ color: var(--color-primary);
transition: opacity 0.2s ease-in-out;
}
@@ -29,7 +29,7 @@ article {
}
}
- // 各级标题特殊样式
+ /* 各级标题特殊样式 */
h1 {
@apply text-2xl;
}
@@ -47,7 +47,7 @@ article {
@apply text-base;
}
- // 基础文本元素
+ /* 基础文本元素 */
p {
margin: 0.5rem 0;
}
@@ -61,7 +61,7 @@ article {
}
}
- // 媒体元素
+ /* 媒体元素 */
img {
position: relative;
margin: 1rem auto;
@@ -76,7 +76,7 @@ article {
border: 1px dashed;
}
- // 列表样式
+ /* 列表样式 */
ul,
ol {
margin-top: 0.5rem;
@@ -147,13 +147,13 @@ article {
position: absolute;
font-size: 0.75em;
line-height: 0.75em;
- color: theme('colors.primary-content');
+ color: var(--colors-primary-content);
}
}
}
}
- // 代码样式
+ /* 代码样式 */
pre {
padding: 0.5rem;
counter-reset: line;
@@ -190,7 +190,7 @@ article {
code:not(pre code) {
padding: 0 0.25rem;
- @apply rounded-md bg-primary/10 text-primary;
+ @apply bg-primary/10 text-primary rounded-md;
}
.astro-code,
@@ -212,14 +212,14 @@ article {
}
}
- // 引用块样式
+ /* 引用块样式 */
blockquote {
padding: 0.25rem 0.25rem 0.25rem 0.75rem;
- @apply my-2 rounded-sm border-l-4 border-primary bg-primary/10;
+ @apply border-primary bg-primary/10 my-2 rounded-sm border-l-4;
}
- // GitHub Alert 样式
+ /* GitHub Alert 样式 */
.admonition {
padding: 0.25rem 0.25rem 0.25rem 0.75rem;
@@ -229,7 +229,7 @@ article {
font-weight: bold;
}
- &-note {
+ &.admonition-note {
@apply border-info bg-info/10;
.admonition-title {
@@ -237,7 +237,7 @@ article {
}
}
- &-tip {
+ &.admonition-tip {
@apply border-success bg-success/10;
.admonition-title {
@@ -245,7 +245,7 @@ article {
}
}
- &-important {
+ &.admonition-important {
@apply border-accent bg-accent/10;
.admonition-title {
@@ -253,7 +253,7 @@ article {
}
}
- &-warning {
+ &.admonition-warning {
@apply border-warning bg-warning/10;
.admonition-title {
@@ -261,7 +261,7 @@ article {
}
}
- &-caution {
+ &.admonition-caution {
@apply border-error bg-error/10;
.admonition-title {
@@ -270,12 +270,12 @@ article {
}
}
- // 折叠块样式
+ /* 折叠块样式 */
details {
- @apply w-full overflow-hidden rounded-xl border-2 border-base-300 duration-300;
+ @apply border-base-300 w-full overflow-hidden rounded-xl border-2 duration-300;
summary {
- @apply w-full px-3 py-1 text-start text-2xl duration-300 hover:bg-primary/50;
+ @apply hover:bg-primary/50 w-full px-3 py-1 text-start text-2xl duration-300;
&::marker {
margin-right: 1.5rem;
@@ -289,20 +289,20 @@ article {
}
}
- // 表格样式
+ /* 表格样式 */
table {
@apply relative w-full text-left text-sm;
:where(thead tr, tbody tr:not(:last-child), tbody tr:first-child:last-child) {
- @apply border-b-2 border-b-base-200;
+ @apply border-b-base-200 border-b-2;
}
:where(tfoot) {
- @apply border-t-2 border-t-base-200;
+ @apply border-t-base-200 border-t-2;
}
:where(thead, tfoot) {
- @apply whitespace-nowrap bg-base-300/15 text-xs font-bold text-base-content/90;
+ @apply bg-base-300/15 text-base-content/90 text-xs font-bold whitespace-nowrap;
}
:where(th, td) {
@@ -311,7 +311,7 @@ article {
}
}
- // 数学样式
+ /* 数学样式 */
mjx-container[display='true'] {
overflow: auto;
}
src/styles/twikoo.scss → src/styles/twikoo.css
@@ -1,12 +1,17 @@
/* stylelint-disable no-descending-specificity */
/* stylelint-disable selector-class-pattern */
-
-@use './globals.scss' as global;
+@reference './global.css';
.twikoo {
@apply relative flex h-fit w-full flex-col items-center;
}
+input,
+textarea,
+select {
+ border: none;
+}
+
.tk-comments {
@apply w-full;
@@ -18,7 +23,7 @@
@apply flex w-full flex-col gap-2;
}
- // 回复框样式
+ /* 回复框样式 */
.tk-submit {
@apply relative w-full;
@@ -26,17 +31,17 @@
display: none;
}
- // 输入框部分样式
+ /* 输入框部分样式 */
.tk-col {
@apply flex-col-reverse;
}
- // 文本框输入样式
+ /* 文本框输入样式 */
.el-textarea {
- @apply relative w-full overflow-hidden rounded-xl border-2 border-base-300 pb-9;
+ @apply border-base-300 relative w-full overflow-hidden rounded-xl border-2 pb-9;
textarea {
- @apply w-full bg-base-200/50 p-4;
+ @apply bg-base-200/50 w-full p-4;
resize: none;
@@ -50,11 +55,11 @@
}
.el-input__count {
- @apply absolute bottom-2 right-10 text-sm text-base-content/50;
+ @apply text-base-content/50 absolute right-10 bottom-2 text-sm;
}
}
- // 个人信息输入框样式
+ /* 个人信息输入框样式 */
.tk-meta-input {
@apply flex w-[calc(100%-3.5rem)] flex-col items-center gap-2 md:w-[calc(100%-6.75rem)] md:flex-row;
}
@@ -71,20 +76,20 @@
}
button {
- @apply absolute border-base-300 bg-primary py-[0.95rem] md:py-[0.3rem];
+ @apply border-base-300 bg-primary absolute py-[0.95rem] md:py-[0.3rem];
&.tk-preview {
- @apply bottom-[3.7rem] right-0 md:bottom-0 md:right-[3.35rem];
+ @apply right-0 bottom-[3.7rem] md:right-[3.35rem] md:bottom-0;
}
&.tk-send {
- @apply bottom-0 right-0;
+ @apply right-0 bottom-0;
}
}
}
.__markdown {
- @apply absolute bottom-[7.75rem] right-3 md:bottom-[2.75rem];
+ @apply absolute right-3 bottom-[7.75rem] md:bottom-[2.75rem];
}
&:has(.tk-cancel) {
@@ -100,20 +105,20 @@
}
&.tk-cancel {
- @apply bottom-[2.4rem] right-0 bg-error text-error-content md:bottom-0 md:right-[6.7rem];
+ @apply bg-error text-error-content right-0 bottom-[2.4rem] md:right-[6.7rem] md:bottom-0;
}
}
}
.tk-preview-container {
- @apply mt-2 w-full rounded-xl border-2 border-base-300 bg-base-100 p-2;
+ @apply border-base-300 bg-base-100 mt-2 w-full rounded-xl border-2 p-2;
}
}
- // 表情框样式
+ /* 表情框样式 */
.OwO-body {
/* stylelint-disable-next-line scss/operator-no-unspaced */
- @apply absolute -left-3 top-9 z-20 hidden w-[calc(100vw-3rem)] max-w-[30rem] rounded-xl border-2 border-base-300 bg-base-200/50 duration-300;
+ @apply border-base-300 bg-base-200/50 absolute top-9 -left-3 z-20 hidden w-[calc(100vw-3rem)] max-w-[30rem] rounded-xl border-2 duration-300;
}
.OwO-open .OwO-body {
@@ -141,10 +146,10 @@
}
.OwO-packages {
- @apply flex flex-wrap items-center text-nowrap px-4;
+ @apply flex flex-wrap items-center px-4 text-nowrap;
> li {
- @apply flex h-8 cursor-pointer items-center px-3 text-center duration-300 hover:bg-primary/50;
+ @apply hover:bg-primary/50 flex h-8 cursor-pointer items-center px-3 text-center duration-300;
&.OwO-package-active {
@apply bg-primary/50;
@@ -153,7 +158,7 @@
}
.tk-comments-container {
- // 评论整体样式
+ /* 评论整体样式 */
@apply mt-4 flex w-full flex-col gap-4;
.tk-comments-title {
@@ -173,7 +178,7 @@
}
> .tk-comment {
- @apply p-4 max-md:rounded-xl max-md:border-2 max-md:border-base-300 max-md:bg-base-200/50;
+ @apply max-md:border-base-300 max-md:bg-base-200/50 p-4 max-md:rounded-xl max-md:border-2;
> .tk-avatar {
@apply top-3;
@@ -181,16 +186,16 @@
}
.tk-replies {
- @apply ml-6 mt-4 flex flex-col gap-2;
+ @apply mt-4 ml-6 flex flex-col gap-2;
&:not(.tk-replies-expand) {
@apply max-h-32 overflow-y-hidden;
}
}
- // 详细样式
+ /* 详细样式 */
.tk-avatar {
- @apply absolute top-0 h-8 min-h-8 w-8 min-w-8 overflow-hidden rounded-full border-2 border-base-300;
+ @apply border-base-300 absolute top-0 h-8 min-h-8 w-8 min-w-8 overflow-hidden rounded-full border-2;
}
.tk-main > .tk-row {
@@ -199,7 +204,7 @@
.tk-meta {
a {
- @apply duration-300 hover:text-primary;
+ @apply hover:text-primary duration-300;
}
small {
@@ -211,14 +216,14 @@
}
}
- // 评论操作样式
+ /* 评论操作样式 */
.tk-main:not(:has(.tk-replies:hover)):hover > .tk-row .tk-meta .tk-actions {
@apply opacity-100;
}
.tk-action {
.tk-action-link {
- @apply relative flex items-center justify-center rounded-xl border-2 border-base-300 px-2 py-1 text-center duration-300;
+ @apply border-base-300 relative flex items-center justify-center rounded-xl border-2 px-2 py-1 text-center duration-300;
.tk-action-icon-solid {
@apply absolute left-2 opacity-0 duration-300;
@@ -254,7 +259,7 @@
@apply flex flex-row gap-3;
.tk-extra {
- @apply flex flex-row items-center justify-center gap-2 rounded-md border-2 border-base-300 p-1 text-center text-xs text-base-content/50;
+ @apply border-base-300 text-base-content/50 flex flex-row items-center justify-center gap-2 rounded-md border-2 p-1 text-center text-xs;
}
.tk-icon {
@@ -263,8 +268,8 @@
}
.tk-replies .tk-content > span:first-child {
- // 回复提示(回复:xxx)样式
- @apply text-xs text-base-content/50;
+ /* 回复提示(回复:xxx)样式 */
+ @apply text-base-content/50 text-xs;
}
.tk-expand-wrap,
@@ -273,25 +278,25 @@
}
.tk-expand {
- @apply w-full cursor-pointer rounded-md bg-base-200/50 py-1 text-sm duration-300 hover:bg-primary/50;
+ @apply bg-base-200/50 hover:bg-primary/50 w-full cursor-pointer rounded-md py-1 text-sm duration-300;
}
}
- // 图标样式
+ /* 图标样式 */
.tk-submit-action-icon {
- @apply inline-block max-h-6 min-h-6 min-w-6 max-w-6 cursor-pointer fill-primary;
+ @apply fill-primary inline-block max-h-6 min-h-6 max-w-6 min-w-6 cursor-pointer;
}
.tk-action-icon {
- @apply inline-block max-h-5 min-h-5 min-w-5 max-w-5 overflow-clip fill-primary;
+ @apply fill-primary inline-block max-h-5 min-h-5 max-w-5 min-w-5 overflow-clip;
}
.tk-icon {
- @apply inline-block max-h-4 min-h-4 min-w-4 max-w-4 overflow-clip fill-primary;
+ @apply fill-primary inline-block max-h-4 min-h-4 max-w-4 min-w-4 overflow-clip;
}
.tk-tag {
- @apply rounded-lg border-2 border-base-300 p-1 text-xs;
+ @apply border-base-300 rounded-lg border-2 p-1 text-xs;
}
}
@@ -314,7 +319,11 @@
@apply relative flex h-full w-full items-center justify-center text-center;
.tk-admin-close {
- @apply absolute right-2 top-[0.65rem] z-50 h-8 w-8 fill-primary;
+ @apply fill-primary absolute top-[0.65rem] right-2 z-50 h-4 w-4;
+
+ @variant md {
+ @apply top-4 right-3 h-8 w-8;
+ }
}
> div {
@@ -334,26 +343,26 @@
@apply h-full w-full overflow-y-scroll;
.tk-panel-title {
- @apply left-0 top-0 z-40 flex w-full flex-row items-center justify-between p-4;
+ @apply top-0 left-0 z-40 flex w-full flex-row items-center justify-between p-4;
- // 管理面板标题
+ /* 管理面板标题 */
div {
@apply text-xl font-bold;
}
a {
- @apply mx-6 rounded-xl border-2 border-base-300 bg-base-200/50 px-3 py-1 text-xs duration-300 hover:bg-primary;
+ @apply border-base-300 bg-base-200/50 hover:bg-primary mx-6 rounded-xl border-2 px-3 py-1 text-xs duration-300;
}
}
.tk-tabs {
- @apply flex flex-row items-center justify-between border-b-2 border-base-300 px-4 text-center text-lg;
+ @apply border-base-300 flex flex-row items-center justify-between border-b-2 px-4 text-center text-lg;
.tk-tab {
- @apply w-full cursor-pointer py-1 duration-300 hover:bg-primary;
+ @apply hover:bg-primary w-full min-w-fit cursor-pointer py-1 duration-300;
&.__active {
- @apply border-b-2 border-primary;
+ @apply border-primary border-b-2;
}
}
}
@@ -366,7 +375,7 @@
}
}
- // 评论管理样式
+ /* 评论管理样式 */
.tk-admin-comment {
@apply p-4;
}
@@ -378,7 +387,7 @@
@apply w-full;
input {
- @apply w-full rounded-xl border-2 border-base-300 bg-base-200/50 px-2 py-1;
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border-2 px-2 py-1;
&:focus {
outline: none;
@@ -387,7 +396,7 @@
}
select {
- @apply w-1/4 rounded-xl border-2 border-base-300 bg-base-200/50 p-2;
+ @apply border-base-300 bg-base-200/50 w-1/4 rounded-xl border-2 p-2;
}
}
@@ -396,23 +405,23 @@
}
.tk-admin-comment-item {
- @apply border-b-2 border-base-300 py-1;
+ @apply border-base-300 border-b-2 py-1;
}
.tk-admin-comment-meta {
@apply flex flex-row flex-wrap items-center gap-2 text-start;
.tk-avatar {
- @apply h-8 w-8 overflow-hidden rounded-full border-2 border-base-300;
+ @apply border-base-300 h-8 w-8 overflow-hidden rounded-full border-2;
}
a {
- @apply duration-300 hover:text-primary;
+ @apply hover:text-primary duration-300;
}
span:last-child,
.tk-time {
- @apply text-sm text-base-content/50;
+ @apply text-base-content/50 text-sm;
}
}
@@ -424,7 +433,7 @@
}
input {
- @apply w-16 rounded-xl border-2 border-base-300 bg-base-200/50 px-2 py-1;
+ @apply border-base-300 bg-base-200/50 w-16 rounded-xl border-2 px-2 py-1;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
@@ -442,14 +451,14 @@
}
.tk-pagination-pager {
- @apply cursor-pointer rounded-md px-2 py-1 hover:bg-primary;
+ @apply hover:bg-primary cursor-pointer rounded-md px-2 py-1;
&.__current {
@apply bg-primary;
}
}
- // 配置管理样式
+ /* 配置管理样式 */
.tk-admin-config {
@apply p-4;
}
@@ -459,10 +468,10 @@
}
details {
- @apply w-full overflow-hidden rounded-xl border-2 border-base-300 duration-300;
+ @apply border-base-300 w-full overflow-hidden rounded-xl border-2 duration-300;
summary {
- @apply w-full px-3 py-1 text-start text-2xl duration-300 hover:bg-primary/50;
+ @apply hover:bg-primary/50 w-full px-3 py-1 text-start text-2xl duration-300;
&::marker {
margin-right: 1.5rem;
@@ -486,7 +495,7 @@
}
input {
- @apply w-full rounded-xl border-2 border-base-300 bg-base-200/50 px-2 py-1;
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border-2 px-2 py-1;
&:focus {
outline: none;
@@ -494,11 +503,11 @@
}
.tk-admin-config-desc {
- @apply whitespace-pre-wrap text-start text-sm text-base-content/50;
+ @apply text-base-content/50 text-start text-sm whitespace-pre-wrap;
}
}
- // 导入样式
+ /* 导入样式 */
.tk-admin-import {
@apply flex flex-col items-start gap-4 p-4;
@@ -507,11 +516,11 @@
}
select {
- @apply w-full rounded-xl border-2 border-base-300 bg-base-200/50 p-2;
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border-2 p-2;
}
input {
- @apply w-full rounded-xl border-2 border-base-300 bg-base-200/50 px-2 py-1;
+ @apply border-base-300 bg-base-200/50 w-full rounded-xl border-2 px-2 py-1;
&:focus {
outline: none;
@@ -522,7 +531,7 @@
@apply h-full w-full;
textarea {
- @apply h-full w-full rounded-xl border-2 border-base-300 bg-base-200/50 px-2 py-1;
+ @apply border-base-300 bg-base-200/50 h-full w-full rounded-xl border-2 px-2 py-1;
&:focus {
outline: none;
@@ -531,7 +540,7 @@
}
}
- // 导出样式
+ /* 导出样式 */
.tk-admin-export {
@apply p-4;
}
@@ -539,10 +548,10 @@
}
.el-input-group {
- @apply flex w-full flex-row items-center overflow-hidden rounded-xl border-2 border-base-300 bg-base-200/50 text-sm;
+ @apply border-base-300 bg-base-200/50 flex w-full flex-row items-center overflow-hidden rounded-xl border-2 text-sm;
div {
- @apply w-fit whitespace-nowrap bg-primary/50 px-2 py-1;
+ @apply bg-primary/50 w-fit px-2 py-1 whitespace-nowrap;
}
input {
@@ -559,7 +568,7 @@
}
.el-button {
- @apply text-nowrap rounded-xl border-2 border-base-300 bg-primary px-2 py-1 text-center text-sm duration-300;
+ @apply border-base-300 bg-primary rounded-xl border-2 px-2 py-1 text-center text-sm text-nowrap duration-300;
&:not(.is-disabled) {
@apply hover:scale-105 hover:brightness-110 active:scale-95 active:brightness-90;
@@ -570,10 +579,10 @@
}
}
-// Markdown 样式
+/* Markdown 样式 */
.tk-content,
.tk-preview-container {
- // 标题通用样式
+ /* 标题通用样式 */
h1,
h2,
h3,
@@ -586,7 +595,7 @@
font-weight: bold;
}
- // 基础文本元素
+ /* 基础文本元素 */
p {
margin: 0.5rem 0;
}
@@ -600,16 +609,16 @@
}
}
- // 代码样式
+ /* 代码样式 */
.code-toolbar {
@apply relative w-full;
.toolbar {
- @apply absolute right-3 top-1 flex flex-row-reverse items-center justify-between gap-4 text-xs;
+ @apply absolute top-1 right-3 flex flex-row-reverse items-center justify-between gap-4 text-xs;
}
.copy-to-clipboard-button {
- @apply rounded-md border-2 border-base-300 bg-primary px-2 py-1 opacity-0 duration-300;
+ @apply border-base-300 bg-primary rounded-md border-2 px-2 py-1 opacity-0 duration-300;
}
&:hover .copy-to-clipboard-button {
@@ -624,10 +633,10 @@
code:not(pre code) {
padding: 0 0.25rem;
- @apply rounded-md bg-primary/10 text-primary;
+ @apply bg-primary/10 text-primary rounded-md;
}
- // 媒体元素
+ /* 媒体元素 */
img:not(.tk-owo-emotion) {
position: relative;
margin: 1rem auto;
@@ -641,25 +650,25 @@
@apply inline-block h-7 self-baseline;
}
- // 分割线样式
+ /* 分割线样式 */
hr {
margin: 1.5rem 0.25rem;
border: 1px dashed;
}
- // 引用块样式
+ /* 引用块样式 */
blockquote {
padding: 0.25rem 0.25rem 0.25rem 0.75rem;
- @apply my-2 rounded-sm border-l-4 border-primary bg-primary/10;
+ @apply border-primary bg-primary/10 my-2 rounded-sm border-l-4;
}
- // 折叠块样式
+ /* 折叠块样式 */
details {
- @apply w-full overflow-hidden rounded-xl border-2 border-base-300 duration-300;
+ @apply border-base-300 w-full overflow-hidden rounded-xl border-2 duration-300;
summary {
- @apply w-full px-3 py-1 text-start text-2xl duration-300 hover:bg-primary/50;
+ @apply hover:bg-primary/50 w-full px-3 py-1 text-start text-2xl duration-300;
&::marker {
margin-right: 1.5rem;
astro.config.mjs
@@ -5,7 +5,7 @@ import { remarkExcerpt } from './src/plugins/remark-excerpt';
import { remarkReadingTime } from './src/plugins/remark-reading-time.mjs';
import { rehypeHeadingIds } from '@astrojs/markdown-remark';
import sitemap from '@astrojs/sitemap';
-import tailwind from '@astrojs/tailwind';
+import tailwindcss from '@tailwindcss/vite';
import icon from 'astro-icon';
import pagefind from 'astro-pagefind';
import { defineConfig } from 'astro/config';
@@ -21,7 +21,6 @@ export default defineConfig({
output: 'static',
trailingSlash: 'ignore',
integrations: [
- tailwind({ nesting: true, applyBaseStyles: false }),
icon(),
sitemap({ filter: (page) => !page.includes('/archives/') && !page.includes('/about/') }),
pagefind(),
@@ -76,4 +75,7 @@ export default defineConfig({
rehypeWrapTables,
],
},
+ vite: {
+ plugins: [tailwindcss()],
+ },
});
package.json
@@ -16,15 +16,15 @@
"@astrojs/markdown-remark": "^6.1.0",
"@astrojs/rss": "^4.0.11",
"@astrojs/sitemap": "^3.2.1",
- "@astrojs/tailwind": "^5.1.5",
"@iconify-json/material-symbols": "^1.2.14",
"@iconify-json/mdi": "^1.2.3",
+ "@tailwindcss/vite": "^4.0.4",
"astro": "^5.2.5",
"astro-compress": "2.3.5",
"astro-icon": "^1.1.5",
"astro-pagefind": "^1.8.0",
"autoprefixer": "^10.4.20",
- "daisyui": "^4.12.23",
+ "daisyui": "5.0.0-beta.7",
"mdast-util-to-string": "^4.0.0",
"postcss-load-config": "^6.0.1",
"reading-time": "^1.5.0",
@@ -32,9 +32,8 @@
"rehype-mathjax": "^6.0.0",
"remark-github-beta-blockquote-admonitions": "^3.1.1",
"remark-math": "^6.0.0",
- "sass": "^1.84.0",
"sharp": "^0.33.5",
- "tailwindcss": "^3.4.17",
+ "tailwindcss": "^4.0.4",
"typescript": "^5.7.3",
"unist-util-visit": "^5.0.0"
},
@@ -55,7 +54,6 @@
"prettier-plugin-tailwindcss": "^0.6.11",
"stylelint": "^16.14.1",
"stylelint-config-html": "^1.1.0",
- "stylelint-config-standard-scss": "^14.0.0",
"typescript-eslint": "^8.23.0"
}
}
\ No newline at end of file
postcss.config.mjs
@@ -1,12 +0,0 @@
-import postcssImport from 'postcss-import';
-import tailwindcss from 'tailwindcss';
-import postcssNesting from 'tailwindcss/nesting/index.js';
-
-/** @type {import('postcss-load-config').Config} */
-export default {
- plugins: {
- 'postcss-import': postcssImport, // to combine multiple css files
- 'tailwindcss/nesting': postcssNesting,
- tailwindcss: tailwindcss,
- },
-};
stylelint.config.mjs
@@ -1,16 +1,22 @@
/** @type {import('stylelint').Config} */
export default {
- extends: ['stylelint-config-standard-scss', 'stylelint-config-html/astro'],
+ extends: ['stylelint-config-html/astro'],
rules: {
- 'scss/at-rule-no-unknown': [
+ 'at-rule-no-unknown': [
true,
{
ignoreAtRules: [
// Tailwind CSS
- 'tailwind',
+ 'theme',
+ 'source',
+ 'utility',
+ 'variant',
+ 'custom-variant',
'apply',
'layer',
'config',
+ 'plugin',
+ 'reference',
],
},
],
tailwind.config.mjs
@@ -1,46 +0,0 @@
-import daisyui from 'daisyui';
-
-/** @type {import('tailwindcss').Config} */
-export default {
- content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
- theme: {
- extend: {
- letterSpacing: {
- 'extra-wide': '0.25em',
- },
- },
- },
- darkMode: ['selector', '[data-theme="dark"]'],
- plugins: [daisyui],
- daisyui: {
- base: false,
- themes: [
- {
- light: {
- primary: '#BC4D2E',
- 'primary-content': '#FEFEDB',
- secondary: '#EFBF89',
- 'secondary-content': '#111',
- accent: '#742C22',
- 'accent-content': '#FFF',
- 'base-100': '#FFFFFD',
- 'base-200': '#F6E7D2',
- 'base-300': '#E6C9AC',
- 'base-content': '#111',
- },
- dark: {
- primary: '#88B7DC',
- 'primary-content': '#FFF',
- secondary: '#C47890',
- 'secondary-content': '#FFF',
- accent: '#A343B0',
- 'accent-content': '#FFF',
- 'base-100': '#272A3C',
- 'base-200': '#18192A',
- 'base-300': '#11121F',
- 'base-content': '#EEE',
- },
- },
- ],
- },
-};