fix(cv): enforce readable render palettes
CI and Deploy / test (pull_request) Successful in 4m37s
CI and Deploy / deploy (pull_request) Has been skipped

Choose a contrasting header foreground for custom accents and keep public colour and font overrides inside safe supported values.
This commit is contained in:
cesnimda
2026-08-15 17:08:20 +02:00
parent f0b9b222ff
commit 3b86ea2da0
8 changed files with 98 additions and 18 deletions
+29
View File
@@ -63,6 +63,16 @@ public sealed class CvCustomSectionSetting
public static class CvVariantSettingsJson
{
private static readonly HashSet<string> AllowedFonts = new(StringComparer.Ordinal)
{
"'Segoe UI', Roboto, Arial, sans-serif",
"Arial, Helvetica, sans-serif",
"Georgia, 'Times New Roman', serif",
"'Helvetica Neue', Arial, sans-serif",
"'Roboto', Arial, sans-serif",
"'Poppins', 'Segoe UI', Arial, sans-serif",
};
private static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web)
{
PropertyNameCaseInsensitive = true,
@@ -83,9 +93,28 @@ public static class CvVariantSettingsJson
{
s ??= new CvVariantSettings();
s.ThemeId = string.IsNullOrWhiteSpace(s.ThemeId) ? "modern" : s.ThemeId.Trim().ToLowerInvariant();
s.AccentColor = NormalizeColor(s.AccentColor);
s.HeadingFont = NormalizeFont(s.HeadingFont);
s.BodyFont = NormalizeFont(s.BodyFont);
s.Sections ??= new();
s.Overrides ??= new();
s.CustomSections ??= new();
return s;
}
private static string? NormalizeColor(string? value)
{
var candidate = value?.Trim();
return candidate is { Length: 7 }
&& candidate[0] == '#'
&& candidate.Skip(1).All(Uri.IsHexDigit)
? candidate.ToLowerInvariant()
: null;
}
private static string? NormalizeFont(string? value)
{
var candidate = value?.Trim();
return candidate is not null && AllowedFonts.Contains(candidate) ? candidate : null;
}
}