@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.
@@ -1,18 +1,14 @@
1
- /** Manifesto do tema default (`theme.json` = nome canônico lido por runtime, service e CLI). */
1
+ /** Default theme manifest (`theme.json` = canonical name read by runtime, service and CLI). */
2
2
  export declare const DEFAULT_THEME_MANIFEST: string;
3
- /** Estilos básicos do tema default — servido direto de dist/theme.css (sem build). */
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
- /** Tema default completo gravado pelo `okcms init` (caminhos relativos a themes/default/). */
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
- * Arquivos BINÁRIOS do tema default: gravados com Buffer decodificado do
14
- * base64 (writeFile de string corromperia o PNG). Mesma regra de re-init —
15
- * nunca sobrescreve um arquivo já presente.
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":"AAQA,gGAAgG;AAChG,eAAO,MAAM,sBAAsB,QA8BlC,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,iBAAiB,usDA0C7B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAqHvD,CAAC;AA8BF,8FAA8F;AAC9F,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"}
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"}
@@ -1,204 +1,493 @@
1
- // @oktis-works/cms - Templates do tema default embutidos no CLI
1
+ // @oktis-works/cms - Default theme templates embedded in the CLI
2
2
  //
3
- // O `okcms init` copia estes arquivos para `themes/default/` do projeto novo:
4
- // o site já renderiza de cara (templates .astro na raiz + dist/theme.css
5
- // servido direto). Mantidos em string porque o package publica só `dist/`.
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
- /** Manifesto do tema default (`theme.json` = nome canônico lido por runtime, service e CLI). */
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.1.0',
11
- description: 'Tema padrão do OkCMS — templates hierárquicos com interpolação real de conteúdo',
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
- // Contrato BUSI-022: exigido pelo theme:install via API. Sem o range,
15
- // o tema default seria rejeitado na instalação explícita. Derivado do
16
- // CMS_VERSION (fonte única) — nunca literal, senão dessincroniza.
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 do card na tela Temas do admin (servido por /themes/default/).
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 commitado já escopado — o tema assume o isolamento (BUSI-040)
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: 'Título do site', default: 'OkCMS' },
31
- { name: 'siteDescription', type: 'text', label: 'Descrição do site', default: '' },
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
- /** Estilos básicos do tema default — servido direto de dist/theme.css (sem build). */
36
- export const DEFAULT_THEME_CSS = `/* Tema default do OkCMS — estilos básicos (servido direto de dist/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
- --text: #1f2937;
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"] *{ box-sizing: border-box; }
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(--surface);
52
- line-height: 1.6;
62
+ background: var(--bg);
63
+ line-height: 1.65;
64
+ -webkit-font-smoothing: antialiased;
53
65
  }
54
66
 
55
- [data-theme="default"] main{
56
- max-width: 46rem;
57
- margin: 0 auto;
58
- padding: 2.5rem 1.5rem;
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
- [data-theme="default"] .hero__title{ margin: 0 0 0.5rem; font-size: 2rem; }
62
- [data-theme="default"] .hero__description{ margin: 0 0 2rem; color: var(--muted); }
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
- [data-theme="default"] .card{ border: 1px solid var(--border); border-radius: 8px; padding: 1rem 1.25rem; }
66
- [data-theme="default"] .entry__title{ margin: 0 0 0.25rem; font-size: 1.15rem; }
67
- [data-theme="default"] .entry__title a{ color: var(--brand); text-decoration: none; }
68
- [data-theme="default"] .entry__title a:hover{ text-decoration: underline; }
69
- [data-theme="default"] .entry__excerpt{ margin: 0; color: var(--muted); }
70
-
71
- [data-theme="default"] .entry__header{ margin-bottom: 1.5rem; }
72
- [data-theme="default"] .entry__cover{ max-width: 100%; border-radius: 8px; margin: 1rem 0; }
73
- [data-theme="default"] .entry__body{ font-size: 1.05rem; }
74
- [data-theme="default"] .entry__date{ color: var(--muted); font-size: 0.85rem; }
75
-
76
- [data-theme="default"] .not-found__code{ margin: 0; font-size: 4rem; color: var(--brand); }
77
- [data-theme="default"] .not-found__message{ color: var(--muted); }
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 da hierarquia (formato do runtime: `*.astro` NA RAIZ do tema,
81
- * sintaxe `{{var}}` / `{{{raw}}}` / `{{#each}}` / `{{#if}}`).
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
- export const THEME_TEMPLATE_FILES = {
84
- 'home.astro': `<main data-theme="{{site.theme}}" data-template="home">
85
- <section class="hero">
86
- <h1 class="hero__title">{{site.title}}</h1>
87
- {{#if site.description}}
88
- <p class="hero__description">{{site.description}}</p>
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
- </section>
91
-
92
- {{#if items}}
93
- <section class="listing">
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 entry entry--item">
96
- <h2 class="entry__title"><a href="/{{slug}}">{{title}}</a></h2>
97
- {{#if excerpt}}<p class="entry__excerpt">{{excerpt}}</p>{{/if}}
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
- </section>
101
- {{/if}}
102
- </main>
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
- 'index.astro': `<main data-theme="{{site.theme}}" data-template="index" data-type="{{page.type}}">
105
- <article class="entry">
106
- <header class="entry__header">
107
- <h1 class="entry__title">{{page.title}}</h1>
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="entry__excerpt">{{site.description}}</p>
366
+ <p class="hero__description">{{site.description}}</p>
110
367
  {{/if}}
111
- </header>
112
-
113
- <div class="entry__body">
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
- {{/if}}
129
- </article>
130
- </main>
372
+ ${POSTS_SECTION} </main>
373
+ ${FOOTER}</div>
131
374
  `,
132
- 'single.astro': `<main data-theme="{{site.theme}}" data-template="single" data-type="{{page.type}}">
133
- <article class="entry">
134
- <header class="entry__header">
135
- <h1 class="entry__title">{{content.title}}</h1>
136
- {{#if content.excerpt}}
137
- <p class="entry__excerpt">{{content.excerpt}}</p>
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
- {{#if content.cover.url}}
143
- <img class="entry__cover" src="{{content.cover.url}}" alt="{{content.cover.alt}}" loading="lazy" />
144
- {{/if}}
145
- </header>
146
-
147
- <div class="entry__body">
148
- {{#if content.html}}{{{content.html}}}{{/if}}
149
- {{#if content.content}}{{{content.content}}}{{/if}}
150
- {{#if content.text}}<p>{{content.text}}</p>{{/if}}
151
- </div>
152
-
153
- <footer class="entry__footer">
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
- 'page.astro': `<main data-theme="{{site.theme}}" data-template="page" data-type="{{page.type}}">
160
- <article class="entry entry--page">
161
- <header class="entry__header">
162
- <h1 class="entry__title">{{content.title}}</h1>
163
- </header>
164
-
165
- <div class="entry__body">
166
- {{#if content.html}}{{{content.html}}}{{/if}}
167
- {{#if content.content}}{{{content.content}}}{{/if}}
168
- {{#if content.text}}<p>{{content.text}}</p>{{/if}}
169
- </div>
170
- </article>
171
- </main>
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
- 'archive.astro': `<main data-theme="{{site.theme}}" data-template="archive" data-type="{{page.type}}">
174
- <header class="archive-header">
175
- <h1 class="archive-header__title">{{page.title}}</h1>
176
- {{#if site.description}}
177
- <p class="archive-header__description">{{site.description}}</p>
178
- {{/if}}
179
- </header>
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
- <section class="listing">
182
- {{#each items}}
183
- <article class="card entry entry--item">
184
- <h2 class="entry__title"><a href="/{{slug}}">{{title}}</a></h2>
185
- {{#if excerpt}}<p class="entry__excerpt">{{excerpt}}</p>{{/if}}
186
- {{#if published_at}}<time class="entry__date" datetime="{{published_at}}">{{published_at}}</time>{{/if}}
187
- </article>
188
- {{/each}}
189
- </section>
190
- </main>
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': `<main data-theme="{{site.theme}}" data-template="404">
193
- <section class="not-found">
194
- <h1 class="not-found__code">404</h1>
195
- <p class="not-found__message">Página não encontrada.</p>
196
- <p class="not-found__back"><a href="/">{{site.title}}</a></p>
197
- </section>
198
- </main>
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
- /** Screenshot real do tema default (PNG 600×400 — preview no card do admin). */
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
- /** Tema default completo gravado pelo `okcms init` (caminhos relativos a themes/default/). */
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
- * Arquivos BINÁRIOS do tema default: gravados com Buffer decodificado do
235
- * base64 (writeFile de string corromperia o PNG). Mesma regra de re-init —
236
- * nunca sobrescreve um arquivo já presente.
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,
@@ -1 +1 @@
1
- {"version":3,"file":"theme-assets.js","sourceRoot":"","sources":["../src/theme-assets.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,8EAA8E;AAC9E,yEAAyE;AACzE,2EAA2E;AAE3E,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,gGAAgG;AAChG,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,IAAI,CAAC,SAAS,CACrD;IACE,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,iFAAiF;IAC9F,IAAI,EAAE,OAAO;IACb,MAAM,EAAE,aAAa;IACrB,sEAAsE;IACtE,sEAAsE;IACtE,kEAAkE;IAClE,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,WAAW,EAAE,EAAE;IAC3C,yEAAyE;IACzE,WAAW,EAAE,CAAC,gBAAgB,CAAC;IAC/B,QAAQ,EAAE;QACR,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC;QAC9D,MAAM,EAAE,CAAC,gBAAgB,CAAC;KAC3B;IACD,YAAY,EAAE;QACZ,MAAM,EAAE,KAAK;QACb,oEAAoE;QACpE,SAAS,EAAE,QAAQ;KACpB;IACD,QAAQ,EAAE;QACR,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,EAAE;QAC9E,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE,EAAE;KACnF;CACF,EACD,IAAI,EACJ,CAAC,CACF;CACA,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0ChC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA2B;IAC1D,YAAY,EAAE;;;;;;;;;;;;;;;;;;;CAmBf;IACC,aAAa,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BhB;IACC,cAAc,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BjB;IACC,YAAY,EAAE;;;;;;;;;;;;;CAaf;IACC,eAAe,EAAE;;;;;;;;;;;;;;;;;;CAkBlB;IACC,WAAW,EAAE;;;;;;;CAOd;CACA,CAAC;AAEF,gFAAgF;AAChF,MAAM,+BAA+B,GACnC,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,0HAA0H;IAC1H,kCAAkC,CAAC;AAErC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,mBAAmB,GAA2B;IACzD,YAAY,EAAE,sBAAsB;IACpC,GAAG,oBAAoB;IACvB,gBAAgB,EAAE,iBAAiB;CACpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAA2B;IAChE,gBAAgB,EAAE,+BAA+B;CAClD,CAAC"}
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.10.10",
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.7",
23
+ "@oktis-works/auth": "^0.7.8",
24
24
  "@oktis-works/config": "^0.6.4",
25
- "@oktis-works/core": "^0.11.2",
26
- "@oktis-works/database": "^0.12.1",
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.8.1"
28
+ "@oktis-works/theme-runtime": "^0.9.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "typescript": "5.7.3"