<div id="root"></div>
	
:root {
  --highlight: #ffa500;
}

.light-theme {
  --primary: #02475e;
  --secondary: #194350;
  --primaryBackground: #f9f3f3;
  --secondaryBackground: #d8e3e7;
  --primaryBorder: #000;
  --secondaryBorder: #333;
}
.dark-theme {
  --primary: #f9f3f3;
  --secondary: #dddddd;
  --primaryBackground: #151515;
  --secondaryBackground: #301b3f;
  --primaryBorder: #3c415c;
  --secondaryBorder: #b4a5a5;
}

#app {
  color: var(--primary);
  background-color: var(--primaryBackground);
  width: 100%;
  height: 100%;
  position: absolute;
  font-family: 'Zen Dots', cursive;
}

.header {
  text-align: center;
  font-size: 1.5em;
  margin: 10px 0px 20px 0px;
}

.card {
  color: var(--secondary);
  background-color: var(--secondaryBackground);
  border: 1px solid var(--secondaryBorder);
  width: 300px;
  height: 300px;
  margin: auto;
  padding: 5px;
  border-radius: 5px;
  text-align: center;
  .title {
    font-size: 2em;
    margin-bottom: 10px;
  }
}

.toggle-theme {
  position: absolute;
  right: 10px;
  top: 5px;
  border: 1px solid var(--secondaryBorder);
  border-radius: 5px;
  background-color: var(--secondaryBackground);
}

.icon {
  display: inline-block;
  padding: 2px 4px;
  cursor: pointer;
  border-radius: 0px 5px 5px 0px;
  &.selected {
    background-color: var(--highlight);
  }
  &:nth-child(1) {
    border-radius: 5px 0px 0px 5px;
    border-right: 1px solid var(--secondaryBorder);
  }
  svg {
    width: 24px;
    height: 24px;
  }
}

.beacon svg {
  width:64px;
  height: 64px;
}

.choice span {
  font-size: 1.2em;
  font-weight: 600;
}
View Compiled
const LIGHT_THEME = "light-theme";
const DARK_THEME = "dark-theme";

const ThemeContext = React.createContext();

