Module:User:Saph/Babel palette

Hello, you have come here looking for the meaning of the word Module:User:Saph/Babel palette. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:User:Saph/Babel palette, but we will also tell you about its etymology, its characteristics and you will know how to say Module:User:Saph/Babel palette in singular and plural. Everything you need to know about the word Module:User:Saph/Babel palette you have here. The definition of the word Module:User:Saph/Babel palette will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:User:Saph/Babel palette, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.

location light mode dark mode WCAG contrast (with text colour) WCAG contrast (with link colour)
Babel-0 left #FFB3B3 #4A0000 Light mode: 9.485 (AAA)
Dark mode: 13.75 (AAA)
Light mode: 9.485 (AAA)
Dark mode: 6.545 (AA)
Babel-1 left #FEA6DB #570035 Light mode: 8.979 (AAA)
Dark mode: 12.18 (AAA)
Light mode: 8.979 (AAA)
Dark mode: 5.801 (AA)
Babel-2 left #EA9BFD #4F0162 Light mode: 8.145 (AAA)
Dark mode: 11.73 (AAA)
Light mode: 8.145 (AAA)
Dark mode: 5.584 (AA)
Babel-3 left #A68FFC #19026D Light mode: 6.110 (AA)
Dark mode: 13.97 (AAA)
Light mode: 6.110 (AA)
Dark mode: 6.649 (AA)
Babel-4 left #84B2FA #043178 Light mode: 7.472 (AAA)
Dark mode: 10.34 (AAA)
Light mode: 7.472 (AAA)
Dark mode: 4.925 (AA)
Babel-5 left #78F7F8 #068384 Light mode: 12.64 (AAA)
Dark mode: 3.870 (FAIL)
Light mode: 12.64 (AAA)
Dark mode: 1.842 (FAIL)
Babel-N left #6DF7A6 #078E3F Light mode: 11.90 (AAA)
Dark mode: 3.586 (FAIL)
Light mode: 11.90 (AAA)
Dark mode: 1.707 (FAIL)
Babel-0 right #FFE0E8 #410010 Light mode: 13.11 (AAA)
Dark mode: 14.40 (AAA)
Light mode: 13.11 (AAA)
Dark mode: 6.858 (AA)
Babel-1 right #FEDBF8 #390130 Light mode: 12.82 (AAA)
Dark mode: 14.54 (AAA)
Light mode: 12.82 (AAA)
Dark mode: 6.921 (AA)
Babel-2 right #EFD6FE #210135 Light mode: 12.07 (AAA)
Dark mode: 15.84 (AAA)
Light mode: 12.07 (AAA)
Dark mode: 7.542 (AAA)
Babel-3 right #D5D2FD #05022F Light mode: 11.11 (AAA)
Dark mode: 16.81 (AAA)
Light mode: 11.11 (AAA)
Dark mode: 8.001 (AAA)
Babel-4 right #CDE4FD #011831 Light mode: 12.37 (AAA)
Dark mode: 15.09 (AAA)
Light mode: 12.37 (AAA)
Dark mode: 7.184 (AAA)
Babel-5 right #C9FCFB #023534 Light mode: 14.43 (AAA)
Dark mode: 11.37 (AAA)
Light mode: 14.43 (AAA)
Dark mode: 5.412 (AA)
Babel-N right #C4FCDB #023A19 Light mode: 14.05 (AAA)
Dark mode: 10.94 (AAA)
Light mode: 14.05 (AAA)
Dark mode: 5.210 (AA)
.babel-box {
	float: left;
	box-sizing: border-box;
	border-style: solid;
	border-width: 1px;
	margin: 1px;
}

.babel-box-wrapper .babel-box {
	width: calc(100% - 2px); /* subtract horizontal margin */
}

.babel-box table {
	border-spacing: 0; /* replacement for cellspacing="0" */
}

.babel-box .babel-content {
	width: 100%;
	min-width: 238px;
	height: 100%;
	margin: 0;
}

.babel-box .babel-code {
	width: 45px;
	height: 45px;
	text-align: center;
}

.babel-box .babel-text {
	font-size: 8pt;
	padding: 4pt;
	line-height: 1.25em;
}

