init5
This commit is contained in:
573
app/assets/css/main.css
Normal file
573
app/assets/css/main.css
Normal file
@@ -0,0 +1,573 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
/* 背景图居中 */
|
||||
/* 背景图居中覆盖 - 支持自定义padding控制 */
|
||||
.bg-flex-center {
|
||||
@apply flex items-center justify-center bg-center bg-no-repeat bg-contain;
|
||||
}
|
||||
|
||||
/* 自定义样式 */
|
||||
.crud-container {
|
||||
@apply max-w-7xl mx-auto p-6;
|
||||
}
|
||||
|
||||
.crud-header {
|
||||
@apply mb-6 flex justify-between items-center;
|
||||
}
|
||||
|
||||
.crud-table {
|
||||
@apply bg-white rounded-lg shadow-sm;
|
||||
}
|
||||
|
||||
.crud-form {
|
||||
@apply bg-white p-6 rounded-lg shadow-sm;
|
||||
}
|
||||
|
||||
/*
|
||||
九宫格(9-slice)图片边框 Utility
|
||||
|
||||
目标:
|
||||
- 传入一张九宫格图片的 URL,保持4个角按上下左右的参数不拉伸
|
||||
- 中间和4个角中间的区域拉伸
|
||||
- 支持自定义重复模式、填充行为、边框扩展等高级选项
|
||||
|
||||
核心参数:
|
||||
- 图片URL:--nine-src
|
||||
- 切片参数:--nine-top/right/bottom/left(基于图片实际像素)
|
||||
- 快速设置:--nine-all(一次性设置四个角相等)
|
||||
- 重复模式:--nine-repeat(stretch/repeat/round/space)
|
||||
- 填充控制:--nine-fill(1 填充/0 不填充)
|
||||
- 边框扩展:--nine-outset(向外扩展距离)
|
||||
- 边框宽度:--nine-width(边框图像宽度)
|
||||
|
||||
使用说明(Tailwind 原子类 + CSS 变量):
|
||||
1) 在元素上添加基础类:`nine-slice`
|
||||
2) 通过 Tailwind 任意值设置 CSS 变量:
|
||||
- 设置图片 URL:`[--nine-src:url('/public/images/frame-9.png')]`
|
||||
- 设置切片大小:`[--nine-top:10] [--nine-right:10] [--nine-bottom:10] [--nine-left:10]`
|
||||
- 快速设置(四个角相等):`[--nine-all:15]`(等效于设置四个角都为15)
|
||||
- 可选高级参数:
|
||||
- 重复模式:`[--nine-repeat:repeat]`(默认 stretch)
|
||||
- 向外扩展:`[--nine-outset:5]`(默认 0)
|
||||
- 边框宽度:`[--nine-width:2]`(默认 1)
|
||||
3) 填充控制:
|
||||
- 默认:填充中心区域
|
||||
- 添加 `nine-slice-no-fill` 类:不填充中心,露出背景
|
||||
|
||||
示例:
|
||||
<!-- 基础使用 -->
|
||||
<div class="nine-slice [--nine-src:url('/public/images/frame-9.png')] [--nine-top:10] [--nine-right:10] [--nine-bottom:10] [--nine-left:10] p-4">
|
||||
内容区域
|
||||
</div>
|
||||
|
||||
<!-- 快速设置(四个角相等) -->
|
||||
<div class="nine-slice [--nine-src:url('/public/images/frame-9.png')] [--nine-all:15] p-4">
|
||||
快速设置 - 四个角都是15px
|
||||
</div>
|
||||
|
||||
<!-- 重复图案 -->
|
||||
<div class="nine-slice [--nine-src:url('/public/images/pattern.png')] [--nine-top:15] [--nine-right:15] [--nine-bottom:15] [--nine-left:15] [--nine-repeat:round] p-6">
|
||||
重复图案边框
|
||||
</div>
|
||||
|
||||
<!-- 不填充中心 -->
|
||||
<div class="nine-slice nine-slice-no-fill [--nine-src:url('/public/images/frame.png')] [--nine-top:20] [--nine-right:20] [--nine-bottom:20] [--nine-left:20] p-8">
|
||||
不填充中心
|
||||
</div>
|
||||
|
||||
关键点:
|
||||
- 使用 CSS border-image 实现精确的9宫格切片
|
||||
- 4个角保持不拉伸,边缘和中心区域可配置拉伸或重复
|
||||
- 支持 fill/unfill 控制中心区域填充
|
||||
- 兼容所有现代浏览器
|
||||
*/
|
||||
@layer utilities {
|
||||
.H2 {
|
||||
@apply text-2xl font-bold;
|
||||
}
|
||||
.H3 {
|
||||
@apply text-xl font-bold;
|
||||
}
|
||||
.H4 {
|
||||
@apply text-base font-light;
|
||||
}
|
||||
.frame1 {
|
||||
@apply nine-slice [--nine-src:url('/public/images/Frame1.png')] [--nine-all:10] [--nine-fill:1];
|
||||
}
|
||||
.frame-border2 {
|
||||
@apply absolute inset-0 nine-slice [--nine-src:url('/public/images/frame-border2.png')] [--nine-all:50] [--nine-fill:1];
|
||||
}
|
||||
/* 九宫格边框类 - 支持基础到高级功能 */
|
||||
.nine-slice {
|
||||
border-style: solid;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* 边框厚度:基于独立的切片值或快速设置 */
|
||||
border-width: calc(var(--nine-top, var(--nine-all, 24)) * 1px)
|
||||
calc(var(--nine-right, var(--nine-all, 24)) * 1px)
|
||||
calc(var(--nine-bottom, var(--nine-all, 24)) * 1px)
|
||||
calc(var(--nine-left, var(--nine-all, 24)) * 1px);
|
||||
|
||||
/* 边框图像 */
|
||||
border-image-source: var(--nine-src);
|
||||
|
||||
/* 边框图像宽度 */
|
||||
border-image-width: var(--nine-width, 1);
|
||||
|
||||
/* 边框图像向外扩展 */
|
||||
border-image-outset: calc(var(--nine-outset, 0) * 1px);
|
||||
|
||||
/* 重复模式 - 支持 stretch, repeat, round, space */
|
||||
border-image-repeat: var(--nine-repeat, stretch);
|
||||
|
||||
/* 默认切片设置(填充中心) */
|
||||
border-image-slice: var(--nine-top, var(--nine-all, 24)) var(--nine-right, var(--nine-all, 24))
|
||||
var(--nine-bottom, var(--nine-all, 24)) var(--nine-left, var(--nine-all, 24)) fill;
|
||||
}
|
||||
|
||||
/* 不填充中心的变体 */
|
||||
.nine-slice.nine-slice-no-fill {
|
||||
border-image-slice: var(--nine-top, var(--nine-all, 24)) var(--nine-right, var(--nine-all, 24))
|
||||
var(--nine-bottom, var(--nine-all, 24)) var(--nine-left, var(--nine-all, 24));
|
||||
}
|
||||
|
||||
/* 动画支持 - 平滑过渡 */
|
||||
.nine-slice-animated {
|
||||
transition:
|
||||
border-image-source 0.3s ease,
|
||||
border-width 0.3s ease,
|
||||
border-image-slice 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
大屏看板专用 TailwindCSS Utilities
|
||||
|
||||
设计目标:
|
||||
- 适配4K大屏分辨率 (3840x2160)
|
||||
- 支持多种布局模式(网格、弹性、绝对定位)
|
||||
- 提供专业的数据可视化容器
|
||||
- 优化文字可读性和对比度
|
||||
- 支持动态主题切换
|
||||
*/
|
||||
|
||||
@layer utilities {
|
||||
/* 大屏布局容器 */
|
||||
.dashboard-container {
|
||||
@apply w-full h-screen overflow-hidden bg-slate-900 text-white;
|
||||
}
|
||||
|
||||
.dashboard-grid {
|
||||
@apply grid gap-4 p-6 h-full;
|
||||
}
|
||||
|
||||
.dashboard-grid-2x2 {
|
||||
@apply grid grid-cols-2 grid-rows-2 gap-6 p-8;
|
||||
}
|
||||
|
||||
.dashboard-grid-3x3 {
|
||||
@apply grid grid-cols-3 grid-rows-3 gap-4 p-6;
|
||||
}
|
||||
|
||||
.dashboard-grid-4x4 {
|
||||
@apply grid grid-cols-4 grid-rows-4 gap-3 p-4;
|
||||
}
|
||||
|
||||
/* 大屏卡片容器 */
|
||||
.dashboard-card {
|
||||
@apply bg-slate-800/80 backdrop-blur-sm rounded-xl border border-slate-700 p-6 shadow-2xl;
|
||||
}
|
||||
|
||||
.dashboard-card-highlight {
|
||||
@apply dashboard-card border-blue-500/50 bg-slate-800/90;
|
||||
}
|
||||
|
||||
.dashboard-card-warning {
|
||||
@apply dashboard-card border-amber-500/50 bg-orange-900/20;
|
||||
}
|
||||
|
||||
.dashboard-card-danger {
|
||||
@apply dashboard-card border-red-500/50 bg-red-900/20;
|
||||
}
|
||||
|
||||
/* 大屏标题文字 */
|
||||
.dashboard-title {
|
||||
@apply text-4xl font-bold text-white tracking-wide mb-4;
|
||||
}
|
||||
|
||||
.dashboard-subtitle {
|
||||
@apply text-2xl font-semibold text-slate-300 mb-3;
|
||||
}
|
||||
|
||||
.dashboard-metric-title {
|
||||
@apply text-lg font-medium text-slate-400 mb-2;
|
||||
}
|
||||
|
||||
/* 大屏数值显示 */
|
||||
.dashboard-metric-large {
|
||||
@apply text-6xl font-bold text-white tabular-nums;
|
||||
}
|
||||
|
||||
.dashboard-metric-medium {
|
||||
@apply text-5xl font-semibold text-white tabular-nums;
|
||||
}
|
||||
|
||||
.dashboard-metric-small {
|
||||
@apply text-3xl font-medium text-slate-200 tabular-nums;
|
||||
}
|
||||
|
||||
.dashboard-metric-trend-up {
|
||||
@apply text-green-400 text-2xl font-semibold;
|
||||
}
|
||||
|
||||
.dashboard-metric-trend-down {
|
||||
@apply text-red-400 text-2xl font-semibold;
|
||||
}
|
||||
|
||||
/* 图表容器 */
|
||||
.chart-container {
|
||||
@apply w-full h-80 bg-slate-800/50 rounded-lg p-4 border border-slate-700;
|
||||
}
|
||||
|
||||
.chart-container-large {
|
||||
@apply w-full h-96 bg-slate-800/50 rounded-lg p-4 border border-slate-700;
|
||||
}
|
||||
|
||||
.chart-container-small {
|
||||
@apply w-full h-48 bg-slate-800/50 rounded-lg p-3 border border-slate-700;
|
||||
}
|
||||
|
||||
/* 进度条 */
|
||||
.dashboard-progress {
|
||||
@apply w-full h-3 bg-slate-700 rounded-full overflow-hidden;
|
||||
}
|
||||
|
||||
.dashboard-progress-bar {
|
||||
@apply h-full bg-gradient-to-r from-blue-500 to-cyan-400 rounded-full transition-all duration-500;
|
||||
}
|
||||
|
||||
.dashboard-progress-bar-success {
|
||||
@apply bg-gradient-to-r from-green-500 to-emerald-400;
|
||||
}
|
||||
|
||||
.dashboard-progress-bar-warning {
|
||||
@apply bg-gradient-to-r from-amber-500 to-yellow-400;
|
||||
}
|
||||
|
||||
.dashboard-progress-bar-danger {
|
||||
@apply bg-gradient-to-r from-red-500 to-rose-400;
|
||||
}
|
||||
|
||||
/* 状态指示器 */
|
||||
.status-indicator {
|
||||
@apply inline-flex items-center px-3 py-1 rounded-full text-sm font-medium;
|
||||
}
|
||||
|
||||
.status-online {
|
||||
@apply status-indicator bg-green-500/20 text-green-300 border border-green-500/30;
|
||||
}
|
||||
|
||||
.status-offline {
|
||||
@apply status-indicator bg-red-500/20 text-red-300 border border-red-500/30;
|
||||
}
|
||||
|
||||
.status-warning {
|
||||
@apply status-indicator bg-amber-500/20 text-amber-300 border border-amber-500/30;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
@apply w-3 h-3 rounded-full mr-2;
|
||||
}
|
||||
|
||||
.status-dot-online {
|
||||
@apply status-dot bg-green-400 animate-pulse;
|
||||
}
|
||||
|
||||
.status-dot-offline {
|
||||
@apply status-dot bg-red-400;
|
||||
}
|
||||
|
||||
.status-dot-warning {
|
||||
@apply status-dot bg-amber-400;
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
.dashboard-fade-in {
|
||||
@apply animate-fade-in duration-1000;
|
||||
}
|
||||
|
||||
.dashboard-slide-up {
|
||||
@apply animate-slide-up duration-700;
|
||||
}
|
||||
|
||||
.dashboard-scale-in {
|
||||
@apply animate-scale-in duration-500;
|
||||
}
|
||||
|
||||
/* 自定义动画 */
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-up {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scale-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fade-in ease-out;
|
||||
}
|
||||
|
||||
.animate-slide-up {
|
||||
animation: slide-up ease-out;
|
||||
}
|
||||
|
||||
.animate-scale-in {
|
||||
animation: scale-in ease-out;
|
||||
}
|
||||
|
||||
/* 数据表格样式 */
|
||||
.dashboard-table {
|
||||
@apply w-full border-collapse bg-slate-800/50 rounded-lg overflow-hidden;
|
||||
}
|
||||
|
||||
.dashboard-table th {
|
||||
@apply px-6 py-4 text-left text-sm font-semibold text-slate-300 border-b border-slate-700 bg-slate-800/80;
|
||||
}
|
||||
|
||||
.dashboard-table td {
|
||||
@apply px-6 py-4 text-sm text-slate-200 border-b border-slate-700/50;
|
||||
}
|
||||
|
||||
.dashboard-table tr:hover {
|
||||
@apply bg-slate-700/30;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.dashboard-scrollbar {
|
||||
overflow: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #475569 #1e293b;
|
||||
}
|
||||
|
||||
.dashboard-scrollbar::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.dashboard-scrollbar::-webkit-scrollbar-track {
|
||||
background: #1e293b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.dashboard-scrollbar::-webkit-scrollbar-thumb {
|
||||
background: #475569;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.dashboard-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: #64748b;
|
||||
}
|
||||
|
||||
/* 全屏模式 */
|
||||
.dashboard-fullscreen {
|
||||
@apply fixed inset-0 z-50 bg-slate-900;
|
||||
}
|
||||
|
||||
/* 分屏布局 */
|
||||
.dashboard-split-horizontal {
|
||||
@apply grid grid-cols-2 gap-0 h-full;
|
||||
}
|
||||
|
||||
.dashboard-split-vertical {
|
||||
@apply grid grid-rows-2 gap-0 h-full;
|
||||
}
|
||||
|
||||
/* 边缘对齐 */
|
||||
.dashboard-align-top {
|
||||
@apply flex items-start justify-center;
|
||||
}
|
||||
|
||||
.dashboard-align-bottom {
|
||||
@apply flex items-end justify-center;
|
||||
}
|
||||
|
||||
.dashboard-align-left {
|
||||
@apply flex items-center justify-start;
|
||||
}
|
||||
|
||||
.dashboard-align-right {
|
||||
@apply flex items-center justify-end;
|
||||
}
|
||||
|
||||
/* 页面过渡动画 - 淡入淡出效果 */
|
||||
.page-transition {
|
||||
@apply transition-all duration-1000 ease-out;
|
||||
}
|
||||
|
||||
.page-enter {
|
||||
@apply opacity-0 scale-95;
|
||||
}
|
||||
|
||||
.page-enter-active {
|
||||
@apply transition-all duration-1000 ease-out;
|
||||
}
|
||||
|
||||
.page-enter-to {
|
||||
@apply opacity-100 scale-100;
|
||||
}
|
||||
|
||||
.page-leave {
|
||||
@apply opacity-100 scale-100;
|
||||
}
|
||||
|
||||
.page-leave-active {
|
||||
@apply transition-all duration-500 ease-in;
|
||||
}
|
||||
|
||||
.page-leave-to {
|
||||
@apply opacity-0 scale-95;
|
||||
}
|
||||
|
||||
/* 元素淡入动画 */
|
||||
.fade-in {
|
||||
animation: fade-in 1s ease-out forwards;
|
||||
opacity: 0; /* 初始状态设为透明,避免闪烁 */
|
||||
}
|
||||
|
||||
.fade-in-left {
|
||||
animation: fade-in-left 1s ease-out forwards;
|
||||
opacity: 0; /* 初始状态设为透明,避免闪烁 */
|
||||
}
|
||||
|
||||
.fade-in-right {
|
||||
animation: fade-in-right 1s ease-out forwards;
|
||||
opacity: 0; /* 初始状态设为透明,避免闪烁 */
|
||||
}
|
||||
|
||||
.fade-in-up {
|
||||
animation: fade-in-up 1s ease-out forwards;
|
||||
}
|
||||
|
||||
.fade-in-down {
|
||||
animation: fade-in-down 1s ease-out forwards;
|
||||
}
|
||||
|
||||
/* 淡入动画关键帧 */
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in-left {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in-right {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in-up {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in-down {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 动画延迟工具类 */
|
||||
.delay-100 {
|
||||
animation-delay: 100ms;
|
||||
}
|
||||
|
||||
.delay-200 {
|
||||
animation-delay: 200ms;
|
||||
}
|
||||
|
||||
.delay-300 {
|
||||
animation-delay: 300ms;
|
||||
}
|
||||
|
||||
.delay-400 {
|
||||
animation-delay: 400ms;
|
||||
}
|
||||
|
||||
.delay-500 {
|
||||
animation-delay: 500ms;
|
||||
}
|
||||
|
||||
.delay-600 {
|
||||
animation-delay: 600ms;
|
||||
}
|
||||
|
||||
.delay-700 {
|
||||
animation-delay: 700ms;
|
||||
}
|
||||
|
||||
.delay-800 {
|
||||
animation-delay: 800ms;
|
||||
}
|
||||
|
||||
.delay-900 {
|
||||
animation-delay: 900ms;
|
||||
}
|
||||
|
||||
.delay-1000 {
|
||||
animation-delay: 1000ms;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user