feat: 全面重构网站工程化体系与 UI 架构
- 将单体 style.css 拆分为 tokens/reset/fonts/layout/responsive/组件级 CSS 模块 - 从 Google Fonts CDN 迁移至本地自托管字体(JetBrainsMono、NotoSansSC) - 引入 Vitest + Testing Library 测试体系,新增单元测试 - 添加 GitHub Actions CI 流水线(lint → build → test) - 新增 Prettier 格式化与 ESLint 规则强化 - 重构全部 YAML 数据文件,完善项目详情页(截图轮播、更新日志) - 新增项目文档编写指南(docs/create-project.md)
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
/* ═══════════════════════════════════════════════════════
|
||||
Scroll Reveal System
|
||||
Progressive: hidden only when JS is confirmed ready
|
||||
═══════════════════════════════════════════════════════ */
|
||||
|
||||
html.reveal-active .section,
|
||||
html.reveal-active .stat-item,
|
||||
html.reveal-active .project-card,
|
||||
html.reveal-active .category-card,
|
||||
html.reveal-active .contact-card,
|
||||
html.reveal-active .changelog-entry,
|
||||
html.reveal-active .about-header,
|
||||
html.reveal-active .focus-item {
|
||||
opacity: 0;
|
||||
transform: translateY(28px);
|
||||
transition:
|
||||
opacity 0.7s var(--ease-out-expo),
|
||||
transform 0.7s var(--ease-out-expo),
|
||||
border-color var(--transition),
|
||||
box-shadow var(--transition),
|
||||
background var(--transition);
|
||||
}
|
||||
|
||||
html.reveal-active .section.revealed,
|
||||
html.reveal-active .stat-item.revealed,
|
||||
html.reveal-active .project-card.revealed,
|
||||
html.reveal-active .category-card.revealed,
|
||||
html.reveal-active .contact-card.revealed,
|
||||
html.reveal-active .changelog-entry.revealed,
|
||||
html.reveal-active .about-header.revealed,
|
||||
html.reveal-active .focus-item.revealed {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Stagger delays for grid items */
|
||||
html.reveal-active .project-card:nth-child(2),
|
||||
html.reveal-active .stat-item:nth-child(2),
|
||||
html.reveal-active .category-card:nth-child(2),
|
||||
html.reveal-active .focus-item:nth-child(2) {
|
||||
transition-delay: 0.06s;
|
||||
}
|
||||
|
||||
html.reveal-active .project-card:nth-child(3),
|
||||
html.reveal-active .stat-item:nth-child(3),
|
||||
html.reveal-active .category-card:nth-child(3),
|
||||
html.reveal-active .focus-item:nth-child(3) {
|
||||
transition-delay: 0.12s;
|
||||
}
|
||||
|
||||
html.reveal-active .project-card:nth-child(4),
|
||||
html.reveal-active .stat-item:nth-child(4),
|
||||
html.reveal-active .category-card:nth-child(4),
|
||||
html.reveal-active .focus-item:nth-child(4) {
|
||||
transition-delay: 0.18s;
|
||||
}
|
||||
|
||||
html.reveal-active .project-card:nth-child(5),
|
||||
html.reveal-active .stat-item:nth-child(5),
|
||||
html.reveal-active .category-card:nth-child(5),
|
||||
html.reveal-active .focus-item:nth-child(5) {
|
||||
transition-delay: 0.24s;
|
||||
}
|
||||
|
||||
html.reveal-active .project-card:nth-child(6),
|
||||
html.reveal-active .category-card:nth-child(6) {
|
||||
transition-delay: 0.3s;
|
||||
}
|
||||
|
||||
html.reveal-active .project-card:nth-child(7),
|
||||
html.reveal-active .category-card:nth-child(7) {
|
||||
transition-delay: 0.36s;
|
||||
}
|
||||
|
||||
html.reveal-active .project-card:nth-child(8),
|
||||
html.reveal-active .category-card:nth-child(8) {
|
||||
transition-delay: 0.42s;
|
||||
}
|
||||
|
||||
/* Changelog stagger */
|
||||
html.reveal-active .changelog-entry:nth-child(2) {
|
||||
transition-delay: 0.08s;
|
||||
}
|
||||
html.reveal-active .changelog-entry:nth-child(3) {
|
||||
transition-delay: 0.16s;
|
||||
}
|
||||
html.reveal-active .changelog-entry:nth-child(4) {
|
||||
transition-delay: 0.24s;
|
||||
}
|
||||
html.reveal-active .changelog-entry:nth-child(5) {
|
||||
transition-delay: 0.32s;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════
|
||||
Keyframe Animations
|
||||
═══════════════════════════════════════════════════════ */
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(24px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.4s var(--ease-out-expo) forwards;
|
||||
}
|
||||
|
||||
@keyframes selectMenuIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-4px) scale(0.98);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes meshFloat1 {
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0) scale(1);
|
||||
}
|
||||
33% {
|
||||
transform: translate(40px, -30px) scale(1.08);
|
||||
}
|
||||
66% {
|
||||
transform: translate(-20px, 20px) scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes meshFloat2 {
|
||||
0%,
|
||||
100% {
|
||||
transform: translate(0, 0) scale(1);
|
||||
}
|
||||
33% {
|
||||
transform: translate(-30px, 25px) scale(1.05);
|
||||
}
|
||||
66% {
|
||||
transform: translate(25px, -15px) scale(0.92);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glowDot {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 0 6px currentColor;
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
0 0 12px currentColor,
|
||||
0 0 20px currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% center;
|
||||
}
|
||||
100% {
|
||||
background-position: 200% center;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gradientShift {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes avatarPulse {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 0 30px oklch(74% 0.2 45 / 10%);
|
||||
}
|
||||
50% {
|
||||
box-shadow:
|
||||
0 0 40px oklch(74% 0.2 45 / 20%),
|
||||
0 0 60px oklch(70% 0.24 20 / 10%);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Loading Spinner ──────────────────────────────────── */
|
||||
.loading-spinner {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 3px solid var(--border);
|
||||
border-top-color: var(--accent);
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/* About page */
|
||||
.about-header {
|
||||
display: flex;
|
||||
gap: 28px;
|
||||
align-items: center;
|
||||
margin: 28px 0 24px;
|
||||
}
|
||||
|
||||
.about-avatar {
|
||||
width: 88px;
|
||||
height: 88px;
|
||||
border-radius: 50%;
|
||||
background: oklch(74% 0.2 45 / 8%);
|
||||
box-shadow: 0 0 0 2px oklch(74% 0.2 45 / 25%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
color: var(--accent);
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 0 30px oklch(74% 0.2 45 / 10%);
|
||||
position: relative;
|
||||
animation: avatarPulse 4s ease-in-out infinite;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.about-avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.about-avatar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -4px;
|
||||
border-radius: 50%;
|
||||
background: var(--gradient-aurora);
|
||||
z-index: -1;
|
||||
opacity: 0.3;
|
||||
filter: blur(8px);
|
||||
}
|
||||
|
||||
.about-name {
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.about-bio {
|
||||
font-size: 15px;
|
||||
color: var(--muted);
|
||||
margin-top: 6px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.focus-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.focus-item {
|
||||
padding: 12px 16px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
background: oklch(15% 0.025 270 / 40%);
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
:root.light .focus-item {
|
||||
background: oklch(98% 0.005 270);
|
||||
}
|
||||
|
||||
.focus-item:hover {
|
||||
border-color: oklch(74% 0.2 45 / 20%);
|
||||
background: oklch(74% 0.2 45 / 5%);
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.focus-item::before {
|
||||
content: '\2192';
|
||||
color: var(--accent);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Contact cards */
|
||||
.contact-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.contact-card {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 16px;
|
||||
background: oklch(15% 0.025 270 / 50%);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
transition: all var(--transition);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
:root.light .contact-card {
|
||||
background: oklch(100% 0 0 / 70%);
|
||||
}
|
||||
|
||||
.contact-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--gradient-glow);
|
||||
opacity: 0;
|
||||
transition: opacity var(--transition);
|
||||
}
|
||||
|
||||
.contact-card:hover {
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
box-shadow: 0 0 16px oklch(74% 0.2 45 / 8%);
|
||||
transform: translateY(-2px);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.contact-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.contact-card h3 {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.contact-card p {
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.contact-card-link {
|
||||
display: inline-flex;
|
||||
margin-top: 12px;
|
||||
color: var(--accent);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Tech stack tags */
|
||||
.techstack-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.tech-tag {
|
||||
padding: 6px 14px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 13px;
|
||||
background: oklch(74% 0.2 45 / 6%);
|
||||
border: 1px solid oklch(74% 0.2 45 / 12%);
|
||||
color: var(--accent);
|
||||
font-family: var(--font-mono);
|
||||
font-weight: 500;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.tech-tag:hover {
|
||||
border-color: oklch(74% 0.2 45 / 30%);
|
||||
background: oklch(74% 0.2 45 / 14%);
|
||||
box-shadow: 0 0 16px oklch(74% 0.2 45 / 12%);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/* ── Buttons ─────────────────────────────────────────── */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 10px 20px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
color: var(--fg);
|
||||
transition: all var(--transition);
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--gradient-glow);
|
||||
opacity: 0;
|
||||
transition: opacity var(--transition);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
box-shadow: var(--shadow-glow);
|
||||
text-decoration: none;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(0) scale(0.98);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--gradient-primary);
|
||||
color: var(--accent-fg);
|
||||
border-color: transparent;
|
||||
font-weight: 600;
|
||||
box-shadow:
|
||||
0 0 24px oklch(74% 0.2 45 / 20%),
|
||||
0 2px 8px oklch(0% 0 0 / 20%);
|
||||
}
|
||||
|
||||
.btn-primary::before {
|
||||
background: linear-gradient(135deg, oklch(100% 0 0 / 15%) 0%, transparent 60%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
box-shadow: var(--shadow-glow);
|
||||
border-color: transparent;
|
||||
filter: brightness(1.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
transform: translateY(0) scale(0.98);
|
||||
filter: brightness(0.95);
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
border-color: transparent;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.btn-ghost:hover {
|
||||
background: oklch(74% 0.2 45 / 6%);
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.btn-ghost::before {
|
||||
display: none;
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
/* ── Section ─────────────────────────────────────────── */
|
||||
.section {
|
||||
padding: 40px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-compact {
|
||||
padding: 32px 0;
|
||||
}
|
||||
|
||||
.section + .section::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 120px;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, oklch(74% 0.2 45 / 20%), transparent);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
position: relative;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 1px;
|
||||
bottom: 1px;
|
||||
width: 4px;
|
||||
border-radius: 2px;
|
||||
background: var(--gradient-primary);
|
||||
box-shadow: 0 0 12px oklch(74% 0.2 45 / 40%);
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.section-action {
|
||||
font-size: 14px;
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.section-action:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* ── Card grid ───────────────────────────────────────── */
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.card-grid-sm {
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
}
|
||||
|
||||
.card-grid > .empty-state {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
/* ── Project card ────────────────────────────────────── */
|
||||
.project-card-link,
|
||||
.project-card-link:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.project-card {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: 24px;
|
||||
background: oklch(15% 0.025 270 / 50%);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.project-card::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--gradient-aurora);
|
||||
opacity: 0;
|
||||
transition: opacity 0.4s ease;
|
||||
}
|
||||
|
||||
.project-card:hover {
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
box-shadow:
|
||||
var(--shadow-glow),
|
||||
0 8px 32px oklch(0% 0 0 / 20%);
|
||||
transform: translateY(-6px);
|
||||
}
|
||||
|
||||
.project-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.project-card:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.project-card:active {
|
||||
transform: translateY(-2px) scale(0.99);
|
||||
}
|
||||
|
||||
:root.light .project-card {
|
||||
background: oklch(100% 0 0 / 70%);
|
||||
}
|
||||
|
||||
:root.light .project-card:hover {
|
||||
box-shadow:
|
||||
var(--shadow-glow),
|
||||
0 8px 32px oklch(13% 0.02 270 / 6%);
|
||||
}
|
||||
|
||||
.project-card-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.project-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: var(--radius-md);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
flex-shrink: 0;
|
||||
border: 1px solid oklch(74% 0.2 45 / 12%);
|
||||
background: oklch(74% 0.2 45 / 8%);
|
||||
color: var(--accent);
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.project-card:hover .project-icon {
|
||||
border-color: oklch(74% 0.2 45 / 30%);
|
||||
background: oklch(74% 0.2 45 / 15%);
|
||||
box-shadow: 0 0 24px oklch(74% 0.2 45 / 20%);
|
||||
transform: scale(1.08);
|
||||
}
|
||||
|
||||
.project-card-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.project-name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.project-name a {
|
||||
color: var(--fg);
|
||||
transition: color var(--transition);
|
||||
}
|
||||
|
||||
.project-name a:hover {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.project-slogan {
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
margin-top: 3px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.project-card-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.project-card-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* ── Badges ──────────────────────────────────────────── */
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 3px 10px;
|
||||
border-radius: 99px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 1.5;
|
||||
border: 1px solid var(--border);
|
||||
background: oklch(15% 0.025 270 / 60%);
|
||||
color: var(--muted);
|
||||
white-space: nowrap;
|
||||
transition: all var(--transition-fast);
|
||||
}
|
||||
|
||||
:root.light .badge {
|
||||
background: oklch(97% 0.005 270);
|
||||
}
|
||||
|
||||
.badge-accent {
|
||||
background: oklch(74% 0.2 45 / 8%);
|
||||
border-color: oklch(74% 0.2 45 / 20%);
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
.badge-status {
|
||||
border: none;
|
||||
color: var(--fg);
|
||||
font-weight: 600;
|
||||
padding: 3px 10px 3px 8px;
|
||||
}
|
||||
|
||||
.badge-status::before {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--status-color, currentColor);
|
||||
margin-inline-end: 3px;
|
||||
box-shadow: 0 0 8px var(--status-color, currentColor);
|
||||
animation: glowDot 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* ── Category cards ──────────────────────────────────── */
|
||||
.category-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.category-card {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 24px 16px;
|
||||
background: oklch(15% 0.025 270 / 40%);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
text-align: center;
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.category-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(ellipse at 50% 100%, oklch(74% 0.2 45 / 6%) 0%, transparent 70%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.35s ease;
|
||||
}
|
||||
|
||||
.category-card:hover {
|
||||
border-color: oklch(74% 0.2 45 / 30%);
|
||||
box-shadow: var(--shadow-glow);
|
||||
transform: translateY(-6px);
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.category-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.category-card:active {
|
||||
transform: translateY(-2px) scale(0.98);
|
||||
}
|
||||
|
||||
:root.light .category-card {
|
||||
background: oklch(100% 0 0 / 60%);
|
||||
}
|
||||
|
||||
:root.light .category-card:hover {
|
||||
box-shadow:
|
||||
var(--shadow-glow),
|
||||
0 8px 24px oklch(13% 0.02 270 / 5%);
|
||||
}
|
||||
|
||||
.category-icon {
|
||||
font-size: 28px;
|
||||
margin-bottom: 10px;
|
||||
color: var(--accent);
|
||||
transition:
|
||||
transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
|
||||
color var(--transition);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.category-card:hover .category-icon {
|
||||
transform: scale(1.2);
|
||||
filter: drop-shadow(0 0 8px oklch(74% 0.2 45 / 30%));
|
||||
}
|
||||
|
||||
.category-label {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
.changelog-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* Changelog */
|
||||
.changelog-entry {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
background: oklch(15% 0.025 270 / 35%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:root.light .changelog-entry {
|
||||
background: oklch(100% 0 0 / 55%);
|
||||
}
|
||||
|
||||
.changelog-summary {
|
||||
min-height: 44px;
|
||||
padding: 9px 12px;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(82px, auto) 1fr auto;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.changelog-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.changelog-summary::before {
|
||||
content: '';
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-right: 2px solid var(--accent);
|
||||
border-bottom: 2px solid var(--accent);
|
||||
transform: rotate(-45deg);
|
||||
transition: transform var(--transition);
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.changelog-entry[open] .changelog-summary::before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.changelog-version {
|
||||
padding-left: 16px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
font-family: var(--font-mono);
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.changelog-date {
|
||||
min-width: 0;
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.changelog-count {
|
||||
min-width: 24px;
|
||||
height: 22px;
|
||||
padding: 0 8px;
|
||||
border-radius: 999px;
|
||||
background: oklch(74% 0.2 45 / 9%);
|
||||
color: var(--accent);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.changelog-changes {
|
||||
margin: 0;
|
||||
padding: 0 14px 12px 34px;
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
.changelog-changes li {
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.changelog-changes li::marker {
|
||||
color: var(--accent);
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
/* ── Breadcrumb ──────────────────────────────────────── */
|
||||
.breadcrumb {
|
||||
padding: 8px 0;
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.breadcrumb a {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.breadcrumb-current {
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
/* ── Detail page ─────────────────────────────────────── */
|
||||
.detail-header {
|
||||
padding-top: 48px;
|
||||
padding-bottom: 36px;
|
||||
padding-inline: 24px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.detail-header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(ellipse 60% 80% at 10% 50%, oklch(74% 0.2 45 / 8%) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 40% 60% at 90% 30%, oklch(70% 0.24 20 / 6%) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:root.light .detail-header::before {
|
||||
background:
|
||||
radial-gradient(ellipse 60% 80% at 10% 50%, oklch(58% 0.22 45 / 5%) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 40% 60% at 90% 30%, oklch(55% 0.24 20 / 4%) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
.detail-header-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.detail-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: var(--radius-lg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
flex-shrink: 0;
|
||||
border: 1px solid oklch(74% 0.2 45 / 15%);
|
||||
background: oklch(74% 0.2 45 / 8%);
|
||||
color: var(--accent);
|
||||
box-shadow: 0 0 24px oklch(74% 0.2 45 / 10%);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.detail-icon::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: inherit;
|
||||
background: linear-gradient(135deg, oklch(100% 0 0 / 10%) 0%, transparent 60%);
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.03em;
|
||||
background: var(--gradient-primary);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.detail-slogan {
|
||||
font-size: 16px;
|
||||
color: var(--muted);
|
||||
margin-top: 6px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.detail-badges {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.detail-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 24px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.detail-body {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 300px;
|
||||
gap: 40px;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.detail-sidebar {
|
||||
position: sticky;
|
||||
top: calc(var(--nav-height) + 32px);
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.detail-section {
|
||||
margin-bottom: 40px;
|
||||
scroll-margin-top: calc(var(--nav-height) + 24px);
|
||||
}
|
||||
|
||||
.detail-section-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: relative;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.detail-section-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
width: 60px;
|
||||
height: 2px;
|
||||
background: var(--gradient-primary);
|
||||
box-shadow: 0 0 8px oklch(74% 0.2 45 / 25%);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.detail-prose {
|
||||
font-size: 15px;
|
||||
line-height: 1.8;
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
.detail-prose + .detail-prose {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
/* Sidebar compact metadata */
|
||||
.detail-meta-panel {
|
||||
width: 100%;
|
||||
font-size: 13px;
|
||||
background: oklch(15% 0.025 270 / 50%);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border-radius: var(--radius-lg);
|
||||
border: 1px solid var(--border);
|
||||
padding: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
:root.light .detail-meta-panel {
|
||||
background: oklch(100% 0 0 / 70%);
|
||||
}
|
||||
|
||||
.detail-meta-item {
|
||||
min-width: 0;
|
||||
padding: 9px 10px;
|
||||
border-radius: var(--radius-sm);
|
||||
background: oklch(74% 0.2 45 / 4%);
|
||||
border: 1px solid oklch(74% 0.2 45 / 8%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
:root.light .detail-meta-item {
|
||||
background: oklch(98% 0.005 270 / 70%);
|
||||
}
|
||||
|
||||
.detail-meta-label {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.detail-meta-value {
|
||||
min-width: 0;
|
||||
color: var(--fg);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 1.35;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.detail-meta-value.mono {
|
||||
font-family: var(--font-mono);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.detail-link-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.detail-link-btn {
|
||||
min-width: 0;
|
||||
min-height: 38px;
|
||||
padding: 8px 10px;
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--border);
|
||||
background: oklch(15% 0.025 270 / 45%);
|
||||
color: var(--fg);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
transition:
|
||||
color var(--transition),
|
||||
border-color var(--transition),
|
||||
background var(--transition);
|
||||
}
|
||||
|
||||
.detail-link-btn:hover {
|
||||
color: var(--accent);
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
background: oklch(74% 0.2 45 / 7%);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
:root.light .detail-link-btn {
|
||||
background: oklch(100% 0 0 / 65%);
|
||||
}
|
||||
|
||||
/* Feature tags — compact highlight */
|
||||
.feature-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.feature-tag {
|
||||
padding: 4px 12px;
|
||||
border-radius: 99px;
|
||||
font-size: 13px;
|
||||
background: oklch(74% 0.2 45 / 10%);
|
||||
color: var(--accent);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
transition: background var(--transition);
|
||||
}
|
||||
|
||||
.feature-tag::before {
|
||||
content: '\2713';
|
||||
margin-inline-end: 6px;
|
||||
font-weight: 700;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.feature-tag:hover {
|
||||
background: oklch(74% 0.2 45 / 18%);
|
||||
}
|
||||
|
||||
:root.light .feature-tag {
|
||||
background: oklch(58% 0.22 45 / 8%);
|
||||
}
|
||||
|
||||
:root.light .feature-tag:hover {
|
||||
background: oklch(58% 0.22 45 / 14%);
|
||||
}
|
||||
|
||||
/* Screenshot carousel */
|
||||
.screenshot-carousel {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.screenshot-scroll {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
overflow-x: auto;
|
||||
scroll-snap-type: x mandatory;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.screenshot-scroll::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.screenshot-slide {
|
||||
flex: 0 0 85%;
|
||||
max-width: 400px;
|
||||
scroll-snap-align: center;
|
||||
}
|
||||
|
||||
.screenshot-slide:first-child {
|
||||
margin-inline-start: 4px;
|
||||
}
|
||||
|
||||
.screenshot-placeholder {
|
||||
aspect-ratio: 16/10;
|
||||
border-radius: var(--radius-lg);
|
||||
border: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--muted);
|
||||
font-size: 14px;
|
||||
background: oklch(15% 0.025 270 / 60%);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.screenshot-placeholder::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--gradient-glow);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
:root.light .screenshot-placeholder {
|
||||
background: oklch(96% 0.008 270 / 70%);
|
||||
}
|
||||
|
||||
.screenshot-dots {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.screenshot-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background: var(--border);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
.screenshot-dot.active {
|
||||
background: var(--accent);
|
||||
width: 18px;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 8px oklch(74% 0.2 45 / 30%);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.screenshot-slide {
|
||||
flex: 0 0 calc(33.333% - 8px);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Install guide ───────────────────────────────────── */
|
||||
.install-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.install-item {
|
||||
padding: 10px 14px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 13px;
|
||||
background: oklch(15% 0.025 270 / 40%);
|
||||
transition: all var(--transition);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
:root.light .install-item {
|
||||
background: oklch(98% 0.005 270);
|
||||
}
|
||||
|
||||
.install-item:hover {
|
||||
background: oklch(74% 0.2 45 / 6%);
|
||||
}
|
||||
|
||||
.install-item strong {
|
||||
display: inline;
|
||||
margin-inline-end: 6px;
|
||||
font-size: 12px;
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
/* ── Project selector (for roadmap/changelog) ────────── */
|
||||
.project-selector {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* Download table */
|
||||
.download-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.download-table th {
|
||||
text-align: start;
|
||||
padding: 10px 14px;
|
||||
font-weight: 600;
|
||||
color: var(--muted);
|
||||
border-bottom: 2px solid oklch(74% 0.2 45 / 15%);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.download-table td {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
transition: background var(--transition);
|
||||
}
|
||||
|
||||
.download-table tr:hover td {
|
||||
background: oklch(74% 0.2 45 / 4%);
|
||||
}
|
||||
|
||||
.sha256 {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* Trust note */
|
||||
.trust-note {
|
||||
padding: 18px 22px;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid oklch(74% 0.2 45 / 12%);
|
||||
background: oklch(74% 0.2 45 / 4%);
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
margin-top: 20px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.trust-note::before {
|
||||
content: '\2139';
|
||||
margin-inline-end: 10px;
|
||||
color: var(--accent);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Docs hub */
|
||||
.docs-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.doc-link {
|
||||
padding: 14px 18px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
.doc-link:hover {
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
box-shadow: 0 0 16px oklch(74% 0.2 45 / 6%);
|
||||
text-decoration: none;
|
||||
color: var(--accent);
|
||||
transform: translateX(4px);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/* Footer ─────────────────────────────────────────────── */
|
||||
.footer {
|
||||
position: relative;
|
||||
padding: 48px 0;
|
||||
margin-top: auto;
|
||||
background: oklch(12% 0.02 270);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:root.light .footer {
|
||||
background: oklch(96% 0.008 270);
|
||||
}
|
||||
|
||||
/* Gradient top border */
|
||||
.footer::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--gradient-aurora);
|
||||
opacity: 0.6;
|
||||
box-shadow: 0 0 16px oklch(74% 0.2 45 / 15%);
|
||||
}
|
||||
|
||||
.footer-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(260px, 2fr) minmax(180px, 1fr) minmax(160px, 1fr);
|
||||
gap: 36px;
|
||||
}
|
||||
|
||||
.footer-brand {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.footer-slogan {
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.footer-col-title {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--muted);
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
transition:
|
||||
color var(--transition),
|
||||
padding-inline-start var(--transition);
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
padding-inline-start: 4px;
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
margin-top: 36px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid var(--border);
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.footer-policy-links,
|
||||
.footer-legal {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.footer-legal a {
|
||||
color: var(--muted);
|
||||
transition: color var(--transition);
|
||||
}
|
||||
|
||||
.footer-legal a:hover {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer-policy-link {
|
||||
color: var(--muted);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/* ── Hero ─────────────────────────────────────────────── */
|
||||
.hero {
|
||||
padding-top: 120px;
|
||||
padding-bottom: 80px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Animated gradient mesh — blob 1 */
|
||||
.hero::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -80px;
|
||||
left: -10%;
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
oklch(74% 0.2 45 / 28%) 0%,
|
||||
oklch(70% 0.24 20 / 16%) 40%,
|
||||
transparent 70%
|
||||
);
|
||||
pointer-events: none;
|
||||
filter: blur(60px);
|
||||
animation: meshFloat1 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Animated gradient mesh — blob 2 */
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: -5%;
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
oklch(68% 0.22 350 / 22%) 0%,
|
||||
oklch(80% 0.17 85 / 12%) 40%,
|
||||
transparent 70%
|
||||
);
|
||||
pointer-events: none;
|
||||
filter: blur(50px);
|
||||
animation: meshFloat2 10s ease-in-out infinite;
|
||||
}
|
||||
|
||||
:root.light .hero::before {
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
oklch(58% 0.22 45 / 12%) 0%,
|
||||
oklch(55% 0.24 20 / 6%) 40%,
|
||||
transparent 70%
|
||||
);
|
||||
}
|
||||
|
||||
:root.light .hero::after {
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
oklch(52% 0.22 350 / 10%) 0%,
|
||||
oklch(65% 0.18 85 / 5%) 40%,
|
||||
transparent 70%
|
||||
);
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: clamp(36px, 5.5vw, 64px);
|
||||
font-weight: 800;
|
||||
line-height: 1.08;
|
||||
letter-spacing: -0.04em;
|
||||
max-width: 720px;
|
||||
background: var(--gradient-primary);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
position: relative;
|
||||
animation: fadeInUp 0.8s var(--ease-out-expo) both;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 17px;
|
||||
color: oklch(75% 0.02 270);
|
||||
margin-top: 20px;
|
||||
max-width: 600px;
|
||||
line-height: 1.8;
|
||||
animation: fadeInUp 0.8s var(--ease-out-expo) 0.1s both;
|
||||
}
|
||||
|
||||
:root.light .hero-subtitle {
|
||||
color: oklch(40% 0.028 270);
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
margin-top: 40px;
|
||||
flex-wrap: wrap;
|
||||
animation: fadeInUp 0.8s var(--ease-out-expo) 0.2s both;
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/* ── Navigation ──────────────────────────────────────── */
|
||||
.nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
inset-inline: 0;
|
||||
height: var(--nav-height);
|
||||
background: oklch(11% 0.02 270 / 20%);
|
||||
backdrop-filter: blur(32px) saturate(1.8);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(1.8);
|
||||
border-bottom: 1px solid oklch(74% 0.2 45 / 6%);
|
||||
z-index: 300;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition:
|
||||
background 0.4s ease,
|
||||
border-color 0.4s ease,
|
||||
box-shadow 0.4s ease;
|
||||
}
|
||||
|
||||
.nav.scrolled,
|
||||
.nav:has(~ .main-content) {
|
||||
background: oklch(11% 0.02 270 / 35%);
|
||||
box-shadow:
|
||||
0 4px 30px oklch(0% 0 0 / 20%),
|
||||
0 1px 0 oklch(74% 0.2 45 / 8%);
|
||||
}
|
||||
|
||||
:root.light .nav {
|
||||
background: oklch(98% 0.005 270 / 35%);
|
||||
border-bottom: 1px solid oklch(58% 0.22 45 / 6%);
|
||||
}
|
||||
|
||||
:root.light .nav.scrolled,
|
||||
:root.light .nav:has(~ .main-content) {
|
||||
background: oklch(98% 0.005 270 / 55%);
|
||||
box-shadow:
|
||||
0 4px 30px oklch(13% 0.02 270 / 6%),
|
||||
0 1px 0 oklch(58% 0.22 45 / 8%);
|
||||
}
|
||||
|
||||
/* Gradient line under nav */
|
||||
.nav::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent 0%,
|
||||
oklch(74% 0.2 45 / 40%) 15%,
|
||||
oklch(70% 0.24 20 / 50%) 35%,
|
||||
oklch(68% 0.22 350 / 50%) 55%,
|
||||
oklch(80% 0.17 85 / 40%) 75%,
|
||||
transparent 100%
|
||||
);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.nav-inner {
|
||||
max-width: var(--max-width);
|
||||
margin: 0 auto;
|
||||
padding-inline: var(--gutter);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.nav-brand {
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
color: var(--fg);
|
||||
margin-inline-end: 24px;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
transition: opacity var(--transition);
|
||||
}
|
||||
|
||||
.nav-brand:hover {
|
||||
text-decoration: none;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.nav-brand-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--gradient-primary);
|
||||
color: var(--accent-fg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
font-family: var(--font-mono);
|
||||
box-shadow: 0 0 16px oklch(74% 0.2 45 / 20%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nav-brand-icon::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(135deg, oklch(100% 0 0 / 20%) 0%, transparent 60%);
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
flex: 1;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.nav-links::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
padding: 7px 14px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
transition:
|
||||
color var(--transition),
|
||||
background var(--transition);
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: var(--fg);
|
||||
background: oklch(74% 0.2 45 / 6%);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-link.active {
|
||||
color: var(--accent);
|
||||
background: oklch(74% 0.2 45 / 10%);
|
||||
}
|
||||
|
||||
.nav-link.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 16px;
|
||||
height: 2px;
|
||||
border-radius: 1px;
|
||||
background: var(--gradient-primary);
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
margin-inline-start: 12px;
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border: none;
|
||||
border-radius: var(--radius-sm);
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition:
|
||||
color var(--transition),
|
||||
background var(--transition),
|
||||
transform var(--transition-fast);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.nav-btn:hover {
|
||||
color: var(--accent);
|
||||
background: oklch(74% 0.2 45 / 8%);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.nav-btn:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* ── Mobile nav overlay ──────────────────────────────── */
|
||||
.nav-mobile-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-mobile-menu {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: var(--nav-height);
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: oklch(11% 0.02 270 / 95%);
|
||||
backdrop-filter: blur(24px);
|
||||
-webkit-backdrop-filter: blur(24px);
|
||||
z-index: 290;
|
||||
padding: 24px var(--gutter);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
:root.light .nav-mobile-menu {
|
||||
background: oklch(98% 0.005 270 / 95%);
|
||||
}
|
||||
|
||||
.nav-mobile-menu.open {
|
||||
animation: fadeIn 0.25s var(--ease-out-expo);
|
||||
}
|
||||
|
||||
.nav-mobile-menu .nav-link {
|
||||
padding: 14px 18px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.nav-links {
|
||||
display: none;
|
||||
}
|
||||
.nav-mobile-toggle {
|
||||
display: flex;
|
||||
}
|
||||
.nav-mobile-menu.open {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/* Roadmap compact tabs */
|
||||
.roadmap-compact {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
background: oklch(15% 0.025 270 / 40%);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
:root.light .roadmap-compact {
|
||||
background: oklch(100% 0 0 / 60%);
|
||||
}
|
||||
|
||||
.roadmap-tabs {
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.roadmap-tab {
|
||||
flex: 1;
|
||||
padding: 10px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.roadmap-tab::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: transparent;
|
||||
transition: background var(--transition);
|
||||
}
|
||||
|
||||
.roadmap-tab.active {
|
||||
color: var(--fg);
|
||||
background: oklch(15% 0.025 270 / 30%);
|
||||
}
|
||||
|
||||
:root.light .roadmap-tab.active {
|
||||
background: oklch(97% 0.005 270);
|
||||
}
|
||||
|
||||
.roadmap-tab.done.active {
|
||||
color: var(--emerald);
|
||||
}
|
||||
.roadmap-tab.done.active::after {
|
||||
background: var(--emerald);
|
||||
}
|
||||
.roadmap-tab.doing.active {
|
||||
color: var(--amber);
|
||||
}
|
||||
.roadmap-tab.doing.active::after {
|
||||
background: var(--amber);
|
||||
}
|
||||
.roadmap-tab.planned.active {
|
||||
color: var(--cyan);
|
||||
}
|
||||
.roadmap-tab.planned.active::after {
|
||||
background: var(--cyan);
|
||||
}
|
||||
|
||||
.roadmap-tab-content {
|
||||
padding: 12px 16px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.roadmap-item-inline {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
.roadmap-item-inline .dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.roadmap-item-inline .dot.done {
|
||||
background: var(--emerald);
|
||||
box-shadow: 0 0 6px oklch(74% 0.2 165 / 40%);
|
||||
}
|
||||
.roadmap-item-inline .dot.doing {
|
||||
background: var(--amber);
|
||||
box-shadow: 0 0 6px oklch(83% 0.19 85 / 40%);
|
||||
animation: glowDot 2s ease-in-out infinite;
|
||||
}
|
||||
.roadmap-item-inline .dot.planned {
|
||||
background: var(--cyan);
|
||||
box-shadow: 0 0 6px oklch(77% 0.16 200 / 40%);
|
||||
}
|
||||
|
||||
.roadmap-empty {
|
||||
color: var(--muted);
|
||||
padding: 8px 0;
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/* ── Filter bar ──────────────────────────────────────── */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 24px;
|
||||
padding: 14px;
|
||||
border-radius: var(--radius-md);
|
||||
background: oklch(15% 0.025 270 / 46%);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--border);
|
||||
box-shadow: 0 1px 0 oklch(100% 0 0 / 4%) inset;
|
||||
position: relative;
|
||||
z-index: 30;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.filter-bar:has(.select-control.open) {
|
||||
z-index: 260;
|
||||
}
|
||||
|
||||
:root.light .filter-bar {
|
||||
background: oklch(100% 0 0 / 72%);
|
||||
box-shadow: 0 1px 0 oklch(100% 0 0 / 70%) inset;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
min-width: 240px;
|
||||
min-height: 40px;
|
||||
padding: 9px 13px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: oklch(11% 0.02 270 / 45%);
|
||||
color: var(--fg);
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
transition:
|
||||
border-color var(--transition),
|
||||
box-shadow var(--transition),
|
||||
background var(--transition);
|
||||
}
|
||||
|
||||
:root.light .search-input {
|
||||
background: oklch(98% 0.005 270 / 80%);
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: oklch(74% 0.2 45 / 40%);
|
||||
box-shadow: 0 0 0 3px oklch(74% 0.2 45 / 8%);
|
||||
background: var(--surface);
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.filter-group-label {
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--surface);
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
.filter-btn:hover {
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
.filter-btn.active {
|
||||
background: oklch(74% 0.2 45 / 10%);
|
||||
border-color: oklch(74% 0.2 45 / 30%);
|
||||
color: var(--accent);
|
||||
box-shadow: 0 0 12px oklch(74% 0.2 45 / 8%);
|
||||
}
|
||||
|
||||
.select-control {
|
||||
position: relative;
|
||||
min-width: 132px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.select-control.open {
|
||||
z-index: 280;
|
||||
}
|
||||
|
||||
.select-trigger {
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: oklch(11% 0.02 270 / 45%);
|
||||
color: var(--fg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
border-color var(--transition),
|
||||
box-shadow var(--transition),
|
||||
background var(--transition);
|
||||
}
|
||||
|
||||
:root.light .select-trigger {
|
||||
background: oklch(98% 0.005 270 / 80%);
|
||||
}
|
||||
|
||||
.select-trigger:hover,
|
||||
.select-control.open .select-trigger {
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
background: oklch(74% 0.2 45 / 6%);
|
||||
}
|
||||
|
||||
.select-trigger:focus-visible,
|
||||
.select-control.open .select-trigger {
|
||||
border-color: oklch(74% 0.2 45 / 40%);
|
||||
box-shadow: 0 0 0 3px oklch(74% 0.2 45 / 8%);
|
||||
}
|
||||
|
||||
.select-chevron {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-right: 2px solid var(--muted);
|
||||
border-bottom: 2px solid var(--muted);
|
||||
transform: translateY(-2px) rotate(45deg);
|
||||
transition:
|
||||
border-color var(--transition),
|
||||
transform var(--transition);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.select-trigger:hover .select-chevron,
|
||||
.select-trigger:focus-visible .select-chevron,
|
||||
.select-control.open .select-chevron {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.select-control.open .select-chevron {
|
||||
transform: translateY(2px) rotate(225deg);
|
||||
}
|
||||
|
||||
.select-menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 6px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 300;
|
||||
padding: 6px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: oklch(13% 0.018 270 / 98%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
max-height: min(320px, calc(100vh - 220px));
|
||||
box-shadow:
|
||||
0 14px 36px oklch(0% 0 0 / 32%),
|
||||
0 0 0 1px oklch(100% 0 0 / 3%) inset;
|
||||
backdrop-filter: blur(18px);
|
||||
-webkit-backdrop-filter: blur(18px);
|
||||
animation: selectMenuIn 120ms var(--ease-out-expo);
|
||||
}
|
||||
|
||||
:root.light .select-menu {
|
||||
background: oklch(100% 0 0 / 98%);
|
||||
box-shadow:
|
||||
0 16px 36px oklch(13% 0.02 270 / 12%),
|
||||
0 0 0 1px oklch(100% 0 0 / 80%) inset;
|
||||
}
|
||||
|
||||
.select-search {
|
||||
width: 100%;
|
||||
min-height: 32px;
|
||||
padding: 7px 10px;
|
||||
border: 1px solid oklch(74% 0.2 45 / 18%);
|
||||
border-radius: 6px;
|
||||
background: oklch(11% 0.02 270 / 55%);
|
||||
color: var(--fg);
|
||||
font-size: 12px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
:root.light .select-search {
|
||||
background: oklch(98% 0.005 270 / 90%);
|
||||
}
|
||||
|
||||
.select-search:focus {
|
||||
border-color: oklch(74% 0.2 45 / 42%);
|
||||
box-shadow: 0 0 0 2px oklch(74% 0.2 45 / 8%);
|
||||
}
|
||||
|
||||
.select-options {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.select-options::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.select-options::-webkit-scrollbar-thumb {
|
||||
background: oklch(74% 0.2 45 / 28%);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.select-option {
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
padding: 7px 9px 7px 12px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: var(--fg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
transition:
|
||||
color var(--transition-fast),
|
||||
background var(--transition-fast);
|
||||
}
|
||||
|
||||
.select-option:hover {
|
||||
background: oklch(74% 0.2 45 / 8%);
|
||||
}
|
||||
|
||||
.select-option.active {
|
||||
background: oklch(74% 0.2 45 / 13%);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
:root.light .select-option:hover {
|
||||
background: oklch(58% 0.22 45 / 8%);
|
||||
}
|
||||
|
||||
:root.light .select-option.active {
|
||||
background: oklch(58% 0.22 45 / 12%);
|
||||
}
|
||||
|
||||
.select-check {
|
||||
color: var(--accent);
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.select-empty {
|
||||
padding: 10px 12px;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/* ── Stats bar ───────────────────────────────────────── */
|
||||
.stats-bar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
padding: 48px 0;
|
||||
border-bottom: 1px solid oklch(24% 0.035 270);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
padding: 24px 16px;
|
||||
border-radius: var(--radius-lg);
|
||||
background: oklch(15% 0.025 270 / 60%);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--border);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
border-color var(--transition),
|
||||
box-shadow var(--transition),
|
||||
transform var(--transition),
|
||||
background var(--transition);
|
||||
}
|
||||
|
||||
.stat-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: radial-gradient(ellipse at 50% 0%, oklch(74% 0.2 45 / 5%) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:root.light .stat-item {
|
||||
background: oklch(100% 0 0 / 70%);
|
||||
}
|
||||
|
||||
:root.light .stat-item::before {
|
||||
background: radial-gradient(ellipse at 50% 0%, oklch(58% 0.22 45 / 4%) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
/* Gradient accent line at bottom */
|
||||
.stat-item::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 10%;
|
||||
right: 10%;
|
||||
height: 2px;
|
||||
border-radius: 1px;
|
||||
opacity: 0.6;
|
||||
transition:
|
||||
opacity var(--transition),
|
||||
left var(--transition),
|
||||
right var(--transition);
|
||||
}
|
||||
|
||||
.stat-item:nth-child(1)::after {
|
||||
background: var(--blue);
|
||||
}
|
||||
.stat-item:nth-child(2)::after {
|
||||
background: var(--emerald);
|
||||
}
|
||||
.stat-item:nth-child(3)::after {
|
||||
background: var(--violet);
|
||||
}
|
||||
.stat-item:nth-child(4)::after {
|
||||
background: var(--amber);
|
||||
}
|
||||
|
||||
.stat-item:hover {
|
||||
border-color: oklch(74% 0.2 45 / 25%);
|
||||
box-shadow: var(--shadow-glow);
|
||||
transform: translateY(-4px);
|
||||
background: oklch(15% 0.025 270 / 80%);
|
||||
}
|
||||
|
||||
:root.light .stat-item:hover {
|
||||
background: oklch(100% 0 0 / 90%);
|
||||
}
|
||||
|
||||
.stat-item:hover::after {
|
||||
opacity: 1;
|
||||
left: 5%;
|
||||
right: 5%;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
font-family: var(--font-mono);
|
||||
font-variant-numeric: tabular-nums;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.stat-item:nth-child(1) .stat-value {
|
||||
color: var(--blue);
|
||||
text-shadow: 0 0 20px oklch(74% 0.2 45 / 15%);
|
||||
}
|
||||
.stat-item:nth-child(2) .stat-value {
|
||||
color: var(--emerald);
|
||||
text-shadow: 0 0 20px oklch(74% 0.2 165 / 15%);
|
||||
}
|
||||
.stat-item:nth-child(3) .stat-value {
|
||||
color: var(--violet);
|
||||
text-shadow: 0 0 20px oklch(70% 0.24 20 / 15%);
|
||||
}
|
||||
.stat-item:nth-child(4) .stat-value {
|
||||
color: var(--amber);
|
||||
text-shadow: 0 0 20px oklch(83% 0.19 85 / 15%);
|
||||
}
|
||||
|
||||
.stat-value .accent {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
margin-top: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono';
|
||||
font-style: normal;
|
||||
font-weight: 400 600;
|
||||
font-display: swap;
|
||||
src: url('/fonts/JetBrainsMono-Latin.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
|
||||
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Noto Sans SC';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('/fonts/NotoSansSC-400.woff2') format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Noto Sans SC';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('/fonts/NotoSansSC-500.woff2') format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Noto Sans SC';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url('/fonts/NotoSansSC-600.woff2') format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Noto Sans SC';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('/fonts/NotoSansSC-700.woff2') format('woff2');
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* ── Layout ──────────────────────────────────────────── */
|
||||
.container {
|
||||
max-width: var(--max-width);
|
||||
margin: 0 auto;
|
||||
padding-inline: var(--gutter);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding-top: calc(var(--nav-height) + 32px);
|
||||
padding-bottom: 80px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* ── Empty state ─────────────────────────────────────── */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 56px 0;
|
||||
color: var(--muted);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* ── Page header ─────────────────────────────────────── */
|
||||
.page-header {
|
||||
padding: 24px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.03em;
|
||||
background: var(--gradient-primary);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 15px;
|
||||
color: var(--muted);
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
/* ── CTA section ─────────────────────────────────────── */
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cta-subtitle {
|
||||
margin: 8px auto 0;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.cta-actions {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
/* ── Loading fallback ────────────────────────────────── */
|
||||
.loading-fallback {
|
||||
padding: 80px 0;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/* ── Reset ───────────────────────────────────────────── */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Ambient aurora gradients on body */
|
||||
body::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(ellipse 80% 60% at 8% 15%, oklch(74% 0.2 45 / 14%) 0%, transparent 60%),
|
||||
radial-gradient(ellipse 60% 80% at 92% 65%, oklch(70% 0.24 20 / 10%) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 70% 70% at 50% 40%, oklch(68% 0.22 350 / 7%) 0%, transparent 55%);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
:root.light body::before {
|
||||
background:
|
||||
radial-gradient(ellipse 80% 60% at 8% 15%, oklch(58% 0.22 45 / 8%) 0%, transparent 60%),
|
||||
radial-gradient(ellipse 60% 80% at 92% 65%, oklch(55% 0.24 20 / 6%) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 70% 70% at 50% 40%, oklch(52% 0.22 350 / 4%) 0%, transparent 55%);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--fg);
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
button {
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
font-family: inherit;
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
/* ── Responsive ──────────────────────────────────────── */
|
||||
@media (max-width: 1023px) {
|
||||
.detail-body {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.detail-sidebar {
|
||||
position: static;
|
||||
}
|
||||
.footer-grid {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
:root {
|
||||
--gutter: 20px;
|
||||
--nav-height: 56px;
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding-top: 64px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
.hero-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 15px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.hero-actions {
|
||||
margin-top: 24px;
|
||||
gap: 10px;
|
||||
}
|
||||
.hero::before {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
.hero::after {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
}
|
||||
.section {
|
||||
padding: 28px 0;
|
||||
}
|
||||
.section-compact {
|
||||
padding: 24px 0;
|
||||
}
|
||||
.section-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.stats-bar {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px;
|
||||
padding: 32px 0;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
}
|
||||
.stat-item {
|
||||
padding: 16px 12px;
|
||||
}
|
||||
.card-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.category-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
/* Detail page compact */
|
||||
.detail-header {
|
||||
padding-top: 24px;
|
||||
padding-bottom: 20px;
|
||||
padding-inline: 16px;
|
||||
}
|
||||
.detail-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
.detail-header-top {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.detail-icon {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
}
|
||||
.detail-slogan {
|
||||
font-size: 14px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.detail-badges {
|
||||
gap: 5px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.detail-badges .badge {
|
||||
padding: 3px 8px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.detail-actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
margin-top: 14px;
|
||||
gap: 8px;
|
||||
}
|
||||
.detail-actions .btn {
|
||||
width: 100%;
|
||||
min-height: 36px;
|
||||
justify-content: center;
|
||||
padding: 8px 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.detail-body {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
gap: 24px;
|
||||
}
|
||||
.detail-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.detail-section-title {
|
||||
font-size: 17px;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.detail-prose {
|
||||
font-size: 14px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Feature tags compact on mobile */
|
||||
.feature-tags {
|
||||
gap: 5px;
|
||||
}
|
||||
.feature-tag {
|
||||
padding: 3px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Screenshot carousel mobile */
|
||||
.screenshot-slide {
|
||||
flex: 0 0 80%;
|
||||
}
|
||||
|
||||
/* Footer compact */
|
||||
.footer {
|
||||
padding: 28px 0;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
.footer-brand {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.footer-col-title {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.footer-links {
|
||||
justify-content: center;
|
||||
}
|
||||
.footer-project-links {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, max-content);
|
||||
justify-content: center;
|
||||
gap: 8px 22px;
|
||||
}
|
||||
.footer-project-links li:last-child:nth-child(odd) {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.footer-community-links {
|
||||
flex-direction: row;
|
||||
gap: 8px 18px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.footer-links a:hover {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
.footer-bottom {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 22px;
|
||||
padding-top: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-policy-links,
|
||||
.footer-legal {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav-links {
|
||||
display: none;
|
||||
}
|
||||
.nav-mobile-toggle {
|
||||
display: flex;
|
||||
}
|
||||
.page-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
.filter-bar {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
padding: 10px;
|
||||
}
|
||||
.search-input {
|
||||
grid-column: 1 / -1;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
.filter-group {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 4px;
|
||||
}
|
||||
.filter-group-label {
|
||||
margin: 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
.select-control {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
.select-trigger {
|
||||
min-height: 36px;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.select-menu {
|
||||
top: calc(100% + 5px);
|
||||
padding: 5px;
|
||||
max-height: min(260px, calc(100vh - 180px));
|
||||
}
|
||||
.select-search {
|
||||
min-height: 30px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.select-option {
|
||||
min-height: 32px;
|
||||
padding: 6px 8px 6px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Install guide compact */
|
||||
.install-item {
|
||||
padding: 8px 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.install-item strong {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/* Download table scroll */
|
||||
.download-table {
|
||||
font-size: 12px;
|
||||
}
|
||||
.download-table th,
|
||||
.download-table td {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
/* Sidebar compact metadata */
|
||||
.detail-meta-panel {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
padding: 8px;
|
||||
gap: 6px;
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
.detail-meta-item {
|
||||
padding: 7px 8px;
|
||||
}
|
||||
.detail-meta-label {
|
||||
font-size: 10px;
|
||||
}
|
||||
.detail-meta-value {
|
||||
font-size: 12px;
|
||||
}
|
||||
.detail-link-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 6px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.detail-link-btn {
|
||||
min-height: 34px;
|
||||
padding: 7px 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Trust note */
|
||||
.trust-note {
|
||||
padding: 12px 14px;
|
||||
font-size: 13px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
/* Changelog */
|
||||
.changelog-list {
|
||||
gap: 6px;
|
||||
}
|
||||
.changelog-summary {
|
||||
min-height: 38px;
|
||||
padding: 7px 10px;
|
||||
grid-template-columns: minmax(76px, auto) 1fr auto;
|
||||
gap: 8px;
|
||||
}
|
||||
.changelog-version {
|
||||
font-size: 13px;
|
||||
padding-left: 14px;
|
||||
}
|
||||
.changelog-date {
|
||||
font-size: 11px;
|
||||
}
|
||||
.changelog-count {
|
||||
min-width: 22px;
|
||||
height: 20px;
|
||||
padding: 0 6px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.changelog-changes {
|
||||
padding: 0 10px 10px 28px;
|
||||
font-size: 12px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.about-header {
|
||||
gap: 16px;
|
||||
margin: 22px 0 18px;
|
||||
}
|
||||
.about-avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
font-size: 24px;
|
||||
}
|
||||
.about-name {
|
||||
font-size: 22px;
|
||||
}
|
||||
.about-bio {
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.focus-grid,
|
||||
.contact-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.contact-card {
|
||||
padding: 14px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/* ── Scrollbar ───────────────────────────────────────── */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: oklch(28% 0.04 270);
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: oklch(74% 0.2 45 / 35%);
|
||||
}
|
||||
|
||||
:root.light ::-webkit-scrollbar-thumb {
|
||||
background: oklch(80% 0.02 270);
|
||||
}
|
||||
:root.light ::-webkit-scrollbar-thumb:hover {
|
||||
background: oklch(58% 0.22 45 / 35%);
|
||||
}
|
||||
|
||||
/* ── Selection ───────────────────────────────────────── */
|
||||
::selection {
|
||||
background: oklch(74% 0.2 45 / 25%);
|
||||
color: var(--fg);
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/* ═══════════════════════════════════════════════════════
|
||||
ZUJ OL Apps — Warm Aurora Design System v2
|
||||
Palette: Deep space + Warm amber-coral aurora gradients
|
||||
Font: Noto Sans SC + JetBrains Mono
|
||||
Color Space: OKLCH
|
||||
═══════════════════════════════════════════════════════ */
|
||||
|
||||
/* ── Tokens (Dark-first) ──────────────────────────────── */
|
||||
:root {
|
||||
--bg: oklch(11% 0.02 270);
|
||||
--surface: oklch(15% 0.025 270);
|
||||
--surface-2: oklch(19% 0.028 270);
|
||||
--fg: oklch(97% 0.005 270);
|
||||
--muted: oklch(58% 0.028 270);
|
||||
--border: oklch(24% 0.035 270);
|
||||
--accent: oklch(74% 0.2 45);
|
||||
--accent-fg: oklch(99% 0.005 270);
|
||||
|
||||
--blue: oklch(74% 0.2 45);
|
||||
--emerald: oklch(74% 0.2 165);
|
||||
--amber: oklch(83% 0.19 85);
|
||||
--violet: oklch(70% 0.24 20);
|
||||
--cyan: oklch(77% 0.16 200);
|
||||
--red: oklch(69% 0.28 25);
|
||||
--orange: oklch(76% 0.22 55);
|
||||
--pink: oklch(72% 0.26 340);
|
||||
|
||||
--gradient-primary: linear-gradient(135deg, oklch(74% 0.2 45), oklch(70% 0.24 20));
|
||||
--gradient-aurora: linear-gradient(
|
||||
135deg,
|
||||
oklch(74% 0.2 45),
|
||||
oklch(70% 0.24 20),
|
||||
oklch(68% 0.22 350),
|
||||
oklch(80% 0.17 85)
|
||||
);
|
||||
--gradient-warm: linear-gradient(
|
||||
135deg,
|
||||
oklch(69% 0.28 25),
|
||||
oklch(76% 0.22 55),
|
||||
oklch(83% 0.19 85)
|
||||
);
|
||||
--gradient-shine: linear-gradient(
|
||||
135deg,
|
||||
oklch(80% 0.17 85),
|
||||
oklch(70% 0.24 20),
|
||||
oklch(68% 0.22 350)
|
||||
);
|
||||
--gradient-glow: linear-gradient(
|
||||
135deg,
|
||||
oklch(74% 0.2 45 / 30%),
|
||||
oklch(70% 0.24 20 / 30%),
|
||||
oklch(68% 0.22 350 / 20%)
|
||||
);
|
||||
|
||||
--font-display: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
|
||||
--font-body: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
|
||||
--font-mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, Menlo, monospace;
|
||||
|
||||
--radius-sm: 8px;
|
||||
--radius-md: 12px;
|
||||
--radius-lg: 16px;
|
||||
--radius-xl: 20px;
|
||||
|
||||
--shadow-sm: 0 1px 3px oklch(0% 0 0 / 20%);
|
||||
--shadow-raised: 0 4px 24px oklch(0% 0 0 / 30%), 0 1px 4px oklch(0% 0 0 / 20%);
|
||||
--shadow-glow: 0 0 30px oklch(74% 0.2 45 / 12%), 0 0 60px oklch(70% 0.24 20 / 8%);
|
||||
--shadow-glow-lg: 0 0 40px oklch(74% 0.2 45 / 15%), 0 0 80px oklch(70% 0.24 20 / 10%);
|
||||
|
||||
--nav-height: 64px;
|
||||
--max-width: 1200px;
|
||||
--gutter: 40px;
|
||||
|
||||
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--transition: 250ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* ── Light mode ───────────────────────────────────────── */
|
||||
:root.light {
|
||||
--bg: oklch(98% 0.005 270);
|
||||
--surface: oklch(100% 0 0);
|
||||
--surface-2: oklch(96% 0.008 270);
|
||||
--fg: oklch(13% 0.025 270);
|
||||
--muted: oklch(46% 0.028 270);
|
||||
--border: oklch(88% 0.018 270);
|
||||
--accent: oklch(58% 0.22 45);
|
||||
--accent-fg: oklch(98% 0.005 270);
|
||||
|
||||
--blue: oklch(58% 0.22 45);
|
||||
--emerald: oklch(52% 0.2 165);
|
||||
--amber: oklch(68% 0.2 85);
|
||||
--violet: oklch(55% 0.24 20);
|
||||
--cyan: oklch(52% 0.18 200);
|
||||
--red: oklch(55% 0.28 25);
|
||||
--orange: oklch(60% 0.24 55);
|
||||
--pink: oklch(52% 0.26 340);
|
||||
|
||||
--gradient-primary: linear-gradient(135deg, oklch(55% 0.24 20), oklch(58% 0.22 45));
|
||||
--gradient-aurora: linear-gradient(
|
||||
135deg,
|
||||
oklch(55% 0.24 20),
|
||||
oklch(58% 0.22 45),
|
||||
oklch(52% 0.22 350),
|
||||
oklch(65% 0.18 85)
|
||||
);
|
||||
--gradient-warm: linear-gradient(
|
||||
135deg,
|
||||
oklch(55% 0.28 25),
|
||||
oklch(60% 0.24 55),
|
||||
oklch(68% 0.2 85)
|
||||
);
|
||||
--gradient-shine: linear-gradient(
|
||||
135deg,
|
||||
oklch(65% 0.18 85),
|
||||
oklch(55% 0.24 20),
|
||||
oklch(52% 0.26 340)
|
||||
);
|
||||
--gradient-glow: linear-gradient(
|
||||
135deg,
|
||||
oklch(58% 0.22 45 / 10%),
|
||||
oklch(55% 0.24 20 / 10%),
|
||||
oklch(52% 0.22 350 / 6%)
|
||||
);
|
||||
|
||||
--shadow-sm: 0 1px 3px oklch(13% 0.02 270 / 6%);
|
||||
--shadow-raised: 0 4px 24px oklch(13% 0.02 270 / 8%), 0 1px 4px oklch(13% 0.02 270 / 4%);
|
||||
--shadow-glow: 0 0 30px oklch(58% 0.22 45 / 8%), 0 0 60px oklch(55% 0.24 20 / 5%);
|
||||
--shadow-glow-lg: 0 0 40px oklch(58% 0.22 45 / 10%), 0 0 80px oklch(55% 0.24 20 / 6%);
|
||||
|
||||
color-scheme: light;
|
||||
}
|
||||
Reference in New Issue
Block a user