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
29 changes: 24 additions & 5 deletions src/assets/css/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,27 @@ h3 { font-size: clamp(1.2rem, 2vw, 1.55rem); }
.page-head { max-width: 62rem; margin-bottom: 3rem; }
.page-head h1 { font-size: clamp(2.5rem, 6vw, 5rem); }
.index-list { display: grid; gap: .7rem; padding: 0; list-style: none; }
.index-list a { display: grid; grid-template-columns: 7rem 1fr auto; gap: 1rem; align-items: baseline; padding: .9rem 1rem; border: 1px solid var(--line); border-radius: .75rem; background: rgba(16,24,42,.75); color: inherit; text-decoration: none; }
.index-list a:hover { border-color: var(--violet); }
.index-list > li > a { display: grid; grid-template-columns: 7rem 1fr auto; gap: 1rem; align-items: baseline; padding: .9rem 1rem; border: 1px solid var(--line); border-radius: .75rem; background: rgba(16,24,42,.75); color: inherit; text-decoration: none; }
.index-list > li > a:hover { border-color: var(--violet); }
.index-list small { color: var(--silver); }
.canon-outline .canon-unit { margin: 0; padding: 0; overflow: hidden; background: rgba(16,24,42,.75); }
.canon-unit-summary { position: relative; display: grid; grid-template-columns: 7rem 1fr auto; gap: 1rem; align-items: baseline; padding: .9rem 1rem; list-style: none; }
.canon-unit-summary::-webkit-details-marker { display: none; }
.canon-unit-summary::before { content: "+"; position: absolute; transform: translate(-.55rem, -.05rem); color: var(--cyan); font: 800 1rem/1 ui-monospace, monospace; }
.canon-unit[open] .canon-unit-summary::before { content: "−"; }
.canon-unit-summary:hover { background: rgba(22,33,58,.72); }
.canon-unit-summary strong { padding-left: .35rem; }
.canon-unit .disclosure-open { display: none; }
.canon-unit[open] .disclosure-closed { display: none; }
.canon-unit[open] .disclosure-open { display: inline-flex; }
.canon-unit-text { padding: 0 1rem 1rem; border-top: 1px solid var(--line); }
.canon-unit-text .source-block { max-height: 28rem; overflow: auto; margin: 1rem 0; }
.canon-unit-text .actions { margin-top: 1rem; }
.canon-unit-text .actions a { display: inline-flex; padding: .7rem 1rem; }
.canon-outline .unit-level-3 { margin-left: clamp(1rem, 3vw, 2.5rem); }
.canon-outline .unit-level-4 { margin-left: clamp(2rem, 6vw, 5rem); }
.canon-outline .unit-level-3 a { border-left: .25rem solid var(--violet); }
.canon-outline .unit-level-4 a { border-left: .25rem solid var(--cyan); background: rgba(9, 13, 24, .76); }
.canon-outline .unit-level-3 .canon-unit { border-left: .25rem solid var(--violet); }
.canon-outline .unit-level-4 .canon-unit { border-left: .25rem solid var(--cyan); background: rgba(9, 13, 24, .76); }
.chapter-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); gap: 1rem; padding: 0; margin: 1.5rem 0 3rem; list-style: none; }
.chapter-grid li { min-width: 0; }
.chapter-card { height: 100%; }
Expand Down Expand Up @@ -152,7 +166,12 @@ summary { cursor: pointer; font-weight: 800; }
.primary-nav a { padding: .7rem; border: 1px solid var(--line); }
.hero { grid-template-columns: 1fr; min-height: auto; }
.hero-field { max-width: 22rem; width: 78%; margin: 1rem auto; }
.index-list a { grid-template-columns: 1fr; gap: .15rem; }
.index-list > li > a { grid-template-columns: 1fr; gap: .15rem; }
.canon-unit-summary { grid-template-columns: 1fr auto; gap: .2rem .6rem; padding-left: 1.35rem; }
.canon-unit-summary small { grid-column: 1 / -1; }
.canon-unit-summary strong { padding-left: 0; }
.canon-unit-text { padding: 0 .7rem .7rem; }
.canon-unit-text .actions .button { flex: 1 1 100%; }
.canon-outline .unit-level-3 { margin-left: .65rem; }
.canon-outline .unit-level-4 { margin-left: 1.3rem; }
.textbook-chapter { padding: 1rem; }
Expand Down
4 changes: 2 additions & 2 deletions src/way/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ layout: layouts/base.njk
title: Explore The Way
description: A sectioned and nested companion map of The Interdependent Way, with exact source available one deliberate layer deeper.
---
<header class="page-head"><p class="eyebrow">Canon-derived map</p><h1>Explore The Way</h1><p class="lede">This layer identifies the shape and relations of the source. Major sections, subheadings, and nested headings remain visibly distinct. It does not replace the canon. Open a unit for orientation, then choose its Lab conversation or exact source.</p></header>
<header class="page-head"><p class="eyebrow">Canon-derived map</p><h1>Explore The Way</h1><p class="lede">This layer identifies the shape and relations of the source. Major sections, subheadings, and nested headings remain visibly distinct. Tap any unit to reveal its exact bounded text here; the Unit, Lab, and Source links preserve the deeper paths.</p></header>
{% for section in generated.canon.sections %}
<section class="category"><p class="eyebrow">{{ section.id }}</p><h2>{{ section.title }}</h2><ul class="index-list canon-outline">{% for unit in generated.canon.units %}{% if unit.section == section.id %}<li class="unit-level-{{ unit.level }}" data-parent-id="{{ unit.parentId or '' }}"><a href="/way/{{ unit.routeSlug }}/"><small>lines {{ unit.startLine }}–{{ unit.endLine }} · {% if unit.level <= 2 %}section{% elif unit.level == 3 %}subheading{% else %}nested heading{% endif %}</small><strong>{{ unit.title }}</strong><span class="status status-canon">canon-derived</span></a></li>{% endif %}{% endfor %}</ul></section>
<section class="category"><p class="eyebrow">{{ section.id }}</p><h2>{{ section.title }}</h2><ul class="index-list canon-outline">{% for unit in generated.canon.units %}{% if unit.section == section.id %}<li class="unit-level-{{ unit.level }}" data-parent-id="{{ unit.parentId or '' }}"><details class="canon-unit" id="{{ unit.routeSlug }}"><summary class="canon-unit-summary"><small>lines {{ unit.startLine }}–{{ unit.endLine }} · {% if unit.level <= 2 %}section{% elif unit.level == 3 %}subheading{% else %}nested heading{% endif %}</small><strong>{{ unit.title }}</strong><span class="status status-canon disclosure-closed">tap to read</span><span class="status status-canon disclosure-open">text open</span></summary><div class="canon-unit-text"><pre class="source-block">{{ unit.content }}</pre><div class="actions"><a class="button" href="/way/{{ unit.routeSlug }}/">Open unit page</a><a class="button secondary" href="/lab/{{ unit.routeSlug }}/">Enter Lab</a><a class="button secondary" href="/source/{{ unit.routeSlug }}/">Source and provenance</a></div></div></details></li>{% endif %}{% endfor %}</ul></section>
{% endfor %}
4 changes: 4 additions & 0 deletions tests/generated-site.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ test('Way map renders Human consciousness beneath Interdefinables and before Pre
assert.match(way, /class="unit-level-3"[^>]*>[\s\S]*?Human consciousness emerges from/);
assert.match(way, /class="unit-level-4"[^>]*>[\s\S]*?Binary essences meaningfully/);
assert.doesNotMatch(way, /<h2>Human consciousness emerges from:?<\/h2>/);
assert.match(way, /<details class="canon-unit"/);
assert.match(way, /<summary class="canon-unit-summary">/);
assert.match(way, /Tap any unit to reveal its exact bounded text here/);
assert.match(way, /Human consciousness emerges from[\s\S]*?Source and provenance/);
});

