feat(portal-shell): v2.0 P0 shadcn standardization + security + streaming + error handling
- shadcn/ui 标准化:废弃纸感令牌,统一 bg-background/text-foreground 等 - Tailwind v4 + @theme inline,移除 tailwind.config.js - React 19 use() + Suspense 流式渲染,首屏骨架秒出 - 三级错误边界:Route → Section → Widget 层层兜底 - 错误上报:useErrorReport → sendBeacon → /api/log mock 端点 - 三层安全边界:L1 角色门禁 / L2 权限点门禁 / L3 数据范围 - 权限位图 base36 压缩:67 权限点 → ~14 字符,JWT 体积减少 ≥ 99% - notify 统一 Toast 封装,禁止业务直接 import sonner - PluginBoundary 替代 PluginLoader(错误边界 + Suspense + Skeleton 三件套) 验证:typecheck 0 错误 / lint 0 错误 / build 6 路由生成成功
This commit is contained in:
@@ -1,55 +1,62 @@
|
||||
/**
|
||||
* portal-shell 全局样式
|
||||
* portal-shell 全局样式(Tailwind v4 + shadcn 标准令牌)
|
||||
*
|
||||
* 引入 @edu/ui-tokens 三层设计令牌(primitive → semantic → tailwind-theme)
|
||||
* 业务代码使用 Tailwind 类(bg-background / text-foreground / bg-card ...)或 hsl(var(--*)) 引用。
|
||||
*
|
||||
* 禁止规则(ESLint + project_rules §3.10):
|
||||
* - 禁止 #hex 字面量(用 hsl(var(--*)) 或 Tailwind bg-* 类)
|
||||
* - 禁止字体名字面量(用 var(--font-family-*))
|
||||
* - 禁止 font-size: Npx(用 var(--font-size-*) 或 Tailwind text-* 类)
|
||||
*
|
||||
* 对齐:CICD 项目 src/app/globals.css
|
||||
*/
|
||||
|
||||
@import "tailwindcss";
|
||||
@import "@edu/ui-tokens/all.css";
|
||||
@plugin "tailwindcss-animate";
|
||||
@plugin "@tailwindcss/typography";
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
/* 排除非源码目录,防止文档中的 Tailwind 任意值语法字符串被误识别为类名 */
|
||||
@source not "../../docs";
|
||||
@source not "../../scripts";
|
||||
@source not "../../tests";
|
||||
|
||||
/* Reduced Motion */
|
||||
@layer base {
|
||||
html,
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Base Styles */
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
background: var(--bg-paper);
|
||||
color: var(--color-ink);
|
||||
@apply bg-background text-foreground;
|
||||
font-family: var(--font-family-sans);
|
||||
font-feature-settings: "rlig" 1, "calt" 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--font-family-serif);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
letter-spacing: var(--letter-spacing-tight);
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
/* 纸感分隔线 */
|
||||
.rule {
|
||||
border-top: 1px solid var(--color-rule);
|
||||
}
|
||||
|
||||
.rule-thin {
|
||||
border-top: 2px solid var(--color-rule);
|
||||
}
|
||||
|
||||
/* 左侧竖线标记 */
|
||||
.mark-left {
|
||||
border-left: 2px solid var(--color-rule);
|
||||
padding-left: var(--space-md);
|
||||
font-family: var(--font-family-sans);
|
||||
font-weight: var(--weight-semibold);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user