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
1 change: 1 addition & 0 deletions src/_includes/layouts/base.njk
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<button class="nav-toggle" type="button" hidden aria-expanded="false" aria-controls="primary-nav">Menu</button>
<nav id="primary-nav" class="primary-nav" aria-label="Primary navigation">
<a href="/start/">Start</a>
<a href="/preamble/">Preamble</a>
<a href="/way/">The Way</a>
<a href="/lab/">Article Lab</a>
<a href="/projects/">Projects</a>
Expand Down
5 changes: 3 additions & 2 deletions src/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ description: A calm, layered entrance to the canon, its deliberate tensions, the
<div>
<p class="eyebrow">Canon · interpretation · research · implementation · frontier</p>
<h1>A way through complexity without pretending the tension is gone.</h1>
<p class="lede">The Interdependent Way is a dense living text and a constellation of attempts to test, explain, implement, challenge, and preserve it. This site starts with orientation. Exact source remains available when intentionally sought.</p>
<div class="actions"><a class="button" href="/start/">Begin with orientation</a><a class="button secondary" href="/way/">Explore the Way</a></div>
<p class="lede">The Interdependent Way is a dense living text and a constellation of attempts to test, explain, implement, challenge, and preserve it. The Preamble is directly available here; deeper orientation and exact source remain available without hiding the entrance.</p>
<div class="actions"><a class="button" href="/preamble/">Read the Preamble</a><a class="button secondary" href="/start/">Begin with orientation</a><a class="button secondary" href="/way/">Explore the Way</a></div>
</div>
<div class="hero-field" aria-label="Three concentric fields around a thirteenth center"><span></span><strong>12 + 1</strong></div>
</section>
Expand All @@ -22,6 +22,7 @@ description: A calm, layered entrance to the canon, its deliberate tensions, the
<p class="eyebrow">Choose a depth</p>
<h2>One body of work, several honest entrances</h2>
<div class="grid">
<a class="card" href="/preamble/"><span class="status status-canon">Canon-derived</span><h3>Read the Preamble</h3><p>Enter the opening civic claim directly through a stable route generated from the selected canon.</p></a>
<a class="card" href="/way/"><span class="status status-canon">Canon-derived</span><h3>Read the Way</h3><p>Move through the preamble, articles, etiquette, addenda, and their internal structure without beginning at the raw wall of text.</p></a>
<a class="card" href="/lab/"><span class="status status-interpretation">Interpretation</span><h3>Enter the Article Lab</h3><p>Read the main text and its notes as two speakers. Supporting, dissenting, mixed, and missing research remain visibly separate.</p></a>
<a class="card" href="/articles/"><span class="status status-interpretation">Publication</span><h3>Read public articles</h3><p>Follow selected canon units through companion readings, applications, handbook seeds, and script drafts without losing source boundaries.</p></a>
Expand Down
33 changes: 33 additions & 0 deletions src/preamble/index.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
layout: layouts/base.njk
title: Preamble
description: The canonical Preamble of The Interdependent Way, directly accessible from the public entrance.
permalink: /preamble/
---
{% set preambles = generated.canon.units | where("title", "Preamble") %}
{% set preamble = preambles[0] %}
<nav class="breadcrumb" aria-label="Breadcrumb"><a href="/">Home</a> / Preamble</nav>
<header class="page-head">
<p class="eyebrow">One-click canon entrance</p>
<h1>Preamble</h1>
<div class="status-row"><span class="status status-canon">exact canon-derived unit</span></div>
<p class="lede">The Preamble is a first-order entrance to The Interdependent Way. This stable route is generated from the selected canonical source and does not maintain a separate copy.</p>
</header>
{% if preamble %}
<section>
<h2>Canonical text</h2>
<pre class="source-block">{{ preamble.content }}</pre>
</section>
<section class="panel">
<h2>Source evidence</h2>
<dl class="meta">
<dt>Canonical repository</dt><dd><code>{{ generated.canon.source.repository }}</code></dd>
<dt>Canonical path</dt><dd><code>{{ generated.canon.source.path }}</code></dd>
<dt>Source lines</dt><dd>{{ preamble.startLine }}–{{ preamble.endLine }}</dd>
<dt>Unit digest</dt><dd><code>{{ preamble.hash }}</code></dd>
</dl>
</section>
<div class="actions"><a class="button" href="/source/{{ preamble.routeSlug }}/">Read exact source view</a><a class="button secondary" href="/way/">Continue through The Way</a></div>
{% else %}
<section class="hmmm"><h2>hmmm</h2><p>The selected canon did not produce a Preamble unit. The release tests must treat this as a broken public contract.</p></section>
{% endif %}
2 changes: 1 addition & 1 deletion tests/accessibility.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { test, expect } from '@playwright/test';
const require = createRequire(import.meta.url);
const axePath = require.resolve('axe-core/axe.min.js');

for (const route of ['/', '/articles/', '/articles/article-two/', '/way/', '/projects/']) {
for (const route of ['/', '/preamble/', '/articles/', '/articles/article-two/', '/way/', '/projects/']) {
test(`${route} has no serious or critical automated accessibility violations`, async ({ page }) => {
await page.goto(route);
await page.addScriptTag({ path: axePath });
Expand Down
7 changes: 6 additions & 1 deletion tests/generated-site.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import { readFile } from 'node:fs/promises';

// Usage: run only after Eleventy has generated _site, normally through npm run test:generated or npm run check.
test('generated deployment artifact contains the unified routes', async () => {
const [home, artifacts, fourCuts, fallback, articles] = await Promise.all([
const [home, preamble, artifacts, fourCuts, fallback, articles] = await Promise.all([
readFile('_site/index.html', 'utf8'),
readFile('_site/preamble/index.html', 'utf8'),
readFile('_site/artifacts/index.html', 'utf8'),
readFile('_site/artifacts/four-cuts/index.html', 'utf8'),
readFile('_site/fallback/index.html', 'utf8'),
readFile('_site/articles/index.html', 'utf8')
]);

assert.match(home, /A way through complexity/);
assert.match(home, /href="\/preamble\/"[^>]*>Read the Preamble/);
assert.match(preamble, /One-click canon entrance/);
assert.match(preamble, /Humanity faces extinction/);
assert.match(preamble, /Canonical repository/);
assert.match(artifacts, /Artifacts/);
assert.match(fourCuts, /Wealth and tax/);
assert.match(fallback, /Emergency static edition/);
Expand Down
13 changes: 13 additions & 0 deletions tests/site.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { test, expect } from '@playwright/test';

const routes = [
['/', /A way through complexity/],
['/preamble/', /Humanity faces extinction/],
['/articles/', /Publication drafts/],
['/articles/article-two/', /Freedom without abandonment/],
['/way/', /The Way/],
Expand All @@ -22,6 +23,18 @@ test('primary public routes render meaningful headings', async ({ page }) => {
}
});

test('Preamble is one click from the public entrance and primary navigation', async ({ page }) => {
await page.goto('/');
const heroLink = page.locator('main a[href="/preamble/"]', { hasText: 'Read the Preamble' }).first();
const navLink = page.locator('nav[aria-label="Primary navigation"] a[href="/preamble/"]');
await expect(heroLink).toBeVisible();
await expect(navLink).toBeVisible();
await heroLink.click();
await expect(page).toHaveURL(/\/preamble\/$/);
await expect(page.locator('h1')).toHaveText('Preamble');
await expect(page.locator('.source-block')).toContainText('Humanity faces extinction');
});

test('all eight rights articles are reachable from the article index', async ({ page }) => {
await page.goto('/articles/');
for (const word of ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']) {
Expand Down
Loading