Skip to content

Commit 0b9dade

Browse files
Merge pull request #43 from programmerShinobi/feat/phase2-content-guide-polish
[feat](advisor+ui): Fase 2 — 10 scenario presets, factor examples, full-feature Guide, calm futuristic chrome
2 parents 221547f + bc578a5 commit 0b9dade

21 files changed

Lines changed: 447 additions & 187 deletions

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,27 @@ The decision **model** carries its own version, recorded in the
99

1010
## [Unreleased]
1111

12+
### Added / Changed (Fase 2 — richer scenarios & guidance, full-feature Guide, calm chrome — 2026-07-16)
13+
14+
- **10 scenario presets** — five new helper scenarios (B2B SaaS, consumer mobile, data platform,
15+
legacy modernization, real-time collaboration) marked `calibrated: false`; the five ADR-0002
16+
presets stay bit-exact and guard-pinned. `check-app-config.mjs` extended accordingly; a new
17+
unit test pins each helper's engine outcome per dimension (drift guard).
18+
- **Per-level factor examples** — every one of the 14 factors shows a bilingual real-world
19+
example for the selected level in guided mode (pure UI copy; the frozen model is untouched).
20+
- **Guide = full feature map** — section 7 now covers Home, the guided/expert Advisor toolset,
21+
all seven Insights lenses, save/export/share, the command palette & shortcuts, EN/ID, themes,
22+
mobile chrome, and PWA install/offline.
23+
- **Calm text gradients** — gradient text ("evidence", "Always explains why") moved to a muted,
24+
theme-tuned `--aa-grad-text` (deeper on light, pastel on dark) — decorative fills keep the
25+
vivid accent, text never glares.
26+
- **Modern app bar** — one sticky glass bar: nav tabs (futuristic segmented badges) in the
27+
top-left corner, compact controls + brand mark docked right; the app title lives on the Home
28+
hero. The guided "New here?" strip is now a slim, calm inline hint with a ⌘K key cap.
29+
- **Brand mark v5 "compass"** — a minimal monochrome compass on a transparent background:
30+
black in the light theme, auto-inverting via `currentColor` (app) and `prefers-color-scheme`
31+
(favicon); PWA icons regenerated as a black compass on a soft-white tile.
32+
1233
### Changed (Fase 1 — "Aurora Glass" borderless evolution + identity — 2026-07-16)
1334

1435
- **Component tree grouped by feature area**`src/components/` reorganised into

