diff --git a/crates/cli/src/ui.rs b/crates/cli/src/ui.rs index 6013e3a0..c04cdc63 100644 --- a/crates/cli/src/ui.rs +++ b/crates/cli/src/ui.rs @@ -22194,9 +22194,7 @@ fn render_playbook_inline_spans<'a>( link_idx += 1; } PlaybookInlineToken::Code { content, .. } => { - let code_style = base_style - .fg(app.theme.highlight_fg) - .bg(app.theme.inactive_highlight_bg); + let code_style = playbook_inline_code_style(&app.theme, base_style); spans.extend(playbook_text_spans( &app.theme, content, @@ -22227,6 +22225,12 @@ fn render_playbook_inline_spans<'a>( spans } +fn playbook_inline_code_style(theme: &Theme, base_style: Style) -> Style { + base_style + .fg(theme.text) + .bg(theme.inactive_highlight_bg) +} + /// Attachment chip painter (spec 0099): the compact `[Image: name]` / /// `[File: name]` pill an inline attachment link renders as. Static styling — /// liveness/status concepts don't apply to files; the hover card carries the @@ -23846,6 +23850,22 @@ mod tests { ); } + #[test] + fn playbook_inline_code_uses_readable_inactive_highlight_pair_across_themes() { + for theme in [ + Theme::dark(), + Theme::light(), + Theme::basic_dark(), + Theme::basic_light(), + Theme::dark_ui(), + Theme::light_ui(), + ] { + let style = playbook_inline_code_style(&theme, Style::default()); + assert_eq!(style.fg, Some(theme.text)); + assert_eq!(style.bg, Some(theme.inactive_highlight_bg)); + } + } + /// Without expansion state the chip keeps its collapsed label; when /// expanded, `playbook_md_chip_label` returns None and the source /// occupies zero cells — asserted end-to-end (label absence, no chip diff --git a/crates/daemon/assets/index.html b/crates/daemon/assets/index.html index 6c177d68..ebf2b967 100644 --- a/crates/daemon/assets/index.html +++ b/crates/daemon/assets/index.html @@ -3208,7 +3208,7 @@ /* One source line. Empty lines keep height via a
. */ .playbook-line { min-height: 1.6em; } .playbook-inline-code { - color: var(--fg-strong, var(--fg)); + color: var(--fg); background: color-mix(in srgb, var(--accent) 16%, var(--bg-elev)); border-radius: 4px; padding: 0 2px; diff --git a/crates/e2e/tests/playbook_view.rs b/crates/e2e/tests/playbook_view.rs index 3dd630d3..fa58beb2 100644 --- a/crates/e2e/tests/playbook_view.rs +++ b/crates/e2e/tests/playbook_view.rs @@ -136,6 +136,19 @@ async fn web_playbook_view_full_parity() { const sourceBefore = playbookSerialize(); const visibleBefore = code ? code.textContent : null; const lineTextBefore = playbookInputEl.querySelector(".playbook-line").textContent; + const stylesByTheme = {}; + for (const themeName of Object.keys(WEB_THEMES)) { + applyWebTheme(themeName, { persist: false }); + const codeStyle = getComputedStyle(code); + const editorStyle = getComputedStyle(playbookInputEl); + stylesByTheme[themeName] = { + foreground: codeStyle.color, + editorForeground: editorStyle.color, + background: codeStyle.backgroundColor, + editorBackground: editorStyle.backgroundColor, + }; + } + applyWebTheme("dark", { persist: false }); const sel = window.getSelection(); const range = document.createRange(); range.setStartAfter(code); range.collapse(true); @@ -145,7 +158,7 @@ async fn web_playbook_view_full_parity() { const formattedAfterBackspace = !!playbookInputEl.querySelector(".playbook-inline-code"); document.execCommand("insertText", false, "`"); return { - sourceBefore, visibleBefore, lineTextBefore, + sourceBefore, visibleBefore, lineTextBefore, stylesByTheme, sourceAfterBackspace, formattedAfterBackspace, sourceAfterRetype: playbookSerialize(), formattedAfterRetype: !!playbookInputEl.querySelector(".playbook-inline-code"), @@ -160,6 +173,17 @@ async fn web_playbook_view_full_parity() { assert_eq!(inline_code["sourceBefore"], "run `cargo test` now\n", "{inline_code:?}"); assert_eq!(inline_code["visibleBefore"], "cargo test", "{inline_code:?}"); assert_eq!(inline_code["lineTextBefore"], "run cargo test now", "{inline_code:?}"); + for theme in ["dark", "light", "matrix"] { + let style = &inline_code["stylesByTheme"][theme]; + assert_eq!( + style["foreground"], style["editorForeground"], + "{theme} inline code should use the editor's readable foreground: {style:?}" + ); + assert_ne!( + style["background"], style["editorBackground"], + "{theme} inline code should retain its highlighted background: {style:?}" + ); + } assert_eq!(inline_code["sourceAfterBackspace"], "run `cargo test now\n", "{inline_code:?}"); assert_eq!(inline_code["formattedAfterBackspace"], false, "{inline_code:?}"); assert_eq!(inline_code["sourceAfterRetype"], "run `cargo test` now\n", "{inline_code:?}");