Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/deploy-marketing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
paths:
- 'apps/marketing/**'
- 'scripts/validate-staticwebapp-config.mjs'
- '.npmrc'
- 'pnpm-lock.yaml'
- '.github/workflows/deploy-marketing.yml'
workflow_dispatch:

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/preview-marketing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
paths:
- 'apps/marketing/**'
- 'scripts/validate-staticwebapp-config.mjs'
- '.npmrc'
- 'pnpm-lock.yaml'
- '.github/workflows/preview-marketing.yml'

concurrency:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ coverage/
.idea/
.vscode/
!.vscode/extensions.json
apps/marketing/public/admin/vendor/
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
auto-install-peers=true
strict-peer-dependencies=false
@singleton-sd:registry=https://gitlab.com/api/v4/packages/npm/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Public landing site for **Singleton Software Development** at [singletonsd.com](

## Stack

- Astro SSG + Tailwind + Singleton SD design tokens
- Astro SSG + Tailwind + `@singleton-sd/tokens` (GitLab npm, `--ssd-*`)
- Decap CMS at `/admin` (GitHub backend)
- Azure Static Web Apps Free + Decap OAuth Azure Function
- Shared Key Vault in `rg-ssd-global`
Expand Down
2 changes: 2 additions & 0 deletions SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

## Local

`@singleton-sd/tokens` comes from GitLab’s npm registry (see `.npmrc`).

