diff --git a/src/command/render/filters.ts b/src/command/render/filters.ts
index bae4f4d1a10..1081b5fc6ec 100644
--- a/src/command/render/filters.ts
+++ b/src/command/render/filters.ts
@@ -9,6 +9,7 @@ import { existsSync } from "../../deno_ral/fs.ts";
import {
kBibliography,
kBrand,
+ kBrandMode,
kCitationLocation,
kCiteMethod,
kClearCellOptions,
@@ -909,6 +910,7 @@ const extractTypstFilterParams = (format: Format) => {
[kTocIndent]: format.metadata[kTocIndent],
[kLogo]: format.metadata[kLogo],
[kCssPropertyProcessing]: format.metadata[kCssPropertyProcessing],
+ [kBrandMode]: format.metadata[kBrandMode],
[kHtmlPreTagProcessing]: format.metadata[kHtmlPreTagProcessing],
};
};
diff --git a/src/config/constants.ts b/src/config/constants.ts
index d322ad6fd28..988e34f1ce4 100644
--- a/src/config/constants.ts
+++ b/src/config/constants.ts
@@ -141,6 +141,7 @@ export const kFontPaths = "font-paths";
export const kHtmlTableProcessing = "html-table-processing";
export const kHtmlPreTagProcessing = "html-pre-tag-processing";
export const kCssPropertyProcessing = "css-property-processing";
+export const kBrandMode = "brand-mode";
export const kUseRsvgConvert = "use-rsvg-convert";
export const kValidateYaml = "validate-yaml";
diff --git a/src/resources/editor/tools/vs-code.mjs b/src/resources/editor/tools/vs-code.mjs
index 3652d57fe17..af71dc09979 100644
--- a/src/resources/editor/tools/vs-code.mjs
+++ b/src/resources/editor/tools/vs-code.mjs
@@ -15621,6 +15621,22 @@ var require_yaml_intelligence_resources = __commonJS({
},
description: "The paper size for the document.\n"
},
+ {
+ name: "brand-mode",
+ schema: {
+ enum: [
+ "light",
+ "dark"
+ ]
+ },
+ default: "light",
+ tags: {
+ formats: [
+ "typst"
+ ]
+ },
+ description: "The brand mode to use for rendering the Typst document, `light` or `dark`.\n"
+ },
{
name: "layout",
schema: {
@@ -20935,6 +20951,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -21095,6 +21112,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -23419,6 +23437,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -23772,6 +23791,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -24022,7 +24042,8 @@ var require_yaml_intelligence_resources = __commonJS({
"Disambiguating year suffix in author-date styles (e.g. \u201Ca\u201D in \u201CDoe,\n1999a\u201D).",
"Manuscript configuration",
"internal-schema-hack",
- "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto\u2019s default order\nis \u2018knitr\u2019, \u2018jupyter\u2019, \u2018markdown\u2019, \u2018julia\u2019."
+ "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto\u2019s default order\nis \u2018knitr\u2019, \u2018jupyter\u2019, \u2018markdown\u2019, \u2018julia\u2019.",
+ "The brand mode to use for rendering the Typst document,\nlight or dark."
],
"schema/external-schemas.yml": [
{
@@ -24251,12 +24272,12 @@ var require_yaml_intelligence_resources = __commonJS({
mermaid: "%%"
},
"handlers/mermaid/schema.yml": {
- _internalId: 194252,
+ _internalId: 194259,
type: "object",
description: "be an object",
properties: {
"mermaid-format": {
- _internalId: 194244,
+ _internalId: 194251,
type: "enum",
enum: [
"png",
@@ -24272,7 +24293,7 @@ var require_yaml_intelligence_resources = __commonJS({
exhaustiveCompletions: true
},
theme: {
- _internalId: 194251,
+ _internalId: 194258,
type: "anyOf",
anyOf: [
{
@@ -31402,6 +31423,51 @@ function guessChunkOptionsFormat(options) {
}
// ../yaml-validation/validator.ts
+function createNiceError(obj) {
+ const {
+ violatingObject,
+ source,
+ message
+ } = obj;
+ const locF = mappedIndexToLineCol(source);
+ let location;
+ try {
+ location = {
+ start: locF(violatingObject.start),
+ end: locF(violatingObject.end)
+ };
+ } catch (_e) {
+ location = {
+ start: { line: 0, column: 0 },
+ end: { line: 0, column: 0 }
+ };
+ }
+ const mapResult = source.map(violatingObject.start);
+ const fileName = mapResult ? mapResult.originalString.fileName : void 0;
+ return {
+ heading: message,
+ error: [],
+ info: {},
+ fileName,
+ location,
+ sourceContext: createSourceContext(violatingObject.source, {
+ start: violatingObject.start,
+ end: violatingObject.end
+ })
+ };
+}
+var NoExprTag = class extends Error {
+ constructor(violatingObject, source) {
+ super(`Unexpected !expr tag`);
+ this.name = "NoExprTag";
+ this.niceError = createNiceError({
+ violatingObject,
+ source,
+ message: "!expr tags are not allowed in Quarto outside of knitr code cells."
+ });
+ }
+ niceError;
+};
var ValidationContext = class {
instancePath;
root;
@@ -31793,6 +31859,9 @@ function validateObject(value, schema2, context) {
}
}
}
+ if (value.result && typeof value.result === "object" && !Array.isArray(value.result) && value.result.tag === "!expr") {
+ throw new NoExprTag(value, value.source);
+ }
throw new InternalError(`Couldn't locate key ${key}`);
};
const inspectedProps = /* @__PURE__ */ new Set();
diff --git a/src/resources/editor/tools/yaml/web-worker.js b/src/resources/editor/tools/yaml/web-worker.js
index 8eb91e50487..7bc0b7f3045 100644
--- a/src/resources/editor/tools/yaml/web-worker.js
+++ b/src/resources/editor/tools/yaml/web-worker.js
@@ -15622,6 +15622,22 @@ try {
},
description: "The paper size for the document.\n"
},
+ {
+ name: "brand-mode",
+ schema: {
+ enum: [
+ "light",
+ "dark"
+ ]
+ },
+ default: "light",
+ tags: {
+ formats: [
+ "typst"
+ ]
+ },
+ description: "The brand mode to use for rendering the Typst document, `light` or `dark`.\n"
+ },
{
name: "layout",
schema: {
@@ -20936,6 +20952,7 @@ try {
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -21096,6 +21113,7 @@ try {
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -23420,6 +23438,7 @@ try {
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -23773,6 +23792,7 @@ try {
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -24023,7 +24043,8 @@ try {
"Disambiguating year suffix in author-date styles (e.g. \u201Ca\u201D in \u201CDoe,\n1999a\u201D).",
"Manuscript configuration",
"internal-schema-hack",
- "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto\u2019s default order\nis \u2018knitr\u2019, \u2018jupyter\u2019, \u2018markdown\u2019, \u2018julia\u2019."
+ "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto\u2019s default order\nis \u2018knitr\u2019, \u2018jupyter\u2019, \u2018markdown\u2019, \u2018julia\u2019.",
+ "The brand mode to use for rendering the Typst document,\nlight or dark."
],
"schema/external-schemas.yml": [
{
@@ -24252,12 +24273,12 @@ try {
mermaid: "%%"
},
"handlers/mermaid/schema.yml": {
- _internalId: 194252,
+ _internalId: 194259,
type: "object",
description: "be an object",
properties: {
"mermaid-format": {
- _internalId: 194244,
+ _internalId: 194251,
type: "enum",
enum: [
"png",
@@ -24273,7 +24294,7 @@ try {
exhaustiveCompletions: true
},
theme: {
- _internalId: 194251,
+ _internalId: 194258,
type: "anyOf",
anyOf: [
{
@@ -31416,6 +31437,51 @@ ${tidyverseInfo(
}
// ../yaml-validation/validator.ts
+ function createNiceError(obj) {
+ const {
+ violatingObject,
+ source,
+ message
+ } = obj;
+ const locF = mappedIndexToLineCol(source);
+ let location;
+ try {
+ location = {
+ start: locF(violatingObject.start),
+ end: locF(violatingObject.end)
+ };
+ } catch (_e) {
+ location = {
+ start: { line: 0, column: 0 },
+ end: { line: 0, column: 0 }
+ };
+ }
+ const mapResult = source.map(violatingObject.start);
+ const fileName = mapResult ? mapResult.originalString.fileName : void 0;
+ return {
+ heading: message,
+ error: [],
+ info: {},
+ fileName,
+ location,
+ sourceContext: createSourceContext(violatingObject.source, {
+ start: violatingObject.start,
+ end: violatingObject.end
+ })
+ };
+ }
+ var NoExprTag = class extends Error {
+ constructor(violatingObject, source) {
+ super(`Unexpected !expr tag`);
+ this.name = "NoExprTag";
+ this.niceError = createNiceError({
+ violatingObject,
+ source,
+ message: "!expr tags are not allowed in Quarto outside of knitr code cells."
+ });
+ }
+ niceError;
+ };
var ValidationContext = class {
instancePath;
root;
@@ -31807,6 +31873,9 @@ ${tidyverseInfo(
}
}
}
+ if (value.result && typeof value.result === "object" && !Array.isArray(value.result) && value.result.tag === "!expr") {
+ throw new NoExprTag(value, value.source);
+ }
throw new InternalError(`Couldn't locate key ${key}`);
};
const inspectedProps = /* @__PURE__ */ new Set();
diff --git a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json
index 9ef575dc130..5c1e641f1fb 100644
--- a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json
+++ b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json
@@ -8593,6 +8593,22 @@
},
"description": "The paper size for the document.\n"
},
+ {
+ "name": "brand-mode",
+ "schema": {
+ "enum": [
+ "light",
+ "dark"
+ ]
+ },
+ "default": "light",
+ "tags": {
+ "formats": [
+ "typst"
+ ]
+ },
+ "description": "The brand mode to use for rendering the Typst document, `light` or `dark`.\n"
+ },
{
"name": "layout",
"schema": {
@@ -13907,6 +13923,7 @@
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -14067,6 +14084,7 @@
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -16391,6 +16409,7 @@
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -16744,6 +16763,7 @@
"Number of matches to display (defaults to 20)",
"Matches after which to collapse additional results",
"Provide button for copying search link",
+ "When false, do not merge navbar crumbs into the crumbs in\nsearch.json.",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"One or more keys that will act as a shortcut to launch search (single\ncharacters)",
"Whether to include search result parents when displaying items in\nsearch results (when possible).",
@@ -16994,7 +17014,8 @@
"Disambiguating year suffix in author-date styles (e.g. “a” in “Doe,\n1999a”).",
"Manuscript configuration",
"internal-schema-hack",
- "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto’s default order\nis ‘knitr’, ‘jupyter’, ‘markdown’, ‘julia’."
+ "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto’s default order\nis ‘knitr’, ‘jupyter’, ‘markdown’, ‘julia’.",
+ "The brand mode to use for rendering the Typst document,\nlight or dark."
],
"schema/external-schemas.yml": [
{
@@ -17223,12 +17244,12 @@
"mermaid": "%%"
},
"handlers/mermaid/schema.yml": {
- "_internalId": 194252,
+ "_internalId": 194259,
"type": "object",
"description": "be an object",
"properties": {
"mermaid-format": {
- "_internalId": 194244,
+ "_internalId": 194251,
"type": "enum",
"enum": [
"png",
@@ -17244,7 +17265,7 @@
"exhaustiveCompletions": true
},
"theme": {
- "_internalId": 194251,
+ "_internalId": 194258,
"type": "anyOf",
"anyOf": [
{
diff --git a/src/resources/filters/modules/typst_css.lua b/src/resources/filters/modules/typst_css.lua
index 45725d5ad65..97a05daeaf2 100644
--- a/src/resources/filters/modules/typst_css.lua
+++ b/src/resources/filters/modules/typst_css.lua
@@ -176,7 +176,7 @@ local typst_named_colors = {
lime = '#01ff70',
}
-local brandMode = 'light' --- ugh
+local brandMode = param('brand-mode') or 'light'
-- css can have fraction or percent
-- typst can have int or percent
@@ -748,6 +748,7 @@ local function expand_side_shorthand(items, context, warnings)
end
return {
+ set_brand_mode = set_brand_mode,
parse_color = parse_color,
parse_opacity = parse_opacity,
output_color = output_color,
diff --git a/src/resources/filters/quarto-post/cell-renderings.lua b/src/resources/filters/quarto-post/cell-renderings.lua
index b3486b8326f..4829a3920cf 100644
--- a/src/resources/filters/quarto-post/cell-renderings.lua
+++ b/src/resources/filters/quarto-post/cell-renderings.lua
@@ -47,6 +47,13 @@ function choose_cell_renderings()
if quarto.format.isHtmlOutput() and lightDiv and darkDiv then
blocks:insert(pandoc.Div(lightDiv.content, pandoc.Attr("", {'light-content'}, {})))
blocks:insert(pandoc.Div(darkDiv.content, pandoc.Attr("", {'dark-content'}, {})))
+ elseif quarto.format.isTypstOutput() and lightDiv and darkDiv then
+ local brandMode = param('brand-mode') or 'light'
+ if brandMode == 'light' then
+ blocks:insert(lightDiv)
+ elseif brandMode == 'dark' then
+ blocks:insert(darkDiv)
+ end
else
blocks:insert(lightDiv or darkDiv)
end
diff --git a/src/resources/filters/quarto-post/typst-brand-yaml.lua b/src/resources/filters/quarto-post/typst-brand-yaml.lua
index 81a6f782474..6650459c7e7 100644
--- a/src/resources/filters/quarto-post/typst-brand-yaml.lua
+++ b/src/resources/filters/quarto-post/typst-brand-yaml.lua
@@ -59,7 +59,7 @@ function render_typst_brand_yaml()
return {
Pandoc = function(pandoc0)
local brand = param('brand')
- local brandMode = 'light'
+ local brandMode = param('brand-mode') or 'light'
brand = brand and brand[brandMode]
if brand and brand.processedData then
-- color
@@ -300,7 +300,7 @@ function render_typst_brand_yaml()
end
end,
Meta = function(meta)
- local brandMode = 'light'
+ local brandMode = param('brand-mode') or 'light'
-- it can contain the path but we want to store an object here
if not meta.brand or pandoc.utils.type(meta.brand) == 'Inlines' then
meta.brand = {}
diff --git a/src/resources/schema/document-layout.yml b/src/resources/schema/document-layout.yml
index dd8795d35ff..ee0beac8f69 100644
--- a/src/resources/schema/document-layout.yml
+++ b/src/resources/schema/document-layout.yml
@@ -48,6 +48,15 @@
description: |
The paper size for the document.
+- name: brand-mode
+ schema:
+ enum: [light, dark]
+ default: light
+ tags:
+ formats: [typst]
+ description: |
+ The brand mode to use for rendering the Typst document, `light` or `dark`.
+
- name: layout
schema:
maybeArrayOf: string
diff --git a/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-named-color-dark.qmd b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-named-color-dark.qmd
new file mode 100644
index 00000000000..161215052f8
--- /dev/null
+++ b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-named-color-dark.qmd
@@ -0,0 +1,39 @@
+---
+title: Translate brand named color references from CSS to Typst
+format:
+ typst:
+ keep-typ: true
+ brand-mode: dark
+brand:
+ light:
+ color:
+ palette:
+ dark-grey: "#444"
+ blue: "#82aeef"
+ dark:
+ color:
+ palette:
+ dark-grey: "#222"
+ blue: "#415777"
+_quarto:
+ tests:
+ typst:
+ ensureTypstFileRegexMatches:
+ -
+ - '#block\(fill: brand-color\.dark-grey\)\[\s*#set text\(fill: brand-color\.blue\);'
+ - 'blue: rgb\("#415777"\)'
+ - 'dark-grey: rgb\("#222"\)'
+ - []
+---
+
+
+```{=typst}
+// stopgap to make this look ok
+#set block(inset: 6pt)
+```
+
+:::{style="background-color: var(--brand-dark-grey); color: var(--brand-blue)"}
+This div is blue on dark grey.
+:::
+
+{{< lipsum 2 >}}
diff --git a/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-named-color.qmd b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-named-color.qmd
new file mode 100644
index 00000000000..63b6167b72d
--- /dev/null
+++ b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-named-color.qmd
@@ -0,0 +1,38 @@
+---
+title: Translate brand named color references from CSS to Typst
+format:
+ typst:
+ keep-typ: true
+brand:
+ light:
+ color:
+ palette:
+ dark-grey: "#444"
+ blue: "#82aeef"
+ dark:
+ color:
+ palette:
+ dark-grey: "#222"
+ blue: "#415777"
+_quarto:
+ tests:
+ typst:
+ ensureTypstFileRegexMatches:
+ -
+ - '#block\(fill: brand-color\.dark-grey\)\[\s*#set text\(fill: brand-color\.blue\);'
+ - 'blue: rgb\("#82aeef"\)'
+ - 'dark-grey: rgb\("#444"\)'
+ - []
+---
+
+
+```{=typst}
+// stopgap to make this look ok
+#set block(inset: 6pt)
+```
+
+:::{style="background-color: var(--brand-dark-grey); color: var(--brand-blue)"}
+This div is blue on dark grey.
+:::
+
+{{< lipsum 2 >}}
diff --git a/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-wrong-named-color-dark.qmd b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-wrong-named-color-dark.qmd
new file mode 100644
index 00000000000..b416c2bf7bf
--- /dev/null
+++ b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-wrong-named-color-dark.qmd
@@ -0,0 +1,42 @@
+---
+title: Translate brand named color references from CSS to Typst
+format:
+ typst:
+ keep-typ: true
+ brand-mode: dark
+brand:
+ light:
+ color:
+ palette:
+ light-grey: "#444"
+ blue: "#82aeef"
+ dark:
+ color:
+ palette:
+ dark-grey: "#222"
+ blue: "#415777"
+_quarto:
+ tests:
+ typst:
+ ensureTypstFileRegexMatches:
+ -
+ - 'blue: rgb\("#415777"\)'
+ - 'dark-grey: rgb\("#222"\)'
+ - '#set text\(fill: brand-color\.blue\);'
+ -
+ printsMessage:
+ level: INFO
+ regex: 'unknown brand color light-grey'
+---
+
+
+```{=typst}
+// stopgap to make this look ok
+#set block(inset: 6pt)
+```
+
+:::{style="background-color: var(--brand-light-grey); color: var(--brand-blue)"}
+This div is blue on dark grey.
+:::
+
+{{< lipsum 2 >}}
diff --git a/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-wrong-named-color-light.qmd b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-wrong-named-color-light.qmd
new file mode 100644
index 00000000000..46a248c50db
--- /dev/null
+++ b/tests/docs/smoke-all/typst/brand-yaml/color/typst-css-duobrand-wrong-named-color-light.qmd
@@ -0,0 +1,42 @@
+---
+title: Translate brand named color references from CSS to Typst
+format:
+ typst:
+ keep-typ: true
+ brand-mode: light
+brand:
+ light:
+ color:
+ palette:
+ light-grey: "#444"
+ blue: "#82aeef"
+ dark:
+ color:
+ palette:
+ dark-grey: "#222"
+ blue: "#415777"
+_quarto:
+ tests:
+ typst:
+ ensureTypstFileRegexMatches:
+ -
+ - 'blue: rgb\("#82aeef"\)'
+ - 'light-grey: rgb\("#444"\)'
+ - '#set text\(fill: brand-color\.blue\);'
+ -
+ printsMessage:
+ level: INFO
+ regex: 'unknown brand color dark-grey'
+---
+
+
+```{=typst}
+// stopgap to make this look ok
+#set block(inset: 6pt)
+```
+
+:::{style="background-color: var(--brand-dark-grey); color: var(--brand-blue)"}
+This div is blue on dark grey.
+:::
+
+{{< lipsum 2 >}}