Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <picture>
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-male-dark.avif" media="(prefers-color-scheme:dark)" type="image/avif">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-male-dark.heic" media="(prefers-color-scheme:dark)" type="image/heic">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-male-dark.webp" media="(prefers-color-scheme:dark)" type="image/webp">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-male-dark.png" media="(prefers-color-scheme:dark)" type="image/png">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-male-light.avif" media="(prefers-color-scheme:light)" type="image/avif">
  <source srcset="/img/icons/shell-blue-male-light.heic" media="(prefers-color-scheme:light)" type="image/heic">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-male-light.webp" media="(prefers-color-scheme:light)" type="image/webp">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-male-light.png" media="(prefers-color-scheme:light)" type="image/png">
  <img alt="Reinhart Previano K." src="https://reinhart1010.id/img/icons/shell-blue-male-neutral.png" height="668" width="691" style="height: 6rem; width: auto;">
</picture>
<picture>
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-female-dark.avif" media="(prefers-color-scheme:dark)" type="image/avif">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-female-dark.heic" media="(prefers-color-scheme:dark)" type="image/heic">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-female-dark.webp" media="(prefers-color-scheme:dark)" type="image/webp">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-female-dark.png" media="(prefers-color-scheme:dark)" type="image/png">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-female-light.avif" media="(prefers-color-scheme:light)" type="image/avif">
  <source srcset="/img/icons/shell-blue-female-light.heic" media="(prefers-color-scheme:light)" type="image/heic">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-female-light.webp" media="(prefers-color-scheme:light)" type="image/webp">
  <source srcset="https://reinhart1010.id/img/icons/shell-blue-female-light.png" media="(prefers-color-scheme:light)" type="image/png">
  <img alt="Reinhart Previano K." src="https://reinhart1010.id/img/icons/shell-blue-female-neutral.png" height="668" width="691" style="height: 6rem; width: auto;">
</picture>

# OkLCH _Color Palette_ for 2023

**Check out our article at <https://reinhart1010.id/blog/2023/01/01/new-color-palettes/>.**

We decided to use **OkLCH** instead of regular RGB/HSV, and taking advantage of newer electronic displays<sup>1, 3</sup> to make our brand colors more expressive than ever.

Our color palettes were divided into two main series, **Galih-Ratna** and **Dilan-Milea**. However, we decided to merge both to use different palettes for light (Galih-Ratna) and dark (Dilan-Milea) display modes.

<noscript>
  You'll need to enable JavaScript to view the color palette.
</noscript>

Your browser currently <i class="bi bi-check-circle-fill" aria-hidden="true" style="color: #0094D7"></i> supports (and <i class="bi bi-x-circle-fill" aria-hidden="true" style="color: #D55F57"></i> does not support):