```powershell
pnpm install
pnpm dev
Expand Down
6 changes: 4 additions & 2 deletions apps/marketing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"private": true,
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "node ../../scripts/validate-staticwebapp-config.mjs public/staticwebapp.config.json && astro build",
"copy-tokens": "node ./scripts/copy-token-css.mjs",
"dev": "node ./scripts/copy-token-css.mjs && astro dev",
"build": "node ../../scripts/validate-staticwebapp-config.mjs public/staticwebapp.config.json && node ./scripts/copy-token-css.mjs && astro build",
"preview": "astro preview",
"lint": "node ../../scripts/validate-staticwebapp-config.mjs public/staticwebapp.config.json && astro check",
"test": "node --test ../../scripts/validate-staticwebapp-config.test.mjs src/lib/site.test.mjs && node ../../scripts/validate-staticwebapp-config.mjs public/staticwebapp.config.json && astro check"
Expand All @@ -14,6 +15,7 @@
"@astrojs/check": "^0.9.4",
"@astrojs/sitemap": "3.6.0",
"@astrojs/tailwind": "^5.1.4",
"@singleton-sd/tokens": "1.3.0",
"astro": "^4.16.18",
"tailwindcss": "^3.4.15",
"typescript": "^5.7.2"
Expand Down
4 changes: 2 additions & 2 deletions apps/marketing/public/admin/admin-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
CMS.registerPreviewStyle('/admin/preview.css');

/**
* Token CSS is gated on [data-theme='dark']. Decap preview iframes omit it,
* so stamp the attribute whenever a preview frame mounts.
* Preview CSS uses root/dark tokens on :root. Stamp data-theme anyway so
* any [data-theme='dark'] sheets in the iframe still apply.
*/
function stampPreviewTheme() {
const frames = document.querySelectorAll('iframe');
Expand Down
30 changes: 15 additions & 15 deletions apps/marketing/public/admin/admin-theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,21 @@
const cs = getComputedStyle(root);
const get = (name, fallback) => cs.getPropertyValue(name).trim() || fallback;
return {
accent: get('--pk-accent', 'var(--colors-yellow-light-400)'),
accentBg: get('--pk-accent-bg', 'var(--colors-yellow-light-900)'),
bg: get('--pk-bg', 'var(--colors-gray-900)'),
surface: get('--pk-surface', 'var(--colors-gray-800)'),
surfaceRaised: get('--pk-surface-raised', 'var(--colors-gray-700)'),
fg: get('--pk-fg', 'var(--colors-gray-100)'),
muted: get('--pk-muted', 'var(--colors-gray-400)'),
border: get('--pk-border', 'var(--colors-gray-700)'),
danger: get('--pk-danger', 'var(--colors-red-400)'),
dangerBg: get('--pk-danger-bg', 'var(--colors-red-900)'),
success: get('--pk-success', 'var(--colors-green-400)'),
successBg: get('--pk-success-bg', 'var(--colors-green-900)'),
warn: get('--pk-warn', 'var(--colors-yellow-light-300)'),
warnBg: get('--pk-warn-bg', 'var(--colors-yellow-light-900)'),
info: get('--pk-info', 'var(--colors-yellow-light-400)'),
accent: get('--pk-accent', 'var(--ssd-color-yellow-light-400)'),
accentBg: get('--pk-accent-bg', 'var(--ssd-color-yellow-light-900)'),
bg: get('--pk-bg', 'var(--ssd-color-gray-900)'),
surface: get('--pk-surface', 'var(--ssd-color-gray-800)'),
surfaceRaised: get('--pk-surface-raised', 'var(--ssd-color-gray-700)'),
fg: get('--pk-fg', 'var(--ssd-color-gray-100)'),
muted: get('--pk-muted', 'var(--ssd-color-gray-400)'),
border: get('--pk-border', 'var(--ssd-color-gray-700)'),
danger: get('--pk-danger', 'var(--ssd-color-red-400)'),
dangerBg: get('--pk-danger-bg', 'var(--ssd-color-red-900)'),
success: get('--pk-success', 'var(--ssd-color-green-400)'),
successBg: get('--pk-success-bg', 'var(--ssd-color-green-900)'),
warn: get('--pk-warn', 'var(--ssd-color-yellow-light-300)'),
warnBg: get('--pk-warn-bg', 'var(--ssd-color-yellow-light-900)'),
info: get('--pk-info', 'var(--ssd-color-yellow-light-400)'),
};
}

Expand Down
57 changes: 24 additions & 33 deletions apps/marketing/public/admin/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,30 @@
*
* Emotion class names include component labels; substring selectors may drift
* across Decap versions — pin the CDN build in index.html.
*
* Token CSS is copied from @singleton-sd/tokens into /admin/vendor at build.
*/
@import url('https://tokens.design.singletonsd.com/css/dark/_variables.css');

html[data-theme='dark'] {
/* Product roles */
--pk-bg: var(--colors-gray-900);
--pk-fg: var(--colors-gray-100);
--pk-muted: var(--colors-gray-400);
--pk-accent: var(--colors-yellow-light-400);
--pk-accent-on: var(--colors-gray-900);
--pk-accent-bg: var(--colors-yellow-light-900);
--pk-surface: var(--colors-gray-800);
--pk-surface-raised: var(--colors-gray-700);
--pk-border: var(--colors-gray-700);
/* Decap chrome: primitives for readable gray/yellow admin UI. */
--pk-bg: var(--ssd-color-gray-900);
--pk-fg: var(--ssd-color-gray-100);
--pk-muted: var(--ssd-color-gray-400);
--pk-accent: var(--ssd-color-yellow-light-400);
--pk-accent-on: var(--ssd-color-gray-900);
--pk-accent-bg: var(--ssd-color-yellow-light-900);
--pk-surface: var(--ssd-color-gray-800);
--pk-surface-raised: var(--ssd-color-gray-700);
--pk-border: var(--ssd-color-gray-700);
--pk-glow: color-mix(in srgb, var(--pk-accent) 18%, transparent);
--pk-danger: var(--colors-red-400);
--pk-danger-bg: var(--colors-red-900);
--pk-success: var(--colors-green-400);
--pk-success-bg: var(--colors-green-900);
--pk-warn: var(--colors-yellow-light-300);
--pk-warn-bg: var(--colors-yellow-light-900);
--pk-danger: var(--ssd-color-red-400);
--pk-danger-bg: var(--ssd-color-red-900);
--pk-success: var(--ssd-color-green-400);
--pk-success-bg: var(--ssd-color-green-900);
--pk-warn: var(--ssd-color-yellow-light-300);
--pk-warn-bg: var(--ssd-color-yellow-light-900);
--pk-info: var(--pk-accent);
--pk-info-bg: var(--pk-accent-bg);

/* Override CDN token semantics that clash with product yellow/gray */
--fg-default: var(--pk-fg);
--fg-muted: var(--pk-muted);
--bg-default: var(--pk-bg);
--bg-muted: var(--pk-surface);
--accent-default: var(--pk-accent);
--accent-on-accent: var(--pk-accent-on);
--accent-bg: var(--pk-accent-bg);

/* Decap styles.js semantic → product (documentation aid for remapper) */
--decap-background: var(--pk-bg);
--decap-foreground: var(--pk-surface);
Expand All @@ -53,16 +44,16 @@ html,
body {
margin: 0;
min-height: 100%;
font-family: var(--font-families-body), ui-sans-serif, system-ui, sans-serif;
background-color: var(--bg-default);
font-family: var(--ssd-font-family-body), ui-sans-serif, system-ui, sans-serif;
background-color: var(--pk-bg);
background-image:
radial-gradient(ellipse 80% 55% at 50% -12%, var(--pk-glow), transparent 55%),
radial-gradient(
circle at 88% 82%,
color-mix(in srgb, var(--colors-gray-700) 35%, transparent),
color-mix(in srgb, var(--ssd-color-gray-700) 35%, transparent),
transparent 42%
);
color: var(--fg-default);
color: var(--pk-fg);
}

body > div {
Expand All @@ -75,7 +66,7 @@ button,
}

a {
color: var(--accent-default);
color: var(--pk-accent);
}

/* ——— Shell: solid surfaces (never transparent main panes) ——— */
Expand Down Expand Up @@ -132,7 +123,7 @@ a {
content: 'Content admin';
display: block;
margin-top: 0.75rem;
font-family: var(--font-families-body), ui-sans-serif, system-ui, sans-serif;
font-family: var(--ssd-font-family-body), ui-sans-serif, system-ui, sans-serif;
font-size: 0.875rem;
font-weight: 500;
letter-spacing: 0.02em;
Expand Down
3 changes: 2 additions & 1 deletion apps/marketing/public/admin/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@
/>
<!-- Absolute path: at /admin (no trailing slash) a relative config.yml resolves to /config.yml. -->
<link href="/admin/config.yml" type="text/yaml" rel="cms-config-url" />
<!-- Open Sauce Sans — matches Singleton SD --font-families-* tokens. -->
<!-- Open Sauce Sans — matches Singleton SD --ssd-font-family-* tokens. -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@fontsource/open-sauce-sans@5.3.0/index.css"
/>
<link rel="stylesheet" href="/admin/vendor/tokens-dark.css" />
<link rel="stylesheet" href="/admin/admin.css" />
</head>
<body>
Expand Down
62 changes: 22 additions & 40 deletions apps/marketing/public/admin/preview.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,30 @@
* Preview pane iframe styles — official CMS.registerPreviewStyle target.
* Mirrors marketing token roles + home / [slug] layouts.
*
* Token sheet vars are gated on [data-theme='dark']. Decap’s preview iframe
* has no data-theme by default (admin-preview.js stamps it). Mirror the needed
* --colors-* / font tokens on :root so contrast works even before that runs.
* Token CSS is copied from @singleton-sd/tokens (root/dark) so vars live on
* :root even before admin-preview.js stamps [data-theme='dark'].
*/
@import url('https://tokens.design.singletonsd.com/css/dark/_variables.css');
@import url('./vendor/tokens-root-dark.css');
@import url('https://cdn.jsdelivr.net/npm/@fontsource/open-sauce-sans@5.3.0/index.css');

:root {
/* Same values as tokens.design.singletonsd.com dark sheet (iframe bridge). */
--colors-gray-100: #f5f6f7;
--colors-gray-400: #b3b7bd;
--colors-gray-700: #60656b;
--colors-gray-800: #44484d;
--colors-gray-900: #292c30;
--colors-yellow-light-400: #fdc94a;
--colors-yellow-light-900: #6b4500;
--font-families-heading: 'Open Sauce Sans';
--font-families-body: 'Open Sauce Sans';

--pk-bg: var(--colors-gray-900);
--pk-fg: var(--colors-gray-100);
--pk-muted: var(--colors-gray-400);
--pk-accent: var(--colors-yellow-light-400);
--pk-accent-on: var(--colors-gray-900);
--pk-accent-bg: var(--colors-yellow-light-900);
--pk-surface: var(--colors-gray-800);
--fg-default: var(--pk-fg);
--fg-muted: var(--pk-muted);
--bg-default: var(--pk-bg);
--accent-default: var(--pk-accent);
--accent-on-accent: var(--pk-accent-on);
--accent-bg: var(--pk-accent-bg);
--pk-bg: var(--ssd-color-background-default);
--pk-fg: var(--ssd-color-text-default);
--pk-muted: var(--ssd-color-text-muted);
--pk-accent: var(--ssd-color-background-brand);
--pk-accent-on: var(--ssd-color-text-on-brand);
--pk-accent-bg: var(--ssd-color-background-muted);
--pk-surface: var(--ssd-color-background-muted);
color-scheme: dark;
}

html,
body {
margin: 0;
padding: 0;
font-family: var(--font-families-body), ui-sans-serif, system-ui, sans-serif;
background: var(--bg-default);
color: var(--fg-default);
font-family: var(--ssd-font-family-body), ui-sans-serif, system-ui, sans-serif;
background: var(--pk-bg);
color: var(--pk-fg);
}

/* ——— Home (index.astro) ——— */
Expand All @@ -57,7 +39,7 @@ body {

.pk-preview__brand {
margin: 0 0 1.25rem;
font-family: var(--font-families-heading), ui-sans-serif, system-ui, sans-serif;
font-family: var(--ssd-font-family-heading), ui-sans-serif, system-ui, sans-serif;
font-size: clamp(2.25rem, 7vw, 3.5rem);
font-weight: 700;
line-height: 1;
Expand All @@ -71,7 +53,7 @@ body {

.pk-preview__headline {
margin: 0 0 0.75rem;
font-family: var(--font-families-heading), ui-sans-serif, system-ui, sans-serif;
font-family: var(--ssd-font-family-heading), ui-sans-serif, system-ui, sans-serif;
font-size: clamp(1.15rem, 2.5vw, 1.35rem);
font-weight: 500;
letter-spacing: -0.02em;
Expand Down Expand Up @@ -128,7 +110,7 @@ body {

.pk-preview__title {
margin: 0 0 0.25rem;
font-family: var(--font-families-heading), ui-sans-serif, system-ui, sans-serif;
font-family: var(--ssd-font-family-heading), ui-sans-serif, system-ui, sans-serif;
font-size: 1.875rem;
font-weight: 700;
letter-spacing: -0.02em;
Expand Down Expand Up @@ -168,7 +150,7 @@ body {
.pk-preview__brand,
.pk-preview__headline {
color: var(--pk-fg) !important;
font-family: var(--font-families-heading), ui-sans-serif, system-ui, sans-serif;
font-family: var(--ssd-font-family-heading), ui-sans-serif, system-ui, sans-serif;
}

.pk-preview__body a,
Expand All @@ -184,22 +166,22 @@ body > div:not(.pk-preview) {
h1,
h2,
h3 {
color: var(--fg-default);
font-family: var(--font-families-heading), ui-sans-serif, system-ui, sans-serif;
color: var(--pk-fg);
font-family: var(--ssd-font-family-heading), ui-sans-serif, system-ui, sans-serif;
}

p,
li {
color: var(--fg-muted);
color: var(--pk-muted);
line-height: 1.55;
}

a {
color: var(--accent-default);
color: var(--pk-accent);
}

strong {
color: var(--fg-default);
color: var(--pk-fg);
}

code {
Expand Down
15 changes: 15 additions & 0 deletions apps/marketing/scripts/copy-token-css.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { copyFileSync, mkdirSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const dest = join(dirname(fileURLToPath(import.meta.url)), '../public/admin/vendor');
mkdirSync(dest, { recursive: true });

const files = [
['@singleton-sd/tokens/css/dark', 'tokens-dark.css'],
['@singleton-sd/tokens/css/root/dark', 'tokens-root-dark.css'],
];

for (const [specifier, name] of files) {
copyFileSync(fileURLToPath(import.meta.resolve(specifier)), join(dest, name));
}
Loading
Loading