Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ vite*.log
# impeccable design-skill detector cache (transient; the design system itself
# lives in DESIGN.md + .impeccable/design.json, which ARE tracked).
.impeccable/hook.cache.json

# impeccable critique snapshots (local evaluation history, per-run)
.impeccable/critique/
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,41 @@ file format introduced in `[0.0.1.0]` was dropped.

## [Unreleased]

## [0.8.3] - 2026-06-27

### Fixed

- **AI-translate dual columns fill the reader pane.** The bilingual view's root
inherits `.markdown-body`'s single-column `max-width: 72ch`, so the source /
translation columns crushed into one measure on the left and left the pane's
right half empty. `.bilingual-cols` now overrides that cap — it fills the reader
width (each column gets its own measure) and, past two measures on an ultra-wide
pane, caps and centers. Below 1100px, where the pairs collapse to one stacked
column, the cap reverts to the single-column 72ch so a stacked paragraph never
runs past a comfortable line length. _e2e guards: `bilingual.spec.ts`
"dual-column view fills the reader pane…" + "…restores the single-column measure
when columns stack…"._
- **DESIGN.md typography frontmatter matched to the implementation.** The
machine-readable `typography:` block still named the pre-v0.8.0 families (Source
Serif 4 / Inter Tight / JetBrains Mono) and carried swapped weights (display 500,
label 600) — contradicting the shipped IBM Plex superfamily and the §3 prose
table (display 600, label 500). Frontmatter families, weights, and the stray
§3 "JetBrains Mono" mention now read IBM Plex.

### Changed

- **MB-Web radii and colors consolidated onto the shared tokens.** `src/mb/mb.css`
kept a parallel light + dark palette whose values already duplicated the
workbench tokens. Differently-named locals (`--ac` / `--acb` / `--border` / …)
now alias their `styles.css` equivalent and same-named ones (`--bg` / `--surface`
/ `--text` / …) inherit the global values, so the parallel dark block is gone;
the off-scale radii snapped to the `4 / 6 / 7 / 8 / 999` scale (cards 8px; the
badge / chip / filter / toast / sync pills fully round); the note highlighter
yellows became named `--mb-mark` / `--mb-mark-staged` tokens. Only the few
genuinely MB-specific literals with no shared equivalent (answer-blue, on-accent
foreground, AA-darkened faint, hover wash) stay local. Zero-visual-change for
colors; verified in the browser across library, reader, and notes in light + dark.

## [0.8.2] - 2026-06-27

