224 lines
17 KiB
HTML
224 lines
17 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<script src="./support.js"></script>
|
||
</head>
|
||
<body>
|
||
<x-dc>
|
||
<helmet>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||
<style>
|
||
html{scroll-behavior:smooth;scroll-padding-top:72px}
|
||
body{margin:0;background:#233148;color:#e9edf3;font-family:Roboto,system-ui,sans-serif;-webkit-font-smoothing:antialiased}
|
||
a{color:#f5c55a;text-decoration:none}
|
||
a:hover{color:#fbe3a6}
|
||
::selection{background:#f5c55a;color:#1d2940}
|
||
</style>
|
||
</helmet>
|
||
|
||
<div style="min-height:100vh;background:#233148;overflow-x:hidden">
|
||
|
||
<header style="position:sticky;top:0;z-index:10;background:rgba(29,41,64,0.82);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid rgba(255,255,255,0.07)">
|
||
<nav style="max-width:1120px;margin:0 auto;padding:0 24px;height:64px;display:flex;align-items:center;gap:16px">
|
||
<a href="#top" style="flex-shrink:0;white-space:nowrap;display:flex;align-items:center;gap:10px;color:#fff;font-weight:700;font-size:18px;letter-spacing:-0.01em">
|
||
<img src="assets/sun-crop.png" alt="" style="width:30px;height:30px;-webkit-mask-image:radial-gradient(circle,#000 52%,transparent 70%);mask-image:radial-gradient(circle,#000 52%,transparent 70%);transform:scale(1.35)">
|
||
<span>Summer<span style="color:#fbd77e">CMS</span></span>
|
||
</a>
|
||
<span style="flex-shrink:0;white-space:nowrap;font-size:11px;font-weight:500;letter-spacing:0.12em;color:#f5c55a;border:1px solid rgba(245,197,90,0.35);border-radius:999px;padding:3px 9px">ALPHA 0.1</span>
|
||
<div style="flex:1;display:flex;min-width:0;overflow-x:auto;scrollbar-width:none">
|
||
<sc-if value="{{ wide }}" hint-placeholder-val="{{ true }}">
|
||
<div style="display:flex;gap:4px;flex-wrap:nowrap;margin-left:auto">
|
||
<sc-for list="{{ navItems }}" as="n" hint-placeholder-count="4">
|
||
<a href="{{ n.href }}" style="{{ n.style }}">{{ n.label }}</a>
|
||
</sc-for>
|
||
</div>
|
||
</sc-if>
|
||
</div>
|
||
<a href="/docs" style="flex-shrink:0;white-space:nowrap;display:flex;align-items:center;gap:8px;background:#f5c55a;color:#1d2940;font-weight:500;font-size:14px;padding:9px 16px;border-radius:999px" style-hover="background:#fbd77e;color:#1d2940">Docs <span>→</span></a>
|
||
</nav>
|
||
</header>
|
||
|
||
<section id="top" data-screen-label="Hero" style="position:relative;padding:120px 24px 128px;display:flex;flex-direction:column;align-items:center;text-align:center;overflow:hidden">
|
||
<sc-if value="{{ showRays }}" hint-placeholder-val="{{ true }}">
|
||
<div style="position:absolute;inset:-40% -20%;background:repeating-conic-gradient(from 0deg at 50% 50%,rgba(255,255,255,0.035) 0deg 7deg,rgba(255,255,255,0) 7deg 15deg);-webkit-mask-image:radial-gradient(circle at 50% 50%,#000 10%,transparent 62%);mask-image:radial-gradient(circle at 50% 50%,#000 10%,transparent 62%);pointer-events:none"></div>
|
||
</sc-if>
|
||
<div style="position:absolute;left:50%;top:210px;width:520px;height:520px;transform:translate(-50%,-50%);background:radial-gradient(circle,rgba(245,197,90,0.16),transparent 60%);pointer-events:none"></div>
|
||
<div style="position:relative;width:180px;height:180px;border-radius:50%;border:1px solid rgba(255,255,255,0.12);display:flex;align-items:center;justify-content:center;background:#29344a">
|
||
<img src="assets/sun-crop.png" alt="SummerCMS sun" style="width:180px;height:180px;border-radius:50%">
|
||
</div>
|
||
<h1 style="position:relative;margin:28px 0 0;font-size:clamp(44px,7vw,76px);line-height:1;font-weight:700;letter-spacing:-0.02em;color:#fff">Summer<span style="background:linear-gradient(180deg,#fde9b4,#f5c55a);-webkit-background-clip:text;background-clip:text;color:transparent">CMS</span></h1>
|
||
<p style="position:relative;margin:16px 0 0;font-size:clamp(18px,2.2vw,22px);font-weight:300;letter-spacing:0.01em;color:#c5ccd6">A new dawn in content management</p>
|
||
<p style="position:relative;margin:24px 0 0;max-width:600px;font-size:17px;line-height:1.6;color:#a3adbd;text-wrap:pretty">A content management framework for Go, inspired by WinterCMS. Plugins, the admin SPA and console commands compile into a single binary.</p>
|
||
<div style="position:relative;margin-top:40px;display:flex;gap:12px;flex-wrap:wrap;justify-content:center">
|
||
<a href="/docs" style="background:#f5c55a;color:#1d2940;font-weight:500;font-size:15px;padding:14px 26px;border-radius:999px" style-hover="background:#fbd77e;color:#1d2940">Read the docs</a>
|
||
<a href="#start" style="display:flex;align-items:center;gap:10px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.14);color:#e9edf3;font-weight:500;font-size:15px;padding:13px 24px;border-radius:999px" style-hover="background:rgba(255,255,255,0.1);color:#fff"><span style="width:8px;height:8px;border-radius:50%;background:#f5c55a"></span>Alpha 0.1 is out</a>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="why" data-screen-label="Why" style="max-width:1120px;margin:0 auto;padding:96px 24px">
|
||
<div style="font-size:12px;font-weight:500;letter-spacing:0.16em;color:#f5c55a">WHY SUMMER</div>
|
||
<h2 style="margin:12px 0 0;max-width:720px;font-size:clamp(30px,4vw,42px);line-height:1.15;font-weight:700;letter-spacing:-0.015em;color:#fff;text-wrap:pretty">What you tested is exactly what you deploy.</h2>
|
||
<div style="margin-top:48px;display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:20px">
|
||
<div style="background:#29344a;border:1px solid rgba(255,255,255,0.08);border-radius:16px;padding:28px">
|
||
<div style="font-family:'Roboto Mono',monospace;font-size:13px;color:#f5c55a">01</div>
|
||
<h3 style="margin:16px 0 8px;font-size:20px;font-weight:500;color:#fff">One binary</h3>
|
||
<p style="margin:0;font-size:15px;line-height:1.6;color:#a3adbd;text-wrap:pretty">Plugins are Go packages compiled in at build time. Nothing is scanned, loaded or installed at runtime.</p>
|
||
</div>
|
||
<div style="background:#29344a;border:1px solid rgba(255,255,255,0.08);border-radius:16px;padding:28px">
|
||
<div style="font-family:'Roboto Mono',monospace;font-size:13px;color:#f5c55a">02</div>
|
||
<h3 style="margin:16px 0 8px;font-size:20px;font-weight:500;color:#fff">YAML-driven admin</h3>
|
||
<p style="margin:0;font-size:15px;line-height:1.6;color:#a3adbd;text-wrap:pretty">Describe lists and forms in <code style="font-family:'Roboto Mono',monospace;font-size:13px;color:#e9edf3">fields.yaml</code> and <code style="font-family:'Roboto Mono',monospace;font-size:13px;color:#e9edf3">columns.yaml</code>. An embedded SPA renders them.</p>
|
||
</div>
|
||
<div style="background:#29344a;border:1px solid rgba(255,255,255,0.08);border-radius:16px;padding:28px">
|
||
<div style="font-family:'Roboto Mono',monospace;font-size:13px;color:#f5c55a">03</div>
|
||
<h3 style="margin:16px 0 8px;font-size:20px;font-weight:500;color:#fff">Headless by design</h3>
|
||
<p style="margin:0;font-size:15px;line-height:1.6;color:#a3adbd;text-wrap:pretty">A JSON API declared route by route, plus realtime channels. Build the public site in whatever frontend you like.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="features" data-screen-label="Features" style="border-top:1px solid rgba(255,255,255,0.07);border-bottom:1px solid rgba(255,255,255,0.07);background:#1f2b42">
|
||
<div style="max-width:1120px;margin:0 auto;padding:96px 24px">
|
||
<div style="font-size:12px;font-weight:500;letter-spacing:0.16em;color:#f5c55a">WHAT'S IN THE BOX</div>
|
||
<h2 style="margin:12px 0 0;max-width:720px;font-size:clamp(30px,4vw,42px);line-height:1.15;font-weight:700;letter-spacing:-0.015em;color:#fff">The services a content app needs.</h2>
|
||
<div style="margin-top:48px;display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:1px;background:rgba(255,255,255,0.08);border:1px solid rgba(255,255,255,0.08);border-radius:16px;overflow:hidden">
|
||
<sc-for list="{{ features }}" as="f" hint-placeholder-count="8">
|
||
<a href="{{ f.href }}" style="display:flex;flex-direction:column;gap:6px;background:#1f2b42;padding:24px;color:#e9edf3" style-hover="background:#253350;color:#fff">
|
||
<span style="font-size:16px;font-weight:500">{{ f.title }}</span>
|
||
<span style="font-size:14px;line-height:1.5;color:#a3adbd">{{ f.body }}</span>
|
||
</a>
|
||
</sc-for>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="winter" data-screen-label="From WinterCMS" style="max-width:1120px;margin:0 auto;padding:96px 24px;display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:48px;align-items:start">
|
||
<div>
|
||
<div style="font-size:12px;font-weight:500;letter-spacing:0.16em;color:#f5c55a">COMING FROM WINTERCMS</div>
|
||
<h2 style="margin:12px 0 0;font-size:clamp(30px,4vw,42px);line-height:1.15;font-weight:700;letter-spacing:-0.015em;color:#fff;text-wrap:pretty">Same shape. Compiled and typed.</h2>
|
||
<p style="margin:20px 0 0;font-size:16px;line-height:1.65;color:#a3adbd;text-wrap:pretty">Plugins still register and boot, require each other, ship migrations and admin YAML. A plugin ports file by file.</p>
|
||
<a href="/docs/setup/coming-from-wintercms" style="display:inline-flex;margin-top:24px;font-weight:500;font-size:15px">See the full concept map →</a>
|
||
</div>
|
||
<div style="border:1px solid rgba(255,255,255,0.08);border-radius:16px;overflow:hidden;background:#29344a">
|
||
<div style="display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);padding:14px 20px;font-size:12px;font-weight:500;letter-spacing:0.12em;color:#8a94a3;border-bottom:1px solid rgba(255,255,255,0.08)">
|
||
<span>WINTERCMS</span><span>SUMMERCMS</span>
|
||
</div>
|
||
<sc-for list="{{ concepts }}" as="c" hint-placeholder-count="6">
|
||
<div style="display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);gap:12px;padding:14px 20px;border-bottom:1px solid rgba(255,255,255,0.06);font-family:'Roboto Mono',monospace;font-size:13px;line-height:1.5">
|
||
<span style="color:#a3adbd">{{ c.w }}</span>
|
||
<span style="color:#fbe3a6">{{ c.s }}</span>
|
||
</div>
|
||
</sc-for>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="start" data-screen-label="Get started" style="border-top:1px solid rgba(255,255,255,0.07);background:#1f2b42">
|
||
<div style="max-width:1120px;margin:0 auto;padding:96px 24px;display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:48px;align-items:center">
|
||
<div>
|
||
<div style="font-size:12px;font-weight:500;letter-spacing:0.16em;color:#f5c55a">GET STARTED</div>
|
||
<h2 style="margin:12px 0 0;font-size:clamp(30px,4vw,42px);line-height:1.15;font-weight:700;letter-spacing:-0.015em;color:#fff">Build your first app.</h2>
|
||
<div style="margin-top:24px;display:flex;gap:8px;flex-wrap:wrap">
|
||
<span style="font-size:13px;color:#c5ccd6;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);border-radius:999px;padding:6px 12px">Go 1.27</span>
|
||
<span style="font-size:13px;color:#c5ccd6;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);border-radius:999px;padding:6px 12px">PostgreSQL 16</span>
|
||
</div>
|
||
<p style="margin:20px 0 0;font-size:16px;line-height:1.65;color:#a3adbd;text-wrap:pretty">Alpha 0.1 is for early adopters. APIs may change before 1.0.</p>
|
||
<div style="margin-top:28px;display:flex;gap:12px;flex-wrap:wrap">
|
||
<a href="/docs/setup/installation" style="background:#f5c55a;color:#1d2940;font-weight:500;font-size:15px;padding:13px 24px;border-radius:999px" style-hover="background:#fbd77e;color:#1d2940">Installation guide</a>
|
||
<a href="https://git.golem15.com/golem15/summercms" style="border:1px solid rgba(255,255,255,0.14);color:#e9edf3;font-weight:500;font-size:15px;padding:12px 22px;border-radius:999px" style-hover="background:rgba(255,255,255,0.08);color:#fff">Source</a>
|
||
</div>
|
||
</div>
|
||
<div style="background:#18223a;border:1px solid rgba(255,255,255,0.08);border-radius:16px;overflow:hidden">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;padding:12px 18px;border-bottom:1px solid rgba(255,255,255,0.07)">
|
||
<span style="font-family:'Roboto Mono',monospace;font-size:12px;color:#8a94a3">terminal</span>
|
||
<button onClick="{{ copy }}" style="font:500 12px Roboto,sans-serif;color:#c5ccd6;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);border-radius:6px;padding:5px 10px;cursor:pointer">{{ copyLabel }}</button>
|
||
</div>
|
||
<div style="padding:22px 20px;font-family:'Roboto Mono',monospace;font-size:14px;line-height:1.9;color:#e9edf3;overflow-x:auto;display:flex;flex-direction:column">
|
||
<span style="color:#8a94a3;white-space:pre"># install the summer CLI</span>
|
||
<span style="white-space:pre"><span style="color:#f5c55a">$ </span>go install ./cmd/summer</span>
|
||
<span style="color:#8a94a3;white-space:pre;margin-top:16px"># build and run the example app</span>
|
||
<span style="white-space:pre"><span style="color:#f5c55a">$ </span>cd examples/hello</span>
|
||
<span style="white-space:pre"><span style="color:#f5c55a">$ </span>summer build</span>
|
||
<span style="white-space:pre"><span style="color:#f5c55a">$ </span>./bin/hello greeter:hello</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<footer style="border-top:1px solid rgba(255,255,255,0.07)">
|
||
<div style="max-width:1120px;margin:0 auto;padding:32px 24px;display:flex;gap:24px;align-items:center;flex-wrap:wrap;font-size:13px;color:#8a94a3">
|
||
<span>© 2026 SummerCMS. Something bright is here.</span>
|
||
<div style="flex:1"></div>
|
||
<div style="display:flex;gap:20px">
|
||
<a href="/docs" style="color:#a3adbd" style-hover="color:#f5c55a">Docs</a>
|
||
<a href="https://git.golem15.com/golem15/summercms" style="color:#a3adbd" style-hover="color:#f5c55a">Source</a>
|
||
<a href="#top" style="color:#a3adbd" style-hover="color:#f5c55a">Back to top ↑</a>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
</x-dc>
|
||
<script type="text/x-dc" data-dc-script data-props="{"showRays":{"editor":"boolean","default":true,"tsType":"boolean"},"scrollSpy":{"editor":"boolean","default":true,"tsType":"boolean"}}">
|
||
class Component extends DCLogic {
|
||
state = { active: '', copied: false, wide: window.innerWidth > 720 };
|
||
sections = [['why','Why'],['features','Features'],['winter','From WinterCMS'],['start','Get started']];
|
||
componentDidMount() {
|
||
this.onScroll = () => {
|
||
let a = '';
|
||
for (const [id] of this.sections) {
|
||
const el = document.getElementById(id);
|
||
if (el && el.getBoundingClientRect().top < 140) a = id;
|
||
}
|
||
if (a !== this.state.active) this.setState({ active: a });
|
||
};
|
||
window.addEventListener('scroll', this.onScroll, { passive: true });
|
||
this.mq = window.matchMedia('(min-width: 721px)');
|
||
this.onMq = () => this.setState({ wide: this.mq.matches });
|
||
this.mq.addEventListener('change', this.onMq);
|
||
this.onScroll();
|
||
}
|
||
componentWillUnmount() { window.removeEventListener('scroll', this.onScroll); this.mq?.removeEventListener('change', this.onMq); }
|
||
renderVals() {
|
||
const spy = this.props.scrollSpy ?? true;
|
||
return {
|
||
showRays: this.props.showRays ?? true,
|
||
wide: this.state.wide,
|
||
navItems: this.sections.map(([id, label]) => {
|
||
const on = spy && this.state.active === id;
|
||
return { href: '#' + id, label, style: `white-space:nowrap;flex-shrink:0;font-size:14px;font-weight:500;padding:8px 12px;border-radius:999px;color:${on ? '#f5c55a' : '#c5ccd6'};background:${on ? 'rgba(245,197,90,0.1)' : 'transparent'}` };
|
||
}),
|
||
features: [
|
||
{ title: 'Admin SPA', body: 'Embedded in the binary, driven by each plugin’s YAML.', href: '/docs/backend/admin-spa' },
|
||
{ title: 'Models & migrations', body: 'GORM structs with fill, validation and pagination helpers.', href: '/docs/database/models' },
|
||
{ title: 'Routing & auth', body: 'Route groups, named middleware, tokens and OAuth.', href: '/docs/services/routing' },
|
||
{ title: 'Queued jobs', body: 'Dispatched inside the caller’s transaction.', href: '/docs/services/jobs' },
|
||
{ title: 'Realtime', body: 'Broadcast model changes to subscribed clients.', href: '/docs/services/realtime' },
|
||
{ title: 'Search', body: 'Searchable models, synced after commit.', href: '/docs/services/search' },
|
||
{ title: 'Mail & push', body: 'Plugin mail templates and push notifications.', href: '/docs/services/mail' },
|
||
{ title: 'Console', body: 'Scaffolding, scheduler, workers and your own commands.', href: '/docs/console/introduction' },
|
||
],
|
||
concepts: [
|
||
{ w: 'Plugin.php', s: 'party.Plugin' },
|
||
{ w: 'version.yaml + updates/', s: 'pact.HasMigrations' },
|
||
{ w: 'Eloquent models', s: 'GORM + lagoon' },
|
||
{ w: 'fields.yaml / columns.yaml', s: 'Same YAML, compiled at boot' },
|
||
{ w: 'routes.php', s: 'pact.HasRoutes' },
|
||
{ w: 'Event::listen / fire', s: 'festival.Bus' },
|
||
{ w: 'Artisan commands', s: 'bonfire.Command' },
|
||
],
|
||
copyLabel: this.state.copied ? 'Copied' : 'Copy',
|
||
copy: () => {
|
||
navigator.clipboard?.writeText('go install ./cmd/summer\ncd examples/hello\nsummer build\n./bin/hello greeter:hello');
|
||
this.setState({ copied: true });
|
||
setTimeout(() => this.setState({ copied: false }), 1500);
|
||
},
|
||
};
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|