<h1>Automated Color Contrast Ratios</h1>

<div class="color">
  <h2>Test Cases &nbsp;</h2>
  <div class="color__swatch color__swatch--fg1">fg-1</div>
  <div class="color__swatch color__swatch--fg2">fg-2</div>
  <div class="color__swatch color__swatch--bg1">bg-1</div>
  <div class="color__swatch color__swatch--bg2">bg-2</div>
  <div class="color__swatch color__swatch--bg3">bg-3</div>
</div>

<div class="ally">
  <div class="ally__item ally-fg1-bg1">
    <p>BEFORE: Foreground 1 over background 1: AAA target (7.0), 16px text, not bold</p>
  </div>
  <div class="ally__item pair-fg1-bg1">
    <p>AFTER: Foreground 1 over background 1: AAA target (7.0), 16px text, not bold</p>
  </div>
  
  <div class="ally__item ally-fg1-bg2">
    <p style="font-size: 19px;"><b>BEFORE: Foreground 1 over background 2: AA target (3.0), 19px text, bold</b></p>
  </div>
  <div class="ally__item pair-fg1-bg2">
    <p style="font-size: 19px;"><b>AFTER: Foreground 1 over background 2: AA target (3.0), 19px text, bold</b></p>
  </div>
  
  <div class="ally__item ally-fg1-bg3">
    <p>BEFORE: Foreground 1 over background 3: AA target (4.5), 16px text, not bold</p>
  </div>
  <div class="ally__item pair-fg1-bg3">
    <p>AFTER: Foreground 1 over background 3: AA target (4.5), 16px text, not bold</p>
  </div>
  
  <div class="ally__item ally-fg2-bg1">
    <p>BEFORE: Foreground 2 over background 1: AA target (4.5), 16px text, not bold</p>
  </div>
  <div class="ally__item pair-fg2-bg1">
    <p>AFTER: Foreground 2 over background 1: AA target (4.5), 16px text, not bold</p>
  </div>
  
  <div class="ally__item ally-fg2-bg2">
    <p style="font-size: 19px;">BEFORE: Foreground 2 over background 2: AAA target (4.5), 19px text, not bold</p>
  </div>
  <div class="ally__item pair-fg2-bg2">
    <p style="font-size: 19px;">AFTER: Foreground 2 over background 2: AAA target (4.5), 19px text, not bold</p>
  </div>
  
  <div class="ally__item ally-fg2-bg3">
    <p>BEFORE: Foreground 2 over background 3: AA target (4.5), 16px text, not bold</p>
  </div>
  <div class="ally__item pair-fg2-bg3">
    <p>AFTER: Foreground 2 over background 3: AA target (4.5), 16px text, not bold</p>
  </div>
</div>

<h2>Usage</h2>
<p>Input a foreground color, background color, desired WCAG Level (optional), font-size (optional), and whether or not the font is bold (optional) to return an adjusted foreground color that passes the chosen WCAG Level for color contrast ratio.</p>

<pre>
  // Usage, where:
  // $text-color is the desired color which will be changed
  // $background is the unchanged color
  // $level is the WCAG level desired, default 'AA'
  // $size is the font-size to consider, default 16
  // $bold is whether or not the font is bold, default 'false'
  .example {
    background-color: $background;
    color: a11y-color($text-color, $background, $level, $size, $bold);
  }
</pre>

<h2>Explanation</h2>
<p>An accessible Color Contrast is important for legibility. Often, a company’s brand color palette does not take this into account. Further, the color behind a foreground text color will effect its ability to pass for sufficient contrast ratio. This set of functions provides programmatic SASS to achieve passing color contrast tests. It allows the theme engineer to pass colors and optional parameters to get the results that pass the desired threshold. Sensible defaults are in place. </p>

<h2>More about WCAG Color Contrast levels</h2>
<p>WCAG 2.1 guidelines dictate a minimum contrast ratio of 4.5:1 for the visual presentation of both text and images embedded as text. Large text (18 point, 14 point if bold, and larger font sizes plus images of very large text) requires a 3:1 contrast ratio.</p>
<p>14 point text is equivalent to 19px. 18 point text is equivalent to 24px. Therefore:</p>
<ul>
  <li>Level AA: Text 24px and larger <b>or 19px and larger if bold</b> should have a CCR of 3:1</li>
  <li>Level AA: Text 23px and smaller should have a CCR of 4.5:1</li>
  <li>Level AAA: Text 24px and larger <b>or 19px and larger if bold</b> should have a CCR of 4.5:1</li>
  <li>Level AAA: Text 23px and smaller should have a CCR of 7:1</li>
