Files
cc-switch/tailwind.config.cjs
T
Jason 40aa2864a2 feat(ui): move to a sidebar shell with global pages and grouped settings
Replace the header toolbar and icon-only app switcher with the v7 shell:

- Sidebar (200px, collapses to a 72px icon rail under 960px, Cmd/Ctrl+\
  toggles and remembers the choice): the app list with mode tags and
  "needs attention" dots, then Usage (today's cost), Accounts (re-login
  dot), MCP, Skills, Prompts and Sessions pinned to the bottom, and an
  Apps / Settings footer. Settings swaps the sidebar for its own
  directory.
- Every screen gets a 52px page header; Linux in-app window controls
  sit at its far right. macOS traffic lights move down to centre in the
  44px sidebar top bar.
- Usage, Accounts, MCP, Skills, Prompts (with an app picker) and
  Sessions become global pages instead of settings tabs or per-app
  toolbar buttons. OpenClaw and Hermes switch to their own pages with a
  segmented control; OpenClaw's env, tools and agents merge into one
  Config page.
- New Apps page: per-app install / upgrade with path and install
  source, batch upgrade, conflict details, manual commands, and the
  "show in sidebar" switch that used to live in settings. Tool
  management moves out of About into a shared hook; a read-only
  list_tool_installations command feeds the page so it does not share
  calls with the upgrade preflight.
- Settings regroup into General, App config, Local routing, Network,
  Data and About, using row/card layout. Path settings save per
  section; switches still save immediately. Skills storage and sync
  move to a sheet on the Skills page.
- New opt-in "check app updates on startup" setting (off by default):
  when on, a background check puts a neutral dot on Apps.
- Switch adopts the v7 track and action colour; env-conflict banner
  joins the page flow instead of overlaying the header.

The old route / Stack / failover toggles stay in the provider page
header until the mode tabs land.
2026-10-03 23:28:58 +08:00