### Fixed
Expand Down
41 changes: 24 additions & 17 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,38 @@ colors:
accent-border-hover: "color-mix(in srgb, {colors.deep-petrol} 35%, {colors.line})"
typography:
# Six roles across three voices. Each maps to --type-<role>-{size,lh,ls} in styles.css.
display: # Source Serif 4 — reader article H1/H2 (the one editorial voice)
fontFamily: "Source Serif 4, ui-serif, Georgia, Source Han Serif CN, serif"
display: # IBM Plex Serif — reader article H1/H2 (the one editorial voice)
fontFamily: "IBM Plex Serif, ui-serif, Georgia, Songti SC, Source Han Serif CN, serif"
fontSize: "32px"
fontWeight: 500
fontWeight: 600
lineHeight: 1.18
letterSpacing: "-0.01em"
title-page: # Inter Tight — page-header H1 (NOTE: sans, not serif)
fontFamily: "Inter Tight, Inter, ui-sans-serif, system-ui, sans-serif"
title-page: # IBM Plex Sans — page-header H1 (NOTE: sans, not serif)
fontFamily: "IBM Plex Sans, ui-sans-serif, system-ui, PingFang SC, Microsoft YaHei, sans-serif"
fontSize: "30px"
fontWeight: 600
lineHeight: 1.1
letterSpacing: "-0.01em"
title: # Inter Tight — panel / card / session headings
fontFamily: "Inter Tight, Inter, ui-sans-serif, system-ui, sans-serif"
title: # IBM Plex Sans — panel / card / session headings
fontFamily: "IBM Plex Sans, ui-sans-serif, system-ui, PingFang SC, Microsoft YaHei, sans-serif"
fontSize: "17px"
fontWeight: 600
lineHeight: 1.3
letterSpacing: "-0.005em"
body: # Inter Tight — interface text, descriptions, agent replies
fontFamily: "Inter Tight, Inter, ui-sans-serif, system-ui, sans-serif"
body: # IBM Plex Sans — interface text, descriptions, agent replies
fontFamily: "IBM Plex Sans, ui-sans-serif, system-ui, PingFang SC, Microsoft YaHei, sans-serif"
fontSize: "15px"
fontWeight: 400
lineHeight: 1.55
body-sm: # Inter Tight — dense metadata / secondary UI text
fontFamily: "Inter Tight, Inter, ui-sans-serif, system-ui, sans-serif"
body-sm: # IBM Plex Sans — dense metadata / secondary UI text
fontFamily: "IBM Plex Sans, ui-sans-serif, system-ui, PingFang SC, Microsoft YaHei, sans-serif"
fontSize: "13px"
fontWeight: 400
lineHeight: 1.45
label: # JetBrains Mono UPPERCASE — field labels, table heads, IDs
fontFamily: "JetBrains Mono, ui-monospace, SFMono-Regular, Consolas, monospace"
label: # IBM Plex Mono UPPERCASE — field labels, table heads, IDs
fontFamily: "IBM Plex Mono, ui-monospace, SFMono-Regular, Consolas, Sarasa Mono SC, monospace"
fontSize: "11px"
fontWeight: 600
fontWeight: 500
lineHeight: 1.2
letterSpacing: "0.04em"
rounded:
Expand Down Expand Up @@ -361,8 +361,15 @@ half-step scale (11.5 / 12.5 / 13.5 / 14.5 …) collapsed onto label / body-sm /
`main.tsx`) makes the tokens available inside the MB-Web tree. The one deliberate
literal is `.mb-r-title` (22px) — the paper-reader title, the reader-h2 editorial
step, kept compact rather than the workbench reader's 32. MB-Web's **radii and
colors** are still off the documented scale (a separate `detect.mjs` finding) and
remain a tracked follow-up; only type was migrated here.
colors now ride the shared tokens too**: every differently-named local token
(`--ac` / `--acb` / `--border` / …) aliases its `styles.css` equivalent and the
same-named ones (`--bg` / `--surface` / `--text` / …) inherit the global light +
dark values, so the parallel dark block is gone; its former off-scale radii
snapped to the `4 / 6 / 7 / 8 / 999` scale (cards 8px, the badge / chip / filter /
toast / sync pills fully round). The few genuinely MB-specific literals with no
shared equivalent stay named and local: the answer-blue pair (`--ans-*`), the
on-accent foreground (`--acfg`), the AA-darkened `--faint`, the hover wash
(`--hover-bp`), and the note highlighter (`--mb-mark` / `--mb-mark-staged`).

**The agent surface rides the roles.** Assistant and user messages use the body
role (15px) for prose, the editorial serif for the three markdown heading levels
Expand Down Expand Up @@ -601,7 +608,7 @@ layer. Rules below are tagged **[EN]**, **[ZH]**, or **[both]**.
is structural, not floated.
- **Do** snap spacing to the `--space-*` grid and radii to the `4 / 6 / 7 / 8 /
999` scale; controls at 7px, cards at 8px, pills fully round.
- **Do** confine uppercase + letter-spacing to the JetBrains Mono `label` role,
- **Do** confine uppercase + letter-spacing to the IBM Plex Mono `label` role,
and keep ≤2 font weights per view.
- **Do** put a focus ring on every interactive element (`--focus-ring` for text
fields, `--focus-outline` elsewhere — already single-sourced), and drive
Expand Down
11 changes: 9 additions & 2 deletions docs/ui-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,15 @@ no e2e are the ones the manual pass exists for.
## Bilingual reader (`#base` EN→中)

> On an English Base page with the translator enabled, toggle **AI 翻译** and
> watch the dual column fill. These guard the two regressions found in review.

> watch the dual column fill. These guard the layout and translation regressions
> found in review.