test('generated deployment artifact contains all rights article vertical slices with research attachment', async () => {
Expand Down
11 changes: 11 additions & 0 deletions tests/site-contract.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ test('base layout remains readable without javascript and exposes the textbook a
assert.doesNotMatch(layout, /fetch\(/);
});

test('Way map uses native disclosure and keeps deeper routes separate', async () => {
const way = await readFile('src/way/index.njk', 'utf8');
assert.match(way, /<details class="canon-unit"/);
assert.match(way, /<summary class="canon-unit-summary">/);
assert.match(way, /<pre class="source-block">{{ unit\.content }}<\/pre>/);
assert.match(way, /href="\/way\/{{ unit\.routeSlug }}\/"/);
assert.match(way, /href="\/lab\/{{ unit\.routeSlug }}\/"/);
assert.match(way, /href="\/source\/{{ unit\.routeSlug }}\/"/);
assert.doesNotMatch(way, /<script/i);
});

test('Awakening owns the static public threshold and routes inward', async () => {
const [layout, splash, home] = await Promise.all([
readFile('src/_includes/layouts/splash.njk', 'utf8'),
Expand Down
15 changes: 15 additions & 0 deletions tests/site.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,21 @@
}
});

test('clicking a Way row reveals its bounded canon text without leaving the tree', async ({ page }) => {
const articleFiveUnit = canon.units.find(unit => unit.title === 'Article Five');
expect(articleFiveUnit, 'Article Five canon unit should exist').toBeTruthy();
await page.goto('/way/');
const articleFive = page.locator('details.canon-unit', { has: page.locator('summary', { hasText: 'Article Five' }) }).first();
await expect(articleFive).not.toHaveAttribute('open', '');
await articleFive.locator('summary').click();
await expect(articleFive).toHaveAttribute('open', '');
await expect(articleFive.locator('.source-block')).toHaveText(articleFiveUnit.content);

Check failure on line 103 in tests/site.spec.mjs

View workflow job for this annotation

GitHub Actions / Verify generated site

tests/site.spec.mjs:90:1 › clicking a Way row reveals its bounded canon text without leaving the tree

1) tests/site.spec.mjs:90:1 › clicking a Way row reveals its bounded canon text without leaving the tree Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: Timed out 5000ms waiting for expect(locator).toHaveText(expected) Locator: locator('details.canon-unit').filter({ has: locator('summary').filter({ hasText: 'Article Five' }) }).first().locator('.source-block') - Expected string - 16 + Received string + 12 - #### Article Five + Article Five - Adulthood ceases to be defined by an arbitrary and is instead claimed by intentional action of demonstrated competence in a field of study. Independence is the field describing the general skill-set to obtain relief from parental or guardian limitations. An independent adult owns their own actions, needs, resources and liability for harm caused by their actions. Interdependence is the field describing the general skill-set required for political adulthood. An interdependent adult is an independent adult who owns the consequences of their existence beyond being held accountable for deliberate or negligent harm. - - Every field of study possesses children, sophomores, and adults. Children can be taught. Sophomores know enough to be dangerous. Adults know enough to be dangerous without causing harm. Every individual within a field is dependent, independent, or interdependent. Dependents require intercession to survive the environment. Independents manage their own survival under the constraints of the environment. Interdependents manage their own survival and the survival of others. - - a dependent child becomes independent when they are capable of demonstrating firecraft, cooking, first aid, sanitation, communication and maintenance of the tools necessary for such. this results in an independent (can survive without constant supervision) sophomore (knows enough to be dangerous). - - An individual claims [1] adulthood [2] in a field by creating a proclamation of competency [3]. For participation in the body politic: handwritten [4] verbatim transcription of these Articles [5], portfolio of demonstrable skills, schedule of intended activities. - - [1] Who will not claim Adulthood remains a child; who renounces Adulthood becomes retired; who cannot attain or retain Adulthood are invalids. - [2] all adults are the same legal age, alive now. - [3] Each field outside the body politic will require their own set of demonstrable skills validation process delineated in a field specific interdependent way canon. - [4] save for prohibitive neurodivergence - [5] the Rights and Definitions of The Way - - --- + There are children¹, invalids¹, and adults². There are dependents, independents, and interdependents + Adulthood, defined by the capacity to survive physically and socially without direct intervention of parents or guardians; claimed by competent³ demonstration of the skills necessary: cooking, first aid, communication, sanitation, skill acquisition, shelter infrastructure maintenance. + Political Adulthood - the capacity to demonstrate self-sufficient interdependency; claimed by demonstration competencies of the body politic: an original, personal Preamble⁵; a hand-written transcription of these Articles⁴; a portfolio of demonstrated skill sets⁶; and a schedule of intended actions⁷. Twelve such are a Political Circle. + + > ¹ dependents. + > ² once adulthood is claimed, all adults are the same legal age, alive now. + > ³ the capacity to reliably perform a skill, practice an art, or otherwise contribute meaningfully to survival and conversation + > ⁴ Hand-writing is the standard, save for cases of prohibitive neurodivergence. + > ⁵ A few sentences that demonstrate a grasp of current political realities. + > ⁶ l

Check failure on line 103 in tests/site.spec.mjs

View workflow job for this annotation

GitHub Actions / Verify generated site

tests/site.spec.mjs:90:1 › clicking a Way row reveals its bounded canon text without leaving the tree

1) tests/site.spec.mjs:90:1 › clicking a Way row reveals its bounded canon text without leaving the tree Error: Timed out 5000ms waiting for expect(locator).toHaveText(expected) Locator: locator('details.canon-unit').filter({ has: locator('summary').filter({ hasText: 'Article Five' }) }).first().locator('.source-block') - Expected string - 16 + Received string + 12 - #### Article Five + Article Five - Adulthood ceases to be defined by an arbitrary and is instead claimed by intentional action of demonstrated competence in a field of study. Independence is the field describing the general skill-set to obtain relief from parental or guardian limitations. An independent adult owns their own actions, needs, resources and liability for harm caused by their actions. Interdependence is the field describing the general skill-set required for political adulthood. An interdependent adult is an independent adult who owns the consequences of their existence beyond being held accountable for deliberate or negligent harm. - - Every field of study possesses children, sophomores, and adults. Children can be taught. Sophomores know enough to be dangerous. Adults know enough to be dangerous without causing harm. Every individual within a field is dependent, independent, or interdependent. Dependents require intercession to survive the environment. Independents manage their own survival under the constraints of the environment. Interdependents manage their own survival and the survival of others. - - a dependent child becomes independent when they are capable of demonstrating firecraft, cooking, first aid, sanitation, communication and maintenance of the tools necessary for such. this results in an independent (can survive without constant supervision) sophomore (knows enough to be dangerous). - - An individual claims [1] adulthood [2] in a field by creating a proclamation of competency [3]. For participation in the body politic: handwritten [4] verbatim transcription of these Articles [5], portfolio of demonstrable skills, schedule of intended activities. - - [1] Who will not claim Adulthood remains a child; who renounces Adulthood becomes retired; who cannot attain or retain Adulthood are invalids. - [2] all adults are the same legal age, alive now. - [3] Each field outside the body politic will require their own set of demonstrable skills validation process delineated in a field specific interdependent way canon. - [4] save for prohibitive neurodivergence - [5] the Rights and Definitions of The Way - - --- + There are children¹, invalids¹, and adults². There are dependents, independents, and interdependents + Adulthood, defined by the capacity to survive physically and socially without direct intervention of parents or guardians; claimed by competent³ demonstration of the skills necessary: cooking, first aid, communication, sanitation, skill acquisition, shelter infrastructure maintenance. + Political Adulthood - the capacity to demonstrate self-sufficient interdependency; claimed by demonstration competencies of the body politic: an original, personal Preamble⁵; a hand-written transcription of these Articles⁴; a portfolio of demonstrated skill sets⁶; and a schedule of intended actions⁷. Twelve such are a Political Circle. + + > ¹ dependents. + > ² once adulthood is claimed, all adults are the same legal age, alive now. + > ³ the capacity to reliably perform a skill, practice an art, or otherwise contribute meaningfully to survival and conversation + > ⁴ Hand-writing is the standard, save for cases of prohibitive neurodivergence. + > ⁵ A few sentences that demonstrate a grasp of current political realities. + > ⁶ lineaged by craft masters, doctors, or certifying authorities as appropriate. + > ⁷ Providing points of failure so as to determine character and integrity Call log: - Expect "toHaveText" with timeout 5000ms - waiting for locator('details.canon-unit').fil
await expect(articleFive.locator('a', { hasText: 'Open unit page' })).toBeVisible();
await expect(articleFive.locator('a', { hasText: 'Enter Lab' })).toBeVisible();
await expect(articleFive.locator('a', { hasText: 'Source and provenance' })).toBeVisible();
await expect(page).toHaveURL(/\/way\/$/);
});

test('living narratives keep fiction and adulthood boundaries visible', async ({ page }) => {
await page.goto('/narratives/');
await expect(page.locator('a[href="/narratives/jack-and-diane/"]')).toBeVisible();
Expand Down
Loading