redesign: テック感のあるトップページに刷新
All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 29s

This commit is contained in:
koide 2026-02-28 02:05:37 +00:00
parent 8f2b0885f3
commit 51a1104284
3 changed files with 167 additions and 51 deletions

View File

@ -1,10 +1,5 @@
/** @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap');
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root { :root {
--ifm-color-primary: #2e8555; --ifm-color-primary: #2e8555;
--ifm-color-primary-dark: #29784c; --ifm-color-primary-dark: #29784c;
@ -15,9 +10,9 @@
--ifm-color-primary-lightest: #3cad6e; --ifm-color-primary-lightest: #3cad6e;
--ifm-code-font-size: 95%; --ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
--site-font-mono: 'JetBrains Mono', monospace;
} }
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] { [data-theme='dark'] {
--ifm-color-primary: #25c2a0; --ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90; --ifm-color-primary-dark: #21af90;

View File

@ -1,63 +1,148 @@
/* ===== Animations ===== */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
/* ===== Main ===== */
.main { .main {
min-height: calc(100vh - 60px); min-height: calc(100vh - 60px);
} }
/* ===== Hero ===== */
.hero { .hero {
padding: 4rem 2rem; position: relative;
padding: 5rem 2rem 4rem;
text-align: center; text-align: center;
background: linear-gradient(180deg, var(--ifm-background-surface-color) 0%, var(--ifm-background-color) 100%); overflow: hidden;
background:
radial-gradient(circle, var(--ifm-color-primary) 1px, transparent 1px) 0 0 / 24px 24px,
linear-gradient(180deg, var(--ifm-background-surface-color) 0%, var(--ifm-background-color) 100%);
background-blend-mode: overlay;
}
[data-theme='dark'] .hero {
background:
radial-gradient(circle, rgba(37,194,160,0.15) 1px, transparent 1px) 0 0 / 24px 24px,
linear-gradient(180deg, var(--ifm-background-surface-color) 0%, var(--ifm-background-color) 100%);
}
:root .hero {
background:
radial-gradient(circle, rgba(46,133,85,0.12) 1px, transparent 1px) 0 0 / 24px 24px,
linear-gradient(180deg, var(--ifm-background-surface-color) 0%, var(--ifm-background-color) 100%);
} }
.heroInner { .heroInner {
max-width: 800px; max-width: 960px;
margin: 0 auto; margin: 0 auto;
animation: fadeInUp 0.6s ease both;
}
.heroPrompt {
font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
font-size: 1.1rem;
color: var(--ifm-color-emphasis-600);
margin-bottom: 0.25rem;
} }
.heroTitle { .heroTitle {
font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
font-size: 3rem; font-size: 3rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
display: inline-block;
}
.cursor {
display: inline-block;
width: 0.6ch;
height: 1em;
background: var(--ifm-color-primary);
margin-left: 4px;
vertical-align: text-bottom;
animation: blink 1s step-end infinite;
} }
.heroSubtitle { .heroSubtitle {
font-size: 1.25rem; font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
font-size: 1.1rem;
color: var(--ifm-color-emphasis-600); color: var(--ifm-color-emphasis-600);
margin: 0; margin: 0 0 1.5rem 0;
} }
.skillTags {
display: flex;
justify-content: center;
gap: 0.75rem;
flex-wrap: wrap;
}
.skillTag {
font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
font-size: 0.8rem;
padding: 0.3rem 0.9rem;
border-radius: 999px;
border: 1px solid var(--ifm-color-primary);
color: var(--ifm-color-primary);
background: transparent;
font-weight: 500;
}
/* ===== Content ===== */
.content { .content {
max-width: 800px; max-width: 960px;
margin: 0 auto; margin: 0 auto;
padding: 2rem; padding: 2rem;
} }
.section { .twoCol {
margin-bottom: 3rem; display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
} }
/* ===== Sections ===== */
.section {
margin-bottom: 3rem;
animation: fadeInUp 0.6s ease both;
}
.section:nth-child(1) { animation-delay: 0.1s; }
.section:nth-child(2) { animation-delay: 0.25s; }
.sectionWorks { animation-delay: 0.4s; }
.sectionTitle { .sectionTitle {
font-size: 1.5rem; font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
font-size: 1.3rem;
margin-bottom: 0.25rem; margin-bottom: 0.25rem;
color: var(--ifm-color-primary);
} }
.sectionDesc { .sectionDesc {
font-size: 0.9rem; font-size: 0.85rem;
color: var(--ifm-color-emphasis-600); color: var(--ifm-color-emphasis-600);
margin-bottom: 1rem; margin-bottom: 1rem;
} }
/* Posts */ /* ===== Post Cards ===== */
.posts { .posts {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1rem; gap: 0.75rem;
} }
.postCard { .postCard {
display: block; display: block;
padding: 1.25rem; padding: 1.1rem 1.25rem;
border-radius: 8px; border-radius: 8px;
background: var(--ifm-background-surface-color); background: var(--ifm-background-surface-color);
border: 1px solid var(--ifm-color-emphasis-200); border: 1px solid var(--ifm-color-emphasis-200);
border-left: 3px solid var(--ifm-color-primary);
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
transition: all 0.2s ease; transition: all 0.2s ease;
@ -65,43 +150,42 @@
.postCard:hover { .postCard:hover {
border-color: var(--ifm-color-primary); border-color: var(--ifm-color-primary);
transform: translateY(-2px); border-left-color: var(--ifm-color-primary);
transform: scale(1.02);
box-shadow: 0 0 16px rgba(var(--ifm-color-primary-rgb, 46,133,85), 0.25);
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
} }
[data-theme='dark'] .postCard:hover {
box-shadow: 0 0 16px rgba(37,194,160,0.25);
}
.postTitle { .postTitle {
font-size: 1.1rem; font-size: 1rem;
margin: 0 0 0.5rem 0; margin: 0 0 0.4rem 0;
} }
.postMeta { .postMeta {
display: flex; display: flex;
gap: 1rem; gap: 0.75rem;
font-size: 0.875rem; font-size: 0.8rem;
color: var(--ifm-color-emphasis-600); color: var(--ifm-color-emphasis-600);
} }
.postDate { .postDate {
font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
} }
.postTag { .postTag {
font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
background: var(--ifm-color-emphasis-100); background: var(--ifm-color-emphasis-100);
padding: 0.125rem 0.5rem; padding: 0.1rem 0.5rem;
border-radius: 4px; border-radius: 4px;
font-size: 0.75rem;
} }
/* Coming Soon */ /* ===== Works ===== */
.comingSoon {
padding: 2rem;
text-align: center;
color: var(--ifm-color-emphasis-500);
background: var(--ifm-background-surface-color);
border: 1px dashed var(--ifm-color-emphasis-300);
border-radius: 8px;
}
/* Works */
.works { .works {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
@ -114,6 +198,7 @@
border-radius: 8px; border-radius: 8px;
background: var(--ifm-background-surface-color); background: var(--ifm-background-surface-color);
border: 1px solid var(--ifm-color-emphasis-200); border: 1px solid var(--ifm-color-emphasis-200);
border-left: 3px solid var(--ifm-color-primary);
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
transition: all 0.2s ease; transition: all 0.2s ease;
@ -121,26 +206,33 @@
.workCard:hover { .workCard:hover {
border-color: var(--ifm-color-primary); border-color: var(--ifm-color-primary);
transform: translateY(-2px); border-left-color: var(--ifm-color-primary);
transform: scale(1.02);
box-shadow: 0 0 16px rgba(var(--ifm-color-primary-rgb, 46,133,85), 0.25);
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
} }
[data-theme='dark'] .workCard:hover {
box-shadow: 0 0 16px rgba(37,194,160,0.25);
}
.workName { .workName {
font-size: 1.1rem; font-size: 1.1rem;
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
} }
.workDescription { .workDescription {
font-size: 0.9rem; font-size: 0.85rem;
color: var(--ifm-color-emphasis-600); color: var(--ifm-color-emphasis-600);
margin: 0; margin: 0;
} }
.moreLink { .moreLink {
display: inline-block; display: inline-block;
margin-top: 1rem; margin-top: 0.75rem;
font-size: 0.9rem; font-size: 0.85rem;
font-family: var(--site-font-mono, 'JetBrains Mono', monospace);
color: var(--ifm-color-primary); color: var(--ifm-color-primary);
} }
@ -148,13 +240,26 @@
text-decoration: underline; text-decoration: underline;
} }
/* Responsive */ /* ===== Responsive ===== */
@media (max-width: 768px) { @media (max-width: 768px) {
.heroTitle { .heroTitle {
font-size: 2rem; font-size: 2rem;
} }
.heroPrompt {
font-size: 0.9rem;
}
.heroSubtitle {
font-size: 0.95rem;
}
.content { .content {
padding: 1rem; padding: 1rem;
} }
.twoCol {
grid-template-columns: 1fr;
gap: 0;
}
} }

View File

@ -7,10 +7,18 @@ function HomepageHeader() {
return ( return (
<header className={styles.hero}> <header className={styles.hero}>
<div className={styles.heroInner}> <div className={styles.heroInner}>
<h1 className={styles.heroTitle}>👋 swallow</h1> <p className={styles.heroPrompt}>$ whoami</p>
<h1 className={styles.heroTitle}>
swallow<span className={styles.cursor} />
</h1>
<p className={styles.heroSubtitle}> <p className={styles.heroSubtitle}>
AI AI
</p> </p>
<div className={styles.skillTags}>
<span className={styles.skillTag}>AI</span>
<span className={styles.skillTag}>Infrastructure</span>
<span className={styles.skillTag}>Development</span>
</div>
</div> </div>
</header> </header>
); );
@ -46,7 +54,7 @@ function RecentTech() {
return ( return (
<section className={styles.section}> <section className={styles.section}>
<h2 className={styles.sectionTitle}>💻 Tech</h2> <h2 className={styles.sectionTitle}>// Tech</h2>
<p className={styles.sectionDesc}></p> <p className={styles.sectionDesc}></p>
<div className={styles.posts}> <div className={styles.posts}>
{posts.map((post, idx) => ( {posts.map((post, idx) => (
@ -69,10 +77,16 @@ function RecentTech() {
function RecentBlog() { function RecentBlog() {
return ( return (
<section className={styles.section}> <section className={styles.section}>
<h2 className={styles.sectionTitle}>📝 Blog</h2> <h2 className={styles.sectionTitle}>// Blog</h2>
<p className={styles.sectionDesc}></p> <p className={styles.sectionDesc}></p>
<div className={styles.posts}> <div className={styles.posts}>
<Link to="/blog/2026-02-19-headline" className={styles.postCard}><h3 className={styles.postTitle}>02/19 AIヘッドライン</h3><div className={styles.postMeta}><span className={styles.postDate}>2026-02-19</span><span className={styles.postTag}>AI</span></div></Link> <Link to="/blog/2026-02-19-headline" className={styles.postCard}>
<h3 className={styles.postTitle}>02/19 AIヘッドライン</h3>
<div className={styles.postMeta}>
<span className={styles.postDate}>2026-02-19</span>
<span className={styles.postTag}>AI</span>
</div>
</Link>
</div> </div>
<Link to="/blog" className={styles.moreLink}> <Link to="/blog" className={styles.moreLink}>
@ -91,8 +105,8 @@ function Works() {
]; ];
return ( return (
<section className={styles.section}> <section className={`${styles.section} ${styles.sectionWorks}`}>
<h2 className={styles.sectionTitle}>🛠 Works</h2> <h2 className={styles.sectionTitle}>// Works</h2>
<p className={styles.sectionDesc}></p> <p className={styles.sectionDesc}></p>
<div className={styles.works}> <div className={styles.works}>
{works.map((work, idx) => ( {works.map((work, idx) => (
@ -124,8 +138,10 @@ export default function Home(): React.JSX.Element {
<main className={styles.main}> <main className={styles.main}>
<HomepageHeader /> <HomepageHeader />
<div className={styles.content}> <div className={styles.content}>
<RecentTech /> <div className={styles.twoCol}>
<RecentBlog /> <RecentTech />
<RecentBlog />
</div>
<Works /> <Works />
</div> </div>
</main> </main>