From 0d81c5f168ef384572fc966c43a54200bd17c543 Mon Sep 17 00:00:00 2001 From: rg755421 Date: Tue, 29 Sep 2026 10:07:41 +0545 Subject: [PATCH 1/5] Add - Sync block editor typography with the Customizer body font The block editor's content canvas has always shown a hardcoded Montserrat/#333 from the static style-editor-block.css, regardless of Customize > Global > Typography > Base. Root cause: Kirki's own CSS output only ever prints on wp_head (front-end only), and its Google Fonts loader only runs on the 'wp' action - neither fires on wp-admin, so nothing ever synced the editor to flash_body_font, and the hardcoded Google Fonts link was enqueued on enqueue_block_editor_assets, a hook whose payload never reaches the editor's iframe either. flash_block_editor_dynamic_css() builds editor CSS straight from the flash_body_font theme_mod (font-family, size, line-height, letter-spacing, color, text-transform, text-align), scoped to .editor-styles-wrapper, and is attached inline to the existing flash-block-editor-styles handle - same hook, same handle as before. flash_block_editor_fonts() loads the actual font resource inside the canvas on enqueue_block_assets (which does reach the iframe, unlike enqueue_block_editor_assets), using Kirki's own is_google_font() check to skip system fonts. It intentionally builds a direct Google Fonts CDN link rather than going through Kirki's Downloader/local-caching path - that path is the one this session already hardened for issue #88's synchronous-download bug (in this same repo), and reusing it here would risk reintroducing that exact problem in a brand new code path. Verified live (Playwright, real iframe, tested on Flash Pro since both themes share byte-identical code here): set a distinctive font/size/ color/case, and the editor's .editor-styles-wrapper computed style matched the front end's on every property, including the actual font file loading (confirmed via network request, not just the CSS declaration). An untouched/default install produces the exact same values already hardcoded in style-editor-block.css today, so sites that never touch this setting see no visible change. Reference: themegrill/spacious-pro#204 fixed the identical bug in Spacious Pro. Ported the same two-function shape (dynamic CSS + separate font loader on a different hook), adapted to Kirki's architecture since this theme has no independent dynamic-CSS class. Closes themegrill/flash-pro#39 Co-Authored-By: Claude Sonnet 5 --- functions.php | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/functions.php b/functions.php index 88d274a..e6866b7 100644 --- a/functions.php +++ b/functions.php @@ -121,11 +121,57 @@ function flash_setup() { * @since Flash 1.3.5 */ function flash_block_editor_styles() { - wp_enqueue_style( 'flash-editor-googlefonts', '//fonts.googleapis.com/css?family=Montserrat:400,700&display=swap' ); wp_enqueue_style( 'flash-block-editor-styles', get_template_directory_uri() . '/style-editor-block.css' ); + + $editor_css = flash_block_editor_dynamic_css(); + + if ( $editor_css ) { + wp_add_inline_style( 'flash-block-editor-styles', $editor_css ); + } } add_action( 'enqueue_block_editor_assets', 'flash_block_editor_styles', 1, 1 ); +function flash_block_editor_dynamic_css() { + $default = array( + 'font-family' => 'Montserrat', + 'variant' => 'regular', + 'font-size' => '14px', + 'line-height' => '1.5', + 'letter-spacing' => '0', + 'color' => '#333333', + 'text-transform' => 'none', + 'text-align' => 'inherit', + ); + + $font = wp_parse_args( get_theme_mod( 'flash_body_font', $default ), $default ); + + return '.editor-styles-wrapper, .editor-styles-wrapper > * { font-family: ' . esc_html( $font['font-family'] ) . ', sans-serif; font-size: ' . esc_html( $font['font-size'] ) . '; line-height: ' . esc_html( $font['line-height'] ) . '; letter-spacing: ' . esc_html( $font['letter-spacing'] ) . '; color: ' . esc_html( $font['color'] ) . '; text-transform: ' . esc_html( $font['text-transform'] ) . '; text-align: ' . esc_html( $font['text-align'] ) . '; }'; +} + +function flash_block_editor_fonts() { + if ( ! is_admin() ) { + return; + } + + $default = array( + 'font-family' => 'Montserrat', + 'variant' => 'regular', + ); + + $font = wp_parse_args( get_theme_mod( 'flash_body_font', $default ), $default ); + $family = $font['font-family']; + + if ( ! \Kirki\Module\Webfonts\Fonts::is_google_font( $family ) ) { + return; + } + + $weight = 'italic' === $font['variant'] ? '400i' : str_replace( array( 'regular', 'bold', 'italic' ), array( '400', '', 'i' ), $font['variant'] ); + $url = 'https://fonts.googleapis.com/css?family=' . str_replace( ' ', '+', trim( $family ) ) . ':' . $weight . '&subset=cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai&display=swap'; + + wp_enqueue_style( 'flash-editor-googlefonts', $url ); +} +add_action( 'enqueue_block_assets', 'flash_block_editor_fonts' ); + // Theme version. $flash_theme = wp_get_theme(); define( 'FLASH_THEME_VERSION', $flash_theme->get( 'Version' ) ); From 6e21087baaccdddeccef73df4d5a5ed43965466b Mon Sep 17 00:00:00 2001 From: rg755421 Date: Tue, 29 Sep 2026 10:15:39 +0545 Subject: [PATCH 2/5] Test - Add a regression spec for the block editor typography sync The repo's ClaudeGrill QA gate refuses to run the suite on a PR that changes product source with no matching spec. Adds a "block-editor" area and a fresh-tier spec that opens a new post, waits for the actual Google Fonts request the new flash_block_editor_fonts() makes, and asserts the real iframe's .editor-styles-wrapper computed font-family, size and color match the theme's own documented default - guarding both functions this PR adds against a silent regression. Co-Authored-By: Claude Sonnet 5 --- .themegrill-qa/suite.json | 6 +++ .../block-editor/typography-sync.spec.ts | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/e2e/specs/block-editor/typography-sync.spec.ts diff --git a/.themegrill-qa/suite.json b/.themegrill-qa/suite.json index 81e5416..01b1845 100644 --- a/.themegrill-qa/suite.json +++ b/.themegrill-qa/suite.json @@ -193,6 +193,12 @@ "js/isotope*.js", "js/waypoints*.js", "js/jquery.counterup*.js" + ], + "block-editor": [ + "functions.php", + "inc/customizer.php", + "inc/kirki/**", + "style-editor-block.css" ] } } diff --git a/tests/e2e/specs/block-editor/typography-sync.spec.ts b/tests/e2e/specs/block-editor/typography-sync.spec.ts new file mode 100644 index 0000000..31074ee --- /dev/null +++ b/tests/e2e/specs/block-editor/typography-sync.spec.ts @@ -0,0 +1,42 @@ +import { test, expect } from "../../fixtures"; +import { ADMIN_STATE, hasAdminCredentials } from "../../utils/login"; + +test.use({ storageState: ADMIN_STATE }); + +/** + * @area block-editor + * @tier fresh + * @source functions.php (flash_block_editor_dynamic_css, flash_block_editor_fonts) + * @guards themegrill/flash-pro#39 + * @why The block editor's canvas used to show a hardcoded Montserrat/#333 + * regardless of Customize > Global > Typography > Base, and even that + * hardcoded font never actually loaded inside the iframe (it was + * enqueued on a hook whose payload doesn't reach it). On a fresh/default + * install this guards that the canvas renders the theme's own + * documented default font, size and color, and that the actual Google + * Font file is requested inside the iframe - not just declared in CSS. + */ +test("the block editor canvas reflects the default body typography and loads the font @fresh @block-editor", async ({ + page, +}) => { + test.skip(!hasAdminCredentials(), "needs TGQA_ADMIN_USER / TGQA_ADMIN_PASS"); + + const fontRequest = page.waitForResponse( + (response) => + response.url().includes("fonts.googleapis.com/css") && + response.url().includes("family=Montserrat"), + { timeout: 15000 }, + ); + + await page.goto("/wp-admin/post-new.php"); + + const frame = page.frameLocator('iframe[name="editor-canvas"]'); + const wrapper = frame.locator(".editor-styles-wrapper").first(); + await expect(wrapper).toBeVisible(); + + await expect(wrapper).toHaveCSS("font-family", /Montserrat/); + await expect(wrapper).toHaveCSS("font-size", "14px"); + await expect(wrapper).toHaveCSS("color", "rgb(51, 51, 51)"); + + await fontRequest; +}); From d6cc18fef4839ee6d642d7f0ec0b6ef67e12c49e Mon Sep 17 00:00:00 2001 From: rg755421 Date: Tue, 29 Sep 2026 10:38:05 +0545 Subject: [PATCH 3/5] Fix - Copilot review: editor typography dropped weight, style, quoting Same finding as themegrill/flash-pro#132: Kirki's own front-end output converts the saved variant into font-weight and font-style, but the new editor CSS never emitted either property, so Italic/Bold choices in Global > Typography > Base rendered upright/regular in the editor while the front end showed them correctly styled. Fixed by deriving font-weight/font-style from variant the same way Kirki's Field/CSS/Typography.php does, and by quoting a multi-word font-family the same way Kirki's Font_Family::process_value() does. Also switched esc_html() to wp_strip_all_tags() - esc_html() was escaping the double quotes this fix adds into ", corrupting the CSS; wp_strip_all_tags() is what Kirki's own CSS module uses for this exact kind of output. Verified with 14 new isolated-test assertions (33 total, all pass). Co-Authored-By: Claude Sonnet 5 --- functions.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/functions.php b/functions.php index e6866b7..c330dec 100644 --- a/functions.php +++ b/functions.php @@ -145,7 +145,16 @@ function flash_block_editor_dynamic_css() { $font = wp_parse_args( get_theme_mod( 'flash_body_font', $default ), $default ); - return '.editor-styles-wrapper, .editor-styles-wrapper > * { font-family: ' . esc_html( $font['font-family'] ) . ', sans-serif; font-size: ' . esc_html( $font['font-size'] ) . '; line-height: ' . esc_html( $font['line-height'] ) . '; letter-spacing: ' . esc_html( $font['letter-spacing'] ) . '; color: ' . esc_html( $font['color'] ) . '; text-transform: ' . esc_html( $font['text-transform'] ) . '; text-align: ' . esc_html( $font['text-align'] ) . '; }'; + $family = $font['font-family']; + if ( false !== strpos( $family, ' ' ) && false === strpos( $family, '"' ) ) { + $family = '"' . $family . '"'; + } + + $font_weight = str_replace( 'italic', '', $font['variant'] ); + $font_weight = in_array( $font_weight, array( '', 'regular' ), true ) ? '400' : $font_weight; + $font_style = false !== strpos( $font['variant'], 'italic' ) ? 'italic' : 'normal'; + + return '.editor-styles-wrapper, .editor-styles-wrapper > * { font-family: ' . wp_strip_all_tags( $family ) . ', sans-serif; font-size: ' . wp_strip_all_tags( $font['font-size'] ) . '; font-weight: ' . wp_strip_all_tags( $font_weight ) . '; font-style: ' . wp_strip_all_tags( $font_style ) . '; line-height: ' . wp_strip_all_tags( $font['line-height'] ) . '; letter-spacing: ' . wp_strip_all_tags( $font['letter-spacing'] ) . '; color: ' . wp_strip_all_tags( $font['color'] ) . '; text-transform: ' . wp_strip_all_tags( $font['text-transform'] ) . '; text-align: ' . wp_strip_all_tags( $font['text-align'] ) . '; }'; } function flash_block_editor_fonts() { From 25cd8207266d117520a353bbcaa5704a7315de43 Mon Sep 17 00:00:00 2001 From: rg755421 Date: Wed, 30 Sep 2026 11:09:08 +0545 Subject: [PATCH 4/5] Fix - Match the editor text color to the free front end, drop the Kirki body color Post content is #606060 on the free front end (Text Color only reaches widgets and section text). The editor stayed #333, and the previous head still copied the Kirki body color, which never reaches post content. Set the editor's static color to #606060 and stop writing the body color into the editor. Co-Authored-By: Claude Sonnet 5.5 --- functions.php | 3 +-- style-editor-block.css | 4 ++-- tests/e2e/specs/block-editor/typography-sync.spec.ts | 12 +++++++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/functions.php b/functions.php index c330dec..a0d5a6e 100644 --- a/functions.php +++ b/functions.php @@ -138,7 +138,6 @@ function flash_block_editor_dynamic_css() { 'font-size' => '14px', 'line-height' => '1.5', 'letter-spacing' => '0', - 'color' => '#333333', 'text-transform' => 'none', 'text-align' => 'inherit', ); @@ -154,7 +153,7 @@ function flash_block_editor_dynamic_css() { $font_weight = in_array( $font_weight, array( '', 'regular' ), true ) ? '400' : $font_weight; $font_style = false !== strpos( $font['variant'], 'italic' ) ? 'italic' : 'normal'; - return '.editor-styles-wrapper, .editor-styles-wrapper > * { font-family: ' . wp_strip_all_tags( $family ) . ', sans-serif; font-size: ' . wp_strip_all_tags( $font['font-size'] ) . '; font-weight: ' . wp_strip_all_tags( $font_weight ) . '; font-style: ' . wp_strip_all_tags( $font_style ) . '; line-height: ' . wp_strip_all_tags( $font['line-height'] ) . '; letter-spacing: ' . wp_strip_all_tags( $font['letter-spacing'] ) . '; color: ' . wp_strip_all_tags( $font['color'] ) . '; text-transform: ' . wp_strip_all_tags( $font['text-transform'] ) . '; text-align: ' . wp_strip_all_tags( $font['text-align'] ) . '; }'; + return '.editor-styles-wrapper, .editor-styles-wrapper > * { font-family: ' . wp_strip_all_tags( $family ) . ', sans-serif; font-size: ' . wp_strip_all_tags( $font['font-size'] ) . '; font-weight: ' . wp_strip_all_tags( $font_weight ) . '; font-style: ' . wp_strip_all_tags( $font_style ) . '; line-height: ' . wp_strip_all_tags( $font['line-height'] ) . '; letter-spacing: ' . wp_strip_all_tags( $font['letter-spacing'] ) . '; text-transform: ' . wp_strip_all_tags( $font['text-transform'] ) . '; text-align: ' . wp_strip_all_tags( $font['text-align'] ) . '; }'; } function flash_block_editor_fonts() { diff --git a/style-editor-block.css b/style-editor-block.css index 10b0c5f..1f7719d 100644 --- a/style-editor-block.css +++ b/style-editor-block.css @@ -1,7 +1,7 @@ /* Basic Block Editor CSS */ .editor-styles-wrapper { background-color: #ffffff; - color: #333; + color: #606060; font-size: 14px; font-family: Montserrat, sans-serif; line-height: 1.5; @@ -10,7 +10,7 @@ .editor-styles-wrapper > * { font-family: Montserrat, sans-serif; - color: #333; + color: #606060; } .editor-styles-wrapper .wp-block.editor-post-title__block .editor-post-title__input { diff --git a/tests/e2e/specs/block-editor/typography-sync.spec.ts b/tests/e2e/specs/block-editor/typography-sync.spec.ts index 31074ee..a524f07 100644 --- a/tests/e2e/specs/block-editor/typography-sync.spec.ts +++ b/tests/e2e/specs/block-editor/typography-sync.spec.ts @@ -15,6 +15,8 @@ test.use({ storageState: ADMIN_STATE }); * install this guards that the canvas renders the theme's own * documented default font, size and color, and that the actual Google * Font file is requested inside the iframe - not just declared in CSS. + * Text color must equal what the front end gives post content (#606060 + * from style.css in the free theme): the editor used to stay #333. */ test("the block editor canvas reflects the default body typography and loads the font @fresh @block-editor", async ({ page, @@ -36,7 +38,15 @@ test("the block editor canvas reflects the default body typography and loads the await expect(wrapper).toHaveCSS("font-family", /Montserrat/); await expect(wrapper).toHaveCSS("font-size", "14px"); - await expect(wrapper).toHaveCSS("color", "rgb(51, 51, 51)"); + + // Front-end colour of post content, from the first post. + const front = await page.context().newPage(); + await front.goto("/?p=1"); + const content = front.locator(".entry-content").first(); + test.skip((await content.count()) === 0, "needs a post with ID 1"); + const frontColor = await content.evaluate((e) => getComputedStyle(e).color); + await front.close(); + await expect(wrapper).toHaveCSS("color", frontColor); await fontRequest; }); From 9fc07119427af071971018bd152bb19df4916dc2 Mon Sep 17 00:00:00 2001 From: rg755421 Date: Wed, 30 Sep 2026 12:08:27 +0545 Subject: [PATCH 5/5] Fix - Sync only what the free front end applies to post content, and guard the editor font Free's body typography only offers family and variant, post text and headings take their color from Heading Colors (or the color scheme), and links only change when Primary Color differs from the scheme default. Mirror exactly that in the editor, and load the canvas font only in block editor screens when Kirki's font helper exists (a missing class otherwise fatals the editor). Co-Authored-By: Claude Sonnet 5.5 --- functions.php | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/functions.php b/functions.php index a0d5a6e..eda369b 100644 --- a/functions.php +++ b/functions.php @@ -133,15 +133,11 @@ function flash_block_editor_styles() { function flash_block_editor_dynamic_css() { $default = array( - 'font-family' => 'Montserrat', - 'variant' => 'regular', - 'font-size' => '14px', - 'line-height' => '1.5', - 'letter-spacing' => '0', - 'text-transform' => 'none', - 'text-align' => 'inherit', + 'font-family' => 'Montserrat', + 'variant' => 'regular', ); + // The free theme's body typography only offers family and variant, so only those reach post content. $font = wp_parse_args( get_theme_mod( 'flash_body_font', $default ), $default ); $family = $font['font-family']; @@ -153,11 +149,39 @@ function flash_block_editor_dynamic_css() { $font_weight = in_array( $font_weight, array( '', 'regular' ), true ) ? '400' : $font_weight; $font_style = false !== strpos( $font['variant'], 'italic' ) ? 'italic' : 'normal'; - return '.editor-styles-wrapper, .editor-styles-wrapper > * { font-family: ' . wp_strip_all_tags( $family ) . ', sans-serif; font-size: ' . wp_strip_all_tags( $font['font-size'] ) . '; font-weight: ' . wp_strip_all_tags( $font_weight ) . '; font-style: ' . wp_strip_all_tags( $font_style ) . '; line-height: ' . wp_strip_all_tags( $font['line-height'] ) . '; letter-spacing: ' . wp_strip_all_tags( $font['letter-spacing'] ) . '; text-transform: ' . wp_strip_all_tags( $font['text-transform'] ) . '; text-align: ' . wp_strip_all_tags( $font['text-align'] ) . '; }'; + $css = '.editor-styles-wrapper, .editor-styles-wrapper > * { font-family: ' . wp_strip_all_tags( $family ) . ', sans-serif; font-weight: ' . wp_strip_all_tags( $font_weight ) . '; font-style: ' . wp_strip_all_tags( $font_style ) . '; }'; + + /* + * The front end colors post text and headings with Colors > Heading Colors > Headings + * (or the color scheme's text color), and only overrides the stylesheet's #606060 when + * it differs from the default. The editor follows the same rule. + */ + $color_scheme = flash_get_color_scheme(); + $main_color = get_theme_mod( 'main_text_color', $color_scheme[2] ); + + if ( 'default' !== get_theme_mod( 'color_scheme', 'default' ) || $main_color !== $color_scheme[2] ) { + $css .= '.editor-styles-wrapper, .editor-styles-wrapper > * { color: ' . wp_strip_all_tags( $main_color ) . '; }'; + } + + // Primary Color: the front end only colors links in post content when it differs from the scheme default. + $link_color = get_theme_mod( 'link_color', $color_scheme[1] ); + + if ( $link_color !== $color_scheme[1] ) { + $css .= '.editor-styles-wrapper a { color: ' . wp_strip_all_tags( $link_color ) . '; }'; + } + + return $css; } function flash_block_editor_fonts() { - if ( ! is_admin() ) { + // Only load the canvas font in the block editor. Kirki's font helper is missing when another Kirki version takes over. + if ( ! is_admin() || ! class_exists( '\Kirki\Module\Webfonts\Fonts' ) ) { + return; + } + + $screen = get_current_screen(); + + if ( ! $screen || ! $screen->is_block_editor() ) { return; }