From 7f39b62c2135527585d264b6b451e0082600383e Mon Sep 17 00:00:00 2001 From: Minh Tran <4847344+minhtt159@users.noreply.github.com> Date: Wed, 16 Sep 2026 02:07:29 +0200 Subject: [PATCH 1/2] fix(site): make code blocks legible in the light theme Code blocks were effectively invisible in Catppuccin Latte. Two causes. PaperMod hardcodes `color: rgb(213, 213, 214)` on `.md-content pre code` with no light-mode variant, because its own light `--code-block-bg` is near-black. theme.css moved that variable to Latte mantle but never overrode the literal, leaving untagged fences at 1.21:1 against the block. chroma.css served Latte tokens in light mode, and Latte's accents cannot reach the WCAG AA 4.5:1 minimum on a light surface: NameVariable, which is the bulk of a PromQL block, measured 2.17:1, comments 2.14, operators 2.30, numbers 2.45, strings 2.75. No lighter background fixes this - peach on pure white is still 2.97:1 - and darkening the accents toward Latte text leaves the worst at 3.33:1. The Catppuccin style guide's rule is "legibility always comes first, so please use your own judgement", so the code block now keeps a Mocha surface in both theme states and the Latte page frames it. This is also what PaperMod ships by default, and its copy button is already styled white-on-dark to suit. chroma.css collapses to the Mocha half, unscoped, which drops 55 lines. Its one deviation from the generated output is that every Comment* token plus LiteralStringDoc and LiteralStringHeredoc take overlay2 rather than overlay0 and surface2, which are 3.59:1 and 2.63:1; the style guide's Code Editors section specifies overlay2 for comments anyway. Measured in the browser on the SLO post, light and dark: pre code 1.21:1 -> 12.14:1 worst token 2.14:1 -> 6.22:1 tokens under AA 12 -> 0 Inline code is untouched and was already AA: Latte surface0 at 5.17:1 in light, Mocha surface0 at 8.69:1 in dark. Co-Authored-By: Claude Opus 5 --- assets/css/extended/chroma.css | 246 ++++++++++++--------------------- assets/css/extended/theme.css | 15 +- 2 files changed, 103 insertions(+), 158 deletions(-) diff --git a/assets/css/extended/chroma.css b/assets/css/extended/chroma.css index 3739fa9..3066113 100644 --- a/assets/css/extended/chroma.css +++ b/assets/css/extended/chroma.css @@ -1,164 +1,98 @@ -/* Chroma: catppuccin-latte, and catppuccin-mocha under [data-theme="dark"]. Generated with hugo gen chromastyles; block background comes from --code-block-bg. */ +/* Chroma: catppuccin-mocha in both theme states. Generated with hugo gen + chromastyles, then edited as noted below; the block background is + --code-block-bg (theme.css), mocha mantle in light and dark alike. -/* Other */ .chroma .x { color:#4c4f69 } -/* Error */ .chroma .err { color:#d20f39 } -/* CodeLine */ .chroma .cl { color:#4c4f69 } + Why not catppuccin-latte in light: Latte's accents cannot reach the WCAG AA + 4.5:1 minimum on any light surface. Measured against Latte mantle, comments + are 2.14:1, operators 2.30, numbers 2.45, strings 2.75, and NameVariable - + the metric names that are the bulk of a PromQL block - 2.17; peach on pure + white is still only 2.97. The style guide's rule is "legibility always comes + first, so please use your own judgement", so the code block stays Mocha and + the Latte page frames it. Every colour below is 4.75:1 or better on + --code-block-bg. + + One edit to the generated output: every Comment* token, LiteralStringDoc and + LiteralStringHeredoc take overlay2 #9399b2 (6.22:1) rather than the generated + overlay0 #6c7086 (3.59:1) and surface2 #585b70 (2.63:1), both under AA. The + style guide's Code Editors section specifies overlay2 for comments. */ + +/* Other */ .chroma .x { color:#cdd6f4 } +/* Error */ .chroma .err { color:#f38ba8 } +/* CodeLine */ .chroma .cl { color:#cdd6f4 } /* LineLink */ .chroma .lnlinks { outline:none;text-decoration:none;color:inherit } /* LineTableTD */ .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0; } /* LineTable */ .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0; } -/* LineHighlight */ .chroma .hl { background-color:#bcc0cc } -/* LineNumbersTable */ .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1 } -/* LineNumbers */ .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8c8fa1 } +/* LineHighlight */ .chroma .hl { background-color:#45475a } +/* LineNumbersTable */ .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c } +/* LineNumbers */ .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c } /* Line */ .chroma .line { display:flex; } -/* Keyword */ .chroma .k { color:#8839ef } -/* KeywordConstant */ .chroma .kc { color:#fe640b } -/* KeywordDeclaration */ .chroma .kd { color:#d20f39 } -/* KeywordNamespace */ .chroma .kn { color:#179299 } -/* KeywordPseudo */ .chroma .kp { color:#8839ef } -/* KeywordReserved */ .chroma .kr { color:#8839ef } -/* KeywordType */ .chroma .kt { color:#d20f39 } -/* NameAttribute */ .chroma .na { color:#1e66f5 } -/* NameClass */ .chroma .nc { color:#df8e1d } -/* NameConstant */ .chroma .no { color:#df8e1d } -/* NameDecorator */ .chroma .nd { color:#1e66f5;font-weight:bold } -/* NameEntity */ .chroma .ni { color:#179299 } -/* NameException */ .chroma .ne { color:#fe640b } -/* NameLabel */ .chroma .nl { color:#04a5e5 } -/* NameNamespace */ .chroma .nn { color:#fe640b } -/* NameOther */ .chroma .nx { color:#4c4f69 } -/* NameProperty */ .chroma .py { color:#fe640b } -/* NameTag */ .chroma .nt { color:#8839ef } -/* NameBuiltin */ .chroma .nb { color:#04a5e5 } -/* NameBuiltinPseudo */ .chroma .bp { color:#04a5e5 } -/* NameVariable */ .chroma .nv { color:#dc8a78 } -/* NameVariableClass */ .chroma .vc { color:#dc8a78 } -/* NameVariableGlobal */ .chroma .vg { color:#dc8a78 } -/* NameVariableInstance */ .chroma .vi { color:#dc8a78 } -/* NameVariableMagic */ .chroma .vm { color:#dc8a78 } -/* NameFunction */ .chroma .nf { color:#1e66f5 } -/* NameFunctionMagic */ .chroma .fm { color:#1e66f5 } -/* LiteralDate */ .chroma .ld { color:#4c4f69 } -/* LiteralString */ .chroma .s { color:#40a02b } -/* LiteralStringAffix */ .chroma .sa { color:#d20f39 } -/* LiteralStringBacktick */ .chroma .sb { color:#40a02b } -/* LiteralStringChar */ .chroma .sc { color:#40a02b } -/* LiteralStringDelimiter */ .chroma .dl { color:#1e66f5 } -/* LiteralStringDoc */ .chroma .sd { color:#9ca0b0 } -/* LiteralStringDouble */ .chroma .s2 { color:#40a02b } -/* LiteralStringEscape */ .chroma .se { color:#1e66f5 } -/* LiteralStringHeredoc */ .chroma .sh { color:#9ca0b0 } -/* LiteralStringInterpol */ .chroma .si { color:#40a02b } -/* LiteralStringOther */ .chroma .sx { color:#40a02b } -/* LiteralStringRegex */ .chroma .sr { color:#179299 } -/* LiteralStringSingle */ .chroma .s1 { color:#40a02b } -/* LiteralStringSymbol */ .chroma .ss { color:#40a02b } -/* LiteralNumber */ .chroma .m { color:#fe640b } -/* LiteralNumberBin */ .chroma .mb { color:#fe640b } -/* LiteralNumberFloat */ .chroma .mf { color:#fe640b } -/* LiteralNumberHex */ .chroma .mh { color:#fe640b } -/* LiteralNumberInteger */ .chroma .mi { color:#fe640b } -/* LiteralNumberIntegerLong */ .chroma .il { color:#fe640b } -/* LiteralNumberOct */ .chroma .mo { color:#fe640b } -/* Operator */ .chroma .o { color:#04a5e5;font-weight:bold } -/* OperatorWord */ .chroma .ow { color:#04a5e5;font-weight:bold } -/* OperatorReserved */ .chroma .or { color:#04a5e5;font-weight:bold } -/* Comment */ .chroma .c { color:#9ca0b0;font-style:italic } -/* CommentHashbang */ .chroma .ch { color:#acb0be;font-style:italic } -/* CommentMultiline */ .chroma .cm { color:#9ca0b0;font-style:italic } -/* CommentSingle */ .chroma .c1 { color:#9ca0b0;font-style:italic } -/* CommentSpecial */ .chroma .cs { color:#9ca0b0;font-style:italic } -/* CommentPreproc */ .chroma .cp { color:#9ca0b0;font-style:italic } -/* CommentPreprocFile */ .chroma .cpf { color:#9ca0b0;font-weight:bold;font-style:italic } -/* GenericDeleted */ .chroma .gd { color:#d20f39;background-color:#ccd0da } +/* Keyword */ .chroma .k { color:#cba6f7 } +/* KeywordConstant */ .chroma .kc { color:#fab387 } +/* KeywordDeclaration */ .chroma .kd { color:#f38ba8 } +/* KeywordNamespace */ .chroma .kn { color:#94e2d5 } +/* KeywordPseudo */ .chroma .kp { color:#cba6f7 } +/* KeywordReserved */ .chroma .kr { color:#cba6f7 } +/* KeywordType */ .chroma .kt { color:#f38ba8 } +/* NameAttribute */ .chroma .na { color:#89b4fa } +/* NameClass */ .chroma .nc { color:#f9e2af } +/* NameConstant */ .chroma .no { color:#f9e2af } +/* NameDecorator */ .chroma .nd { color:#89b4fa;font-weight:bold } +/* NameEntity */ .chroma .ni { color:#94e2d5 } +/* NameException */ .chroma .ne { color:#fab387 } +/* NameLabel */ .chroma .nl { color:#89dceb } +/* NameNamespace */ .chroma .nn { color:#fab387 } +/* NameOther */ .chroma .nx { color:#cdd6f4 } +/* NameProperty */ .chroma .py { color:#fab387 } +/* NameTag */ .chroma .nt { color:#cba6f7 } +/* NameBuiltin */ .chroma .nb { color:#89dceb } +/* NameBuiltinPseudo */ .chroma .bp { color:#89dceb } +/* NameVariable */ .chroma .nv { color:#f5e0dc } +/* NameVariableClass */ .chroma .vc { color:#f5e0dc } +/* NameVariableGlobal */ .chroma .vg { color:#f5e0dc } +/* NameVariableInstance */ .chroma .vi { color:#f5e0dc } +/* NameVariableMagic */ .chroma .vm { color:#f5e0dc } +/* NameFunction */ .chroma .nf { color:#89b4fa } +/* NameFunctionMagic */ .chroma .fm { color:#89b4fa } +/* LiteralDate */ .chroma .ld { color:#cdd6f4 } +/* LiteralString */ .chroma .s { color:#a6e3a1 } +/* LiteralStringAffix */ .chroma .sa { color:#f38ba8 } +/* LiteralStringBacktick */ .chroma .sb { color:#a6e3a1 } +/* LiteralStringChar */ .chroma .sc { color:#a6e3a1 } +/* LiteralStringDelimiter */ .chroma .dl { color:#89b4fa } +/* LiteralStringDoc */ .chroma .sd { color:#9399b2 } +/* LiteralStringDouble */ .chroma .s2 { color:#a6e3a1 } +/* LiteralStringEscape */ .chroma .se { color:#89b4fa } +/* LiteralStringHeredoc */ .chroma .sh { color:#9399b2 } +/* LiteralStringInterpol */ .chroma .si { color:#a6e3a1 } +/* LiteralStringOther */ .chroma .sx { color:#a6e3a1 } +/* LiteralStringRegex */ .chroma .sr { color:#94e2d5 } +/* LiteralStringSingle */ .chroma .s1 { color:#a6e3a1 } +/* LiteralStringSymbol */ .chroma .ss { color:#a6e3a1 } +/* LiteralNumber */ .chroma .m { color:#fab387 } +/* LiteralNumberBin */ .chroma .mb { color:#fab387 } +/* LiteralNumberFloat */ .chroma .mf { color:#fab387 } +/* LiteralNumberHex */ .chroma .mh { color:#fab387 } +/* LiteralNumberInteger */ .chroma .mi { color:#fab387 } +/* LiteralNumberIntegerLong */ .chroma .il { color:#fab387 } +/* LiteralNumberOct */ .chroma .mo { color:#fab387 } +/* Operator */ .chroma .o { color:#89dceb;font-weight:bold } +/* OperatorWord */ .chroma .ow { color:#89dceb;font-weight:bold } +/* OperatorReserved */ .chroma .or { color:#89dceb;font-weight:bold } +/* Comment */ .chroma .c { color:#9399b2;font-style:italic } +/* CommentHashbang */ .chroma .ch { color:#9399b2;font-style:italic } +/* CommentMultiline */ .chroma .cm { color:#9399b2;font-style:italic } +/* CommentSingle */ .chroma .c1 { color:#9399b2;font-style:italic } +/* CommentSpecial */ .chroma .cs { color:#9399b2;font-style:italic } +/* CommentPreproc */ .chroma .cp { color:#9399b2;font-style:italic } +/* CommentPreprocFile */ .chroma .cpf { color:#9399b2;font-weight:bold;font-style:italic } +/* GenericDeleted */ .chroma .gd { color:#f38ba8;background-color:#313244 } /* GenericEmph */ .chroma .ge { font-style:italic } -/* GenericError */ .chroma .gr { color:#d20f39 } -/* GenericHeading */ .chroma .gh { color:#fe640b;font-weight:bold } -/* GenericInserted */ .chroma .gi { color:#40a02b;background-color:#ccd0da } -/* GenericOutput */ .chroma .go { color:#4c4f69 } -/* GenericPrompt */ .chroma .gp { color:#4c4f69 } +/* GenericError */ .chroma .gr { color:#f38ba8 } +/* GenericHeading */ .chroma .gh { color:#fab387;font-weight:bold } +/* GenericInserted */ .chroma .gi { color:#a6e3a1;background-color:#313244 } +/* GenericOutput */ .chroma .go { color:#cdd6f4 } +/* GenericPrompt */ .chroma .gp { color:#cdd6f4 } /* GenericStrong */ .chroma .gs { font-weight:bold } -/* GenericSubheading */ .chroma .gu { color:#fe640b;font-weight:bold } -/* GenericTraceback */ .chroma .gt { color:#d20f39 } +/* GenericSubheading */ .chroma .gu { color:#fab387;font-weight:bold } +/* GenericTraceback */ .chroma .gt { color:#f38ba8 } /* GenericUnderline */ .chroma .gl { text-decoration:underline } - - -/* Other */ [data-theme="dark"] .chroma .x { color:#cdd6f4 } -/* Error */ [data-theme="dark"] .chroma .err { color:#f38ba8 } -/* CodeLine */ [data-theme="dark"] .chroma .cl { color:#cdd6f4 } -/* LineLink */ [data-theme="dark"] .chroma .lnlinks { outline:none;text-decoration:none;color:inherit } -/* LineTableTD */ [data-theme="dark"] .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0; } -/* LineTable */ [data-theme="dark"] .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0; } -/* LineHighlight */ [data-theme="dark"] .chroma .hl { background-color:#45475a } -/* LineNumbersTable */ [data-theme="dark"] .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c } -/* LineNumbers */ [data-theme="dark"] .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c } -/* Line */ [data-theme="dark"] .chroma .line { display:flex; } -/* Keyword */ [data-theme="dark"] .chroma .k { color:#cba6f7 } -/* KeywordConstant */ [data-theme="dark"] .chroma .kc { color:#fab387 } -/* KeywordDeclaration */ [data-theme="dark"] .chroma .kd { color:#f38ba8 } -/* KeywordNamespace */ [data-theme="dark"] .chroma .kn { color:#94e2d5 } -/* KeywordPseudo */ [data-theme="dark"] .chroma .kp { color:#cba6f7 } -/* KeywordReserved */ [data-theme="dark"] .chroma .kr { color:#cba6f7 } -/* KeywordType */ [data-theme="dark"] .chroma .kt { color:#f38ba8 } -/* NameAttribute */ [data-theme="dark"] .chroma .na { color:#89b4fa } -/* NameClass */ [data-theme="dark"] .chroma .nc { color:#f9e2af } -/* NameConstant */ [data-theme="dark"] .chroma .no { color:#f9e2af } -/* NameDecorator */ [data-theme="dark"] .chroma .nd { color:#89b4fa;font-weight:bold } -/* NameEntity */ [data-theme="dark"] .chroma .ni { color:#94e2d5 } -/* NameException */ [data-theme="dark"] .chroma .ne { color:#fab387 } -/* NameLabel */ [data-theme="dark"] .chroma .nl { color:#89dceb } -/* NameNamespace */ [data-theme="dark"] .chroma .nn { color:#fab387 } -/* NameOther */ [data-theme="dark"] .chroma .nx { color:#cdd6f4 } -/* NameProperty */ [data-theme="dark"] .chroma .py { color:#fab387 } -/* NameTag */ [data-theme="dark"] .chroma .nt { color:#cba6f7 } -/* NameBuiltin */ [data-theme="dark"] .chroma .nb { color:#89dceb } -/* NameBuiltinPseudo */ [data-theme="dark"] .chroma .bp { color:#89dceb } -/* NameVariable */ [data-theme="dark"] .chroma .nv { color:#f5e0dc } -/* NameVariableClass */ [data-theme="dark"] .chroma .vc { color:#f5e0dc } -/* NameVariableGlobal */ [data-theme="dark"] .chroma .vg { color:#f5e0dc } -/* NameVariableInstance */ [data-theme="dark"] .chroma .vi { color:#f5e0dc } -/* NameVariableMagic */ [data-theme="dark"] .chroma .vm { color:#f5e0dc } -/* NameFunction */ [data-theme="dark"] .chroma .nf { color:#89b4fa } -/* NameFunctionMagic */ [data-theme="dark"] .chroma .fm { color:#89b4fa } -/* LiteralDate */ [data-theme="dark"] .chroma .ld { color:#cdd6f4 } -/* LiteralString */ [data-theme="dark"] .chroma .s { color:#a6e3a1 } -/* LiteralStringAffix */ [data-theme="dark"] .chroma .sa { color:#f38ba8 } -/* LiteralStringBacktick */ [data-theme="dark"] .chroma .sb { color:#a6e3a1 } -/* LiteralStringChar */ [data-theme="dark"] .chroma .sc { color:#a6e3a1 } -/* LiteralStringDelimiter */ [data-theme="dark"] .chroma .dl { color:#89b4fa } -/* LiteralStringDoc */ [data-theme="dark"] .chroma .sd { color:#6c7086 } -/* LiteralStringDouble */ [data-theme="dark"] .chroma .s2 { color:#a6e3a1 } -/* LiteralStringEscape */ [data-theme="dark"] .chroma .se { color:#89b4fa } -/* LiteralStringHeredoc */ [data-theme="dark"] .chroma .sh { color:#6c7086 } -/* LiteralStringInterpol */ [data-theme="dark"] .chroma .si { color:#a6e3a1 } -/* LiteralStringOther */ [data-theme="dark"] .chroma .sx { color:#a6e3a1 } -/* LiteralStringRegex */ [data-theme="dark"] .chroma .sr { color:#94e2d5 } -/* LiteralStringSingle */ [data-theme="dark"] .chroma .s1 { color:#a6e3a1 } -/* LiteralStringSymbol */ [data-theme="dark"] .chroma .ss { color:#a6e3a1 } -/* LiteralNumber */ [data-theme="dark"] .chroma .m { color:#fab387 } -/* LiteralNumberBin */ [data-theme="dark"] .chroma .mb { color:#fab387 } -/* LiteralNumberFloat */ [data-theme="dark"] .chroma .mf { color:#fab387 } -/* LiteralNumberHex */ [data-theme="dark"] .chroma .mh { color:#fab387 } -/* LiteralNumberInteger */ [data-theme="dark"] .chroma .mi { color:#fab387 } -/* LiteralNumberIntegerLong */ [data-theme="dark"] .chroma .il { color:#fab387 } -/* LiteralNumberOct */ [data-theme="dark"] .chroma .mo { color:#fab387 } -/* Operator */ [data-theme="dark"] .chroma .o { color:#89dceb;font-weight:bold } -/* OperatorWord */ [data-theme="dark"] .chroma .ow { color:#89dceb;font-weight:bold } -/* OperatorReserved */ [data-theme="dark"] .chroma .or { color:#89dceb;font-weight:bold } -/* Comment */ [data-theme="dark"] .chroma .c { color:#6c7086;font-style:italic } -/* CommentHashbang */ [data-theme="dark"] .chroma .ch { color:#585b70;font-style:italic } -/* CommentMultiline */ [data-theme="dark"] .chroma .cm { color:#6c7086;font-style:italic } -/* CommentSingle */ [data-theme="dark"] .chroma .c1 { color:#6c7086;font-style:italic } -/* CommentSpecial */ [data-theme="dark"] .chroma .cs { color:#6c7086;font-style:italic } -/* CommentPreproc */ [data-theme="dark"] .chroma .cp { color:#6c7086;font-style:italic } -/* CommentPreprocFile */ [data-theme="dark"] .chroma .cpf { color:#6c7086;font-weight:bold;font-style:italic } -/* GenericDeleted */ [data-theme="dark"] .chroma .gd { color:#f38ba8;background-color:#313244 } -/* GenericEmph */ [data-theme="dark"] .chroma .ge { font-style:italic } -/* GenericError */ [data-theme="dark"] .chroma .gr { color:#f38ba8 } -/* GenericHeading */ [data-theme="dark"] .chroma .gh { color:#fab387;font-weight:bold } -/* GenericInserted */ [data-theme="dark"] .chroma .gi { color:#a6e3a1;background-color:#313244 } -/* GenericOutput */ [data-theme="dark"] .chroma .go { color:#cdd6f4 } -/* GenericPrompt */ [data-theme="dark"] .chroma .gp { color:#cdd6f4 } -/* GenericStrong */ [data-theme="dark"] .chroma .gs { font-weight:bold } -/* GenericSubheading */ [data-theme="dark"] .chroma .gu { color:#fab387;font-weight:bold } -/* GenericTraceback */ [data-theme="dark"] .chroma .gt { color:#f38ba8 } -/* GenericUnderline */ [data-theme="dark"] .chroma .gl { text-decoration:underline } diff --git a/assets/css/extended/theme.css b/assets/css/extended/theme.css index 27d059a..1a123b8 100644 --- a/assets/css/extended/theme.css +++ b/assets/css/extended/theme.css @@ -11,7 +11,6 @@ --content: #4c4f69; /* text */ --secondary: #6c6f85; /* subtext0 */ --tertiary: #ccd0da; /* surface0 */ - --code-block-bg: #e6e9ef; /* mantle */ --code-bg: #ccd0da; /* surface0 */ --border: #ccd0da; /* surface0 */ --link: #1e66f5; /* blue */ @@ -36,7 +35,6 @@ --content: #cdd6f4; /* text */ --secondary: #a6adc8; /* subtext0 */ --tertiary: #313244; /* surface0 */ - --code-block-bg: #181825; /* mantle */ --code-bg: #313244; /* surface0 */ --border: #313244; /* surface0 */ --link: #89b4fa; /* blue */ @@ -114,3 +112,16 @@ svg.dg .ar-b { fill: var(--dg-b); } svg.dg .ar-c { fill: var(--dg-c); } svg.dg .ar-d { fill: var(--dg-d); } svg.dg .ar-e { fill: var(--dg-e); } + +/* Code blocks keep a Mocha surface in both theme states; see chroma.css for why + and for the token colours. Latte's accents cannot reach WCAG AA on a light + surface, so the block stays dark and the Latte page frames it (15.5:1 against + Latte base). Inline code is unaffected: it stays --code-bg, Latte surface0 in + light (5.17:1) and Mocha surface0 in dark (8.69:1), both already AA. */ +:root, +:root[data-theme="dark"] { --code-block-bg: #181825; } /* mocha mantle, both states */ + +/* PaperMod hardcodes rgb(213, 213, 214) here with no light-mode variant, which + left untagged fences at 1.21:1 on a Latte block. Carries the text colour for + any fence chroma does not tokenise. */ +.md-content pre code { color: #cdd6f4; } /* mocha text */ From 590f5bf89e529ceeb0331fec2338726cc395f0da Mon Sep 17 00:00:00 2001 From: Minh Tran <4847344+minhtt159@users.noreply.github.com> Date: Wed, 16 Sep 2026 02:15:51 +0200 Subject: [PATCH 2/2] refactor(site): keep Latte in light, drive all colour from one palette Reverses the previous commit's decision to put a Mocha block in both theme states. Latte stays in light mode, strictly. Rereading the style guide's Code Editors table found the real culprit. The generated chroma style maps NameVariable to Rosewater, which the guide never says - it assigns Rosewater to Macros alone, so plain identifiers fall to Text. In a PromQL fence the metric names are almost the whole block, so that single deviation was most of the illegibility: 2.17:1 against 7.06:1. The guide also puts Builtins on Red rather than Sky, Attributes on Yellow rather than Blue, Comments on Overlay 2 rather than Overlay 0, and Escapes and Regex on Pink. chroma.css now follows the guide instead of the generator. The block background is each flavour's extreme rather than its mantle, because that buys the most token contrast: base is the lightest Latte pane, crust the darkest Mocha one. A surface0 border does the separating that the mantle fill used to. theme.css now carries the full 26-colour ramp of both flavours as --ctp-* variables, verbatim from catppuccin/palette, and everything else in the repo - PaperMod's variables, the diagram palette, the chroma mapping - references those. chroma.css contains no hex at all, and one set of selectors serves both theme states because the variables swap underneath. The dark selector is repeated on the mapping blocks so they outrank PaperMod's own :root[data-theme="dark"] defaults, which were silently winning for --theme, --content and friends. Measured on the SLO post, light and dark: pre code 1.21 -> 7.06 light, 12.97 dark metric names 2.17 -> 7.06 light, 12.97 dark comments 2.14 -> 3.49 light, 6.64 dark worst token 2.14 -> 2.47 light, 6.64 dark Mocha clears WCAG AA on every role. Latte does not and cannot: its accents top out under 4.5:1 on every Catppuccin background, so operators, numbers, strings, comments and punctuation sit between 2.47 and 3.49 in light mode. That is a property of the palette and is kept deliberately, for fidelity over contrast. The body of a code block - identifiers, literals, untokenised text - carries 7.06:1. Co-Authored-By: Claude Opus 5 --- assets/css/extended/chroma.css | 195 ++++++++++++++++----------------- assets/css/extended/theme.css | 162 +++++++++++++++++---------- 2 files changed, 200 insertions(+), 157 deletions(-) diff --git a/assets/css/extended/chroma.css b/assets/css/extended/chroma.css index 3066113..fe44480 100644 --- a/assets/css/extended/chroma.css +++ b/assets/css/extended/chroma.css @@ -1,98 +1,97 @@ -/* Chroma: catppuccin-mocha in both theme states. Generated with hugo gen - chromastyles, then edited as noted below; the block background is - --code-block-bg (theme.css), mocha mantle in light and dark alike. - - Why not catppuccin-latte in light: Latte's accents cannot reach the WCAG AA - 4.5:1 minimum on any light surface. Measured against Latte mantle, comments - are 2.14:1, operators 2.30, numbers 2.45, strings 2.75, and NameVariable - - the metric names that are the bulk of a PromQL block - 2.17; peach on pure - white is still only 2.97. The style guide's rule is "legibility always comes - first, so please use your own judgement", so the code block stays Mocha and - the Latte page frames it. Every colour below is 4.75:1 or better on - --code-block-bg. - - One edit to the generated output: every Comment* token, LiteralStringDoc and - LiteralStringHeredoc take overlay2 #9399b2 (6.22:1) rather than the generated - overlay0 #6c7086 (3.59:1) and surface2 #585b70 (2.63:1), both under AA. The - style guide's Code Editors section specifies overlay2 for comments. */ - -/* Other */ .chroma .x { color:#cdd6f4 } -/* Error */ .chroma .err { color:#f38ba8 } -/* CodeLine */ .chroma .cl { color:#cdd6f4 } -/* LineLink */ .chroma .lnlinks { outline:none;text-decoration:none;color:inherit } -/* LineTableTD */ .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0; } -/* LineTable */ .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0; } -/* LineHighlight */ .chroma .hl { background-color:#45475a } -/* LineNumbersTable */ .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c } -/* LineNumbers */ .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f849c } -/* Line */ .chroma .line { display:flex; } -/* Keyword */ .chroma .k { color:#cba6f7 } -/* KeywordConstant */ .chroma .kc { color:#fab387 } -/* KeywordDeclaration */ .chroma .kd { color:#f38ba8 } -/* KeywordNamespace */ .chroma .kn { color:#94e2d5 } -/* KeywordPseudo */ .chroma .kp { color:#cba6f7 } -/* KeywordReserved */ .chroma .kr { color:#cba6f7 } -/* KeywordType */ .chroma .kt { color:#f38ba8 } -/* NameAttribute */ .chroma .na { color:#89b4fa } -/* NameClass */ .chroma .nc { color:#f9e2af } -/* NameConstant */ .chroma .no { color:#f9e2af } -/* NameDecorator */ .chroma .nd { color:#89b4fa;font-weight:bold } -/* NameEntity */ .chroma .ni { color:#94e2d5 } -/* NameException */ .chroma .ne { color:#fab387 } -/* NameLabel */ .chroma .nl { color:#89dceb } -/* NameNamespace */ .chroma .nn { color:#fab387 } -/* NameOther */ .chroma .nx { color:#cdd6f4 } -/* NameProperty */ .chroma .py { color:#fab387 } -/* NameTag */ .chroma .nt { color:#cba6f7 } -/* NameBuiltin */ .chroma .nb { color:#89dceb } -/* NameBuiltinPseudo */ .chroma .bp { color:#89dceb } -/* NameVariable */ .chroma .nv { color:#f5e0dc } -/* NameVariableClass */ .chroma .vc { color:#f5e0dc } -/* NameVariableGlobal */ .chroma .vg { color:#f5e0dc } -/* NameVariableInstance */ .chroma .vi { color:#f5e0dc } -/* NameVariableMagic */ .chroma .vm { color:#f5e0dc } -/* NameFunction */ .chroma .nf { color:#89b4fa } -/* NameFunctionMagic */ .chroma .fm { color:#89b4fa } -/* LiteralDate */ .chroma .ld { color:#cdd6f4 } -/* LiteralString */ .chroma .s { color:#a6e3a1 } -/* LiteralStringAffix */ .chroma .sa { color:#f38ba8 } -/* LiteralStringBacktick */ .chroma .sb { color:#a6e3a1 } -/* LiteralStringChar */ .chroma .sc { color:#a6e3a1 } -/* LiteralStringDelimiter */ .chroma .dl { color:#89b4fa } -/* LiteralStringDoc */ .chroma .sd { color:#9399b2 } -/* LiteralStringDouble */ .chroma .s2 { color:#a6e3a1 } -/* LiteralStringEscape */ .chroma .se { color:#89b4fa } -/* LiteralStringHeredoc */ .chroma .sh { color:#9399b2 } -/* LiteralStringInterpol */ .chroma .si { color:#a6e3a1 } -/* LiteralStringOther */ .chroma .sx { color:#a6e3a1 } -/* LiteralStringRegex */ .chroma .sr { color:#94e2d5 } -/* LiteralStringSingle */ .chroma .s1 { color:#a6e3a1 } -/* LiteralStringSymbol */ .chroma .ss { color:#a6e3a1 } -/* LiteralNumber */ .chroma .m { color:#fab387 } -/* LiteralNumberBin */ .chroma .mb { color:#fab387 } -/* LiteralNumberFloat */ .chroma .mf { color:#fab387 } -/* LiteralNumberHex */ .chroma .mh { color:#fab387 } -/* LiteralNumberInteger */ .chroma .mi { color:#fab387 } -/* LiteralNumberIntegerLong */ .chroma .il { color:#fab387 } -/* LiteralNumberOct */ .chroma .mo { color:#fab387 } -/* Operator */ .chroma .o { color:#89dceb;font-weight:bold } -/* OperatorWord */ .chroma .ow { color:#89dceb;font-weight:bold } -/* OperatorReserved */ .chroma .or { color:#89dceb;font-weight:bold } -/* Comment */ .chroma .c { color:#9399b2;font-style:italic } -/* CommentHashbang */ .chroma .ch { color:#9399b2;font-style:italic } -/* CommentMultiline */ .chroma .cm { color:#9399b2;font-style:italic } -/* CommentSingle */ .chroma .c1 { color:#9399b2;font-style:italic } -/* CommentSpecial */ .chroma .cs { color:#9399b2;font-style:italic } -/* CommentPreproc */ .chroma .cp { color:#9399b2;font-style:italic } -/* CommentPreprocFile */ .chroma .cpf { color:#9399b2;font-weight:bold;font-style:italic } -/* GenericDeleted */ .chroma .gd { color:#f38ba8;background-color:#313244 } -/* GenericEmph */ .chroma .ge { font-style:italic } -/* GenericError */ .chroma .gr { color:#f38ba8 } -/* GenericHeading */ .chroma .gh { color:#fab387;font-weight:bold } -/* GenericInserted */ .chroma .gi { color:#a6e3a1;background-color:#313244 } -/* GenericOutput */ .chroma .go { color:#cdd6f4 } -/* GenericPrompt */ .chroma .gp { color:#cdd6f4 } -/* GenericStrong */ .chroma .gs { font-weight:bold } -/* GenericSubheading */ .chroma .gu { color:#fab387;font-weight:bold } -/* GenericTraceback */ .chroma .gt { color:#f38ba8 } -/* GenericUnderline */ .chroma .gl { text-decoration:underline } +/* Chroma tokens mapped onto the Catppuccin roles, following the Code Editors + section of the style guide: + https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md + + One set of rules serves both theme states, because every colour here is a + --ctp-* role that theme.css redefines per flavour. No hex values in this file. + + This follows the style guide rather than `hugo gen chromastyles`, which + disagrees with it in a few places. The one that mattered: the generated style + puts NameVariable on Rosewater, which the guide never says - it assigns + Rosewater to Macros alone, so plain identifiers fall to Text. On a Latte + block that is the difference between 2.17:1 and 7.06:1, and in a PromQL + fence the metric names are almost the whole block. The guide also puts + Builtins on Red rather than Sky, Attributes on Yellow rather than Blue, + Comments on Overlay 2 rather than Overlay 0, and Escapes and Regex on Pink. + + Contrast against --code-block-bg: Mocha clears WCAG AA on every role + (worst 5.07:1). Latte does not and cannot - its accents top out well under + 4.5:1 on any Catppuccin background, so light mode carries Text at 7.06:1 and + accents between 2.3 and 4.8. That is a property of the palette, kept + deliberately for fidelity. */ + +/* structure, no colour */ +.chroma .lnlinks { outline: none; text-decoration: none; color: inherit; } +.chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } +.chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } +.chroma .line { display: flex; } +.chroma .ge { font-style: italic; } +.chroma .gs { font-weight: bold; } +.chroma .gl { text-decoration: underline; } + +/* body: identifiers, literals and anything untokenised */ +.chroma, .chroma .cl, .chroma .x, .chroma .n, .chroma .nx, .chroma .nn, +.chroma .nl, .chroma .nv, .chroma .vc, .chroma .vg, .chroma .vi, +.chroma .l, .chroma .ld, .chroma .g, .chroma .go, +.chroma .gp { color: var(--ctp-text); } + +/* Keyword -> Mauve */ +.chroma .k, .chroma .kr, .chroma .kp, .chroma .kd, +.chroma .kn { color: var(--ctp-mauve); } + +/* Strings -> Green */ +.chroma .s, .chroma .s1, .chroma .s2, .chroma .sb, .chroma .sc, .chroma .sx, +.chroma .ss, .chroma .si, .chroma .sd, .chroma .sh { color: var(--ctp-green); } + +/* Escape Sequences, Regex -> Pink */ +.chroma .se, .chroma .sr { color: var(--ctp-pink); } + +/* Symbols, Atoms / Builtins / Errors -> Red */ +.chroma .sa, .chroma .nb, .chroma .bp, .chroma .err, .chroma .gr, +.chroma .gt { color: var(--ctp-red); } + +/* Constants, Numbers -> Peach */ +.chroma .m, .chroma .mb, .chroma .mf, .chroma .mh, .chroma .mi, .chroma .mo, +.chroma .il, .chroma .kc, .chroma .no { color: var(--ctp-peach); } + +/* Classes, Types, Annotations, Attributes -> Yellow */ +.chroma .nc, .chroma .kt, .chroma .ne, .chroma .na { color: var(--ctp-yellow); } +.chroma .nd { color: var(--ctp-yellow); font-weight: bold; } + +/* Methods, Functions, and Property (e.g. JSON keys) -> Blue */ +.chroma .nf, .chroma .fm, .chroma .py { color: var(--ctp-blue); } + +/* Enum Variants -> Teal */ +.chroma .ni { color: var(--ctp-teal); } + +/* Macros -> Rosewater */ +.chroma .vm { color: var(--ctp-rosewater); } + +/* Operators -> Sky */ +.chroma .o, .chroma .ow, .chroma .or { color: var(--ctp-sky); font-weight: bold; } + +/* Comments -> Overlay 2 */ +.chroma .c, .chroma .c1, .chroma .cm, .chroma .cs, .chroma .cp, +.chroma .ch { color: var(--ctp-overlay2); font-style: italic; } +.chroma .cpf { color: var(--ctp-overlay2); font-weight: bold; font-style: italic; } + +/* Braces, Delimiters -> Overlay 2 */ +.chroma .p, .chroma .dl { color: var(--ctp-overlay2); } + +/* Line Numbers -> Overlay 1 */ +.chroma .lnt, .chroma .ln { + white-space: pre; + -webkit-user-select: none; + user-select: none; + margin-right: 0.4em; + padding: 0 0.4em; + color: var(--ctp-overlay1); +} + +/* Diff and Merge: header Blue, hunk header Peach, inserted/removed lines + tinted at 20%, the middle of the guide's 15-25% band */ +.chroma .gh { color: var(--ctp-blue); font-weight: bold; } +.chroma .gu { color: var(--ctp-peach); font-weight: bold; } +.chroma .gi { color: var(--ctp-green); background-color: color-mix(in srgb, var(--ctp-green) 20%, transparent); } +.chroma .gd { color: var(--ctp-red); background-color: color-mix(in srgb, var(--ctp-red) 20%, transparent); } +.chroma .hl { background-color: color-mix(in srgb, var(--ctp-yellow) 15%, transparent); } diff --git a/assets/css/extended/theme.css b/assets/css/extended/theme.css index 1a123b8..81092fb 100644 --- a/assets/css/extended/theme.css +++ b/assets/css/extended/theme.css @@ -1,63 +1,105 @@ -/* Catppuccin Latte (light) / Mocha (dark), mapped onto PaperMod's variables. - Roles follow https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md: - base = page, mantle = secondary pane, surface0 = surface elements, - text = body copy, subtext0 = labels, blue = links, green/yellow/red = ok/warn/error. - Hex values from https://github.com/catppuccin/palette (palette.json). */ +/* Catppuccin, Latte in light and Mocha in dark. Every colour in the repo comes + from the two blocks below; no other file carries a hex value. Hexes are + verbatim from https://github.com/catppuccin/palette (palette.json), the whole + 26-colour ramp of each flavour so later work can reach for a role without + adding a literal. Roles follow the style guide: + https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md */ :root { - --theme: #eff1f5; /* base */ - --entry: #e6e9ef; /* mantle */ - --primary: #4c4f69; /* text */ - --content: #4c4f69; /* text */ - --secondary: #6c6f85; /* subtext0 */ - --tertiary: #ccd0da; /* surface0 */ - --code-bg: #ccd0da; /* surface0 */ - --border: #ccd0da; /* surface0 */ - --link: #1e66f5; /* blue */ - --selection: rgba(124, 127, 147, 0.25); /* overlay2 @ 25% */ + --ctp-rosewater: #dc8a78; + --ctp-flamingo: #dd7878; + --ctp-pink: #ea76cb; + --ctp-mauve: #8839ef; + --ctp-red: #d20f39; + --ctp-maroon: #e64553; + --ctp-peach: #fe640b; + --ctp-yellow: #df8e1d; + --ctp-green: #40a02b; + --ctp-teal: #179299; + --ctp-sky: #04a5e5; + --ctp-sapphire: #209fb5; + --ctp-blue: #1e66f5; + --ctp-lavender: #7287fd; + --ctp-text: #4c4f69; + --ctp-subtext1: #5c5f77; + --ctp-subtext0: #6c6f85; + --ctp-overlay2: #7c7f93; + --ctp-overlay1: #8c8fa1; + --ctp-overlay0: #9ca0b0; + --ctp-surface2: #acb0be; + --ctp-surface1: #bcc0cc; + --ctp-surface0: #ccd0da; + --ctp-base: #eff1f5; + --ctp-mantle: #e6e9ef; + --ctp-crust: #dce0e8; +} - /* diagram palette: svg.dg reads only these */ - --dg-surface: #ccd0da; /* surface0 */ - --dg-border: #9ca0b0; /* overlay0 */ - --dg-text: #4c4f69; /* text */ - --dg-muted: #6c6f85; /* subtext0 */ - --dg-a: #1e66f5; /* blue: primary flow, links */ - --dg-b: #40a02b; /* green: good, healthy, counted */ - --dg-c: #d20f39; /* red: bad, excluded, blind spot */ - --dg-d: #df8e1d; /* yellow: caution, partial */ - --dg-e: #8839ef; /* mauve: external, third party */ +:root[data-theme="dark"] { + --ctp-rosewater: #f5e0dc; + --ctp-flamingo: #f2cdcd; + --ctp-pink: #f5c2e7; + --ctp-mauve: #cba6f7; + --ctp-red: #f38ba8; + --ctp-maroon: #eba0ac; + --ctp-peach: #fab387; + --ctp-yellow: #f9e2af; + --ctp-green: #a6e3a1; + --ctp-teal: #94e2d5; + --ctp-sky: #89dceb; + --ctp-sapphire: #74c7ec; + --ctp-blue: #89b4fa; + --ctp-lavender: #b4befe; + --ctp-text: #cdd6f4; + --ctp-subtext1: #bac2de; + --ctp-subtext0: #a6adc8; + --ctp-overlay2: #9399b2; + --ctp-overlay1: #7f849c; + --ctp-overlay0: #6c7086; + --ctp-surface2: #585b70; + --ctp-surface1: #45475a; + --ctp-surface0: #313244; + --ctp-base: #1e1e2e; + --ctp-mantle: #181825; + --ctp-crust: #11111b; } +/* PaperMod's variables, mapped onto the palette. base = page, mantle = + secondary pane, surface0 = surface elements, text = body copy, subtext0 = + labels, blue = links, green/yellow/red = success/warning/error. + The dark selector is repeated so these outrank PaperMod's own + :root[data-theme="dark"] block; the --ctp-* values already swap per flavour. */ +:root, :root[data-theme="dark"] { - --theme: #1e1e2e; /* base */ - --entry: #181825; /* mantle */ - --primary: #cdd6f4; /* text */ - --content: #cdd6f4; /* text */ - --secondary: #a6adc8; /* subtext0 */ - --tertiary: #313244; /* surface0 */ - --code-bg: #313244; /* surface0 */ - --border: #313244; /* surface0 */ - --link: #89b4fa; /* blue */ - --selection: rgba(147, 153, 178, 0.25); /* overlay2 @ 25% */ + --theme: var(--ctp-base); + --entry: var(--ctp-mantle); + --primary: var(--ctp-text); + --content: var(--ctp-text); + --secondary: var(--ctp-subtext0); + --tertiary: var(--ctp-surface0); + --code-bg: var(--ctp-surface0); + --border: var(--ctp-surface0); + --link: var(--ctp-blue); + --selection: color-mix(in srgb, var(--ctp-overlay2) 25%, transparent); /* guide: 20-30% */ - --dg-surface: #313244; /* surface0 */ - --dg-border: #6c7086; /* overlay0 */ - --dg-text: #cdd6f4; /* text */ - --dg-muted: #a6adc8; /* subtext0 */ - --dg-a: #89b4fa; - --dg-b: #a6e3a1; - --dg-c: #f38ba8; - --dg-d: #f9e2af; - --dg-e: #cba6f7; + /* diagram palette: svg.dg reads only these */ + --dg-surface: var(--ctp-surface0); + --dg-border: var(--ctp-overlay0); + --dg-text: var(--ctp-text); + --dg-muted: var(--ctp-subtext0); + --dg-a: var(--ctp-blue); /* primary flow, links */ + --dg-b: var(--ctp-green); /* good, healthy, counted */ + --dg-c: var(--ctp-red); /* bad, excluded, blind spot */ + --dg-d: var(--ctp-yellow); /* caution, partial */ + --dg-e: var(--ctp-mauve); /* external, third party */ } /* tints: accent over the page at 15%, the style guide's 10-25% band */ :root { - --dg-a-bg: color-mix(in srgb, var(--dg-a) 15%, var(--theme)); - --dg-b-bg: color-mix(in srgb, var(--dg-b) 15%, var(--theme)); - --dg-c-bg: color-mix(in srgb, var(--dg-c) 15%, var(--theme)); - --dg-d-bg: color-mix(in srgb, var(--dg-d) 15%, var(--theme)); - --dg-e-bg: color-mix(in srgb, var(--dg-e) 15%, var(--theme)); + --dg-a-bg: color-mix(in srgb, var(--dg-a) 15%, var(--ctp-base)); + --dg-b-bg: color-mix(in srgb, var(--dg-b) 15%, var(--ctp-base)); + --dg-c-bg: color-mix(in srgb, var(--dg-c) 15%, var(--ctp-base)); + --dg-d-bg: color-mix(in srgb, var(--dg-d) 15%, var(--ctp-base)); + --dg-e-bg: color-mix(in srgb, var(--dg-e) 15%, var(--ctp-base)); } ::selection { background: var(--selection); } @@ -113,15 +155,17 @@ svg.dg .ar-c { fill: var(--dg-c); } svg.dg .ar-d { fill: var(--dg-d); } svg.dg .ar-e { fill: var(--dg-e); } -/* Code blocks keep a Mocha surface in both theme states; see chroma.css for why - and for the token colours. Latte's accents cannot reach WCAG AA on a light - surface, so the block stays dark and the Latte page frames it (15.5:1 against - Latte base). Inline code is unaffected: it stays --code-bg, Latte surface0 in - light (5.17:1) and Mocha surface0 in dark (8.69:1), both already AA. */ -:root, -:root[data-theme="dark"] { --code-block-bg: #181825; } /* mocha mantle, both states */ +/* Code blocks. Latte in light, Mocha in dark, strict palette either way; the + token mapping is in chroma.css. Background is the flavour's extreme rather + than its mantle, because that is what buys the most token contrast: base is + the lightest Latte pane, crust the darkest Mocha one. A surface0 border does + the separating that a mantle fill used to. */ +:root { --code-block-bg: var(--ctp-base); } +:root[data-theme="dark"] { --code-block-bg: var(--ctp-crust); } /* outranks PaperMod's own */ +.md-content .highlight:not(table), +.md-content pre code { border: 1px solid var(--ctp-surface0); } /* PaperMod hardcodes rgb(213, 213, 214) here with no light-mode variant, which - left untagged fences at 1.21:1 on a Latte block. Carries the text colour for - any fence chroma does not tokenise. */ -.md-content pre code { color: #cdd6f4; } /* mocha text */ + left an untagged fence at 1.21:1 on a Latte block. Also carries the colour + for any fence chroma does not tokenise. */ +.md-content pre code { color: var(--ctp-text); }