</ul>
<p>There are no contrast requirements for logotypes and incidental text — text that has no context to the website's core purpose. This would include text for decoration and iconography alongside descriptive text. Inactive elements — like a button in a disabled state — are identified by their low contrast and therefore are not required to meet minimum. </p>

<h2>Acknowledgments</h2>
<p>The build time required for this solution is much better than <a href="https://codepen.io/jhogue/pen/WNeBNpr">my previous idea</a>. Thanks to <a href="https://medium.com/dev-channel/using-sass-to-automatically-pick-text-colors-4ba7645d2796">Sérgio Gomes</a> for his idea of using a lookup table. It makes all the difference. </p>
<p>Credit to Lea Verou and her <a hre="https://github.com/LeaVerou/contrast-ratio/blob/gh-pages/color.js">Color.js</a> for direction and others who provided <a href="http://www.sassmeister.com/gist/ad6e6771df050ff3727f">complicated math functions</a> and inspiration for calculating luminance in multiple ways. Finding an efficient set of functions to compute decimal exponents (“POW” functions) was the most difficult previously, but now I decided to leave that work to a lookup table instead. Its much more performant that forcing SASS to do things it was not meant to do.</p>

<h2>Edge Case(s)</h2>
<p>There are some edge cases I am sure. Need to find them and figure out how to work around them.</p>
<p>Here is one: Supplying black or white as the foreground color yields unexpected results.</p>
<ul>
  <li>Example: <code>@include count-a11y-color(#000, #c0c);</code></li>
  <li><code>color-contrast(#000, #c0c)</code> = 4.44, which rightly fails</li>
  <li>But #000 can only be lightened which means the combo will never pass. What needs to happen in this case is the background color should be modified to pass</li>
  <li>The @while gives up after 206 loops with color #fef8f8, which also fails. No light foreground will pass with a light background</li>
  </ul>
// Play with These to Test!
$fg-1: #0094c2;
$fg-2: #E35B34;
$bg-1: #fff;
$bg-2: #efefef;
$bg-3: #444; // changing this to #0c0 makes CodePen hang

// Globals
$white: #fff;
$black: #101010;

@function strip-unit($value) {
  @return ($value / ($value * 0 + 1));
}

// From https://github.com/material-components/material-components-web/blob/master/packages/mdc-theme/_constants.scss
//
// Copyright 2017 Google Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Precomputed linear color channel values, for use in contrast calculations.
// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
//
// Algorithm, for c in 0 to 255:
// f(c) {
//   c = c / 255;
//   return c < 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
// }
//
// This lookup table is needed since there is no `pow` in SASS.
$linear-channel-values:
  0
  .0003035269835488375
  .000607053967097675
  .0009105809506465125
  .00121410793419535
  .0015176349177441874
  .001821161901293025
  .0021246888848418626
  .0024282158683907
  .0027317428519395373
  .003035269835488375
  .003346535763899161
  .003676507324047436
  .004024717018496307
  .004391442037410293
  .004776953480693729
  .005181516702338386
  .005605391624202723
  .006048833022857054
  .006512090792594475
  .006995410187265387
  .007499032043226175
  .008023192985384994
  .008568125618069307
  .009134058702220787
  .00972121732023785
  .010329823029626936
  .010960094006488246
  .011612245179743885
  .012286488356915872
  .012983032342173012
  .013702083047289686
  .014443843596092545
  .01520851442291271
  .01599629336550963
  .016807375752887384
  .017641954488384078
  .018500220128379697
  .019382360956935723
  .0202885630566524
  .021219010376003555
  .022173884793387385
  .02315336617811041
  .024157632448504756
  .02518685962736163
  .026241221894849898
  .027320891639074894
  .028426039504420793
  .0295568344378088
  .030713443732993635
  .03189603307301153
  .033104766570885055
  .03433980680868217
  .03560131487502034
  .03688945040110004
  .0382043715953465
  .03954623527673284
  .04091519690685319
  .042311410620809675
  .043735029256973465
  .04518620438567554
  .046665086336880095
  .04817182422688942
  .04970656598412723
  .05126945837404324
  .052860647023180246
  .05448027644244237
  .05612849004960009
  .05780543019106723
  .0595112381629812
  .06124605423161761
  .06301001765316767
  .06480326669290577
  .06662593864377289
  .06847816984440017
  .07036009569659588
  .07227185068231748
  .07421356838014963
  .07618538148130785
  .07818742180518633
  .08021982031446832
  .0822827071298148
  .08437621154414882
  .08650046203654976
  .08865558628577294
  .09084171118340768
  .09305896284668745
  .0953074666309647
  .09758734714186246
  .09989872824711389
  .10224173308810132
  .10461648409110419
  .10702310297826761
  .10946171077829933
  .1119324278369056
  .11443537382697373
  .11697066775851084
  .11953842798834562
  .12213877222960187
  .12477181756095049
  .12743768043564743
  .1301364766903643
  .13286832155381798
  .13563332965520566
  .13843161503245183
  .14126329114027164
  .14412847085805777
  .14702726649759498
  .14995978981060856
  .15292615199615017
  .1559264637078274
  .1589608350608804
  .162029375639111
  .1651321945016676
  .16826940018969075
  .1714411007328226
  .17464740365558504
  .17788841598362912
  .18116424424986022
  .184474994500441
  .18782077230067787
  .19120168274079138
  .1946178304415758
  .19806931955994886
  .20155625379439707
  .20507873639031693
  .20863687014525575
  .21223075741405523
  .21586050011389926
  .2195261997292692
  .2232279573168085
  .22696587351009836
  .23074004852434915
  .23455058216100522
  .238397573812271
  .24228112246555486
  .24620132670783548
  .25015828472995344
  .25415209433082675
  .2581828529215958
  .26225065752969623
  .26635560480286247
  .2704977910130658
  .27467731206038465
  .2788942634768104
  .2831487404299921
  .2874408377269175
  .29177064981753587
  .2961382707983211
  .3005437944157765
  .3049873140698863
  .30946892281750854
  .31398871337571754
  .31854677812509186
  .32314320911295075
  .3277780980565422
  .33245153634617935
  .33716361504833037
  .3419144249086609
  .3467040563550296
  .35153259950043936
  .3564001441459435
  .3613067797835095
  .3662525955988395
  .3712376804741491
  .3762621229909065
  .38132601143253014
  .386429433787049
  .39157247774972326
  .39675523072562685
  .4019777798321958
  .4072402119017367
  .41254261348390375
  .4178850708481375
  .4232676699860717
  .4286904966139066
  .43415363617474895
  .4396571738409188
  .44520119451622786
  .45078578283822346
  .45641102318040466
  .4620769996544071
  .467783796112159
  .47353149614800955
  .4793201831008268
  .4851499400560704
  .4910208498478356
  .4969329950608704
  .5028864580325687
  .5088813208549338
  .5149176653765214
  .5209955732043543
  .5271151257058131
  .5332764040105052
  .5394794890121072
  .5457244613701866
  .5520114015120001
  .5583403896342679
  .5647115057049292
  .5711248294648731
  .5775804404296506
  .5840784178911641
  .5906188409193369
  .5972017883637634
  .6038273388553378
  .6104955708078648
  .6172065624196511
  .6239603916750761
  .6307571363461468
  .6375968739940326
  .6444796819705821
  .6514056374198242
  .6583748172794485
  .665387298282272
  .6724431569576875
  .6795424696330938
  .6866853124353135
  .6938717612919899
  .7011018919329731
  .7083757798916868
  .7156935005064807
  .7230551289219693
  .7304607400903537
  .7379104087727308
  .7454042095403874
  .7529422167760779
  .7605245046752924
  .768151147247507
  .7758222183174236
  .7835377915261935
  .7912979403326302
  .799102738014409
  .8069522576692516
  .8148465722161012
  .8227857543962835
  .8307698767746546
  .83879901174074
  .846873231509858
  .8549926081242338
  .8631572134541023
  .8713671191987972
  .8796223968878317
  .8879231178819663
  .8962693533742664
  .9046611743911496
  .9130986517934192
  .9215818562772946
  .9301108583754237
  .938685728457888
  .9473065367331999
  .9559733532492861
  .9646862478944651
  .9734452903984125
  .9822505503331171
  .9911020971138298
  1;

// luminance($color)
// @requires $linear-channel-values [list]
// Helper: Calculate Luminance of a single color
// Adapted from: https://medium.com/dev-channel/using-sass-to-automatically-pick-text-colors-4ba7645d2796
// White luminance is 1, Black luminance is 0
// To be used in other functions or mixins — creates non-standard CSS output:
// Usage: 
// .sample { luminance: luminance(#c00); }
// Output:
// .sample { luminance: 0.1283736922; }
//
@function luminance($color) {
  // $linear-channel-values are our Lookup Table of constants
  $red: nth($linear-channel-values, red($color) + 1);
  $green: nth($linear-channel-values, green($color) + 1);
  $blue: nth($linear-channel-values, blue($color) + 1);
  $calculation: .2126 * $red + .7152 * $green + .0722 * $blue;
  @return $calculation;
}

// color-contrast($fg, $bg)
// Helper: Calculate "readability" as defined by WCAG 2.1
// Adapted from: https://github.com/LeaVerou/contrast-ratio/blob/gh-pages/color.js
// Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
// To be used in other functions or mixins — creates non-standard CSS output:
// Usage: 
// .sample { color-contrast: color-contrast(#c00, #fff); }
// Output:
// .sample { color-contrast: 5.89; }
//
@function color-contrast($fg, $bg) {
  $luminance1: luminance($fg) + 0.05;
  $luminance2: luminance($bg) + 0.05;
  $ratio: $luminance1 / $luminance2;
  @if $luminance2 > $luminance1 {
    $ratio: 1 / $ratio;
  }
  // Round to a hundreth because 6.96 should not pass a ratio of 7.0
  $ratio: round($ratio * 100) / 100;
  @return $ratio;
}

// validate-font-size($size)
// Helper: Depending on the unit recalculate a font size value into pixels if possible
// To be used in other functions or mixins — creates non-standard CSS output:
// Usage: 
// .sample { validate-font-size: validate-font-size(1em); }
// Output: 
// .sample { validate-font-size: 16; }
//
@function validate-font-size($size) {
  @if unit($size) == 'em' or unit($size) == 'rem' or unit($size) == 'px' or unit($size) == '' {
    // Check if a flexible unit
    @if unit($size) == 'em' or unit($size) == 'rem' {
      // Need to convert to a pixel value. Let's not overcomplicate it with possible EM inheritence scale factors
      @return strip-unit($size * 16)
    }
    @if unit($size) == 'px' {
      // We expect PX, so strip the value and return it
      @return strip-unit($size);
    }
    @if unit($size) == '' {
      @return $size;
    }
  } @else {
    @error 'validate-font-size(): An unexpected font size unit was supplied.';
  }
}

// get-ratio($level: 'AA', $size: 16, $bold: false)
// Helper: Determine the correct ratio value to use based on font-size and WCAG Level
// To be used in other functions or mixins — creates non-standard CSS output:
// Usage: 
// .sample { get-ratio: get-ratio('AAA', 19, true); }
// Output: 
// .sample { get-ratio: 4.5; }
//
@function get-ratio($level: 'AA', $size: 16, $bold: false) {
  // Default ratio
  $ratio: 4.5;
  @if $level == 'AAA' {
    $ratio: 7;
  }
  
  // Make sure the size is valid. If the value is not EM, REM, or PX (preferred), we can't help
  $size: validate-font-size($size);
  
  // Check font size
  @if $size < 24 {
    // Small text, use defaults
    // But:
    @if $size >= 19 and $bold == true {
      // Special case: Small text but also bold
      @if $level == 'AAA' {
        $ratio: 4.5;
      } @else {
        $ratio: 3;
      }
    }
  } @else {
    // Larger than 24
    $ratio: 3;
    @if $level == 'AAA' {
      $ratio: 4.5;
    }
  }
  @return $ratio;
}

// light-or-dark($color)
// Helper: Use contrast against white or black to determine if a color is "light" or "dark"
// Adapted from: https://medium.com/dev-channel/using-sass-to-automatically-pick-text-colors-4ba7645d2796
// To be used in other functions or mixins — creates non-standard CSS output:
// Usage: 
// .sample { light-or-dark: light-or-dark(#c00); }
// Output: 
// .sample { light-or-dark: "light"; }
//
@function light-or-dark($color) {
  $light-contrast: color-contrast($color, $white);
  $dark-contrast: color-contrast($color, $black);

  @if $light-contrast > $dark-contrast {
    // Contrast against white is higher than against black, so, this is a dark color
    @return "dark";
  } @else {
    @return "light";
  }
}

// most-legible-color($color)
// Helper: In some cases, we simply want to use black or white text over a color, whichever is more appropriate
// Usage: 
// .sample {
//   background-color: #c00;
//   color: most-legible-color(#c00);
// }
// Output:
// .sample {
//   background-color: #c00;
//   color: #fff;
// }
@function most-legible-color($color) {
  $color-lod: light-or-dark($color);

  @if ($color-lod == "dark") {
    @return $white;
  } @else {
    @return $black;
  }
}

// a11y-color($fg, $bg, $level: 'AA', $size: 16, $bold: false)
// Goal: Return a color that passes for the chosen WCAG level without changing the Hue of the color
// Usage:
// .sample {
//   background-color: #000;
//   color: a11y-color(#c0c, #000);
// }
// Output:
// .sample {
//   background-color: #000;
//   color: #d200d2;
// }
//
@function a11y-color($fg, $bg, $level: 'AA', $size: 16, $bold: false) {
  // Helper: make sure the font size value is acceptable
  $font-size: validate-font-size($size);
  // Helper: With the level, font size, and bold boolean, return the proper target ratio. 3.0, 4.5, or 7.0 expected
  $ratio: get-ratio($level, $font-size, $bold);
  // Calculate the first contrast ratio of the given pair
  $original-contrast: color-contrast($fg, $bg);
  
  @if $original-contrast >= $ratio {
    // If we pass the ratio already, return the original color
    @return $fg;
  } @else {
    // Doesn't pass. Time to get to work
    // Should the color be lightened or darkened?
    $fg-lod: light-or-dark($fg);
    $bg-lod: light-or-dark($bg);

    // Set a "step" value to lighten or darken a color
    // Note: Higher percentage steps means faster compile time, but we might overstep the required threshold too far with something higher than 5%
    $step: 2%;
    
    // Run through some cases where we want to darken, or use a negative step value
    @if $fg-lod == 'light' and $bg-lod == 'light' {
      // Both are light colors, darken the fg
      $step: - $step;
    } @else if $fg-lod == 'dark' and $bg-lod == 'light' {
      // bg is light, fg is dark but does not pass, darken more
      $step: - $step;
    }
    // Keeping the rest of the logic here, but our default values do not change, so this logic is not needed
    //@else if $fg-lod == 'light' and $bg-lod == 'dark' {
    //  // bg is dark, fg is light but does not pass, lighten further
    //  $step: $step;
    //} @else if $fg-lod == 'dark' and $bg-lod == 'dark' {
    //  // Both are dark, so lighten the fg
    //  $step: $step;
    //}
    
    // The magic happens here
    // Loop through with a @while statement until the color combination passes our required ratio. Scale the color by our step value until the expression is false
    // This might loop 100 times or more depending on the colors
    @while color-contrast($fg, $bg) < $ratio {
      $fg: scale-color($fg, $lightness: $step, $saturation: $step/2);
    }
    @return $fg;
  }
}

///
/// ! - - - Styles for the Demo Color Values - - - 
///

.color {
  display: flex;
  flex-flow: row nowrap;

  &__swatch {
    padding: 1.5rem;
    border: 0.5px solid #101010;
    position: relative;
  
    &--fg1 {
      color: most-legible-color($fg-1);
      background-color: $fg-1;
      
      &::after { content: ' #{$fg-1}'; }
    }
    
    &--fg2 {
      color: most-legible-color($fg-2);
      background-color: $fg-2;
      
      &::after { content: ' #{$fg-2}'; }
    }
    
    &--bg1 {
      color: most-legible-color($bg-1);
      background-color: $bg-1;
      
      &::after { content: ' #{$bg-1}'; }
    }
    
    &--bg2 {
      color: most-legible-color($bg-2);
      background-color: $bg-2;
      
      &::after { content: ' #{$bg-2}'; }
    }
    
    &--bg3 {
      color: most-legible-color($bg-3);
      background-color: $bg-3;
      
      &::after { content: ' #{$bg-3}'; }
    }
  }
}

.ally {
  border: 0.5px solid #101010;
  
  &__item {
    padding: 1rem 2rem 1rem 1rem;
    position: relative;
    
    p {
      margin: 0;
    }
    
    &::after {
      font-size: 0.75rem;
      font-weight: bold;
      position: absolute;
      top: 50%;
      right: 0.5rem;
      transform: translateY(-50%);
    }
  }
}


.ally-fg1-bg1 {
  background-color: $bg-1;
  color: $fg-1;
  
  &::after {
    content: '#{color-contrast($fg-1, $bg-1)}';
  }
}

.pair-fg1-bg1 {
  background-color: $bg-1;
  $a11y-color: a11y-color($fg-1, $bg-1, 'AAA', 24, true);
  color: $a11y-color;
  
  &::after {
    content: '#{color-contrast($a11y-color, $bg-1)}';
  }
}

.ally-fg1-bg2 {
  background-color: $bg-2;
  color: $fg-1;
  
  &::after {
    content: '#{color-contrast($fg-1, $bg-2)}';
  }
}

.pair-fg1-bg2 {
  background-color: $bg-2;
  $a11y-color: a11y-color($fg-1, $bg-2, 'AAA', 19, true);
  color: $a11y-color;
  
  &::after {
    content: '#{color-contrast($a11y-color, $bg-2)}';
  }
}

.ally-fg1-bg3 {
  background-color: $bg-3;
  color: $fg-1;
  
  &::after {
    content: '#{color-contrast($fg-1, $bg-3)}';
  }
}

.pair-fg1-bg3 {
  background-color: $bg-3;
  $a11y-color: a11y-color($fg-1, $bg-3);
  color: $a11y-color;
  
  &::after {
    content: '#{color-contrast($a11y-color, $bg-3)}';
  }
}

.ally-fg2-bg1 {
  background-color: $bg-1;
  color: $fg-2;
  
  &::after {
    content: '#{color-contrast($fg-2, $bg-1)}';
  }
}

.pair-fg2-bg1 {
  background-color: $bg-1;
  $a11y-color: a11y-color($fg-2, $bg-1);
  color: $a11y-color;
  
  &::after {
    content: '#{color-contrast($a11y-color, $bg-1)}';
  }
}

.ally-fg2-bg2 {
  background-color: $bg-2;
  color: $fg-2;
  
  &::after {
    content: '#{color-contrast($fg-2, $bg-2)}';
  }
}

.pair-fg2-bg2 {
  background-color: $bg-2;
  $a11y-color: a11y-color($fg-2, $bg-2, 'AAA', 19, true);
  color: $a11y-color;
  
  &::after {
    content: '#{color-contrast($a11y-color, $bg-2)}';
  }
}

.ally-fg2-bg3 {
  background-color: $bg-3;
  color: $fg-2;
  
  &::after {
    content: '#{color-contrast($fg-2, $bg-3)}';
  }
}

.pair-fg2-bg3 {
  background-color: $bg-3;
  $a11y-color: a11y-color($fg-2, $bg-3);
  color: $a11y-color;
  
  &::after {
    content: '#{color-contrast($a11y-color, $bg-3)}';
  }
}


///
/// ! - - - Styles to Make the Demo Prettier - - - 
///
body {
  padding: 2em;
  font-family: sans-serif;
  line-height: 1.5;
}

h1 {
  margin-top: 0;
  padding-top: 0;
}

pre {
  $sage-green: #00552A;
  background-color: a11y-color(#9fdfbf, $sage-green);
  color: $sage-green;
  padding: 1.25rem 0.5rem;
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.