diff --git a/NOTICE.md b/NOTICE.md index 75ea700..210f095 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -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. diff --git a/tests/test_branding.py b/tests/test_branding.py new file mode 100644 index 0000000..51e47e8 --- /dev/null +++ b/tests/test_branding.py @@ -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')) diff --git a/web/static/BRAND-NOTICE.txt b/web/static/BRAND-NOTICE.txt index 07b6683..d264d29 100644 --- a/web/static/BRAND-NOTICE.txt +++ b/web/static/BRAND-NOTICE.txt @@ -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 diff --git a/web/static/wordmark.css b/web/static/wordmark.css new file mode 100644 index 0000000..80f6ae7 --- /dev/null +++ b/web/static/wordmark.css @@ -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; +} diff --git a/web/static/wordmark.webp b/web/static/wordmark.webp deleted file mode 100644 index d96dd18..0000000 Binary files a/web/static/wordmark.webp and /dev/null differ diff --git a/web/static/wordmark/development.webp b/web/static/wordmark/development.webp new file mode 100644 index 0000000..df38c23 Binary files /dev/null and b/web/static/wordmark/development.webp differ diff --git a/web/static/wordmark/h.webp b/web/static/wordmark/h.webp new file mode 100644 index 0000000..93eb0b1 Binary files /dev/null and b/web/static/wordmark/h.webp differ diff --git a/web/static/wordmark/r.webp b/web/static/wordmark/r.webp new file mode 100644 index 0000000..5a16fe5 Binary files /dev/null and b/web/static/wordmark/r.webp differ diff --git a/web/static/wordmark/vast.webp b/web/static/wordmark/vast.webp new file mode 100644 index 0000000..b00f686 Binary files /dev/null and b/web/static/wordmark/vast.webp differ diff --git a/web/static/wordmark/y.webp b/web/static/wordmark/y.webp new file mode 100644 index 0000000..7c64cc2 Binary files /dev/null and b/web/static/wordmark/y.webp differ diff --git a/web/templates/page.html b/web/templates/page.html index b285ba5..3ead0f9 100644 --- a/web/templates/page.html +++ b/web/templates/page.html @@ -22,6 +22,7 @@ window.MathJax = {tex:{inlineMath:[['\\(','\\)']],displayMath:[['$$','$$']],processEscapes:true},svg:{fontCache:'global'},options:{skipHtmlTags:['script','noscript','style','textarea','pre','code']}}; + @@ -50,7 +51,25 @@
{{ article.meta.section }}{{ minutes }} min read ยท Edition {{ config.version }}
- {% if article.path == 'index.md' %}
Vast Development MethodTHEORY
{% endif %} + {% if article.path == 'index.md' %}
+ +Vast Development Method Theory + + + + + + + + + + + + + + + +
{% endif %}
Read MarkdownDownload MarkdownSource
{{ article.rendered|safe }}
Evidence profile{{ article.meta.evidence }}How to read a claim