.babel-box.babel-0 { border-color: #FFB3B3; }
.babel-box.babel-0 .babel-content { background-color: #FFE0E8; }
.babel-box.babel-0 .babel-code { background-color: #FFB3B3; }

.babel-box.babel-1 { border-color: #FEA6DB; }
.babel-box.babel-1 .babel-content { background-color: #FEDBF8; }
.babel-box.babel-1 .babel-code { background-color: #FEA6DB; }

.babel-box.babel-2 { border-color: #EA9BFD; }
.babel-box.babel-2 .babel-content { background-color: #EFD6FE; }
.babel-box.babel-2 .babel-code { background-color: #EA9BFD; }

.babel-box.babel-3 { border-color: #A68FFC; }
.babel-box.babel-3 .babel-content { background-color: #D5D2FD; }
.babel-box.babel-3 .babel-code { background-color: #A68FFC; }

.babel-box.babel-4 { border-color: #84B2FA; }
.babel-box.babel-4 .babel-content { background-color: #CDE4FD; }
.babel-box.babel-4 .babel-code { background-color: #84B2FA; }

.babel-box.babel-5 { border-color: #78F7F8; }
.babel-box.babel-5 .babel-content { background-color: #C9FCFB; }
.babel-box.babel-5 .babel-code { background-color: #78F7F8; }

.babel-box.babel-N { border-color: #6DF7A6; }
.babel-box.babel-N .babel-content { background-color: #C4FCDB; }
.babel-box.babel-N .babel-code { background-color: #6DF7A6; }

/* dark mode colors; styles need to be duplicated exactly between these two media blocks */
@media screen {
    html.skin-theme-clientpref-night .babel-box .babel-code a { color: #3366EE; }
    
    html.skin-theme-clientpref-night .babel-box.babel-0 { border-color: #4A0000; }
    html.skin-theme-clientpref-night .babel-box.babel-0 .babel-content { background-color: #410010; }
    html.skin-theme-clientpref-night .babel-box.babel-0 .babel-code {  background-color: #4A0000; }
    
    html.skin-theme-clientpref-night .babel-box.babel-1 { border-color: #570035; }
    html.skin-theme-clientpref-night .babel-box.babel-1 .babel-content { background-color: #390130; }
    html.skin-theme-clientpref-night .babel-box.babel-1 .babel-code {  background-color: #570035; }
    
    html.skin-theme-clientpref-night .babel-box.babel-2 { border-color: #4F0162; }
    html.skin-theme-clientpref-night .babel-box.babel-2 .babel-content { background-color: #210135; }
    html.skin-theme-clientpref-night .babel-box.babel-2 .babel-code {  background-color: #4F0162; }
    
    html.skin-theme-clientpref-night .babel-box.babel-3 { border-color: #19026D; }
    html.skin-theme-clientpref-night .babel-box.babel-3 .babel-content { background-color: #05022F; }
    html.skin-theme-clientpref-night .babel-box.babel-3 .babel-code {  background-color: #19026D; }
    
    html.skin-theme-clientpref-night .babel-box.babel-4 { border-color: #043178; }
    html.skin-theme-clientpref-night .babel-box.babel-4 .babel-content { background-color: #011831; }
    html.skin-theme-clientpref-night .babel-box.babel-4 .babel-code {  background-color: #043178; }
    
    html.skin-theme-clientpref-night .babel-box.babel-5 { border-color: #068384; }
    html.skin-theme-clientpref-night .babel-box.babel-5 .babel-content { background-color: #023534; }
    html.skin-theme-clientpref-night .babel-box.babel-5 .babel-code {  background-color: #068384; }
    
    html.skin-theme-clientpref-night .babel-box.babel-N { border-color: #078E3F; }
    html.skin-theme-clientpref-night .babel-box.babel-N .babel-content { background-color: #023A19; }
    html.skin-theme-clientpref-night .babel-box.babel-N .babel-code {  background-color: #078E3F; }
}

@media screen and (prefers-color-scheme: dark) {
    html.skin-theme-clientpref-os    .babel-box .babel-code a { color: #3366EE; }
    
    html.skin-theme-clientpref-os    .babel-box.babel-0 { border-color: #FFB3B3; }
    html.skin-theme-clientpref-os    .babel-box.babel-0 .babel-content { background-color: #FFE0E8; }
    html.skin-theme-clientpref-os    .babel-box.babel-0 .babel-code { color: #000000; }
    
    html.skin-theme-clientpref-os    .babel-box.babel-1 { border-color: #FEA6DB; }
    html.skin-theme-clientpref-os    .babel-box.babel-1 .babel-content { background-color: #FEDBF8; }
    html.skin-theme-clientpref-os    .babel-box.babel-1 .babel-code { color: #000000; }
    
    html.skin-theme-clientpref-os    .babel-box.babel-2 { border-color: #EA9BFD; }
    html.skin-theme-clientpref-os    .babel-box.babel-2 .babel-content { background-color: #EFD6FE; }
    html.skin-theme-clientpref-os    .babel-box.babel-2 .babel-code { color: #000000; }
    
    html.skin-theme-clientpref-os    .babel-box.babel-3 { border-color: #A68FFC; }
    html.skin-theme-clientpref-os    .babel-box.babel-3 .babel-content { background-color: #D5D2FD; }
    html.skin-theme-clientpref-os    .babel-box.babel-3 .babel-code { color: #000000; }
    
    html.skin-theme-clientpref-os    .babel-box.babel-4 { border-color: #84B2FA; }
    html.skin-theme-clientpref-os    .babel-box.babel-4 .babel-content { background-color: #CDE4FD; }
    html.skin-theme-clientpref-os    .babel-box.babel-4 .babel-code { color: #000000; }
    
    html.skin-theme-clientpref-os    .babel-box.babel-5 { border-color: #78F7F8; }
    html.skin-theme-clientpref-os    .babel-box.babel-5 .babel-content { background-color: #C9FCFB; }
    html.skin-theme-clientpref-os    .babel-box.babel-5 .babel-code { color: #000000; }
    
    html.skin-theme-clientpref-os    .babel-box.babel-N { border-color: #6DF7A6; }
    html.skin-theme-clientpref-os    .babel-box.babel-N .babel-content { background-color: #C4FCDB; }
    html.skin-theme-clientpref-os    .babel-box.babel-N .babel-code { color: #000000; }

}

local export = {}

local function hex_to_RGB(colour)
	colour = colour:gsub("#", "")
	return tonumber(colour:sub(1, 2), 16), tonumber(colour:sub(3, 4), 16), tonumber(colour:sub(5, 6), 16)
end

local function RGB_to_hex(r, g, b)
	return ("#%02X%02X%02X"):format(r, g, b)
end

local function RGB_to_HSL(r, g, b)
	r, g, b = r/255, g/255, b/255
	local max = math.max(r, g, b)
	local min = math.min(r, g, b)
	local h, s, l = 0, 0, (max + min) / 2

	if max ~= min then
		local d = max - min
		s = l > 0.5 and d / (2 - max - min) or d / (max + min)
		if max == r then
			h = ((g - b) / d) % 6
		elseif max == g then
			h = ((b - r) / d) + 2
		else
			h = ((r - g) / d) + 4
		end
		h = h * 60
	end
	return h, s, l
end

function HSL_to_RGB(h, s, l)
	local function hue_to_RGB(p, q, t)
		if t < 0 then t = t + 1 end
		if t > 1 then t = t - 1 end
		if t < 1/6 then return p + (q - p) * 6 * t end
		if t < 1/2 then return q end
		if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end
		return p
	end

	h = h / 360
	local r, g, b

	if s == 0 then
		r, g, b = l, l, l
	else
		local q = l < 0.5 and l * (1 + s) or l + s - l * s
		local p = 2 * l - q
		r = hue_to_RGB(p, q, h + 1/3)
		g = hue_to_RGB(p, q, h)
		b = hue_to_RGB(p, q, h - 1/3)
	end

	return math.floor(r * 255), math.floor(g * 255), math.floor(b * 255)
end

local function invert(colours, blend)
	assert(blend <= 1.3, "blend cannot be greater than 1.3, but " .. blend .. " was provided")
	blend = blend or 0
	
	results = {}
	n = 1
	
	for _, hex in ipairs(colours) do
		local h, s, l = RGB_to_HSL(hex_to_RGB(hex))
		
		-- invert lightness and blend with lightness of dark mode background colour, 101418
		l = (1 - blend) * math.max(1 - l, l - 0.81) + blend * 0.08
		
		results = RGB_to_hex(HSL_to_RGB(h, s, l))
		n = n + 1
	end
	
	return results
end

local function interpolate(first, second, steps, blend)
	local results = {}
	
	local h1, s1, l1 = RGB_to_HSL(hex_to_RGB(first))
	local h2, s2, l2 = RGB_to_HSL(hex_to_RGB(second))
	
	if math.abs(h2 - h1) < 180 then
		if h2 > h1 then
			h1 = h1 + 360
		else
			h2 = h2 + 360
		end
	end
	
	n = 1
	for i = 0, steps - 1 do
		local t = i / (steps - 1)
		local h = ((1 - t) * h1 + t * h2) % 360
		local s = (1 - t) * s1 + t * s2
		local l = (1 - t) * l1 + t * l2
		
		results = RGB_to_hex(HSL_to_RGB(h, s, l))
		n = n + 1
	end

	return results, invert(results, blend)
end

-- https://www.w3.org/WAI/GLhttps://dictious.com/en/Relative_luminance
local function get_WCAG_21_luminance(rgb)
	local r, g, b = rgb, rgb, rgb
	
	local function linearize(c)
		if c <= 0.03928 then
			return c / 12.92
		else
			return ((c + 0.055) / 1.055) ^ 2.4
		end
	end
	
	r = linearize(r / 255)
	g = linearize(g / 255)
	b = linearize(b / 255)
	
	return 0.2126 * r + 0.7152 * g + 0.0722 * b
end

-- Copied from ]:

-- Calculate the WCAG2.1 contrast ratio given two RGB tuples.
-- https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html#dfn-contrast-ratio
local function get_WCAG_21_contrast(rgb1, rgb2)
	local luminance1 = get_WCAG_21_luminance(rgb1)
	local luminance2 = get_WCAG_21_luminance(rgb2)

	-- The lighter colour is used in the numerator.
	local contrast_ratio
	if luminance1 >= luminance2 then
		contrast_ratio = (luminance1 + 0.05) / (luminance2 + 0.05)
	else
		contrast_ratio = (luminance2 + 0.05) / (luminance1 + 0.05)
	end

	return contrast_ratio
end

-- Get the WCAG2.1 rating as HTML, given a contrast value.
local function get_WCAG_21_rating(contrast_value)
	if contrast_value >= 7 then
		return "<span style=\"color:var(--wikt-palette-deepblue)\">(AAA)</span>"
	elseif contrast_value >= 4.5 then
		return "<span style=\"color:var(--wikt-palette-forestgreen)\">(AA)</span>"
	else
		return "<span style=\"color:var(--wikt-palette-red)\">(FAIL)</span>"
	end
end


function export.show(frame)
	local args = frame.args
	
	--- COLOUR TABLE ---
	
	local ret = [[{| class = "wikitable"
				  ! location
				  ! light mode
				  ! dark mode
				  ! WCAG contrast (with text colour)
				  ! WCAG contrast (with <span style="color:var(--color-progressive--hover,#3056a9);">link</span> colour)
				  |- ]]
	
	local blend = 0.03
	local light_colours_left, dark_colours_left = interpolate(frame.args, frame.args, 7, blend)
	local light_colours_right, dark_colours_right = interpolate(frame.args, frame.args, 7, blend)
	
	local light_mode_text = { 32, 33, 34 }
	local dark_mode_text = { 234, 236, 240 }
	local light_mode_link = { 8, 50, 186 }
	local dark_mode_link = { 136, 163, 232 }
	
	local proficiencies = { "0", "1", "2", "3","4", "5", "N" }
	local style_content = mw.title.new("Template:Babel/style.css"):getContent()
	
	for n, i in ipairs(light_colours_left) do
		style_content = style_content
			:gsub("(%.babel%-box%.babel%-" .. proficiencies .. " { border%-color: )#+; }", "%1" .. i .. "; }")
			:gsub("(%.babel%-box%.babel%-" .. proficiencies .. " %.babel%-code { background%-color: )#+; }", "%1" .. i .. "; }")
		local contrast = get_WCAG_21_contrast({ hex_to_RGB(i) }, light_mode_text)
		local link_contrast = get_WCAG_21_contrast({ hex_to_RGB(i) }, light_mode_link)
		ret = ret .. '\n! Babel-' .. proficiencies .. ' left'
				  .. '\n| style="background-color:' .. i .. ';padding:1.7em 0.3em;" |<span style="position:relative;z-index:0;padding:2px 5px;background:var(--wikt-palette-lavender);opacity:0.8;border-radius:3px;">' .. i .. '</span>' 
				  .. '\n| DARK_PLACEHOLDER_LEFT_' .. n
				  .. '\n| <b>Light mode:</b> ' .. tostring(contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(contrast) .. '<br><b>Dark mode:</b> DARK_CONTRAST_LEFT_' .. n
				  .. '\n| <b>Light mode:</b> ' .. tostring(contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(contrast) .. '<br><b>Dark mode:</b> DARK_LINK_CONTRAST_LEFT_' .. n
				  .. '\n|-'
	end
	
	for n, i in ipairs(light_colours_right) do
		style_content = style_content
			:gsub("(%.babel%-box%.babel%-" .. proficiencies .. " %.babel%-content { background%-color: )#+; }", "%1" .. i .. "; }")
		local contrast = get_WCAG_21_contrast({ hex_to_RGB(i) }, light_mode_text)
		ret = ret .. '\n! Babel-' .. proficiencies .. ' right'
				  .. '\n| style="background-color:' .. i .. ';padding:1.7em 0.3em;" |<span style="position:relative;z-index:0;padding:2px 5px;background:var(--wikt-palette-lavender);opacity:0.8;border-radius:3px;">' .. i .. '</span>' 
				  .. '\n| DARK_PLACEHOLDER_RIGHT_' .. n
				  .. '\n| <b>Light mode:</b> ' .. tostring(contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(contrast) .. '<br><b>Dark mode:</b> DARK_CONTRAST_RIGHT_' .. n
				  .. '\n| <b>Light mode:</b> ' .. tostring(contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(contrast) .. '<br><b>Dark mode:</b> DARK_LINK_CONTRAST_RIGHT_' .. n
				  .. '\n|-'
	end
	
	for n, i in ipairs(dark_colours_left) do
		style_content = style_content
			:gsub("(html%.skin%-theme%-clientpref%-night %.babel%-box%.babel%-" .. proficiencies .. " { border%-color: )#+; }", "%1" .. i .. "; }")
			:gsub("(html%.skin%-theme%-clientpref%-night %.babel%-box%.babel%-" .. proficiencies .. " %.babel%-code { )color: #000000; }", "%1 background-color: " .. i .. "; }")
			:gsub("(html%.skin%-theme%-clientpref%-os	%.babel%-box%.babel%-" .. proficiencies .. " { border%-color: )#+; }", "%1" .. i .. "; }")
			:gsub("(html%.skin%-theme%-clientpref%-os	%.babel%-box%.babel%-" .. proficiencies .. " %.babel%-code { )color: #000000; }", "%1 background-color: " .. i .. "; }")
		local contrast = get_WCAG_21_contrast({ hex_to_RGB(i) }, dark_mode_text)
		local link_contrast = get_WCAG_21_contrast({ hex_to_RGB(i) }, dark_mode_link)
		ret = ret:gsub("DARK_PLACEHOLDER_LEFT_" .. n, 'style="background-color:' .. i .. ';padding:1.7em 0.3em;" |<span style="position:relative;z-index:0;padding:2px 5px;background:var(--wikt-palette-lavender);opacity:0.8;border-radius:3px;">' .. i .. '</span>')
				 :gsub("DARK_CONTRAST_LEFT_" .. n, tostring(contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(contrast))
				 :gsub("DARK_LINK_CONTRAST_LEFT_" .. n, tostring(link_contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(link_contrast))
	end
	
	for n, i in ipairs(dark_colours_right) do
		style_content = style_content
			:gsub("(html%.skin%-theme%-clientpref%-night %.babel%-box%.babel%-" .. proficiencies .. " %.babel%-content { background%-color: )#+; }", "%1" .. i .. "; }")
			:gsub("(html%.skin%-theme%-clientpref%-os	%.babel%-box%.babel%-" .. proficiencies .. " %.babel%-content { background%-color: )#+; }", "%1" .. i .. "; }")
		local contrast = get_WCAG_21_contrast({ hex_to_RGB(i) }, dark_mode_text)
		local link_contrast = get_WCAG_21_contrast({ hex_to_RGB(i) }, dark_mode_link)
		ret = ret:gsub("DARK_PLACEHOLDER_RIGHT_" .. n, 'style="background-color:' .. i .. ';padding:1.7em 0.3em;" |<span style="position:relative;z-index:0;padding:2px 5px;background:var(--wikt-palette-lavender);opacity:0.8;border-radius:3px;">' .. i .. '</span>')
				 :gsub("DARK_CONTRAST_RIGHT_" .. n, tostring(contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(contrast))
				 :gsub("DARK_LINK_CONTRAST_RIGHT_" .. n, tostring(link_contrast):sub(1, 5) .. ' ' .. get_WCAG_21_rating(link_contrast))
	end
	
	return ret .. "\n|}\n"
	-- Stylesheet preview
	.. frame:preprocess('<syntaxhighlight lang="CSS">' .. style_content .. '</syntaxhighlight>')
end

return export