|
@@ -67,67 +67,17 @@
|
|
|
if (document.visibilityState === 'visible') refreshGoal('focus');
|
|
if (document.visibilityState === 'visible') refreshGoal('focus');
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // Goal 41 T6 (bet 2): the anchor sub-nav. Statum re-renders
|
|
|
|
|
- // replace the DOM, so the listener binds ONCE on document
|
|
|
|
|
- // and the highlight pass re-runs after every evaluate -
|
|
|
|
|
- // the same rebound pattern as the filter strip (the
|
|
|
|
|
- // seals survive because nothing page-scoped is captured).
|
|
|
|
|
- var SUBNAV = 'goal-subnav';
|
|
|
|
|
- var SECTIONS = 'goal-section';
|
|
|
|
|
-
|
|
|
|
|
- function goalHighlightSubnav() {
|
|
|
|
|
- var nav = document.getElementsByClassName(SUBNAV)[0];
|
|
|
|
|
- if (!nav) return;
|
|
|
|
|
- var links = nav.querySelectorAll('a[href^="#"]');
|
|
|
|
|
- var sections = document.getElementsByClassName(SECTIONS);
|
|
|
|
|
- if (!links.length || !sections.length) return;
|
|
|
|
|
- // Two columns share the viewport, so "the last section
|
|
|
|
|
- // that crossed the line" (the single-column rule) can
|
|
|
|
|
- // pick a consult-column card while the reader looks at
|
|
|
|
|
- // an act-column one. The section whose top sits
|
|
|
|
|
- // CLOSEST to the nav's bottom edge (just below it)
|
|
|
|
|
- // is the one the reader entered; ties go to the later
|
|
|
|
|
- // DOM node (the deeper scroll).
|
|
|
|
|
- var mark = nav.getBoundingClientRect().bottom + 24;
|
|
|
|
|
- var current = null;
|
|
|
|
|
- var best = Infinity;
|
|
|
|
|
- for (var i = 0; i < sections.length; i++) {
|
|
|
|
|
- var distance = sections[i].getBoundingClientRect().top - mark;
|
|
|
|
|
- if (distance > 0) continue; // still below the fold line
|
|
|
|
|
- if (-distance <= best) {
|
|
|
|
|
- best = -distance;
|
|
|
|
|
- current = sections[i].id;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- for (var j = 0; j < links.length; j++) {
|
|
|
|
|
- var active = links[j].getAttribute('href') === '#' + current;
|
|
|
|
|
- links[j].classList.toggle('active', active);
|
|
|
|
|
- if (active) links[j].setAttribute('aria-current', 'true');
|
|
|
|
|
- else links[j].removeAttribute('aria-current');
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // Goal 41 T6 shipped this page's sub-nav highlight inline
|
|
|
|
|
+ // (closest-to-fold - the two-column grid made the
|
|
|
|
|
+ // single-column observer rule light the wrong card); T11
|
|
|
|
|
+ // unified it with the task page's chassis into app.js's
|
|
|
|
|
+ // shared initSubnav engine, which keeps this page's
|
|
|
|
|
+ // selection rule for BOTH pages. The strip carries
|
|
|
|
|
+ // data-subnav; sections carry id + data-subnav-section.
|
|
|
|
|
+ if (window.initSubnav) {
|
|
|
|
|
+ window.initSubnav();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- document.addEventListener('click', function (event) {
|
|
|
|
|
- var link = event.target.closest
|
|
|
|
|
- && event.target.closest('.' + SUBNAV + ' a[href^="#"]');
|
|
|
|
|
- if (!link) return;
|
|
|
|
|
- var target = document.getElementById(
|
|
|
|
|
- link.getAttribute('href').slice(1));
|
|
|
|
|
- if (!target) return;
|
|
|
|
|
- event.preventDefault();
|
|
|
|
|
- target.scrollIntoView();
|
|
|
|
|
- // scrollIntoView respects the sticky nav only through
|
|
|
|
|
- // scroll-margin-top (app.css); the highlight lands on
|
|
|
|
|
- // the raf after the scroll settles.
|
|
|
|
|
- requestAnimationFrame(goalHighlightSubnav);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- window.addEventListener('scroll', goalHighlightSubnav,
|
|
|
|
|
- { passive: true });
|
|
|
|
|
- window.addEventListener('resize', goalHighlightSubnav,
|
|
|
|
|
- { passive: true });
|
|
|
|
|
- statum.afterEvaluate(goalHighlightSubnav);
|
|
|
|
|
-
|
|
|
|
|
if (window.initQuoteComments) {
|
|
if (window.initQuoteComments) {
|
|
|
window.initQuoteComments({
|
|
window.initQuoteComments({
|
|
|
matches: function (node) {
|
|
matches: function (node) {
|
|
@@ -253,7 +203,7 @@
|
|
|
Sticky under the topbar (app.css reads its height);
|
|
Sticky under the topbar (app.css reads its height);
|
|
|
the highlight listener lives in the page script
|
|
the highlight listener lives in the page script
|
|
|
(rebound through statum.afterEvaluate). -->
|
|
(rebound through statum.afterEvaluate). -->
|
|
|
- <nav class="goal-subnav" aria-label="Sections" data-goal-subnav>
|
|
|
|
|
|
|
+ <nav class="subnav" aria-label="Sections" data-subnav>
|
|
|
<a href="#goal-sec-status">Status</a>
|
|
<a href="#goal-sec-status">Status</a>
|
|
|
<a href="#goal-sec-blocks">Blocks</a>
|
|
<a href="#goal-sec-blocks">Blocks</a>
|
|
|
<a href="#goal-sec-plan">Plan</a>
|
|
<a href="#goal-sec-plan">Plan</a>
|
|
@@ -271,7 +221,7 @@
|
|
|
reviews lead (actions surface), then state, blocks,
|
|
reviews lead (actions surface), then state, blocks,
|
|
|
plan, comments. CONSULT carries the reference
|
|
plan, comments. CONSULT carries the reference
|
|
|
surfaces the reader jumps to. -->
|
|
surfaces the reader jumps to. -->
|
|
|
- <div class="goal-columns with-sidebar" data-goal-columns>
|
|
|
|
|
|
|
+ <div class="act-consult with-sidebar" data-goal-columns>
|
|
|
<div class="stack" data-goal-act>
|
|
<div class="stack" data-goal-act>
|
|
|
|
|
|
|
|
<!-- GOAL 41 T6 ("actions surface"): while a plan review is
|
|
<!-- GOAL 41 T6 ("actions surface"): while a plan review is
|
|
@@ -279,9 +229,7 @@
|
|
|
(stm-if ordering by state) — the reader answers before
|
|
(stm-if ordering by state) — the reader answers before
|
|
|
anything else. The plan-history card below renders
|
|
anything else. The plan-history card below renders
|
|
|
only when nothing is pending. -->
|
|
only when nothing is pending. -->
|
|
|
- <section class="card plan-review-card goal-section"
|
|
|
|
|
- stm-if="goal.plan_pending_block != null && goal.plan_pending_block != false"
|
|
|
|
|
- id="goal-sec-plan-review">
|
|
|
|
|
|
|
+ <section class="card plan-review-card" stm-if="goal.plan_pending_block != null && goal.plan_pending_block != false" id="goal-sec-plan-review" data-subnav-section="goal-sec-plan-review">
|
|
|
<h3>Plan review</h3>
|
|
<h3>Plan review</h3>
|
|
|
<div class="plan-review" data-plan-review
|
|
<div class="plan-review" data-plan-review
|
|
|
stm-attribute.data-block-id="goal.plan_pending_block.id">
|
|
stm-attribute.data-block-id="goal.plan_pending_block.id">
|
|
@@ -310,9 +258,7 @@
|
|
|
review leads the acting column the same way — hoisted
|
|
review leads the acting column the same way — hoisted
|
|
|
out of the blocks loop (which skips review rows) and
|
|
out of the blocks loop (which skips review rows) and
|
|
|
keyed on the slot's completion_pending_block. -->
|
|
keyed on the slot's completion_pending_block. -->
|
|
|
- <section class="card plan-review-card goal-section"
|
|
|
|
|
- stm-if="goal.completion_pending_block != null && goal.completion_pending_block != false"
|
|
|
|
|
- id="goal-sec-completion-review">
|
|
|
|
|
|
|
+ <section class="card plan-review-card" stm-if="goal.completion_pending_block != null && goal.completion_pending_block != false" id="goal-sec-completion-review" data-subnav-section="goal-sec-completion-review">
|
|
|
<h3>Completion review</h3>
|
|
<h3>Completion review</h3>
|
|
|
<div class="plan-review" data-plan-review
|
|
<div class="plan-review" data-plan-review
|
|
|
stm-attribute.data-block-id="goal.completion_pending_block.id">
|
|
stm-attribute.data-block-id="goal.completion_pending_block.id">
|
|
@@ -349,7 +295,7 @@
|
|
|
unconditionally by design. Yeehaw stays on task
|
|
unconditionally by design. Yeehaw stays on task
|
|
|
rows only. The strip above carries the one-glance
|
|
rows only. The strip above carries the one-glance
|
|
|
verdict; this card keeps the detail. -->
|
|
verdict; this card keeps the detail. -->
|
|
|
- <section class="card goal-head goal-section" id="goal-sec-status">
|
|
|
|
|
|
|
+ <section class="card goal-head" id="goal-sec-status" data-subnav-section="goal-sec-status">
|
|
|
<div class="card-head">
|
|
<div class="card-head">
|
|
|
<h3>Status</h3>
|
|
<h3>Status</h3>
|
|
|
</div>
|
|
</div>
|
|
@@ -427,9 +373,7 @@
|
|
|
the historic answered ones fold behind the
|
|
the historic answered ones fold behind the
|
|
|
answered-blocks expander (the task page's pattern);
|
|
answered-blocks expander (the task page's pattern);
|
|
|
the completion review follows when one awaits. -->
|
|
the completion review follows when one awaits. -->
|
|
|
- <section class="card goal-section"
|
|
|
|
|
- stm-if="goal.open_blocks.length > 0 || goal.answered_blocks.length > 0"
|
|
|
|
|
- id="goal-sec-blocks">
|
|
|
|
|
|
|
+ <section class="card" stm-if="goal.open_blocks.length > 0 || goal.answered_blocks.length > 0" id="goal-sec-blocks" data-subnav-section="goal-sec-blocks">
|
|
|
<h3>Goal agent blocks</h3>
|
|
<h3>Goal agent blocks</h3>
|
|
|
<div stm-for-block-in="goal.open_blocks" class="goal-block">
|
|
<div stm-for-block-in="goal.open_blocks" class="goal-block">
|
|
|
<!-- A pending completion review renders in the
|
|
<!-- A pending completion review renders in the
|
|
@@ -468,7 +412,7 @@
|
|
|
once the goal is complete/failed, with the report and
|
|
once the goal is complete/failed, with the report and
|
|
|
the compare link. While PENDING, the review lives in
|
|
the compare link. While PENDING, the review lives in
|
|
|
the attention blocks above (the rich review form). -->
|
|
the attention blocks above (the rich review form). -->
|
|
|
- <section class="card goal-section" stm-if="goal.terminal && goal.completion_report.length > 0">
|
|
|
|
|
|
|
+ <section class="card" stm-if="goal.terminal && goal.completion_report.length > 0" id="goal-sec-completion-report" data-subnav-section="goal-sec-completion-report">
|
|
|
<h3>Completion review</h3>
|
|
<h3>Completion review</h3>
|
|
|
<pstm-fragment name="goal-branches"/>
|
|
<pstm-fragment name="goal-branches"/>
|
|
|
<pstm-fragment name="goal-compare"/>
|
|
<pstm-fragment name="goal-compare"/>
|
|
@@ -481,7 +425,7 @@
|
|
|
needs a human, not with settled history. While a plan
|
|
needs a human, not with settled history. While a plan
|
|
|
review is open the LEADING plan-review card above
|
|
review is open the LEADING plan-review card above
|
|
|
carries it (this card waits below). -->
|
|
carries it (this card waits below). -->
|
|
|
- <section class="card goal-section" id="goal-sec-plan">
|
|
|
|
|
|
|
+ <section class="card" id="goal-sec-plan" data-subnav-section="goal-sec-plan">
|
|
|
<h3>Plan</h3>
|
|
<h3>Plan</h3>
|
|
|
|
|
|
|
|
<details class="history-expander">
|
|
<details class="history-expander">
|
|
@@ -512,7 +456,7 @@
|
|
|
bookkeeping renders as distinct muted system rows,
|
|
bookkeeping renders as distinct muted system rows,
|
|
|
never agent comment rows. The composer opens with
|
|
never agent comment rows. The composer opens with
|
|
|
the run (a draft goal has no thread to inject into). -->
|
|
the run (a draft goal has no thread to inject into). -->
|
|
|
- <section class="card goal-section" id="goal-sec-comments">
|
|
|
|
|
|
|
+ <section class="card" id="goal-sec-comments" data-subnav-section="goal-sec-comments">
|
|
|
<h3>Comments</h3>
|
|
<h3>Comments</h3>
|
|
|
<!-- Plan 15 C4: timeless-comment footnote styling —
|
|
<!-- Plan 15 C4: timeless-comment footnote styling —
|
|
|
the BODY leads; the author and time read as a
|
|
the BODY leads; the author and time read as a
|
|
@@ -567,7 +511,7 @@
|
|
|
<!-- Task status strip + the goal's task list (plan 14 B5:
|
|
<!-- Task status strip + the goal's task list (plan 14 B5:
|
|
|
tasks above the brief; capability badges per row —
|
|
tasks above the brief; capability badges per row —
|
|
|
no editing here; yeehaw on rows only). -->
|
|
no editing here; yeehaw on rows only). -->
|
|
|
- <section class="card goal-section" id="goal-sec-tasks">
|
|
|
|
|
|
|
+ <section class="card" id="goal-sec-tasks" data-subnav-section="goal-sec-tasks">
|
|
|
<h3>Tasks</h3>
|
|
<h3>Tasks</h3>
|
|
|
<p class="goal-strip">
|
|
<p class="goal-strip">
|
|
|
<button type="button" stm-attribute.class="window.goalFilterClass('draft')"
|
|
<button type="button" stm-attribute.class="window.goalFilterClass('draft')"
|
|
@@ -620,8 +564,7 @@
|
|
|
nothing else could change). Starting locks the brief:
|
|
nothing else could change). Starting locks the brief:
|
|
|
the editor's stm-if wrapper disappears with the
|
|
the editor's stm-if wrapper disappears with the
|
|
|
update action and the card stays the plain read view. -->
|
|
update action and the card stays the plain read view. -->
|
|
|
- <section class="card goal-section" id="goal-sec-brief" data-long-form data-field="goal"
|
|
|
|
|
- data-lf-open="0">
|
|
|
|
|
|
|
+ <section class="card" data-long-form data-field="goal" data-lf-open="0" id="goal-sec-brief" data-subnav-section="goal-sec-brief">
|
|
|
<h3>Initial brief
|
|
<h3>Initial brief
|
|
|
<button type="button" class="btn-ghost" stm-if="goal.update != null"
|
|
<button type="button" class="btn-ghost" stm-if="goal.update != null"
|
|
|
data-lf-toggle>Edit</button>
|
|
data-lf-toggle>Edit</button>
|
|
@@ -697,7 +640,7 @@
|
|
|
<!-- The supervision narrative (plan 14 B6): state events
|
|
<!-- The supervision narrative (plan 14 B6): state events
|
|
|
at full weight, comment events as .footnote — the
|
|
at full weight, comment events as .footnote — the
|
|
|
feed reads as events-with-occasional-footnotes. -->
|
|
feed reads as events-with-occasional-footnotes. -->
|
|
|
- <section class="card goal-section" id="goal-sec-narrative">
|
|
|
|
|
|
|
+ <section class="card" id="goal-sec-narrative" data-subnav-section="goal-sec-narrative">
|
|
|
<h3>Supervision narrative</h3>
|
|
<h3>Supervision narrative</h3>
|
|
|
<p stm-if="goal.events.length == 0" class="text-muted">Nothing yet — start the goal.</p>
|
|
<p stm-if="goal.events.length == 0" class="text-muted">Nothing yet — start the goal.</p>
|
|
|
<div stm-for-event-in="goal.events"
|
|
<div stm-for-event-in="goal.events"
|
|
@@ -740,7 +683,7 @@
|
|
|
</section>
|
|
</section>
|
|
|
|
|
|
|
|
</div><!-- /data-goal-consult -->
|
|
</div><!-- /data-goal-consult -->
|
|
|
- </div><!-- /goal-columns -->
|
|
|
|
|
|
|
+ </div><!-- /act-consult columns -->
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</body>
|
|
</body>
|