<header>
  <h3>Scheme</h3>
  <form id="theme-switcher">
    <div>
      <input checked type="radio" id="auto" name="theme" value="auto">
      <label for="auto">Auto</label>
    </div>
    <div>
      <input type="radio" id="light" name="theme" value="light">
      <label for="light">Light</label>
    </div>
    <div>
      <input type="radio" id="dark" name="theme" value="dark">
      <label for="dark">Dark</label>
    </div>
    <div>
      <input type="radio" id="dim" name="theme" value="dim">
      <label for="dim">Dim</label>
    </div>
  </form>
</header>

<div class="wrapper">
  <ul>
    <li>Primary</li>
    <li>Surface1</li>
    <li>Surface2</li>
    <li>Surface3</li>
    <li>Surface4</li>
  </ul>
</div>
@import url("https://fonts.googleapis.com/css2?family=Exo:wght@600&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  width: 100vw;
  min-height: 100vh;
  font-family: "Exo", Arial, sans-serif;
  background-color: #557;

  padding: 5vmax;
  display: grid;
  grid-template-columns: 1fr;
  place-content: center;
  gap: 5vmax;
}

header {
  display: inline-grid;
  gap: 1ch;
}

form {
  display: flex;
  gap: 2ch;
}

form > div {
  display: inline-flex;
  align-items: center;
  gap: 0.75ch;
}

/* Default: Light*/
:root {
  color-scheme: light;
  --primary-hue: 250;
  --primary-saturation: 100%;
  --primary-lightness: 90%;
}

html {
  --primary: hsl(
    var(--primary-hue) var(--primary-saturation) var(--primary-lightness)
  );
  --on-primary: hsl(var(--primary-hue) var(--primary-saturation) 10%);

  --surface1: hsl(var(--primary-hue) 40% 90%);
  --surface2: hsl(var(--primary-hue) 30% 99%);
  --surface3: hsl(var(--primary-hue) 30% 92%);
  --surface4: hsl(var(--primary-hue) 30% 85%);

  --surface-shadow: var(--primary-hue) 40% 10%;
  --shadow-strength: 0.25;
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
  }
  html {
    --primary: hsl(
      var(--primary-hue) calc(var(--primary-saturation) / 2.5)
        calc(var(--primary-lightness) / 2.5)
    );
    --on-primary: hsl(var(--primary-hue) var(--primary-saturation) 90%);

    --surface1: hsl(var(--primary-hue) 40% 50%);
    --surface2: hsl(var(--primary-hue) 38% 46%);
    --surface3: hsl(var(--primary-hue) 36% 41%);
    --surface4: hsl(var(--primary-hue) 34% 30%);
    --surface-shadow: var(--primary-hue) 40% 20%;
    --shadow-strength: 0.25;
  }
}

@media (prefers-contrast: less) {
  html {
    --primary: hsl(
      var(--primary-hue) calc(var(--primary-saturation) / 1.5)
        calc(var(--primary-lightness) / 3.5)
    );
    --on-primary: hsl(var(--primary-hue) 35% 90%);

    --surface1: hsl(var(--primary-hue) 40% 20%);
    --surface2: hsl(var(--primary-hue) 40% 25%);
    --surface3: hsl(var(--primary-hue) 30% 30%);
    --surface4: hsl(var(--primary-hue) 30% 35%);

    --surface-shadow: var(--primary-hue) 40% 10%;
    --shadow-strength: 0.25;
  }
}

[color-scheme="light"] {
  color-scheme: light;
  --primary: hsl(
    var(--primary-hue) var(--primary-saturation) var(--primary-lightness)
  );
  --on-primary: hsl(var(--primary-hue) var(--primary-saturation) 10%);

  --surface1: hsl(var(--primary-hue) 40% 90%);
  --surface2: hsl(var(--primary-hue) 30% 99%);
  --surface3: hsl(var(--primary-hue) 30% 92%);
  --surface4: hsl(var(--primary-hue) 30% 85%);

  --surface-shadow: var(--primary-hue) 40% 10%;
  --shadow-strength: 0.25;
}

[color-scheme="dark"] {
  color-scheme: dark;
  --primary: hsl(
    var(--primary-hue) calc(var(--primary-saturation) / 2.5)
      calc(var(--primary-lightness) / 2.5)
  );
  --on-primary: hsl(var(--primary-hue) var(--primary-saturation) 90%);

  --surface1: hsl(var(--primary-hue) 40% 50%);
  --surface2: hsl(var(--primary-hue) 38% 46%);
  --surface3: hsl(var(--primary-hue) 36% 41%);
  --surface4: hsl(var(--primary-hue) 34% 30%);
  --surface-shadow: var(--primary-hue) 40% 20%;
  --shadow-strength: 0.25;
}

[color-scheme="dim"] {
  color-scheme: dark;
  --primary: hsl(
    var(--primary-hue) calc(var(--primary-saturation) / 1.5)
      calc(var(--primary-lightness) / 3.5)
  );
  --on-primary: hsl(var(--primary-hue) 35% 90%);

  --surface1: hsl(var(--primary-hue) 40% 20%);
  --surface2: hsl(var(--primary-hue) 40% 25%);
  --surface3: hsl(var(--primary-hue) 30% 30%);
  --surface4: hsl(var(--primary-hue) 30% 35%);

  --surface-shadow: var(--primary-hue) 40% 10%;
  --shadow-strength: 0.25;
}

ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
  list-style: none;
}

li {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  aspect-ratio: 4 / 1;
  border-radius: 6px;
  box-shadow: 0 0 2px 3px hsl(var(--surface-shadow) / var(--shadow-strength));
  color: var(--on-primary);
}

li:nth-child(1) {
  background-color: var(--primary);
}

li:nth-child(2) {
  background-color: var(--surface1);
}

li:nth-child(3) {
  background-color: var(--surface2);
}

li:nth-child(4) {
  background-color: var(--surface3);
}

li:nth-child(5) {
  background-color: var(--surface4);
}
const switcher = document.querySelector("#theme-switcher");
const doc = document.firstElementChild;

switcher.addEventListener("input", (e) => setTheme(e.target.value));

const setTheme = (theme) => doc.setAttribute("color-scheme", theme);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.