MediaWiki:Custom-Themes.scss

//  Compile with the command:

/**/ /* NB: The CSS from here on out was compiled from Special:PermanentLink/ with dart-sass #{$dart_sass_version}. /* Please edit and recompile that source Sass file instead of manually editing what follows. /**/

// // // [config] group theme selectors by palette declarations // // //

// TODO: Empirically determine what's optimal against gzip compression.

$ff_group_theme_selectors_by_palette_decls: false;

// // // [utils] WCAG 2 contrast tester // // //

// See  for details. // Note we use a cut-off of 0.04045 instead of 0.03928; see  for rationale. // Lookup table generated in Python with `[round((c / 12.92) if (c <= 0.04045) else (((c + 0.055) / 1.055) ** 2.4), 4) for c in map(lambda x: x / 255., range(0, 256))]`.

$c_linear_lut: 0.0, 0.0003, 0.0006, 0.0009, 0.0012, 0.0015, 0.0018, 0.0021, 0.0024, 0.0027, 0.003, 0.0033, 0.0037, 0.004, 0.0044, 0.0048, 0.0052, 0.0056, 0.006, 0.0065, 0.007, 0.0075, 0.008, 0.0086, 0.0091, 0.0097, 0.0103, 0.011, 0.0116, 0.0123, 0.013, 0.0137, 0.0144, 0.0152, 0.016, 0.0168, 0.0176, 0.0185, 0.0194, 0.0203, 0.0212, 0.0222, 0.0232, 0.0242, 0.0252, 0.0262, 0.0273, 0.0284, 0.0296, 0.0307, 0.0319, 0.0331, 0.0343, 0.0356, 0.0369, 0.0382, 0.0395, 0.0409, 0.0423, 0.0437, 0.0452, 0.0467, 0.0482, 0.0497, 0.0513, 0.0529, 0.0545, 0.0561, 0.0578, 0.0595, 0.0612, 0.063, 0.0648, 0.0666, 0.0685, 0.0704, 0.0723, 0.0742, 0.0762, 0.0782, 0.0802, 0.0823, 0.0844, 0.0865, 0.0887, 0.0908, 0.0931, 0.0953, 0.0976, 0.0999, 0.1022, 0.1046, 0.107, 0.1095, 0.1119, 0.1144, 0.117, 0.1195, 0.1221, 0.1248, 0.1274, 0.1301, 0.1329, 0.1356, 0.1384, 0.1413, 0.1441, 0.147, 0.15, 0.1529, 0.1559, 0.159, 0.162, 0.1651, 0.1683, 0.1714, 0.1746, 0.1779, 0.1812, 0.1845, 0.1878, 0.1912, 0.1946, 0.1981, 0.2016, 0.2051, 0.2086, 0.2122, 0.2159, 0.2195, 0.2232, 0.227, 0.2307, 0.2346, 0.2384, 0.2423, 0.2462, 0.2502, 0.2542, 0.2582, 0.2623, 0.2664, 0.2705, 0.2747, 0.2789, 0.2831, 0.2874, 0.2918, 0.2961, 0.3005, 0.305, 0.3095, 0.314, 0.3185, 0.3231, 0.3278, 0.3325, 0.3372, 0.3419, 0.3467, 0.3515, 0.3564, 0.3613, 0.3663, 0.3712, 0.3763, 0.3813, 0.3864, 0.3916, 0.3968, 0.402, 0.4072, 0.4125, 0.4179, 0.4233, 0.4287, 0.4342, 0.4397, 0.4452, 0.4508, 0.4564, 0.4621, 0.4678, 0.4735, 0.4793, 0.4851, 0.491, 0.4969, 0.5029, 0.5089, 0.5149, 0.521, 0.5271, 0.5333, 0.5395, 0.5457, 0.552, 0.5583, 0.5647, 0.5711, 0.5776, 0.5841, 0.5906, 0.5972, 0.6038, 0.6105, 0.6172, 0.624, 0.6308, 0.6376, 0.6445, 0.6514, 0.6584, 0.6654, 0.6724, 0.6795, 0.6867, 0.6939, 0.7011, 0.7084, 0.7157, 0.7231, 0.7305, 0.7379, 0.7454, 0.7529, 0.7605, 0.7682, 0.7758, 0.7835, 0.7913, 0.7991, 0.807, 0.8148, 0.8228, 0.8308, 0.8388, 0.8469, 0.855, 0.8632, 0.8714, 0.8796, 0.8879, 0.8963, 0.9047, 0.9131, 0.9216, 0.9301, 0.9387, 0.9473, 0.956, 0.9647, 0.9734, 0.9823, 0.9911, 1.0;

