@@ -3,11 +3,168 @@
|
||||
.features {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 0;
|
||||
padding: 3rem 0;
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, rgba(33, 96, 253, 0.05) 0%, rgba(6, 182, 212, 0.05) 100%);
|
||||
}
|
||||
|
||||
.featureGrid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.featureSvg {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
@media (max-width: 768px) {
|
||||
.featureGrid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Feature Card Styling */
|
||||
.featureCard {
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.cardInner {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 1.5rem;
|
||||
border: 1px solid rgba(33, 96, 253, 0.1);
|
||||
background: linear-gradient(135deg, rgba(33, 96, 253, 0.02), rgba(6, 182, 212, 0.02));
|
||||
padding: 1.5rem;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.featureCard:hover .cardInner {
|
||||
border-color: var(--card-color, #2160fd);
|
||||
background: linear-gradient(135deg, rgba(33, 96, 253, 0.08), rgba(6, 182, 212, 0.08));
|
||||
box-shadow: 0 10px 30px rgba(33, 96, 253, 0.1),
|
||||
0 0 1px rgba(33, 96, 253, 0.3);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.cardIcon {
|
||||
font-size: 2.5rem;
|
||||
line-height: 1;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(33, 96, 253, 0.1);
|
||||
border-radius: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.featureCard:hover .cardIcon {
|
||||
background: var(--card-color, #2160fd);
|
||||
color: white;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.cardContent {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: var(--docs-color-text, #1f2937);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
[data-theme='dark'] .cardTitle {
|
||||
color: #f3f4f6;
|
||||
}
|
||||
|
||||
.featureCard:hover .cardTitle {
|
||||
color: var(--card-color, #2160fd);
|
||||
}
|
||||
|
||||
.cardDescription {
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
color: var(--docs-color-text-secondary, #6b7280);
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
[data-theme='dark'] .cardDescription {
|
||||
color: #d1d5db;
|
||||
}
|
||||
|
||||
.cardGradient {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
background: radial-gradient(circle at top right, rgba(33, 96, 253, 0.15), transparent 70%);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.featureCard:hover .cardGradient {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.cardArrow {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
font-size: 1.5rem;
|
||||
opacity: 0;
|
||||
transform: translate(8px, -8px);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
color: var(--card-color, #2160fd);
|
||||
}
|
||||
|
||||
.featureCard:hover .cardArrow {
|
||||
opacity: 1;
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
|
||||
/* Animation */
|
||||
@keyframes slideInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.cardInner {
|
||||
animation: slideInUp 0.5s ease-out;
|
||||
}
|
||||
|
||||
/* Stagger animation for cards */
|
||||
:nth-child(1) .cardInner {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
:nth-child(2) .cardInner {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
:nth-child(3) .cardInner {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
@@ -1,38 +1,87 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import Link from '@docusaurus/Link';
|
||||
import styles from './HomepageFeatures.module.css';
|
||||
|
||||
interface FeatureItem {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
icon: React.ReactNode;
|
||||
link: string;
|
||||
color: string;
|
||||
gradient: string;
|
||||
}
|
||||
|
||||
const FeatureList: FeatureItem[] = [
|
||||
{
|
||||
title: '📚 系统化文档',
|
||||
id: 'backend',
|
||||
title: '后端技术',
|
||||
description:
|
||||
'涵盖后端(Spring Boot/Cloud)、前端(React/Vue)和算法(LeetCode),分门别类,清晰索引。',
|
||||
'深度讲解 Spring Boot / Spring Cloud 核心概念、最佳实践与微服务架构,含真实项目案例。',
|
||||
icon: '⚙️',
|
||||
link: '/docs/backend-doc/intro-docs',
|
||||
color: '#2160fd',
|
||||
gradient: 'from-blue-500/20 to-transparent',
|
||||
},
|
||||
{
|
||||
title: '⚡ 快速检索',
|
||||
id: 'frontend',
|
||||
title: '前端开发',
|
||||
description:
|
||||
'集成 Algolia DocSearch,毫秒级全文检索,快速定位任意知识点。',
|
||||
'系统化学习 React / Vue 现代框架、状态管理、组件设计与性能优化,打造高质量前端应用。',
|
||||
icon: '⚛️',
|
||||
link: '/docs/frontend-doc/intro-docs',
|
||||
color: '#06b6d4',
|
||||
gradient: 'from-cyan-500/20 to-transparent',
|
||||
},
|
||||
{
|
||||
title: '🌐 持续更新',
|
||||
id: 'algorithms',
|
||||
title: '算法与面试',
|
||||
description:
|
||||
'由技术团队持续维护,定期同步最新技术栈实践和面试题解析。',
|
||||
'精选 LeetCode 题目分类讲解、编程面试题库与数据结构深度分析,快速突破算法关卡。',
|
||||
icon: '🧠',
|
||||
link: '/docs/LeetCode/intro-docs',
|
||||
color: '#ec4899',
|
||||
gradient: 'from-pink-500/20 to-transparent',
|
||||
},
|
||||
];
|
||||
|
||||
function Feature({ title, description }: FeatureItem): JSX.Element {
|
||||
interface FeatureCardProps extends FeatureItem {}
|
||||
|
||||
function FeatureCard({
|
||||
title,
|
||||
description,
|
||||
icon,
|
||||
link,
|
||||
color,
|
||||
gradient,
|
||||
}: FeatureCardProps): JSX.Element {
|
||||
return (
|
||||
<div className={clsx('col col--4')}>
|
||||
<div className="text--center padding-horiz--md">
|
||||
<h3>{title}</h3>
|
||||
<p>{description}</p>
|
||||
<Link
|
||||
to={link}
|
||||
className={`${styles.featureCard} group`}
|
||||
style={
|
||||
{
|
||||
'--card-color': color,
|
||||
} as React.CSSProperties & { '--card-color': string }
|
||||
}
|
||||
>
|
||||
<div className={styles.cardInner}>
|
||||
{/* Icon */}
|
||||
<div className={styles.cardIcon}>{icon}</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className={styles.cardContent}>
|
||||
<h3 className={styles.cardTitle}>{title}</h3>
|
||||
<p className={styles.cardDescription}>{description}</p>
|
||||
</div>
|
||||
|
||||
{/* Gradient Background */}
|
||||
<div className={`${styles.cardGradient} ${gradient}`}></div>
|
||||
|
||||
{/* Arrow Icon */}
|
||||
<div className={styles.cardArrow}>→</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,9 +89,9 @@ export default function HomepageFeatures(): JSX.Element {
|
||||
return (
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<Feature key={idx} {...props} />
|
||||
<div className={styles.featureGrid}>
|
||||
{FeatureList.map((props) => (
|
||||
<FeatureCard key={props.id} {...props} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+69
-7
@@ -5,21 +5,83 @@
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* Import Tailwind CSS */
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-color-primary: #25c2a0;
|
||||
--ifm-color-primary-dark: rgb(33, 175, 144);
|
||||
--ifm-color-primary-darker: rgb(31, 165, 136);
|
||||
--ifm-color-primary-darkest: rgb(26, 136, 112);
|
||||
--ifm-color-primary-light: rgb(70, 203, 174);
|
||||
--ifm-color-primary-lighter: rgb(102, 212, 189);
|
||||
--ifm-color-primary-lightest: rgb(146, 224, 208);
|
||||
--ifm-color-primary: #2160fd;
|
||||
--ifm-color-primary-dark: #1850d8;
|
||||
--ifm-color-primary-darker: #1442c4;
|
||||
--ifm-color-primary-darkest: #102ca0;
|
||||
--ifm-color-primary-light: #4d7ffe;
|
||||
--ifm-color-primary-lighter: #7a9eff;
|
||||
--ifm-color-primary-lightest: #a8c0ff;
|
||||
|
||||
--docs-color-primary: rgb(33 96 253);
|
||||
--docs-color-primary-100: rgb(26 144 255);
|
||||
--docs-color-primary-200: rgb(33 96 253);
|
||||
|
||||
--docs-color-secondary-1000: rgb(0 0 0);
|
||||
--docs-color-secondary-900: rgb(25 25 25);
|
||||
--docs-color-secondary-800: rgb(38 38 38);
|
||||
--docs-color-secondary-700: rgb(71 71 71);
|
||||
|
||||
--docs-color-text: rgb(31 41 55);
|
||||
--docs-color-text-100: rgb(107 114 128);
|
||||
--docs-color-text-400: rgb(153 153 153);
|
||||
|
||||
--docs-color-text-secondary: rgb(107 114 128);
|
||||
|
||||
--ifm-code-font-size: 95%;
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
--docs-color-text: rgb(243 244 246);
|
||||
--docs-color-text-secondary: rgb(209 213 219);
|
||||
}
|
||||
|
||||
/* Code highlighting */
|
||||
.docusaurus-highlight-code-line {
|
||||
background-color: rgb(72, 77, 91);
|
||||
display: block;
|
||||
margin: 0 calc(-1 * var(--ifm-pre-padding));
|
||||
padding: 0 var(--ifm-pre-padding);
|
||||
}
|
||||
|
||||
/* Enhanced link hover decoration */
|
||||
.navbar__link,
|
||||
.menu__link,
|
||||
.table-of-contents__link,
|
||||
.pagination-nav,
|
||||
.footer {
|
||||
--ifm-link-hover-decoration: none;
|
||||
}
|
||||
|
||||
.menu__link {
|
||||
--ifm-link-hover-color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
/* Smooth transitions */
|
||||
* {
|
||||
@apply transition-colors;
|
||||
}
|
||||
|
||||
/* Hero section enhancements */
|
||||
.hero {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(33, 96, 253, 0.05) 0%,
|
||||
rgba(6, 182, 212, 0.05) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.hero--primary {
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
|
||||
[data-theme='dark'] .hero--primary {
|
||||
background-color: #1a1a2e;
|
||||
}
|
||||
|
||||
+18
-3
@@ -11,13 +11,28 @@ function HomepageHeader(): JSX.Element {
|
||||
return (
|
||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||
<div className="container">
|
||||
<h1 className="hero__title">{siteConfig.title}</h1>
|
||||
<h1 className="hero__title">🚀 {siteConfig.title}</h1>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
<p style={{ fontSize: '0.95rem', color: 'rgba(0,0,0,0.6)', marginBottom: '1.5rem' }}>
|
||||
为全栈、全端工程师精心打造的<strong>技术文档 + 算法面试 + 最佳实践</strong>一站式参考库
|
||||
</p>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className="button button--primary button--lg"
|
||||
to="/docs/backend-doc/intro-docs">
|
||||
⚙️ 后端技术
|
||||
</Link>
|
||||
<Link
|
||||
className="button button--secondary button--lg"
|
||||
to="/docs/intro-docs">
|
||||
Code Docs 介绍 - 1min ⏱️
|
||||
to="/docs/frontend-doc/intro-docs"
|
||||
style={{ marginLeft: '1rem' }}>
|
||||
⚛️ 前端开发
|
||||
</Link>
|
||||
<Link
|
||||
className="button button--outline button--lg"
|
||||
to="/docs/LeetCode/intro-docs"
|
||||
style={{ marginLeft: '1rem' }}>
|
||||
🧠 算法面试
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user