267 lines
7.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/index.html", "./src/**/*.{js,ts,jsx,tsx}"],
darkMode: ["selector", ".dark"],
theme: {
extend: {
// v7 禁用态统一 0.45(tokens.css 的 [aria-disabled] 规则)
opacity: { 45: "0.45" },
colors: {
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
// v7 设计 token(见 src/index.css)。纯 var() 颜色不支持 /50 这类透明度修饰。
app: "var(--bg-app)",
sidebar: "var(--bg-sidebar)",
subtle: "var(--bg-subtle)",
selected: "var(--bg-selected)",
surface: "var(--bg-card)",
"border-strong": "var(--border-strong)",
fg: {
1: "var(--text-1)",
2: "var(--text-2)",
3: "var(--text-3)",
},
action: {
DEFAULT: "var(--action-bg)",
fg: "var(--action-fg)",
hover: "var(--action-hover)",
},
inverse: {
DEFAULT: "var(--inverse-bg)",
fg: "var(--inverse-fg)",
hover: "var(--inverse-hover)",
},
overlay: "var(--overlay)",
"control-off": "var(--control-off)",
direct: {
DEFAULT: "var(--direct-fill)",
text: "var(--direct-text)",
soft: "var(--direct-soft)",
solid: "var(--direct-solid)",
on: "var(--direct-on)",
},
route: {
DEFAULT: "var(--route-fill)",
text: "var(--route-text)",
soft: "var(--route-soft)",
solid: "var(--route-solid)",
on: "var(--route-on)",
},
stack: {
DEFAULT: "var(--stack-fill)",
text: "var(--stack-text)",
soft: "var(--stack-soft)",
solid: "var(--stack-solid)",
on: "var(--stack-on)",
},
success: {
DEFAULT: "var(--success)",
text: "var(--success-text)",
soft: "var(--success-soft)",
},
warning: {
DEFAULT: "var(--warning)",
text: "var(--warning-text)",
soft: "var(--warning-soft)",
},
danger: {
DEFAULT: "var(--danger)",
text: "var(--danger-text)",
soft: "var(--danger-soft)",
},
chart: {
1: "var(--chart-1)",
2: "var(--chart-2)",
grid: "var(--chart-grid)",
},
blue: {
400: "#409CFF",
500: "#0A84FF",
600: "#0060DF",
},
gray: {
50: "#fafafa",
100: "#f4f4f5",
200: "#e4e4e7",
300: "#d4d4d8",
400: "#a1a1aa",
500: "#71717a",
600: "#636366",
700: "#48484A",
800: "#3A3A3C",
900: "#2C2C2E",
950: "#1C1C1E",
},
green: {
100: "#d1fae5",
500: "#10b981",
},
red: {
100: "#fee2e2",
500: "#ef4444",
},
amber: {
100: "#fef3c7",
500: "#f59e0b",
},
},
boxShadow: {
sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
// v7:分段控件凸起、卡片悬停 / 菜单、弹层 / 对话框、抽屉
"v7-sm": "var(--shadow-sm)",
"v7-md": "var(--shadow-md)",
"v7-lg": "var(--shadow-lg)",
},
borderRadius: {
sm: "0.375rem",
md: "0.5rem",
lg: "0.75rem",
xl: "0.875rem",
// v7:按钮、小控件、侧栏行 / 卡片、分段控件、输入框、弹层、通知条 / 对话框、抽屉
control: "6px",
panel: "10px",
dialog: "14px",
},
fontSize: {
// v7 字体角色(AUTHORING.md「颜色与字体」)
badge: ["11px", { lineHeight: "16px", fontWeight: "500" }],
caption: ["12px", { lineHeight: "18px" }],
body: ["13px", { lineHeight: "20px" }],
strong: ["14px", { lineHeight: "20px", fontWeight: "500" }],
section: ["15px", { lineHeight: "22px", fontWeight: "600" }],
title: ["16px", { lineHeight: "24px", fontWeight: "600" }],
page: ["18px", { lineHeight: "26px", fontWeight: "600" }],
metric: ["24px", { lineHeight: "32px", fontWeight: "600" }],
},
fontFamily: {
// 使用与之前版本保持一致的系统字体栈
sans: [
"-apple-system",
"BlinkMacSystemFont",
'"SF Pro Text"',
'"PingFang SC"',
'"Hiragino Sans GB"',
'"Segoe UI Variable Text"',
'"Segoe UI"',
'"Microsoft YaHei UI"',
'"Microsoft YaHei"',
"Roboto",
'"Helvetica Neue"',
"Arial",
"system-ui",
"sans-serif",
],
mono: [
"ui-monospace",
"SFMono-Regular",
'"SF Mono"',
"Consolas",
'"Liberation Mono"',
"Menlo",
"monospace",
],
},
animation: {
"fade-in": "fadeIn 0.5s ease-out",
"slide-up": "slideUp 0.5s ease-out",
"slide-down": "slideDown 0.3s ease-out",
"slide-in-right": "slideInRight 0.3s ease-out",
"pulse-slow": "pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite",
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
keyframes: {
fadeIn: {
"0%": {
opacity: "0",
},
"100%": {
opacity: "1",
},
},
slideUp: {
"0%": {
transform: "translateY(20px)",
opacity: "0",
},
"100%": {
transform: "translateY(0)",
opacity: "1",
},
},
slideDown: {
"0%": {
transform: "translateY(-100%)",
opacity: "0",
},
"100%": {
transform: "translateY(0)",
opacity: "1",
},
},
slideInRight: {
"0%": {
transform: "translateX(100%)",
opacity: "0",
},
"100%": {
transform: "translateX(0)",
opacity: "1",
},
},
"accordion-down": {
from: {
height: "0",
},
to: {
height: "var(--radix-accordion-content-height)",
},
},
"accordion-up": {
from: {
height: "var(--radix-accordion-content-height)",
},
to: {
height: "0",
},
},
},
},
},
plugins: [],
};