@function luminance($color) { $r: nth($c_linear_lut, red($color) + 1); $g: nth($c_linear_lut, green($color) + 1); $b: nth($c_linear_lut, blue($color) + 1);

@return ((0.2126 * $r) + (0.7152 * $g) + (0.0722 * $b)); }

@function contrast($text_color, $background_color) { $text_lum: luminance($text_color); $background_lum: luminance($background_color);

$l1: max($text_lum, $background_lum); $l2: min($text_lum, $background_lum);

@return (($l1 + 0.05) / ($l2 + 0.05)); }

@mixin emit_contrast_test($comment_prefix, $text_color, $background_color) { $ratio: round(contrast($text_color, $background_color) * 100) / 100;

$comment_prefix: '#{$comment_prefix}the contrast ratio is #{$ratio}:1, which '; @if $ratio >= 7 { /* #{$comment_prefix}passes WCAG 2's enhanced contrast requirements */ } @else if $ratio >= 4.5 { /* #{$comment_prefix}partially passes WCAG 2's enhanced contrast requirements (failing AAA for non-bold text < 18pt and bold text < 14pt) */ } @else if $ratio >= 3 { /* #{$comment_prefix}partially passes WCAG 2's minimum contrast requirements (failing AA for non-bold text < 18pt and bold text < 14pt) */ } @else { /* #{$comment_prefix}fails WCAG 2's minimum contrast requirements */ } }

// // /* [components] navboxes: common layout */ // //

// We're using "navibox" instead of "navbox" as the class prefix because FANDOM have made the unfortunate decision to hide anything matching `.navbox` for mobile. // See  for details.

.navibox { border: 1px solid transparent; border-collapse: separate; border-spacing: 2px; font-size: 90%; width: 100%;

th, td { padding: 2px; } } .navibox-title, .navibox-header, .navibox-group { font-weight: bold; text-align: center; } .navibox-group { font-size: smaller; } .navibox-list { text-align: center; }

// // // [components] navboxes: theme mixins // // //

@mixin themed_navbox($group_width, $palette) { $selector: &;

@at-root { .navibox#{$selector} { @include set_border_color($palette);

.navibox-title, .navibox-header, .navibox-group { @include set_background_color($palette); @include set_text_and_link_color($palette); }

.navibox-group { width: $group_width; }       }    } }