DECISIONS.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,41 @@ commitment the code must match (cross-checked by review, gates, and tests).
279279
All rights reserved.` — plus the same notice in `site.ts` config, the SEO snapshots, the README
280280
and the print report. **Scope note:** code stays MIT and docs CC BY 4.0 (unchanged LICENSE
281281
files); the copyright line asserts *identity/attribution* of the work, it does not re-license it.
282+
283+
## Fase 2 — richer scenarios & factor guidance, full-feature Guide, calm futuristic chrome (2026-07)
284+
285+
Documented **before** implementation (docs-first). The frozen model stays frozen — every point
286+
below is content or presentation, never scoring.
287+
288+
- **Presets grow 5 → 10; the calibrated five stay bit-exact.** The five ADR-0002 presets are
289+
pinned by the frozen guards (`verify-model.mjs` fixtures + `cross-check-docs.mjs`, which assert
290+
exactly those five against the Model Data Sheet Section 6) and are NOT touched. Five new
291+
**helper scenarios** (B2B SaaS · consumer mobile backend · data/analytics platform · legacy
292+
modernization · real-time collaboration) live only in `src/config/presets.ts`, marked
293+
`calibrated: false` — they are conveniences that pre-fill the 14 factors, not part of the
294+
ratified model. `check-app-config.mjs` (not frozen) is extended: the calibrated five must still
295+
match `verify-model.mjs` exactly; helper presets are validated structurally (14 factors, levels
296+
0–2). A unit test pins each helper's top pick per dimension so any future drift fails the build.
297+
- **Factors stay 14 — enriched, not extended.** Adding a scoring factor would change the frozen
298+
model (influence matrix, MDS, SRS cross-checks — all guard-pinned), so instead every factor
299+
gains bilingual **per-level real-world examples** (`examples`) shown as a hint under the
300+
selected level in the Advisor: more relevant guidance per question with zero model impact.
301+
- **The Guide becomes a full-feature manual.** `ManualBook` gains a "what's in the app" feature
302+
map covering everything shipped since it was written: Home landing, Advisor guided/expert flow
303+
(presets, priorities/overrides, radar, sensitivity, A/B compare, anti-patterns, migration,
304+
risks, fitness functions, C4, exports, share links), Insights' seven lenses, command palette &
305+
shortcuts, EN/ID, themes, install/offline (PWA), and the copyright/identity line.
306+
- **Calm gradients (owner feedback: "terlalu mencolok").** Gradient-filled text (`.lp-grad`
307+
"evidence", the eyebrow's "Always explains why", and any sibling accent text) switches to a
308+
**muted, theme-tuned** two-stop gradient — deeper/desaturated on light, softer pastel on dark —
309+
tuned separately per theme so neither glares.
310+
- **Modern app bar: nav left, controls right.** The centered nav pill moves to the **top-left
311+
corner** as futuristic segmented badges; the header controls (save status, Guide, ⌘K, ?, mode,
312+
language, theme) dock to the **right** of the same bar with the brand mark; the title/tagline
313+
live on the Home hero + document title (the bar stays one row). The guided "New here?" strip
314+
becomes a slimmer, calmer inline hint.
315+
- **Brand mark v5: monochrome compass.** Per owner direction the glyph becomes a minimal modern
316+
**compass** (ring + needle + hub) in a single color on a **transparent** background — black in
317+
the light theme (elegant), automatically light in dark contexts via `currentColor` (in-app) and
318+
an SVG-embedded `prefers-color-scheme` rule (favicon), so it is never invisible. PWA PNG icons
319+
keep a solid tile (maskable requirement): black compass on a soft white tile.

public/favicon.svg

Lines changed: 16 additions & 47 deletions
Loading

public/icons/apple-touch-icon.png

-27.6 KB
Loading

public/icons/icon-192.png

-29 KB
Loading

public/icons/icon-512.png

-163 KB
Loading

public/icons/icon-maskable-512.png

-134 KB
Loading

scripts/check-app-config.mjs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,26 @@ function mjsPresets() {
129129
return out;
130130
}
131131
{
132+
// Fase 2 (DECISIONS.md): the app may ship extra HELPER presets beyond the five calibrated
133+
// ones. The calibrated five must still match verify-model.mjs bit-exactly; helpers are
134+
// validated structurally (14 factors, levels 0–2) and must be marked `calibrated: false`.
132135
const app = appPresets(), mjs = mjsPresets();
136+
const calibratedIds = Object.keys(mjs);
137+
const flags = {};
138+
for (const m of noComments(read('src/config/presets.ts')).matchAll(/id:\s*'([a-z-]+)',[\s\S]*?calibrated:\s*(true|false)/g))
139+
flags[m[1]] = m[2] === 'true';
133140
const diff = [];
134-
for (const k of new Set([...Object.keys(app), ...Object.keys(mjs)]))
141+
for (const k of calibratedIds)
135142
for (const f of FACT) if (app[k]?.[f] !== mjs[k]?.[f]) diff.push(`${k}.${f}`);
136-
diff.length === 0 && Object.keys(app).length === 5 ? ok('preset levels match verify-model.mjs (5 presets × 14)') : bad(`preset levels differ at: ${diff.join(', ') || 'count'}`);
143+
const helpers = Object.keys(app).filter((k) => !calibratedIds.includes(k));
144+
const badHelpers = helpers.filter((k) => FACT.some((f) => ![0, 1, 2].includes(app[k][f])));
145+
const badFlags = [
146+
...calibratedIds.filter((k) => flags[k] !== true).map((k) => `${k} (expect calibrated: true)`),
147+
...helpers.filter((k) => flags[k] !== false).map((k) => `${k} (expect calibrated: false)`),
148+
];
149+
diff.length === 0 && badHelpers.length === 0 && badFlags.length === 0
150+
? ok(`preset levels: 5 calibrated match verify-model.mjs exactly; ${helpers.length} helper preset(s) structurally valid (14 × 0–2, flagged)`)
151+
: bad(`presets: calibrated diff at [${diff.join(', ')}]; invalid helpers: [${badHelpers.join(', ')}]; wrong flags: [${badFlags.join(', ')}]`);
137152
}
138153

139154
// ---- 8. anti-pattern ids + severities vs Model Data Sheet Section 5 ----

src/App.tsx

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -217,40 +217,44 @@ export default function App() {
217217
canvas; the header/nav are glass. The extra wrapper div is gone with the frame. */}
218218
<div>
219219
<div id="f-app" className={mode} style={{ position: 'relative' }}>
220-
<Header
221-
mode={mode}
222-
onToggleMode={setMode}
223-
onCmdK={() => setOverlay('palette')}
224-
onHelp={() => setOverlay('shortcuts')}
225-
onManual={() => setOverlay('manual')}
226-
theme={theme}
227-
onToggleTheme={toggleTheme}
228-
saveSig={saveSig}
229-
/>
230-
231-
<nav aria-label={t('m.primaryNav')} className="screen-only aa-topnav aa-glass">
232-
{(
233-
[
234-
{ v: 'home', key: 'nav.home', Icon: IconHome },
235-
{ v: 'advisor', key: 'nav.advisor', Icon: IconCompass },
236-
{ v: 'learn', key: 'nav.learn', Icon: IconBulb },
237-
] as const
238-
).map(({ v, key, Icon }) => {
239-
const active = mainView === v;
240-
return (
241-
<button
242-
key={v}
243-
type="button"
244-
aria-current={active ? 'page' : undefined}
245-
onClick={() => navigate(v)}
246-
className={'aa-topnav-tab' + (active ? ' on' : '')}
247-
>
248-
<Icon size={15} aria-hidden />
249-
{t(key)}
250-
</button>
251-
);
252-
})}
253-
</nav>
220+
{/* Modern app bar (Fase 2, DECISIONS.md): ONE sticky glass bar — nav tabs in the
221+
top-LEFT corner, controls + brand docked RIGHT. The app title lives on the Home
222+
hero and the document title, keeping the bar a single calm row. */}
223+
<div className="aa-appbar aa-glass">
224+
<nav aria-label={t('m.primaryNav')} className="screen-only aa-topnav">
225+
{(
226+
[
227+
{ v: 'home', key: 'nav.home', Icon: IconHome },
228+
{ v: 'advisor', key: 'nav.advisor', Icon: IconCompass },
229+
{ v: 'learn', key: 'nav.learn', Icon: IconBulb },
230+
] as const
231+
).map(({ v, key, Icon }) => {
232+
const active = mainView === v;
233+
return (
234+
<button
235+
key={v}
236+
type="button"
237+
aria-current={active ? 'page' : undefined}
238+
onClick={() => navigate(v)}
239+
className={'aa-topnav-tab' + (active ? ' on' : '')}
240+
>
241+
<Icon size={15} aria-hidden />
242+
{t(key)}
243+
</button>
244+
);
245+
})}
246+
</nav>
247+
<Header
248+
mode={mode}
249+
onToggleMode={setMode}
250+
onCmdK={() => setOverlay('palette')}
251+
onHelp={() => setOverlay('shortcuts')}
252+
onManual={() => setOverlay('manual')}
253+
theme={theme}
254+
onToggleTheme={toggleTheme}
255+
saveSig={saveSig}
256+
/>
257+
</div>
254258

255259
{mainView === 'home' ? (
256260
<div className="aa-panel">

src/components/advisor/FactorField.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ export function FactorField({ factor, level, onChange }: Props) {
4747
</span>
4848
))}
4949
</div>
50+
{/* Real-world example for the SELECTED level (Fase 2) — guided-mode guidance only. */}
51+
{factor.examples && (
52+
<div className="f-gloss guided-only" style={{ marginTop: '6px' }}>
53+
{tr(factor.examples[level] ?? factor.examples[0])}
54+
</div>
55+
)}
5056
</div>
5157
);
5258
}

0 commit comments

Comments
 (0)