css refact

This commit is contained in:
2026-03-04 07:46:02 +01:00
parent 5ee3579353
commit af37c38893
8 changed files with 512 additions and 360 deletions
View File
-210
View File
@@ -1,210 +0,0 @@
---
import astroLogo from '../assets/astro.svg';
import background from '../assets/background.svg';
---
<div id="container">
<img id="background" src={background.src} alt="" fetchpriority="high" />
<main>
<section id="hero">
<a href="https://astro.build"
><img src={astroLogo.src} width="115" height="48" alt="Astro Homepage" /></a
>
<h1>
To get started, open the <code><pre>src/pages</pre></code> directory in your project.
</h1>
<section id="links">
<a class="button" href="https://docs.astro.build">Read our docs</a>
<a href="https://astro.build/chat"
>Join our Discord <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"
><path
fill="currentColor"
d="M107.7 8.07A105.15 105.15 0 0 0 81.47 0a72.06 72.06 0 0 0-3.36 6.83 97.68 97.68 0 0 0-29.11 0A72.37 72.37 0 0 0 45.64 0a105.89 105.89 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.73 105.73 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.42 68.42 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2a68.68 68.68 0 0 1-10.87 5.19 77 77 0 0 0 6.89 11.1 105.25 105.25 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15ZM42.45 65.69C36.18 65.69 31 60 31 53s5-12.74 11.43-12.74S54 46 53.89 53s-5.05 12.69-11.44 12.69Zm42.24 0C78.41 65.69 73.25 60 73.25 53s5-12.74 11.44-12.74S96.23 46 96.12 53s-5.04 12.69-11.43 12.69Z"
></path></svg
>
</a>
</section>
</section>
</main>
<a href="https://astro.build/blog/astro-5/" id="news" class="box">
<svg width="32" height="32" fill="none" xmlns="http://www.w3.org/2000/svg"
><path
d="M24.667 12c1.333 1.414 2 3.192 2 5.334 0 4.62-4.934 5.7-7.334 12C18.444 28.567 18 27.456 18 26c0-4.642 6.667-7.053 6.667-14Zm-5.334-5.333c1.6 1.65 2.4 3.43 2.4 5.333 0 6.602-8.06 7.59-6.4 17.334C13.111 27.787 12 25.564 12 22.666c0-4.434 7.333-8 7.333-16Zm-6-5.333C15.111 3.555 16 5.556 16 7.333c0 8.333-11.333 10.962-5.333 22-3.488-.774-6-4-6-8 0-8.667 8.666-10 8.666-20Z"
fill="#111827"></path></svg
>
<h2>What's New in Astro 5.0?</h2>
<p>
From content layers to server islands, click to learn more about the new features and
improvements in Astro 5.0
</p>
</a>
</div>
<style>
#background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
filter: blur(100px);
}
#container {
font-family: Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif;
height: 100%;
}
main {
height: 100%;
display: flex;
justify-content: center;
}
#hero {
display: flex;
align-items: start;
flex-direction: column;
justify-content: center;
padding: 16px;
}
h1 {
font-size: 22px;
margin-top: 0.25em;
}
#links {
display: flex;
gap: 16px;
}
#links a {
display: flex;
align-items: center;
padding: 10px 12px;
color: #111827;
text-decoration: none;
transition: color 0.2s;
}
#links a:hover {
color: rgb(78, 80, 86);
}
#links a svg {
height: 1em;
margin-left: 8px;
}
#links a.button {
color: white;
background: linear-gradient(83.21deg, #3245ff 0%, #bc52ee 100%);
box-shadow:
inset 0 0 0 1px rgba(255, 255, 255, 0.12),
inset 0 -2px 0 rgba(0, 0, 0, 0.24);
border-radius: 10px;
}
#links a.button:hover {
color: rgb(230, 230, 230);
box-shadow: none;
}
pre {
font-family:
ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono',
monospace;
font-weight: normal;
background: linear-gradient(14deg, #d83333 0%, #f041ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin: 0;
}
h2 {
margin: 0 0 1em;
font-weight: normal;
color: #111827;
font-size: 20px;
}
p {
color: #4b5563;
font-size: 16px;
line-height: 24px;
letter-spacing: -0.006em;
margin: 0;
}
code {
display: inline-block;
background:
linear-gradient(66.77deg, #f3cddd 0%, #f5cee7 100%) padding-box,
linear-gradient(155deg, #d83333 0%, #f041ff 18%, #f5cee7 45%) border-box;
border-radius: 8px;
border: 1px solid transparent;
padding: 6px 8px;
}
.box {
padding: 16px;
background: rgba(255, 255, 255, 1);
border-radius: 16px;
border: 1px solid white;
}
#news {
position: absolute;
bottom: 16px;
right: 16px;
max-width: 300px;
text-decoration: none;
transition: background 0.2s;
backdrop-filter: blur(50px);
}
#news:hover {
background: rgba(255, 255, 255, 0.55);
}
@media screen and (max-height: 368px) {
#news {
display: none;
}
}
@media screen and (max-width: 768px) {
#container {
display: flex;
flex-direction: column;
}
#hero {
display: block;
padding-top: 10%;
}
#links {
flex-wrap: wrap;
}
#links a.button {
padding: 14px 18px;
}
#news {
right: 16px;
left: 16px;
bottom: 2.5rem;
max-width: 100%;
}
h1 {
line-height: 1.5;
}
}
</style>
+87 -24
View File
@@ -138,9 +138,9 @@ function timeAgo(dateStr: string): string {
---
<Layout>
<div class="bg-gray-50 min-h-screen pb-20">
<header class="relative overflow-hidden py-24 text-white text-center bg-indigo-900">
<div class="absolute inset-0 opacity-30">
<div class="blog-container">
<header class="blog-header">
<div class="blog-header-decor">
<div class="hero-decor-blob -top-24 -left-24 h-96 w-96 bg-purple-600"></div>
<div class="hero-decor-blob -bottom-24 -right-24 h-96 w-96 bg-blue-600"></div>
</div>
@@ -158,51 +158,50 @@ function timeAgo(dateStr: string): string {
</div>
</header>
<main class="w-full px-4 md:px-8 -mt-12 relative z-10">
<main class="blog-main">
{error && (
<div class="max-w-7xl mx-auto bg-red-50 border-l-4 border-red-500 p-6 rounded-r-xl shadow-lg mb-12 flex items-start gap-4" role="alert">
<div class="error-banner" role="alert">
<span class="text-2xl">⚠️</span>
<div>
<h3 class="text-red-800 font-bold text-lg">Failed to connect to Wiki</h3>
<p class="text-red-700 mt-1">{error}</p>
<h3 class="error-banner-title">Failed to connect to Wiki</h3>
<p class="error-banner-desc">{error}</p>
</div>
</div>
)}
{permissionWarning && (
<div class="max-w-7xl mx-auto bg-amber-50 border-l-4 border-amber-500 p-6 rounded-r-xl shadow-lg mb-12 flex items-start gap-4" role="alert">
<div class="warning-banner" role="alert">
<span class="text-2xl">️</span>
<div>
<h3 class="text-amber-800 font-bold text-lg">Limited Access</h3>
<p class="text-amber-700 mt-1">Full content is hidden because the API token lacks <code>manage:pages</code> or <code>delete:pages</code> permissions in Wiki.js. Showing summaries instead.</p>
<h3 class="warning-banner-title">Limited Access</h3>
<p class="warning-banner-desc">Full content is hidden because the API token lacks <code>manage:pages</code> or <code>delete:pages</code> permissions in Wiki.js. Showing summaries instead.</p>
</div>
</div>
)}
{!error && blogPages.length === 0 && (
<div class="max-w-7xl mx-auto bg-white rounded-2xl shadow-xl p-12 text-center border border-gray-100">
<div class="text-6xl mb-4">📭</div>
<h2 class="text-2xl font-bold text-gray-900 mb-2">No blog posts found</h2>
<p class="text-gray-500 max-w-md mx-auto">We haven't published any blog posts yet. Check back soon!</p>
<div class="empty-state">
<div class="empty-state-icon">📭</div>
<h2 class="empty-state-title">No blog posts found</h2>
<p class="empty-state-desc">We haven't published any blog posts yet. Check back soon!</p>
</div>
)}
{!error && blogPages.length > 0 && (
<div class="flex flex-col gap-12">
<div class="blog-posts-list">
{blogPages.map((page) => {
const pageUrl = `${WIKIJS_BASE_URL}/${page.locale}/${page.path}`;
const isNew = (new Date().getTime() - new Date(page.createdAt).getTime()) < 7 * 24 * 60 * 60 * 1000;
return (
<article class="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">
<div class="p-8 md:p-12">
<div class="flex items-center justify-between mb-6">
<article class="blog-post-card">
<div class="blog-post-content">
<div class="blog-post-meta">
<div class="flex items-center gap-4">
<div class="flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-400">
<div class="blog-post-timestamp">
{isNew && (
<span class="flex items-center gap-1 text-green-600 bg-green-50 px-2 py-0.5 rounded-full border border-green-100">
<span class="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse"></span>
<span class="new-post-badge">
<span class="new-post-dot"></span>
New Post
</span>
)}
@@ -211,14 +210,14 @@ function timeAgo(dateStr: string): string {
</div>
</div>
<h2 class="text-3xl md:text-4xl font-black text-gray-900 mb-8 leading-tight">
<h2 class="blog-post-title">
{page.title}
</h2>
{page.render ? (
<div class="wiki-content prose prose-lg max-w-none text-gray-700 leading-relaxed" set:html={page.render} />
) : (
<div class="text-gray-600 text-lg leading-relaxed whitespace-pre-wrap">
<div class="blog-post-fallback">
{page.description || "No preview available for this post."}
</div>
)}
@@ -232,6 +231,70 @@ function timeAgo(dateStr: string): string {
</div>
</Layout>
<style>
.blog-container {
@apply bg-gray-50 min-h-screen pb-20;
}
.blog-header {
@apply relative overflow-hidden py-24 text-white text-center bg-indigo-900;
}
.blog-header-decor {
@apply absolute inset-0 opacity-30;
}
.blog-main {
@apply w-full px-4 md:px-8 -mt-12 relative z-10;
}
/* Banners */
.banner-base {
@apply max-w-7xl mx-auto border-l-4 p-6 rounded-r-xl shadow-lg mb-12 flex items-start gap-4;
}
.error-banner { @apply banner-base bg-red-50 border-red-500; }
.error-banner-title { @apply text-red-800 font-bold text-lg; }
.error-banner-desc { @apply text-red-700 mt-1; }
.warning-banner { @apply banner-base bg-amber-50 border-amber-500; }
.warning-banner-title { @apply text-amber-800 font-bold text-lg; }
.warning-banner-desc { @apply text-amber-700 mt-1; }
/* Empty State */
.empty-state {
@apply max-w-7xl mx-auto bg-white rounded-2xl shadow-xl p-12 text-center border border-gray-100;
}
.empty-state-icon { @apply text-6xl mb-4; }
.empty-state-title { @apply text-2xl font-bold text-gray-900 mb-2; }
.empty-state-desc { @apply text-gray-500 max-w-md mx-auto; }
/* Posts */
.blog-posts-list {
@apply flex flex-col gap-12;
}
.blog-post-card {
@apply bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden;
}
.blog-post-content {
@apply p-8 md:p-12;
}
.blog-post-meta {
@apply flex items-center justify-between mb-6;
}
.blog-post-timestamp {
@apply flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-400;
}
.new-post-badge {
@apply flex items-center gap-1 text-green-600 bg-green-50 px-2 py-0.5 rounded-full border border-green-100;
}
.new-post-dot {
@apply w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse;
}
.blog-post-title {
@apply text-3xl md:text-4xl font-black text-gray-900 mb-8 leading-tight;
}
.blog-post-fallback {
@apply text-gray-600 text-lg leading-relaxed whitespace-pre-wrap;
}
</style>
<style is:global>
.wiki-content h1 { @apply text-3xl font-bold mt-8 mb-4 text-gray-900; }
.wiki-content h2 { @apply text-2xl font-bold mt-6 mb-3 text-gray-800; }
+143 -50
View File
@@ -18,85 +18,83 @@ const softwares = json.softwares;
<main class="main-container py-12 px-4 grid grid-cols-1 gap-8 mt-0">
{softwares.map(({ software, releases, latestRelease }) => (
<div class="bg-white shadow-lg relative rounded-xl overflow-hidden hover:shadow-2xl transition-shadow duration-300">
<div class="p-6 pr-28 sm:pr-6">
<h2 class="text-2xl font-semibold mb-2">{software.title}</h2>
<p class="text-gray-600 mb-4">{software.desc}</p>
<div class="text-sm text-gray-500 mb-4">
<div class="software-card">
<div class="software-card-content">
<h2 class="software-title">{software.title}</h2>
<p class="software-desc">{software.desc}</p>
<div class="software-meta">
<div>Author: {software.author}</div>
<div>Platform: {software.platform}</div>
</div>
{/* New section for latest release buttons */}
{latestRelease && (
<div class="absolute top-4 right-4 flex flex-col sm:flex-row gap-1 z-10">
<div class="latest-release-actions">
{latestRelease.htmlFolderPath ? (
<a href={BASE + latestRelease.htmlFolderPath} target="_blank" class="inline-block bg-purple-600 hover:bg-purple-700 text-white font-bold py-1 px-2 rounded-lg text-sm transition-colors">▶ Play</a>
<a href={BASE + latestRelease.htmlFolderPath} target="_blank" class="btn-play-sm">▶ Play</a>
) : (
<span class="inline-block bg-gray-200 text-gray-400 font-bold py-1 px-2 rounded-lg text-sm cursor-not-allowed">▶ Play</span>
<span class="btn-disabled-sm">▶ Play</span>
)}
{latestRelease.cartridgePath ? (
<a href={BASE + latestRelease.cartridgePath} target="_blank" class="inline-block bg-blue-600 hover:bg-blue-700 text-white font-bold py-1 px-2 rounded-lg text-sm transition-colors">Download</a>
<a href={BASE + latestRelease.cartridgePath} target="_blank" class="btn-download-sm">Download</a>
) : (
<span class="inline-block bg-gray-200 text-gray-400 font-bold py-1 px-2 rounded-lg text-sm cursor-not-allowed">Download</span>
<span class="btn-disabled-sm">Download</span>
)}
{latestRelease.sourcePath ? (
<a href={BASE + latestRelease.sourcePath} target="_blank" class="inline-block bg-green-600 hover:bg-green-700 text-white font-bold py-1 px-2 rounded-lg text-sm transition-colors">Source</a>
<a href={BASE + latestRelease.sourcePath} target="_blank" class="btn-source-sm">Source</a>
) : (
<span class="inline-block bg-gray-200 text-gray-400 font-bold py-1 px-2 rounded-lg text-sm cursor-not-allowed">Source</span>
<span class="btn-disabled-sm">Source</span>
)}
{latestRelease.docsFolderPath ? (
<a href={BASE + latestRelease.docsFolderPath} target="_blank" class="inline-block bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-1 px-2 rounded-lg text-sm transition-colors">Docs</a>
<a href={BASE + latestRelease.docsFolderPath} target="_blank" class="btn-docs-sm">Docs</a>
) : (
<span class="inline-block bg-gray-200 text-gray-400 font-bold py-1 px-2 rounded-lg text-sm cursor-not-allowed">Docs</span>
<span class="btn-disabled-sm">Docs</span>
)}
</div>
)}
{/* End new section */}
<details class="mt-4">
<summary class="cursor-pointer font-semibold text-purple-600 hover:text-purple-800">
<summary class="releases-summary">
Releases ({releases.length})
</summary>
<div class="mt-4">
{/* Desktop Table View */}
<div class="hidden sm:block overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<div class="desktop-releases">
<table class="releases-table">
<thead class="releases-thead">
<tr>
<th scope="col" class="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Version</th>
<th scope="col" class="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
<th scope="col" class="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
<th scope="col" class="releases-th">Version</th>
<th scope="col" class="releases-th">Date</th>
<th scope="col" class="releases-th text-right">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<tbody class="releases-tbody">
{releases.map((release) => (
<tr>
<td class="px-3 py-2 whitespace-nowrap text-sm font-medium text-gray-900">{release.version}</td>
<td class="px-3 py-2 whitespace-nowrap text-sm text-gray-500">
<td class="releases-td font-medium text-gray-900">{release.version}</td>
<td class="releases-td text-gray-500">
{new Date(release.CreatedAt).toLocaleDateString('en-US')}
</td>
<td class="px-3 py-2 whitespace-nowrap text-right text-sm font-medium">
<td class="releases-td text-right">
{release.htmlFolderPath ? (
<a href={BASE + release.htmlFolderPath} target="_blank" class="text-purple-600 hover:text-purple-900 mr-2">▶ Play</a>
<a href={BASE + release.htmlFolderPath} target="_blank" class="action-link-purple">▶ Play</a>
) : (
<span class="text-gray-400 cursor-not-allowed mr-2">▶ Play</span>
<span class="action-link-disabled">▶ Play</span>
)}
{release.cartridgePath ? (
<a href={BASE + release.cartridgePath} target="_blank" class="text-blue-600 hover:text-blue-900 mr-2">Download</a>
<a href={BASE + release.cartridgePath} target="_blank" class="action-link-blue">Download</a>
) : (
<span class="text-gray-400 cursor-not-allowed mr-2">Download</span>
<span class="action-link-disabled">Download</span>
)}
{release.sourcePath ? (
<a href={BASE + release.sourcePath} target="_blank" class="text-green-600 hover:text-green-900 mr-2">Source</a>
<a href={BASE + release.sourcePath} target="_blank" class="action-link-green">Source</a>
) : (
<span class="text-gray-400 cursor-not-allowed mr-2">Source</span>
<span class="action-link-disabled">Source</span>
)}
{release.docsFolderPath ? (
<a href={BASE + release.docsFolderPath} target="_blank" class="text-yellow-600 hover:text-yellow-900">Docs</a>
<a href={BASE + release.docsFolderPath} target="_blank" class="action-link-yellow">Docs</a>
) : (
<span class="text-gray-400 cursor-not-allowed">Docs</span>
<span class="action-link-disabled">Docs</span>
)}
</td>
</tr>
@@ -106,33 +104,33 @@ const softwares = json.softwares;
</div>
{/* Mobile Stacked View */}
<div class="sm:hidden space-y-4">
<div class="mobile-releases">
{releases.map((release) => (
<div class="border border-gray-100 rounded-lg p-4 bg-gray-50 shadow-sm">
<div class="flex flex-col mb-3 border-b border-gray-200 pb-2">
<span class="font-bold text-gray-900 text-lg break-words">v{release.version}</span>
<span class="text-xs text-gray-500 mt-1">{new Date(release.CreatedAt).toLocaleDateString('en-US')}</span>
<div class="release-mobile-card">
<div class="release-mobile-header">
<span class="release-mobile-version">v{release.version}</span>
<span class="release-mobile-date">{new Date(release.CreatedAt).toLocaleDateString('en-US')}</span>
</div>
<div class="grid grid-cols-2 gap-2">
<div class="release-mobile-grid">
{release.htmlFolderPath ? (
<a href={BASE + release.htmlFolderPath} target="_blank" class="flex items-center justify-center bg-purple-600 text-white py-2 px-3 rounded text-sm font-bold shadow-sm">▶ Play</a>
<a href={BASE + release.htmlFolderPath} target="_blank" class="mobile-btn-play">▶ Play</a>
) : (
<span class="flex items-center justify-center bg-gray-200 text-gray-400 py-2 px-3 rounded text-sm font-bold cursor-not-allowed">▶ Play</span>
<span class="mobile-btn-disabled">▶ Play</span>
)}
{release.cartridgePath ? (
<a href={BASE + release.cartridgePath} target="_blank" class="flex items-center justify-center bg-blue-600 text-white py-2 px-3 rounded text-sm font-bold shadow-sm">Download</a>
<a href={BASE + release.cartridgePath} target="_blank" class="mobile-btn-download">Download</a>
) : (
<span class="flex items-center justify-center bg-gray-200 text-gray-400 py-2 px-3 rounded text-sm font-bold cursor-not-allowed">Download</span>
<span class="mobile-btn-disabled">Download</span>
)}
{release.sourcePath ? (
<a href={BASE + release.sourcePath} target="_blank" class="flex items-center justify-center bg-green-600 text-white py-2 px-3 rounded text-sm font-bold shadow-sm">Source</a>
<a href={BASE + release.sourcePath} target="_blank" class="mobile-btn-source">Source</a>
) : (
<span class="flex items-center justify-center bg-gray-200 text-gray-400 py-2 px-3 rounded text-sm font-bold cursor-not-allowed">Source</span>
<span class="mobile-btn-disabled">Source</span>
)}
{release.docsFolderPath ? (
<a href={BASE + release.docsFolderPath} target="_blank" class="flex items-center justify-center bg-yellow-600 text-white py-2 px-3 rounded text-sm font-bold shadow-sm">Docs</a>
<a href={BASE + release.docsFolderPath} target="_blank" class="mobile-btn-docs">Docs</a>
) : (
<span class="flex items-center justify-center bg-gray-200 text-gray-400 py-2 px-3 rounded text-sm font-bold cursor-not-allowed">Docs</span>
<span class="mobile-btn-disabled">Docs</span>
)}
</div>
</div>
@@ -144,4 +142,99 @@ const softwares = json.softwares;
</div>
))}
</main>
</Layout>
</Layout>
<style>
.software-card {
@apply bg-white shadow-lg relative rounded-xl overflow-hidden hover:shadow-2xl transition-shadow duration-300;
}
.software-card-content {
@apply p-6 pr-28 sm:pr-6;
}
.software-title {
@apply text-2xl font-semibold mb-2;
}
.software-desc {
@apply text-gray-600 mb-4;
}
.software-meta {
@apply text-sm text-gray-500 mb-4;
}
.latest-release-actions {
@apply absolute top-4 right-4 flex flex-col sm:flex-row gap-1 z-10;
}
/* Small Action Buttons */
.btn-base-sm {
@apply inline-block font-bold py-1 px-2 rounded-lg text-sm transition-colors;
}
.btn-play-sm { @apply btn-base-sm bg-purple-600 hover:bg-purple-700 text-white; }
.btn-download-sm { @apply btn-base-sm bg-blue-600 hover:bg-blue-700 text-white; }
.btn-source-sm { @apply btn-base-sm bg-green-600 hover:bg-green-700 text-white; }
.btn-docs-sm { @apply btn-base-sm bg-yellow-600 hover:bg-yellow-700 text-white; }
.btn-disabled-sm { @apply btn-base-sm bg-gray-200 text-gray-400 cursor-not-allowed; }
.releases-summary {
@apply cursor-pointer font-semibold text-purple-600 hover:text-purple-800;
}
/* Desktop Table Styles */
.desktop-releases {
@apply hidden sm:block overflow-x-auto;
}
.releases-table {
@apply min-w-full divide-y divide-gray-200;
}
.releases-thead {
@apply bg-gray-50;
}
.releases-th {
@apply px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider;
}
.releases-tbody {
@apply bg-white divide-y divide-gray-200;
}
.releases-td {
@apply px-3 py-2 whitespace-nowrap text-sm;
}
/* Action Links */
.action-link-base {
@apply hover:underline mr-2 last:mr-0;
}
.action-link-purple { @apply action-link-base text-purple-600 hover:text-purple-900; }
.action-link-blue { @apply action-link-base text-blue-600 hover:text-blue-900; }
.action-link-green { @apply action-link-base text-green-600 hover:text-green-900; }
.action-link-yellow { @apply action-link-base text-yellow-600 hover:text-yellow-900; }
.action-link-disabled { @apply text-gray-400 cursor-not-allowed mr-2 last:mr-0; }
/* Mobile Release Styles */
.mobile-releases {
@apply sm:hidden space-y-4;
}
.release-mobile-card {
@apply border border-gray-100 rounded-lg p-4 bg-gray-50 shadow-sm;
}
.release-mobile-header {
@apply flex flex-col mb-3 border-b border-gray-200 pb-2;
}
.release-mobile-version {
@apply font-bold text-gray-900 text-lg break-words;
}
.release-mobile-date {
@apply text-xs text-gray-500 mt-1;
}
.release-mobile-grid {
@apply grid grid-cols-2 gap-2;
}
/* Mobile Buttons */
.mobile-btn-base {
@apply flex items-center justify-center py-2 px-3 rounded text-sm font-bold shadow-sm;
}
.mobile-btn-play { @apply mobile-btn-base bg-purple-600 text-white; }
.mobile-btn-download { @apply mobile-btn-base bg-blue-600 text-white; }
.mobile-btn-source { @apply mobile-btn-base bg-green-600 text-white; }
.mobile-btn-docs { @apply mobile-btn-base bg-yellow-600 text-white; }
.mobile-btn-disabled { @apply mobile-btn-base bg-gray-200 text-gray-400 cursor-not-allowed; }
</style>
+68 -16
View File
@@ -135,7 +135,7 @@ const recentCommits = allCommits.slice(0, 20);
<main class="main-container">
{error && (
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-8" role="alert">
<div class="error-alert" role="alert">
<strong class="font-bold">Error!</strong>
<span class="block sm:inline"> {error}</span>
</div>
@@ -145,43 +145,43 @@ const recentCommits = allCommits.slice(0, 20);
<div class="card-grid mb-16">
{publicRepos.map((repo) => (
<div class="card-base">
<h3 class="text-xl font-semibold mb-2">
<a href={repo.html_url} target="_blank" class="text-blue-600 hover:text-blue-800">
<h3 class="repo-card-title">
<a href={repo.html_url} target="_blank" class="repo-link">
{repo.owner.login}/{repo.name}
</a>
</h3>
{repo.description && <p class="text-gray-700 text-sm">{repo.description}</p>}
{repo.language && <p class="text-gray-500 text-xs mt-1">Language: {repo.language}</p>}
<p class="text-gray-500 text-xs mt-1">Updated: {new Date(repo.updated_at).toLocaleDateString('en-US', {year: 'numeric', month: 'short', day: 'numeric'})}</p>
{repo.description && <p class="repo-card-desc">{repo.description}</p>}
{repo.language && <p class="repo-card-meta">Language: {repo.language}</p>}
<p class="repo-card-meta">Updated: {new Date(repo.updated_at).toLocaleDateString('en-US', {year: 'numeric', month: 'short', day: 'numeric'})}</p>
</div>
))}
</div>
)}
<h2 class="text-3xl font-bold mb-8 text-center text-gray-800">Recent Commits</h2>
<h2 class="commits-section-title">Recent Commits</h2>
{!error && recentCommits.length === 0 && (
<p class="text-center text-gray-600 text-lg">No recent commits found or accessible from public repositories.</p>
<p class="empty-commits-msg">No recent commits found or accessible from public repositories.</p>
)}
<div class="space-y-4 mb-12">
<div class="commits-list">
{recentCommits.map((commit) => (
<div class="bg-white shadow-lg rounded-lg p-4 flex items-center space-x-4 border border-gray-100">
<div class="flex-shrink-0 text-3xl">
<div class="commit-item">
<div class="commit-icon">
🚀
</div>
<div class="flex-grow">
<p class="text-gray-800 font-semibold">
<a href={commit.repo.html_url} target="_blank" class="text-blue-600 hover:text-blue-800">
<div class="commit-content">
<p class="commit-message">
<a href={commit.repo.html_url} target="_blank" class="commit-repo-link">
<span class="font-bold">{commit.repo.owner}</span> / <span class="font-bold">{commit.repo.name}</span>
</a>
: <span class="text-gray-700">{commit.message.split('\n')[0]}</span>
</p>
<p class="text-gray-600 text-sm mt-1">
<p class="commit-meta">
Authored by <span class="font-bold">{commit.author.name}</span> on {new Date(commit.date).toLocaleDateString('en-US', {
year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit'
})}
<a href={commit.url} target="_blank" class="ml-2 text-blue-500 hover:text-blue-700">
<a href={commit.url} target="_blank" class="commit-sha-link">
<span class="font-mono text-xs">{commit.sha.substring(0, 7)}</span>
</a>
</p>
@@ -191,3 +191,55 @@ const recentCommits = allCommits.slice(0, 20);
</div>
</main>
</Layout>
<style>
.error-alert {
@apply bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-8;
}
/* Repo Cards */
.repo-card-title {
@apply text-xl font-semibold mb-2;
}
.repo-link {
@apply text-blue-600 hover:text-blue-800;
}
.repo-card-desc {
@apply text-gray-700 text-sm;
}
.repo-card-meta {
@apply text-gray-500 text-xs mt-1;
}
/* Commits */
.commits-section-title {
@apply text-3xl font-bold mb-8 text-center text-gray-800;
}
.empty-commits-msg {
@apply text-center text-gray-600 text-lg;
}
.commits-list {
@apply space-y-4 mb-12;
}
.commit-item {
@apply bg-white shadow-lg rounded-lg p-4 flex items-center space-x-4 border border-gray-100;
}
.commit-icon {
@apply flex-shrink-0 text-3xl;
}
.commit-content {
@apply flex-grow;
}
.commit-message {
@apply text-gray-800 font-semibold;
}
.commit-repo-link {
@apply text-blue-600 hover:text-blue-800;
}
.commit-meta {
@apply text-gray-600 text-sm mt-1;
}
.commit-sha-link {
@apply ml-2 text-blue-500 hover:text-blue-700;
}
</style>
+60 -18
View File
@@ -14,7 +14,7 @@ const DISCORD_INVITE_LINK = import.meta.env.DISCORD_INVITE_LINK || "https://disc
<a
href={DISCORD_INVITE_LINK}
target="_blank"
class="inline-flex items-center gap-3 bg-[#5865F2] hover:bg-[#4752C4] text-white font-black py-4 px-8 rounded-full text-lg transition-all transform hover:scale-105 shadow-xl"
class="discord-hero-btn"
>
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037 19.736 19.736 0 0 0-4.885 1.515.069.069 0 0 0-.032.027C.533 9.048-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.862-1.297 1.197-1.99.051-.105.001-.23-.106-.272a13.223 13.223 0 0 1-1.878-.894.077.077 0 0 1-.007-.128c.126-.094.252-.192.372-.29a.074.074 0 0 1 .077-.01c3.927 1.793 8.18 1.793 12.061 0a.074.074 0 0 1 .077.01c.12.098.246.196.373.29a.077.077 0 0 1-.006.128 12.299 12.299 0 0 1-1.878.894.077.077 0 0 0-.106.272c.335.693.735 1.36 1.197 1.99a.078.078 0 0 0 .084.028 19.83 19.83 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.182 0-2.156-1.085-2.156-2.419 0-1.333.956-2.419 2.156-2.419 1.21 0 2.176 1.096 2.156 2.419 0 1.334-.956 2.419-2.156 2.419zm7.974 0c-1.182 0-2.156-1.085-2.156-2.419 0-1.333.955-2.419 2.156-2.419 1.21 0 2.176 1.096 2.156 2.419 0 1.334-.946 2.419-2.156 2.419z"/>
@@ -25,15 +25,15 @@ const DISCORD_INVITE_LINK = import.meta.env.DISCORD_INVITE_LINK || "https://disc
</header>
<main class="main-container py-16 px-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 max-w-5xl mx-auto">
<div class="bg-white p-8 rounded-2xl shadow-xl border border-gray-100">
<h2 class="text-2xl font-black text-gray-900 mb-6 flex items-center gap-3">
<div class="contact-grid">
<div class="contact-card">
<h2 class="contact-card-title">
<span class="text-3xl">📧</span> Email Us
</h2>
<p class="text-gray-600 mb-6 leading-relaxed">
<p class="contact-card-desc">
For business inquiries, support, or detailed feedback, feel free to drop us an email.
</p>
<div id="email-container" class="text-indigo-600 font-bold text-xl hover:underline cursor-pointer transition-all">
<div id="email-container" class="email-link">
<span class="opacity-50 text-sm font-normal italic">Loading email...</span>
</div>
@@ -52,28 +52,28 @@ const DISCORD_INVITE_LINK = import.meta.env.DISCORD_INVITE_LINK || "https://disc
</script>
</div>
<div class="bg-white p-8 rounded-2xl shadow-xl border border-gray-100">
<h2 class="text-2xl font-black text-gray-900 mb-6 flex items-center gap-3">
<div class="contact-card">
<h2 class="contact-card-title">
<span class="text-3xl">💬</span> Community
</h2>
<p class="text-gray-600 mb-8 leading-relaxed">
<p class="contact-card-desc mb-8">
Join our primarily Hungarian-speaking community (English speakers are also welcome!).
</p>
<div class="space-y-8">
<div class="border-l-4 border-[#5865F2] pl-4">
<h3 class="text-lg font-bold text-gray-900 mb-2">Discord</h3>
<p class="text-gray-600 text-sm mb-3">We have a vibrant Discord server for real-time chat and support.</p>
<a href={DISCORD_INVITE_LINK} target="_blank" class="text-[#5865F2] font-bold hover:underline inline-flex items-center gap-1">
<div class="community-section border-[#5865F2]">
<h3 class="community-section-title">Discord</h3>
<p class="community-section-desc">We have a vibrant Discord server for real-time chat and support.</p>
<a href={DISCORD_INVITE_LINK} target="_blank" class="community-link-discord">
Join Discord Server <span>→</span>
</a>
</div>
<div class="border-l-4 border-indigo-600 pl-4">
<h3 class="text-lg font-bold text-gray-900 mb-2">IRC Chat</h3>
<div class="bg-indigo-50 p-4 rounded-xl border border-indigo-100 mt-3 inline-block">
<span class="block text-xs font-semibold text-indigo-400 uppercase tracking-wider mb-1">Network: Libera.Chat</span>
<code class="text-indigo-600 font-mono text-lg font-bold">#teletypegames</code>
<div class="community-section border-indigo-600">
<h3 class="community-section-title">IRC Chat</h3>
<div class="irc-box">
<span class="irc-network">Network: Libera.Chat</span>
<code class="irc-channel">#teletypegames</code>
</div>
</div>
</div>
@@ -81,3 +81,45 @@ const DISCORD_INVITE_LINK = import.meta.env.DISCORD_INVITE_LINK || "https://disc
</div>
</main>
</Layout>
<style>
.discord-hero-btn {
@apply inline-flex items-center gap-3 bg-[#5865F2] hover:bg-[#4752C4] text-white font-black py-4 px-8 rounded-full text-lg transition-all transform hover:scale-105 shadow-xl;
}
.contact-grid {
@apply grid grid-cols-1 md:grid-cols-2 gap-12 max-w-5xl mx-auto;
}
.contact-card {
@apply bg-white p-8 rounded-2xl shadow-xl border border-gray-100;
}
.contact-card-title {
@apply text-2xl font-black text-gray-900 mb-6 flex items-center gap-3;
}
.contact-card-desc {
@apply text-gray-600 mb-6 leading-relaxed;
}
.email-link {
@apply text-indigo-600 font-bold text-xl hover:underline cursor-pointer transition-all;
}
.community-section {
@apply border-l-4 pl-4;
}
.community-section-title {
@apply text-lg font-bold text-gray-900 mb-2;
}
.community-section-desc {
@apply text-gray-600 text-sm mb-3;
}
.community-link-discord {
@apply text-[#5865F2] font-bold hover:underline inline-flex items-center gap-1;
}
.irc-box {
@apply bg-indigo-50 p-4 rounded-xl border border-indigo-100 mt-3 inline-block;
}
.irc-network {
@apply block text-xs font-semibold text-indigo-400 uppercase tracking-wider mb-1;
}
.irc-channel {
@apply text-indigo-600 font-mono text-lg font-bold;
}
</style>
+85 -21
View File
@@ -94,10 +94,10 @@ function timeAgo(dateStr: string): string {
---
<Layout>
<div class="bg-gray-50 min-h-screen pb-20">
<div class="howtos-container">
<header class="hero-section-slate">
<!-- Decorative background elements -->
<div class="absolute inset-0 opacity-30">
<div class="howtos-header-decor">
<div class="hero-decor-blob -top-24 -left-24 h-96 w-96 bg-indigo-600"></div>
<div class="hero-decor-blob -bottom-24 -right-24 h-96 w-96 bg-purple-600"></div>
</div>
@@ -125,20 +125,20 @@ function timeAgo(dateStr: string): string {
<main class="main-container">
{error && (
<div class="bg-red-50 border-l-4 border-red-500 p-6 rounded-r-xl shadow-lg mb-12 flex items-start gap-4" role="alert">
<div class="error-banner" role="alert">
<span class="text-2xl">⚠️</span>
<div>
<h3 class="text-red-800 font-bold text-lg">Failed to connect to Wiki</h3>
<p class="text-red-700 mt-1">{error}</p>
<h3 class="error-banner-title">Failed to connect to Wiki</h3>
<p class="error-banner-desc">{error}</p>
</div>
</div>
)}
{!error && recentPages.length === 0 && (
<div class="bg-white rounded-2xl shadow-xl p-12 text-center border border-gray-100">
<div class="text-6xl mb-4">📭</div>
<h2 class="text-2xl font-bold text-gray-900 mb-2">No pages found</h2>
<p class="text-gray-500 max-w-md mx-auto">It seems like there aren't any public pages available on the wiki at the moment.</p>
<div class="empty-state">
<div class="empty-state-icon">📭</div>
<h2 class="empty-state-title">No pages found</h2>
<p class="empty-state-desc">It seems like there aren't any public pages available on the wiki at the moment.</p>
</div>
)}
@@ -154,11 +154,11 @@ function timeAgo(dateStr: string): string {
target="_blank"
class="group card-interactive flex flex-col"
>
<div class="flex items-center justify-end mb-4">
<div class="flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-400">
<div class="howto-card-meta">
<div class="howto-card-timestamp">
{isNew && (
<span class="flex items-center gap-1 text-green-600 bg-green-50 px-2 py-0.5 rounded-full border border-green-100">
<span class="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse"></span>
<span class="new-badge">
<span class="new-dot"></span>
New
</span>
)}
@@ -166,23 +166,23 @@ function timeAgo(dateStr: string): string {
</div>
</div>
<h2 class="text-xl font-bold text-gray-900 group-hover:text-indigo-600 transition-colors mb-2 line-clamp-2 leading-tight">
<h2 class="howto-card-title">
{page.title}
</h2>
{page.description ? (
<p class="text-gray-600 text-sm mb-4 line-clamp-3 leading-relaxed flex-grow">
<p class="howto-card-desc">
{page.description}
</p>
) : (
<div class="flex-grow mb-4 italic text-gray-400 text-sm">No description provided.</div>
<div class="howto-card-no-desc">No description provided.</div>
)}
<div class="pt-4 border-t border-gray-100 mt-auto flex items-center justify-between">
<span class="text-xs font-mono text-gray-400 truncate max-w-[180px]">
<div class="howto-card-footer">
<span class="howto-card-path">
{page.path}
</span>
<span class="text-indigo-600 text-sm font-bold flex items-center gap-1 group-hover:translate-x-1 transition-transform">
<span class="howto-card-read-link">
Read <span class="text-lg">→</span>
</span>
</div>
@@ -193,11 +193,11 @@ function timeAgo(dateStr: string): string {
)}
{!error && recentPages.length > 0 && (
<div class="mt-16 text-center">
<div class="howtos-footer">
<a
href={WIKIJS_BASE_URL}
target="_blank"
class="inline-flex items-center gap-2 bg-slate-900 text-white px-8 py-4 rounded-xl hover:bg-slate-800 transition-all font-bold shadow-lg hover:shadow-indigo-200/50"
class="browse-wiki-btn"
>
Browse Wiki Home
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
@@ -209,3 +209,67 @@ function timeAgo(dateStr: string): string {
</main>
</div>
</Layout>
<style>
.howtos-container {
@apply bg-gray-50 min-h-screen pb-20;
}
.howtos-header-decor {
@apply absolute inset-0 opacity-30;
}
/* Banners */
.banner-base {
@apply max-w-7xl mx-auto border-l-4 p-6 rounded-r-xl shadow-lg mb-12 flex items-start gap-4;
}
.error-banner { @apply banner-base bg-red-50 border-red-500; }
.error-banner-title { @apply text-red-800 font-bold text-lg; }
.error-banner-desc { @apply text-red-700 mt-1; }
/* Empty State */
.empty-state {
@apply max-w-7xl mx-auto bg-white rounded-2xl shadow-xl p-12 text-center border border-gray-100;
}
.empty-state-icon { @apply text-6xl mb-4; }
.empty-state-title { @apply text-2xl font-bold text-gray-900 mb-2; }
.empty-state-desc { @apply text-gray-500 max-w-md mx-auto; }
/* Cards */
.howto-card-meta {
@apply flex items-center justify-end mb-4;
}
.howto-card-timestamp {
@apply flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-400;
}
.new-badge {
@apply flex items-center gap-1 text-green-600 bg-green-50 px-2 py-0.5 rounded-full border border-green-100;
}
.new-dot {
@apply w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse;
}
.howto-card-title {
@apply text-xl font-bold text-gray-900 group-hover:text-indigo-600 transition-colors mb-2 line-clamp-2 leading-tight;
}
.howto-card-desc {
@apply text-gray-600 text-sm mb-4 line-clamp-3 leading-relaxed flex-grow;
}
.howto-card-no-desc {
@apply flex-grow mb-4 italic text-gray-400 text-sm;
}
.howto-card-footer {
@apply pt-4 border-t border-gray-100 mt-auto flex items-center justify-between;
}
.howto-card-path {
@apply text-xs font-mono text-gray-400 truncate max-w-[180px];
}
.howto-card-read-link {
@apply text-indigo-600 text-sm font-bold flex items-center gap-1 group-hover:translate-x-1 transition-transform;
}
.howtos-footer {
@apply mt-16 text-center;
}
.browse-wiki-btn {
@apply inline-flex items-center gap-2 bg-slate-900 text-white px-8 py-4 rounded-xl hover:bg-slate-800 transition-all font-bold shadow-lg hover:shadow-indigo-200/50;
}
</style>
+69 -21
View File
@@ -66,10 +66,10 @@ try {
---
<Layout>
<div class="bg-gray-50 min-h-screen pb-20">
<div class="home-container">
<!-- Header Section -->
<header class="hero-section-slate">
<div class="absolute inset-0 opacity-30">
<div class="home-header-decor">
<div class="hero-decor-blob -top-24 -left-24 h-96 w-96 bg-indigo-600"></div>
<div class="hero-decor-blob -bottom-24 -right-24 h-96 w-96 bg-purple-600"></div>
</div>
@@ -91,19 +91,19 @@ try {
<!-- Countdown Section -->
{nextEvent && (
<section class="mb-12">
<div class="bg-white rounded-2xl shadow-xl overflow-hidden border border-gray-100 p-8 md:p-12 text-center transition-all duration-300">
<h2 class="text-2xl font-bold text-gray-400 uppercase tracking-widest mb-2">{nextEvent.name}</h2>
<div id="countdown" data-date={nextEvent.dateISO} class="text-5xl md:text-7xl font-mono font-black text-transparent bg-clip-text bg-gradient-to-r from-violet-600 to-fuchsia-600 my-6">
<div class="countdown-card">
<h2 class="countdown-event-name">{nextEvent.name}</h2>
<div id="countdown" data-date={nextEvent.dateISO} class="countdown-timer">
-- : -- : -- : --
</div>
<p class="text-gray-500 text-lg">Starts on: <span class="font-semibold">{nextEvent.dateText}</span></p>
<p class="countdown-date">Starts on: <span class="font-semibold">{nextEvent.dateText}</span></p>
{followingEvents.length > 0 && (
<div class="mt-12 pt-12 border-t border-gray-100 text-left max-w-2xl mx-auto">
<h3 class="text-xl font-bold text-gray-900 mb-6">Upcoming Events</h3>
<div class="upcoming-events-section">
<h3 class="upcoming-events-title">Upcoming Events</h3>
<div class="space-y-4">
{followingEvents.map(event => (
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-xl border border-gray-100">
<div class="upcoming-event-item">
<span class="font-bold text-gray-800">{event.name}</span>
<span class="text-sm text-gray-500 font-mono">{event.dateText}</span>
</div>
@@ -118,36 +118,36 @@ try {
<!-- Navigation Grid -->
<section class="card-grid">
<!-- Catalog Section -->
<div class="group card-interactive flex flex-col h-full">
<div class="w-14 h-14 bg-purple-50 rounded-xl flex items-center justify-center mb-6 group-hover:bg-purple-100 transition-colors">
<div class="nav-card group">
<div class="nav-card-icon bg-purple-50 group-hover:bg-purple-100">
<span class="text-3xl">🎮</span>
</div>
<h2 class="text-2xl font-bold text-gray-900 mb-3">Catalog</h2>
<p class="text-gray-600 mb-6 flex-grow leading-relaxed">Here you can find our games. Discover our creations for TIC-80 and other platforms, many of which you can try directly in your browser.</p>
<h2 class="nav-card-title">Catalog</h2>
<p class="nav-card-desc">Here you can find our games. Discover our creations for TIC-80 and other platforms, many of which you can try directly in your browser.</p>
<a href="/catalog" class="btn-primary bg-purple-600 hover:bg-purple-700 text-white hover:shadow-purple-200">
Browse Games
</a>
</div>
<!-- Wiki Section -->
<div class="group card-interactive flex flex-col h-full">
<div class="w-14 h-14 bg-green-50 rounded-xl flex items-center justify-center mb-6 group-hover:bg-green-100 transition-colors">
<div class="nav-card group">
<div class="nav-card-icon bg-green-50 group-hover:bg-green-100">
<span class="text-3xl">📚</span>
</div>
<h2 class="text-2xl font-bold text-gray-900 mb-3">Wiki</h2>
<p class="text-gray-600 mb-6 flex-grow leading-relaxed">We gather our public interest development knowledge here. Read through technical descriptions and development logs.</p>
<h2 class="nav-card-title">Wiki</h2>
<p class="nav-card-desc">We gather our public interest development knowledge here. Read through technical descriptions and development logs.</p>
<a href="https://wiki.teletype.hu" target="_blank" rel="noopener noreferrer" class="btn-primary bg-green-600 hover:bg-green-700 text-white hover:shadow-green-200">
Knowledge Base
</a>
</div>
<!-- Git Section -->
<div class="group card-interactive flex flex-col h-full">
<div class="w-14 h-14 bg-slate-50 rounded-xl flex items-center justify-center mb-6 group-hover:bg-slate-100 transition-colors">
<div class="nav-card group">
<div class="nav-card-icon bg-slate-50 group-hover:bg-slate-100">
<span class="text-3xl">💻</span>
</div>
<h2 class="text-2xl font-bold text-gray-900 mb-3">Git Repos</h2>
<p class="text-gray-600 mb-6 flex-grow leading-relaxed">All our projects are open source. Browse our code, study our solutions, or even participate in the development.</p>
<h2 class="nav-card-title">Git Repos</h2>
<p class="nav-card-desc">All our projects are open source. Browse our code, study our solutions, or even participate in the development.</p>
<a href="https://git.teletype.hu" target="_blank" rel="noopener noreferrer" class="btn-primary bg-slate-800 hover:bg-slate-900 text-white hover:shadow-slate-200">
Gitea
</a>
@@ -157,6 +157,54 @@ try {
</div>
</Layout>
<style>
.home-container {
@apply bg-gray-50 min-h-screen pb-20;
}
.home-header-decor {
@apply absolute inset-0 opacity-30;
}
/* Countdown Card */
.countdown-card {
@apply bg-white rounded-2xl shadow-xl overflow-hidden border border-gray-100 p-8 md:p-12 text-center transition-all duration-300;
}
.countdown-event-name {
@apply text-2xl font-bold text-gray-400 uppercase tracking-widest mb-2;
}
.countdown-timer {
@apply text-5xl md:text-7xl font-mono font-black text-transparent bg-clip-text bg-gradient-to-r from-violet-600 to-fuchsia-600 my-6;
}
.countdown-date {
@apply text-gray-500 text-lg;
}
/* Upcoming Events */
.upcoming-events-section {
@apply mt-12 pt-12 border-t border-gray-100 text-left max-w-2xl mx-auto;
}
.upcoming-events-title {
@apply text-xl font-bold text-gray-900 mb-6;
}
.upcoming-event-item {
@apply flex items-center justify-between p-4 bg-gray-50 rounded-xl border border-gray-100;
}
/* Nav Cards */
.nav-card {
@apply card-interactive flex flex-col h-full;
}
.nav-card-icon {
@apply w-14 h-14 rounded-xl flex items-center justify-center mb-6 transition-colors;
}
.nav-card-title {
@apply text-2xl font-bold text-gray-900 mb-3;
}
.nav-card-desc {
@apply text-gray-600 mb-6 flex-grow leading-relaxed;
}
</style>
<script>
function updateCountdown() {
const countdownElement = document.getElementById('countdown');