@mixin themed_navbox_section($palette) { $selector: &;

@at-root { .navibox { .navibox-header#{$selector}, .navibox-group#{$selector} { @include set_background_color($palette); @include set_text_and_link_color($palette); }       }    } }

// ~ // // [themes] helpers // // ~ //

@function make_palette($text_color, $background_color, $border_color: $background_color, $link_color: $text_color) { $palette: (       text_color: $text_color,        link_color: $link_color,        background_color: $background_color,        border_color: $border_color,    );

@if $ff_group_theme_selectors_by_palette_decls { $prefix: '%#{str-slice(#{&}, 2)}-'; @debug $prefix; $palette: map-merge($palette, ( text_and_link_color_selector: #{$prefix}text_and_link_color, background_color_selector: #{$prefix}background_color, border_color_selector: #{$prefix}border_color, ));   }

@return $palette; }

@mixin prep_theme($palette) { $text_color: map-get($palette, 'text_color'); $link_color: map-get($palette, 'link_color'); $background_color: map-get($palette, 'background_color'); $border_color: map-get($palette, 'border_color');

@at-root { @include emit_contrast_test(' - NB: for text, ', $text_color, $background_color); @if $link_color != $text_color { @include emit_contrast_test(' - NB: for links, ', $link_color, $background_color); }

@if $ff_group_theme_selectors_by_palette_decls { $text_and_link_color_selector: map-get($palette, 'text_and_link_color_selector'); $background_color_selector: map-get($palette, 'background_color_selector'); $border_color_selector: map-get($palette, 'border_color_selector');

@if $text_color == #ffffff and $link_color == #ffffff { #{$text_and_link_color_selector} { @extend %theme-dark; }           } @else if $text_color == #1a1a1a and $link_color == #1a1a1a { #{$text_and_link_color_selector} { @extend %theme-light; }           } @else if $text_color == $link_color { #{$text_and_link_color_selector}, #{$text_and_link_color_selector} a { color: $text_color; }           } @else { #{$text_and_link_color_selector} { color: $text_color; a { color: $link_color; }               }            }

#{$background_color_selector} { background-color: $background_color; }

#{$border_color_selector} { border-color: $border_color; }       }    } }

@mixin set_text_and_link_color($palette) { @if $ff_group_theme_selectors_by_palette_decls { @extend #{map-get($palette, 'text_and_link_color_selector')}; } @else { color: map-get($palette, 'text_color'); a { color: map-get($palette, 'link_color'); }   } }

@mixin set_background_color($palette) { @if $ff_group_theme_selectors_by_palette_decls { @extend #{map-get($palette, 'background_color_selector')}; } @else { background-color: map-get($palette, 'background_color'); } }

@mixin set_border_color($palette) { @if $ff_group_theme_selectors_by_palette_decls { @extend #{map-get($palette, 'border_color_selector')}; } @else { border-color: map-get($palette, 'border_color'); } }

@if $ff_group_theme_selectors_by_palette_decls { // ~ //   /* [themes] white on dark */ // ~ //

%theme-dark, %theme-dark a { color: #ffffff; }

// //    /* [themes] black on light */ // //

%theme-light, %theme-light a { color: #1a1a1a; } }

// ~ // /* [themes] by affiliation: League of Villains */ // ~ //

.theme-affiliation-league_of_villains { $palette: make_palette(       $text_color: #ffffff,        $background_color: #708090,    ); @include prep_theme($palette);

@include themed_navbox_section($palette); }

// // /* [themes] by affiliation: Shie Hassaikai */ // //

.theme-affiliation-shie_hassaikai { $palette: make_palette(       $text_color: #ffffff,        $background_color: #483d8b,    ); @include prep_theme($palette);

@include themed_navbox_section($palette); }

// // /* [themes] by affiliation: villains */ // //

.theme-affiliation-villains { $palette: make_palette(       $text_color: #ffffff,        $background_color: #141414,    ); @include prep_theme($palette);

@include themed_navbox(       $group_width: 100px,        $palette: $palette,    ); }

// ~ // /* [themes] by page type: music */ // ~ //

.theme-page_type-music { $palette: make_palette(       $text_color: #ffffff,        $background_color: #2f4f4f,        $border_color: #aaaaaa,    ); @include prep_theme($palette);

@include themed_navbox(       $group_width: 125px,        $palette: $palette,    ); }

// // /* [themes] by page type: Quirks */ // //

.theme-page_type-quirks { $palette: make_palette(       $text_color: #ffffff,        $background_color: #ffbf00,        $border_color: #aaaaaa,    ); @include prep_theme($palette);

@include themed_navbox(       $group_width: 125px,        $palette: $palette,    ); }

//