Skip to content
Closed
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: 1 addition & 1 deletion NOTICE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ The built website uses MathJax 3.2.2 (Apache-2.0) for SVG mathematical typesetti

Python build dependencies retain their own licenses: Mistune (BSD-3-Clause), Jinja2 (BSD-3-Clause), PyYAML (MIT), Pillow (HPND), Beautiful Soup (MIT), and Playwright (Apache-2.0). They are development/build dependencies, not copies of the theory.

The VDM wordmark is a resized derivative of the author-supplied branding. The small mark and favicon use official VDM branding: the build requests https://www.vdm.io/VDM.png first and can use the official organization's GitHub avatar if that endpoint rejects acquisition. The selected source and digest are recorded, not silently substituted. Brand assets are excluded from the prose and code licenses; no trademark or endorsement rights are granted.
The VDM Theory wordmark isolates the original blue lettering from the author-supplied branding, removes the mosaic background, and adds matching THEORY lettering on the same baseline. The asset uses source glyph construction, not a separately distributed font. The small mark and favicon use official VDM branding: the build requests https://www.vdm.io/VDM.png first and can use the official organization's GitHub avatar if that endpoint rejects acquisition. The selected source and digest are recorded, not silently substituted. Brand assets are excluded from the prose and code licenses; no trademark or endorsement rights are granted.
53 changes: 53 additions & 0 deletions tests/test_branding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Source-derived wordmark transparency and responsive placement contracts. MIT."""
from pathlib import Path
import unittest
from bs4 import BeautifulSoup
from PIL import Image

ROOT = Path(__file__).resolve().parents[1]


class WordmarkTests(unittest.TestCase):
def test_all_lettering_assets_have_transparent_margins(self):
paths = sorted((ROOT / 'web/static/wordmark').glob('*.webp'))
self.assertEqual(len(paths), 5)
for path in paths:
with self.subTest(asset=path.name), Image.open(path) as image:
self.assertEqual(image.height, 80)
alpha = image.convert('RGBA').getchannel('A')
self.assertEqual(alpha.getextrema()[0], 0)
self.assertGreaterEqual(alpha.getextrema()[1], 250)
self.assertIsNone(alpha.crop((0, 0, image.width, 8)).getbbox())
self.assertIsNone(alpha.crop((0, 72, image.width, 80)).getbbox())

def test_wordmark_has_one_accessible_label_and_no_caption(self):
soup = BeautifulSoup((ROOT / 'web/templates/page.html').read_text(), 'html.parser')
wordmark = soup.select_one('.wordmark')
self.assertIsNotNone(wordmark)
root = wordmark.find('svg', recursive=False)
self.assertIsNotNone(root)
self.assertEqual(root.get('role'), 'img')
self.assertEqual(root.find('title').text, 'Vast Development Method Theory')
self.assertIsNone(wordmark.find('span'))
self.assertEqual(root.get('viewbox'), '0 0 1200 80')

def test_all_svg_image_references_exist(self):
soup = BeautifulSoup((ROOT / 'web/templates/page.html').read_text(), 'html.parser')
for image in soup.select('.wordmark image'):
href = image.get('href', '')
self.assertTrue(href.startswith('/assets/wordmark/'))
self.assertTrue((ROOT / 'web/static' / href.removeprefix('/assets/')).is_file())

def test_glyphs_share_one_baseline(self):
soup = BeautifulSoup((ROOT / 'web/templates/page.html').read_text(), 'html.parser')
for image in soup.select('.wordmark image'):
self.assertEqual(image.get('height'), '80')
self.assertIn(image.get('y'), (None, '0'))

def test_wordmark_styles_are_scoped_and_loaded_after_the_theme(self):
css = (ROOT / 'web/static/wordmark.css').read_text()
for declaration in ('width: 100%', 'max-width: none', 'background: transparent', 'border: 0', 'padding: 0'):
self.assertIn(declaration, css)
soup = BeautifulSoup((ROOT / 'web/templates/page.html').read_text(), 'html.parser')
sheets = [node.get('href') for node in soup.select('link[rel="stylesheet"]')]
self.assertGreater(sheets.index('/assets/wordmark.css'), sheets.index('/assets/site.css'))
8 changes: 6 additions & 2 deletions web/static/BRAND-NOTICE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
VDM branding identifies this official Vast Development Method publication.
wordmark.webp is a resized derivative of vast_development_method.jpg supplied
by the publication's originator.
The wordmark/ assets isolate blue lettering from the originator-supplied
vast_development_method.jpg. The homepage composes them into one accessible,
transparent, single-line SVG wordmark: VAST DEVELOPMENT METHOD THEORY.
Existing letter shapes are reused; the R and Y extend the source construction.
There is no separately loaded font, no mosaic backdrop, and no detached caption.
The SVG is a layout for raster lettering; it is not represented as a vector font.

The small mark and favicon are derived from official VDM branding. The build
first requests https://www.vdm.io/VDM.png. When that endpoint rejects automated
Expand Down
16 changes: 16 additions & 0 deletions web/static/wordmark.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* Source-lettering wordmark only; the publication theme is unchanged. */
.wordmark {
display: block;
width: 100%;
max-width: none;
margin: 4px 0 28px;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
}
.wordmark > svg {
display: block;
width: 100%;
height: auto;
}
Binary file removed web/static/wordmark.webp
Binary file not shown.
Binary file added web/static/wordmark/development.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/static/wordmark/h.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/static/wordmark/r.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/static/wordmark/vast.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/static/wordmark/y.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 20 additions & 1 deletion web/templates/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
window.MathJax = {tex:{inlineMath:[['\\(','\\)']],displayMath:[['$$','$$']],processEscapes:true},svg:{fontCache:'global'},options:{skipHtmlTags:['script','noscript','style','textarea','pre','code']}};
</script>
<link rel="stylesheet" href="/assets/site.css">
<link rel="stylesheet" href="/assets/wordmark.css">
<script defer src="/assets/vendor/mathjax/tex-svg.js"></script>
<script type="module" src="/assets/site.js"></script>
</head>
Expand Down Expand Up @@ -50,7 +51,25 @@
</aside>
<main id="main" tabindex="-1">
<div class="article-meta"><span class="eyebrow">{{ article.meta.section }}</span><span>{{ minutes }} min read · Edition {{ config.version }}</span></div>
{% if article.path == 'index.md' %}<div class="wordmark"><img src="/assets/wordmark.webp" width="440" height="112" alt="Vast Development Method"><span>THEORY</span></div>{% endif %}
{% if article.path == 'index.md' %}<div class="wordmark">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 80" width="1200" height="80" role="img" aria-labelledby="vdmt-wordmark-title">
<title id="vdmt-wordmark-title">Vast Development Method Theory</title>
<image href="/assets/wordmark/vast.webp" x="0" y="0" width="172" height="80"/>
<image href="/assets/wordmark/development.webp" x="172" y="0" width="469" height="80"/>
<svg x="649" y="0" width="59" height="80" viewBox="291 0 59 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<svg x="709" y="0" width="36" height="80" viewBox="132 0 36 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<svg x="746" y="0" width="35" height="80" viewBox="428 0 35 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<image href="/assets/wordmark/h.webp" x="781" y="0" width="40" height="80"/>
<svg x="821" y="0" width="48" height="80" viewBox="201 0 48 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<svg x="873" y="0" width="42" height="80" viewBox="8 0 42 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<svg x="932" y="0" width="35" height="80" viewBox="428 0 35 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<image href="/assets/wordmark/h.webp" x="969" y="0" width="40" height="80"/>
<svg x="1011" y="0" width="36" height="80" viewBox="132 0 36 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<svg x="1049" y="0" width="48" height="80" viewBox="201 0 48 80"><image href="/assets/wordmark/development.webp" width="469" height="80"/></svg>
<image href="/assets/wordmark/r.webp" x="1099" y="0" width="45" height="80"/>
<image href="/assets/wordmark/y.webp" x="1146" y="0" width="46" height="80"/>
</svg>
</div>{% endif %}
<div class="article-tools" aria-label="Article formats and sharing"><a href="{{ markdown_url }}">Read Markdown</a><a href="{{ markdown_url }}" download>Download Markdown</a><button type="button" data-copy="{{ canonical }}">Copy link</button><button type="button" data-copy="{{ citation }}">Cite</button><a href="{{ source_url }}">Source</a></div>
<article class="prose">{{ article.rendered|safe }}</article>
<div class="evidence-note"><span>Evidence profile</span><strong>{{ article.meta.evidence }}</strong><a href="/foundations/epistemic-status/">How to read a claim</a></div>
Expand Down