@oktis-works/cms 0.10.10 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/theme-assets.d.ts +7 -11
- package/dist/theme-assets.d.ts.map +1 -1
- package/dist/theme-assets.js +436 -147
- package/dist/theme-assets.js.map +1 -1
- package/package.json +5 -5
package/dist/theme-assets.d.ts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Default theme manifest (`theme.json` = canonical name read by runtime, service and CLI). */
|
|
2
2
|
export declare const DEFAULT_THEME_MANIFEST: string;
|
|
3
|
-
/**
|
|
4
|
-
export declare const DEFAULT_THEME_CSS = "/* Tema default do OkCMS \u2014 estilos b\u00E1sicos (servido direto de dist/theme.css) */\n[data-theme=\"default\"]{\n --brand: #4f46e5;\n --text: #1f2937;\n --muted: #6b7280;\n --surface: #ffffff;\n --border: #e5e7eb;\n}\n\n[data-theme=\"default\"] *{ box-sizing: border-box; }\n\n[data-theme=\"default\"]{\n margin: 0;\n font-family: system-ui, -apple-system, \"Segoe UI\", sans-serif;\n color: var(--text);\n background: var(--surface);\n line-height: 1.6;\n}\n\n[data-theme=\"default\"] main{\n max-width: 46rem;\n margin: 0 auto;\n padding: 2.5rem 1.5rem;\n}\n\n[data-theme=\"default\"] .hero__title{ margin: 0 0 0.5rem; font-size: 2rem; }\n[data-theme=\"default\"] .hero__description{ margin: 0 0 2rem; color: var(--muted); }\n\n[data-theme=\"default\"] .listing{ display: grid; gap: 1rem; }\n[data-theme=\"default\"] .card{ border: 1px solid var(--border); border-radius: 8px; padding: 1rem 1.25rem; }\n[data-theme=\"default\"] .entry__title{ margin: 0 0 0.25rem; font-size: 1.15rem; }\n[data-theme=\"default\"] .entry__title a{ color: var(--brand); text-decoration: none; }\n[data-theme=\"default\"] .entry__title a:hover{ text-decoration: underline; }\n[data-theme=\"default\"] .entry__excerpt{ margin: 0; color: var(--muted); }\n\n[data-theme=\"default\"] .entry__header{ margin-bottom: 1.5rem; }\n[data-theme=\"default\"] .entry__cover{ max-width: 100%; border-radius: 8px; margin: 1rem 0; }\n[data-theme=\"default\"] .entry__body{ font-size: 1.05rem; }\n[data-theme=\"default\"] .entry__date{ color: var(--muted); font-size: 0.85rem; }\n\n[data-theme=\"default\"] .not-found__code{ margin: 0; font-size: 4rem; color: var(--brand); }\n[data-theme=\"default\"] .not-found__message{ color: var(--muted); }\n";
|
|
5
|
-
/**
|
|
6
|
-
* Templates da hierarquia (formato do runtime: `*.astro` NA RAIZ do tema,
|
|
7
|
-
* sintaxe `{{var}}` / `{{{raw}}}` / `{{#each}}` / `{{#if}}`).
|
|
8
|
-
*/
|
|
3
|
+
/** Default theme design system — served straight from dist/theme.css (no build). */
|
|
4
|
+
export declare const DEFAULT_THEME_CSS = "/* OkCMS default theme \u2014 design system (served straight from dist/theme.css) */\n[data-theme=\"default\"]{\n --brand: #4f46e5;\n --brand-strong: #4338ca;\n --brand-soft: #eef2ff;\n --text: #111827;\n --muted: #6b7280;\n --surface: #ffffff;\n --bg: #f9fafb;\n --border: #e5e7eb;\n --border-strong: #d1d5db;\n --radius: 12px;\n --radius-sm: 8px;\n --shadow-sm: 0 1px 2px rgba(17,24,39,.06);\n --shadow-md: 0 6px 20px rgba(17,24,39,.08);\n --shadow-lg: 0 16px 40px rgba(17,24,39,.14);\n}\n\n[data-theme=\"default\"] *,[data-theme=\"default\"] *::before,[data-theme=\"default\"] *::after{ box-sizing: border-box; }\n\n[data-theme=\"default\"]{\n margin: 0;\n font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n color: var(--text);\n background: var(--bg);\n line-height: 1.65;\n -webkit-font-smoothing: antialiased;\n}\n\n[data-theme=\"default\"] a{ color: var(--brand); text-decoration: none; }\n[data-theme=\"default\"] a:hover{ color: var(--brand-strong); }\n[data-theme=\"default\"] img{ max-width: 100%; border-radius: var(--radius-sm); }\n\n[data-theme=\"default\"] .container{ max-width: 72rem; margin: 0 auto; padding: 0 1.25rem; }\n\n/* ---------- Header ---------- */\n[data-theme=\"default\"] .site-header{\n position: sticky; top: 0; z-index: 20;\n background: rgba(255,255,255,.86);\n backdrop-filter: blur(10px);\n border-bottom: 1px solid var(--border);\n}\n[data-theme=\"default\"] .site-header__inner{\n display: flex; align-items: center; justify-content: space-between;\n gap: 1rem; min-height: 3.75rem; flex-wrap: wrap; padding-top: .5rem; padding-bottom: .5rem;\n}\n[data-theme=\"default\"] .site-brand{\n font-weight: 800; font-size: 1.15rem; letter-spacing: -.02em; color: var(--text);\n display: inline-flex; align-items: center; gap: .5rem;\n}\n[data-theme=\"default\"] .site-brand::before{\n content: \"\"; width: .65rem; height: .65rem; border-radius: 999px;\n background: linear-gradient(135deg, var(--brand), #8b5cf6);\n}\n[data-theme=\"default\"] .site-brand:hover{ color: var(--text); }\n[data-theme=\"default\"] .site-nav{ display: flex; align-items: center; gap: .25rem; flex-wrap: wrap; }\n[data-theme=\"default\"] .site-nav__link{\n padding: .45rem .85rem; border-radius: 999px; color: var(--muted); font-weight: 500; font-size: .95rem;\n}\n[data-theme=\"default\"] .site-nav__link:hover{ color: var(--brand); background: var(--brand-soft); }\n\n/* ---------- Hero ---------- */\n[data-theme=\"default\"] .hero{\n position: relative; overflow: hidden;\n background: linear-gradient(135deg, #4f46e5 0%, #6d28d9 55%, #7c3aed 100%);\n color: #fff; text-align: center;\n padding: 5rem 1.5rem 5.5rem;\n}\n[data-theme=\"default\"] .hero::after{\n content: \"\"; position: absolute; inset: auto -10% -60% -10%; height: 70%;\n background: var(--bg); border-radius: 50% 50% 0 0;\n}\n[data-theme=\"default\"] .hero > *{ position: relative; z-index: 1; }\n[data-theme=\"default\"] .hero__kicker{\n margin: 0 0 .75rem; text-transform: uppercase; letter-spacing: .18em;\n font-size: .78rem; font-weight: 700; color: rgba(255,255,255,.75);\n}\n[data-theme=\"default\"] .hero__title{\n margin: 0 0 1rem; font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1.12; letter-spacing: -.03em; font-weight: 800;\n}\n[data-theme=\"default\"] .hero__description{\n margin: 0 auto 1.75rem; max-width: 42rem; font-size: 1.1rem; color: rgba(255,255,255,.85);\n}\n[data-theme=\"default\"] .hero__actions{ display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }\n[data-theme=\"default\"] .hero--compact{ padding: 3.25rem 1.5rem 4rem; }\n\n/* ---------- Buttons ---------- */\n[data-theme=\"default\"] .btn{\n display: inline-flex; align-items: center; gap: .5rem;\n padding: .7rem 1.4rem; border-radius: 999px; font-weight: 600; font-size: .98rem;\n border: 1px solid transparent; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease, background .15s ease;\n}\n[data-theme=\"default\"] .btn:hover{ transform: translateY(-1px); }\n[data-theme=\"default\"] .btn--primary{ background: #fff; color: var(--brand-strong); box-shadow: var(--shadow-md); }\n[data-theme=\"default\"] .btn--primary:hover{ background: var(--brand-soft); color: var(--brand-strong); }\n[data-theme=\"default\"] .btn--ghost{ background: rgba(255,255,255,.12); color: #fff; border-color: rgba(255,255,255,.45); }\n[data-theme=\"default\"] .btn--ghost:hover{ background: rgba(255,255,255,.22); color: #fff; }\n[data-theme=\"default\"] .btn--outline{ background: transparent; color: var(--brand); border-color: var(--border-strong); }\n[data-theme=\"default\"] .btn--outline:hover{ background: var(--brand-soft); border-color: var(--brand); }\n\n/* ---------- Sections ---------- */\n[data-theme=\"default\"] .site-main{ min-height: 60vh; }\n[data-theme=\"default\"] .section{ max-width: 72rem; margin: 0 auto; padding: 3.5rem 1.25rem; }\n[data-theme=\"default\"] .section__kicker{\n margin: 0 0 .5rem; text-transform: uppercase; letter-spacing: .16em;\n font-size: .74rem; font-weight: 700; color: var(--brand);\n}\n[data-theme=\"default\"] .section__title{\n margin: 0 0 .75rem; font-size: clamp(1.5rem, 3vw, 2rem); letter-spacing: -.02em; font-weight: 800;\n}\n[data-theme=\"default\"] .section__lead{ margin: 0 0 1rem; color: var(--muted); font-size: 1.05rem; max-width: 46rem; }\n[data-theme=\"default\"] .section__more{ font-weight: 600; }\n[data-theme=\"default\"] .section--tight{ padding: 2.25rem 1.25rem; }\n[data-theme=\"default\"] .section__head{\n display: flex; align-items: baseline; justify-content: space-between;\n gap: 1rem; flex-wrap: wrap; margin-bottom: 1.75rem;\n}\n\n/* ---------- Cards / listings ---------- */\n[data-theme=\"default\"] .cards{\n display: grid; gap: 1.25rem;\n grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));\n}\n[data-theme=\"default\"] .card{\n display: flex; flex-direction: column; gap: .5rem;\n background: var(--surface); border: 1px solid var(--border);\n border-radius: var(--radius); padding: 1.4rem 1.4rem 1.2rem; box-shadow: var(--shadow-sm);\n transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;\n}\n[data-theme=\"default\"] .card:hover{ transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }\n[data-theme=\"default\"] .card__date{ font-size: .8rem; color: var(--muted); }\n[data-theme=\"default\"] .card__title{ margin: 0; font-size: 1.12rem; line-height: 1.35; }\n[data-theme=\"default\"] .card__title a{ color: var(--text); }\n[data-theme=\"default\"] .card__title a:hover{ color: var(--brand); }\n[data-theme=\"default\"] .card__excerpt{ margin: 0; color: var(--muted); font-size: .95rem; }\n[data-theme=\"default\"] .card__more{\n margin-top: auto; padding-top: .4rem; font-weight: 600; font-size: .92rem; color: var(--brand);\n}\n[data-theme=\"default\"] .listing{ display: grid; gap: 1rem; }\n\n/* ---------- Entries (single / page) ---------- */\n[data-theme=\"default\"] .entry{\n max-width: 46rem; margin: 0 auto; padding: 3rem 1.25rem 4rem;\n}\n[data-theme=\"default\"] .entry__header{ margin-bottom: 1.75rem; }\n[data-theme=\"default\"] .entry__kicker{\n margin: 0 0 .5rem; text-transform: uppercase; letter-spacing: .16em;\n font-size: .74rem; font-weight: 700; color: var(--brand);\n}\n[data-theme=\"default\"] .entry__title{\n margin: 0 0 .5rem; font-size: clamp(1.75rem, 4vw, 2.5rem); letter-spacing: -.025em; line-height: 1.15; font-weight: 800;\n}\n[data-theme=\"default\"] .entry__meta{ display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; color: var(--muted); font-size: .9rem; }\n[data-theme=\"default\"] .entry__cover{ width: 100%; border-radius: var(--radius); margin: 1rem 0; box-shadow: var(--shadow-sm); }\n[data-theme=\"default\"] .entry__body{ font-size: 1.06rem; }\n[data-theme=\"default\"] .entry__body h2{ font-size: 1.5rem; letter-spacing: -.01em; margin: 2rem 0 .75rem; }\n[data-theme=\"default\"] .entry__body h3{ font-size: 1.2rem; margin: 1.5rem 0 .5rem; }\n[data-theme=\"default\"] .entry__body p{ margin: 0 0 1rem; color: #374151; }\n[data-theme=\"default\"] .entry__body a{ text-decoration: underline; text-underline-offset: 3px; }\n[data-theme=\"default\"] .entry__body blockquote{\n margin: 1.5rem 0; padding: .75rem 1.25rem; border-left: 3px solid var(--brand);\n background: var(--brand-soft); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; color: #374151;\n}\n[data-theme=\"default\"] .entry__body pre{\n background: #0f172a; color: #e2e8f0; padding: 1rem 1.25rem; border-radius: var(--radius-sm);\n overflow: auto; font-size: .9rem;\n}\n[data-theme=\"default\"] .entry__body code{ background: var(--brand-soft); border-radius: 4px; padding: .1rem .35rem; }\n[data-theme=\"default\"] .entry__body pre code{ background: transparent; padding: 0; }\n[data-theme=\"default\"] .entry__terms{ display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }\n[data-theme=\"default\"] .badge{\n display: inline-block; padding: .25rem .7rem; border-radius: 999px;\n background: var(--brand-soft); color: var(--brand-strong); font-size: .8rem; font-weight: 600;\n}\n[data-theme=\"default\"] .entry__footer{\n margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--border);\n display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap;\n color: var(--muted); font-size: .92rem;\n}\n[data-theme=\"default\"] .entry__back{ font-weight: 600; }\n\n/* ---------- Home body sections (seeded content) ---------- */\n[data-theme=\"default\"] .about-preview{\n display: grid; gap: 1.5rem; grid-template-columns: 1.2fr .8fr; align-items: start;\n}\n[data-theme=\"default\"] .about-preview .section__more{ display: inline-block; }\n[data-theme=\"default\"] .contact{\n background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);\n box-shadow: var(--shadow-sm);\n}\n[data-theme=\"default\"] .contact .section__lead a{ font-weight: 600; }\n\n/* ---------- Archive ---------- */\n[data-theme=\"default\"] .archive-header{\n background: linear-gradient(135deg, #4f46e5 0%, #6d28d9 60%, #7c3aed 100%);\n color: #fff; text-align: center; padding: 3.25rem 1.5rem 4rem;\n}\n[data-theme=\"default\"] .archive-header__title{ margin: 0 0 .4rem; font-size: clamp(1.7rem, 4vw, 2.4rem); letter-spacing: -.02em; font-weight: 800; }\n[data-theme=\"default\"] .archive-header__description{ margin: 0; color: rgba(255,255,255,.85); }\n[data-theme=\"default\"] .archive-header + .section{ margin-top: -1.5rem; }\n[data-theme=\"default\"] .archive-header + .section .card{ background: var(--surface); }\n\n/* ---------- Empty state ---------- */\n[data-theme=\"default\"] .empty{\n text-align: center; color: var(--muted); padding: 2.5rem 1rem;\n border: 1px dashed var(--border-strong); border-radius: var(--radius); background: var(--surface);\n}\n\n/* ---------- 404 ---------- */\n[data-theme=\"default\"] .not-found{ text-align: center; padding: 5rem 1.5rem; }\n[data-theme=\"default\"] .not-found__code{\n margin: 0 0 .5rem; font-size: 5rem; font-weight: 800; letter-spacing: -.04em;\n background: linear-gradient(135deg, var(--brand), #8b5cf6);\n -webkit-background-clip: text; background-clip: text; color: transparent;\n}\n[data-theme=\"default\"] .not-found__message{ margin: 0 0 1.5rem; color: var(--muted); font-size: 1.1rem; }\n\n/* ---------- Footer ---------- */\n[data-theme=\"default\"] .site-footer{\n background: #111827; color: #d1d5db; margin-top: 4rem;\n}\n[data-theme=\"default\"] .site-footer__inner{\n display: flex; justify-content: space-between; gap: 2rem; flex-wrap: wrap;\n padding-top: 2.75rem; padding-bottom: 1.5rem;\n}\n[data-theme=\"default\"] .site-footer__title{ margin: 0 0 .35rem; color: #fff; font-weight: 700; font-size: 1.05rem; }\n[data-theme=\"default\"] .site-footer__description{ margin: 0; max-width: 24rem; color: #9ca3af; font-size: .93rem; }\n[data-theme=\"default\"] .site-footer__nav{ display: flex; flex-direction: column; gap: .45rem; }\n[data-theme=\"default\"] .site-footer__link{ color: #d1d5db; font-size: .95rem; }\n[data-theme=\"default\"] .site-footer__link:hover{ color: #fff; }\n[data-theme=\"default\"] .site-footer__bottom{ border-top: 1px solid rgba(255,255,255,.1); }\n[data-theme=\"default\"] .site-footer__copyright{\n margin: 0; padding: 1.1rem 0; text-align: center; color: #9ca3af; font-size: .85rem;\n}\n\n/* ---------- Responsive ---------- */\n@media (max-width: 860px){\n [data-theme=\"default\"] .about-preview{ grid-template-columns: 1fr; }\n [data-theme=\"default\"] .hero{ padding: 4rem 1.25rem 4.5rem; }\n}\n@media (max-width: 560px){\n [data-theme=\"default\"] .site-header__inner{ justify-content: center; }\n [data-theme=\"default\"] .site-nav{ justify-content: center; }\n [data-theme=\"default\"] .hero{ padding: 3.25rem 1rem 3.75rem; }\n [data-theme=\"default\"] .section{ padding: 2.5rem 1rem; }\n [data-theme=\"default\"] .cards{ grid-template-columns: 1fr; }\n}\n";
|
|
9
5
|
export declare const THEME_TEMPLATE_FILES: Record<string, string>;
|
|
10
|
-
/**
|
|
6
|
+
/** Complete default theme written by `okcms init` (paths relative to themes/default/). */
|
|
11
7
|
export declare const DEFAULT_THEME_FILES: Record<string, string>;
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
14
|
-
* base64 (
|
|
15
|
-
*
|
|
9
|
+
* BINARY files of the default theme: written with a Buffer decoded from
|
|
10
|
+
* base64 (writing a string would corrupt the PNG). Same re-init rule —
|
|
11
|
+
* never overwrites a file that is already present.
|
|
16
12
|
*/
|
|
17
13
|
export declare const DEFAULT_THEME_BINARY_FILES: Record<string, string>;
|
|
18
14
|
//# sourceMappingURL=theme-assets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-assets.d.ts","sourceRoot":"","sources":["../src/theme-assets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"theme-assets.d.ts","sourceRoot":"","sources":["../src/theme-assets.ts"],"names":[],"mappings":"AAUA,+FAA+F;AAC/F,eAAO,MAAM,sBAAsB,QA8BlC,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,4tZAuP7B,CAAC;AAkEF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA+IvD,CAAC;AA8BF,0FAA0F;AAC1F,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAItD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAE7D,CAAC"}
|
package/dist/theme-assets.js
CHANGED
|
@@ -1,204 +1,493 @@
|
|
|
1
|
-
// @oktis-works/cms -
|
|
1
|
+
// @oktis-works/cms - Default theme templates embedded in the CLI
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// `okcms init` writes these files into the new project's `themes/default/`:
|
|
4
|
+
// the site renders out of the box (root-level .astro templates + dist/theme.css
|
|
5
|
+
// served directly). Kept as strings because the package publishes only `dist/`.
|
|
6
|
+
// The renderer supports: {{var}} / {{{raw}}} / {{#if x}} / {{#each path}} —
|
|
7
|
+
// no {{else}} and no @index, so templates are written within that syntax.
|
|
6
8
|
import { CMS_VERSION } from '@oktis-works/validation';
|
|
7
|
-
/**
|
|
9
|
+
/** Default theme manifest (`theme.json` = canonical name read by runtime, service and CLI). */
|
|
8
10
|
export const DEFAULT_THEME_MANIFEST = `${JSON.stringify({
|
|
9
11
|
name: 'default',
|
|
10
|
-
version: '0.
|
|
11
|
-
description: '
|
|
12
|
+
version: '0.2.0',
|
|
13
|
+
description: 'OkCMS default theme — responsive hierarchical templates with real content interpolation',
|
|
12
14
|
type: 'theme',
|
|
13
15
|
author: 'Oktis Works',
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
// CMS_VERSION (
|
|
16
|
+
// BUSI-022 contract: required by theme:install through the API. Without the
|
|
17
|
+
// range the default theme would be rejected on explicit install. Derived
|
|
18
|
+
// from CMS_VERSION (single source) — never a literal.
|
|
17
19
|
compatibility: { okcms: `^${CMS_VERSION}` },
|
|
18
|
-
// Preview
|
|
20
|
+
// Preview card on the admin Themes screen (served from /themes/default/).
|
|
19
21
|
screenshots: ['screenshot.png'],
|
|
20
22
|
provides: {
|
|
21
|
-
layouts: ['home', 'index', 'single', 'page', 'archive', '404'],
|
|
23
|
+
layouts: ['front-page', 'home', 'index', 'single', 'page', 'archive', '404'],
|
|
22
24
|
assets: ['dist/theme.css'],
|
|
23
25
|
},
|
|
24
26
|
stylesConfig: {
|
|
25
27
|
engine: 'css',
|
|
26
|
-
// CSS
|
|
28
|
+
// Committed CSS already scoped — the theme owns its isolation (BUSI-040)
|
|
27
29
|
isolation: 'manual',
|
|
28
30
|
},
|
|
29
31
|
settings: [
|
|
30
|
-
{ name: 'siteTitle', type: 'text', label: '
|
|
31
|
-
{ name: 'siteDescription', type: 'text', label: '
|
|
32
|
+
{ name: 'siteTitle', type: 'text', label: 'Site title', default: 'OkCMS' },
|
|
33
|
+
{ name: 'siteDescription', type: 'text', label: 'Site description', default: '' },
|
|
32
34
|
],
|
|
33
35
|
}, null, 2)}
|
|
34
36
|
`;
|
|
35
|
-
/**
|
|
36
|
-
export const DEFAULT_THEME_CSS = `/*
|
|
37
|
+
/** Default theme design system — served straight from dist/theme.css (no build). */
|
|
38
|
+
export const DEFAULT_THEME_CSS = `/* OkCMS default theme — design system (served straight from dist/theme.css) */
|
|
37
39
|
[data-theme="default"]{
|
|
38
40
|
--brand: #4f46e5;
|
|
39
|
-
--
|
|
41
|
+
--brand-strong: #4338ca;
|
|
42
|
+
--brand-soft: #eef2ff;
|
|
43
|
+
--text: #111827;
|
|
40
44
|
--muted: #6b7280;
|
|
41
45
|
--surface: #ffffff;
|
|
46
|
+
--bg: #f9fafb;
|
|
42
47
|
--border: #e5e7eb;
|
|
48
|
+
--border-strong: #d1d5db;
|
|
49
|
+
--radius: 12px;
|
|
50
|
+
--radius-sm: 8px;
|
|
51
|
+
--shadow-sm: 0 1px 2px rgba(17,24,39,.06);
|
|
52
|
+
--shadow-md: 0 6px 20px rgba(17,24,39,.08);
|
|
53
|
+
--shadow-lg: 0 16px 40px rgba(17,24,39,.14);
|
|
43
54
|
}
|
|
44
55
|
|
|
45
|
-
[data-theme="default"]
|
|
56
|
+
[data-theme="default"] *,[data-theme="default"] *::before,[data-theme="default"] *::after{ box-sizing: border-box; }
|
|
46
57
|
|
|
47
58
|
[data-theme="default"]{
|
|
48
59
|
margin: 0;
|
|
49
|
-
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
60
|
+
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
50
61
|
color: var(--text);
|
|
51
|
-
background: var(--
|
|
52
|
-
line-height: 1.
|
|
62
|
+
background: var(--bg);
|
|
63
|
+
line-height: 1.65;
|
|
64
|
+
-webkit-font-smoothing: antialiased;
|
|
53
65
|
}
|
|
54
66
|
|
|
55
|
-
[data-theme="default"]
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
[data-theme="default"] a{ color: var(--brand); text-decoration: none; }
|
|
68
|
+
[data-theme="default"] a:hover{ color: var(--brand-strong); }
|
|
69
|
+
[data-theme="default"] img{ max-width: 100%; border-radius: var(--radius-sm); }
|
|
70
|
+
|
|
71
|
+
[data-theme="default"] .container{ max-width: 72rem; margin: 0 auto; padding: 0 1.25rem; }
|
|
72
|
+
|
|
73
|
+
/* ---------- Header ---------- */
|
|
74
|
+
[data-theme="default"] .site-header{
|
|
75
|
+
position: sticky; top: 0; z-index: 20;
|
|
76
|
+
background: rgba(255,255,255,.86);
|
|
77
|
+
backdrop-filter: blur(10px);
|
|
78
|
+
border-bottom: 1px solid var(--border);
|
|
79
|
+
}
|
|
80
|
+
[data-theme="default"] .site-header__inner{
|
|
81
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
82
|
+
gap: 1rem; min-height: 3.75rem; flex-wrap: wrap; padding-top: .5rem; padding-bottom: .5rem;
|
|
83
|
+
}
|
|
84
|
+
[data-theme="default"] .site-brand{
|
|
85
|
+
font-weight: 800; font-size: 1.15rem; letter-spacing: -.02em; color: var(--text);
|
|
86
|
+
display: inline-flex; align-items: center; gap: .5rem;
|
|
87
|
+
}
|
|
88
|
+
[data-theme="default"] .site-brand::before{
|
|
89
|
+
content: ""; width: .65rem; height: .65rem; border-radius: 999px;
|
|
90
|
+
background: linear-gradient(135deg, var(--brand), #8b5cf6);
|
|
91
|
+
}
|
|
92
|
+
[data-theme="default"] .site-brand:hover{ color: var(--text); }
|
|
93
|
+
[data-theme="default"] .site-nav{ display: flex; align-items: center; gap: .25rem; flex-wrap: wrap; }
|
|
94
|
+
[data-theme="default"] .site-nav__link{
|
|
95
|
+
padding: .45rem .85rem; border-radius: 999px; color: var(--muted); font-weight: 500; font-size: .95rem;
|
|
96
|
+
}
|
|
97
|
+
[data-theme="default"] .site-nav__link:hover{ color: var(--brand); background: var(--brand-soft); }
|
|
98
|
+
|
|
99
|
+
/* ---------- Hero ---------- */
|
|
100
|
+
[data-theme="default"] .hero{
|
|
101
|
+
position: relative; overflow: hidden;
|
|
102
|
+
background: linear-gradient(135deg, #4f46e5 0%, #6d28d9 55%, #7c3aed 100%);
|
|
103
|
+
color: #fff; text-align: center;
|
|
104
|
+
padding: 5rem 1.5rem 5.5rem;
|
|
105
|
+
}
|
|
106
|
+
[data-theme="default"] .hero::after{
|
|
107
|
+
content: ""; position: absolute; inset: auto -10% -60% -10%; height: 70%;
|
|
108
|
+
background: var(--bg); border-radius: 50% 50% 0 0;
|
|
109
|
+
}
|
|
110
|
+
[data-theme="default"] .hero > *{ position: relative; z-index: 1; }
|
|
111
|
+
[data-theme="default"] .hero__kicker{
|
|
112
|
+
margin: 0 0 .75rem; text-transform: uppercase; letter-spacing: .18em;
|
|
113
|
+
font-size: .78rem; font-weight: 700; color: rgba(255,255,255,.75);
|
|
114
|
+
}
|
|
115
|
+
[data-theme="default"] .hero__title{
|
|
116
|
+
margin: 0 0 1rem; font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1.12; letter-spacing: -.03em; font-weight: 800;
|
|
59
117
|
}
|
|
118
|
+
[data-theme="default"] .hero__description{
|
|
119
|
+
margin: 0 auto 1.75rem; max-width: 42rem; font-size: 1.1rem; color: rgba(255,255,255,.85);
|
|
120
|
+
}
|
|
121
|
+
[data-theme="default"] .hero__actions{ display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }
|
|
122
|
+
[data-theme="default"] .hero--compact{ padding: 3.25rem 1.5rem 4rem; }
|
|
123
|
+
|
|
124
|
+
/* ---------- Buttons ---------- */
|
|
125
|
+
[data-theme="default"] .btn{
|
|
126
|
+
display: inline-flex; align-items: center; gap: .5rem;
|
|
127
|
+
padding: .7rem 1.4rem; border-radius: 999px; font-weight: 600; font-size: .98rem;
|
|
128
|
+
border: 1px solid transparent; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
|
|
129
|
+
}
|
|
130
|
+
[data-theme="default"] .btn:hover{ transform: translateY(-1px); }
|
|
131
|
+
[data-theme="default"] .btn--primary{ background: #fff; color: var(--brand-strong); box-shadow: var(--shadow-md); }
|
|
132
|
+
[data-theme="default"] .btn--primary:hover{ background: var(--brand-soft); color: var(--brand-strong); }
|
|
133
|
+
[data-theme="default"] .btn--ghost{ background: rgba(255,255,255,.12); color: #fff; border-color: rgba(255,255,255,.45); }
|
|
134
|
+
[data-theme="default"] .btn--ghost:hover{ background: rgba(255,255,255,.22); color: #fff; }
|
|
135
|
+
[data-theme="default"] .btn--outline{ background: transparent; color: var(--brand); border-color: var(--border-strong); }
|
|
136
|
+
[data-theme="default"] .btn--outline:hover{ background: var(--brand-soft); border-color: var(--brand); }
|
|
60
137
|
|
|
61
|
-
|
|
62
|
-
[data-theme="default"] .
|
|
138
|
+
/* ---------- Sections ---------- */
|
|
139
|
+
[data-theme="default"] .site-main{ min-height: 60vh; }
|
|
140
|
+
[data-theme="default"] .section{ max-width: 72rem; margin: 0 auto; padding: 3.5rem 1.25rem; }
|
|
141
|
+
[data-theme="default"] .section__kicker{
|
|
142
|
+
margin: 0 0 .5rem; text-transform: uppercase; letter-spacing: .16em;
|
|
143
|
+
font-size: .74rem; font-weight: 700; color: var(--brand);
|
|
144
|
+
}
|
|
145
|
+
[data-theme="default"] .section__title{
|
|
146
|
+
margin: 0 0 .75rem; font-size: clamp(1.5rem, 3vw, 2rem); letter-spacing: -.02em; font-weight: 800;
|
|
147
|
+
}
|
|
148
|
+
[data-theme="default"] .section__lead{ margin: 0 0 1rem; color: var(--muted); font-size: 1.05rem; max-width: 46rem; }
|
|
149
|
+
[data-theme="default"] .section__more{ font-weight: 600; }
|
|
150
|
+
[data-theme="default"] .section--tight{ padding: 2.25rem 1.25rem; }
|
|
151
|
+
[data-theme="default"] .section__head{
|
|
152
|
+
display: flex; align-items: baseline; justify-content: space-between;
|
|
153
|
+
gap: 1rem; flex-wrap: wrap; margin-bottom: 1.75rem;
|
|
154
|
+
}
|
|
63
155
|
|
|
156
|
+
/* ---------- Cards / listings ---------- */
|
|
157
|
+
[data-theme="default"] .cards{
|
|
158
|
+
display: grid; gap: 1.25rem;
|
|
159
|
+
grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
|
|
160
|
+
}
|
|
161
|
+
[data-theme="default"] .card{
|
|
162
|
+
display: flex; flex-direction: column; gap: .5rem;
|
|
163
|
+
background: var(--surface); border: 1px solid var(--border);
|
|
164
|
+
border-radius: var(--radius); padding: 1.4rem 1.4rem 1.2rem; box-shadow: var(--shadow-sm);
|
|
165
|
+
transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
|
|
166
|
+
}
|
|
167
|
+
[data-theme="default"] .card:hover{ transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }
|
|
168
|
+
[data-theme="default"] .card__date{ font-size: .8rem; color: var(--muted); }
|
|
169
|
+
[data-theme="default"] .card__title{ margin: 0; font-size: 1.12rem; line-height: 1.35; }
|
|
170
|
+
[data-theme="default"] .card__title a{ color: var(--text); }
|
|
171
|
+
[data-theme="default"] .card__title a:hover{ color: var(--brand); }
|
|
172
|
+
[data-theme="default"] .card__excerpt{ margin: 0; color: var(--muted); font-size: .95rem; }
|
|
173
|
+
[data-theme="default"] .card__more{
|
|
174
|
+
margin-top: auto; padding-top: .4rem; font-weight: 600; font-size: .92rem; color: var(--brand);
|
|
175
|
+
}
|
|
64
176
|
[data-theme="default"] .listing{ display: grid; gap: 1rem; }
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
[data-theme="default"] .
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
[data-theme="default"] .
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
177
|
+
|
|
178
|
+
/* ---------- Entries (single / page) ---------- */
|
|
179
|
+
[data-theme="default"] .entry{
|
|
180
|
+
max-width: 46rem; margin: 0 auto; padding: 3rem 1.25rem 4rem;
|
|
181
|
+
}
|
|
182
|
+
[data-theme="default"] .entry__header{ margin-bottom: 1.75rem; }
|
|
183
|
+
[data-theme="default"] .entry__kicker{
|
|
184
|
+
margin: 0 0 .5rem; text-transform: uppercase; letter-spacing: .16em;
|
|
185
|
+
font-size: .74rem; font-weight: 700; color: var(--brand);
|
|
186
|
+
}
|
|
187
|
+
[data-theme="default"] .entry__title{
|
|
188
|
+
margin: 0 0 .5rem; font-size: clamp(1.75rem, 4vw, 2.5rem); letter-spacing: -.025em; line-height: 1.15; font-weight: 800;
|
|
189
|
+
}
|
|
190
|
+
[data-theme="default"] .entry__meta{ display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; color: var(--muted); font-size: .9rem; }
|
|
191
|
+
[data-theme="default"] .entry__cover{ width: 100%; border-radius: var(--radius); margin: 1rem 0; box-shadow: var(--shadow-sm); }
|
|
192
|
+
[data-theme="default"] .entry__body{ font-size: 1.06rem; }
|
|
193
|
+
[data-theme="default"] .entry__body h2{ font-size: 1.5rem; letter-spacing: -.01em; margin: 2rem 0 .75rem; }
|
|
194
|
+
[data-theme="default"] .entry__body h3{ font-size: 1.2rem; margin: 1.5rem 0 .5rem; }
|
|
195
|
+
[data-theme="default"] .entry__body p{ margin: 0 0 1rem; color: #374151; }
|
|
196
|
+
[data-theme="default"] .entry__body a{ text-decoration: underline; text-underline-offset: 3px; }
|
|
197
|
+
[data-theme="default"] .entry__body blockquote{
|
|
198
|
+
margin: 1.5rem 0; padding: .75rem 1.25rem; border-left: 3px solid var(--brand);
|
|
199
|
+
background: var(--brand-soft); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; color: #374151;
|
|
200
|
+
}
|
|
201
|
+
[data-theme="default"] .entry__body pre{
|
|
202
|
+
background: #0f172a; color: #e2e8f0; padding: 1rem 1.25rem; border-radius: var(--radius-sm);
|
|
203
|
+
overflow: auto; font-size: .9rem;
|
|
204
|
+
}
|
|
205
|
+
[data-theme="default"] .entry__body code{ background: var(--brand-soft); border-radius: 4px; padding: .1rem .35rem; }
|
|
206
|
+
[data-theme="default"] .entry__body pre code{ background: transparent; padding: 0; }
|
|
207
|
+
[data-theme="default"] .entry__terms{ display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }
|
|
208
|
+
[data-theme="default"] .badge{
|
|
209
|
+
display: inline-block; padding: .25rem .7rem; border-radius: 999px;
|
|
210
|
+
background: var(--brand-soft); color: var(--brand-strong); font-size: .8rem; font-weight: 600;
|
|
211
|
+
}
|
|
212
|
+
[data-theme="default"] .entry__footer{
|
|
213
|
+
margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--border);
|
|
214
|
+
display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap;
|
|
215
|
+
color: var(--muted); font-size: .92rem;
|
|
216
|
+
}
|
|
217
|
+
[data-theme="default"] .entry__back{ font-weight: 600; }
|
|
218
|
+
|
|
219
|
+
/* ---------- Home body sections (seeded content) ---------- */
|
|
220
|
+
[data-theme="default"] .about-preview{
|
|
221
|
+
display: grid; gap: 1.5rem; grid-template-columns: 1.2fr .8fr; align-items: start;
|
|
222
|
+
}
|
|
223
|
+
[data-theme="default"] .about-preview .section__more{ display: inline-block; }
|
|
224
|
+
[data-theme="default"] .contact{
|
|
225
|
+
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
|
|
226
|
+
box-shadow: var(--shadow-sm);
|
|
227
|
+
}
|
|
228
|
+
[data-theme="default"] .contact .section__lead a{ font-weight: 600; }
|
|
229
|
+
|
|
230
|
+
/* ---------- Archive ---------- */
|
|
231
|
+
[data-theme="default"] .archive-header{
|
|
232
|
+
background: linear-gradient(135deg, #4f46e5 0%, #6d28d9 60%, #7c3aed 100%);
|
|
233
|
+
color: #fff; text-align: center; padding: 3.25rem 1.5rem 4rem;
|
|
234
|
+
}
|
|
235
|
+
[data-theme="default"] .archive-header__title{ margin: 0 0 .4rem; font-size: clamp(1.7rem, 4vw, 2.4rem); letter-spacing: -.02em; font-weight: 800; }
|
|
236
|
+
[data-theme="default"] .archive-header__description{ margin: 0; color: rgba(255,255,255,.85); }
|
|
237
|
+
[data-theme="default"] .archive-header + .section{ margin-top: -1.5rem; }
|
|
238
|
+
[data-theme="default"] .archive-header + .section .card{ background: var(--surface); }
|
|
239
|
+
|
|
240
|
+
/* ---------- Empty state ---------- */
|
|
241
|
+
[data-theme="default"] .empty{
|
|
242
|
+
text-align: center; color: var(--muted); padding: 2.5rem 1rem;
|
|
243
|
+
border: 1px dashed var(--border-strong); border-radius: var(--radius); background: var(--surface);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* ---------- 404 ---------- */
|
|
247
|
+
[data-theme="default"] .not-found{ text-align: center; padding: 5rem 1.5rem; }
|
|
248
|
+
[data-theme="default"] .not-found__code{
|
|
249
|
+
margin: 0 0 .5rem; font-size: 5rem; font-weight: 800; letter-spacing: -.04em;
|
|
250
|
+
background: linear-gradient(135deg, var(--brand), #8b5cf6);
|
|
251
|
+
-webkit-background-clip: text; background-clip: text; color: transparent;
|
|
252
|
+
}
|
|
253
|
+
[data-theme="default"] .not-found__message{ margin: 0 0 1.5rem; color: var(--muted); font-size: 1.1rem; }
|
|
254
|
+
|
|
255
|
+
/* ---------- Footer ---------- */
|
|
256
|
+
[data-theme="default"] .site-footer{
|
|
257
|
+
background: #111827; color: #d1d5db; margin-top: 4rem;
|
|
258
|
+
}
|
|
259
|
+
[data-theme="default"] .site-footer__inner{
|
|
260
|
+
display: flex; justify-content: space-between; gap: 2rem; flex-wrap: wrap;
|
|
261
|
+
padding-top: 2.75rem; padding-bottom: 1.5rem;
|
|
262
|
+
}
|
|
263
|
+
[data-theme="default"] .site-footer__title{ margin: 0 0 .35rem; color: #fff; font-weight: 700; font-size: 1.05rem; }
|
|
264
|
+
[data-theme="default"] .site-footer__description{ margin: 0; max-width: 24rem; color: #9ca3af; font-size: .93rem; }
|
|
265
|
+
[data-theme="default"] .site-footer__nav{ display: flex; flex-direction: column; gap: .45rem; }
|
|
266
|
+
[data-theme="default"] .site-footer__link{ color: #d1d5db; font-size: .95rem; }
|
|
267
|
+
[data-theme="default"] .site-footer__link:hover{ color: #fff; }
|
|
268
|
+
[data-theme="default"] .site-footer__bottom{ border-top: 1px solid rgba(255,255,255,.1); }
|
|
269
|
+
[data-theme="default"] .site-footer__copyright{
|
|
270
|
+
margin: 0; padding: 1.1rem 0; text-align: center; color: #9ca3af; font-size: .85rem;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* ---------- Responsive ---------- */
|
|
274
|
+
@media (max-width: 860px){
|
|
275
|
+
[data-theme="default"] .about-preview{ grid-template-columns: 1fr; }
|
|
276
|
+
[data-theme="default"] .hero{ padding: 4rem 1.25rem 4.5rem; }
|
|
277
|
+
}
|
|
278
|
+
@media (max-width: 560px){
|
|
279
|
+
[data-theme="default"] .site-header__inner{ justify-content: center; }
|
|
280
|
+
[data-theme="default"] .site-nav{ justify-content: center; }
|
|
281
|
+
[data-theme="default"] .hero{ padding: 3.25rem 1rem 3.75rem; }
|
|
282
|
+
[data-theme="default"] .section{ padding: 2.5rem 1rem; }
|
|
283
|
+
[data-theme="default"] .cards{ grid-template-columns: 1fr; }
|
|
284
|
+
}
|
|
78
285
|
`;
|
|
79
286
|
/**
|
|
80
|
-
* Templates
|
|
81
|
-
*
|
|
287
|
+
* Templates of the hierarchy (runtime format: `*.astro` at the theme root,
|
|
288
|
+
* syntax `{{var}}` / `{{{raw}}}` / `{{#each}}` / `{{#if}}`).
|
|
289
|
+
*
|
|
290
|
+
* Shared shell: every template renders the same header (brand + `menus.header`)
|
|
291
|
+
* and footer (`menus.footer`) around its own content, all scoped by the
|
|
292
|
+
* `[data-theme]` wrapper the stylesheet targets.
|
|
82
293
|
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
{{#if
|
|
88
|
-
<
|
|
294
|
+
/** Header shell (brand + main menu). */
|
|
295
|
+
const HEADER = `<header class="site-header">
|
|
296
|
+
<div class="container site-header__inner">
|
|
297
|
+
<a class="site-brand" href="/">{{site.title}}</a>
|
|
298
|
+
{{#if menus.header}}
|
|
299
|
+
<nav class="site-nav" aria-label="Main navigation">
|
|
300
|
+
{{#each menus.header.items}}<a class="site-nav__link" href="{{url}}">{{label}}</a>{{/each}}
|
|
301
|
+
</nav>
|
|
89
302
|
{{/if}}
|
|
90
|
-
</
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
303
|
+
</div>
|
|
304
|
+
</header>
|
|
305
|
+
`;
|
|
306
|
+
/** Footer shell (brand + description + footer menu + copyright). */
|
|
307
|
+
const FOOTER = `<footer class="site-footer">
|
|
308
|
+
<div class="container site-footer__inner">
|
|
309
|
+
<div class="site-footer__info">
|
|
310
|
+
<p class="site-footer__title">{{site.title}}</p>
|
|
311
|
+
{{#if site.description}}<p class="site-footer__description">{{site.description}}</p>{{/if}}
|
|
312
|
+
</div>
|
|
313
|
+
{{#if menus.footer}}
|
|
314
|
+
<nav class="site-footer__nav" aria-label="Footer navigation">
|
|
315
|
+
{{#each menus.footer.items}}<a class="site-footer__link" href="{{url}}">{{label}}</a>{{/each}}
|
|
316
|
+
</nav>
|
|
317
|
+
{{/if}}
|
|
318
|
+
</div>
|
|
319
|
+
<div class="container site-footer__bottom">
|
|
320
|
+
<p class="site-footer__copyright">© {{site.title}} · Powered by OkCMS</p>
|
|
321
|
+
</div>
|
|
322
|
+
</footer>
|
|
323
|
+
`;
|
|
324
|
+
/** Latest posts grid — fed by `items` (fetched for home/front-page/archive). */
|
|
325
|
+
const POSTS_SECTION = `{{#if items}}
|
|
326
|
+
<section class="section" id="posts">
|
|
327
|
+
<div class="section__head">
|
|
328
|
+
<div>
|
|
329
|
+
<p class="section__kicker">Blog</p>
|
|
330
|
+
<h2 class="section__title">Latest posts</h2>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
<div class="cards">
|
|
94
334
|
{{#each items}}
|
|
95
|
-
<article class="card
|
|
96
|
-
<
|
|
97
|
-
|
|
335
|
+
<article class="card">
|
|
336
|
+
{{#if published_at}}<time class="card__date" datetime="{{published_at}}">{{published_at}}</time>{{/if}}
|
|
337
|
+
<h3 class="card__title"><a href="/{{slug}}">{{title}}</a></h3>
|
|
338
|
+
{{#if excerpt}}<p class="card__excerpt">{{excerpt}}</p>{{/if}}
|
|
339
|
+
<a class="card__more" href="/{{slug}}">Read more →</a>
|
|
98
340
|
</article>
|
|
99
341
|
{{/each}}
|
|
100
|
-
</
|
|
101
|
-
|
|
102
|
-
|
|
342
|
+
</div>
|
|
343
|
+
</section>
|
|
344
|
+
{{/if}}
|
|
345
|
+
`;
|
|
346
|
+
export const THEME_TEMPLATE_FILES = {
|
|
347
|
+
// Static front page (Reading Settings → homepage): renders the page body
|
|
348
|
+
// (seeded hero/about/contact sections) plus the latest posts grid.
|
|
349
|
+
'front-page.astro': `<div class="site" data-theme="{{site.theme}}" data-template="front-page">
|
|
350
|
+
${HEADER}
|
|
351
|
+
<main class="site-main">
|
|
352
|
+
{{#if content.html}}
|
|
353
|
+
{{{content.html}}}
|
|
354
|
+
{{/if}}
|
|
355
|
+
${POSTS_SECTION} </main>
|
|
356
|
+
${FOOTER}</div>
|
|
103
357
|
`,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
358
|
+
// Non-static home (no front page configured): hero + latest posts.
|
|
359
|
+
'home.astro': `<div class="site" data-theme="{{site.theme}}" data-template="home">
|
|
360
|
+
${HEADER}
|
|
361
|
+
<main class="site-main">
|
|
362
|
+
<section class="hero">
|
|
363
|
+
<p class="hero__kicker">Welcome</p>
|
|
364
|
+
<h1 class="hero__title">{{site.title}}</h1>
|
|
108
365
|
{{#if site.description}}
|
|
109
|
-
<p class="
|
|
366
|
+
<p class="hero__description">{{site.description}}</p>
|
|
110
367
|
{{/if}}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{{#if content.html}}{{{content.html}}}{{/if}}
|
|
115
|
-
{{#if content.content}}{{{content.content}}}{{/if}}
|
|
116
|
-
{{#if content.text}}<p>{{content.text}}</p>{{/if}}
|
|
117
|
-
</div>
|
|
118
|
-
|
|
119
|
-
{{#if items}}
|
|
120
|
-
<section class="listing">
|
|
121
|
-
{{#each items}}
|
|
122
|
-
<article class="card entry entry--item">
|
|
123
|
-
<h2 class="entry__title"><a href="/{{slug}}">{{title}}</a></h2>
|
|
124
|
-
{{#if excerpt}}<p class="entry__excerpt">{{excerpt}}</p>{{/if}}
|
|
125
|
-
</article>
|
|
126
|
-
{{/each}}
|
|
368
|
+
<div class="hero__actions">
|
|
369
|
+
<a class="btn btn--primary" href="#posts">Browse posts</a>
|
|
370
|
+
</div>
|
|
127
371
|
</section>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
</main>
|
|
372
|
+
${POSTS_SECTION} </main>
|
|
373
|
+
${FOOTER}</div>
|
|
131
374
|
`,
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
<
|
|
375
|
+
// Generic fallback: page-ish content + items listing.
|
|
376
|
+
'index.astro': `<div class="site" data-theme="{{site.theme}}" data-template="index" data-type="{{page.type}}">
|
|
377
|
+
${HEADER}
|
|
378
|
+
<main class="site-main">
|
|
379
|
+
<article class="entry">
|
|
380
|
+
<header class="entry__header">
|
|
381
|
+
<p class="entry__kicker">{{page.type}}</p>
|
|
382
|
+
<h1 class="entry__title">{{page.title}}</h1>
|
|
383
|
+
{{#if site.description}}
|
|
384
|
+
<p class="entry__meta">{{site.description}}</p>
|
|
385
|
+
{{/if}}
|
|
386
|
+
</header>
|
|
387
|
+
<div class="entry__body">
|
|
388
|
+
{{#if content.html}}{{{content.html}}}{{/if}}
|
|
389
|
+
{{#if content.content}}{{{content.content}}}{{/if}}
|
|
390
|
+
{{#if content.text}}<p>{{content.text}}</p>{{/if}}
|
|
391
|
+
</div>
|
|
392
|
+
</article>
|
|
393
|
+
${POSTS_SECTION} </main>
|
|
394
|
+
${FOOTER}</div>
|
|
395
|
+
`,
|
|
396
|
+
// Single post: title, date, categories, cover, body, back link.
|
|
397
|
+
'single.astro': `<div class="site" data-theme="{{site.theme}}" data-template="single" data-type="{{page.type}}">
|
|
398
|
+
${HEADER}
|
|
399
|
+
<main class="site-main">
|
|
400
|
+
<article class="entry">
|
|
401
|
+
<header class="entry__header">
|
|
402
|
+
<p class="entry__kicker">Post</p>
|
|
403
|
+
<h1 class="entry__title">{{content.title}}</h1>
|
|
404
|
+
<div class="entry__meta">
|
|
405
|
+
{{#if content.published_at}}<time datetime="{{content.published_at}}">{{content.published_at}}</time>{{/if}}
|
|
406
|
+
{{#if _terms.category}}
|
|
407
|
+
<span class="entry__terms">
|
|
408
|
+
{{#each _terms.category}}<span class="badge">{{name}}</span>{{/each}}
|
|
409
|
+
</span>
|
|
410
|
+
{{/if}}
|
|
411
|
+
</div>
|
|
412
|
+
</header>
|
|
413
|
+
{{#if content.cover.url}}
|
|
414
|
+
<img class="entry__cover" src="{{content.cover.url}}" alt="{{content.cover.alt}}" loading="lazy" />
|
|
138
415
|
{{/if}}
|
|
139
416
|
{{#if content.thumbnail.url}}
|
|
140
417
|
<img class="entry__cover" src="{{content.thumbnail.url}}" alt="{{content.thumbnail.alt}}" loading="lazy" />
|
|
141
418
|
{{/if}}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
</
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
<time class="entry__date" datetime="{{content.published_at}}">{{content.published_at}}</time>
|
|
155
|
-
</footer>
|
|
156
|
-
</article>
|
|
157
|
-
</main>
|
|
419
|
+
<div class="entry__body">
|
|
420
|
+
{{#if content.html}}{{{content.html}}}{{/if}}
|
|
421
|
+
{{#if content.content}}{{{content.content}}}{{/if}}
|
|
422
|
+
{{#if content.text}}<p>{{content.text}}</p>{{/if}}
|
|
423
|
+
</div>
|
|
424
|
+
<footer class="entry__footer">
|
|
425
|
+
<a class="entry__back" href="/blog">← Back to the blog</a>
|
|
426
|
+
{{#if content.updated_at}}<span>Updated {{content.updated_at}}</span>{{/if}}
|
|
427
|
+
</footer>
|
|
428
|
+
</article>
|
|
429
|
+
</main>
|
|
430
|
+
${FOOTER}</div>
|
|
158
431
|
`,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
</
|
|
432
|
+
// Static page (also the front-page fallback when front-page.astro is absent).
|
|
433
|
+
'page.astro': `<div class="site" data-theme="{{site.theme}}" data-template="page" data-type="{{page.type}}">
|
|
434
|
+
${HEADER}
|
|
435
|
+
<main class="site-main">
|
|
436
|
+
<article class="entry">
|
|
437
|
+
<header class="entry__header">
|
|
438
|
+
<p class="entry__kicker">Page</p>
|
|
439
|
+
<h1 class="entry__title">{{content.title}}</h1>
|
|
440
|
+
</header>
|
|
441
|
+
<div class="entry__body">
|
|
442
|
+
{{#if content.html}}{{{content.html}}}{{/if}}
|
|
443
|
+
{{#if content.content}}{{{content.content}}}{{/if}}
|
|
444
|
+
{{#if content.text}}<p>{{content.text}}</p>{{/if}}
|
|
445
|
+
</div>
|
|
446
|
+
</article>
|
|
447
|
+
</main>
|
|
448
|
+
${FOOTER}</div>
|
|
172
449
|
`,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
<
|
|
178
|
-
|
|
179
|
-
|
|
450
|
+
// Archive (post type listing — e.g. the blog page configured as page_for_posts).
|
|
451
|
+
'archive.astro': `<div class="site" data-theme="{{site.theme}}" data-template="archive" data-type="{{page.type}}">
|
|
452
|
+
${HEADER}
|
|
453
|
+
<main class="site-main">
|
|
454
|
+
<header class="archive-header">
|
|
455
|
+
<h1 class="archive-header__title">{{page.title}}</h1>
|
|
456
|
+
{{#if site.description}}
|
|
457
|
+
<p class="archive-header__description">{{site.description}}</p>
|
|
458
|
+
{{/if}}
|
|
459
|
+
</header>
|
|
180
460
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
</
|
|
461
|
+
<section class="section section--tight">
|
|
462
|
+
{{#if items}}
|
|
463
|
+
<div class="cards">
|
|
464
|
+
{{#each items}}
|
|
465
|
+
<article class="card">
|
|
466
|
+
{{#if published_at}}<time class="card__date" datetime="{{published_at}}">{{published_at}}</time>{{/if}}
|
|
467
|
+
<h2 class="card__title"><a href="/{{slug}}">{{title}}</a></h2>
|
|
468
|
+
{{#if excerpt}}<p class="card__excerpt">{{excerpt}}</p>{{/if}}
|
|
469
|
+
<a class="card__more" href="/{{slug}}">Read more →</a>
|
|
470
|
+
</article>
|
|
471
|
+
{{/each}}
|
|
472
|
+
</div>
|
|
473
|
+
{{/if}}
|
|
474
|
+
</section>
|
|
475
|
+
</main>
|
|
476
|
+
${FOOTER}</div>
|
|
191
477
|
`,
|
|
192
|
-
'404.astro': `<
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
</
|
|
478
|
+
'404.astro': `<div class="site" data-theme="{{site.theme}}" data-template="404">
|
|
479
|
+
${HEADER}
|
|
480
|
+
<main class="site-main">
|
|
481
|
+
<section class="not-found">
|
|
482
|
+
<h1 class="not-found__code">404</h1>
|
|
483
|
+
<p class="not-found__message">Page not found. It may have been moved or deleted.</p>
|
|
484
|
+
<a class="btn btn--outline" href="/">{{site.title}}</a>
|
|
485
|
+
</section>
|
|
486
|
+
</main>
|
|
487
|
+
${FOOTER}</div>
|
|
199
488
|
`,
|
|
200
489
|
};
|
|
201
|
-
/**
|
|
490
|
+
/** Real default theme screenshot (PNG 600×400 — preview card in the admin). */
|
|
202
491
|
const DEFAULT_THEME_SCREENSHOT_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAYAAAByNR6YAAAIT0lEQVR4nO3WsU0EQQAEwYsOl9gxsLBfGARxJNHPa9gqqf0x57oBAEhdrx4AAPDfOFgAADEH' +
|
|
203
492
|
'CwAg5mABAMQcLACAmIMFABBzsAAAYg4WAEDMwQIAiDlYAAAxBwsAIOZgAQDEHCwAgJiDBQAQc7AAAGIOFgBAzMECAIg5WAAAMQcLACDmYAEAxBwsAICYgwUA' +
|
|
204
493
|
'EHOwAABiDhYAQMzBAgCIOVgAADEHCwAg5mABAMQcLACAmIMFABBzsAAAYg4WAEDMwQIAiDlYAAAxBwsAIOZgAQDEHCwAgJiDBQAQc7AAAGIOFgBAzMECAIg5' +
|
|
@@ -224,16 +513,16 @@ const DEFAULT_THEME_SCREENSHOT_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAYAAAB
|
|
|
224
513
|
'ACDmYAEAxBwsAICYgwUAEHOwAABiDhYAQMzBAgCIOVgAADEHCwAg5mABAMQcLACAmIMFABBzsAAAYg4WAEDMwQIAiDlYAAAxBwsAIOZgAQDEHCwAgJiDBQAQ' +
|
|
225
514
|
'c7AAAGIOFgBAzMECAIg5WAAAMQcLACDmYAEAxBwsAICYgwUAEHOwAABiDhYAQMzBAgCIOVgAADEHCwAg5mABAMQcLACAmIMFABBzsAAAYg4WAEDMwQIAiDlY' +
|
|
226
515
|
'AACxXxc1EEhePb4DAAAAAElFTkSuQmCC';
|
|
227
|
-
/**
|
|
516
|
+
/** Complete default theme written by `okcms init` (paths relative to themes/default/). */
|
|
228
517
|
export const DEFAULT_THEME_FILES = {
|
|
229
518
|
'theme.json': DEFAULT_THEME_MANIFEST,
|
|
230
519
|
...THEME_TEMPLATE_FILES,
|
|
231
520
|
'dist/theme.css': DEFAULT_THEME_CSS,
|
|
232
521
|
};
|
|
233
522
|
/**
|
|
234
|
-
*
|
|
235
|
-
* base64 (
|
|
236
|
-
*
|
|
523
|
+
* BINARY files of the default theme: written with a Buffer decoded from
|
|
524
|
+
* base64 (writing a string would corrupt the PNG). Same re-init rule —
|
|
525
|
+
* never overwrites a file that is already present.
|
|
237
526
|
*/
|
|
238
527
|
export const DEFAULT_THEME_BINARY_FILES = {
|
|
239
528
|
'screenshot.png': DEFAULT_THEME_SCREENSHOT_BASE64,
|
package/dist/theme-assets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-assets.js","sourceRoot":"","sources":["../src/theme-assets.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"theme-assets.js","sourceRoot":"","sources":["../src/theme-assets.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oktis-works/cms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"clean": "rm -rf dist migrations tsconfig.tsbuildinfo"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@oktis-works/auth": "^0.7.
|
|
23
|
+
"@oktis-works/auth": "^0.7.8",
|
|
24
24
|
"@oktis-works/config": "^0.6.4",
|
|
25
|
-
"@oktis-works/core": "^0.11.
|
|
26
|
-
"@oktis-works/database": "^0.
|
|
25
|
+
"@oktis-works/core": "^0.11.4",
|
|
26
|
+
"@oktis-works/database": "^0.13.1",
|
|
27
27
|
"@oktis-works/validation": "^0.7.0",
|
|
28
|
-
"@oktis-works/theme-runtime": "^0.
|
|
28
|
+
"@oktis-works/theme-runtime": "^0.9.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"typescript": "5.7.3"
|