added changelog and blog to astro site

This commit is contained in:
Ramon Perez 2025-08-07 18:09:51 +10:00
parent 06941b932d
commit 179c1f66b7
37 changed files with 3138 additions and 277 deletions

BIN
blog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
clog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

BIN
clog10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
clog11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
clog12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
clog13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
clog2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

BIN
clog3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
clog4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
clog5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
clog6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
clog7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
clog8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
clog9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -1,7 +1,8 @@
// @ts-check
import { defineConfig } from 'astro/config'
import starlight from '@astrojs/starlight'
import starlightThemeRapide from 'starlight-theme-rapide'
import starlightThemeNext from 'starlight-theme-next'
// import starlightThemeRapide from 'starlight-theme-rapide'
import starlightSidebarTopics from 'starlight-sidebar-topics'
import mermaid from 'astro-mermaid'
@ -19,7 +20,8 @@ export default defineConfig({
title: '👋 Jan',
favicon: 'jan2.png',
plugins: [
starlightThemeRapide(),
// starlightThemeRapide(),
starlightThemeNext(),
starlightSidebarTopics(
[
{
@ -144,14 +146,14 @@ export default defineConfig({
{
label: 'Jan Mobile',
link: '/mobile/',
badge: { text: 'Coming Soon', variant: 'caution' },
badge: { text: 'Soon', variant: 'caution' },
icon: 'phone',
items: [{ label: 'Overview', slug: 'mobile' }],
},
{
label: 'Jan Server',
link: '/server/',
badge: { text: 'Coming Soon', variant: 'caution' },
badge: { text: 'Soon', variant: 'caution' },
icon: 'forward-slash',
items: [{ label: 'Overview', slug: 'server' }],
},

View File

@ -14,6 +14,7 @@
"sharp": "^0.34.3",
"starlight-openapi": "^0.19.1",
"starlight-sidebar-topics": "^0.6.0",
"starlight-theme-next": "^0.3.2",
"starlight-theme-rapide": "^0.5.1",
"starlight-videos": "^0.3.0",
},
@ -1076,6 +1077,8 @@
"starlight-sidebar-topics": ["starlight-sidebar-topics@0.6.0", "", { "dependencies": { "picomatch": "^4.0.2" }, "peerDependencies": { "@astrojs/starlight": ">=0.32.0" } }, "sha512-ysmOR7zaHYKtk18/mpW4MbEMDioR/ZBsisu9bdQrq0v9BlHWpW7gAdWlqFWO9zdv1P7l0Mo1WKd0wJ0UtqOVEQ=="],
"starlight-theme-next": ["starlight-theme-next@0.3.2", "", { "peerDependencies": { "@astrojs/starlight": ">=0.34" } }, "sha512-GQGhZ67nZ09pWVQoecl1N+H/1EUkUOvLVpjqOCHlkSotCblwrWrj4guEsdF9aKkNqiyTi6zzwZ5sxQospvdHOg=="],
"starlight-theme-rapide": ["starlight-theme-rapide@0.5.1", "", { "peerDependencies": { "@astrojs/starlight": ">=0.34.0" } }, "sha512-QRF6mzcYHLEX5UpUvOPXVVwISS298siIJLcKextoMLhXcnF12nX+IYJ0LNxFk9XaPbX9uDXIieSBJf5Pztkteg=="],
"starlight-videos": ["starlight-videos@0.3.0", "", { "dependencies": { "@astro-community/astro-embed-youtube": "^0.5.6", "hastscript": "^9.0.0", "iso8601-duration": "^2.1.2", "srt-parser-2": "^1.2.3", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "@astrojs/starlight": ">=0.34.0" } }, "sha512-1yvFUEn3P+ZjuGr5COswQp14cZdIvsGjg9lqDIyW5clCrZaBiDMSNPLYngyQozaDbrublEp6/V9HbJR6sGnSOA=="],

View File

@ -20,6 +20,7 @@
"sharp": "^0.34.3",
"starlight-openapi": "^0.19.1",
"starlight-sidebar-topics": "^0.6.0",
"starlight-theme-next": "^0.3.2",
"starlight-theme-rapide": "^0.5.1",
"starlight-videos": "^0.3.0"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@ -4,6 +4,17 @@
import Search from '@astrojs/starlight/components/Search.astro';
import ThemeSelect from '@astrojs/starlight/components/ThemeSelect.astro';
import { Icon } from '@astrojs/starlight/components';
// Determine if we're on a docs page based on the current path
const currentPath = Astro.url.pathname;
const isDocsPage = currentPath.startsWith('/jan/') ||
currentPath.startsWith('/mobile/') ||
currentPath.startsWith('/server/') ||
currentPath.startsWith('/local-server/') ||
currentPath === '/' ||
currentPath === '/index' ||
currentPath === '/docs' ||
currentPath === '/docs/';
---
<div class="sl-nav-wrapper">
@ -15,13 +26,16 @@ import { Icon } from '@astrojs/starlight/components';
👋 Jan
</a>
<!-- Main navigation links -->
<div class="sl-nav__links">
<a href="/products" class="sl-nav__link">
<!-- Main navigation links - hide on mobile for docs pages -->
<div class={`sl-nav__links ${isDocsPage ? 'docs-page' : 'custom-page'}`}>
<a href="/products" class="sl-nav__link" data-nav-item="products">
Products
</a>
<a href="/docs/" class="sl-nav__link">
Docs
<a href="/blog" class="sl-nav__link" data-nav-item="blog">
Blog
</a>
<a href="/changelog" class="sl-nav__link" data-nav-item="changelog">
Changelog
</a>
</div>
</div>
@ -33,82 +47,108 @@ import { Icon } from '@astrojs/starlight/components';
</div>
</div>
<!-- Right side items (API Reference, theme toggle, social links, etc.) -->
<!-- Right side items -->
<div class="sl-nav__end">
<!-- API Reference moved to right -->
<a href="/api-reference" class="sl-nav__link">
<!-- API Reference link -->
<a href="/api-reference" class={`sl-nav__link sl-nav__api-link ${isDocsPage ? 'docs-page' : 'custom-page'}`} data-nav-item="api">
API Reference
</a>
<!-- Theme toggle -->
<ThemeSelect />
<!-- Theme toggle - always visible on desktop -->
<div class="sl-nav__theme">
<ThemeSelect />
</div>
<!-- Social links -->
<div class="sl-nav__social">
<a href="https://github.com/menloresearch/jan" class="sl-nav__social-link" aria-label="GitHub">
<Icon name="github"/>
</a>
</div>
<div class="sl-nav__social">
<a href="https://twitter.com/jandotai" class="sl-nav__social-link" aria-label="X">
<Icon name="x.com"/>
<Icon name="x.com"/>
</a>
</div>
<div class="sl-nav__social">
<a href="https://discord.com/invite/FTk2MvZwJH" class="sl-nav__social-link" aria-label="Discord">
<Icon name="discord"/>
<Icon name="discord"/>
</a>
</div>
<!-- Mobile hamburger menu - only for custom pages -->
{!isDocsPage && (
<div class="sl-nav__hamburger">
<button id="hamburger-btn" class="hamburger-button" aria-label="Toggle navigation menu">
<span class="hamburger-icon">☰</span>
</button>
<div id="hamburger-menu" class="hamburger-menu">
<a href="/products" class="hamburger-link">Products</a>
<a href="/blog" class="hamburger-link">Blog</a>
<a href="/changelog" class="hamburger-link">Changelog</a>
<a href="/api-reference" class="hamburger-link">API Reference</a>
<div class="hamburger-social">
<a href="https://github.com/menloresearch/jan" class="hamburger-social-link" aria-label="GitHub">
<Icon name="github"/>
</a>
<a href="https://twitter.com/jandotai" class="hamburger-social-link" aria-label="X">
<Icon name="x.com"/>
</a>
<a href="https://discord.com/invite/FTk2MvZwJH" class="hamburger-social-link" aria-label="Discord">
<Icon name="discord"/>
</a>
</div>
<div class="hamburger-theme">
<ThemeSelect />
</div>
</div>
</div>
)}
</div>
</nav>
</div>
<style>
/* Base navigation styles */
.sl-nav-wrapper {
background: var(--sl-color-bg-nav);
border-bottom: 1px solid var(--sl-color-hairline-shade);
position: fixed;
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 1000;
padding: 0;
margin: 0;
z-index: 999; /* High z-index to stay above ToC and other elements */
background: var(--sl-color-bg-nav);
border-bottom: 1px solid var(--sl-color-hairline);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.sl-nav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.75rem 1rem;
width: 100%;
max-width: 100%;
margin: 0 auto;
height: var(--sl-nav-height, 3.5rem);
}
.sl-nav__center {
display: flex;
align-items: center;
flex: 1;
display: flex;
justify-content: center;
max-width: 500px;
margin: 0 2rem;
max-width: 600px;
margin: 0 1rem;
}
.sl-nav__left {
display: flex;
align-items: center;
gap: 0.5rem;
gap: 1.5rem;
}
.sl-nav__title {
color: var(--sl-color-text);
text-decoration: none;
font-size: 1.25rem;
font-size: 1.125rem;
font-weight: 600;
line-height: 1;
margin: 0;
padding: 0;
color: var(--sl-color-white);
text-decoration: none;
display: flex;
align-items: center;
white-space: nowrap;
}
.sl-nav__title:hover {
@ -118,40 +158,44 @@ import { Icon } from '@astrojs/starlight/components';
.sl-nav__links {
display: flex;
align-items: center;
gap: 0.5rem;
margin-left: 0.5rem;
gap: 1.5rem;
}
.sl-nav__link {
color: var(--sl-color-text);
color: var(--sl-color-gray-3);
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
padding: 0.5rem 0.75rem;
border-radius: 0.375rem;
transition: all 0.15s ease;
font-size: 0.9375rem;
transition: color 0.2s ease;
white-space: nowrap;
}
.sl-nav__link:hover {
color: #000 !important;
background: var(--sl-color-bg-accent);
color: var(--sl-color-white);
text-decoration: none;
}
/* Dark mode hover text should be white for contrast */
html[data-theme="dark"] .sl-nav__link:hover {
color: #fff !important;
/* Light theme adjustments - better contrast */
html[data-theme="light"] .sl-nav__link {
color: #374151; /* Darker gray for better readability */
}
/* Active state styling for better contrast */
html[data-theme="light"] .sl-nav__link:hover {
color: var(--sl-color-accent);
}
html[data-theme="light"] .sl-nav__title {
color: #111827; /* Very dark gray, almost black */
}
/* Active link styling */
.sl-nav__link.active {
color: #000 !important;
background: var(--sl-color-bg-accent) !important;
font-weight: 600 !important;
color: var(--sl-color-text-accent);
font-weight: 500;
}
/* Dark mode active state */
html[data-theme="dark"] .sl-nav__link.active {
color: #fff !important;
/* Light theme active link */
html[data-theme="light"] .sl-nav__link.active {
color: var(--sl-color-text-accent);
}
.sl-nav__end {
@ -161,16 +205,39 @@ import { Icon } from '@astrojs/starlight/components';
}
.sl-nav__search {
display: flex;
align-items: center;
width: 100%;
min-width: 300px;
max-width: 400px;
position: relative;
}
/* Make the actual search input wider */
/* Fix search input styling for light mode */
.sl-nav__search :global(input) {
min-width: 300px !important;
width: 100% !important;
width: 100%;
padding: 0.5rem 1rem;
}
/* Fix search bar in light mode with more specific selectors */
html[data-theme="light"] .sl-nav__search :global(.pagefind-ui__search-input),
html[data-theme="light"] .sl-nav__search :global(input[type="search"]),
html[data-theme="light"] .sl-nav__search :global(input) {
background: #f9fafb !important;
background-color: #f9fafb !important;
border: 1px solid #d1d5db !important;
color: #111827 !important;
}
html[data-theme="light"] .sl-nav__search :global(.pagefind-ui__search-input:focus),
html[data-theme="light"] .sl-nav__search :global(input[type="search"]:focus),
html[data-theme="light"] .sl-nav__search :global(input:focus) {
background: #ffffff !important;
background-color: #ffffff !important;
border-color: var(--sl-color-accent) !important;
color: #111827 !important;
}
html[data-theme="light"] .sl-nav__search :global(.pagefind-ui__search-input::placeholder),
html[data-theme="light"] .sl-nav__search :global(input::placeholder) {
color: #9ca3af !important;
}
.sl-nav__social {
@ -180,143 +247,407 @@ import { Icon } from '@astrojs/starlight/components';
}
.sl-nav__social-link {
color: var(--sl-color-text-muted);
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: 0.375rem;
transition: all 0.15s ease;
padding: 0.375rem;
color: var(--sl-color-gray-3);
transition: color 0.2s ease;
text-decoration: none;
}
.sl-nav__social-link:hover {
color: var(--sl-color-text);
background: var(--sl-color-bg-accent);
color: var(--sl-color-white);
text-decoration: none;
}
/* Hide links on mobile, show hamburger menu instead */
@media (max-width: 768px) {
/* Light theme social links - better contrast */
html[data-theme="light"] .sl-nav__social-link {
color: #6b7280; /* Medium gray for icons */
}
html[data-theme="light"] .sl-nav__social-link:hover {
color: var(--sl-color-accent);
}
/* Theme selector container */
.sl-nav__theme {
display: flex;
align-items: center;
}
/* Hide only the "Select theme" label text, keep dropdown visible */
.sl-nav__theme :global(starlight-theme-select) {
position: relative;
}
/* Hide only the screen reader text */
.sl-nav__theme :global(starlight-theme-select .sr-only) {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
/* Style the select dropdown with visible text */
.sl-nav__theme :global(starlight-theme-select select) {
font-size: 0.875rem !important;
color: var(--sl-color-text) !important;
background: transparent !important;
border: none !important;
cursor: pointer !important;
padding-right: 1.5rem !important;
}
/* Ensure options are visible with proper contrast */
.sl-nav__theme :global(starlight-theme-select option) {
font-size: 0.875rem !important;
color: var(--sl-color-black) !important;
background: var(--sl-color-white) !important;
}
/* Light mode select text color */
html[data-theme="light"] .sl-nav__theme :global(starlight-theme-select select) {
color: var(--sl-color-gray-5) !important;
}
/* Hide the icon to prevent overlap with text */
.sl-nav__theme :global(starlight-theme-select svg) {
display: none;
}
/* Hamburger menu styles */
.sl-nav__hamburger {
display: none;
position: relative; /* Changed from static to contain the menu properly */
}
.hamburger-button {
background: transparent;
border: none;
color: var(--sl-color-white);
font-size: 1.5rem;
cursor: pointer;
padding: 0.375rem;
display: flex;
align-items: center;
justify-content: center;
transition: color 0.2s ease;
}
/* Fix hamburger button visibility in light mode */
html[data-theme="light"] .hamburger-button {
color: #374151; /* Darker gray for better visibility */
}
.hamburger-button:hover {
color: var(--sl-color-text-accent);
}
html[data-theme="light"] .hamburger-button:hover {
color: var(--sl-color-text-accent);
}
.hamburger-menu {
display: none;
position: absolute;
top: calc(100% + 0.5rem); /* Add small gap below navbar */
right: 0;
background: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 0.5rem;
padding: 1rem;
min-width: 200px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
z-index: 1000; /* Ensure menu stays above other content */
}
/* Light mode menu background */
html[data-theme="light"] .hamburger-menu {
background: var(--sl-color-bg);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.hamburger-menu.show {
display: block;
}
.hamburger-link {
display: block;
padding: 0.5rem 1rem;
color: var(--sl-color-gray-3);
text-decoration: none;
transition: color 0.2s ease, background 0.2s ease;
border-radius: 0.25rem;
}
/* Light mode hamburger links */
html[data-theme="light"] .hamburger-link {
color: #374151; /* Consistent with nav links */
}
.hamburger-link:hover {
color: var(--sl-color-white);
background: var(--sl-color-gray-6);
}
html[data-theme="light"] .hamburger-link:hover {
color: var(--sl-color-accent);
background: var(--sl-color-gray-6);
}
.hamburger-social {
display: flex;
gap: 0.5rem;
padding: 0.5rem 1rem;
margin-top: 0.5rem;
border-top: 1px solid var(--sl-color-hairline);
}
.hamburger-social-link {
display: flex;
align-items: center;
padding: 0.375rem;
color: var(--sl-color-gray-3);
transition: color 0.2s ease;
text-decoration: none;
}
html[data-theme="light"] .hamburger-social-link {
color: #6b7280; /* Consistent with nav social links */
}
.hamburger-social-link:hover {
color: var(--sl-color-white);
}
html[data-theme="light"] .hamburger-social-link:hover {
color: var(--sl-color-accent);
}
.hamburger-theme {
padding: 0.5rem 1rem;
margin-top: 0.5rem;
border-top: 1px solid var(--sl-color-hairline);
}
/* Search component integration styles */
.sl-nav__search :global(.pagefind-ui) {
--pagefind-ui-scale: 0.9;
}
.sl-nav__search :global(.pagefind-ui__search-input) {
background: var(--sl-color-gray-6);
border: 1px solid var(--sl-color-gray-5);
color: var(--sl-color-white);
border-radius: 0.375rem;
font-size: 0.875rem;
padding: 0.375rem 1rem;
transition: border-color 0.2s ease, background 0.2s ease;
}
/* Override any Starlight defaults for search in dark mode */
html[data-theme="dark"] .sl-nav__search :global(.pagefind-ui__search-input),
html[data-theme="dark"] .sl-nav__search :global(input[type="search"]),
html[data-theme="dark"] .sl-nav__search :global(input) {
background: #1f2937 !important;
background-color: #1f2937 !important;
border: 1px solid #374151 !important;
color: #f3f4f6 !important;
}
.sl-nav__search :global(.pagefind-ui__search-input:hover) {
border-color: var(--sl-color-gray-4);
background: var(--sl-color-gray-5);
}
.sl-nav__search :global(.pagefind-ui__search-input:focus) {
outline: none;
border-color: var(--sl-color-text-accent);
background: var(--sl-color-bg);
}
.sl-nav__search :global(.pagefind-ui__search-input::placeholder) {
color: var(--sl-color-gray-3);
}
/* Responsive styles */
/* Tablet view */
@media (max-width: 900px) {
.sl-nav__links {
display: none;
gap: 1rem;
}
.sl-nav__left {
gap: 0.25rem;
flex-shrink: 0;
.sl-nav__link {
font-size: 0.875rem;
}
.sl-nav__social {
display: none;
}
}
/* Mobile view - differentiate between docs and custom pages */
@media (max-width: 768px) {
.sl-nav {
padding: 0.5rem 1rem;
}
.sl-nav__center {
margin: 0 0.5rem;
max-width: 200px;
flex-shrink: 1;
}
.sl-nav__end {
gap: 0.25rem;
flex-shrink: 0;
}
.sl-nav__search {
min-width: 150px;
}
.sl-nav__search :global(input) {
min-width: 150px !important;
}
/* Hide API Reference on very small screens */
.sl-nav__end > .sl-nav__link {
/* For docs pages - hide custom nav items on mobile, let Starlight handle it */
.sl-nav__links.docs-page {
display: none;
}
/* Make social links smaller on mobile */
.sl-nav__social-link {
width: 1.5rem;
height: 1.5rem;
.sl-nav__api-link.docs-page {
display: none;
}
/* For custom pages - hide nav items but show hamburger */
.sl-nav__links.custom-page {
display: none;
}
.sl-nav__api-link.custom-page {
display: none;
}
.sl-nav__theme {
display: none;
}
/* Show hamburger only for custom pages */
.sl-nav__hamburger {
display: block;
}
}
/* Responsive adjustments */
/* Small mobile */
@media (max-width: 640px) {
.sl-nav {
padding: 0.5rem 0.75rem;
gap: 0.5rem;
}
.sl-nav__left {
gap: 0.5rem;
}
.sl-nav__center {
flex: 1;
margin: 0 0.5rem;
}
.sl-nav__end {
gap: 0.5rem;
}
.sl-nav__title {
font-size: 1rem;
white-space: nowrap;
}
.sl-nav__left {
gap: 0.125rem;
}
.sl-nav__center {
margin: 0 0.25rem;
max-width: 150px;
}
.sl-nav__search {
min-width: 120px;
}
.sl-nav__search :global(input) {
min-width: 120px !important;
font-size: 0.875rem;
}
.sl-nav__end {
gap: 0.125rem;
flex-shrink: 0;
min-width: fit-content;
}
/* Hide some social links on very small screens to make room */
.sl-nav__social:nth-child(n+2) {
display: none;
}
/* Hide theme toggle on very small screens */
:global(starlight-theme-select) {
display: none !important;
.sl-nav__search :global(.pagefind-ui__search-input) {
padding: 0.25rem 0.75rem;
font-size: 0.8125rem;
}
}
/* Ensure page content doesn't hide behind fixed navbar */
/* Make sure content doesn't jump */
:global(body) {
padding-top: var(--sl-nav-height, 3.5rem) !important;
padding-top: 0;
}
/* Override any conflicting Starlight body padding */
:global(.sl-layout) {
padding-top: 0 !important;
padding-top: 0;
}
/* Reduce top margin on main content area */
/* Adjust main content positioning */
:global(main.sl-content) {
margin-top: 0 !important;
padding-top: 0.5rem !important;
margin-top: 0;
}
/* Target the main content wrapper */
:global(.sl-content__inner) {
padding-top: 0 !important;
padding-top: 1rem;
}
</style>
<script>
// Add active state highlighting based on current page
const currentPath = window.location.pathname;
const links = document.querySelectorAll('.sl-nav__link');
document.addEventListener('DOMContentLoaded', function() {
// Add active state highlighting based on current page
const currentPath = window.location.pathname;
const links = document.querySelectorAll('.sl-nav__link');
links.forEach(link => {
const href = link.getAttribute('href');
if (href && currentPath.startsWith(href)) {
// Add active class for CSS styling
link.classList.add('active');
links.forEach(link => {
const href = link.getAttribute('href');
if (href) {
// Check for exact match or if current path starts with the link href
if (currentPath === href ||
(href !== '/' && currentPath.startsWith(href))) {
link.classList.add('active');
}
}
});
// Theme handling for custom pages
// Listen for theme changes from Starlight's ThemeSelect
const observeThemeChanges = () => {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
const newTheme = document.documentElement.getAttribute('data-theme');
// Theme is already set by Starlight, we just need to ensure it persists
localStorage.setItem('starlight-theme', newTheme === 'dark' ? 'dark' : 'light');
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme']
});
};
observeThemeChanges();
// Hamburger menu functionality (only for custom pages)
const hamburgerBtn = document.getElementById('hamburger-btn');
const hamburgerMenu = document.getElementById('hamburger-menu');
if (hamburgerBtn && hamburgerMenu) {
// Toggle menu on button click
hamburgerBtn.addEventListener('click', function(e) {
e.stopPropagation();
hamburgerMenu.classList.toggle('show');
});
// Close menu when clicking outside
document.addEventListener('click', function(e) {
if (!hamburgerBtn.contains(e.target) && !hamburgerMenu.contains(e.target)) {
hamburgerMenu.classList.remove('show');
}
});
// Close menu when clicking a link
const hamburgerLinks = hamburgerMenu.querySelectorAll('.hamburger-link');
hamburgerLinks.forEach(link => {
link.addEventListener('click', function() {
hamburgerMenu.classList.remove('show');
});
});
// Close menu on escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && hamburgerMenu.classList.contains('show')) {
hamburgerMenu.classList.remove('show');
}
});
}
});
</script>

View File

@ -1,8 +1,38 @@
import { defineCollection } from 'astro:content';
import { defineCollection, z } from 'astro:content';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
import { videosSchema } from 'starlight-videos/schemas';
const changelogSchema = z.object({
title: z.string(),
description: z.string(),
date: z.date(),
version: z.string().optional(),
image: z.string().optional(),
gif: z.string().optional(),
video: z.string().optional(),
featured: z.boolean().default(false),
});
const blogSchema = z.object({
title: z.string(),
description: z.string(),
date: z.date(),
tags: z.string().optional(),
categories: z.string().optional(),
author: z.string().optional(),
ogImage: z.string().optional(),
featured: z.boolean().default(false),
});
export const collections = {
docs: defineCollection({ loader: docsLoader(), schema: docsSchema({ extend: videosSchema }) }),
changelog: defineCollection({
type: 'content',
schema: changelogSchema,
}),
blog: defineCollection({
type: 'content',
schema: blogSchema,
}),
};

View File

@ -0,0 +1,81 @@
---
title: "Run DeepSeek R1 locally on your device"
description: "A straightforward guide to running DeepSeek R1 locally regardless of your background."
date: 2025-01-31
tags: "DeepSeek, R1, local AI, Jan, GGUF, Qwen, Llama"
categories: "guides"
featured: true
ogImage: "/assets/images/blog/deepseek-r1-locally-jan.jpg"
---
# Run DeepSeek R1 locally on your device
DeepSeek R1 is one of the best open-source models in the market right now, and you can run DeepSeek R1 on your own computer!
> **New to running AI models locally?** Check out our guide on running AI models locally first. It covers essential concepts that will help you better understand this DeepSeek R1 guide.
DeepSeek R1 requires data-center level computers to run at its full potential, and we'll use a smaller version that works great on regular computers.
## Why use an optimized version?
- Efficient performance on standard hardware
- Faster download and initialization
- Optimized storage requirements
- Maintains most of the original model's capabilities
## Quick Steps at a Glance
1. Download [Jan](https://jan.ai/)
2. Select a model version
3. Choose settings
4. Set up the prompt template & start using DeepSeek R1
Let's walk through each step with detailed instructions.
## Step 1: Download Jan
[Jan](https://jan.ai/) is an open-source application that enables you to run AI models locally. It's available for Windows, Mac, and Linux. For beginners, Jan is the best choice to get started.
1. Visit [jan.ai](https://jan.ai)
2. Download the appropriate version for your operating system
3. Install the application following the standard installation process for your OS
## Step 2: Choose Your DeepSeek R1 Model
Once Jan is installed, you'll need to select which version of DeepSeek R1 to download. Different versions have different system requirements:
- **DeepSeek R1 7B**: Good for most computers (8GB+ RAM recommended)
- **DeepSeek R1 14B**: Better performance, needs more resources (16GB+ RAM)
- **DeepSeek R1 32B**: Best performance, requires powerful hardware (32GB+ RAM)
## Step 3: Configure Model Settings
After downloading your chosen model, you can adjust settings to optimize performance:
- **Context Length**: How much conversation history the model remembers
- **Temperature**: Controls creativity vs consistency (0.1-1.0)
- **Max Tokens**: Maximum response length
## Step 4: Set Up DeepSeek R1 Prompt Template
DeepSeek R1 works best with proper prompt formatting. Jan handles this automatically, but you can customize it for specific use cases.
## Start Using DeepSeek R1
Once everything is set up, you can start chatting with DeepSeek R1! The model excels at:
- Code generation and debugging
- Mathematical reasoning
- Technical writing
- Problem-solving
- General conversation
## Tips for Best Results
1. **Be specific**: Clear, detailed prompts get better responses
2. **Provide context**: Give the model relevant background information
3. **Experiment**: Try different temperature settings for different tasks
4. **Be patient**: Local models may take a moment to respond, especially on slower hardware
## Conclusion
Running DeepSeek R1 locally gives you powerful AI capabilities while maintaining complete privacy and control over your data. With Jan, the setup process is straightforward, and you can start experimenting with cutting-edge AI models in minutes.
Ready to get started? [Download Jan](https://jan.ai/) and begin your local AI journey today!

View File

@ -0,0 +1,115 @@
---
title: "Offline ChatGPT: You can't run ChatGPT offline, do this instead"
description: "Learn how to use AI offline with Jan - a free, open-source alternative to ChatGPT that works 100% offline on your computer."
date: 2025-02-08
tags: "AI, ChatGPT alternative, offline AI, Jan, local AI, privacy"
categories: "guides"
featured: true
ogImage: "/assets/images/blog/offline-chatgpt-alternatives-jan.jpg"
---
# Offline ChatGPT: You can't run ChatGPT offline, do this instead
ChatGPT is a cloud-based service that requires internet access. However, it's not the only way to use AI. You can run AI models offline on your device with [Jan](https://jan.ai/). It's completely free, open-source, and gives you 100% offline capability. You can even use AI on a plane!
> **Quick Summary:**
> - ChatGPT always needs internet - it can't run offline
> - Jan lets you run AI models 100% offline on your computer
> - It's free and open-source
> - Works on Mac, Windows, and Linux
## Jan as an offline ChatGPT alternative
Jan lets you use AI offline - no internet connection needed. Here's how to get started with offline AI in 3 simple steps:
### 1. Download Jan
Go to [jan.ai](https://jan.ai) and download the version for your computer (Mac, Windows, or Linux). It's completely free.
### 2. Download an AI model
You'll need an AI model to use AI offline, so download a model from Jan. Once it's on your computer, you don't need internet anymore.
> **Recommended models for beginners:**
> - Llama 3.2 3B: Fast and efficient, works on most computers
> - Phi-3 Mini: Great balance of performance and resource usage
> - Qwen2.5 7B: More capable, needs more RAM
### 3. Start chatting offline
Once your model is downloaded, you can use AI completely offline. No internet required!
## Why choose Jan over ChatGPT for offline use?
| Feature | ChatGPT | Jan |
|---------|---------|-----|
| **Offline capability** | ❌ Requires internet | ✅ 100% offline |
| **Privacy** | ❌ Data sent to OpenAI | ✅ Everything stays local |
| **Cost** | 💰 $20/month for Plus | ✅ Completely free |
| **Customization** | ❌ Limited options | ✅ Full control over models |
| **Data ownership** | ❌ OpenAI owns conversations | ✅ You own everything |
## What can you do with offline AI?
With Jan running offline, you can:
- **Write and edit documents** without sending data to the cloud
- **Code and debug** while keeping your projects private
- **Brainstorm ideas** without worrying about data collection
- **Learn and research** with complete privacy
- **Use AI on flights** or anywhere without internet
## Common questions about offline AI
### "Is offline AI as good as ChatGPT?"
For many tasks, yes! While the largest online models might have slight advantages in some areas, offline models have improved dramatically. Plus, you get:
- Complete privacy
- No internet dependency
- No monthly costs
- Full customization control
### "Will it work on my computer?"
Jan works on most modern computers:
- **Minimum**: 8GB RAM, 4GB free storage
- **Recommended**: 16GB RAM, 10GB free storage
- **Operating systems**: Windows 10+, macOS 10.15+, Linux
### "How much storage do I need?"
AI models vary in size:
- Small models (3B parameters): 2-3GB
- Medium models (7B parameters): 4-5GB
- Large models (13B+ parameters): 8GB+
## Getting started with your first offline AI model
1. **Install Jan** from [jan.ai](https://jan.ai)
2. **Browse the model library** and choose a model that fits your computer
3. **Download your chosen model** (this happens once)
4. **Start chatting** - completely offline!
## Advanced tips for power users
- **GPU acceleration**: If you have a graphics card, Jan can use it to run models faster
- **Multiple models**: Download different models for different tasks
- **Custom settings**: Adjust temperature, context length, and other parameters
- **Import custom models**: Use models from Hugging Face and other sources
## Privacy benefits of offline AI
When you use Jan instead of cloud-based AI:
- **No data collection**: Your conversations never leave your device
- **No tracking**: No usage analytics or behavioral profiling
- **No breaches**: Your data can't be hacked if it's not online
- **No censorship**: Use AI without content restrictions
- **No downtime**: Works even when services are down
## Conclusion
While you can't run ChatGPT offline, Jan provides an excellent alternative that works entirely on your computer. You get privacy, control, and zero ongoing costs - all while using powerful AI models.
The best part? You can start using offline AI in just a few minutes.
**Ready to try offline AI?** [Download Jan](https://jan.ai/) and experience the freedom of local AI models today!

View File

@ -0,0 +1,134 @@
---
title: "Jan Enterprise: Security & Compliance"
version: 0.6.2
description: "Enterprise-grade security features, compliance tools, and team management capabilities"
date: 2025-02-14
image: "/assets/images/changelog/enterprise-security.png"
featured: false
---
## Enterprise Ready 🏢
Jan v0.6.2 introduces comprehensive enterprise features designed for organizations that need advanced security, compliance, and management capabilities. Deploy AI with confidence across your entire organization.
### 🔐 Advanced Security Framework
Military-grade security for your AI infrastructure:
- **Zero-Trust Architecture**: Verify every request, trust nothing by default
- **End-to-End Encryption**: Data encrypted in transit and at rest
- **Certificate Management**: Full PKI support with automatic rotation
- **Network Isolation**: Separate AI workloads from corporate networks
- **Audit Logging**: Comprehensive logs for security analysis and compliance
### 👥 Team Management
Sophisticated user and access control:
- **Role-Based Access**: Granular permissions for different user types
- **Single Sign-On**: Integration with Active Directory, SAML, and OAuth
- **Multi-Factor Authentication**: Required 2FA with hardware token support
- **Session Management**: Control session duration and concurrent logins
- **User Provisioning**: Automated user creation and deactivation
### 📊 Compliance Dashboard
Meet regulatory requirements with confidence:
- **SOC 2 Compliance**: Built-in controls for SOC 2 Type II certification
- **GDPR Tools**: Data subject rights management and privacy controls
- **HIPAA Ready**: Healthcare-specific security and privacy features
- **ISO 27001**: Information security management system alignment
- **Custom Frameworks**: Adapt to your specific compliance requirements
### 🏗️ Infrastructure Management
Deploy and scale AI across your organization:
- **Containerized Deployment**: Docker and Kubernetes ready
- **Load Balancing**: Distribute AI workloads across multiple instances
- **Auto-Scaling**: Automatically scale based on demand
- **Health Monitoring**: Real-time system health and performance tracking
- **Disaster Recovery**: Automated backups and failover capabilities
### 🎯 Data Governance
Complete control over your data:
- **Data Classification**: Automatically tag and classify sensitive information
- **Retention Policies**: Automated data lifecycle management
- **Data Loss Prevention**: Prevent sensitive data from leaving your environment
- **Geographic Controls**: Control where data is processed and stored
- **Right to Deletion**: Complete data removal on request
### 🔍 Advanced Analytics
Insights into AI usage across your organization:
- **Usage Analytics**: Understand how teams use AI capabilities
- **Cost Analysis**: Track AI costs by department, team, or user
- **Performance Metrics**: Monitor AI performance and quality
- **Adoption Reports**: Measure AI adoption across the organization
- **Custom Dashboards**: Create reports tailored to your needs
### 🛡️ Threat Protection
Advanced protection against AI-specific threats:
- **Prompt Injection Detection**: Identify and block malicious prompts
- **Content Filtering**: Prevent inappropriate content generation
- **Rate Limiting**: Protect against abuse and resource exhaustion
- **Anomaly Detection**: Identify unusual usage patterns
- **Incident Response**: Automated response to security events
### 🌐 Integration Capabilities
Connect Jan to your existing enterprise systems:
- **API Gateway**: Secure API access with rate limiting and authentication
- **Webhook Support**: Real-time notifications to external systems
- **Database Connections**: Direct integration with enterprise databases
- **Workflow Integration**: Connect to existing business processes
- **Custom Connectors**: Build integrations specific to your needs
### 📋 Policy Management
Implement and enforce AI governance policies:
- **Usage Policies**: Define acceptable use of AI capabilities
- **Content Policies**: Control what types of content can be generated
- **Model Policies**: Restrict access to specific AI models
- **Data Policies**: Control how data is processed and stored
- **Approval Workflows**: Require approval for sensitive operations
### 🔧 Administrative Tools
Powerful tools for IT administrators:
- **Centralized Configuration**: Manage settings across all deployments
- **Bulk Operations**: Perform actions across multiple users or systems
- **Migration Tools**: Move data and settings between environments
- **Backup Management**: Automated and manual backup capabilities
- **System Diagnostics**: Comprehensive troubleshooting tools
### 📞 Enterprise Support
Dedicated support for mission-critical deployments:
- **24/7 Support**: Round-the-clock assistance for critical issues
- **Dedicated Success Manager**: Personal point of contact for your organization
- **Training Programs**: Comprehensive training for administrators and users
- **Implementation Services**: Professional deployment and configuration
- **Custom Development**: Tailored features for unique requirements
## Deployment Options
Choose the deployment model that fits your needs:
- **On-Premises**: Complete control with on-site deployment
- **Private Cloud**: Dedicated cloud environment just for you
- **Hybrid**: Combine on-premises and cloud capabilities
- **Multi-Region**: Deploy across multiple geographic regions
- **Air-Gapped**: Completely isolated environments for maximum security
## Getting Started
Ready to deploy Jan Enterprise?
1. **Assessment**: Our team evaluates your requirements
2. **Pilot Program**: Start with a small-scale deployment
3. **Training**: Comprehensive training for your team
4. **Full Deployment**: Roll out to your entire organization
5. **Ongoing Support**: Continuous support and optimization
Transform how your organization uses AI. Contact our enterprise team to learn more.
[Contact Enterprise Sales](mailto:enterprise@jan.ai) • [Enterprise Documentation](/docs/enterprise) • [Security Whitepaper](/security-whitepaper)

View File

@ -0,0 +1,122 @@
---
title: "Jan v0.6.3: UI Renaissance"
version: 0.6.3
description: "Complete interface redesign with improved UX, dark mode, and accessibility features"
date: 2025-03-05
image: "/assets/images/changelog/ui-redesign.png"
featured: false
---
## A Beautiful New Beginning 🎨
Jan v0.6.3 introduces our most comprehensive UI overhaul yet. Every pixel has been reconsidered, every interaction refined. The result? A beautiful, intuitive interface that gets out of your way and lets you focus on what matters - conversations with AI.
### 🎯 Design Philosophy
Our new design principles:
- **Clarity First**: Remove visual noise, highlight what's important
- **Consistent Language**: Unified design patterns throughout the app
- **Accessibility Focus**: Usable by everyone, regardless of ability
- **Performance Minded**: Beautiful interfaces that are also fast
- **Future Ready**: Scalable design system for upcoming features
### 🌙 Enhanced Dark Mode
Dark mode, reimagined:
- **True Black Option**: Perfect for OLED displays and low-light use
- **Adaptive Contrast**: Automatically adjusts based on ambient light
- **Custom Accent Colors**: Choose your preferred highlight color
- **Smart Switching**: Follows system preferences or custom schedule
- **Reduced Eye Strain**: Carefully calibrated colors for long usage sessions
### 💬 Conversation Experience
Completely redesigned chat interface:
- **Improved Message Bubbles**: Better readability and visual hierarchy
- **Smart Typography**: Optimal font sizes and spacing for every device
- **Code Highlighting**: Syntax highlighting for 200+ programming languages
- **Math Rendering**: Beautiful LaTeX math equation display
- **Image Gallery**: Enhanced image viewing with zoom and navigation
### 🎛️ Settings Overhaul
Settings that make sense:
- **Organized Categories**: Logical grouping of related options
- **Search Settings**: Find any setting instantly
- **Visual Previews**: See changes before applying them
- **Quick Actions**: Common tasks accessible with fewer clicks
- **Import/Export**: Backup and restore your entire configuration
### 📱 Responsive Design
Perfect on every screen:
- **Mobile Optimized**: Touch-friendly interface for tablets and phones
- **Desktop Polish**: Take advantage of larger screens and precise input
- **Window Management**: Better handling of multiple windows and panels
- **Flexible Layouts**: Adapt to any screen size or orientation
- **High DPI Support**: Crisp on retina and 4K displays
### ♿ Accessibility Improvements
Jan for everyone:
- **Screen Reader Support**: Full compatibility with assistive technologies
- **Keyboard Navigation**: Complete interface control without a mouse
- **High Contrast Mode**: Enhanced visibility for low-vision users
- **Font Scaling**: Respect system font size preferences
- **Motion Controls**: Reduced motion options for sensitive users
### 🎨 Theming System
Express your style:
- **Built-in Themes**: 12 carefully crafted color schemes
- **Custom Themes**: Create your own with our theme editor
- **Theme Sharing**: Import themes created by the community
- **Seasonal Themes**: Special themes for holidays and events
- **Auto-Theming**: Themes that change based on time of day
### 🔍 Improved Navigation
Find everything faster:
- **Global Search**: Search conversations, settings, and help instantly
- **Breadcrumbs**: Always know where you are in the app
- **Quick Switcher**: Jump between conversations with keyboard shortcuts
- **Recent Items**: Quick access to your most-used features
- **Favorites System**: Pin important conversations and tools
### 🎪 Animation & Transitions
Delightful micro-interactions:
- **Smooth Transitions**: Fluid movement between screens and states
- **Loading Animations**: Engaging feedback during wait times
- **Hover Effects**: Subtle responses to mouse interaction
- **Focus Indicators**: Clear visual feedback for keyboard users
- **Performance Optimized**: 60fps animations that don't drain battery
### 📊 Visual Data
Information design that informs:
- **Usage Charts**: Beautiful visualizations of your AI usage
- **Performance Graphs**: Real-time system performance monitoring
- **Progress Indicators**: Clear feedback for long-running operations
- **Status Displays**: At-a-glance system health information
- **Comparison Views**: Side-by-side analysis of models and settings
### 🚀 Performance Improvements
Beauty with brains:
- **Faster Rendering**: 40% improvement in interface responsiveness
- **Memory Efficiency**: Reduced RAM usage for smoother operation
- **Bundle Optimization**: Smaller app size, faster loading
- **Asset Loading**: Progressive loading for smoother startup
- **Animation Performance**: Hardware-accelerated animations
## Migration Guide
Your existing data and settings are automatically preserved. Some visual elements may look different, but all functionality remains the same or improved.
**New Users**: Welcome to the most beautiful Jan yet!
**Existing Users**: Your themes and customizations will be migrated automatically.
Experience the new Jan. Clean, beautiful, and more powerful than ever.
[Download Jan v0.6.3](https://jan.ai/) • [UI Guide](/docs/interface) • [Accessibility Documentation](/docs/accessibility)

View File

@ -0,0 +1,119 @@
---
title: "Jan Mobile: AI in Your Pocket"
version: 1.0.0
description: "Introducing Jan Mobile - full-featured AI assistant for iOS and Android with cloud sync"
date: 2025-04-10
image: "/assets/images/changelog/jan-mobile.png"
featured: true
---
## AI Goes Mobile 📱
After months of development, we're thrilled to announce Jan Mobile - bringing the full power of Jan's AI capabilities to your smartphone. Chat with AI anywhere, sync across devices, and never miss a conversation.
### 📱 Native Mobile Experience
Built from the ground up for mobile:
- **Native Performance**: Smooth, responsive interface optimized for touch
- **Offline Capable**: Continue conversations even without internet
- **Battery Optimized**: Efficient background processing preserves battery life
- **Dark Mode**: Beautiful dark theme that's easy on the eyes
- **Haptic Feedback**: Tactile responses for better interaction
### ☁️ Seamless Cloud Sync
Your conversations follow you everywhere:
- **Real-time Sync**: Conversations update instantly across all devices
- **Conflict Resolution**: Smart merging when editing on multiple devices
- **Selective Sync**: Choose which conversations to sync to mobile
- **End-to-End Encryption**: Your data remains private and secure
- **Offline Queue**: Messages sync when connection returns
### 🎯 Mobile-First Features
Designed for how you use your phone:
- **Voice Input**: Speak your messages instead of typing
- **Voice Output**: AI responses read aloud with natural voices
- **Quick Actions**: Swipe gestures for common tasks
- **Share Integration**: Share content to Jan from any app
- **Widget Support**: Quick access from your home screen
### 🔒 Privacy & Security
Your privacy, protected:
- **Local Processing**: Sensitive conversations can stay on-device
- **Biometric Lock**: Secure Jan with fingerprint or face recognition
- **Auto-Lock**: Automatically locks after inactivity
- **Private Mode**: Conversations that don't sync to cloud
- **Data Controls**: Full control over what data is stored where
### 🤖 Full Model Support
Access all your favorite models:
- **Cloud Models**: GPT-4, Claude, Gemini, and more
- **Local Models**: Run smaller models directly on your phone
- **Model Switching**: Change models mid-conversation
- **Smart Routing**: Automatically choose the best model for your query
- **Offline Models**: Basic AI capabilities without internet
### 📸 Rich Media Support
Beyond just text:
- **Image Analysis**: Upload photos for AI to analyze and discuss
- **Camera Integration**: Take photos directly in Jan for analysis
- **Voice Messages**: Send and receive voice messages
- **File Sharing**: Share documents, PDFs, and more
- **Link Previews**: Rich previews for shared links
### 🎨 Personalization
Make Jan your own:
- **Custom Themes**: Choose colors and appearance
- **Chat Backgrounds**: Personalize your conversation view
- **Notification Settings**: Control when and how you're notified
- **Assistant Personalities**: Different AI personalities for different contexts
- **Quick Replies**: Set up common responses
### 🔄 Cross-Platform Features
Unified experience across desktop and mobile:
- **Universal Search**: Find conversations across all devices
- **Shared Assistants**: Use the same AI assistants everywhere
- **Unified Settings**: Preferences sync between devices
- **File Access**: Access files shared from desktop
- **Continuous Conversations**: Start on desktop, continue on mobile
### 📊 Usage Analytics
Understand your AI usage:
- **Conversation Stats**: See your most active conversations
- **Model Usage**: Track which models you use most
- **Time Analytics**: Understand your usage patterns
- **Export Data**: Download your conversation history
- **Privacy Dashboard**: See exactly what data is stored
### 🌟 Launch Features
Available from day one:
- **Free Tier**: Full functionality with generous usage limits
- **Pro Features**: Enhanced models and advanced features
- **Family Sharing**: Share Pro features with family members
- **Student Discount**: Special pricing for students
- **Enterprise Options**: Advanced security and management
## Platform Availability
- **iOS**: Available on the App Store (iOS 15.0+)
- **Android**: Available on Google Play (Android 8.0+)
- **Cross-Platform**: Full feature parity between platforms
## Getting Started
1. Download Jan Mobile from your app store
2. Sign in with your Jan account (or create one)
3. Your desktop conversations automatically appear
4. Start chatting with AI on the go!
Your AI assistant is now truly everywhere. Download Jan Mobile today and experience AI without boundaries.
[Download for iOS](https://apps.apple.com/app/jan-ai) • [Download for Android](https://play.google.com/store/apps/jan) • [Mobile Guide](/docs/mobile)

View File

@ -0,0 +1,101 @@
---
title: "Jan v0.6.4: Performance Powerhouse"
version: 0.6.4
description: "Massive speed improvements, GPU optimization, and streamlined model management"
date: 2025-05-20
image: "/assets/images/changelog/performance-boost.png"
featured: false
---
## Speed Like Never Before ⚡
Jan v0.6.4 delivers our biggest performance update yet. Models load faster, inference is smoother, and memory usage is dramatically reduced. This is the Jan you've been waiting for.
### 🚀 Inference Speed Improvements
Dramatic performance gains across the board:
- **3x Faster Model Loading**: Optimized model initialization reduces wait times
- **50% Faster Inference**: Improved CUDA kernels and memory management
- **Instant Model Switching**: Switch between models with near-zero delay
- **Background Preloading**: Frequently used models stay ready in memory
- **Smart Caching**: Intelligent context caching reduces repeated work
### 🎯 GPU Optimization Revolution
Completely rewritten GPU acceleration:
- **Auto-GPU Detection**: Automatically finds and uses your best GPU
- **Multi-GPU Support**: Distribute model layers across multiple GPUs
- **Memory Optimization**: 40% reduction in VRAM usage
- **Dynamic Offloading**: Automatically balance between GPU and CPU
- **CUDA 12 Support**: Latest NVIDIA drivers and optimizations
### 🧠 Smarter Memory Management
Revolutionary memory handling:
- **Adaptive Memory**: Automatically adjusts to available system memory
- **Memory Pressure Detection**: Gracefully handles low-memory situations
- **Efficient Model Unloading**: Frees memory when models aren't needed
- **Context Length Optimization**: Handle longer conversations without slowdown
- **Memory Usage Dashboard**: Real-time visibility into memory consumption
### 📱 Startup Speed Breakthrough
Jan now starts in seconds, not minutes:
- **Cold Start Optimization**: 5x faster first launch
- **Background Services**: Core services start in parallel
- **Lazy Loading**: Only load components when needed
- **Configuration Caching**: Settings load instantly
- **Progressive Initialization**: UI appears immediately, features load progressively
### 🔧 Model Management Overhaul
Streamlined model experience:
- **One-Click Downloads**: Simplified model acquisition
- **Download Resume**: Interrupted downloads continue automatically
- **Parallel Downloads**: Download multiple models simultaneously
- **Storage Optimization**: Automatic cleanup of unused model files
- **Model Recommendations**: AI suggests optimal models for your hardware
### 💾 Storage Efficiency
Dramatic reduction in disk usage:
- **Model Compression**: 30% smaller model files without quality loss
- **Duplicate Detection**: Automatically removes duplicate models
- **Incremental Updates**: Only download model changes, not entire files
- **Smart Cleanup**: Removes temporary files and caches automatically
- **Storage Analytics**: See exactly what's using your disk space
### 🌐 Network Optimizations
Faster downloads and better connectivity:
- **CDN Integration**: Download models from the closest server
- **Connection Pooling**: Efficient network resource usage
- **Retry Logic**: Automatic recovery from network interruptions
- **Bandwidth Adaptation**: Adjusts download speed to network conditions
- **Offline Mode**: Better handling when internet is unavailable
### 🔍 Performance Monitoring
New tools to understand performance:
- **Real-time Metrics**: See inference speed, memory usage, GPU utilization
- **Performance History**: Track performance over time
- **Bottleneck Detection**: Identify what's slowing down your system
- **Benchmark Tools**: Compare performance across different configurations
- **Performance Profiles**: Save optimal settings for different use cases
### 🐛 Critical Fixes
Major stability improvements:
- Fixed memory leaks during long conversations
- Resolved GPU driver compatibility issues
- Eliminated random crashes during model switching
- Fixed model corruption during interrupted downloads
- Resolved race conditions in multi-threaded operations
## Technical Details
This release includes fundamental changes to our inference engine, memory management, and GPU acceleration systems. While backwards compatible, you may notice different memory usage patterns and significantly improved performance.
Experience the fastest Jan ever. Download v0.6.4 and feel the difference.
[Download Jan v0.6.4](https://jan.ai/) • [Performance Guide](/docs/performance) • [Release Notes](https://github.com/menloresearch/jan/releases/tag/v0.6.4)

View File

@ -0,0 +1,88 @@
---
title: "Jan v0.6.5: MCP Revolution - Connect AI to Everything"
version: 0.6.5
description: "Introducing Model Context Protocol support, browser automation, and powerful tool integrations"
date: 2025-06-15
image: "/assets/images/changelog/mcp-revolution.gif"
featured: true
---
## The MCP Era Begins 🚀
Jan v0.6.5 introduces groundbreaking Model Context Protocol (MCP) support, transforming Jan from a simple chat interface into a powerful AI automation platform. Connect your AI to browsers, APIs, databases, and countless tools.
### 🔗 Model Context Protocol Integration
MCP opens up infinite possibilities:
- **Universal Tool Access**: Connect to any service that supports MCP
- **Real-time Data**: Access live information from APIs and databases
- **Browser Automation**: Control web browsers directly through AI commands
- **File System Access**: Read, write, and manipulate files with AI assistance
- **Custom Tools**: Build your own MCP servers for specialized workflows
### 🌐 Built-in MCP Servers
Launch with powerful integrations:
- **Browser Control**: Automate web tasks, scrape data, fill forms
- **File Management**: AI-powered file operations and organization
- **API Integration**: Connect to REST APIs, GraphQL endpoints
- **Database Access**: Query and update databases through natural language
- **Git Operations**: Manage repositories with AI assistance
### 🎯 Smart Tool Discovery
Jan automatically discovers and configures MCP tools:
- **Auto-detection**: Finds available MCP servers on your system
- **One-click Setup**: Enable tools with simple toggle switches
- **Permission Control**: Fine-grained control over tool access
- **Usage Analytics**: Track which tools your AI uses most
### 🛡️ Enhanced Security Framework
Built with security as a priority:
- **Sandboxed Execution**: Tools run in isolated environments
- **Permission System**: Explicit approval for sensitive operations
- **Audit Logging**: Complete history of tool usage and permissions
- **Safe Defaults**: Conservative permissions that you can expand
### 🎨 Redesigned Tool Interface
Beautiful new interface for tool management:
- **Visual Tool Cards**: See available tools at a glance
- **Real-time Status**: Know when tools are active or inactive
- **Interactive Setup**: Guided configuration for complex tools
- **Usage Insights**: Understand how your AI uses different tools
### 🔧 Developer Experience
For MCP server developers:
- **Local Development**: Test MCP servers directly in Jan
- **Debug Tools**: Built-in logging and error reporting
- **Hot Reload**: Changes to MCP servers update instantly
- **Protocol Validation**: Ensure your servers follow MCP standards
### 🚀 Performance Improvements
Under the hood optimizations:
- **Faster Tool Loading**: MCP servers start 3x faster
- **Memory Efficiency**: Reduced memory usage for tool operations
- **Connection Pooling**: Efficient management of tool connections
- **Async Operations**: Non-blocking tool execution
### 🌟 Coming Next
The MCP ecosystem is just getting started:
- More built-in integrations (Slack, Discord, GitHub)
- Visual workflow builder for complex automations
- Community marketplace for sharing MCP servers
- Enterprise-grade security and compliance features
## Breaking Changes
- Tool permissions now require explicit user approval
- Some legacy integrations have been migrated to MCP
- Configuration format updated for better security
Transform how you work with AI. Download Jan v0.6.5 and enter the MCP era.
For technical details, see our [MCP documentation](/docs/mcp) and [GitHub release](https://github.com/menloresearch/jan/releases/tag/v0.6.5).

View File

@ -0,0 +1,116 @@
---
title: "Jan v0.6.6: Enhanced llama.cpp integration and smarter model management"
version: 0.6.6
description: "Major llama.cpp improvements, Hugging Face provider support, and refined MCP experience"
date: 2025-07-31
image: "/assets/images/changelog/changelog0.6.6.gif"
featured: true
---
## Highlights 🎉
Jan v0.6.6 delivers significant improvements to the llama.cpp backend, introduces Hugging Face as a
built-in provider, and brings smarter model management with auto-unload capabilities. This release
also includes numerous MCP refinements and platform-specific enhancements.
### 🚀 Major llama.cpp Backend Overhaul
We've completely revamped the llama.cpp integration with:
- **Smart Backend Management**: The backend now auto-updates and persists your settings properly
- **Device Detection**: Jan automatically detects available GPUs and hardware capabilities
- **Direct llama.cpp Access**: Models now interface directly with llama.cpp (previously hidden behind Cortex)
- **Automatic Migration**: Your existing models seamlessly move from Cortex to direct llama.cpp management
- **Better Error Handling**: Clear error messages when models fail to load, with actionable solutions
- **Per-Model Overrides**: Configure specific settings for individual models
### 🤗 Hugging Face Cloud Router Integration
Connect to Hugging Face's new cloud inference service:
- Access pre-configured models running on various providers (Fireworks, Together AI, and more)
- Hugging Face handles the routing to the best available provider
- Simplified setup with just your HF token
- Non-deletable provider status to prevent accidental removal
- Note: Direct model ID search in Hub remains available as before
### 🧠 Smarter Model Management
New intelligent features to optimize your system resources:
- **Auto-Unload Old Models**: Automatically free up memory by unloading unused models
- **Persistent Settings**: Your model capabilities and settings now persist across app restarts
- **Zero GPU Layers Support**: Set N-GPU Layers to 0 for CPU-only inference
- **Memory Calculation Improvements**: More accurate memory usage reporting
### 🎯 MCP Refinements
Enhanced MCP experience with:
- Tool approval dialog improvements with scrollable parameters
- Better experimental feature edge case handling
- Fixed tool call button disappearing issue
- JSON editing tooltips for easier configuration
- Auto-focus on "Always Allow" action for smoother workflows
### 📚 New MCP Integration Tutorials
Comprehensive guides for powerful MCP integrations:
- **Canva MCP**: Create and manage designs through natural language - generate logos, presentations, and marketing materials directly from chat
- **Browserbase MCP**: Control cloud browsers with AI - automate web tasks, extract data, and monitor sites without complex scripting
- **Octagon Deep Research MCP**: Access finance-focused research capabilities - analyze markets, investigate companies, and generate investment insights
### 🖥️ Platform-Specific Improvements
**Windows:**
- Fixed terminal windows popping up during model loading
- Better process termination handling
- VCRuntime included in installer for compatibility
- Improved NSIS installer with app running checks
**Linux:**
- AppImage now works properly with newest Tauri version and it went from almost 1GB to less than 200MB
- Better Wayland compatibility
**macOS:**
- Improved build process and artifact naming
### 🎨 UI/UX Enhancements
Quality of life improvements throughout:
- Fixed rename thread dialog showing incorrect thread names
- Assistant instructions now have proper defaults
- Download progress indicators remain visible when scrolling
- Better error pages with clearer messaging
- GPU detection now shows accurate backend information
- Improved clickable areas for better usability
### 🔧 Developer Experience
Behind the scenes improvements:
- New automated QA system using CUA (Computer Use Automation)
- Standardized build process across platforms
- Enhanced error stream handling and parsing
- Better proxy support for the new downloader
- Reasoning format support for advanced models
### 🐛 Bug Fixes
Notable fixes include:
- Factory reset no longer fails with access denied errors
- OpenRouter provider stays selected properly
- Model search in Hub shows latest data only
- Temporary download files are cleaned up on cancel
- Legacy threads no longer appear above new threads
- Fixed encoding issues on various platforms
## Breaking Changes
- Models previously managed by Cortex now interface directly with llama.cpp (automatic migration included)
- Some sampling parameters have been removed from the llama.cpp extension for consistency
- Cortex extension is deprecated in favor of direct llama.cpp integration
## Coming Next
We're working on expanding MCP capabilities, improving model download speeds, and adding more provider
integrations. Stay tuned!
Update your Jan or [download the latest](https://jan.ai/).
For the complete list of changes, see the [GitHub release notes](https://github.com/menloresearch/jan/releases/tag/v0.6.6).

View File

@ -1,171 +1,172 @@
---
title: Jan
description: Jan is an open-source ChatGPT-alternative and self-hosted AI platform - build and run AI on your own desktop or server.
description: Build, run, and own your AI. From laptop to superintelligence.
keywords:
[
Jan,
Jan AI,
ChatGPT alternative,
OpenAI platform alternative,
local API,
self-hosted AI,
local AI,
private AI,
conversational AI,
no-subscription fee,
large language model,
LLM,
open superintelligence,
AI ecosystem,
llama.cpp,
GGUF models,
MCP tools
]
---
import { Aside } from '@astrojs/starlight/components';
![Jan's Cover Image](../../assets/jan-app-new.png)
![Jan Desktop](../../assets/jan-app-new.png)
## Jan's Goal
Jan is a ChatGPT alternative that runs 100% offline on your desktop and (*soon*) on mobile. Our goal is to
make it easy for anyone, with or without coding skills, to download and use AI models with full control and
[privacy](https://www.reuters.com/legal/legalindustry/privacy-paradox-with-ai-2023-10-31/).
> Jan's goal is to build superintelligence that you can self-host and use locally.
Jan is powered by [Llama.cpp](https://github.com/ggerganov/llama.cpp), a local AI engine that provides an OpenAI-compatible
API that can run in the background by default at `https://localhost:1337` (or your custom port). This enables you to power all sorts of
applications with AI capabilities from your laptop/PC. For example, you can connect local tools like [Continue](https://jan.ai/docs/server-examples/continue-dev)
and [Cline](https://cline.bot/) to Jan and power them using your favorite models.
## What is Jan?
Jan doesn't limit you to locally hosted models, meaning, you can create an API key from your favorite model provider,
add it to Jan via the configuration's page and start talking to your favorite models.
Jan is an open-source AI ecosystem that runs on your hardware.
### Features
- **Available Today**: Jan Desktop - run AI models on your computer with zero setup
- **Coming Soon**: Complete ecosystem with specialized models, tools, and cross-device sync
- Download popular open-source LLMs (Llama3, Gemma3, Qwen3, and more) from the HuggingFace [Model Hub](./jan/manage-models)
or import any GGUF files (the model format used by llama.cpp) available locally
- Connect to [cloud services](./jan/remote-models/openai) (OpenAI, Anthropic, Mistral, Groq, etc.)
- [Chat](./jan/threads) with AI models & [customize their parameters](./jan/explanation/model-parameters) via our
intuitive interface
- Use our [local API server](https://jan.ai/api-reference) with an OpenAI-equivalent API to power other apps.
### The Stack
### Philosophy
**Models**: Specialized AI models trained for real tasks (search, analysis, writing)
**Tools**: Browser automation, web search, memory systems via MCP
**Applications**: Desktop (now), Web/Mobile/Server (coming 2025)
Jan is built to be [user-owned](about#-user-owned), this means that Jan is:
- Truly open source via the [Apache 2.0 license](https://github.com/menloresearch/jan/blob/dev/LICENSE)
- [Data is stored locally, following one of the many local-first principles](https://www.inkandswitch.com/local-first)
- Internet is optional, Jan can run 100% offline
- Free choice of AI models, both local and cloud-based
- We do not collect or sell user data. See our [Privacy Policy](./privacy).
Everything works together. Everything runs where you want it.
<Aside type="tip">
No API keys required. No account needed. Just download and use.
</Aside>
## Core Features
### Run Models Locally
- Download any GGUF model from Hugging Face
- Use our Jan models optimized for specific tasks
- Automatic GPU acceleration (NVIDIA/AMD/Intel)
- OpenAI-compatible API at `localhost:1337`
### Connect to Cloud (Optional)
- Your API keys for OpenAI, Anthropic, etc.
- Jan.ai cloud models (coming soon)
- Self-hosted Jan Server
### Extend with Tools
- Web search via MCP
- Browser automation
- File parsing and analysis
- Custom tool development
## Architecture
Jan is built on:
- [Llama.cpp](https://github.com/ggerganov/llama.cpp) for inference
- [Model Context Protocol](https://modelcontextprotocol.io) for tools
- Local-first data storage in `~/jan`
## Why Jan?
| Feature | Other AI Platforms | Jan |
|:--------|:-------------------|:----|
| **Deployment** | Their servers only | Your device, your servers, or our cloud |
| **Models** | One-size-fits-all | Specialized models for specific tasks |
| **Data** | Stored on their servers | Stays on your hardware |
| **Cost** | Monthly subscription | Free locally, pay for cloud |
| **Extensibility** | Limited APIs | Full ecosystem with MCP tools |
## Development Philosophy
1. **Local First**: Everything works offline. Cloud is optional.
2. **User Owned**: Your data, your models, your compute.
3. **Built in Public**: Watch our models train. See our code. Track our progress.
<Aside>
You can read more about our [philosophy](https://jan.ai/about#philosophy) here.
We're building AI that respects your choices. Not another wrapper around someone else's API.
</Aside>
### Inspirations
## System Requirements
Jan is inspired by the concepts of [Calm Computing](https://en.wikipedia.org/wiki/Calm_technology), and the Disappearing Computer.
**Minimum**: 8GB RAM, 10GB storage
**Recommended**: 16GB RAM, NVIDIA GPU, 50GB storage
**Supported**: Windows 10+, macOS 12+, Linux (Ubuntu 20.04+)
## Acknowledgements
Jan is built on the shoulders of many open-source projects like:
- [Llama.cpp](https://github.com/ggerganov/llama.cpp/blob/master/LICENSE)
- [Scalar](https://github.com/scalar/scalar)
## FAQs
## What's Next?
<details>
<summary><strong>What is Jan?</strong></summary>
<summary><strong>When will mobile/web versions launch?</strong></summary>
Jan is a customizable AI assistant that can run offline on your computer - a privacy-focused alternative to tools like ChatGPT, Anthropic's Claude, and Google Gemini, with optional cloud AI support.
- **Jan Web**: Beta Q1 2025
- **Jan Mobile**: Q4 2025
- **Jan Server**: Q3 2025
All versions will sync seamlessly with your desktop.
</details>
<details>
<summary><strong>How do I get started with Jan?</strong></summary>
<summary><strong>What models are available?</strong></summary>
Download Jan on your computer, download a model or add API key for a cloud-based one, and start chatting. For detailed setup instructions, see our installation guides.
**Now**:
- Any GGUF model from Hugging Face
- Cloud models via API keys (OpenAI, Anthropic, etc.)
**Coming Q1 2025**:
- Jan-Search: Optimized for web search and synthesis
- Jan-Write: Creative and technical writing
- Jan-Analyze: Data analysis and reasoning
[Watch live training progress →](https://train.jan.ai)
</details>
<details>
<summary><strong>Is Jan compatible with my system?</strong></summary>
<summary><strong>How does Jan make money?</strong></summary>
Jan supports all major operating systems:
- [Mac](./jan/installation/mac#compatibility)
- [Windows](./jan/installation/windows#compatibility)
- [Linux](./jan/installation/linux)
Hardware compatibility includes:
- NVIDIA GPUs (CUDA)
- AMD GPUs (Vulkan)
- Intel Arc GPUs (Vulkan)
- Any GPU with Vulkan support
- **Local use**: Always free
- **Cloud features**: Optional paid services (coming 2025)
- **Enterprise**: Self-hosted deployment and support
We don't sell your data. We sell software and services.
</details>
<details>
<summary><strong>How does Jan protect my privacy?</strong></summary>
Jan prioritizes privacy by:
- Running 100% offline with locally-stored data
- Using open-source models that keep your conversations private
- Storing all files and chat history on your device in the [Jan Data Folder](./jan/data-folder)
- Never collecting or selling your data
<Aside type="danger">
When using third-party cloud AI services through Jan, their data policies apply. Check their privacy terms.
</Aside>
You can optionally share anonymous usage statistics to help improve Jan, but your conversations are never shared. See our complete [Privacy Policy](./jan/privacy).
<summary><strong>Can I contribute?</strong></summary>
Yes. Everything is open:
- [GitHub](https://github.com/janhq/jan) - Code contributions
- [Model Training](https://jan.ai/docs/models) - See how we train
- [Discord](https://discord.gg/FTk2MvZwJH) - Join discussions
- [Model Testing](https://eval.jan.ai) - Help evaluate models
</details>
<details>
<summary><strong>What models can I use with Jan?</strong></summary>
<summary><strong>Is this just another ChatGPT wrapper?</strong></summary>
- Download optimized models from the [Jan Hub](./jan/manage-models)
- Import GGUF models from Hugging Face or your local files
- Connect to cloud providers like OpenAI, Anthropic, Mistral and Groq (requires your own API keys)
No. We're building:
- Our own models trained for specific tasks
- Complete local AI infrastructure
- Tools that extend model capabilities
- An ecosystem that works offline
ChatGPT is one model behind an API. Jan is a complete AI platform you own.
</details>
<details>
<summary><strong>Is Jan really free? What's the catch?</strong></summary>
<summary><strong>What about privacy?</strong></summary>
Jan is completely free and open-source with no subscription fees for local models and features. When using cloud-based models (like GPT-4o or Claude Sonnet 3.7), you'll only pay the standard rates to those providers—we add no markup.
**Local mode**: Your data never leaves your device. Period.
**Cloud mode**: You choose when to use cloud features. Clear separation.
See our [Privacy Policy](./privacy).
</details>
<details>
<summary><strong>Can I use Jan offline?</strong></summary>
## Get Started
Yes! Once you've downloaded a local model, Jan works completely offline with no internet connection needed.
1. [Install Jan Desktop](./jan/installation) - Your AI workstation
2. [Explore Models](./jan/models) - Download and configure
3. [Learn the API](./api-reference) - Build with Jan
</details>
---
<details>
<summary><strong>How can I contribute or get community help?</strong></summary>
- Join our [Discord community](https://discord.gg/qSwXFx6Krr) to connect with other users
- Contribute through [GitHub](https://github.com/menloresearch/jan) (no permission needed!)
- Get troubleshooting help in our [Discord](https://discord.com/invite/FTk2MvZwJH) channel [#🆘|jan-help](https://discord.com/channels/1107178041848909847/1192090449725358130)
- Check our [Troubleshooting](./jan/troubleshooting) guide for common issues
</details>
<details>
<summary><strong>Can I self-host Jan?</strong></summary>
Yes! We fully support the self-hosted movement. Either download Jan directly or fork it on [GitHub repository](https://github.com/menloresearch/jan) and build it from source.
</details>
<details>
<summary><strong>What does Jan stand for?</strong></summary>
Jan stands for "Just a Name". We are, admittedly, bad at marketing 😂.
</details>
<details>
<summary><strong>Are you hiring?</strong></summary>
Yes! We love hiring from our community. Check out our open positions at [Careers](https://menlo.bamboohr.com/careers).
</details>
**Questions?** Join our [Discord](https://discord.gg/FTk2MvZwJH) or check [GitHub roadmap](https://github.com/janhq/jan/).

View File

@ -23,9 +23,6 @@ keywords:
import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
# Windows Installation
## Compatibility
**System requirements:**

View File

@ -6,7 +6,6 @@ sidebar:
---
import { Aside, Card, CardGrid } from '@astrojs/starlight/components';
**Jan's Goal is**
> **to build a superintelligence that you can self-host and use locally on your own devices.**

View File

@ -27,11 +27,71 @@ const { title } = Astro.props;
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollToPlugin.min.js"></script>
<!-- Starlight theme system -->
<script is:inline>
// Theme initialization - same as Starlight
(() => {
const storedTheme = typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
const theme = storedTheme || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark');
// Apply the correct theme immediately
if (theme === 'auto') {
const actualTheme = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', actualTheme);
} else {
document.documentElement.setAttribute('data-theme', theme);
}
// Store non-auto preference
if (storedTheme && storedTheme !== 'auto') {
document.documentElement.setAttribute('data-theme', storedTheme);
}
})();
</script>
</head>
<body>
<slot />
<style is:global>
/* Starlight CSS Variables for theme consistency */
:root {
--sl-color-white: #ffffff;
--sl-color-black: #000000;
--sl-color-gray-1: #eee;
--sl-color-gray-2: #c2c2c2;
--sl-color-gray-3: #8b8b8b;
--sl-color-gray-4: #585858;
--sl-color-gray-5: #383838;
--sl-color-gray-6: #272727;
--sl-color-accent: #4f46e5;
--sl-nav-height: 3.5rem;
}
/* Dark theme variables */
html[data-theme="dark"] {
--sl-color-text: #ffffff;
--sl-color-text-accent: #ffffff;
--sl-color-bg: #0a0a0a;
--sl-color-bg-nav: #1a1a1a;
--sl-color-bg-sidebar: #111111;
--sl-color-bg-accent: #4f46e5;
--sl-color-hairline-shade: #333333;
--sl-color-text-muted: #888888;
}
/* Light theme variables */
html[data-theme="light"] {
--sl-color-text: #000000;
--sl-color-text-accent: #000000;
--sl-color-bg: #ffffff;
--sl-color-bg-nav: #ffffff;
--sl-color-bg-sidebar: #f8f9fa;
--sl-color-bg-accent: #e5e7eb;
--sl-color-hairline-shade: #e5e7eb;
--sl-color-text-muted: #6b7280;
}
html {
font-family: 'JetBrains Mono', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
scroll-behavior: smooth;
@ -40,9 +100,10 @@ const { title } = Astro.props;
body {
margin: 0;
padding: 0;
background: #0a0a0a;
color: #ffffff;
background: var(--sl-color-bg);
color: var(--sl-color-text);
overflow-x: hidden;
transition: background-color 0.2s ease, color 0.2s ease;
}
* {
@ -60,5 +121,61 @@ const { title } = Astro.props;
transition: all 0.3s ease;
}
</style>
<!-- Theme switching functionality for custom layouts -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// Handle Starlight theme selector changes
const handleThemeChange = (newTheme) => {
let actualTheme = newTheme;
if (newTheme === 'auto') {
actualTheme = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
}
document.documentElement.setAttribute('data-theme', actualTheme);
localStorage.setItem('starlight-theme', newTheme);
};
// Find all theme selectors and add functionality
document.querySelectorAll('starlight-theme-select select').forEach(select => {
select.addEventListener('change', function(e) {
handleThemeChange(e.target.value);
});
});
// Listen for system theme changes when auto is selected
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', function(e) {
const currentPref = localStorage.getItem('starlight-theme');
if (currentPref === 'auto' || !currentPref) {
const actualTheme = e.matches ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', actualTheme);
}
});
// Observe theme changes on the HTML element
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
// Theme has been changed, ensure all selectors are in sync
const currentTheme = document.documentElement.getAttribute('data-theme');
const storedPref = localStorage.getItem('starlight-theme');
// Update all theme selectors to match
document.querySelectorAll('starlight-theme-select select').forEach(select => {
if (select.value !== storedPref) {
select.value = storedPref || 'auto';
}
});
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme']
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,355 @@
---
import { getCollection } from 'astro:content';
import Layout from '../layouts/Layout.astro';
import CustomNav from '../components/CustomNav.astro';
// Get all blog entries and sort by date (newest first)
const blogEntries = await getCollection('blog');
const sortedEntries = blogEntries.sort((a, b) =>
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
);
// Extract unique categories
const allCategories = [...new Set(sortedEntries.flatMap(entry =>
entry.data.categories ? entry.data.categories.split(',').map(cat => cat.trim()) : []
))];
const title = 'Blog';
const description = 'The latest updates from Jan. See Changelog for more product updates.';
// Define gradient colors for cards
const gradients = [
'from-purple-500 to-pink-500',
'from-blue-500 to-cyan-400',
'from-purple-600 to-blue-500',
'from-cyan-400 to-blue-500',
'from-pink-500 to-purple-600',
'from-blue-600 to-purple-600'
];
---
<Layout title={title} description={description}>
<CustomNav />
<main class="blog-page">
<div class="blog-container">
<!-- Header -->
<header class="blog-header">
<h1>Blog</h1>
<p>The latest updates from Jan. See <a href="/changelog" class="changelog-link">Changelog</a> for more product updates.</p>
</header>
<!-- Category Filter -->
<div class="category-filter">
<button class="category-btn active" data-category="all">All Categories</button>
<button class="category-btn" data-category="guides">Guides</button>
<button class="category-btn" data-category="research">Research</button>
<button class="category-btn" data-category="building jan">Building Jan</button>
</div>
<!-- Blog Grid -->
<div class="blog-grid">
{sortedEntries.map((entry, index) => {
const date = new Date(entry.data.date);
const formattedDate = date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
const gradientClass = gradients[index % gradients.length];
const category = entry.data.categories || 'guides';
return (
<article class={`blog-card ${gradientClass}`} data-category={category.toLowerCase()}>
<div class="card-header">
<div class="card-gradient bg-gradient-to-br {gradientClass}">
<div class="category-badge">{category}</div>
<div class="card-date">{formattedDate}</div>
</div>
</div>
<div class="card-content">
<h2 class="card-title">
<a href={`/blog/${entry.slug}`}>{entry.data.title}</a>
</h2>
<p class="card-description">{entry.data.description}</p>
<a href={`/blog/${entry.slug}`} class="read-more">
Read more...
</a>
</div>
</article>
);
})}
</div>
</div>
</main>
</Layout>
<style>
.blog-page {
min-height: 100vh;
background: var(--sl-color-bg);
color: var(--sl-color-text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}
.blog-container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
}
.blog-header {
text-align: center;
margin-bottom: 3rem;
}
.blog-header h1 {
font-size: 4rem;
font-weight: 700;
margin-bottom: 1rem;
background: linear-gradient(135deg, #ffffff 0%, #888888 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.blog-header p {
font-size: 1.1rem;
color: var(--sl-color-text-muted);
max-width: 600px;
margin: 0 auto;
line-height: 1.6;
}
.changelog-link {
color: var(--sl-color-accent);
text-decoration: none;
font-weight: 500;
}
.changelog-link:hover {
text-decoration: underline;
}
.category-filter {
display: flex;
justify-content: center;
gap: 1rem;
margin-bottom: 3rem;
flex-wrap: wrap;
}
.category-btn {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 2rem;
background: var(--sl-color-bg-sidebar);
color: var(--sl-color-text);
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: all 0.15s ease;
border: 1px solid var(--sl-color-gray-5);
}
.category-btn:hover {
background: var(--sl-color-bg-accent);
border-color: var(--sl-color-accent);
transform: translateY(-1px);
}
.category-btn.active {
background: var(--sl-color-accent);
color: white;
border-color: var(--sl-color-accent);
}
.blog-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.blog-card {
background: var(--sl-color-bg-sidebar);
border-radius: 1rem;
overflow: hidden;
border: 1px solid var(--sl-color-gray-5);
transition: transform 0.2s ease, box-shadow 0.2s ease;
height: fit-content;
}
.blog-card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}
.card-header {
position: relative;
}
.card-gradient {
height: 120px;
position: relative;
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 1rem;
}
/* Individual gradient backgrounds */
.blog-card.from-purple-500.to-pink-500 .card-gradient {
background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
}
.blog-card.from-blue-500.to-cyan-400 .card-gradient {
background: linear-gradient(135deg, #3b82f6 0%, #22d3ee 100%);
}
.blog-card.from-purple-600.to-blue-500 .card-gradient {
background: linear-gradient(135deg, #9333ea 0%, #3b82f6 100%);
}
.blog-card.from-cyan-400.to-blue-500 .card-gradient {
background: linear-gradient(135deg, #22d3ee 0%, #3b82f6 100%);
}
.blog-card.from-pink-500.to-purple-600 .card-gradient {
background: linear-gradient(135deg, #ec4899 0%, #9333ea 100%);
}
.blog-card.from-blue-600.to-purple-600 .card-gradient {
background: linear-gradient(135deg, #2563eb 0%, #9333ea 100%);
}
.category-badge {
background: rgba(255, 255, 255, 0.2);
color: white;
padding: 0.5rem 1rem;
border-radius: 1rem;
font-size: 0.85rem;
font-weight: 600;
text-transform: capitalize;
backdrop-filter: blur(10px);
}
.card-date {
color: rgba(255, 255, 255, 0.9);
font-size: 0.85rem;
font-weight: 500;
text-align: right;
}
.card-content {
padding: 1.5rem;
}
.card-title {
font-size: 1.3rem;
font-weight: 600;
margin-bottom: 0.75rem;
line-height: 1.3;
}
.card-title a {
color: var(--sl-color-text);
text-decoration: none;
transition: color 0.2s ease;
}
.card-title a:hover {
color: var(--sl-color-accent);
}
.card-description {
color: var(--sl-color-text-muted);
line-height: 1.6;
margin-bottom: 1rem;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.read-more {
color: var(--sl-color-accent);
text-decoration: none;
font-weight: 500;
font-size: 0.9rem;
transition: color 0.2s ease;
}
.read-more:hover {
color: var(--sl-color-text);
}
/* Responsive design */
@media (max-width: 768px) {
.blog-header h1 {
font-size: 2.5rem;
}
.blog-grid {
grid-template-columns: 1fr;
gap: 1.5rem;
}
.category-filter {
gap: 0.5rem;
margin-bottom: 2rem;
}
.category-btn {
padding: 0.5rem 1rem;
font-size: 0.85rem;
}
}
@media (max-width: 480px) {
.blog-container {
padding: 1.5rem 0.75rem;
}
.blog-header h1 {
font-size: 2rem;
}
.card-gradient {
height: 100px;
}
.card-content {
padding: 1rem;
}
}
</style>
<script>
// Category filtering functionality
const categoryButtons = document.querySelectorAll('.category-btn');
const blogCards = document.querySelectorAll('.blog-card');
categoryButtons.forEach(button => {
button.addEventListener('click', () => {
// Remove active class from all buttons
categoryButtons.forEach(btn => btn.classList.remove('active'));
// Add active class to clicked button
button.classList.add('active');
const selectedCategory = button.dataset.category;
// Show/hide cards based on category
blogCards.forEach(card => {
if (selectedCategory === 'all' || card.dataset.category === selectedCategory) {
card.style.display = 'block';
} else {
card.style.display = 'none';
}
});
});
});
</script>
</Layout>

View File

@ -0,0 +1,373 @@
---
import { getCollection } from 'astro:content';
import Layout from '../../layouts/Layout.astro';
import CustomNav from '../../components/CustomNav.astro';
export async function getStaticPaths() {
const blogEntries = await getCollection('blog');
return blogEntries.map(entry => ({
params: { slug: entry.slug },
props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
const formattedDate = new Date(entry.data.date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
const tags = entry.data.tags ? entry.data.tags.split(',').map(tag => tag.trim()) : [];
---
<Layout title={entry.data.title} description={entry.data.description}>
<CustomNav />
<main class="blog-post">
<article class="blog-article">
<!-- Back to Blog -->
<div class="back-link">
<a href="/blog">← Back to Blog</a>
</div>
<!-- Article Header -->
<header class="article-header">
<div class="article-meta">
<time class="article-date">{formattedDate}</time>
{entry.data.categories && (
<span class="article-category">{entry.data.categories}</span>
)}
</div>
<h1 class="article-title">{entry.data.title}</h1>
<p class="article-description">{entry.data.description}</p>
{tags.length > 0 && (
<div class="article-tags">
{tags.map(tag => (
<span class="tag">{tag}</span>
))}
</div>
)}
</header>
<!-- Article Content -->
<div class="article-content">
<Content />
</div>
<!-- Article Footer -->
<footer class="article-footer">
<div class="footer-cta">
<h3>Ready to try Jan?</h3>
<p>Experience the power of local AI with complete privacy and control.</p>
<a href="https://jan.ai/" class="cta-button" target="_blank" rel="noopener">
Download Jan →
</a>
</div>
<div class="back-to-blog">
<a href="/blog" class="back-button">← Back to Blog</a>
</div>
</footer>
</article>
</main>
</Layout>
<style>
.blog-post {
min-height: 100vh;
background: var(--sl-color-bg);
color: var(--sl-color-text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}
.blog-article {
max-width: 800px;
margin: 0 auto;
padding: 2rem 1rem;
}
.back-link {
margin-bottom: 2rem;
}
.back-link a {
color: var(--sl-color-text-muted);
text-decoration: none;
font-size: 0.9rem;
transition: color 0.2s ease;
}
.back-link a:hover {
color: var(--sl-color-accent);
}
.article-header {
margin-bottom: 3rem;
text-align: center;
}
.article-meta {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
margin-bottom: 1rem;
font-size: 0.9rem;
color: var(--sl-color-text-muted);
}
.article-date {
display: flex;
align-items: center;
}
.article-category {
background: var(--sl-color-accent);
color: white;
padding: 0.25rem 0.75rem;
border-radius: 1rem;
font-size: 0.8rem;
font-weight: 500;
text-transform: capitalize;
}
.article-title {
font-size: 2.5rem;
font-weight: 700;
line-height: 1.2;
margin-bottom: 1rem;
color: var(--sl-color-text);
}
.article-description {
font-size: 1.2rem;
color: var(--sl-color-text-muted);
line-height: 1.6;
margin-bottom: 1.5rem;
}
.article-tags {
display: flex;
justify-content: center;
gap: 0.5rem;
flex-wrap: wrap;
}
.tag {
background: var(--sl-color-bg-sidebar);
color: var(--sl-color-text);
padding: 0.375rem 0.75rem;
border-radius: 1rem;
font-size: 0.8rem;
border: 1px solid var(--sl-color-gray-5);
}
.article-content {
line-height: 1.7;
font-size: 1.1rem;
}
/* Content styling */
.article-content :global(h1),
.article-content :global(h2),
.article-content :global(h3),
.article-content :global(h4) {
color: var(--sl-color-text);
margin-top: 2rem;
margin-bottom: 1rem;
line-height: 1.3;
}
.article-content :global(h1) {
font-size: 2rem;
font-weight: 700;
}
.article-content :global(h2) {
font-size: 1.6rem;
font-weight: 600;
}
.article-content :global(h3) {
font-size: 1.4rem;
font-weight: 600;
}
.article-content :global(p) {
margin-bottom: 1.5rem;
color: var(--sl-color-text);
}
.article-content :global(a) {
color: var(--sl-color-accent);
text-decoration: none;
font-weight: 500;
}
.article-content :global(a:hover) {
text-decoration: underline;
}
.article-content :global(ul),
.article-content :global(ol) {
margin-bottom: 1.5rem;
padding-left: 2rem;
}
.article-content :global(li) {
margin-bottom: 0.5rem;
}
.article-content :global(blockquote) {
border-left: 4px solid var(--sl-color-accent);
background: var(--sl-color-bg-sidebar);
padding: 1rem 1.5rem;
margin: 2rem 0;
border-radius: 0.5rem;
font-style: italic;
}
.article-content :global(code) {
background: var(--sl-color-bg-sidebar);
padding: 0.2rem 0.4rem;
border-radius: 0.25rem;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.9em;
}
.article-content :global(pre) {
background: var(--sl-color-bg-sidebar);
padding: 1.5rem;
border-radius: 0.75rem;
overflow-x: auto;
margin: 1.5rem 0;
border: 1px solid var(--sl-color-gray-5);
}
.article-content :global(table) {
width: 100%;
border-collapse: collapse;
margin: 2rem 0;
border: 1px solid var(--sl-color-gray-5);
border-radius: 0.5rem;
overflow: hidden;
}
.article-content :global(th),
.article-content :global(td) {
padding: 0.75rem;
text-align: left;
border-bottom: 1px solid var(--sl-color-gray-5);
}
.article-content :global(th) {
background: var(--sl-color-bg-sidebar);
font-weight: 600;
}
.article-footer {
margin-top: 4rem;
padding-top: 3rem;
border-top: 1px solid var(--sl-color-gray-5);
}
.footer-cta {
background: linear-gradient(135deg, var(--sl-color-accent) 0%, #6366f1 100%);
padding: 2rem;
border-radius: 1rem;
text-align: center;
margin-bottom: 2rem;
color: white;
}
.footer-cta h3 {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.footer-cta p {
margin-bottom: 1.5rem;
opacity: 0.9;
}
.cta-button {
display: inline-block;
background: rgba(255, 255, 255, 0.2);
color: white !important;
padding: 0.75rem 2rem;
border-radius: 0.5rem;
text-decoration: none !important;
font-weight: 600;
transition: all 0.2s ease;
backdrop-filter: blur(10px);
}
.cta-button:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-1px);
}
.back-to-blog {
text-align: center;
}
.back-button {
color: var(--sl-color-text-muted);
text-decoration: none;
font-weight: 500;
transition: color 0.2s ease;
}
.back-button:hover {
color: var(--sl-color-accent);
}
/* Responsive design */
@media (max-width: 768px) {
.blog-article {
padding: 1.5rem 1rem;
}
.article-title {
font-size: 2rem;
}
.article-description {
font-size: 1.1rem;
}
.article-content {
font-size: 1rem;
}
.article-meta {
flex-direction: column;
gap: 0.5rem;
}
.footer-cta {
padding: 1.5rem;
}
}
@media (max-width: 480px) {
.blog-article {
padding: 1rem 0.75rem;
}
.article-title {
font-size: 1.75rem;
}
.article-content :global(pre) {
padding: 1rem;
}
}
</style>
</Layout>

View File

@ -0,0 +1,469 @@
---
import { getCollection } from 'astro:content';
import Layout from '../layouts/Layout.astro';
import CustomNav from '../components/CustomNav.astro';
// Get all changelog entries and sort by date (newest first)
const changelogEntries = await getCollection('changelog');
const sortedEntries = changelogEntries.sort((a, b) =>
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
);
const title = 'Changelog';
const description = 'Latest release updates from the Jan team. Check out our Roadmap to see what\'s next.';
---
<Layout title={title} description={description}>
<CustomNav />
<main class="changelog-page">
<div class="changelog-container">
<!-- Header -->
<header class="changelog-header">
<h1>Changelog</h1>
<p>Latest release updates from the Jan team. Check out our <a href="/products" class="roadmap-link">Roadmap</a> to see what's next.</p>
<!-- Email signup -->
<div class="email-signup">
<input type="email" placeholder="Enter your email to receive our updates" class="email-input" />
<button class="signup-button">→</button>
</div>
</header>
<!-- Timeline -->
<div class="changelog-timeline">
{sortedEntries.map((entry, index) => {
const date = new Date(entry.data.date);
const formattedDate = date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
return (
<article class="changelog-entry">
<!-- Timeline dot and date -->
<div class="timeline-marker">
<div class="timeline-dot"></div>
<time class="timeline-date">{formattedDate}</time>
</div>
<!-- Content card -->
<div class="content-card">
{entry.data.image && (
<div class="media-container">
<img
src={entry.data.image}
alt={entry.data.title}
class="changelog-media"
/>
</div>
)}
<div class="card-content">
<h2 class="entry-title">
<a href={`/changelog/${entry.slug}`}>{entry.data.title}</a>
</h2>
<p class="entry-description">{entry.data.description}</p>
{entry.data.version && (
<span class="version-badge">New release Jan App v{entry.data.version}</span>
)}
</div>
</div>
</article>
);
})}
</div>
</div>
</main>
</Layout>
<style>
.changelog-page {
min-height: 100vh;
background: var(--sl-color-bg);
color: var(--sl-color-text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}
.changelog-container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
}
.changelog-header {
text-align: center;
margin-bottom: 4rem;
}
.changelog-header h1 {
font-size: 3.5rem;
font-weight: 700;
margin-bottom: 1rem;
background: linear-gradient(135deg, #ffffff 0%, #888888 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.changelog-header p {
font-size: 1.1rem;
color: var(--sl-color-text-muted);
margin-bottom: 2rem;
max-width: 600px;
margin-left: auto;
margin-right: auto;
line-height: 1.6;
}
.roadmap-link {
color: var(--sl-color-accent);
text-decoration: none;
font-weight: 500;
}
.roadmap-link:hover {
text-decoration: underline;
}
.email-signup {
display: flex;
max-width: 400px;
margin: 0 auto;
background: var(--sl-color-bg-sidebar);
border-radius: 12px;
padding: 4px;
border: 1px solid var(--sl-color-hairline-shade);
}
.email-input {
flex: 1;
padding: 12px 16px;
background: transparent;
border: none;
color: var(--sl-color-text);
font-size: 0.95rem;
outline: none;
}
.email-input::placeholder {
color: var(--sl-color-text-muted);
}
.signup-button {
padding: 12px 16px;
background: var(--sl-color-accent);
border: none;
border-radius: 8px;
color: var(--sl-color-white);
font-size: 1.1rem;
font-weight: 500;
cursor: pointer;
transition: background-color 0.2s;
}
.signup-button:hover {
background: var(--sl-color-accent);
opacity: 0.9;
}
.changelog-timeline {
position: relative;
}
.changelog-entry {
display: flex;
margin-bottom: 3rem;
position: relative;
}
.timeline-marker {
flex-shrink: 0;
width: 200px;
display: flex;
flex-direction: row;
align-items: flex-start;
position: relative;
padding-top: 2rem;
}
.timeline-dot {
width: 16px;
height: 16px;
background: var(--sl-color-accent);
border-radius: 50%;
border: 4px solid var(--sl-color-bg);
position: relative;
z-index: 2;
margin-right: 1rem;
}
.timeline-dot::before {
content: '';
position: absolute;
top: 24px;
left: 50%;
transform: translateX(-50%);
width: 2px;
height: 100px;
background: var(--sl-color-hairline-shade);
z-index: 1;
}
.changelog-entry:last-child .timeline-dot::before {
display: none;
}
.timeline-date {
color: var(--sl-color-text-muted);
font-size: 0.9rem;
font-weight: 500;
text-align: left;
white-space: nowrap;
margin-top: -2px;
}
.content-card {
flex: 1;
background: var(--sl-color-bg-sidebar);
border-radius: 16px;
border: 1px solid var(--sl-color-gray-5);
overflow: hidden;
margin-left: 2rem;
transition: transform 0.2s, box-shadow 0.2s;
}
.content-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(74, 158, 255, 0.1);
border-color: var(--sl-color-gray-4);
}
.media-container {
aspect-ratio: 16/9;
overflow: hidden;
background: #1a1a1a;
}
.changelog-media {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s;
}
.content-card:hover .changelog-media {
transform: scale(1.02);
}
.card-content {
padding: 1.5rem;
}
.entry-title {
margin: 0 0 0.75rem 0;
font-size: 1.4rem;
font-weight: 600;
line-height: 1.3;
}
.entry-title a {
color: var(--sl-color-text);
text-decoration: none;
transition: color 0.2s;
}
.entry-title a:hover {
color: var(--sl-color-accent);
}
.entry-description {
color: var(--sl-color-text-muted);
line-height: 1.6;
margin-bottom: 1rem;
font-size: 0.95rem;
}
.version-badge {
display: inline-block;
background: #1a4a2e;
color: #4ade80;
padding: 0.375rem 0.75rem;
border-radius: 6px;
font-size: 0.8rem;
font-weight: 500;
border: 1px solid #2d5f3f;
}
/* === PROGRESSIVE RESPONSIVE DESIGN === */
/* Tablet and down (768px) */
@media (max-width: 768px) {
.changelog-header h1 {
font-size: 2.5rem;
}
.changelog-entry {
flex-direction: column;
}
.timeline-marker {
width: 100%;
flex-direction: row;
justify-content: flex-start;
align-items: center;
margin-bottom: 1rem;
}
.timeline-date {
margin-top: 0;
margin-left: 1rem;
}
.timeline-dot::before {
display: none;
}
.content-card {
margin-left: 0;
}
}
/* Mobile landscape (640px and below) */
@media (max-width: 640px) {
.changelog-header h1 {
font-size: 2rem;
}
.changelog-header p {
font-size: 1rem;
}
/* Email signup remains horizontal on mobile landscape */
.email-signup {
max-width: 350px;
}
.email-input {
font-size: 0.9rem;
}
.signup-button {
font-size: 1rem;
padding: 10px 14px;
}
}
/* Mobile (640px and below) - Much smaller email signup */
@media (max-width: 640px) {
.changelog-container {
padding: 1.5rem 1rem;
}
.changelog-header h1 {
font-size: 2rem;
}
/* Make email signup much more compact */
.email-signup {
flex-direction: column;
max-width: 280px;
padding: 4px;
gap: 4px;
}
.email-input {
padding: 8px 12px;
border-radius: 6px;
font-size: 0.85rem;
}
.signup-button {
padding: 8px 12px;
border-radius: 6px;
font-size: 0.85rem;
min-height: auto;
}
}
/* Very small mobile (480px and below) */
@media (max-width: 480px) {
.changelog-container {
padding: 1rem 0.75rem;
}
.changelog-header h1 {
font-size: 1.75rem;
}
.changelog-header {
margin-bottom: 2.5rem;
}
/* Even more compact email signup */
.email-signup {
max-width: 240px;
padding: 3px;
}
.email-input {
padding: 6px 10px;
font-size: 0.8rem;
}
.signup-button {
padding: 6px 10px;
font-size: 0.8rem;
}
}
/* Tiny screens (360px and below) */
@media (max-width: 360px) {
.changelog-container {
padding: 1rem 0.5rem;
}
.changelog-header h1 {
font-size: 1.5rem;
}
.email-signup {
max-width: 200px;
}
.email-input {
font-size: 0.75rem;
padding: 5px 8px;
}
.signup-button {
font-size: 0.75rem;
padding: 5px 8px;
}
}
</style>
<script>
// Add email signup functionality
const signupButton = document.querySelector('.signup-button');
const emailInput = document.querySelector('.email-input');
signupButton?.addEventListener('click', (e) => {
e.preventDefault();
const email = (emailInput as HTMLInputElement)?.value;
if (email) {
// You can implement your email signup logic here
console.log('Email signup:', email);
alert('Thanks for subscribing! We\'ll keep you updated.');
}
});
emailInput?.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
signupButton?.click();
}
});
</script>
</Layout>

View File

@ -0,0 +1,307 @@
---
import { getCollection, type CollectionEntry } from 'astro:content';
import Layout from '../../layouts/Layout.astro';
import CustomNav from '../../components/CustomNav.astro';
export async function getStaticPaths() {
const changelogEntries = await getCollection('changelog');
return changelogEntries.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}));
}
interface Props {
entry: CollectionEntry<'changelog'>;
}
const { entry } = Astro.props;
const { Content } = await entry.render();
const date = new Date(entry.data.date);
const formattedDate = date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
---
<Layout title={entry.data.title} description={entry.data.description}>
<CustomNav />
<main class="changelog-entry-page">
<div class="container">
<!-- Back link -->
<nav class="back-nav">
<a href="/changelog" class="back-link">← Back to Changelog</a>
</nav>
<!-- Entry header -->
<header class="entry-header">
<time class="entry-date">{formattedDate}</time>
<h1 class="entry-title">{entry.data.title}</h1>
{entry.data.version && (
<div class="version-info">
<span class="version-badge">v{entry.data.version}</span>
</div>
)}
{entry.data.image && (
<div class="hero-media">
<img
src={entry.data.image}
alt={entry.data.title}
class="hero-image"
/>
</div>
)}
</header>
<!-- Entry content -->
<article class="entry-content">
<Content />
</article>
<!-- Footer navigation -->
<footer class="entry-footer">
<a href="/changelog" class="back-to-changelog">← Back to Changelog</a>
<div class="share-links">
<span>Share:</span>
<a href={`https://twitter.com/intent/tweet?text=${encodeURIComponent(entry.data.title)}&url=${encodeURIComponent(Astro.url.href)}`} target="_blank" rel="noopener">Twitter</a>
</div>
</footer>
</div>
</main>
</Layout>
<style>
.changelog-entry-page {
min-height: 100vh;
background: #0a0a0a;
color: #ffffff;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 2rem 1rem;
}
.back-nav {
margin-bottom: 2rem;
}
.back-link {
color: #888;
text-decoration: none;
font-size: 0.9rem;
transition: color 0.2s;
}
.back-link:hover {
color: #4A9EFF;
}
.entry-header {
margin-bottom: 3rem;
text-align: center;
}
.entry-date {
color: #888;
font-size: 0.9rem;
font-weight: 500;
}
.entry-title {
font-size: 2.5rem;
font-weight: 700;
margin: 1rem 0;
line-height: 1.2;
background: linear-gradient(135deg, #ffffff 0%, #888888 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.version-info {
margin-bottom: 2rem;
}
.version-badge {
display: inline-block;
background: #1a4a2e;
color: #4ade80;
padding: 0.5rem 1rem;
border-radius: 8px;
font-size: 0.9rem;
font-weight: 600;
border: 1px solid #2d5f3f;
}
.hero-media {
margin: 2rem 0;
border-radius: 12px;
overflow: hidden;
background: #111;
}
.hero-image {
width: 100%;
height: auto;
display: block;
}
.entry-content {
line-height: 1.7;
font-size: 1.05rem;
}
/* Content styling */
.entry-content :global(h2) {
color: #ffffff;
font-size: 1.75rem;
font-weight: 600;
margin: 2.5rem 0 1rem 0;
border-bottom: 2px solid #222;
padding-bottom: 0.5rem;
}
.entry-content :global(h3) {
color: #ffffff;
font-size: 1.4rem;
font-weight: 600;
margin: 2rem 0 0.75rem 0;
}
.entry-content :global(h4) {
color: #cccccc;
font-size: 1.1rem;
font-weight: 600;
margin: 1.5rem 0 0.5rem 0;
}
.entry-content :global(p) {
color: #cccccc;
margin-bottom: 1.25rem;
}
.entry-content :global(ul),
.entry-content :global(ol) {
margin: 1rem 0;
padding-left: 1.5rem;
}
.entry-content :global(li) {
color: #cccccc;
margin-bottom: 0.5rem;
line-height: 1.6;
}
.entry-content :global(strong) {
color: #ffffff;
font-weight: 600;
}
.entry-content :global(code) {
background: #1a1a1a;
color: #4A9EFF;
padding: 0.2rem 0.4rem;
border-radius: 4px;
font-size: 0.9em;
border: 1px solid #333;
}
.entry-content :global(pre) {
background: #111;
border: 1px solid #333;
border-radius: 8px;
padding: 1rem;
overflow-x: auto;
margin: 1.5rem 0;
}
.entry-content :global(pre code) {
background: none;
border: none;
padding: 0;
}
.entry-content :global(a) {
color: #4A9EFF;
text-decoration: none;
transition: color 0.2s;
}
.entry-content :global(a:hover) {
color: #3A8EEF;
text-decoration: underline;
}
.entry-content :global(blockquote) {
border-left: 4px solid #4A9EFF;
margin: 1.5rem 0;
padding: 1rem 1.5rem;
background: #111;
border-radius: 0 8px 8px 0;
}
.entry-footer {
margin-top: 4rem;
padding-top: 2rem;
border-top: 1px solid #222;
display: flex;
justify-content: space-between;
align-items: center;
}
.back-to-changelog {
color: #888;
text-decoration: none;
font-weight: 500;
transition: color 0.2s;
}
.back-to-changelog:hover {
color: #4A9EFF;
}
.share-links {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
}
.share-links span {
color: #888;
}
.share-links a {
color: #4A9EFF;
text-decoration: none;
transition: color 0.2s;
}
.share-links a:hover {
color: #3A8EEF;
}
@media (max-width: 768px) {
.entry-title {
font-size: 1.75rem;
}
.entry-footer {
flex-direction: column;
gap: 1rem;
text-align: center;
}
.container {
padding: 1rem;
}
}
</style>
</Layout>

View File

@ -6,7 +6,7 @@ import { Content } from '../../content/products/index.mdx';
<StarlightPage
frontmatter={{
title: 'Vision 🚀',
title: "Jan's Goal",
description: 'AI that runs where you need it, how you need it',
tableOfContents: false
}}