feat: Phosphor v0.1.0 — clean CRT block-theme foundation (theme.json, FSE templates, parts, readme)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jeuner 2026-06-10 11:00:15 +02:00
parent 4c25b5eeda
commit ca93367b5b
14 changed files with 490 additions and 0 deletions

20
.gitignore vendored Normal file
View file

@ -0,0 +1,20 @@
# Secrets — never commit
*.env
.env
.env.*
!.env.example
*credentials*
*.pem
*.key
# OS / editor
.DS_Store
Thumbs.db
*.swp
.idea/
.vscode/
# Build artifacts
dist/
*.zip
node_modules/

54
README.md Normal file
View file

@ -0,0 +1,54 @@
# Phosphor
A CRT / terminal **WordPress block theme** — green-on-black, monospace, subtle scanlines.
Minimal, fast, full-site-editing (FSE). Built for people who like their blog to look like a
warm CRT terminal that's *alive*.
> Phosphor (n.) — the glowing coating on the inside of a cathode-ray tube. The green afterglow.
## Status
**v0.1.0 — early.** A clean, installable block-theme foundation extracted and generalized from a
live personal site. No personal data, no API keys, no third-party services — pure GPL theme.
The roadmap below tracks the road to a polished, sellable-grade product.
## Install
1. Download `phosphor.zip` from the [Releases](https://github.com/Jeuners/phosphor/releases) page.
2. WordPress Admin → **Appearance → Themes → Add New → Upload Theme** → choose the ZIP → Activate.
Or clone and symlink the `theme/` folder into `wp-content/themes/phosphor`.
## What's in here
```
theme/ # the Phosphor block theme (this is what gets zipped & installed)
plugins/ # optional companion plugins (CRT admin skin, coming-soon, …) — added incrementally
LICENSE # GPL-2.0-or-later
```
## Design tokens
| Token | Value |
|---|---|
| Background | `#000000` |
| Text | `#ffffff` |
| Accent | `#00ff00` (CRT green) |
| Muted | `#666666` |
| Type | monospace (Courier / system mono) |
All editable in the Site Editor (Styles) or `theme.json` — no code needed to rebrand.
## Roadmap
- [x] Clean block-theme foundation (theme.json, templates, parts, GPL)
- [ ] Companion plugin: CRT admin skin + coming-soon (genericized)
- [ ] Full i18n (`phosphor` text domain, `.pot`)
- [ ] Block patterns (hero, post grid, CRT cards)
- [ ] Customizer-free theming presets + style variations
- [ ] Demo content (WXR) + screenshot
- [ ] `readme.txt` to WordPress.org standard
## License
[GPL-2.0-or-later](LICENSE). Use it, fork it, sell services around it.

40
theme/functions.php Normal file
View file

@ -0,0 +1,40 @@
<?php
/**
* Phosphor theme setup.
*
* A block theme needs very little PHP: enqueue the supplemental stylesheet,
* load the text domain, and add a body class for the optional scanline overlay.
*
* @package Phosphor
*/
if (!defined('ABSPATH')) exit;
add_action('after_setup_theme', function (): void {
load_theme_textdomain('phosphor', get_template_directory() . '/languages');
add_theme_support('wp-block-styles');
add_theme_support('responsive-embeds');
add_theme_support('editor-styles');
add_editor_style('style.css');
});
add_action('wp_enqueue_scripts', function (): void {
$css = get_stylesheet_directory() . '/style.css';
wp_enqueue_style(
'phosphor',
get_stylesheet_uri(),
[],
file_exists($css) ? (string) filemtime($css) : '0.1.0'
);
});
/**
* Toggle the CRT scanline overlay with: add_filter('phosphor_scanlines', '__return_true');
* Off by default so it never surprises a buyer.
*/
add_filter('body_class', function (array $classes): array {
if (apply_filters('phosphor_scanlines', false)) {
$classes[] = 'phosphor-scanlines';
}
return $classes;
});

8
theme/parts/footer.html Normal file
View file

@ -0,0 +1,8 @@
<!-- wp:group {"tagName":"footer","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"2.5rem","bottom":"2.5rem"},"margin":{"top":"3rem"}},"border":{"top":{"color":"var:preset|color|line","width":"1px"}}}} -->
<footer class="wp-block-group" style="border-top-color:var(--wp--preset--color--line);border-top-width:1px;margin-top:3rem;padding-top:2.5rem;padding-bottom:2.5rem">
<!-- wp:site-title {"textAlign":"center","level":0,"style":{"typography":{"fontSize":"0.8rem","textTransform":"lowercase","letterSpacing":"0.2em"},"color":{"text":"#666666"}}} /-->
<!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":"0.7rem","letterSpacing":"0.1em"},"color":{"text":"#444444"},"spacing":{"margin":{"top":"0.6rem"}}}} -->
<p class="has-text-align-center has-text-color" style="color:#444444;font-size:0.7rem;letter-spacing:0.1em;margin-top:0.6rem">Powered by <a href="https://github.com/Jeuners/phosphor">Phosphor</a></p>
<!-- /wp:paragraph -->
</footer>
<!-- /wp:group -->

10
theme/parts/header.html Normal file
View file

@ -0,0 +1,10 @@
<!-- wp:group {"tagName":"header","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"1rem","bottom":"1rem"}},"border":{"bottom":{"color":"var:preset|color|line","width":"1px"}}}} -->
<header class="wp-block-group" style="border-bottom-color:var(--wp--preset--color--line);border-bottom-width:1px;padding-top:1rem;padding-bottom:1rem">
<!-- wp:group {"layout":{"type":"flex","flexWrap":"wrap","justifyContent":"space-between","verticalAlignment":"center"}} -->
<div class="wp-block-group">
<!-- wp:site-title {"level":0,"style":{"typography":{"textTransform":"lowercase","letterSpacing":"0.12em","fontSize":"1rem"}}} /-->
<!-- wp:navigation {"overlayMenu":"mobile","layout":{"type":"flex","justifyContent":"right"},"style":{"typography":{"fontSize":"0.85rem","letterSpacing":"0.06em"}}} /-->
</div>
<!-- /wp:group -->
</header>
<!-- /wp:group -->

34
theme/readme.txt Normal file
View file

@ -0,0 +1,34 @@
=== Phosphor ===
Contributors: phosphor
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.0
Stable tag: 0.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Tags: full-site-editing, blog, one-column, custom-colors, editor-style, block-patterns, dark-mode, accessibility-ready
A CRT/terminal WordPress block theme — green-on-black, monospace, subtle scanlines.
== Description ==
Phosphor is a minimal, fast full-site-editing block theme with a CRT/terminal aesthetic:
green-on-black, monospace type, optional scanline overlay, and a blinking-caret accent.
Everything is editable in the Site Editor (Styles) or theme.json — no code needed to rebrand.
Features:
* Full Site Editing (block templates + template parts)
* CRT design tokens in theme.json (base, contrast, accent, muted, line)
* Optional scanline overlay (off by default; enable via the `phosphor_scanlines` filter)
* Blinking-caret utility class (`ph-caret`)
* Accessibility: honors prefers-reduced-motion
== Installation ==
1. Appearance > Themes > Add New > Upload Theme.
2. Upload phosphor.zip and click Activate.
== Changelog ==
= 0.1.0 =
* Initial release: clean block-theme foundation (theme.json, templates, parts, GPL-2.0).

77
theme/style.css Normal file
View file

@ -0,0 +1,77 @@
/*
Theme Name: Phosphor
Theme URI: https://github.com/Jeuners/phosphor
Author: Phosphor
Author URI: https://github.com/Jeuners/phosphor
Description: A CRT/terminal WordPress block theme green-on-black, monospace, subtle scanlines. Minimal, fast, full-site-editing.
Version: 0.1.0
Requires at least: 6.4
Tested up to: 6.7
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: phosphor
Tags: full-site-editing, blog, one-column, custom-colors, editor-style, block-patterns, dark-mode, accessibility-ready
*/
/* Phosphor — supplemental front-end styles. Design tokens live in theme.json. */
:root {
--ph-bg: #000;
--ph-fg: #fff;
--ph-accent: #00ff00;
--ph-muted: #666;
--ph-line: #1a1a1a;
}
/* CRT scanline overlay — subtle, non-blocking */
body.phosphor-scanlines::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
background: repeating-linear-gradient(
0deg,
rgba(0, 255, 80, 0.03) 0 1px,
transparent 1px 3px
);
mix-blend-mode: screen;
}
/* Links — CRT green with glow on hover */
a {
color: var(--ph-accent);
text-decoration-thickness: 1px;
text-underline-offset: 0.2em;
transition: text-shadow 0.15s ease, opacity 0.15s ease;
}
a:hover {
text-shadow: 0 0 8px rgba(0, 255, 80, 0.5);
}
/* Selection */
::selection {
background: var(--ph-accent);
color: #000;
}
/* Post title accent prompt */
.wp-block-post-title a::before {
content: "\25B8\00a0"; /* ▸ */
color: var(--ph-accent);
opacity: 0.7;
}
/* Blinking caret utility (for headings/heroes) */
.ph-caret::after {
content: "\2588"; /* █ */
color: var(--ph-accent);
margin-left: 0.1em;
animation: ph-blink 1.05s steps(1) infinite;
}
@keyframes ph-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
.ph-caret::after { animation: none; }
}

17
theme/templates/404.html Normal file
View file

@ -0,0 +1,17 @@
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"5rem","bottom":"5rem"}}}} -->
<main class="wp-block-group" style="padding-top:5rem;padding-bottom:5rem">
<!-- wp:heading {"level":1,"className":"ph-caret","style":{"typography":{"fontSize":"clamp(2rem,8vw,5rem)","letterSpacing":"-0.02em"},"color":{"text":"#00ff00"}}} -->
<h1 class="wp-block-heading ph-caret has-text-color" style="color:#00ff00;font-size:clamp(2rem,8vw,5rem);letter-spacing:-0.02em">404 — signal lost</h1>
<!-- /wp:heading -->
<!-- wp:paragraph {"style":{"color":{"text":"#666666"},"spacing":{"margin":{"top":"1rem","bottom":"2rem"}}}} -->
<p class="has-text-color" style="color:#666666;margin-top:1rem;margin-bottom:2rem">// the page you tried to reach is not on this channel.</p>
<!-- /wp:paragraph -->
<!-- wp:search {"label":"Search","showLabel":false,"placeholder":"search ▸","buttonText":"go","buttonPosition":"button-inside"} /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

