chore(embedded): cut v0.0.17-beta
This commit is contained in:
parent
7fd96c7c78
commit
cf5d7c2ea6
8 changed files with 645 additions and 15 deletions
|
|
@ -628,6 +628,28 @@ body.help-open .app-header {
|
|||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* shared/logo.css — paired with shared/logo.js. The wrapping anchor
|
||||
inherits the logo's box and adds a subtle hover/focus affordance
|
||||
so it reads as clickable without altering the logo's visual weight. */
|
||||
|
||||
.app-header__logo-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius);
|
||||
transition: opacity 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.app-header__logo-link:hover .app-header__logo,
|
||||
.app-header__logo-link:focus-visible .app-header__logo {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.app-header__logo-link:focus-visible {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Archive-specific base overrides
|
||||
Reset, tokens, and font are provided by shared/base.css */
|
||||
|
||||
|
|
@ -2245,7 +2267,7 @@ td[data-field="trackingNumber"] {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Archive</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · snail-candle-citrus</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · locust-boat-sage</span></span>
|
||||
</div>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data">⟳</button>
|
||||
|
|
@ -3369,6 +3391,89 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|||
}
|
||||
})();
|
||||
|
||||
// shared/logo.js — turn the inert <svg class="app-header__logo"> on
|
||||
// every tool's header into a clickable link. The destination is the
|
||||
// nearest "home" the user can sensibly back out to:
|
||||
//
|
||||
// file:// → no wrap (no server home)
|
||||
// http(s)://host/ → wrap, href = /
|
||||
// http(s)://host/<tool>.html (deployment root)→ wrap, href = /
|
||||
// http(s)://host/<project>/... → wrap, href = /<project>
|
||||
//
|
||||
// When inside a project, the logo takes the user to the project
|
||||
// landing (synthetic page with the four lifecycle-stage cards + MDL
|
||||
// instructions). When at the deployment root, the logo points at /
|
||||
// (the project picker). Offline, the logo stays decorative — there's
|
||||
// no real "home" to go to.
|
||||
//
|
||||
// Mounts as a sibling-replacement on DOMContentLoaded: wraps the
|
||||
// existing logo SVG in an <a>, preserving classes and attributes.
|
||||
// Idempotent: re-mounting on an already-wrapped logo is a no-op.
|
||||
//
|
||||
// Tools that want to override (e.g. a deployment that pins logo to
|
||||
// an external URL) can set window.zddc.logo.disabled = true before
|
||||
// DOMContentLoaded and inject their own anchor.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (!window.zddc) window.zddc = {};
|
||||
if (window.zddc.logo) return;
|
||||
|
||||
function projectSegment(pathname) {
|
||||
var parts = pathname.split('/').filter(Boolean);
|
||||
if (parts.length === 0) return null;
|
||||
var first = parts[0];
|
||||
// Tool HTMLs at the deployment root (index.html, archive.html
|
||||
// with ?projects=...) don't carry a project segment.
|
||||
if (first.indexOf('.') !== -1) return null;
|
||||
return first;
|
||||
}
|
||||
|
||||
function targetHref() {
|
||||
if (typeof location === 'undefined') return null;
|
||||
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
|
||||
return null;
|
||||
}
|
||||
if (window.zddc.logo && window.zddc.logo.disabled) return null;
|
||||
var seg = projectSegment(location.pathname);
|
||||
return seg ? '/' + encodeURIComponent(seg) : '/';
|
||||
}
|
||||
|
||||
function mount() {
|
||||
var logo = document.querySelector('.app-header__logo');
|
||||
if (!logo) return;
|
||||
// Already wrapped (template-supplied anchor, or a previous mount).
|
||||
if (logo.parentElement && logo.parentElement.tagName === 'A' &&
|
||||
logo.parentElement.classList.contains('app-header__logo-link')) {
|
||||
return;
|
||||
}
|
||||
var href = targetHref();
|
||||
if (!href) return;
|
||||
var a = document.createElement('a');
|
||||
a.href = href;
|
||||
a.className = 'app-header__logo-link';
|
||||
var label = href === '/' ? 'ZDDC home' : 'Project home';
|
||||
a.title = label;
|
||||
a.setAttribute('aria-label', label);
|
||||
logo.parentNode.insertBefore(a, logo);
|
||||
a.appendChild(logo);
|
||||
}
|
||||
|
||||
window.zddc.logo = {
|
||||
mount: mount,
|
||||
// Test seam.
|
||||
_projectSegment: projectSegment,
|
||||
_targetHref: targetHref,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', mount, { once: true });
|
||||
} else {
|
||||
mount();
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* ZDDC — shared preview helpers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -628,6 +628,28 @@ body.help-open .app-header {
|
|||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* shared/logo.css — paired with shared/logo.js. The wrapping anchor
|
||||
inherits the logo's box and adds a subtle hover/focus affordance
|
||||
so it reads as clickable without altering the logo's visual weight. */
|
||||
|
||||
.app-header__logo-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius);
|
||||
transition: opacity 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.app-header__logo-link:hover .app-header__logo,
|
||||
.app-header__logo-link:focus-visible .app-header__logo {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.app-header__logo-link:focus-visible {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* browse-specific layout on top of shared/base.css */
|
||||
|
||||
html, body {
|
||||
|
|
@ -947,7 +969,7 @@ body {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Browse</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · snail-candle-citrus</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · locust-boat-sage</span></span>
|
||||
</div>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh listing" aria-label="Refresh listing">⟳</button>
|
||||
|
|
@ -1904,6 +1926,89 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|||
}
|
||||
})();
|
||||
|
||||
// shared/logo.js — turn the inert <svg class="app-header__logo"> on
|
||||
// every tool's header into a clickable link. The destination is the
|
||||
// nearest "home" the user can sensibly back out to:
|
||||
//
|
||||
// file:// → no wrap (no server home)
|
||||
// http(s)://host/ → wrap, href = /
|
||||
// http(s)://host/<tool>.html (deployment root)→ wrap, href = /
|
||||
// http(s)://host/<project>/... → wrap, href = /<project>
|
||||
//
|
||||
// When inside a project, the logo takes the user to the project
|
||||
// landing (synthetic page with the four lifecycle-stage cards + MDL
|
||||
// instructions). When at the deployment root, the logo points at /
|
||||
// (the project picker). Offline, the logo stays decorative — there's
|
||||
// no real "home" to go to.
|
||||
//
|
||||
// Mounts as a sibling-replacement on DOMContentLoaded: wraps the
|
||||
// existing logo SVG in an <a>, preserving classes and attributes.
|
||||
// Idempotent: re-mounting on an already-wrapped logo is a no-op.
|
||||
//
|
||||
// Tools that want to override (e.g. a deployment that pins logo to
|
||||
// an external URL) can set window.zddc.logo.disabled = true before
|
||||
// DOMContentLoaded and inject their own anchor.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (!window.zddc) window.zddc = {};
|
||||
if (window.zddc.logo) return;
|
||||
|
||||
function projectSegment(pathname) {
|
||||
var parts = pathname.split('/').filter(Boolean);
|
||||
if (parts.length === 0) return null;
|
||||
var first = parts[0];
|
||||
// Tool HTMLs at the deployment root (index.html, archive.html
|
||||
// with ?projects=...) don't carry a project segment.
|
||||
if (first.indexOf('.') !== -1) return null;
|
||||
return first;
|
||||
}
|
||||
|
||||
function targetHref() {
|
||||
if (typeof location === 'undefined') return null;
|
||||
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
|
||||
return null;
|
||||
}
|
||||
if (window.zddc.logo && window.zddc.logo.disabled) return null;
|
||||
var seg = projectSegment(location.pathname);
|
||||
return seg ? '/' + encodeURIComponent(seg) : '/';
|
||||
}
|
||||
|
||||
function mount() {
|
||||
var logo = document.querySelector('.app-header__logo');
|
||||
if (!logo) return;
|
||||
// Already wrapped (template-supplied anchor, or a previous mount).
|
||||
if (logo.parentElement && logo.parentElement.tagName === 'A' &&
|
||||
logo.parentElement.classList.contains('app-header__logo-link')) {
|
||||
return;
|
||||
}
|
||||
var href = targetHref();
|
||||
if (!href) return;
|
||||
var a = document.createElement('a');
|
||||
a.href = href;
|
||||
a.className = 'app-header__logo-link';
|
||||
var label = href === '/' ? 'ZDDC home' : 'Project home';
|
||||
a.title = label;
|
||||
a.setAttribute('aria-label', label);
|
||||
logo.parentNode.insertBefore(a, logo);
|
||||
a.appendChild(logo);
|
||||
}
|
||||
|
||||
window.zddc.logo = {
|
||||
mount: mount,
|
||||
// Test seam.
|
||||
_projectSegment: projectSegment,
|
||||
_targetHref: targetHref,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', mount, { once: true });
|
||||
} else {
|
||||
mount();
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* ZDDC shared help panel — open/close logic.
|
||||
* Works with all four tools regardless of their module pattern.
|
||||
|
|
|
|||
|
|
@ -628,6 +628,28 @@ body.help-open .app-header {
|
|||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* shared/logo.css — paired with shared/logo.js. The wrapping anchor
|
||||
inherits the logo's box and adds a subtle hover/focus affordance
|
||||
so it reads as clickable without altering the logo's visual weight. */
|
||||
|
||||
.app-header__logo-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius);
|
||||
transition: opacity 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.app-header__logo-link:hover .app-header__logo,
|
||||
.app-header__logo-link:focus-visible .app-header__logo {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.app-header__logo-link:focus-visible {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Classifier-specific base overrides
|
||||
Reset, tokens, buttons, and font are provided by shared/base.css */
|
||||
|
||||
|
|
@ -1464,7 +1486,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Classifier</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · snail-candle-citrus</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · locust-boat-sage</span></span>
|
||||
</div>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory" aria-label="Refresh" style="font-size:1.1rem;">⟳</button>
|
||||
|
|
@ -2855,6 +2877,89 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|||
}
|
||||
})();
|
||||
|
||||
// shared/logo.js — turn the inert <svg class="app-header__logo"> on
|
||||
// every tool's header into a clickable link. The destination is the
|
||||
// nearest "home" the user can sensibly back out to:
|
||||
//
|
||||
// file:// → no wrap (no server home)
|
||||
// http(s)://host/ → wrap, href = /
|
||||
// http(s)://host/<tool>.html (deployment root)→ wrap, href = /
|
||||
// http(s)://host/<project>/... → wrap, href = /<project>
|
||||
//
|
||||
// When inside a project, the logo takes the user to the project
|
||||
// landing (synthetic page with the four lifecycle-stage cards + MDL
|
||||
// instructions). When at the deployment root, the logo points at /
|
||||
// (the project picker). Offline, the logo stays decorative — there's
|
||||
// no real "home" to go to.
|
||||
//
|
||||
// Mounts as a sibling-replacement on DOMContentLoaded: wraps the
|
||||
// existing logo SVG in an <a>, preserving classes and attributes.
|
||||
// Idempotent: re-mounting on an already-wrapped logo is a no-op.
|
||||
//
|
||||
// Tools that want to override (e.g. a deployment that pins logo to
|
||||
// an external URL) can set window.zddc.logo.disabled = true before
|
||||
// DOMContentLoaded and inject their own anchor.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (!window.zddc) window.zddc = {};
|
||||
if (window.zddc.logo) return;
|
||||
|
||||
function projectSegment(pathname) {
|
||||
var parts = pathname.split('/').filter(Boolean);
|
||||
if (parts.length === 0) return null;
|
||||
var first = parts[0];
|
||||
// Tool HTMLs at the deployment root (index.html, archive.html
|
||||
// with ?projects=...) don't carry a project segment.
|
||||
if (first.indexOf('.') !== -1) return null;
|
||||
return first;
|
||||
}
|
||||
|
||||
function targetHref() {
|
||||
if (typeof location === 'undefined') return null;
|
||||
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
|
||||
return null;
|
||||
}
|
||||
if (window.zddc.logo && window.zddc.logo.disabled) return null;
|
||||
var seg = projectSegment(location.pathname);
|
||||
return seg ? '/' + encodeURIComponent(seg) : '/';
|
||||
}
|
||||
|
||||
function mount() {
|
||||
var logo = document.querySelector('.app-header__logo');
|
||||
if (!logo) return;
|
||||
// Already wrapped (template-supplied anchor, or a previous mount).
|
||||
if (logo.parentElement && logo.parentElement.tagName === 'A' &&
|
||||
logo.parentElement.classList.contains('app-header__logo-link')) {
|
||||
return;
|
||||
}
|
||||
var href = targetHref();
|
||||
if (!href) return;
|
||||
var a = document.createElement('a');
|
||||
a.href = href;
|
||||
a.className = 'app-header__logo-link';
|
||||
var label = href === '/' ? 'ZDDC home' : 'Project home';
|
||||
a.title = label;
|
||||
a.setAttribute('aria-label', label);
|
||||
logo.parentNode.insertBefore(a, logo);
|
||||
a.appendChild(logo);
|
||||
}
|
||||
|
||||
window.zddc.logo = {
|
||||
mount: mount,
|
||||
// Test seam.
|
||||
_projectSegment: projectSegment,
|
||||
_targetHref: targetHref,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', mount, { once: true });
|
||||
} else {
|
||||
mount();
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* ZDDC — shared preview helpers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -628,6 +628,28 @@ body.help-open .app-header {
|
|||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* shared/logo.css — paired with shared/logo.js. The wrapping anchor
|
||||
inherits the logo's box and adds a subtle hover/focus affordance
|
||||
so it reads as clickable without altering the logo's visual weight. */
|
||||
|
||||
.app-header__logo-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius);
|
||||
transition: opacity 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.app-header__logo-link:hover .app-header__logo,
|
||||
.app-header__logo-link:focus-visible .app-header__logo {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.app-header__logo-link:focus-visible {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Landing page layout */
|
||||
body {
|
||||
margin: 0;
|
||||
|
|
@ -988,7 +1010,7 @@ body {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · snail-candle-citrus</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · locust-boat-sage</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
|
|
@ -1941,6 +1963,89 @@ body {
|
|||
}
|
||||
})();
|
||||
|
||||
// shared/logo.js — turn the inert <svg class="app-header__logo"> on
|
||||
// every tool's header into a clickable link. The destination is the
|
||||
// nearest "home" the user can sensibly back out to:
|
||||
//
|
||||
// file:// → no wrap (no server home)
|
||||
// http(s)://host/ → wrap, href = /
|
||||
// http(s)://host/<tool>.html (deployment root)→ wrap, href = /
|
||||
// http(s)://host/<project>/... → wrap, href = /<project>
|
||||
//
|
||||
// When inside a project, the logo takes the user to the project
|
||||
// landing (synthetic page with the four lifecycle-stage cards + MDL
|
||||
// instructions). When at the deployment root, the logo points at /
|
||||
// (the project picker). Offline, the logo stays decorative — there's
|
||||
// no real "home" to go to.
|
||||
//
|
||||
// Mounts as a sibling-replacement on DOMContentLoaded: wraps the
|
||||
// existing logo SVG in an <a>, preserving classes and attributes.
|
||||
// Idempotent: re-mounting on an already-wrapped logo is a no-op.
|
||||
//
|
||||
// Tools that want to override (e.g. a deployment that pins logo to
|
||||
// an external URL) can set window.zddc.logo.disabled = true before
|
||||
// DOMContentLoaded and inject their own anchor.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (!window.zddc) window.zddc = {};
|
||||
if (window.zddc.logo) return;
|
||||
|
||||
function projectSegment(pathname) {
|
||||
var parts = pathname.split('/').filter(Boolean);
|
||||
if (parts.length === 0) return null;
|
||||
var first = parts[0];
|
||||
// Tool HTMLs at the deployment root (index.html, archive.html
|
||||
// with ?projects=...) don't carry a project segment.
|
||||
if (first.indexOf('.') !== -1) return null;
|
||||
return first;
|
||||
}
|
||||
|
||||
function targetHref() {
|
||||
if (typeof location === 'undefined') return null;
|
||||
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
|
||||
return null;
|
||||
}
|
||||
if (window.zddc.logo && window.zddc.logo.disabled) return null;
|
||||
var seg = projectSegment(location.pathname);
|
||||
return seg ? '/' + encodeURIComponent(seg) : '/';
|
||||
}
|
||||
|
||||
function mount() {
|
||||
var logo = document.querySelector('.app-header__logo');
|
||||
if (!logo) return;
|
||||
// Already wrapped (template-supplied anchor, or a previous mount).
|
||||
if (logo.parentElement && logo.parentElement.tagName === 'A' &&
|
||||
logo.parentElement.classList.contains('app-header__logo-link')) {
|
||||
return;
|
||||
}
|
||||
var href = targetHref();
|
||||
if (!href) return;
|
||||
var a = document.createElement('a');
|
||||
a.href = href;
|
||||
a.className = 'app-header__logo-link';
|
||||
var label = href === '/' ? 'ZDDC home' : 'Project home';
|
||||
a.title = label;
|
||||
a.setAttribute('aria-label', label);
|
||||
logo.parentNode.insertBefore(a, logo);
|
||||
a.appendChild(logo);
|
||||
}
|
||||
|
||||
window.zddc.logo = {
|
||||
mount: mount,
|
||||
// Test seam.
|
||||
_projectSegment: projectSegment,
|
||||
_targetHref: targetHref,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', mount, { once: true });
|
||||
} else {
|
||||
mount();
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* ZDDC shared help panel — open/close logic.
|
||||
* Works with all four tools regardless of their module pattern.
|
||||
|
|
|
|||
|
|
@ -848,6 +848,28 @@ body.help-open .app-header {
|
|||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* shared/logo.css — paired with shared/logo.js. The wrapping anchor
|
||||
inherits the logo's box and adds a subtle hover/focus affordance
|
||||
so it reads as clickable without altering the logo's visual weight. */
|
||||
|
||||
.app-header__logo-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius);
|
||||
transition: opacity 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.app-header__logo-link:hover .app-header__logo,
|
||||
.app-header__logo-link:focus-visible .app-header__logo {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.app-header__logo-link:focus-visible {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* mdedit component styles — reset and tokens from shared/base.css */
|
||||
|
||||
/* Pane resizer */
|
||||
|
|
@ -1903,7 +1925,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Markdown</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · snail-candle-citrus</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · locust-boat-sage</span></span>
|
||||
</div>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary" title="Add a local directory">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh directory" aria-label="Refresh">⟳</button>
|
||||
|
|
@ -3094,6 +3116,89 @@ body.help-open .app-header {
|
|||
}
|
||||
})();
|
||||
|
||||
// shared/logo.js — turn the inert <svg class="app-header__logo"> on
|
||||
// every tool's header into a clickable link. The destination is the
|
||||
// nearest "home" the user can sensibly back out to:
|
||||
//
|
||||
// file:// → no wrap (no server home)
|
||||
// http(s)://host/ → wrap, href = /
|
||||
// http(s)://host/<tool>.html (deployment root)→ wrap, href = /
|
||||
// http(s)://host/<project>/... → wrap, href = /<project>
|
||||
//
|
||||
// When inside a project, the logo takes the user to the project
|
||||
// landing (synthetic page with the four lifecycle-stage cards + MDL
|
||||
// instructions). When at the deployment root, the logo points at /
|
||||
// (the project picker). Offline, the logo stays decorative — there's
|
||||
// no real "home" to go to.
|
||||
//
|
||||
// Mounts as a sibling-replacement on DOMContentLoaded: wraps the
|
||||
// existing logo SVG in an <a>, preserving classes and attributes.
|
||||
// Idempotent: re-mounting on an already-wrapped logo is a no-op.
|
||||
//
|
||||
// Tools that want to override (e.g. a deployment that pins logo to
|
||||
// an external URL) can set window.zddc.logo.disabled = true before
|
||||
// DOMContentLoaded and inject their own anchor.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (!window.zddc) window.zddc = {};
|
||||
if (window.zddc.logo) return;
|
||||
|
||||
function projectSegment(pathname) {
|
||||
var parts = pathname.split('/').filter(Boolean);
|
||||
if (parts.length === 0) return null;
|
||||
var first = parts[0];
|
||||
// Tool HTMLs at the deployment root (index.html, archive.html
|
||||
// with ?projects=...) don't carry a project segment.
|
||||
if (first.indexOf('.') !== -1) return null;
|
||||
return first;
|
||||
}
|
||||
|
||||
function targetHref() {
|
||||
if (typeof location === 'undefined') return null;
|
||||
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
|
||||
return null;
|
||||
}
|
||||
if (window.zddc.logo && window.zddc.logo.disabled) return null;
|
||||
var seg = projectSegment(location.pathname);
|
||||
return seg ? '/' + encodeURIComponent(seg) : '/';
|
||||
}
|
||||
|
||||
function mount() {
|
||||
var logo = document.querySelector('.app-header__logo');
|
||||
if (!logo) return;
|
||||
// Already wrapped (template-supplied anchor, or a previous mount).
|
||||
if (logo.parentElement && logo.parentElement.tagName === 'A' &&
|
||||
logo.parentElement.classList.contains('app-header__logo-link')) {
|
||||
return;
|
||||
}
|
||||
var href = targetHref();
|
||||
if (!href) return;
|
||||
var a = document.createElement('a');
|
||||
a.href = href;
|
||||
a.className = 'app-header__logo-link';
|
||||
var label = href === '/' ? 'ZDDC home' : 'Project home';
|
||||
a.title = label;
|
||||
a.setAttribute('aria-label', label);
|
||||
logo.parentNode.insertBefore(a, logo);
|
||||
a.appendChild(logo);
|
||||
}
|
||||
|
||||
window.zddc.logo = {
|
||||
mount: mount,
|
||||
// Test seam.
|
||||
_projectSegment: projectSegment,
|
||||
_targetHref: targetHref,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', mount, { once: true });
|
||||
} else {
|
||||
mount();
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* ZDDC — shared preview helpers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -632,6 +632,28 @@ body.help-open .app-header {
|
|||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* shared/logo.css — paired with shared/logo.js. The wrapping anchor
|
||||
inherits the logo's box and adds a subtle hover/focus affordance
|
||||
so it reads as clickable without altering the logo's visual weight. */
|
||||
|
||||
.app-header__logo-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius);
|
||||
transition: opacity 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.app-header__logo-link:hover .app-header__logo,
|
||||
.app-header__logo-link:focus-visible .app-header__logo {
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.app-header__logo-link:focus-visible {
|
||||
outline: 2px solid var(--primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Placeholder for contenteditable elements */
|
||||
[data-placeholder]:empty::before {
|
||||
content: attr(data-placeholder);
|
||||
|
|
@ -2263,7 +2285,7 @@ dialog.modal--narrow {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Transmittal</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · snail-candle-citrus</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · locust-boat-sage</span></span>
|
||||
</div>
|
||||
<span id="no-js-notice" class="text-gray-400 text-xs italic">JavaScript not available</span>
|
||||
<!-- Publish split-button (Transmittal-specific primary action;
|
||||
|
|
@ -3874,6 +3896,89 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|||
}
|
||||
})();
|
||||
|
||||
// shared/logo.js — turn the inert <svg class="app-header__logo"> on
|
||||
// every tool's header into a clickable link. The destination is the
|
||||
// nearest "home" the user can sensibly back out to:
|
||||
//
|
||||
// file:// → no wrap (no server home)
|
||||
// http(s)://host/ → wrap, href = /
|
||||
// http(s)://host/<tool>.html (deployment root)→ wrap, href = /
|
||||
// http(s)://host/<project>/... → wrap, href = /<project>
|
||||
//
|
||||
// When inside a project, the logo takes the user to the project
|
||||
// landing (synthetic page with the four lifecycle-stage cards + MDL
|
||||
// instructions). When at the deployment root, the logo points at /
|
||||
// (the project picker). Offline, the logo stays decorative — there's
|
||||
// no real "home" to go to.
|
||||
//
|
||||
// Mounts as a sibling-replacement on DOMContentLoaded: wraps the
|
||||
// existing logo SVG in an <a>, preserving classes and attributes.
|
||||
// Idempotent: re-mounting on an already-wrapped logo is a no-op.
|
||||
//
|
||||
// Tools that want to override (e.g. a deployment that pins logo to
|
||||
// an external URL) can set window.zddc.logo.disabled = true before
|
||||
// DOMContentLoaded and inject their own anchor.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (!window.zddc) window.zddc = {};
|
||||
if (window.zddc.logo) return;
|
||||
|
||||
function projectSegment(pathname) {
|
||||
var parts = pathname.split('/').filter(Boolean);
|
||||
if (parts.length === 0) return null;
|
||||
var first = parts[0];
|
||||
// Tool HTMLs at the deployment root (index.html, archive.html
|
||||
// with ?projects=...) don't carry a project segment.
|
||||
if (first.indexOf('.') !== -1) return null;
|
||||
return first;
|
||||
}
|
||||
|
||||
function targetHref() {
|
||||
if (typeof location === 'undefined') return null;
|
||||
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
|
||||
return null;
|
||||
}
|
||||
if (window.zddc.logo && window.zddc.logo.disabled) return null;
|
||||
var seg = projectSegment(location.pathname);
|
||||
return seg ? '/' + encodeURIComponent(seg) : '/';
|
||||
}
|
||||
|
||||
function mount() {
|
||||
var logo = document.querySelector('.app-header__logo');
|
||||
if (!logo) return;
|
||||
// Already wrapped (template-supplied anchor, or a previous mount).
|
||||
if (logo.parentElement && logo.parentElement.tagName === 'A' &&
|
||||
logo.parentElement.classList.contains('app-header__logo-link')) {
|
||||
return;
|
||||
}
|
||||
var href = targetHref();
|
||||
if (!href) return;
|
||||
var a = document.createElement('a');
|
||||
a.href = href;
|
||||
a.className = 'app-header__logo-link';
|
||||
var label = href === '/' ? 'ZDDC home' : 'Project home';
|
||||
a.title = label;
|
||||
a.setAttribute('aria-label', label);
|
||||
logo.parentNode.insertBefore(a, logo);
|
||||
a.appendChild(logo);
|
||||
}
|
||||
|
||||
window.zddc.logo = {
|
||||
mount: mount,
|
||||
// Test seam.
|
||||
_projectSegment: projectSegment,
|
||||
_targetHref: targetHref,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', mount, { once: true });
|
||||
} else {
|
||||
mount();
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* ZDDC — shared preview helpers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# Generated by build.sh — do not edit. One <app>=<build label> per line.
|
||||
archive=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
transmittal=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
classifier=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
mdedit=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
landing=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
form=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
tables=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
browse=v0.0.17-beta · 2026-05-10 · snail-candle-citrus
|
||||
archive=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
transmittal=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
classifier=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
mdedit=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
landing=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
form=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
tables=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
browse=v0.0.17-beta · 2026-05-10 · locust-boat-sage
|
||||
|
|
|
|||
|
|
@ -1092,7 +1092,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title" id="table-title">ZDDC Table</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-alpha · 2026-05-10 12:33:10 · 837cf47-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.17-beta · 2026-05-10 · locust-boat-sage</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
|
|
|
|||
Loading…
Reference in a new issue