feat: 初始化全部模板

This commit is contained in:
chuan
2026-05-16 02:09:59 +08:00
Unverified
commit 0ff61974ff
22 changed files with 538 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
.gitea
.gitea-data
dist
node_modules
View File
+22
View File
@@ -0,0 +1,22 @@
# Gitea Theme Dev
用于开发 Gitea 自定义主题样式和模板覆盖的工作区。
## 技术选型
当前项目使用 Bun + TypeScript token + Lightning CSS + Preview。
样式按 `tokens -> primitives -> components -> pages` 分层聚合,主题值放在 `themes/`,模板覆盖放在 `templates/`。详细规则见 `docs/rules.md`
## 常用命令
```bash
bun install
bun run build
bun run build:min
bun run dev
bun run preview
bun run test
```
构建会生成 `dist/theme-gitea-auto.css`,并同步输出到 `.gitea/custom/public/assets/css/theme-gitea-auto.css` 供 Gitea custom 目录使用。
+53
View File
@@ -0,0 +1,53 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "gitea-theme-dev",
"devDependencies": {
"@types/bun": "latest",
"lightningcss": "^1.29.2",
"polished": "^4.3.1",
},
},
},
"packages": {
"@babel/runtime": ["@babel/runtime@7.29.2", "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.29.2.tgz", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="],
"@types/bun": ["@types/bun@1.3.14", "https://registry.npmmirror.com/@types/bun/-/bun-1.3.14.tgz", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
"@types/node": ["@types/node@25.8.0", "https://registry.npmmirror.com/@types/node/-/node-25.8.0.tgz", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ=="],
"bun-types": ["bun-types@1.3.14", "https://registry.npmmirror.com/bun-types/-/bun-types-1.3.14.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
"detect-libc": ["detect-libc@2.1.2", "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"lightningcss": ["lightningcss@1.32.0", "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.32.0.tgz", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "https://registry.npmmirror.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "https://registry.npmmirror.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
"polished": ["polished@4.3.1", "https://registry.npmmirror.com/polished/-/polished-4.3.1.tgz", { "dependencies": { "@babel/runtime": "^7.17.8" } }, "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA=="],
"undici-types": ["undici-types@7.24.6", "https://registry.npmmirror.com/undici-types/-/undici-types-7.24.6.tgz", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
}
}
+21
View File
@@ -0,0 +1,21 @@
services:
server:
image: docker.gitea.com/gitea:1.26.1
container_name: gitea-theme-dev
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__server__LANDING_PAGE=explore
- GITEA__service_0x2E_explore__DISABLE_USERS_PAGE=true
- GITEA__service_0x2E_explore__DISABLE_ORGANIZATIONS_PAGE=true
- GITEA__service_0x2E_explore__DISABLE_CODE_PAGE=true
- GITEA__ui__THEMES=gitea-auto
- GITEA__ui__DEFAULT_THEME=gitea-auto
restart: always
volumes:
- ./.gitea-data:/data
- ./.gitea/custom/public:/data/gitea/public
- ./.gitea/custom/templates:/data/gitea/templates
ports:
- "3000:3000"
- "222:22"
+69
View File
@@ -0,0 +1,69 @@
# Gitea 主题项目规则
## 项目目标
本项目用于创建 Gitea 使用的主题样式和模板覆盖。样式使用 Bun + TypeScript token + Lightning CSS + Preview 的组合:TypeScript 负责组织 token 和样式片段,Lightning CSS 负责最终 CSS 转换和压缩,Preview 用于快速查看基础效果。
## 目录职责
`themes/` 放颜色主题和主题 token,例如 `light.ts`。主题文件只定义值,不写 Gitea 选择器。
`styles/tokens/` 放最底层设计变量,例如颜色、字号、间距、圆角、阴影、动效时长。这里不应该出现具体页面选择器。
`styles/primitives/` 放全站基础控件规则,例如 `.ui.button``.ui.input``input[type="checkbox"]``.ui.dropdown``.tippy-box`。这一层可以使用 token,但不应该处理具体页面布局。
`styles/components/` 放 Gitea 可复用业务组件样式,例如顶部导航、仓库列表、热力图、动态列表、登录表单、clone 面板。它比 primitive 更具体,但还不是页面级。
`styles/pages/` 放某个页面的布局修复和局部覆盖,例如 dashboard 首页、explore 仓库页、org/create 页面、登录页布局。这里可以写具体页面选择器,但改动范围必须尽量局部。
`templates/` 放 Gitea 模板覆盖文件。模板修改应尽量保持最小化,避免把样式逻辑写进模板。
`src/` 放构建辅助代码、类型和聚合逻辑。这里不直接承载某个具体页面的样式规则。
`.gitea/` 放 Gitea custom 目录和源代码参考资源。构建产物会输出到 `.gitea/custom/public/assets/css/theme-gitea-auto.css`
`dist/` 放本地构建产物,主要用于检查和 Preview。
## 分层原则
一个规则只应该属于一个层级。按钮、输入框、下拉菜单等基础控件问题放到 `primitives/`;仓库列表、导航栏、动态流等可复用业务块放到 `components/`;只在某个页面成立的间距、布局和覆盖放到 `pages/`
低层不能依赖高层。`tokens/` 不能依赖 `primitives/``components/``pages/``primitives/` 不能依赖页面结构;`components/` 不应该修复具体页面布局。
避免重复定义颜色、阴影、圆角和间距。优先在 `themes/``styles/tokens/` 中新增 token,再在其他层使用 `var(--gt-*)`
页面级选择器必须足够具体,避免影响全站控件。例如登录页按钮间距问题应该放在登录页或登录组件范围内,不应该修改所有 `.ui.button`
## 命名规则
自定义 CSS 变量统一使用 `--gt-*` 前缀,例如 `--gt-color-accent``--gt-radius-md``--gt-space-lg`
主题名与 Gitea CSS 文件名保持一致。当前默认主题名是 `gitea-auto`,输出文件是 `theme-gitea-auto.css`
样式模块默认导出字符串常量,由 `styles/index.ts``tokens -> primitives -> components -> pages` 顺序聚合。
## 构建与预览
使用 `bun run build` 构建未压缩 CSS。
使用 `bun run build:min` 构建压缩 CSS。
使用 `bun run dev` 监听样式、主题和 src 文件变化。
使用 `bun run preview` 启动本地预览页面。
使用 `bun run test` 构建并检查必要输出是否存在。
使用 `bun run compose:up` 启动 Gitea 开发容器,使用 `bun run compose:down` 停止容器。
## 修改流程
新增视觉值时,先判断是否应该成为 token。能复用的值放到 `themes/``styles/tokens/`
修改控件外观时,优先检查 `styles/primitives/`,确保不会破坏页面级布局。
修改业务组件时,优先放到 `styles/components/`,并使用组件范围选择器约束影响面。
修改单个页面问题时,放到 `styles/pages/`,并写明页面级父选择器。
修改模板时,先确认 Gitea 原始模板结构,再把覆盖文件放入 `templates/` 或同步到 `.gitea/custom/templates/`
+23
View File
@@ -0,0 +1,23 @@
{
"name": "gitea-theme-dev",
"version": "0.1.0",
"private": true,
"type": "module",
"description": "Bun-powered custom theme workspace for Gitea.",
"scripts": {
"build": "bun scripts/build.ts",
"dev": "bun scripts/build.ts --watch",
"preview": "bun run build && bun scripts/preview.ts",
"build:min": "bun scripts/build.ts --minify",
"test": "bun run build && bun scripts/verify-theme.ts",
"compose:up": "docker compose -f compose.dev.yaml up -d",
"compose:down": "docker compose -f compose.dev.yaml down",
"compose:logs": "docker compose -f compose.dev.yaml logs -f server",
"docker:test": "bun run build && docker compose -f compose.dev.yaml up -d && bun scripts/verify-docker.ts"
},
"devDependencies": {
"@types/bun": "latest",
"lightningcss": "^1.29.2",
"polished": "^4.3.1"
}
}
+54
View File
@@ -0,0 +1,54 @@
import { mkdir, writeFile } from "node:fs/promises";
import { watch } from "node:fs";
import { dirname, join } from "node:path";
import { transform } from "lightningcss";
import { stylesheet } from "../styles/index";
const root = process.cwd();
const minify = process.argv.includes("--minify");
const watchMode = process.argv.includes("--watch");
const outputs = [
join(root, "dist", "theme-gitea-auto.css"),
join(root, ".gitea", "custom", "public", "assets", "css", "theme-gitea-auto.css"),
];
async function build() {
const result = transform({
filename: "theme-gitea-auto.css",
code: Buffer.from(stylesheet),
minify,
targets: {
chrome: 108 << 16,
firefox: 108 << 16,
safari: 16 << 16,
},
});
await Promise.all(
outputs.map(async (output) => {
await mkdir(dirname(output), { recursive: true });
await writeFile(output, result.code);
}),
);
console.log(`built ${outputs.length} css outputs`);
}
await build();
if (watchMode) {
console.log("watching styles, themes, and src");
const watchedDirs = [join(root, "styles"), join(root, "themes"), join(root, "src")];
const watchers = watchedDirs.map((dir) =>
watch(dir, { recursive: true }, async (_eventType, filename) => {
if (filename?.endsWith(".ts")) {
await build();
}
}),
);
process.on("SIGINT", () => {
watchers.forEach((watcher) => watcher.close());
process.exit(0);
});
}
+42
View File
@@ -0,0 +1,42 @@
const server = Bun.serve({
port: Number(process.env.PORT ?? 4173),
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/" || url.pathname === "/index.html") {
return new Response(
`<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/theme-gitea-auto.css">
<title>Gitea Theme Preview</title>
</head>
<body>
<main class="page-content dashboard" style="max-width: 960px; margin: 0 auto;">
<h1>Gitea Theme Preview</h1>
<p>用于快速检查 token、primitive、component 和 page 覆盖效果。</p>
<button class="ui primary button">Primary Button</button>
<button class="ui button">Default Button</button>
<div class="ui input" style="display:block; margin-top: 1rem;">
<input type="text" value="Repository search">
</div>
</main>
</body>
</html>`,
{ headers: { "content-type": "text/html; charset=utf-8" } },
);
}
if (url.pathname === "/theme-gitea-auto.css") {
return new Response(Bun.file("dist/theme-gitea-auto.css"), {
headers: { "content-type": "text/css; charset=utf-8" },
});
}
return new Response("Not Found", { status: 404 });
},
});
console.log(`preview http://localhost:${server.port}`);
+33
View File
@@ -0,0 +1,33 @@
const baseUrl = process.env.GITEA_PREVIEW_URL ?? "http://localhost:3000";
async function waitFor(url: string) {
const deadline = Date.now() + 60_000;
let lastError: unknown;
while (Date.now() < deadline) {
try {
const response = await fetch(url);
if (response.ok) {
return response;
}
lastError = new Error(`${url} returned ${response.status}`);
} catch (error) {
lastError = error;
}
await Bun.sleep(1000);
}
throw lastError;
}
const home = await waitFor(baseUrl);
const theme = await waitFor(`${baseUrl}/assets/css/theme-gitea-auto.css`);
const css = await theme.text();
if (!css.includes("--gt-color-accent")) {
throw new Error("theme css is reachable but does not contain generated tokens");
}
console.log(`docker preview verified: ${home.status} ${baseUrl}`);
+21
View File
@@ -0,0 +1,21 @@
import { existsSync } from "node:fs";
import { stat } from "node:fs/promises";
import { join } from "node:path";
const requiredOutputs = [
join(process.cwd(), "dist", "theme-gitea-auto.css"),
join(process.cwd(), ".gitea", "custom", "public", "assets", "css", "theme-gitea-auto.css"),
];
for (const output of requiredOutputs) {
if (!existsSync(output)) {
throw new Error(`missing output: ${output}`);
}
const file = await stat(output);
if (file.size === 0) {
throw new Error(`empty output: ${output}`);
}
}
console.log("theme outputs verified");
+17
View File
@@ -0,0 +1,17 @@
import type { ThemeScale, ThemeTokens } from "./theme-types";
const toKebab = (value: string) =>
value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
const scaleToVars = (group: string, scale: ThemeScale) =>
Object.entries(scale)
.map(([key, value]) => ` --gt-${group}-${toKebab(key)}: ${value};`)
.join("\n");
export const themeToRootVars = (theme: ThemeTokens) => {
const groups = Object.entries(theme)
.filter(([key]) => key !== "name")
.map(([group, scale]) => scaleToVars(group, scale as ThemeScale));
return `:root,\n.theme-${theme.name} {\n${groups.join("\n")}\n}`;
};
+11
View File
@@ -0,0 +1,11 @@
export type ThemeScale = Record<string, string>;
export interface ThemeTokens {
name: string;
color: ThemeScale;
radius: ThemeScale;
shadow: ThemeScale;
font: ThemeScale;
space: ThemeScale;
motion: ThemeScale;
}
+26
View File
@@ -0,0 +1,26 @@
export const components = `
.following.bar.light {
background: color-mix(in srgb, var(--gt-color-surface) 92%, transparent);
border-bottom: 1px solid var(--gt-color-border);
backdrop-filter: blur(14px);
}
.repository .header-wrapper,
.repository.file.list #repo-files-table {
border-radius: var(--gt-radius-lg);
border: 1px solid var(--gt-color-border);
box-shadow: var(--gt-shadow-sm);
}
.feeds .news,
.dashboard.feeds .news {
border-radius: var(--gt-radius-lg);
background: var(--gt-color-surface);
}
.user.signin .ui.form,
.user.signup .ui.form {
border-radius: var(--gt-radius-lg);
box-shadow: var(--gt-shadow-md);
}
`;
+6
View File
@@ -0,0 +1,6 @@
import { components } from "./components/index";
import { pages } from "./pages/index";
import { primitives } from "./primitives/index";
import { tokens } from "./tokens/index";
export const stylesheet = [tokens, primitives, components, pages].join("\n\n");
+22
View File
@@ -0,0 +1,22 @@
export const pages = `
.page-content.dashboard {
padding-top: var(--gt-space-lg);
}
.page-content.explore {
padding-top: var(--gt-space-xl);
}
.user.signin .page-content,
.user.signup .page-content {
min-height: calc(100vh - 8rem);
display: grid;
place-items: center;
}
.organization.new.org .page-content,
.organization.new.team .page-content {
max-width: 72rem;
margin-inline: auto;
}
`;
+51
View File
@@ -0,0 +1,51 @@
export const primitives = `
body {
color: var(--gt-color-text);
background:
radial-gradient(circle at 12% 8%, rgb(29 111 95 / 0.12), transparent 28rem),
linear-gradient(180deg, var(--gt-color-canvas), #efe6d4);
font-family: var(--gt-font-sans);
}
a {
color: var(--gt-color-accent);
}
.ui.button,
button.ui.button {
border-radius: var(--gt-radius-md);
border-color: var(--gt-color-border);
box-shadow: var(--gt-shadow-sm);
transition:
background-color var(--gt-motion-fast) ease,
border-color var(--gt-motion-fast) ease,
box-shadow var(--gt-motion-fast) ease;
}
.ui.primary.button,
.ui.green.button {
background: var(--gt-color-accent);
color: #ffffff;
}
.ui.primary.button:hover,
.ui.green.button:hover {
background: var(--gt-color-accent-hover);
}
.ui.input > input,
.ui.form input:not([type]),
.ui.form input[type="text"],
.ui.form input[type="password"],
.ui.form input[type="email"],
.ui.form textarea {
border-radius: var(--gt-radius-md);
border-color: var(--gt-color-border);
background: var(--gt-color-surface-raised);
}
.ui.dropdown,
.tippy-box {
border-radius: var(--gt-radius-md);
}
`;
+4
View File
@@ -0,0 +1,4 @@
import { themeToRootVars } from "../../src/css";
import { lightTheme } from "../../themes/light";
export const tokens = themeToRootVars(lightTheme);
View File
+1
View File
@@ -0,0 +1 @@
{{/* Intentionally empty: hide Gitea's default page footer. */}}
+46
View File
@@ -0,0 +1,46 @@
import type { ThemeTokens } from "../src/theme-types";
export const lightTheme: ThemeTokens = {
name: "gitea-auto",
color: {
canvas: "#f7f3ea",
surface: "#fffaf0",
surfaceRaised: "#ffffff",
border: "#d8cdb8",
text: "#1f2933",
textMuted: "#667085",
accent: "#1d6f5f",
accentHover: "#15574b",
danger: "#b42318",
warning: "#b54708",
success: "#027a48",
},
radius: {
sm: "6px",
md: "10px",
lg: "16px",
pill: "999px",
},
shadow: {
sm: "0 1px 2px rgb(31 41 51 / 0.08)",
md: "0 12px 30px rgb(31 41 51 / 0.12)",
},
font: {
sans: "\"IBM Plex Sans\", \"Noto Sans SC\", sans-serif",
mono: "\"IBM Plex Mono\", \"Noto Sans Mono\", monospace",
sizeSm: "0.875rem",
sizeBase: "1rem",
sizeLg: "1.125rem",
},
space: {
xs: "0.25rem",
sm: "0.5rem",
md: "1rem",
lg: "1.5rem",
xl: "2rem",
},
motion: {
fast: "120ms",
normal: "180ms",
},
};
+12
View File
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["bun"],
"strict": true,
"noEmit": true,
"skipLibCheck": true
},
"include": ["scripts/**/*.ts", "src/**/*.ts", "styles/**/*.ts", "themes/**/*.ts"]
}