function ThemeWrapper({ children }) {
  const [theme, setTheme] = React.useState(LIGHT_THEME);

  const applyTheme = (newTheme) => {
    console.log("apply", newTheme);
    document.getElementById("app").className = newTheme;
    setTheme(newTheme);
  };

  return (
    <ThemeContext.Provider value={{ theme, applyTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

function Card() {
  const { theme } = React.useContext(ThemeContext);
  return (
    <div className="card">
      <Beacon />
      <div className="title">Choose your side</div>
      <div className="choice">
        {["You chose the ", <span>{theme.split("-")[0]}</span>, " side"]}
      </div>
    </div>
  );
}

function App() {
  return (
    <div id="app" className="light-theme">
      <div className="header"> Theme Sandbox </div>
      <ThemeWrapper>
        <div>
          <ToggleTheme />
          <Card />
        </div>
      </ThemeWrapper>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

function ToggleTheme() {
  return (
    <div class="toggle-theme">
      <LightTheme />
      <DarkTheme />
    </div>
  );
}

// rest of js is mostly svg definitions
// svg icons are from https://www.iconfinder.com/iconsets/star-wars-color

function DarkTheme() {
  const { theme, applyTheme } = React.useContext(ThemeContext);

  return (
    <div
      className={`icon ${theme === DARK_THEME ? "selected" : ""}`}
      onClick={() => applyTheme(DARK_THEME)}
    >
      <svg
        height="195px"
        version="1.1"
        viewBox="0 0 216 195"
        width="216px"
        xmlns="http://www.w3.org/2000/svg"
        xmlnsSketch="http://www.bohemiancoding.com/sketch/ns"
        xmlnsXlink="http://www.w3.org/1999/xlink"
      >
        <title />
        <desc />
        <defs />
        <g
          fill="none"
          fillRule="evenodd"
          id="Page-1"
          stroke="none"
          strokeWidth="1"
        >
          <g
            id="star-wars-copy"
            transform="translate(-252.000000, -1251.000000)"
          >
            <g id="darth-vader" transform="translate(252.000000, 1251.000000)">
              <path
                d="M204,177 C205.944,175.494 210.702,174.024 212.496,172.428 L180,95.25 C180,95.25 151.146,9 115.548,9 L100.452,9 C64.854,9 36,95.25 36,95.25 L3.504,172.428 C5.298,174.024 10.056,175.494 12,177 L204,177 Z"
                fill="#323232"
                id="Fill-1"
              />
              <path
                d="M48,117 L72,159 L102,117 L48,117 Z"
                fill="#505050"
                id="Fill-3"
              />
              <path
                d="M144,159 L168,117 L114,117 L144,159 Z"
                fill="#505050"
                id="Fill-5"
              />
              <path
                d="M54,103.5 C54,99.378 56.22,93.342 58.932,90.096 C58.932,90.096 66.534,81 82.002,81 C89.844,81 95.316,84.378 95.316,84.378 C98.994,86.646 102,91.878 102,96 L102,107.25 C102,109.314 98.4,111 94.002,111 L61.998,111 C57.6,111 54,107.622 54,103.5"
                fill="#000000"
                id="Fill-7"
              />
              <path
                d="M154.0002,111 L122.0022,111 C117.5982,111 113.9982,109.314 113.9982,107.25 L113.9982,96 C113.9982,91.872 117.0102,86.646 120.6822,84.378 C120.6822,84.378 126.1542,81 134.0022,81 C149.4642,81 157.0662,90.096 157.0662,90.096 C159.7782,93.342 161.9982,99.378 161.9982,103.5 C161.9982,107.628 158.3982,111 154.0002,111"
                fill="#000000"
                id="Fill-9"
              />
              <path
                d="M180,81 L180,67.452 C180,32.598 152.322,4.284 117.756,3.114 C116.106,1.218 113.706,0 111,0 L105,0 C102.294,0 99.894,1.218 98.244,3.114 C63.678,4.284 36,32.598 36,67.452 L36,81 L0,177 L12,177 L43.668,99.906 C51.798,79.59 63.06,70.926 81.342,70.926 C93.84,70.926 101.574,80.688 102,81 L114,81 C114.426,80.688 122.16,70.926 134.658,70.926 C152.94,70.926 164.202,79.59 172.32,99.876 L204,177 L216,177 L180,81 Z"
                fill="#000000"
                id="Fill-11"
              />
              <path
                d="M53.919,63 C52.371,63 51.111,61.746 51.111,60.192 C51.111,36.99 69.987,18.114 93.195,18.114 C94.743,18.114 95.997,19.368 95.997,20.922 C95.997,22.47 94.743,23.724 93.195,23.724 C73.083,23.724 56.727,40.086 56.727,60.192 C56.727,61.746 55.467,63 53.919,63"
                fill="#1A1A1A"
                id="Fill-13"
              />
              <path
                d="M108,117 C104.688,117 102,119.682 102,123 L102,129 L114,129 L114,123 C114,119.682 111.312,117 108,117 M153,177 C149.688,177 147,179.688 147,183 C147,186.312 149.688,189 153,189 C156.312,189 159,186.312 159,183 C159,179.688 156.312,177 153,177 M63,177 C59.688,177 57,179.688 57,183 C57,186.312 59.688,189 63,189 C66.312,189 69,186.312 69,183 C69,179.688 66.312,177 63,177"
                fill="#FFFFFF"
                id="Fill-15"
              />
              <path
                d="M158.745,172.5306 L167.997,117.0006 L143.997,159.0006 L119.997,125.4006 L119.997,123.0006 C119.997,116.3826 114.621,111.0006 107.997,111.0006 C101.379,111.0006 95.997,116.3826 95.997,123.0006 L95.997,125.4006 L71.997,159.0006 L47.997,117.0006 L57.255,172.5306 C53.547,174.5766 50.997,178.4766 50.997,183.0006 C50.997,189.6186 56.379,195.0006 62.997,195.0006 C67.425,195.0006 71.247,192.5706 73.329,189.0006 L142.671,189.0006 C144.747,192.5706 148.575,195.0006 152.997,195.0006 C159.621,195.0006 164.997,189.6186 164.997,183.0006 C164.997,178.4766 162.453,174.5766 158.745,172.5306"
                fill="#000000"
                id="Fill-17"
              />
              <path
                d="M84,177 L96,177 L96,145.458 L84,161.916 L84,177 Z"
                fill="#323232"
                id="Fill-20"
              />
              <path
                d="M120,145.4574 L120,176.9994 L132,176.9994 L132,161.9154 L120,145.4574 Z"
                fill="#323232"
                id="Fill-22"
              />
              <path
                d="M102,177 L114,177 L114,141 L102,141 L102,177 Z"
                fill="#323232"
                id="Fill-24"
              />
              <path
                d="M108,117 C104.688,117 102,119.682 102,123 L102,129 L114,129 L114,123 C114,119.682 111.312,117 108,117 M153,177 C149.688,177 147,179.688 147,183 C147,186.312 149.688,189 153,189 C156.312,189 159,186.312 159,183 C159,179.688 156.312,177 153,177 M63,177 C59.688,177 57,179.688 57,183 C57,186.312 59.688,189 63,189 C66.312,189 69,186.312 69,183 C69,179.688 66.312,177 63,177"
                fill="#FFFFFF"
                id="Fill-26"
              />
            </g>
          </g>
        </g>
      </svg>{" "}
    </div>
  );
}

function LightTheme() {
  const { theme, applyTheme } = React.useContext(ThemeContext);

  return (
    <div
      className={`icon ${theme === LIGHT_THEME ? "selected" : ""}`}
      onClick={() => applyTheme(LIGHT_THEME)}
    >
      <svg
        height="204px"
        version="1.1"
        viewBox="0 0 216 204"
        width="216px"
        xmlns="http://www.w3.org/2000/svg"
        xmlnsSketch="http://www.bohemiancoding.com/sketch/ns"
        xmlnsXlink="http://www.w3.org/1999/xlink"
      >
        <title />
        <desc />
        <defs>
          <path d="M0,0 L216,0 L216,204 L0,204" id="path-1" />
        </defs>
        <g
          fill="none"
          fillRule="evenodd"
          id="Page-1"
          stroke="none"
          strokeWidth="1"
        >
          <g
            id="star-wars-copy"
            transform="translate(-985.000000, -865.000000)"
          >
            <g id="obiwan-kenobi" transform="translate(985.000000, 865.000000)">
              <path
                d="M48,204 L168,204 L168,126 L48,126 L48,204 Z"
                fill="#503C1D"
                id="Fill-1"
              />
              <path
                d="M108,18 C74.862,18 48,41.346 48,70.14 L48,156 L90,186 L126,186 L168,156 L168,70.14 C168,41.346 141.138,18 108,18"
                fill="#F0B496"
                id="Fill-2"
              />
              <path
                d="M48,120 L48,120 C41.4,120 36,114.6 36,108 L36,90 C36,83.4 41.4,78 48,78 L48,78 C54.6,78 60,83.4 60,90 L60,108 C60,114.6 54.6,120 48,120"
                fill="#F0B496"
                id="Fill-4"
              />
              <path
                d="M168,120 L168,120 C161.4,120 156,114.6 156,108 L156,90 C156,83.4 161.4,78 168,78 L168,78 C174.6,78 180,83.4 180,90 L180,108 C180,114.6 174.6,120 168,120"
                fill="#F0B496"
                id="Fill-6"
              />
              <path
                d="M84,89.706 C80.682,89.706 78,92.388 78,95.706 C78,99.024 80.682,101.706 84,101.706 C87.318,101.706 90,99.024 90,95.706 C90,92.388 87.318,89.706 84,89.706"
                fill="#323232"
                id="Fill-8"
              />
              <path
                d="M132,89.706 C128.682,89.706 126,92.388 126,95.706 C126,99.024 128.682,101.706 132,101.706 C135.318,101.706 138,99.024 138,95.706 C138,92.388 135.318,89.706 132,89.706"
                fill="#323232"
                id="Fill-10"
              />
              <path
                d="M101.9994,117 L101.9994,92.712 C101.9994,91.056 103.3434,89.712 104.9994,89.712 L104.9994,89.712 C106.6554,89.712 107.9994,91.056 107.9994,92.712 L107.9994,117 C107.9994,118.656 106.6554,120 104.9994,120 L104.9994,120 C103.3434,120 101.9994,118.656 101.9994,117"
                fill="#E99977"
                id="Fill-12"
              />
              <path
                d="M132,168 L84,168 L90,138 L126,138 L132,168 Z M168,66 L156,156 L150,156 L132,132 L84,132 L66,156 L60,156 L48,66 L42.828,148.71 C42.312,156.978 46.098,164.928 52.836,169.74 L77.742,187.53 C81.81,190.44 86.688,192 91.692,192 L124.308,192 C129.312,192 134.19,190.44 138.258,187.53 L163.164,169.74 C169.902,164.928 173.688,156.978 173.172,148.71 L168,66 Z"
                fill="#ECECEC"
                id="Fill-14"
              />
              <g id="Group-18">
                <mask fill="white" id="mask-2">
                  <use xlinkHref="#path-1" />
                </mask>
                <g id="Clip-17" />
                <path
                  d="M6.4536,204 L68.9736,204 C48.3936,173.922 49.4616,120.222 49.4616,119.61 C49.4616,86.58 75.6696,59.802 107.9976,59.802 C140.3316,59.802 166.5396,86.58 166.5396,119.61 C166.5396,120.222 167.6016,173.922 147.0276,204 L209.5476,204 C215.0916,204 217.9536,197.274 214.4976,192.702 C183.2616,151.398 186.0516,82.308 186.0516,82.308 C186.0516,38.544 149.4996,0 107.9976,0 C66.5016,0 29.9436,38.544 29.9436,82.308 C29.9436,82.308 32.7336,151.398 1.5036,192.702 C-1.9524,197.274 0.9096,204 6.4536,204"
                  fill="#8C5A3C"
                  id="Fill-16"
                  mask="url(#mask-2)"
                />
              </g>
            </g>
          </g>
        </g>
      </svg>
    </div>
  );
}

function Beacon() {
  return (
    <div className="beacon">
      <svg
        height="121px"
        version="1.1"
        viewBox="0 0 157 121"
        width="157px"
        xmlns="http://www.w3.org/2000/svg"
        xmlnsSketch="http://www.bohemiancoding.com/sketch/ns"
        xmlnsXlink="http://www.w3.org/1999/xlink"
      >
        <title />
        <desc />
        <defs />
        <g
          fill="none"
          fillRule="evenodd"
          id="Page-1"
          stroke="none"
          strokeWidth="1"
        >
          <g
            id="star-wars-copy"
            transform="translate(-283.000000, -907.000000)"
          >
            <g id="r2d2" transform="translate(283.000000, 907.000000)">
              <path
                d="M74.7078,0.5888 C32.7558,2.5628 0.4758,38.7008 0.4758,80.7008 L0.4758,108.4988 C0.4758,115.1288 5.8518,120.4988 12.4758,120.4988 L144.4758,120.4988 C151.1058,120.4988 156.4758,115.1288 156.4758,108.4988 L156.4758,78.4988 C156.4758,34.1708 119.4978,-1.5232 74.7078,0.5888"
                fill="#BEBEBE"
                id="Fill-259"
              />
              <path
                d="M81.4782,0.656 L81.4782,24.5 L134.6802,24.5 C121.1382,10.406 102.3642,1.454 81.4782,0.656"
                fill="#2980B9"
                id="Fill-260"
              />
              <path
                d="M75.4782,0.656 C54.5922,1.454 35.8182,10.406 22.2762,24.5 L75.4782,24.5 L75.4782,0.656 Z"
                fill="#2980B9"
                id="Fill-261"
              />
              <path
                d="M107.5602,72.5 L73.3962,72.5 C69.7422,72.5 66.9402,69.266 67.4562,65.654 L71.7402,35.654 C72.1662,32.696 74.6982,30.5 77.6802,30.5 L103.2762,30.5 C106.2582,30.5 108.7902,32.696 109.2162,35.654 L113.5002,65.654 C114.0162,69.266 111.2142,72.5 107.5602,72.5"
                fill="#2980B9"
                id="Fill-262"
              />
              <path
                d="M105.4782,51.5 C105.4782,59.786 98.7642,66.5 90.4782,66.5 C82.1922,66.5 75.4782,59.786 75.4782,51.5 C75.4782,43.214 82.1922,36.5 90.4782,36.5 C98.7642,36.5 105.4782,43.214 105.4782,51.5"
                fill="#323232"
                id="Fill-263"
              />
              <path
                d="M93.4782,48.5 C93.4782,51.812 90.7902,54.5 87.4782,54.5 C84.1662,54.5 81.4782,51.812 81.4782,48.5 C81.4782,45.188 84.1662,42.5 87.4782,42.5 C90.7902,42.5 93.4782,45.188 93.4782,48.5"
                fill="#FFFFFF"
                id="Fill-264"
              />
              <path
                d="M42.48,84.5 L60.48,84.5 L60.48,72.5 L42.48,72.5 L42.48,84.5 Z"
                fill="#505050"
                id="Fill-265"
              />
              <path
                d="M42.48,96.5 L60.48,96.5 L60.48,84.5 L42.48,84.5 L42.48,96.5 Z"
                fill="#505050"
                id="Fill-266"
              />
              <path
                d="M114.48,96.5 L84.48,96.5 L84.48,78.5 L114.48,78.5 L114.48,96.5 Z"
                fill="#2980B9"
                id="Fill-267"
              />
              <path
                d="M78.48,96.5 L66.48,96.5 L66.48,78.5 L78.48,78.5 L78.48,96.5 Z"
                fill="#2980B9"
                id="Fill-268"
              />
              <path
                d="M0.4782,108.5 C0.4782,110.048 0.7962,111.518 1.3302,112.874 L155.6262,112.874 C156.1602,111.518 156.4782,110.048 156.4782,108.5 L156.4782,103.124 L0.4782,103.124 L0.4782,108.5 Z"
                fill="#2980B9"
                id="Fill-269"
              />
              <path
                d="M36.4782,72.5 L0.9102,72.5 C0.6342,75.206 0.4782,77.936 0.4782,80.702 L0.4782,96.5 L36.4782,96.5 L36.4782,72.5 Z"
                fill="#2980B9"
                id="Fill-270"
              />
              <path
                d="M150.4782,72.5 L150.4782,96.5 L156.4782,96.5 L156.4782,78.5 C156.4782,76.472 156.3162,74.486 156.1662,72.5 L150.4782,72.5 Z"
                fill="#2980B9"
                id="Fill-271"
              />
              <path
                d="M144.4782,84.5 C144.4782,91.13 139.1082,96.5 132.4782,96.5 C125.8482,96.5 120.4782,91.13 120.4782,84.5 C120.4782,77.87 125.8482,72.5 132.4782,72.5 C139.1082,72.5 144.4782,77.87 144.4782,84.5"
                fill="#8C8C8C"
                id="Fill-272"
              />
              <path
                d="M139.9782,84.5 C139.9782,88.64 136.6182,92 132.4782,92 C128.3382,92 124.9782,88.64 124.9782,84.5 C124.9782,80.36 128.3382,77 132.4782,77 C136.6182,77 139.9782,80.36 139.9782,84.5"
                fill="#FFFFFF"
                id="Fill-273"
              />
              <path
                d="M108.4782,87.5 C108.4782,90.812 105.7902,93.5 102.4782,93.5 C99.1662,93.5 96.4782,90.812 96.4782,87.5 C96.4782,84.188 99.1662,81.5 102.4782,81.5 C105.7902,81.5 108.4782,84.188 108.4782,87.5"
                fill="#C0392B"
                id="Fill-274"
              />
              <path
                d="M15.42,63.5 C15.138,63.5 14.85,63.458 14.562,63.374 C12.978,62.9 12.072,61.232 12.546,59.642 C15.282,50.468 19.764,42.044 25.866,34.598 C26.922,33.314 28.818,33.134 30.09,34.178 C31.368,35.234 31.554,37.124 30.51,38.402 C24.906,45.23 20.796,52.952 18.294,61.358 C17.904,62.66 16.716,63.5 15.42,63.5"
                fill="#E6E6E6"
                id="Fill-275"
                opacity="0.571012127"
              />
            </g>
          </g>
        </g>
      </svg>
    </div>
  );
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js