View file

@ -0,0 +1,34 @@
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"2.5rem","bottom":"2.5rem"}}}} -->
<main class="wp-block-group" style="padding-top:2.5rem;padding-bottom:2.5rem">
<!-- wp:query-title {"type":"archive","style":{"typography":{"fontSize":"1.5rem","letterSpacing":"0.04em"}}} /-->
<!-- wp:term-description {"style":{"typography":{"fontSize":"0.85rem"},"color":{"text":"#666666"},"spacing":{"margin":{"bottom":"2rem"}}}} /-->
<!-- wp:query {"queryId":0,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","inherit":true}} -->
<div class="wp-block-query">
<!-- wp:post-template {"style":{"spacing":{"blockGap":"2.5rem"}}} -->
<!-- wp:post-title {"isLink":true,"level":2} /-->
<!-- wp:post-date {"style":{"typography":{"fontSize":"0.72rem","letterSpacing":"0.12em"},"color":{"text":"#666666"}}} /-->
<!-- wp:post-excerpt {"moreText":"read ▸"} /-->
<!-- /wp:post-template -->
<!-- wp:query-pagination {"layout":{"type":"flex","justifyContent":"space-between"},"style":{"spacing":{"margin":{"top":"2rem"}}}} -->
<!-- wp:query-pagination-previous {"label":"▸ prev"} /-->
<!-- wp:query-pagination-numbers /-->
<!-- wp:query-pagination-next {"label":"next ▸"} /-->
<!-- /wp:query-pagination -->
<!-- wp:query-no-results -->
<!-- wp:paragraph {"style":{"color":{"text":"#666666"}}} -->
<p class="has-text-color" style="color:#666666">// nothing here.</p>
<!-- /wp:paragraph -->
<!-- /wp:query-no-results -->
</div>
<!-- /wp:query -->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

View file

@ -0,0 +1,35 @@
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"2.5rem","bottom":"2.5rem"}}}} -->
<main class="wp-block-group" style="padding-top:2.5rem;padding-bottom:2.5rem">
<!-- wp:query {"queryId":0,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","inherit":true}} -->
<div class="wp-block-query">
<!-- wp:post-template {"style":{"spacing":{"blockGap":"3rem"}}} -->
<!-- wp:post-title {"isLink":true,"level":2} /-->
<!-- wp:post-date {"style":{"typography":{"fontSize":"0.72rem","letterSpacing":"0.12em"},"color":{"text":"#666666"}}} /-->
<!-- wp:post-excerpt {"moreText":"read ▸"} /-->
<!-- /wp:post-template -->
<!-- wp:spacer {"height":"2rem"} -->
<div style="height:2rem" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->
<!-- wp:query-pagination {"layout":{"type":"flex","justifyContent":"space-between"}} -->
<!-- wp:query-pagination-previous {"label":"▸ prev"} /-->
<!-- wp:query-pagination-numbers /-->
<!-- wp:query-pagination-next {"label":"next ▸"} /-->
<!-- /wp:query-pagination -->
<!-- wp:query-no-results -->
<!-- wp:paragraph {"style":{"color":{"text":"#666666"}}} -->
<p class="has-text-color" style="color:#666666">// nothing here yet.</p>
<!-- /wp:paragraph -->
<!-- /wp:query-no-results -->
</div>
<!-- /wp:query -->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

11
theme/templates/page.html Normal file
View file

@ -0,0 +1,11 @@
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"2.5rem","bottom":"2.5rem"}}}} -->
<main class="wp-block-group" style="padding-top:2.5rem;padding-bottom:2.5rem">
<!-- wp:post-title {"level":1} /-->
<!-- wp:post-featured-image {"style":{"border":{"radius":"4px"},"spacing":{"margin":{"top":"1rem"}}}} /-->
<!-- wp:post-content {"layout":{"type":"constrained"},"style":{"spacing":{"margin":{"top":"1.6rem"}}}} /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