- [ ] **Dual columns fill the reader pane.** The source / translation columns
span the full reader width with the centered hairline between them — not capped
at the single-column 72ch measure that left-hugged the pane and emptied the
right half (the 0.8.3 layout fix). On an ultra-wide pane the pair caps at two
reading measures and centers. _e2e: `bilingual.spec.ts` "dual-column view fills
the reader pane…"._
- [ ] **Figures render once, centered.** A standalone image / figure (`![[…]]`
or `![](…)` on its own line) appears **once**, centered across both columns —
never duplicated in the left and right column. (Captions, being prose, are a
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dikw-web",
"version": "0.8.2",
"version": "0.8.3",
"private": true,
"type": "module",
"engines": {
Expand Down
87 changes: 39 additions & 48 deletions src/mb/mb.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,35 @@
* panel splitters.
*/
.mb-app {
/* Aligned to the workbench warm-stone + petrol identity (One Indicator Rule):
MB-Web shares the same neutrals and accent as src/styles.css, not its own
green palette. --ans-* (answer blue) stays a distinct functional semantic. */
--bg: #f5f3ee;
--surface: #ffffff;
--surface2: #f0eee8;
--border: #e2dfd6;
--border2: #cdc9bd;
--text: #1a1d1c;
--muted: #6c6f6a;
/* Darkened from #95968f (~2.7:1) to clear AA (~4.5:1) for the meta text that
uses --faint; still the faintest neutral, just readable. */
/* MB-Web rides the workbench design tokens (src/styles.css) directly — its
neutrals, accent, radius and font voices ARE the shared, theme-aware tokens,
not a parallel palette. Same-named tokens (--bg / --surface / --text /
--muted / --danger / --radius) inherit the global :root and dark values;
differently-named ones alias the shared token so they track the theme with
no parallel dark block to maintain. Only the genuinely MB-specific semantics
stay literal — the answer-blue pair, the on-accent foreground, the
AA-darkened faint, the hover wash, and the note highlighter — none of which
has a shared equivalent. */
--surface2: var(--surface-2);
--border: var(--line);
--border2: var(--line-strong);
--ac: var(--accent);
--acb: var(--accent-soft);
--act: var(--accent-strong);
--anno-bg: var(--accent-soft);
/* Darkened from #95968f (~2.7:1) to clear AA (~4.5:1) for --faint meta text. */
--faint: #767771;
--ac: #0d5e57;
--acb: #e2eeec;
--act: #094540;
--acfg: #ffffff;
--hover-bp: #faf9f5;
--anno-bg: #e2eeec;
--ans-bg: #e6f1fb;
--ans-tx: #0c447c;
--danger: #a8362c;
--radius: 8px;
--radius-lg: 12px;
--sans:
"IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
"Microsoft YaHei", sans-serif;
--serif: "IBM Plex Serif", Georgia, "Songti SC", serif;
/* Note highlighter: live selection (yellow) + staged range (warmer amber).
Theme-agnostic — always dark text on a bright mark, on both light and dark
reader/chat surfaces. */
--mb-mark: #fef08a;
--mb-mark-staged: #fcd34d;
--sans: var(--font-ui);
--serif: var(--font-serif);

position: fixed;
inset: 0;
Expand All @@ -47,23 +48,13 @@
overflow: hidden;
}
html[data-theme="dark"] .mb-app {
--bg: #14140f;
--surface: #1b1b15;
--surface2: #25241d;
--border: #2f2d24;
--border2: #4e4a3c;
--text: #f0eee7;
--muted: #b0aca0;
/* Only the MB-specific literals need a dark value; every shared-token alias
and same-named token tracks the global dark block automatically. */
--faint: #87826f;
--ac: #4eb8a6;
--acb: #142a26;
--act: #92e3d4;
--acfg: #06231f;
--hover-bp: #1f1e17;
--anno-bg: #142a26;
--ans-bg: #12304e;
--ans-tx: #b5d4f4;
--danger: #ef7f75;
}
.mb-app *,
.mb-app *::before,
Expand Down Expand Up @@ -137,7 +128,7 @@ html[data-theme="dark"] .mb-app {
background: var(--acb);
color: var(--act);
font-size: var(--type-label-size);
border-radius: 20px;
border-radius: 999px;
padding: 0 6px;
min-width: 16px;
text-align: center;
Expand Down Expand Up @@ -572,7 +563,7 @@ body.mb-col-resizing * {
font-size: var(--type-label-size);
background: var(--acb);
color: var(--act);
border-radius: 12px;
border-radius: 999px;
padding: 1px 8px;
}
.mb-reader-empty {
Expand Down Expand Up @@ -827,7 +818,7 @@ body.mb-col-resizing * {
.mb-f {
font-size: var(--type-body-sm-size);
padding: 5px 13px;
border-radius: 20px;
border-radius: 999px;
border: 0.5px solid var(--border2);
background: transparent;
color: var(--muted);
Expand All @@ -842,7 +833,7 @@ body.mb-col-resizing * {
.mb-note {
background: var(--surface);
border: 0.5px solid var(--border);
border-radius: var(--radius-lg);
border-radius: var(--radius);
padding: 16px 18px;
margin-bottom: 12px;
}
Expand All @@ -861,7 +852,7 @@ body.mb-col-resizing * {
color: var(--text);
background: var(--surface);
border: 0.5px solid var(--border);
border-radius: var(--radius-lg);
border-radius: var(--radius);
padding: 14px 16px;
cursor: pointer;
display: flex;
Expand Down Expand Up @@ -1101,7 +1092,7 @@ body.mb-col-resizing * {
background: var(--ac);
color: var(--acfg);
border: 0;
border-radius: 22px;
border-radius: 999px;
font-size: var(--type-body-sm-size);
padding: 7px 14px;
cursor: pointer;
Expand All @@ -1117,7 +1108,7 @@ body.mb-col-resizing * {
width: 300px;
background: var(--surface);
border: 0.5px solid var(--border2);
border-radius: var(--radius-lg);
border-radius: var(--radius);
padding: 15px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
}
Expand Down Expand Up @@ -1229,7 +1220,7 @@ body.mb-col-resizing * {
width: min(380px, 100%);
background: var(--surface);
border: 0.5px solid var(--border2);
border-radius: var(--radius-lg);
border-radius: var(--radius);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.22);
padding: 18px 18px 16px;
}
Expand Down Expand Up @@ -1276,7 +1267,7 @@ body.mb-col-resizing * {
color: var(--acfg);
font-size: var(--type-body-sm-size);
padding: 9px 16px;
border-radius: 24px;
border-radius: 999px;
display: flex;
align-items: center;
gap: 7px;
Expand All @@ -1292,7 +1283,7 @@ body.mb-col-resizing * {
border: 0.5px solid var(--border);
background: var(--surface2);
color: var(--muted);
border-radius: 20px;
border-radius: 999px;
padding: 2px 9px;
cursor: default;
}
Expand Down Expand Up @@ -1347,20 +1338,20 @@ body.mb-col-resizing * {
paragraph-hover highlight and the user sees exactly what will be saved. */
.mb-reader ::selection,
.mb-msgs ::selection {
background: #fef08a;
background: var(--mb-mark);
color: #1a1a1a;
}
.mb-reader ::-moz-selection,
.mb-msgs ::-moz-selection {
background: #fef08a;
background: var(--mb-mark);
color: #1a1a1a;
}
/* "Staged" highlight: once text is selected we register its range as a CSS
Custom Highlight (see stageHighlight in MbApp) so the chosen text stays
marked — in a slightly warmer amber than the live selection — while the user
moves to the chip/popover, even after the native selection is gone. */
::highlight(mb-staged) {
background: #fcd34d;
background: var(--mb-mark-staged);
color: #1a1a1a;
}

Expand Down
15 changes: 14 additions & 1 deletion src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1895,9 +1895,16 @@ html[data-theme="dark"] .wiki-reader-tabs .wrt-switch__thumb {
}
}

/* Paragraph-aligned dual columns. */
/* Paragraph-aligned dual columns. The dual view is two reading measures side by
side, so it must override the single-column 72ch cap it inherits from
`.markdown-body` — otherwise both columns crush into one measure on the left
and leave the pane's right half empty. Fill the reader pane on normal widths;
past two measures, cap and center so columns never run past a comfortable
line length on an ultra-wide monitor. */
.bilingual-cols {
position: relative;
max-width: calc(72ch * 2 + 40px);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore the single-column cap when columns stack

When the viewport is below 1100px, the media query later in this file collapses .bi-pair to one column, but this new override still leaves the container capped at two reading measures instead of the original .markdown-body 72ch cap. On tablet/narrow desktop widths where the wiki layout is already single-column, bilingual source/translation paragraphs can now run nearly the full panel width while the normal reader remains capped, regressing the readability this cap was meant to protect. Add a narrow-mode override such as restoring max-width: 72ch for .bilingual-cols once the pairs stack.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 95776e0. Below 1100px the pairs stack to a single column, so I restored max-width: 72ch for .bilingual-cols inside that stack media query; the two-measure cap now applies only to the side-by-side layout. Added a bilingual.spec.ts guard asserting the resolved max-width reverts to the single measure at a narrow viewport.

margin-inline: auto;
}
.bilingual-cols::before {
content: "";
Expand Down Expand Up @@ -2039,6 +2046,12 @@ html[data-theme="dark"] .wiki-reader-tabs .wrt-switch__thumb {

/* Narrow screens: collapse the two columns into a stacked single column. */
@media (max-width: 1100px) {
/* Stacked = a single column again, so restore the single-column reading
measure — the two-measure cap above is only for the side-by-side layout and
would let a stacked paragraph run far past a comfortable line length. */
.bilingual-cols {
max-width: 72ch;
}
.bilingual-cols::before {
display: none;
}
Expand Down
Loading