- Good-old **[sRGB]** color codes (HEX, RGB, etc.) <i class="bi bi-check-circle-fill" aria-hidden="true" style="color: #0094D7"></i>
- **[DCI-P3]** color codes <i class="bi bi-check-circle-fill" aria-hidden="true" style="color: transparent; color: color(display-p3 0.2 0.57 0.82);"></i><i class="bi bi-x-circle-fill" aria-hidden="true" style="color: #D55F57; color: color(display-p3 0 0 0 / .0);"></i>
- **[CIE L\*a\*b](https://en.wikipedia.org/wiki/CIELAB_color_space)** color codes, such as `lab()` and `lch()` in CSS <i class="bi bi-check-circle-fill" aria-hidden="true" style="color: transparent; color: lch(57.02% 48.18 248.06);"></i><i class="bi bi-x-circle-fill" aria-hidden="true" style="color: #D55F57; color: lch(0% 0.0 0deg / .0);"></i>
- **[OkLab](https://en.wikipedia.org/wiki/Oklab)** color codes, such as `oklab()` and `oklch()` in CSS <i class="bi bi-check-circle-fill" aria-hidden="true" style="color: transparent; color: oklch(63% .15 236deg);"></i><i class="bi bi-x-circle-fill" aria-hidden="true" style="color: #D55F57; color: oklch(0% 0.0 0deg / .0);"></i>

But don’t worry if your device, browser, or app doesn’t support them. We've added sRGB-compatible color codes to both our official specification and demo site.

<i class="bi bi-lightbulb-fill" aria-hidden="true" style="color: #ffaa00"></i> **Tip:** Just click on the color to copy the values to your clipboard

<small>
  <p>
    <sup>1</sup>Newer electronic displays, primarily OLED and Apple's Retina Display supports displaying colors beyond the good-old sRGB standard. OkLCH by default supports these advancements in displays (which is known as wider color gamut), and our color palettes are now highly optimized for DCI-P3 and Rec2020 screens instead of regular sRGB.
  </p>
  <p>
    <sup>2</sup>Fallbacks include CIE version of the LCH color space as well as sRGB fallback color values.
  </p>
  <p>
    <sup>3</sup>Some Android devices may have DCI-P3 color gamut enabled by default, and forcing sRGB colors to be converted/extended to DCI-P3 ones. This is is known as “Standard”, “Bright”, “Brilliant”, “Cinematic”, or “Vivid” display mode (see Settings > Display) in devices produced by Oppo, Samsung, vivo, and Xiaomi.
  </p>
</small>

<hr>
<h1 id="galih-ratna">Main Color Palette</h1>

<div id="main-palette"></div>
<hr>

<h1 id="specific-palettes">Specific-Use Color Palettes</h1>
<h2 class="ansi-terminal-palette">ANSI Terminal Color Palette</h2>

ANSI "basic" color palettes MUST be rendered using:

- **Color Scale 60** for colored background colors
- **Color Scale 80 (Dark) or 30 (Light)** for colored foreground colors

<details>
  <summary id="for-halfmoon-v1">
    Halfmoon v1 Color Palette
  </summary>
  <fieldgroup>
    <input type="checkbox" id="halfmoon-v1-variable" value="checked">
    <label>Use CSS variables?</label>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Primary Color:</label>
    <select id="halfmoon-v1-override-primary">
    </select>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Secondary Color:</label>
    <select id="halfmoon-v1-override-secondary">
    </select>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Success Color:</label>
    <select id="halfmoon-v1-override-success">
    </select>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Danger Color:</label>
    <select id="halfmoon-v1-override-danger">
    </select>
  </fieldgroup>
  <button id="halfmoon-v1-generate">Generate!</button>
  <pre><code id="halfmoon-v1-css" /></pre>
</details>

<details>
  <summary id="for-halfmoon-v2">
    Bootstrap / Halfmoon v2 Color Palette
  </summary>
  <fieldgroup>
    <input type="checkbox" id="halfmoon-v2-variable" value="checked">
    <label>Use CSS variables?</label>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Primary Color:</label>
    <select id="halfmoon-v2-override-primary">
    </select>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Info Color:</label>
    <select id="halfmoon-v2-override-info">
    </select>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Success Color:</label>
    <select id="halfmoon-v2-override-success">
    </select>
  </fieldgroup>
  <br />
  <fieldgroup>
    <label>Override Danger Color:</label>
    <select id="halfmoon-v2-override-danger">
    </select>
  </fieldgroup>
  <button id="halfmoon-v2-generate">Generate!</button>
  <pre><code id="halfmoon-v2-css" /></pre>
</details>

<details>
  <summary id="for-tailwind">Tailwind Color Palette</summary>
  <pre><code id="tailwind-json" /></pre>
 </details>

[dci-p3]: https://en.wikipedia.org/wiki/DCI-P3
[rec2020]: https://en.wikipedia.org/wiki/Rec2020
[srgb]: https://en.wikipedia.org/wiki/SRGB

              
            
!

CSS

              
                body {
  font-family: "Segoe UI Variable Text", -apple-system, BlinkMacSystemFont,
    Inter, "Segoe UI", Cantarell, "Open Sans", "Noto Sans", Piboto,
    "HarmonyOS Sans", Ubuntu, "Roboto Flex", Roboto, "Helvetica Neue", FreeSans,
    Arial, sans-serif;
  max-width: 850px;
  margin-bottom: 2rem;
  margin-left: auto;
  margin-right: auto;
  margin-top: 2rem;
  padding-left: 2rem;
  padding-right: 2rem;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: ui-serif, "Aptos Serif", "Constantia", "Publico Text", "Charter",
    "STIX Two Text", "Libertinus Serif", "Linux Libertine O",
    "Linux Libertine G", "Linux Libertine", "DejaVu Serif",
    "Bitstream Vera Serif", "Roboto Serif", "Noto Serif", "Times New Roman",
    serif;
  font-weight: 600;
}

a {
  color: #0094d7;
  color: oklch(63% 0.15 236deg);
}

a:active,
a:hover {
  color: #44ade5;
  color: oklch(71% 0.125 236deg);
}

code,
kbd,
table tr:nth-child(n-3) td {
  font-family: Menlo, "DejaVu Sans Mono", Hack, monospace;
}

table {
  border-spacing: 1px;
}

table th {
  text-align: start;
}

table th,
table td {
  padding: 0.33rem;
}

@media screen and (prefers-color-scheme: dark) {
  html {
    background-color: #000000;
    color: #ffffff;
  }
  a {
    color: #44ade5;
    color: oklch(79% 0.1 236deg);
  }
}

              
            
!

JS

              
                export const colorNames = [
  "red",
  "orange",
  "yellow",
  "lime",
  "green",
  "seafoam",
  "cyan",
  "blue",
  "indigo",
  "violet",
  "purple",
  "fuchsia"
];
export const Grades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
// Dilan-Milea, commonly used for dark mode
export const DMLValues = [95, 87, 79, 71, 63, 55, 47, 39, 31, 23, 15];
export const DMCValues = [0.25, 0.23, 0.21, 0.19, 0.17, 0.15, 0.13, 0.11, 0.09, 0.07, 0.05];
// Galih-Ratna, commonly used for light mode
export const GRLValues = [95, 87, 79, 71, 63, 55, 47, 39, 31, 23, 15];
export const GRCValues = [0.05, 0.07, 0.09, 0.11, 0.13, 0.15, 0.17, 0.19, 0.21, 0.23, 0.25];
// Rangga-Cinta, dark mode UI background
export const RCLValues = [95, 87, 79, 71, 63, 55, 47, 39, 31, 23, 15];
export const RCCValues = [0.05, 0.0525, 0.055, 0.0575, 0.06, 0.0625, 0.06, 0.0575, 0.055, 0.0525, 0.05];
function map2CSS(map) {
  map.map((entry) => `${entry[0]}: ${entry[1]};`);
}

function generateColors(i, j) {
  const h = (26 + i * 30) % 360;
  const dilanMilea = chroma.oklch(DMLValues[j] / 100, DMCValues[j], h);
  const galihRatna = chroma.oklch(GRLValues[j] / 100, GRCValues[j], h);
  const ranggaCinta = chroma.oklch(RCLValues[j] / 100, RCCValues[j], h);
  return [dilanMilea, galihRatna, ranggaCinta];
}

function generateHSL(color) {
  let res = color.hsl();
  return [Math.round(res[0] * 100) / 100, Math.round(res[1] * 10000) / 100 + "%", Math.round(res[2] * 10000) / 100 + "%"].join(", ");
}

function getColors() {
  let res = new Map();
  colorNames.forEach((colorName, i) => {
    res.set(colorName, getColorShades(i));
  });
  return res;
}

function getColorShades(i) {
  let res = new Map();
  for (let j = 0; j < DMCValues.length; j++) {
    res.set(Grades[j], generateColors(i, j));
  }
  return res;
}

function makeTable(tableId) {
  /* Autogenerate hues */
  let table = document.getElementById(tableId);
  getColors().forEach((shades, name) => {
    table.innerHTML += `<h2>${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</h2>`;
    let tempHTML = "";
    tempHTML += "<table>";
    let tableData = [
      ["Dilan Milea"],
      ["L"],
      ["C"],
      ["H"],
      ["hex"],
      ["HEX"],
      ["Galih Ratna"],
      ["L"],
      ["C"],
      ["H"],
      ["hex"],
      ["HEX"],
      ["Rangga Cinta"],
      ["L"],
      ["C"],
      ["H"],
      ["hex"],
      ["HEX"],
    ];
    shades.forEach((colors, shade) => {
      const i = Grades.indexOf(shade);
      const l = [DMLValues[i], GRLValues[i], RCLValues[i]];
      const c = [DMCValues[i], GRCValues[i], RCCValues[i]];
      const h = (26 + colorNames.indexOf(name) * 30) % 360;
      tableData[0].push(shade);
      tableData[1].push(l[0]);
      tableData[2].push(c[0]);
      tableData[3].push(h);
      tableData[4].push(colors[0].hex());
      tableData[5].push(colors[0].hex().toUpperCase());
      tableData[6].push(shade);
      tableData[7].push(l[1]);
      tableData[8].push(c[1]);
      tableData[9].push(h);
      tableData[10].push(colors[1].hex());
      tableData[11].push(colors[1].hex().toUpperCase());
      tableData[12].push(shade);
      tableData[13].push(l[2]);
      tableData[14].push(c[2]);
      tableData[15].push(h);
      tableData[16].push(colors[2].hex());
      tableData[17].push(colors[2].hex().toUpperCase());
    });
    tableData.forEach((rows, i) => {
      // i = rows
      tempHTML += "<tr>";
      rows.forEach((cell, j) => {
        // j = grades
        if (j == 0) {
          tempHTML += `<th style="${
            (Math.floor(i / 6) % 2 == 0)
              ? "background-color: #000; color: #FFF;"
              : "background-color: #FFF; color: #000;"
          }">${cell}</th>`;
        } else {
          const LCHColors = shades.get(tableData[0][j]);
          const k = Math.floor(i / 6);
          const l = tableData[1 + 6 * k][j];
          const c = tableData[2 + 6 * k][j];
          const h = tableData[3 + 6 * k][j];
          if (i % 6 < 4) {
            tempHTML += `<td style="background-color: ${LCHColors[k].toString()}; background-color: oklch(${l}% ${c} ${h}); color: ${
            tableData[1 + 6 * k][j] < 70 ? "#FFF" : "#000"
            }">${cell}</td>`;
          } else {
            // For hex codes
            console.log((Math.floor(i / 6)) % 3);
            tempHTML += `<td style="background-color: ${LCHColors[k].toString({ format: "hex" })}; color: ${
              LCHColors[k].luminance() < 0.4
                ? "#FFF"
                : "#000"
            }">${cell}</td>`;
          }
        }
      });
      tempHTML += "</tr>";
    });
    tempHTML += "</table>";
    table.innerHTML += tempHTML;
  });
}

function makeHalfmoonV1CSS(cssId) {
  const variable = document.getElementById("halfmoon-v1-variable");
  const overridePrimary = document.getElementById(
    "halfmoon-v1-override-primary"
  ), primaryValue = overridePrimary.options[overridePrimary.selectedIndex]?.value;
  const overrideSecondary = document.getElementById(
    "halfmoon-v1-override-secondary"
  ), secondaryValue = overrideSecondary.options[overrideSecondary.selectedIndex]?.value;
  const overrideSuccess = document.getElementById(
    "halfmoon-v1-override-success"
  ), successValue = overrideSuccess.options[overrideSuccess.selectedIndex]?.value;
  const overrideDanger = document.getElementById("halfmoon-v1-override-danger"), dangerValue = overrideDanger.options[overrideDanger.selectedIndex]?.value;
  const css = document.getElementById(cssId);
  css.innerHTML = "";

  overridePrimary.innerHTML = "<option value=\"null\">None</option>";
  overrideSecondary.innerHTML = "<option value=\"null\">None</option>";
  overrideSuccess.innerHTML = "<option value=\"null\">None</option>";
  overrideDanger.innerHTML = "<option value=\"null\">None</option>";
  getColors().forEach((shades, name) => {
    overridePrimary.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
    overrideSecondary.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
    overrideSuccess.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
    overrideDanger.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
  });
  
  css.innerHTML="/* Base Color Palettes */\n:root {\n";
  getColors().forEach((shades, name) => {
    css.innerHTML += `  --${name}-color: ${shades.get(500)[1]};
  --${name}-color-light: ${shades.get(300)[1]};
  --${name}-color-very-light: ${shades.get(50)[1]};
  --${name}-color-dark: ${shades.get(500)[0]};
  --${name}-color-very-dark: ${shades.get(700)[0]};
  --${name}-box-shadow-color: rgba(${chroma.hex(shades.get(300)[1]).alpha(0.3).rgba()});
  --${name}-box-shadow-color-darker: rgba(${chroma.hex(shades.get(300)[1]).alpha(0.6).rgba()});
  --${name}-gradient-foil-light: linear-gradient(-30deg, var(--indigo-color) 0%, var(--indigo-color-light) 66.7%, var(--indigo-color-very-light) 100%);
  --${name}-gradient-foil-dark: linear-gradient(300deg, var(--indigo-color-very-dark) 0%, var(--indigo-color-dark) 33.3%, var(--indigo-color) 100%);
  --text-color-on-${name}-color-bg: #ffffff;\n`;
  });
  css.innerHTML += "}\n\n/* OkLCH Support */\n@supports (color: oklch(0% 0 0 / .5)) {\n  :root {\n";
  colorNames.forEach((name, i) => {
    const h = (26 + i * 30) % 360;
    css.innerHTML += `    --${name}-color: oklch(55% 0.175 ${h});
    --${name}-color-light: oklch(71% 0.125 ${h});
    --${name}-color-very-light: oklch(95% 0.05 ${h});
    --${name}-color-dark: oklch(55% 0.15 ${h});
    --${name}-color-very-dark: oklch(39% 0.11 ${h});
    --${name}-box-shadow-color: oklch(55% 0.175 ${h} / .3);
    --${name}-box-shadow-color-darker: oklch(55% 0.175 ${h} / .6);\n`
  });
  css.innerHTML += "  }\n}";
  if (primaryValue && primaryValue != "null") {
    css.innerHTML += `
    
/* Primary Color Overrides */
:root {
  --primary-color: var(--${primaryValue}-color);
  --primary-color-light: var(--${primaryValue}-color-light);
  --primary-color-very-light: var(--${primaryValue}-color-very-light);
  --primary-color-dark: var(--${primaryValue}-color-dark);
  --primary-color-very-dark: var(--${primaryValue}-color-very-dark);
  --primary-box-shadow-color: var(--${primaryValue}-box-shadow-color);
  --primary-box-shadow-color-darker: var(--${primaryValue}-box-shadow-color-darker);
}`;
  }
  if (secondaryValue && secondaryValue != "null") {
    css.innerHTML += `
    
/* Secondary Color Overrides */
:root {
  --secondary-color: var(--${secondaryValue}-color);
  --secondary-color-light: var(--${secondaryValue}-color-light);
  --secondary-color-very-light: var(--${secondaryValue}-color-very-light);
  --secondary-color-dark: var(--${secondaryValue}-color-dark);
  --secondary-color-very-dark: var(--${secondaryValue}-color-very-dark);
  --secondary-box-shadow-color: var(--${secondaryValue}-box-shadow-color);
  --secondary-box-shadow-color-darker: var(--${secondaryValue}-box-shadow-color-darker);
}`;
  }
  if (successValue && successValue != "null") {
    css.innerHTML += `
    
/* Success Color Overrides */
:root {
  --success-color: var(--${successValue}-color);
  --success-color-light: var(--${successValue}-color-light);
  --success-color-very-light: var(--${successValue}-color-very-light);
  --success-color-dark: var(--${successValue}-color-dark);
  --success-color-very-dark: var(--${successValue}-color-very-dark);
  --success-box-shadow-color: var(--${successValue}-box-shadow-color);
  --success-box-shadow-color-darker: var(--${successValue}-box-shadow-color-darker);
}`;
  }
  if (dangerValue && dangerValue != "null") {
    css.innerHTML += `
    
/* Danger Color Overrides */
:root {
  --danger-color: var(--${dangerValue}-color);
  --danger-color-light: var(--${dangerValue}-color-light);
  --danger-color-very-light: var(--${dangerValue}-color-very-light);
  --danger-color-dark: var(--${dangerValue}-color-dark);
  --danger-color-very-dark: var(--${dangerValue}-color-very-dark);
  --danger-box-shadow-color: var(--${dangerValue}-box-shadow-color);
  --danger-box-shadow-color-darker: var(--${dangerValue}-box-shadow-color-darker);
}`;
  }
}

function makeHalfmoonV2CSS(cssId) {
  const variable = document.getElementById("halfmoon-v2-variable");
  const overridePrimary = document.getElementById(
    "halfmoon-v2-override-primary"
  ), primaryValue = overridePrimary.options[overridePrimary.selectedIndex]?.value;
  const overrideInfo= document.getElementById("halfmoon-v2-override-info"), infoValue = overrideInfo.options[overrideInfo.selectedIndex]?.value;
  const overrideSuccess = document.getElementById(
    "halfmoon-v2-override-success"
  ), successValue = overrideSuccess.options[overrideSuccess.selectedIndex]?.value;
  const overrideDanger = document.getElementById("halfmoon-v2-override-danger"), dangerValue = overrideDanger.options[overrideDanger.selectedIndex]?.value;
  const css = document.getElementById(cssId);
  css.innerHTML = "";

  overridePrimary.innerHTML = "<option value=\"null\">None</option>";
  overrideInfo.innerHTML = "<option value=\"null\">None</option>";
  overrideSuccess.innerHTML = "<option value=\"null\">None</option>";
  overrideDanger.innerHTML = "<option value=\"null\">None</option>";
  getColors().forEach((shades, name) => {
    overridePrimary.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
    overrideInfo.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
    overrideSuccess.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
    overrideDanger.innerHTML += `<option value="${name}">${name.substr(0, 1).toUpperCase()}${name.substr(
      1
    )}</option>`;
  });
  
  css.innerHTML="/* Base Color Palettes */\n\n";
  getColors().forEach((shades, name) => {
    css.innerHTML += `:root, [data-bs-theme=light] {\n  --bs-${name}-hue: ${shades.get(500)[1].hsl()[0]};\n  --bs-${name}-saturation: ${shades.get(500)[1].hsl()[1]};\n`;
    shades.keys().forEach((shade) => {
      css.innerHTML += `  --bs-${name}-${shade}-hsl: ${generateHSL(shades.get(shade)[1])};
  --bs-${name}-${shade}: hsl(var(--bs-${name}-${shade}-hsl));
  --bs-${name}-${shade}: ${shades.get(shade)[1].css("oklch")};\n`;
    });
  css.innerHTML += `  --bs-${name}-hsl: var(--bs-${name}-500-hsl);
  --bs-${name}: hsl(var(--bs-${name}-hsl));
  --bs-${name}-foreground-hsl: var(--bs-white-hsl);
  --bs-${name}-foreground: hsl(var(--bs-${name}-foreground-hsl));
  --bs-${name}-text-emphasis-hsl: var(--bs-${name}-600-hsl);
  --bs-${name}-text-emphasis: hsl(var(--bs-${name}-text-emphasis-hsl));
  --bs-${name}-hover-bg: var(--bs-${name}-600);
  --bs-${name}-active-bg: var(--bs-${name}-700);
  --bs-${name}-bg-subtle: hsl(var(--bs-${name}-hue), var(--bs-${name}-saturation), 70%);
  --bs-${name}-border-subtle: var(--bs-${name}-400);
  --bs-${name}-checkbox-svg: var(--bs-checkbox-svg-light);
  --bs-${name}-dash-svg: var(--bs-dash-svg-light);
  --bs-${name}-radio-svg: var(--bs-radio-svg-light);
  --bs-${name}-switch-svg: var(--bs-switch-svg-light);
}
[data-bs-theme=dark] {
  --bs-${name}-text-emphasis-hsl: var(--bs-${name}-400-hsl);
  --bs-${name}-text-emphasis: hsl(var(--bs-${name}-text-emphasis-hsl));
  --bs-${name}-bg-subtle: hsl(var(--bs-${name}-hue), calc(var(--bs-${name}-saturation)/3), 15%);
  --bs-${name}-border-subtle: var(--bs-${name}-600);
}\n\n`;
});

    
  if (primaryValue && primaryValue != "null") {
    css.innerHTML += `
    
/* Primary Color Overrides */
:root, [data-bs-theme=light] {
  --bs-primary-hue: var(--bs-${primaryValue}-hue);
  --bs-primary-saturation: var(--bs-${primaryValue}-saturation);
  --bs-primary-100-hsl: var(--bs-${primaryValue}-100-hsl);
  --bs-primary-200-hsl: var(--bs-${primaryValue}-200-hsl);
  --bs-primary-300-hsl: var(--bs-${primaryValue}-300-hsl);
  --bs-primary-400-hsl: var(--bs-${primaryValue}-400-hsl);
  --bs-primary-500-hsl: var(--bs-${primaryValue}-500-hsl);
  --bs-primary-600-hsl: var(--bs-${primaryValue}-600-hsl);
  --bs-primary-700-hsl: var(--bs-${primaryValue}-700-hsl);
  --bs-primary-800-hsl: var(--bs-${primaryValue}-800-hsl);
  --bs-primary-900-hsl: var(--bs-${primaryValue}-900-hsl);
  --bs-primary-100: var(--bs-${primaryValue}-100);
  --bs-primary-200: var(--bs-${primaryValue}-200);
  --bs-primary-300: var(--bs-${primaryValue}-300);
  --bs-primary-400: var(--bs-${primaryValue}-400);
  --bs-primary-500: var(--bs-${primaryValue}-500);
  --bs-primary-600: var(--bs-${primaryValue}-600);
  --bs-primary-700: var(--bs-${primaryValue}-700);
  --bs-primary-800: var(--bs-${primaryValue}-800);
  --bs-primary-900: var(--bs-${primaryValue}-900);
  --bs-primary-hsl: var(--bs-${primaryValue}-hsl);
  --bs-primary: var(--bs-${primaryValue});
  --bs-primary-foreground-hsl: var(--bs-${primaryValue}-foreground-hsl);
  --bs-primary-foreground: var(--bs-${primaryValue}-foreground);
  --bs-primary-text-emphasis-hsl: var(--bs-${primaryValue}-text-emphasis-hsl);
  --bs-primary-text-emphasis: var(--bs-${primaryValue}-text-emphasis);
  --bs-primary-hover-bg: var(--bs-${primaryValue}-hover-bg);
  --bs-primary-active-bg: var(--bs-${primaryValue}-active-bg);
  --bs-primary-bg-subtle: var(--bs-${primaryValue}-bg-subtle);
  --bs-primary-border-subtle: var(--bs-${primaryValue}-border-subtle);
  --bs-primary-checkbox-svg: var(--bs-${primaryValue}-checkbox-svg);
  --bs-primary-dash-svg: var(--bs-${primaryValue}-dash-svg);
  --bs-primary-radio-svg: var(--bs-${primaryValue}-radio-svg);
  --bs-primary-switch-svg: var(--bs-${primaryValue}-switch-svg);
}
[data-bs-theme=dark] {
  --bs-primary-text-emphasis-hsl: var(--bs-${primaryValue}-text-emphasis-hsl);
  --bs-primary-text-emphasis: var(--bs-${primaryValue}-text-emphasis);
  --bs-primary-bg-subtle: var(--bs-${primaryValue}-bg-subtle);
  --bs-primary-border-subtle: var(--bs-${primaryValue}-border-subtle);
}`;
  }
  if (infoValue && infoValue != "null") {
    css.innerHTML += `
    
/* Info Color Overrides */
:root, [data-bs-theme=light] {
  --bs-info-hue: var(--bs-${infoValue}-hue);
  --bs-info-saturation: var(--bs-${infoValue}-saturation);
  --bs-info-100-hsl: var(--bs-${infoValue}-100-hsl);
  --bs-info-200-hsl: var(--bs-${infoValue}-200-hsl);
  --bs-info-300-hsl: var(--bs-${infoValue}-300-hsl);
  --bs-info-400-hsl: var(--bs-${infoValue}-400-hsl);
  --bs-info-500-hsl: var(--bs-${infoValue}-500-hsl);
  --bs-info-600-hsl: var(--bs-${infoValue}-600-hsl);
  --bs-info-700-hsl: var(--bs-${infoValue}-700-hsl);
  --bs-info-800-hsl: var(--bs-${infoValue}-800-hsl);
  --bs-info-900-hsl: var(--bs-${infoValue}-900-hsl);
  --bs-info-100: var(--bs-${infoValue}-100);
  --bs-info-200: var(--bs-${infoValue}-200);
  --bs-info-300: var(--bs-${infoValue}-300);
  --bs-info-400: var(--bs-${infoValue}-400);
  --bs-info-500: var(--bs-${infoValue}-500);
  --bs-info-600: var(--bs-${infoValue}-600);
  --bs-info-700: var(--bs-${infoValue}-700);
  --bs-info-800: var(--bs-${infoValue}-800);
  --bs-info-900: var(--bs-${infoValue}-900);
  --bs-info-hsl: var(--bs-${infoValue}-hsl);
  --bs-info: var(--bs-${infoValue});
  --bs-info-foreground-hsl: var(--bs-${infoValue}-foreground-hsl);
  --bs-info-foreground: var(--bs-${infoValue}-foreground);
  --bs-info-text-emphasis-hsl: var(--bs-${infoValue}-text-emphasis-hsl);
  --bs-info-text-emphasis: var(--bs-${infoValue}-text-emphasis);
  --bs-info-hover-bg: var(--bs-${infoValue}-hover-bg);
  --bs-info-active-bg: var(--bs-${infoValue}-active-bg);
  --bs-info-bg-subtle: var(--bs-${infoValue}-bg-subtle);
  --bs-info-border-subtle: var(--bs-${infoValue}-border-subtle);
  --bs-info-checkbox-svg: var(--bs-${infoValue}-checkbox-svg);
  --bs-info-dash-svg: var(--bs-${infoValue}-dash-svg);
  --bs-info-radio-svg: var(--bs-${infoValue}-radio-svg);
  --bs-info-switch-svg: var(--bs-${infoValue}-switch-svg);
}
[data-bs-theme=dark] {
  --bs-info-text-emphasis-hsl: var(--bs-${infoValue}-text-emphasis-hsl);
  --bs-info-text-emphasis: var(--bs-${infoValue}-text-emphasis);
  --bs-info-bg-subtle: var(--bs-${infoValue}-bg-subtle);
  --bs-info-border-subtle: var(--bs-${infoValue}-border-subtle);
}`;
  }
  if (successValue && successValue != "null") {
    css.innerHTML += `
    
/* Success Color Overrides */
:root, [data-bs-theme=light] {
  --bs-success-hue: var(--bs-${successValue}-hue);
  --bs-success-saturation: var(--bs-${successValue}-saturation);
  --bs-success-100-hsl: var(--bs-${successValue}-100-hsl);
  --bs-success-200-hsl: var(--bs-${successValue}-200-hsl);
  --bs-success-300-hsl: var(--bs-${successValue}-300-hsl);
  --bs-success-400-hsl: var(--bs-${successValue}-400-hsl);
  --bs-success-500-hsl: var(--bs-${successValue}-500-hsl);
  --bs-success-600-hsl: var(--bs-${successValue}-600-hsl);
  --bs-success-700-hsl: var(--bs-${successValue}-700-hsl);
  --bs-success-800-hsl: var(--bs-${successValue}-800-hsl);
  --bs-success-900-hsl: var(--bs-${successValue}-900-hsl);
  --bs-success-100: var(--bs-${successValue}-100);
  --bs-success-200: var(--bs-${successValue}-200);
  --bs-success-300: var(--bs-${successValue}-300);
  --bs-success-400: var(--bs-${successValue}-400);
  --bs-success-500: var(--bs-${successValue}-500);
  --bs-success-600: var(--bs-${successValue}-600);
  --bs-success-700: var(--bs-${successValue}-700);
  --bs-success-800: var(--bs-${successValue}-800);
  --bs-success-900: var(--bs-${successValue}-900);
  --bs-success-hsl: var(--bs-${successValue}-hsl);
  --bs-success: var(--bs-${successValue});
  --bs-success-foreground-hsl: var(--bs-${successValue}-foreground-hsl);
  --bs-success-foreground: var(--bs-${successValue}-foreground);
  --bs-success-text-emphasis-hsl: var(--bs-${successValue}-text-emphasis-hsl);
  --bs-success-text-emphasis: var(--bs-${successValue}-text-emphasis);
  --bs-success-hover-bg: var(--bs-${successValue}-hover-bg);
  --bs-success-active-bg: var(--bs-${successValue}-active-bg);
  --bs-success-bg-subtle: var(--bs-${successValue}-bg-subtle);
  --bs-success-border-subtle: var(--bs-${successValue}-border-subtle);
  --bs-success-checkbox-svg: var(--bs-${successValue}-checkbox-svg);
  --bs-success-dash-svg: var(--bs-${successValue}-dash-svg);
  --bs-success-radio-svg: var(--bs-${successValue}-radio-svg);
  --bs-success-switch-svg: var(--bs-${successValue}-switch-svg);
}
[data-bs-theme=dark] {
  --bs-success-text-emphasis-hsl: var(--bs-${successValue}-text-emphasis-hsl);
  --bs-success-text-emphasis: var(--bs-${successValue}-text-emphasis);
  --bs-success-bg-subtle: var(--bs-${successValue}-bg-subtle);
  --bs-success-border-subtle: var(--bs-${successValue}-border-subtle);
}`;
  }
  if (dangerValue && dangerValue != "null") {
    css.innerHTML += `
    
/* Danger Color Overrides */
:root, [data-bs-theme=light] {
  --bs-danger-hue: var(--bs-${dangerValue}-hue);
  --bs-danger-saturation: var(--bs-${dangerValue}-saturation);
  --bs-danger-100-hsl: var(--bs-${dangerValue}-100-hsl);
  --bs-danger-200-hsl: var(--bs-${dangerValue}-200-hsl);
  --bs-danger-300-hsl: var(--bs-${dangerValue}-300-hsl);
  --bs-danger-400-hsl: var(--bs-${dangerValue}-400-hsl);
  --bs-danger-500-hsl: var(--bs-${dangerValue}-500-hsl);
  --bs-danger-600-hsl: var(--bs-${dangerValue}-600-hsl);
  --bs-danger-700-hsl: var(--bs-${dangerValue}-700-hsl);
  --bs-danger-800-hsl: var(--bs-${dangerValue}-800-hsl);
  --bs-danger-900-hsl: var(--bs-${dangerValue}-900-hsl);
  --bs-danger-100: var(--bs-${dangerValue}-100);
  --bs-danger-200: var(--bs-${dangerValue}-200);
  --bs-danger-300: var(--bs-${dangerValue}-300);
  --bs-danger-400: var(--bs-${dangerValue}-400);
  --bs-danger-500: var(--bs-${dangerValue}-500);
  --bs-danger-600: var(--bs-${dangerValue}-600);
  --bs-danger-700: var(--bs-${dangerValue}-700);
  --bs-danger-800: var(--bs-${dangerValue}-800);
  --bs-danger-900: var(--bs-${dangerValue}-900);
  --bs-danger-hsl: var(--bs-${dangerValue}-hsl);
  --bs-danger: var(--bs-${dangerValue});
  --bs-danger-foreground-hsl: var(--bs-${dangerValue}-foreground-hsl);
  --bs-danger-foreground: var(--bs-${dangerValue}-foreground);
  --bs-danger-text-emphasis-hsl: var(--bs-${dangerValue}-text-emphasis-hsl);
  --bs-danger-text-emphasis: var(--bs-${dangerValue}-text-emphasis);
  --bs-danger-hover-bg: var(--bs-${dangerValue}-hover-bg);
  --bs-danger-active-bg: var(--bs-${dangerValue}-active-bg);
  --bs-danger-bg-subtle: var(--bs-${dangerValue}-bg-subtle);
  --bs-danger-border-subtle: var(--bs-${dangerValue}-border-subtle);
  --bs-danger-checkbox-svg: var(--bs-${dangerValue}-checkbox-svg);
  --bs-danger-dash-svg: var(--bs-${dangerValue}-dash-svg);
  --bs-danger-radio-svg: var(--bs-${dangerValue}-radio-svg);
  --bs-danger-switch-svg: var(--bs-${dangerValue}-switch-svg);
}
[data-bs-theme=dark] {
  --bs-danger-text-emphasis-hsl: var(--bs-${dangerValue}-text-emphasis-hsl);
  --bs-danger-text-emphasis: var(--bs-${dangerValue}-text-emphasis);
  --bs-danger-bg-subtle: var(--bs-${dangerValue}-bg-subtle);
  --bs-danger-border-subtle: var(--bs-${dangerValue}-border-subtle);
}`;
  }}

function makeTailwindJson(jsonId) {
  const json = document.getElementById(jsonId);
  let s,
    sa = ["dm", "gr", "rc"];
  let output = {};
  for (s = 0; s < sa.length; s++) {
    getColors().forEach((shades, name) => {
      name = `${sa[s]}-${name.toLowerCase()}`;
      output[name] = {};
      shades.forEach((colors, shade) => {
        output[name][shade] = colors[s].hex();
      });
    });
  }
  json.innerHTML = JSON.stringify(output, null, 4);
}

window.onload = function () {
  makeTable("main-palette");
  makeHalfmoonV1CSS("halfmoon-v1-css");
  makeHalfmoonV2CSS("halfmoon-v2-css");
  makeTailwindJson("tailwind-json");
  
  document.getElementById("halfmoon-v1-generate").addEventListener("click", () => {
    makeHalfmoonV1CSS("halfmoon-v1-css");
  });
  document.getElementById("halfmoon-v2-generate").addEventListener("click", () => {
    makeHalfmoonV2CSS("halfmoon-v2-css");
  });
};

              
            
!
999px

Console