View file

@ -0,0 +1,30 @@
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"2.5rem","bottom":"2.5rem"}}}} -->
<main class="wp-block-group" style="padding-top:2.5rem;padding-bottom:2.5rem">
<!-- wp:query-title {"type":"search","style":{"typography":{"fontSize":"1.5rem"}}} /-->
<!-- wp:search {"showLabel":false,"placeholder":"search ▸","buttonText":"go","buttonPosition":"button-inside","style":{"spacing":{"margin":{"top":"1rem","bottom":"2rem"}}}} /-->
<!-- wp:query {"queryId":0,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","inherit":true}} -->
<div class="wp-block-query">
<!-- wp:post-template {"style":{"spacing":{"blockGap":"2.5rem"}}} -->
<!-- wp:post-title {"isLink":true,"level":2} /-->
<!-- wp:post-excerpt {"moreText":"read ▸"} /-->
<!-- /wp:post-template -->
<!-- wp:query-pagination {"layout":{"type":"flex","justifyContent":"space-between"}} -->
<!-- wp:query-pagination-previous {"label":"▸ prev"} /-->
<!-- wp:query-pagination-next {"label":"next ▸"} /-->
<!-- /wp:query-pagination -->
<!-- wp:query-no-results -->
<!-- wp:paragraph {"style":{"color":{"text":"#666666"}}} -->
<p class="has-text-color" style="color:#666666">// no matches.</p>
<!-- /wp:paragraph -->
<!-- /wp:query-no-results -->
</div>
<!-- /wp:query -->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

View file

@ -0,0 +1,43 @@
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"},"style":{"spacing":{"padding":{"top":"2.5rem","bottom":"2.5rem"}}}} -->
<main class="wp-block-group" style="padding-top:2.5rem;padding-bottom:2.5rem">
<!-- wp:post-title {"level":1} /-->
<!-- wp:group {"layout":{"type":"flex","flexWrap":"wrap"},"style":{"typography":{"fontSize":"0.72rem","letterSpacing":"0.12em"},"color":{"text":"#666666"},"spacing":{"margin":{"top":"0.4rem","bottom":"1.6rem"}}}} -->
<div class="wp-block-group has-text-color" style="color:#666666;margin-top:0.4rem;margin-bottom:1.6rem;font-size:0.72rem;letter-spacing:0.12em">
<!-- wp:post-date /-->
<!-- wp:post-terms {"term":"category","prefix":"· "} /-->
</div>
<!-- /wp:group -->
<!-- wp:post-featured-image {"style":{"border":{"radius":"4px"}}} /-->
<!-- wp:post-content {"layout":{"type":"constrained"},"style":{"spacing":{"margin":{"top":"1.6rem"}}}} /-->
<!-- wp:separator {"style":{"color":{"background":"#1a1a1a"}}} -->
<hr class="wp-block-separator has-text-color has-css-opacity has-background" style="background-color:#1a1a1a;color:#1a1a1a"/>
<!-- /wp:separator -->
<!-- wp:comments -->
<div class="wp-block-comments">
<!-- wp:comments-title /-->
<!-- wp:comment-template -->
<!-- wp:comment-author-name /-->
<!-- wp:comment-date /-->
<!-- wp:comment-content /-->
<!-- wp:comment-reply-link /-->
<!-- /wp:comment-template -->
<!-- wp:comments-pagination -->
<!-- wp:comments-pagination-previous /-->
<!-- wp:comments-pagination-next /-->
<!-- /wp:comments-pagination -->
<!-- wp:post-comments-form /-->
</div>
<!-- /wp:comments -->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

77
theme/theme.json Normal file
View file

@ -0,0 +1,77 @@
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"appearanceTools": true,
"useRootPaddingAwareAlignments": true,
"layout": {
"contentSize": "720px",
"wideSize": "1100px"
},
"color": {
"defaultPalette": false,
"custom": true,
"palette": [
{ "slug": "base", "color": "#000000", "name": "Base" },
{ "slug": "contrast", "color": "#ffffff", "name": "Contrast" },
{ "slug": "accent", "color": "#00ff00", "name": "Accent (CRT green)" },
{ "slug": "muted", "color": "#666666", "name": "Muted" },
{ "slug": "line", "color": "#1a1a1a", "name": "Line" }
]
},
"typography": {
"defaultFontSizes": false,
"fluid": true,
"fontFamilies": [
{
"slug": "mono",
"name": "Monospace",
"fontFamily": "'Courier New', Courier, ui-monospace, monospace"
},
{
"slug": "sans",
"name": "System Sans",
"fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"
}
],
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Small" },
{ "slug": "medium", "size": "1rem", "name": "Medium" },
{ "slug": "large", "size": "1.5rem", "name": "Large" },
{ "slug": "xlarge", "size": "clamp(2rem, 8vw, 6rem)", "name": "XL Hero" }
]
},
"spacing": {
"units": ["px", "em", "rem", "vh", "vw", "%"],
"spacingScale": { "steps": 7 }
}
},
"styles": {
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
},
"typography": {
"fontFamily": "var(--wp--preset--font-family--mono)",
"fontSize": "var(--wp--preset--font-size--medium)",
"lineHeight": "1.6",
"letterSpacing": "0.02em"
},
"elements": {
"link": {
"color": { "text": "var(--wp--preset--color--accent)" },
":hover": { "typography": { "textDecoration": "underline" } }
},
"h1": { "typography": { "fontSize": "var(--wp--preset--font-size--xlarge)", "lineHeight": "1.1", "letterSpacing": "-0.02em" } },
"h2": { "typography": { "fontSize": "var(--wp--preset--font-size--large)", "lineHeight": "1.2" } }
},
"blocks": {
"core/post-title": { "typography": { "fontWeight": "500" } }
}
},
"templateParts": [
{ "name": "header", "title": "Header", "area": "header" },
{ "name": "footer", "title": "Footer", "area": "footer" }
],
"customTemplates": []
}