Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ 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

Save Automatically?

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

              
                <div id="app">
        <pages-nav></pages-nav>
       
        <div id='main-page' data-title='Color wheel'>
            <div id='demo-wrapper'>
                <h1>Demo </h1>
                <div class='demo-container' :data-hide-text="(hide_text == true) ? 'on' : 'off'">
                    <demo></demo>
                </div>
            </div>
            <div id='color-wheel-container'>
                <color-wheel></color-wheel>

                <div class='switch-mode'>
                    <color-theory-wheel :mode='selectedPickerMode' :static='true' wheel-style="white"
                        @click.native='modeSpinner()'> </color-theory-wheel>
                    <span class='mode-text'>{{(isCustom) ? "Custom" : pickerModeTitle}}</span>
                </div>
                <colors-display></colors-display>
            </div>
        </div>
        <div id='color-theory-page' data-title='Color theory'>

            <div class='inner-container'>
                <div class='title'>
                    <h1>Color Theory</h1>
                </div>
                <div class='mixing'>
                    <h4>Mixing Colors</h4>
                    <div class='mixing-wrapper'>
                        <div class='additive-wrapper'>

                            <div class='additive-mixing color-mixing'>
                                <span class='cyan'></span>
                                <span class='yellow'></span>
                                <span class='magenta'></span>
                            </div>
                            <h5>CMYK</h5>
                            <h6>Additive</h6>
                        </div>
                        <div class='subtractive-wrapper'>
                            <div class='subtractive-mixing color-mixing'>
                                <span class='red'></span>
                                <span class='blue'></span>
                                <span class='green'></span>
                            </div>
                            <h5>RGB</h5>
                            <h6>Subtractive</h6>
                        </div>
                    </div>
                </div>
                <div class='relationships'>
                    <h4>Relationships</h4>
                    <div class='color-relations-wrapper'>
                        <color-theory-wheel @click.native='wheel_mode = "primary"' mode='primary' title='Primary Colors'
                            :static='true'>
                        </color-theory-wheel>
                        <color-theory-wheel @click.native='wheel_mode = "secondary"' mode='secondary'
                            title='Secondary Colors' :static='true'>
                        </color-theory-wheel>
                        <color-theory-wheel @click.native='wheel_mode = "tertiary"' mode='tertiary'
                            title='Tertiary Colors' :static='true'>
                        </color-theory-wheel>
                        <color-theory-wheel @click.native='wheel_mode = "temperature"' mode='temperature'
                            title='Temperature' :static='true'>
                        </color-theory-wheel>
                    </div>
                </div>
                <div class='modes'>
                    <h4>Modes</h4>
                    <div class='color-modes-wrapper'>
                        <color-theory-wheel @click.native='wheel_mode = m.name' :title='m.title' :mode='m.name'
                            :static='true' v-for='m in modes'></color-theory-wheel>
                    </div>
                </div>
                <div class='wheel'>
                    <color-theory-wheel :static="isStatic" :mode='wheel_mode' title='' :static='true'
                        data-labels='on'>
                    </color-theory-wheel>
                </div>
            </div>
        </div>

        <div id='about-page' data-title='About'>
            <about></about>
        </div>
    </div>



    <template id='color-wheel-template'>
        <div id='color-wheel-wrapper'>
            <div id='color-wheel-lightness' :style='lightnessStyle' draggable="false">
                <div id='lightness-picker' draggable="false" :style='lightnessRotation'></div>
            </div>

            <div id='color-wheel' draggable="false" :data-moving='(pointerMoving) ? "yes" : "no"'>
                <pointer v-for='(p, i) in pointerCount' :key="'pointer-'+i"
                    :class='{selected: selectedPointerIndex == i}' :index='i' :color-wheel='color_wheel'></pointer>
            </div>
        </div>
    </template>

    <template id='pointer-template'>
        <div class='pointer' draggable="false" :data-index='index'
            :style="{left: left, top: top, background: background}" :class="{enlarge: enlarge == true}"></div>
    </template>

    <template id='colors-display-template'>
        <div id='colors-display'>
            <div class='colors-containers'>
                <div v-for='(c, i) in colors' class='color-container' :class="{selected:  selectedPointerIndex == i }">

                    <div class='color-bg' :class='{entered: entered == i}' :style="getBackground(i)" draggable="true"
                        @dragstart="dragstart(i, $event)" @dragend="dragend" @dragenter="dragenter(i)">
                        <i class="fas fa-grip-horizontal"></i>
                        <div class='color-grads'>
                            <div v-for='(g, i) in c.palette' :style="{'background-color': g}"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class='color-variations'>
                <span class='arrow' :style='arrowStyle'></span>
                <span class='title' @click='colorModelSpinner'>{{currentModel.name}} <i class="fas fa-sort"></i></span>
                <span class='color-value' id='color-value-to-copy'>{{currentModel.value}}</span>
                <span class='copy-value' data-clipboard-target="#color-value-to-copy" :data-copy-result='copy_message'
                    @mouseout="copy_message = ''" :data-message='(copy_message != "") ? "on" : "off"'>
                    <i class="far fa-copy"></i>
                </span>
            </div>
        </div>
    </template>

    <template id='color-theory-wheel-template'>
        <div class='color-theory-wheel' :data-mode='mode' :data-style='wheelStyle'>
            <div class='colors-wrapper'>
                <div class='colors-sections-wrapper'>
                    <div class='color-section' v-for='(c, i) in count' @mouseover='processHover(i)'
                        :class="{hover: highlightIndices.indexOf(i) > -1}"></div>
                </div>

                <div class='color-borders-wrapper'>
                    <div class='color-border' v-for='b in 6'></div>
                </div>
            </div>
            <div class='color-theory-wheel-title'>{{title}}</div>
        </div>
    </template>


    <template id='pages-nav-template'>
        <nav id='pages-nav'>
            <div class='page-dots'>
                <div class='page-dot' v-for='(d, i) in pages' @mouseover='dotHover(i, $event)' @click='current_page = i'
                    :class="{active: current_page == i}"></div>
            </div>
            <div class='page-title' :style="{top: title_position +'px'}">{{pageTitle}}</div>
        </nav>

    </template>

    <template id='about-template'>
        <div id='about-container'>
            <div class='color-wheel-title'>
                <div id='logo'>
                    <div class='beak'>
                        <span></span>
                    </div>
                    <div class='body'>
                    </div>
                    <div class='eye'></div>
                </div>
                <div class='title'>Toucan Palatte Generator</div>

            </div>
            <div class='info-wrapper'>
                <div class='about-container'>
                    <h4>About</h4>
                    <div class='about-wrapper'>
                        <p v-for='i in info'>{{i}}</p>
                    </div>
                </div>
                <div class='shortcuts-container'>
                    <h4>Shortcuts</h4>
                    <div class='shortcuts-wrapper'>
                        <div class='shortcut-row' v-for='s in shortcuts'>
                            <div class='shortcut-combination'>
                                <template v-for='(k, i) in s.keys'>
                                    <kbd class='shortcut-key'
                                        v-if='k.indexOf("mouse") == -1 && k != "+" && k != "/"'>{{k}}</kbd>
                                    <span class='shortcut-plus' v-if='k == "+"'>+</span>
                                    <span class='shortcut-plus' v-if='k == "/"'>/</span>
                                    <span class='shortcut-mouse' :class='k' v-if='k.indexOf("mouse") > -1'>
                                        <i></i>
                                    </span>
                                </template>
                            </div>
                            <div class='shortcut-desc'>{{s.desc}}</div>
                        </div>
                    </div>
                </div>
                <div class='made-with-container'>
                    <h4>Made with</h4>
                    <div class='made-with-wrapper'>
                        <a :href="l.link" target='_blank' v-for='l in made_with'>{{l.title}}</a>
                    </div>
                </div>
            </div>
        </div>

    </template>


    <template id='demo-template'>
        <div class="d-flex" id="demo" :style='getNewStyle()' :data-darkmode="(settings.darkmode) ? 'on' : 'off'" :data-hide-text="(settings.hide_text) ? 'on' : 'off'">
            <!-- Sidebar -->
            <div class="border-right d-flex flex-column" id="sidebar-wrapper">
                <div class="sidebar-heading">Dashboard </div>
                <div class="list-group list-group-flush d-flex flex-column flex-grow-1">
                    <a href="#" class="list-group-item list-group-item-action d-flex align-items-center">
                        <i class="fas fa-home"></i><span>Home</span></a>
                    <a href="#" class="list-group-item list-group-item-action d-flex align-items-center">
                        <i class="fas fa-globe"></i>
                        <span>Overview</span></a>
                    <a href="#" class="list-group-item list-group-item-action d-flex align-items-center">
                        <i class="far fa-money-bill-alt"></i>
                        <span>Sales</span>
                        <span class="badge badge-primary badge-pill ml-auto">14</a>
                    <a href="#" class="list-group-item list-group-item-action d-flex align-items-center">
                        <i class="fas fa-user-circle"></i>
                        <span>Profile</span>
                    </a>
                    <a href="#" class="list-group-item list-group-item-action d-flex align-items-center">
                        <i class="fas fa-thermometer-quarter"></i>
                        <span>Status</span>
                        <span class="badge badge-success badge-pill ml-auto">2</span>
                    </a>
                    <a href="#" class="list-group-item list-group-item-action d-flex align-items-center">
                        <i class="fas fa-table"></i>
                        <span>Tabels</span></a>
                    <hr class='my3'>
                    <a href="#" class="list-group-item list-group-item-action d-flex align-items-center mt-auto">
                        <i class="fas fa-level-up-alt"></i>
                        <span>Upgrade</span>
                    </a>
                </div>


            </div>
            <!-- /#sidebar-wrapper -->

            <!-- Page Content -->
            <div id="page-content-wrapper">
                <nav class="navbar navbar-expand-lg navbar-light" id='top-navbar'>
                    <form class="form-inline  mr-auto">
                        <input class="form-control mr-sm-2" type="search" placeholder="Search">
                    </form>


                    <ul class="navbar-nav">
                        <li class="nav-item mx-2">
                            <a class="nav-link" href="#">
                                <i class="far fa-bell"></i>
                            </a>
                        </li>
                        <li class="nav-item mx-2">
                            <a class="nav-link" href="#"><i class="fas fa-th-large"></i></a>
                        </li>
                        <li class="nav-item mx-2">
                            <a class="nav-link" href="#"><i class="fas fa-user"></i></a>
                        </li>
                    </ul>

                </nav>

                <div class="header bg-primary pb-6">
                    <div class="container-fluid">
                        <div class="header-body">
                            <!-- Card stats -->
                            <div class="row">
                                <div class="col-xl-4 col-md-6" v-for='card in admin_cards'>
                                    <div class="card card-stats mb-4">
                                        <!-- Card body -->
                                        <div class="card-body">
                                            <div class="row">
                                                <div class="col">
                                                    <h5 class="card-title text-uppercase text-mute mb-0">{{card.title}}
                                                    </h5>
                                                    <div class="h2 font-weight-bold mb-0 mt-1">{{card.number}}</div>
                                                </div>
                                                <div class="col-auto">
                                                    <div class="icon icon-shape bg-gradient-red rounded-circle">
                                                        <i :class="card.icon_class"></i>
                                                    </div>
                                                </div>
                                            </div>
                                            <p class="mt-3 mb-0 text-sm">
                                                <span class="string-success mr-2"><i class="fa fa-arrow-up"></i>
                                                    {{card.percentage}}%</span>
                                                <span class="text-nowrap">Since last month</span>
                                            </p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <!-- /header -->
                <div class="container-fluid">
                    <div class="row mb-4" id='graphs'>
                        <div class="col-xl-8">
                            <div class="card bg-default shadow-sm border-0">
                                <div class="card-header bg-transparent">
                                    <div class="row align-items-center">
                                        <div class="col">
                                            <h6 class="text-light text-uppercase ls-1 mb-1">Overview</h6>
                                            <h3 class="text-white mb-0">Visitors / Sale</h3>
                                        </div>
                                        <div class="col">
                                            <ul class="nav nav-pills justify-content-end">
                                                <li class="nav-item mr-2 mr-md-0" data-toggle="chart">
                                                    <a href="#" class="btn btn-primary btn-sm py-1 px-3"
                                                        data-toggle="tab" @click.stop.prevent='updateData("traffic")'
                                                        :class="{active: line_chart.source == 'traffic'}">
                                                        <span class="d-none d-md-block">Visitors</span>
                                                        <span class="d-md-none">V</span>
                                                    </a>
                                                </li>
                                                <li class="nav-item" data-toggle="chart">
                                                    <a href="#" class="btn btn-primary btn-sm py-1 px-3 mx-2"
                                                        data-toggle="tab" @click.stop.prevent="updateData('sales')"
                                                        :class="{active: line_chart.source == 'sales'}">
                                                        <span class="d-none d-md-block">Sales</span>
                                                        <span class="d-md-none">S</span>
                                                    </a>
                                                </li>
                                            </ul>
                                        </div>
                                    </div>
                                </div>

                                <div class="card-body">

                                    <!-- Chart -->
                                    <div class="chart">
                                        <div class="chartjs-size-monitor">
                                            <div class="chartjs-size-monitor-expand">
                                                <div class=""></div>
                                            </div>
                                            <div class="chartjs-size-monitor-shrink">
                                                <div class=""></div>
                                            </div>
                                        </div>

                                        <chart :datasets='linechartDataset' :labels="line_chart.labels"
                                            :options="line_chart.options"></chart>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="col-xl-4" id='dashboard-settings'>
                            <div class="card shadow-sm border-0">
                                <div class="card-header bg-transparent">
                                    <div class="row align-items-center">
                                        <div class="col">
                                            <h3 class="mb-0">Settings</h3>
                                        </div>
                                    </div>
                                </div>
                                <div class="card-body">
                                    <div class='settings-row'>
                                        <label class="switch">
                                            <input type="checkbox" v-model='settings.darkmode'>
                                            <span class='switch-toggle'></span>
                                            <span class="text">Darkmode</span>
                                        </label>
                                    </div>
                                    <div class='settings-row'>
                                        <label class="switch">
                                            <input type="checkbox" v-model='settings.default_sidebar_bg'>
                                            <span class='switch-toggle'></span>
                                            <span class="text">Default Sidebar Background</span>
                                        </label>
                                    </div>
                                     <div class='settings-row hide-text'>
                                        <label class="switch">
                                            <input type="checkbox" v-model='settings.hide_text'>
                                            <span class='switch-toggle'></span>
                                            <span class="text">Hide Text</span>
                                        </label>
                                    </div>
                                </div>
                            </div>
                        </div>

                    </div>
                    <!-- /#graphs -->


                    <div class="row" id='stats'>
                        <div class="col-xl-7">
                            <div class="card border-0 shadow">
                                <div class="card-header border-0 bg-white">
                                    <div class="row align-items-center">
                                        <div class="col">
                                            <h3 class="mb-0 text-uppercase">Page visits</h3>
                                        </div>
                                        <div class="col text-right">
                                            <a href="#!" class="btn btn-sm btn-primary shadow-sm">See all</a>
                                        </div>
                                    </div>
                                </div>
                                <div class="table-responsive">
                                    <!-- Projects table -->
                                    <table class="table align-items-center table-flush">
                                        <thead class="thead-light">
                                            <tr>
                                                <th class='border-bottom-0' scope="col">Page name</th>
                                                <th class='border-bottom-0' scope="col">Visitors</th>
                                                <th class='border-bottom-0' scope="col">Unique users</th>
                                                <th class='border-bottom-0' scope="col">Bounce rate</th>
                                            </tr>
                                        </thead>
                                        <tbody>

                                            <tr v-for='row in page_visits'>
                                                <th scope="row"> {{row.name}} </th>
                                                <td> {{row.visitors}} </td>
                                                <td> {{row.unique}} </td>
                                                <td>
                                                    <i class="fas fa-arrow-up text-success mr-3"
                                                        v-if='row.direction == "up"'></i>
                                                    <i class="fas fa-arrow-down text-warning mr-3"
                                                        v-if='row.direction == "down"'></i>
                                                    {{row.rate}}
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                        <div class="col-xl-5 social-ref">
                            <div class="card border-0 shadow">
                                <div class="card-header border-0 bg-white">
                                    <div class="row align-items-center">
                                        <div class="col">
                                            <h3 class="mb-0 text-uppercase">Social traffic</h3>
                                        </div>
                                        <div class="col text-right">
                                            <a href="#!" class="btn btn-sm btn-primary shadow-sm">See all</a>
                                        </div>
                                    </div>
                                </div>
                                <div class="table-responsive">
                                    <!-- Projects table -->
                                    <table class="table align-items-center table-flush">
                                        <thead class="thead-light">
                                            <tr>
                                                <th class='border-bottom-0' scope="col">Referral</th>
                                                <th class='border-bottom-0' scope="col">Visitors</th>
                                                <th class='border-bottom-0' scope="col"></th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <tr v-for='row in social_ref'>
                                                <th scope="row">
                                                    {{row.name}}
                                                </th>
                                                <td>
                                                    {{row.visitors}}
                                                </td>
                                                <td>
                                                    <div class="d-flex align-items-center">

                                                        <div class="progress">
                                                            <div class="progress-bar" role="progressbar"
                                                                :style="{width: row.percentage + '%'}"
                                                                :aria-valuenow="row.percentage" aria-valuemin="0"
                                                                aria-valuemax="100">{{row.percentage}}%
                                                            </div>

                                                        </div>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                    <!-- /#stats -->
                </div>

                <footer class="footer pt-0">
                    <div class="row align-items-center justify-content-lg-between">
                        <div class="col-lg-6">
                            <div class="copyright text-center  text-lg-left  text-muted">
                                © 2021 <a href="#" class="font-weight-bold ml-1" target="_blank">Color wheel</a>
                            </div>
                        </div>
                        <div class="col-lg-6">
                            <ul class="nav nav-footer justify-content-center justify-content-lg-end">
                                <li class="nav-item">
                                    <a href="#" class="nav-link" target="_blank">About Us</a>
                                </li>
                                <li class="nav-item">
                                    <a href="#" class="nav-link" target="_blank">Blog</a>
                                </li>
                                <li class="nav-item">
                                    <a href="#" class="nav-link" target="_blank">MIT License</a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </footer>
            </div>
            <!-- /#page-content-wrapper -->

        </div>
    </template>
   
              
            
!

CSS

              
                @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Open+Sans&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Skranji:wght@400;700&display=swap");

:root {
  --bg-color: #ecf0f1;
  --dark-accent: rgba(180, 180, 180, 0.2);
  --darker-accent: lightgray;
  --light-accent: rgba(180, 180, 180, 0.5);
  --light-color: white;
  --dark-color: black;

  --site-main-color: #21749a;
  --scrollbar-foreground: #b3cde0;
  --scrolbar-background: rgba(255, 255, 255, 0);
}

:root {
  --demo-bg-color: white;
  --demo-sidebar-bg: white;
  --demo-sidebar-hover: #{rgba(gray, 0.1)};
  --demo-sidebar-hover-color: black;

  --demo-primary-bg: #5e72e4;
  --demo-primary-color: white;
  --demo-sidebar-text-color: black;

  --demo-btn-border: #465cda;
  --demo-btn-bg: #{lighten(#5e72e4, 5%)};
  --demo-btn-color: black;
  --demo-btn-active-color: #fff;
  --demo-btn-active: #{lighten(#5e72e4, 10%)};
  --demo-btn-active-border: #{darken(#5e72e4, 10%)};

  --demo-header-card: white;
  --demo-header-card-text: #8898aa;

  --demo-text-success: #28a745;

  --demo-scrollbar-foreground: #b3cde0;
  --demo-scrolbar-background: rgba(255, 255, 255, 0);
}

body {
  background-color: var(--bg-color);
}

@mixin scrollbars(
  $size: 4px,
  $foreground-color: var(--scrollbar-foreground),
  $background-color: var(--scrollbar-background)
) {
  // For Google Chrome
  &::-webkit-scrollbar {
    width: $size;
    height: $size;
  }

  &::-webkit-scrollbar-thumb {
    background: $foreground-color;
    border-radius: 0.3rem;
  }

  &::-webkit-scrollbar-track {
    background: $background-color;
  }

  // For Internet Explorer
  & {
    scrollbar-face-color: $foreground-color;
    scrollbar-track-color: $background-color;
    // firefox
    scrollbar-width: thin;
    scrollbar-color: $foreground-color $background-color;
  }
}

@mixin ribbon($size: 0.4em) {
  padding-bottom: 0.6em;
  background-color: #21749a;
  padding: 0.4em 2.3em;
  font-size: 1.3rem;
  color: white;
  width: 70%;
  margin-left: -0.5em;
  margin-bottom: 1.2em;
  margin-top: 0.6em;
  position: relative;
  white-space: nowrap;
}

#app {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: 100%;
  overflow: auto;
  box-sizing: border-box;
  font-family: "Open Sans", sans-serif;
  user-select: none;
  overflow: hidden;

  > div {
    height: inherit;
    width: inherit;
    border-bottom: 1px solid;
    box-sizing: border-box;
    overflow: auto;
    position: relative;
    background: url("https://www.toptal.com/designers/subtlepatterns/patterns/frenchstucco.png");
  }

  #pages-nav {
    position: fixed;
    left: 0;
    // border: 1px solid;
    top: 50%;
    z-index: 10;
    transform: translateY(-50%);
    margin-left: 0.4rem;

    .page-dots:hover + .page-title {
      opacity: 1;
    }

    .page-dot {
      width: 0.5rem;
      height: 0.5rem;
      background-color: purple;
      border-radius: 50%;
      margin-bottom: 0.5rem;
      cursor: pointer;
      transition: all 0.3s;
      opacity: 0.8;

      &:hover {
        opacity: 1;
      }

      &.active {
        height: 1rem;
        border-radius: 0.2rem;
      }
    }

    .page-title {
      position: absolute;
      top: 0;
      left: 1rem;
      border-radius: 0.3em;
      padding: 0.2em 1em;
      background-color: purple;
      color: white;
      transform: translateY(-50%);
      font-size: 0.7rem;
      pointer-events: none;
      transition: all 0.3s;
      white-space: nowrap;
      opacity: 0;
    }
  }

  #main-page {
    #color-wheel-container {
      position: absolute;
      top: 50%;
      right: 3%;
      transform: translateY(-50%);
      border-radius: 0.3rem;
      background-color: white;
      //background-color: rgba(180, 180, 180, 0.2);
      padding: 2rem;
      box-shadow: 0 0 1em 0 rgba(0, 0, 0, 0.3);

      .color-theory-wheel {
        margin: 0;
        width: auto;
        left: initial;
        top: initial;

        .colors-wrapper {
          height: 2rem;
          width: 2rem;
          border-radius: 50%;
        }
      }

      .switch-mode {
        padding: 0.2em 0.5em 0.2em 1em;
        border-radius: 0.2em;
        margin: 1em 0;
        display: flex;
        font-size: 1rem;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        position: absolute;
        top: 1%;
        right: 2%;

        &:hover {
          .mode-text {
            opacity: 1;
            bottom: 115%;
          }
        }

        .mode-text {
          font-size: 0.6rem;
          position: absolute;
          bottom: 95%;
          padding: 0.2rem 0.5rem;
          background-color: lightgray;
          border-radius: 0.2rem;
          white-space: nowrap;
          pointer-events: none;
          transition: all 0.3s;
          opacity: 0;

          &::before {
            top: 100%;
            left: 50%;
            height: 0.5rem;
            width: 0.5rem;
            background-color: lightgray;
            transform: translate(-50%, -70%) rotate(45deg);
            content: "";
            position: absolute;
          }
        }
      }
    }

    #colors-display {
      display: flex;
      flex-direction: column;
      margin-top: 2rem;

      .colors-containers {
        display: flex;

        > div {
          flex-grow: 1;
          min-width: 20%;
          height: 2em;
          position: relative;

          .color-bg {
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: flex-end;

            color: rgba(black, 0.5);

            transition: opacity 0.3s;
            box-sizing: border-box;

            &.entered {
              border: 0.1em dashed gray;
              opacity: 0.5;
            }

            &:hover i {
              opacity: 1;
            }

            i {
              opacity: 0;
              transition: all 0.3s;
              position: absolute;
              bottom: 100%;
              left: 50%;
              transform: translate(-50%, -10%);
              cursor: grab;
            }

            .color-grads {
              display: flex;
              height: 30%;
              width: 100%;

              div {
                display: block;
                width: 25%;
                height: 100%;
              }
            }
          }
        }
      }

      .color-variations {
        display: flex;

        font-size: 0.7rem;
        margin-top: 2em;

        background-color: var(--dark-accent);
        border-radius: 0.3em;
        position: relative;
        color: var(--dark-color);

        .arrow {
          position: absolute;
          bottom: 100%;
          left: 50%;
          transform: translateX(-50%);
          height: 0;
          width: 0;
          border-bottom: solid 0.6rem var(--dark-accent);
          border-left: solid 0.6rem transparent;
          border-right: solid 0.6rem transparent;
        }

        .title {
          width: 25%;
          display: block;
          padding: 1em;
          text-transform: uppercase;
          cursor: pointer;
        }

        .color-value {
          padding: 1em 0;
          user-select: all;
        }

        .copy-value {
          display: flex;
          justify-content: center;
          align-items: center;
          font-size: 1.1em;
          margin-left: auto;
          cursor: pointer;
          transition: all 0.3s;
          padding: 1em;
          background-color: var(--dark-accent);
          position: relative;

          &:hover {
            background-color: var(--light-accent);
          }

          &[data-message="on"] {
            &::after,
            &::before {
              opacity: 1;
            }
          }

          &::after {
            content: attr(data-copy-result);
            padding: 0.5em 1em;
            white-space: nowrap;
            position: absolute;
            top: 120%;
            left: 50%;
            transform: translatex(-50%);
            background-color: var(--darker-accent);

            pointer-events: none;
            border-radius: 0.3em;
            font-size: 0.7rem;
            opacity: 0;
          }

          &::before {
            content: "";
            position: absolute;
            top: 115%;
            left: 50%;
            transform: translatex(-50%) rotate(45deg);
            background-color: var(--darker-accent);

            pointer-events: none;
            height: 1em;
            width: 1em;
            opacity: 0;
          }
        }
      }
    }
  }

  #color-theory-page {
    display: flex;
    justify-content: center;
    align-items: center;

    flex-direction: column;

    h1 {
      text-transform: uppercase;
      font-weight: bold;
      margin: 1.6em 0;
      font-family: "Skranji", cursive;
      line-height: 0;
    }

    .inner-container {
      max-width: 1200px;
      display: grid;
      grid-template-columns: 0.7fr 1.3fr;
      grid-template-areas:
        "title title"
        "mixing wheel"
        "relationships wheel "
        "modes wheel";
      grid-row-gap: 1em;

      h4 {
        @include ribbon;
        margin-bottom: 0.6em;
      }

      > div:not(.wheel):not(.title) {
        font-size: 0.4em;

        .color-theory-wheel {
          cursor: pointer;
        }
      }

      .title {
        grid-area: title;
        font-size: 1.5em;
        font-weight: bold;
        text-align: center;
        text-transform: uppercase;
      }

      .mixing {
        grid-area: mixing;
        background-color: white;
        border-radius: 0.3em;
        box-shadow: 0 0 0.6em 0 rgba(180, 180, 180, 0.8);

        .mixing-wrapper {
          justify-content: space-around;

          > div {
            justify-content: center;
            display: flex;
            flex-direction: column;
            align-items: center;
          }

          h5 {
            font-weight: bold;
            margin: 0;
          }

          h6 {
            font-size: 1.6em;
            margin: 0;
          }
        }
      }

      .relationships {
        grid-area: relationships;
        background-color: white;
        border-radius: 0.3em;
        box-shadow: 0 0 0.6em 0 rgba(180, 180, 180, 0.8);
      }

      .modes {
        grid-area: modes;
        background-color: white;
        border-radius: 0.3em;
        box-shadow: 0 0 0.6em 0 rgba(180, 180, 180, 0.8);
      }

      .terms {
        grid-area: terms;
      }

      .meaning {
        grid-area: meaning;
      }

      .wheel {
        grid-area: wheel;
        font-size: 3em;

        display: flex;
        flex-direction: column;
      }

      .mixing-wrapper,
      .color-modes-wrapper,
      .color-relations-wrapper {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
      }

      .color-mixing {
        height: 12em;
        width: 12em;
        position: relative;
        isolation: isolate;

        span {
          border-radius: 50%;
          height: inherit;
          width: inherit;
          display: block;
          position: absolute;
          left: 50%;
          top: 50%;
          width: 50%;
          height: 50%;

          transform: translate(-50%, -50%);
          mix-blend-mode: screen;
        }

        &.subtractive-mixing span {
          &.green {
            background-color: lime;
            transform: translate(-20%, -30%);
          }

          &.red {
            background-color: red;
            transform: translate(-50%, -70%);
          }

          &.blue {
            background-color: blue;
            transform: translate(-80%, -30%);
          }
        }

        &.additive-mixing span {
          mix-blend-mode: multiply;

          &.cyan {
            background-color: cyan;
            transform: translate(-20%, -30%);
          }

          &.magenta {
            background-color: magenta;
            transform: translate(-50%, -70%);
          }

          &.yellow {
            background-color: yellow;
            transform: translate(-80%, -30%);
          }
        }
      }
    }
  }

  #about-page {
    #about-container {
      margin: 0 auto;
      padding: 0 2em;
      max-width: 1350px;
    }

    .color-wheel-title {
      display: flex;
      justify-content: center;
      padding: 2rem;
      margin: 3rem 0;

      .title {
        font-size: 2.6rem;
        font-weight: bold;
        font-family: "Skranji", cursive;
      }
    }

    .info-wrapper {
      $shortcut-color: #888888;

      display: flex;
      justify-content: space-around;

      > div {
        font-size: 0.8em;
        line-height: 2;
        text-align: justify;
        background-color: white;
        box-shadow: 0 0 0.3em 0 rgba(128, 128, 128, 0.45098039215686275);
        border-radius: 0.3em;

        h4 {
          @include ribbon;
        }

        > div {
          padding: 0 3em;
        }
      }

      .shortcuts-container {
        width: 45%;
        font-size: 0.9em;

        .shortcut-row {
          margin-bottom: 1em;
          display: flex;

          .shortcut-combination {
            width: 35%;
            display: flex;
            align-items: center;
            margin-right: 1em;
            justify-content: flex-start;

            .shortcut-key {
              color: $shortcut-color;

              box-shadow: 0.05em 0.05em 0 rgba(0, 0, 0, 0.2);
              border: 1px solid #ccc;
              margin: 0 0.1em;
              padding: 0.1em 0.5em;
              border-radius: 0.25em;
              background: #f3f3f3;
              min-height: 2em;
              min-width: 2em;
              display: flex;
              justify-content: center;
              align-items: center;
            }
          }

          .shortcut-desc {
            font-size: 0.8em;
          }
        }

        .shortcut-plus {
          color: $shortcut-color;
          margin: 0 0.4em;
        }

        .shortcut-mouse {
          height: 0.5rem;
          width: 0.5rem;
          border-radius: 50%;
          background: darken(#d2d2d2, 5%);
          position: relative;

          &::after,
          &:before {
            position: absolute;
            bottom: 105%;
            left: 50%;
            transform: translateX(-50%) rotate(45deg);
            border: 0.1em solid transparent;
            border-left: 0.1em solid $shortcut-color;
            border-top: 0.1em solid $shortcut-color;
            height: 0.35em;
            width: 0.35em;
          }

          &::after {
            top: 105%;
            transform: translateX(-50%) rotate(225deg);
          }

          &.mouse-wheel-up {
            &::before {
              content: "";
            }
          }

          &.mouse-wheel {
            &::after,
            &::before {
              content: "";
            }
          }

          &.mouse-click-left {
            height: 1.5em;
            width: 0.8em;
            border-radius: 0.3em;
            overflow: hidden;

            &::before {
              content: "";
              top: 0;
              transform: unset;
              left: 0;
              border: 0;
              background-color: $shortcut-color;
              border-radius: 0 0 0.2em 0;
            }
          }
        }
      }

      .made-with-container {
        width: 20%;

        a {
          display: block;
          font-size: 1.1em;
          color: rgba(0, 0, 0, 0.7);
          margin-bottom: 1em;
          text-decoration: none;
          padding: 0.3em;
          position: relative;
          transition: all 0.3s;

          &::before {
            position: absolute;
            top: 100%;
            width: 0;
            transition: all 0.5s ease-in-out;
            content: "";
            height: 0.3em;
            background-color: rgba(180, 180, 180, 0.2);
          }

          &:hover {
            color: black;

            &::before {
              width: 100%;
            }
          }
        }
      }

      .about-container {
        width: 25%;
      }
    }

    #logo {
      height: 7em;
      width: 7em;
      position: relative;
      font-size: 0.4em;
      $dark: #000923;
      margin: 0 3em;

      .beak {
        height: 30%;
        width: 60%;
        position: absolute;
        right: 0;
        border-radius: 50% 51% 100% 0% / 0% 100% 0% 0%;
        background-color: #fa9c21;
        background-image: radial-gradient(circle at 80% 80%, #ed3027, #fa9c21);
        overflow: hidden;

        span {
          position: absolute;
          bottom: 0;
          right: 0;
          border-radius: 50%;
          background-color: $dark;
          height: 2em;
          width: 2em;
          transform: translate(50%, 50%);
        }
      }

      .body {
        height: 100%;
        width: 40%;
        position: absolute;
        left: 0;
        top: 0;
        border-radius: 100% 0% 100% 0% / 40% 60% 50% 60%;

        background-image: linear-gradient($dark, lighten($dark, 10%));
      }

      .eye {
        border-radius: 2em 0 0 2em;
        background-color: #525252;
        position: absolute;
        top: 0%;
        right: 60%;
        height: 30%;
        width: 20%;
      }
    }
  }
}

#color-wheel-wrapper {
  height: 15rem;
  width: 15rem;
  position: relative;

  #color-wheel-lightness {
    --selected-color: gray;

    position: absolute;
    bottom: 0;
    height: 100%;
    width: 100%;
    background-color: green;
    z-index: 0;
    border-radius: 50%;
    box-shadow: 0 0 1em 0.1em rgba(180, 180, 180, 0.5);

    #lightness-picker {
      height: 100%;
      width: 100%;

      &::before {
        content: "";
        position: absolute;
        bottom: 100%;
        left: 50%;
        transform: translateX(-50%);
        height: 0;
        width: 0;

        border-top: solid 0.5rem black;
        border-left: solid 0.5rem transparent;
        border-right: solid 0.5rem transparent;
      }
    }
  }

  #color-wheel {
    border-radius: 50%;
    height: calc(98% - 0.5em);
    width: calc(98% - 0.5em);
    position: absolute;
    left: calc(1% + 0.25em);
    top: calc(1% + 0.25em);
    z-index: 1;
    box-sizing: border-box;
    box-shadow: 0 0 0 0.1em white;
    overflow: hidden;

    --level: 50%;
    background-image: linear-gradient(red, transparent var(--level)),
      linear-gradient(240deg, yellow, transparent var(--level)),
      linear-gradient(-60deg, green, transparent var(--level)),
      linear-gradient(0deg, cyan, transparent var(--level)),
      linear-gradient(60deg, blue, transparent var(--level)),
      linear-gradient(120deg, magenta, transparent var(--level)),
      radial-gradient(gray, white 70%);

    &[data-moving="yes"] {
      cursor: none !important;

      .pointer {
        cursor: none !important;

        &.selected {
          height: 8%;
          width: 8%;
        }
      }
    }

    .pointer {
      border-radius: 50%;
      height: 3%;
      width: 3%;
      position: absolute;
      left: 50%;
      top: 50%;
      box-shadow: inset 0 0 5px 5px white;
      cursor: pointer;
      z-index: 0;
      transition: width 0.2s, height 0.2s;
      transform: translate(-50%, -50%);

      &.selected {
        box-shadow: inset 0 0 0 3px white, 0 0 0px 2px rgba(black, 0.5);
        z-index: 1;
        height: 6%;
        width: 6%;
      }

      &.enlarge {
        width: 15%;
        height: 15%;
        box-shadow: inset 0 0 0 1px rgba(white, 0.5),
          0 0 0px 1px rgba(black, 0.1);
      }
    }
  }
}

.color-theory-wheel {
  left: 10%;
  top: 10%;
  margin: 2em;
  width: 10em;

  .color-theory-wheel-title {
    color: gray;
    font-size: 1.3em;
    text-align: center;
  }

  .colors-wrapper {
    height: 10em;
    width: 10em;
    border-radius: 50%;
    background-color: white;
    position: relative;
    border: 1px solid gray;

    &::before {
      background-color: white;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      content: "";
      height: 15%;
      width: 15%;
      border-radius: 50%;
      z-index: 5;
    }
  }

  .color-borders-wrapper {
    width: 98%;
    height: 98%;
    position: relative;
    position: absolute;
    top: 1%;
    left: 1%;
    overflow: hidden;
    border-radius: 50%;
    pointer-events: none;

    .color-border {
      position: absolute;
      height: 110%;
      width: 0.05em;
      background-color: white;
      top: 50%;
      left: 50%;
      z-index: 3;
      transform: rotate(15deg);

      @for $i from 1 through 6 {
        &:nth-child(#{$i}) {
          $rotate: $i * 30deg + 15;
          transform: translate(-50%, -50%) rotate($rotate);
        }
      }
    }
  }

  &[data-mode="mono"] .color-section.hover::after {
    content: "";
    position: absolute;
    top: 0%;
    left: 50%;
    transform: translateX(-50%);
    background-image: repeating-radial-gradient(
      circle at 50% 50%,
      rgba(white, 0.5) 0 35%,
      rgba(white, 0.3) 30% 53%,
      transparent 50% 100%
    );
    height: 200%;
    width: 373%;
    border-radius: 50%;
  }

  &[data-style="white"] {
    .colors-wrapper {
      background-color: white;
      position: relative;
      border: 0;
      box-shadow: 0 0 0.5rem 0 rgba(gray, 0.6);
    }

    .color-section {
      &:not(.hover) {
        background-color: #eee !important;

        &::before {
          content: unset;
        }
      }

      &.hover {
        background-color: lightgray !important;
      }
    }

    .colors-wrapper::before {
      content: unset;
    }
  }

  &[data-mode="temperature"] .color-border:nth-child(5) {
    width: 0.3em;
    z-index: 5;

    &::after {
      content: "";
      height: 100%;
      width: 54%;
      border-right: 0.05em dashed gray;
      position: absolute;
      left: 0;
      top: 0;
      box-sizing: border-box;
    }
  }

  &[data-labels="on"] .color-section.hover::after {
    opacity: 1;
  }

  .colors-sections-wrapper {
    width: 98%;
    height: 98%;
    position: relative;
    position: absolute;
    top: 1%;
    left: 1%;
    overflow: hidden;
    border-radius: 50%;

    .color-section {
      height: 50%;
      width: 27%;
      position: absolute;
      left: 50%;
      bottom: 50%;
      transform-origin: bottom center;
      transition: background-color 0.3s;
      overflow: hidden;
      box-sizing: border-box;
      clip-path: polygon(50% 100%, 0 0, 100% 0);

      &::before {
        position: absolute;
        top: 0;
        left: 0;
        height: 100%;
        width: 100%;
        content: "";
        transition: all 0.3s;
        background-image: linear-gradient(
          0deg,
          rgba(lightgray, 0.3),
          rgba(90, 90, 90, 0.2)
        );
      }

      &::after {
        position: absolute;
        top: 0;
        padding: 1em;
        border-radius: 0.3em;
        left: 50%;
        transform: translateX(-50%) rotate(90deg);
        height: 50%;
        font-size: 1rem;
        display: flex;
        justify-content: center;
        align-items: center;
        white-space: pre;
        color: white;
        text-shadow: 0 0 0.2em gray;
        text-transform: capitalize;
        opacity: 0;
        transition: all 0.3s;
      }

      $colors: 0 22 33 49 59 81 117 181 245 266 293 314;
      $light: 50 50 50 50 50 50 41 33 42 50 43 48;
      $names: (
        "red",
        "red-orange",
        "orange",
        "yellow-orange",
        "yellow",
        "yellow-green",
        "green",
        "blue-green",
        "blue",
        "blue-violet",
        "violet",
        "red-violet"
      );

      @for $i from 0 through 11 {
        &:nth-child(#{$i + 1}) {
          $rotate: $i * 30deg;
          $hue: nth($colors, $i + 1);
          $lightness: nth($light, $i + 1);

          transform: translateX(-50%) rotate($rotate);
          background-color: hsla($hue, 100%, 50%, 0.2);

          &.hover {
            background-color: hsla($hue, 100%, $lightness, 1);
          }

          &::after {
            content: nth($names, $i + 1);

            @if ($i < 6) {
              transform: translateX(-50%) rotate(270deg);
            }
          }
        }
      }
    }
  }
}

#demo-wrapper {
  height: 90vh;
  width: 75vw;
  left: 5vw;
  top: 5vh;
  position: relative;
  background-color: white;
  border-radius: 0.2em;
  max-width: 1200px;
  display: flex;
  flex-direction: column;
  box-shadow: 0 0 0.9em 0 rgba(180, 180, 180, 0.6);

  .demo-container {
    padding: 2em;
    overflow: auto;
  }

  h1 {
    display: flex;
    align-items: center;
    @include ribbon();
  }
}

#demo {
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  position: relative;
  overflow: hidden;
  border: 1px solid lightgray;
  border-radius: 0.3em;
  background-color: var(--demo-bg-color);
  color: var(--demo-text-color);

  &[data-hide-text="on"] {
    text-indent: -2000px;

    .settings-row.hide-text {
      text-indent: initial;
    }
  }

  &[data-darkmode="on"] {
    --demo-bg-color: #282b34;
    --demo-sidebar-bg: #282b34;
    --demo-sidebar-hover: #{rgba(white, 0.1)};
    --demo-sidebar-hover-color: white;
    --demo-text-color: white;
    --demo-sidebar-text-color: white;

    --demo-card-bg: #1e1e1e;

    .container-fluid {
      .card {
        background-color: var(--demo-card-bg);
        box-shadow: 0 0.125rem 0.25rem rgba(lightgray, 0.1);
      }

      .bg-white {
        background-color: var(--demo-card-bg) !important;
      }

      thead th {
        background-color: var(--demo-card-bg) !important;
      }
    }

    .table th,
    .table td,
    .border-right {
      border-color: rgba(white, 0.2) !important;
    }
  }

  .bg-primary {
    background-color: var(--demo-primary-bg) !important;
  }

  .btn-primary,
  .progress-bar {
    background-color: var(--demo-btn-bg);
    color: var(--demo-btn-color);
  }

  .btn-primary {
    border-color: var(--demo-btn-border);

    &:focus {
      box-shadow: unset !important;
    }

    &.active {
      background-color: var(--demo-btn-active);
      border-color: var(--demo-btn-active-border);
      color: var(--demo-btn-active-color);
    }
  }

  #dashboard-settings {
    .settings-row {
      font-size: 0.8rem;

      .switch {
        display: flex;
        align-items: center;
        cursor: pointer;

        .switch-toggle {
          border-radius: 1rem;
          width: 1.5rem;
          height: 0.8rem;
          background-color: #b0bec5;
          transition: all 0.3s;
          position: relative;
          margin-right: 0.4em;

          &::before {
            width: 0.4rem;
            height: 0.4rem;
            position: absolute;
            left: 0.2rem;
            top: 0.2rem;
            content: "";
            border-radius: 50%;
            background-color: rgba(white, 0.5);
            transition: all 0.3s;
          }
        }

        input[type="checkbox"] {
          display: none;

          &:checked + .switch-toggle {
            background-color: #1976d2;

            &::before {
              left: 100%;
              transform: translateX(calc(-100% - 0.2rem));
              background-color: rgba(white, 0.5);
            }
          }
        }
      }
    }
  }

  #sidebar-wrapper {
    margin-left: -15rem;
    transition: margin 0.25s ease-out;
    background-color: white;
    padding: 0em;
    background-color: var(--demo-sidebar-bg);
    color: var(--demo-sidebar-text-color);

    .sidebar-heading {
      padding: 0;
      font-size: 1.2rem;
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 2em 0;
    }

    .list-group {
      width: 14em;
      font-size: 0.9rem;
      padding: 0.5em;

      .list-group-item {
        padding: 0.7em 1em 0.7em 0.2em;
        background-color: transparent;
        color: var(--demo-sidebar-text-color);
      }

      > a {
        border: 0;
        border-radius: 0.3rem;
        transition: background-color 0.3s;
        font-weight: normal;

        &:hover {
          background-color: var(--demo-sidebar-hover);
          color: var(--demo-sidebar-hover-color);
        }

        i {
          width: 2.5em;
          text-align: center;
          font-size: 1rem;
          margin-right: 0.5rem;
        }
      }
    }
  }

  #page-content-wrapper {
    min-width: 100vw;

    overflow: auto;
    @include scrollbars(
      4px,
      var(--demo-scrollbar-foreground),
      var(--demo-scrollbar-background)
    );

    #top-navbar {
      padding: 1.3em 2em;
      background-color: var(--demo-primary-bg) !important;

      input[type="search"] {
        border-radius: 0.6em;
        outline: 0;
        transition: all 0.3s;
        border: 0;
        background-color: rgba(white, 0.6);

        &:focus {
          width: 20em;
          background-color: white;
        }
      }

      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .nav-link {
      color: var(--demo-primary-color);
    }

    .string-success {
      color: var(--demo-text-success);
    }

    .container-fluid {
      padding: 2em 2em 8em 2em;

      .header-body {
        .card {
          border-radius: 0.375rem;
          background-color: var(--demo-header-card);
          border: 0;
          color: var(--demo-header-card-text-1);

          .text-mute {
            color: var(--demo-header-card-text-2);
          }

          .card-title,
          p {
            font-size: 0.8rem;
          }

          .h2 {
            font-size: 1.5rem;
          }

          .icon {
            height: 3rem;
            width: 3rem;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2em;
            background-color: rgba(gray, 0.1);
          }
        }
      }

      h6 {
        font-size: 0.7rem;
      }

      h3 {
        font-size: 1rem !important;
      }

      h5 {
        font-size: 0.7rem !important;
      }

      .btn-sm {
        font-size: 0.75rem;
      }

      .text-mute {
        color: #8898aa;
      }

      .bg-default {
        background-color: #172b4d !important;
      }

      #graphs {
        margin-top: -7em;
      }

      #stats {
        font-size: 0.8rem;

        thead th {
          color: #8898aa;
          background-color: #f6f9fc;
          font-weight: normal;
          text-transform: uppercase;
          font-size: 0.8em;
        }

        .progress {
          width: 100%;
          font-size: 0.7em;
        }

        .social-ref td:last-child {
          width: 50%;
        }
      }
    }

    footer {
      padding: 2em;
      font-size: 0.8rem;

      a {
        color: inherit;
      }
    }
  }
}

@media (min-width: 768px) {
  #demo {
    #sidebar-wrapper {
      margin-left: 0;
    }

    #page-content-wrapper {
      min-width: 0;
      width: 100%;
    }
  }
}

@media (max-width: 700px) {
  html {
    font-size: 12px;
  }
  #app{
    h1, .color-wheel-title .title{
      font-size: 2rem !important;
    }
  #color-wheel-wrapper {
    height: 12rem;
    width: 12rem;
  }

   #color-theory-page {
     h5{
       font-size: 1.4em;
     }
     
     .color-theory-wheel-title{
       font-size: 1.7em;
     }
    .inner-container {
      max-width: 100%;

      grid-template-columns: 1fr 1fr 1fr;
      grid-template-areas:
        "title title title"
        "wheel wheel wheel"
        "mixing relationships modes";
      grid-row-gap: 0.5em;

      .color-theory-wheel {
        margin: 1em auto;
      }
      
      .modes, .relationships{
        .color-theory-wheel{
          margin: 1em 4em;
        }
      }
    }
  }
  
  #about-page{
    .info-wrapper{
      display: block;
      > .about-container, .shortcuts-container, .made-with-container{
        width: 100%;
      }
      > div > div{
        padding: 1em 2em;
      }
    }
  }
}
}
              
            
!

JS

              
                /**
 * Uitlity method to map state from observable to components.
 * The methods will convert snake_case keys to camelCase
 * @param Array state  arary of state keys to be mapped
 */
const mapState = function (state) {
    let returnState = {};
    if (!Array.isArray(state))
        return returnState;

    state.forEach(s => {
        let key = s.split("_").map((k, i) => {
            let replaceKey = k.replace(/^./, (m) => m.toUpperCase());
            return (i > 0) ? replaceKey : k;
        }).join("");

        returnState[key] = function () {
            return store[s];
        }
    });

    return returnState;
}
/**
 * Utility methods to map mutations to compoenent
 * @param Array methods array of methods keys to be mapped
 */
const mapMethods = function (methods) {
    let returnMethods = {};
    if (!Array.isArray(methods))
        return returnMethods;

    methods.forEach(m => {
        returnMethods[m] = mutations[m];
    });

    return returnMethods;
}

/**
 * Observable is used in place to Vuex as a simple state management alterantive
 */
let store = Vue.observable({
    picker_modes: [{
        name: "comple",
        title: "Complementary"
    }, {
        name: "split",
        title: "Split Complementary"
    }, {
        name: "mono",
        title: "Monochromatic"
    }, {
        name: "analog",
        title: "Analogous"
    }, {
        name: "tri",
        title: "Triadic"
    }, {
        name: "square",
        title: "Square"
    }, {
        name: "tetra",
        title: "Tetradic"
    }],
    selected_picker_mode: "single",
    is_custom: false,
    picker_mode_title: function () {
        const currentMode = Object.values(this.picker_modes).filter(m => {
            if (m.name == this.selected_picker_mode && m.name != "custom")
                return m.title;
        });

        if (currentMode[0] == undefined)
            return "";

        return currentMode[0].title;
    },
    pointer_count: function () {
        const mode = this.selected_picker_mode;
        let count = 0;

        switch (mode) {
            case "single":
                count = 1;
                break;

            case "comple":
                count = 2;
                break;

            case "split":
            case "analog":
            case "mono":
            case "tri":
                count = 3;
                break;

            case "square":
            case "tetra":
                count = 4;
                break;

        }
        return count;
    },
    pointer_sepration: {
        "comple": [180, 180],
        "split": [140, 140, 80],
        "analog": [40, 40, 280],
        "mono": [
            [0.3, 0.3, 0.6],
            [-0.3, 0.3, 0.3],
            [-0.6, -0.3, 0.3]
        ],
        "tri": [120, 120, 120],
        "square": [90, 90, 90, 90],
        "tetra": [120, 60, 120, 60],
    },
    wheel_demo_indices: {
        "comple": [0, 6],
        "analog": [0, 1, 11],
        "mono": [0],
        "split": [0, 5, 7],
        "tri": [0, 4, 8],
        "tetra": [0, 4, 6, 10],
        "square": [0, 3, 6, 9],
        "temperature": [...Array(12).keys()],
        "primary": [0, 4, 8],
        "secondary": [2, 6, 10],
        "tertiary": [1, 3, 5, 7, 9, 11]
    },
    selected_pointer_index: 0,
    colors: [{
        degrees: 80,
        saturation: 100,
        lightness: 50,
        lightnessRotate: 90,
        left: 0,
        top: 0,
        palette: {
            darkest: "",
            darker: "",
            lighter: "",
            lightest: ""
        }
    }],
    ctrl_pressed: false,
    pointer_moving: false
});

let mutations = {
    updateMode: function (mode) {
        if (mode == 'custom') {
            store.is_custom = true;
        } else {
            store.is_custom = false;
            store.selected_picker_mode = mode;
            store.selected_pointer_index = 0;
        }
    },
    updateColor: function (index, newColors) {
        const currentColors = store.colors[index];
        const updatedColor = Object.assign({}, currentColors, newColors);
        const {
            degrees: h,
            saturation: s,
            lightness: l
        } = updatedColor;

        const color = tinycolor(`hsl(${h}, ${s}%, ${l}%)`);

        updatedColor.palette = {
            darkest: color.clone().darken(30).toHslString(),
            darker: color.clone().darken(15).toHslString(),
            lighter: color.clone().lighten(15).toHslString(),
            lightest: color.clone().lighten(30).toHslString(),
        }

        updatedColor.hsl = color.toHslString();

        Vue.set(store.colors, index, updatedColor);
    },
    removeColor: function (start) {
        store.colors.splice(start);
    },
    swapColors: function (from, to) {
        const a = store.colors[from];
        const b = store.colors[to];

        Vue.set(store.colors, from, b);
        Vue.set(store.colors, to, a);
    },
    updatePointerIndex: function (newIndex) {
        store.selected_pointer_index = parseInt(newIndex);
    },
    updateCtrl: function (newValue) {
        store.ctrl_pressed = newValue;
    },
    updateWheelMode: function (index) {
        store.picker_modes[index];
        store.wheel_demo_mode = mode;
    },
    updateMoving: function (isMoving) {
        store.pointer_moving = isMoving;
    }
};

Vue.component('pointer', {
    template: "#pointer-template",
    props: ['index', 'color-wheel'],
    data: () => {
        return {
            pointer_clicked: false,
            enlarge: false,
            enlargeTimeout: null
        }
    },
    created: function () {
        if (this.index == this.selectedPointerIndex) {
            window.addEventListener('keydown', event => {
                switch (event.code) {
                    case "ArrowUp":
                    case "ArrowDown":
                        this.changeSaturation(event.code);
                        event.preventDefault();
                        break;

                    case "ArrowLeft":
                    case "ArrowRight":
                        this.changeHue(event.code);
                        event.preventDefault();
                        break;
                }
            });
        }

        // check if lightness change and update class for 1 seconds
        this.$parent.$on("lightnessChange", () => {
            if (this.index == this.selectedPointerIndex) {
                this.enlarge = true;
                clearTimeout(this.enlargeTimeout);
                this.enlargeTimeout = setTimeout(() => {
                    this.enlarge = false;
                }, 700);
            }
        });
    },
    mounted: function () {
        // Create object for the current element
        let newObject = {
            degrees: 260,
            saturation: 100,
            lightness: 50,
            light: 90,
            palette: {
                darkest: "",
                darker: "",
                lighter: "",
                lightest: ""
            }
        }

        // update or add new color item if required
        this.updateColor(this.index, newObject);

        // assign events
        document.addEventListener("mousedown", this.mouseDown);
        document.addEventListener("mouseup", e => this.pointer_clicked = false);
        document.addEventListener("mousemove", this.movePointer);

        // this event is needed when picker  mode changes
        this.$parent.$on('updateFirstPointer', data => {
            if (this.index == 0) {
                const coord = this.getPointerPosition(this.colors[0]);
                const firstColor = Object.assign(this.colors[0], coord);
                this.updateColor(this.index, firstColor);
            }
        });

        this.$parent.$on('updateOtherPointers', data => {
            if (this.isCustom != true)
                this.getstyle();
        });
    },
    methods: {
        ...mapMethods(["updateColor", "removeColor", "updatePointerIndex", "updateMode", "updateMoving"]),
        mouseDown: function (e) {
            if (e.target.id == 'color-wheel') {
                this.pointer_clicked = true;
                if (this.ctrlPressed)
                    this.updateMode("custom");
                else
                    this.updatePointerIndex(0);
            }

            if (e.target.classList.contains("pointer")) {
                this.pointer_clicked = true;
                const pointerIndex = e.target.getAttribute("data-index");
                this.updatePointerIndex(pointerIndex);

                if (this.ctrlPressed)
                    this.updateMode("custom");
            }

        },
        changeSaturation: function (direction) {
            // increase or decrease by 5 if ctrl is pressed, otherwise jsut 1
            let factor = 1;
            if (this.ctrlPressed == true)
                factor = 5;

            // Get current color and update saturation accordingly.
            const currentColor = this.colors[this.selectedPointerIndex];
            let newSaturation = (direction == "ArrowDown") ? currentColor.saturation + factor : currentColor.saturation - factor;

            // value can only be betwen 0 and 100, no need to loop
            newSaturation = Math.max(0, Math.min(100, newSaturation));

            // merge new values with old current and overwrite degrees
            let newColor = Object.assign(currentColor, {
                saturation: newSaturation
            });

            // get position for the new values
            newColor = Object.assign(newColor, this.getPointerPosition(newColor));

            // update color picker then update other pickers
            this.updateColor(this.selectedPointerIndex, newColor);
            
            this.$parent.$emit('updateOtherPointers');
        },
        changeHue: function (direction) {
            // increase or decrease by 5 if ctrl is pressed, otherwise jsut 1
            let factor = 1;
            if (this.ctrlPressed == true)
                factor = 5;

            // Get current color and update hue accordingly.
            const currentColor = this.colors[this.selectedPointerIndex];

            let newHue = (direction == "ArrowLeft") ? currentColor.degrees + factor : currentColor.degrees - factor;

            // value can only be betwen 0 and 360
            if (newHue > 360)
                newHue = 0;

            if (newHue < 0)
                newHue = 360;

            // merge new values with old current and overwrite degrees
            let newColor = Object.assign(currentColor, {
                degrees: newHue
            });

            // get position for the new values
            newColor = Object.assign(newColor, this.getPointerPosition(newColor));

            // update current color  then update other colors
            this.updateColor(this.selectedPointerIndex, newColor);
            this.$parent.$emit('updateOtherPointers');
        },
        getPointerPosition: function (currentColor) {

            const wheel_radius = this.colorWheel.radius;
            const angle = currentColor.degrees;
            const distance = currentColor.saturation * wheel_radius / 100;

            // radians start from right center turing count clockwis.
            // hsl degress start top center turning clockwise.
            // we need to adujst the angle to provide the right measuerments
            const radians = (angle - 90) * (Math.PI / 180);
            const left = wheel_radius + distance * Math.cos(radians);
            const top = wheel_radius + distance * Math.sin(radians);

            return {
                top: top.toFixed(2),
                left: left.toFixed(2)
            }
        },
        movePointer: function (e) {
            if (!this.pointer_clicked || this.index != this.selectedPointerIndex)
                return;

            const wheel = this.colorWheel;
            let left = e.clientX - wheel.x;
            let top = e.clientY - wheel.y;

            // calcuate distance of the picker dot from color wheel
            const dx = wheel.radius - left;
            const dy = wheel.radius - top;
            let distance = Math.sqrt(dx * dx + dy * dy);

            // get angle so we can get coords once mouse outside color wheel
            let angle = Math.atan2(dy, dx);

            angle = angle < 0 ? (angle += Math.PI * 2) : angle;

            if (distance > wheel.radius) {
                left = wheel.radius - wheel.radius * Math.cos(angle);
                top = wheel.radius - wheel.radius * Math.sin(angle);
            }

            // Dont make distance greater than radius
            if (distance >= wheel.radius)
                distance = wheel.radius;

            let saturation = distance * 100 / wheel.radius;

            // -90 is to start from top center to avoid discrepancy between circle start point
            // and HSL start point
            let hslDegree = angle * 180 / Math.PI - 90;

            // after 270 degrees hsl will be a negative value starting from -90 to 0
            if (hslDegree < 0)
                hslDegree = 270 + (90 - Math.abs(hslDegree));

            let color = {
                degrees: Math.round(hslDegree),
                saturation: Math.round(saturation),
                lightness: 50,
                left: left.toFixed(2),
                top: top.toFixed(2)
            }

            this.updateColor(this.selectedPointerIndex, color);
            
            this.$parent.$emit('updateOtherPointers');
        },
        getstyle: function () {
            if (this.colors[this.index] == undefined)
                return;

            const mode = this.selectedPickerMode;
            const selectedIndex = this.selectedPointerIndex;
            const anchorColor = this.colors[selectedIndex];
            const pointer = this.index;
            const separation = this.pointerSepration[mode];

            // We need to loop through the array values. i.e if we reach the end start again to get all values
            let separationValues = [];
            if (this.index < selectedIndex)
                separationValues = [...separation.slice(selectedIndex + 1), ...separation.slice(0, this.index + 1)];
            else
                separationValues = this.pointerSepration[mode].slice(selectedIndex + 1, this.index + 1);

            // Calculate hue degree by accumlating previous values in array
            let seprationDegree = 0;
            if (separationValues.length != 0)
                seprationDegree = separationValues.reduce((acc, value) => acc + value);

            if (pointer != selectedIndex) {

                let newColor = {};
                newColor.seprationDegree = seprationDegree;

                if (mode != 'mono') {
                    // change hue degree and keep within 360 for tinyscript
                    let degrees = anchorColor.degrees + seprationDegree;
                    if (degrees > 360)
                        degrees = degrees - 360;

                    newColor.degrees = degrees;
                    newColor.saturation = anchorColor.saturation;

                } else {
                    // for monochrome change saturation other change hue degree
                    let newSaturation = anchorColor.saturation
                    if (selectedIndex != 0)
                        newSaturation = 100 - anchorColor.saturation;
                    // For mono colors, the factor is third. Once we get it we can subtract 
                    // from anchor color to get new one. (factor is negative to move forward when subtracting
                    // and backgward when positive)
                    const third = newSaturation * separation[selectedIndex][pointer];
                    let saturation = anchorColor.saturation - (third);

                    // Saturation can not exceed 100% or be less than 0
                    if (saturation > 100)
                        saturation = 100;
                    if (saturation < 0)
                        saturation = 0;

                    newColor.degrees = anchorColor.degrees;
                    newColor.saturation = saturation;
                }

                newColor.lightness = this.colors[pointer].lightness;


                let coord = this.getPointerPosition(newColor);
                newColor = Object.assign(newColor, coord);

                this.updateColor(pointer, newColor);
            }
        },
    },
    computed: {
        ...mapState(["selected_picker_mode", "pointer_count", "pointer_sepration", "colors", "ctrl_pressed", "is_custom", "selected_pointer_index"]),
        selectedColor: function () {
            return this.colors[this.selectedPointerIndex];
        },
        left: function () {
            if (this.colors[this.index] == undefined)
                return 0;

            return this.colors[this.index].left + "px";
        },
        top: function () {
            if (this.colors[this.index] == undefined)
                return 0;
            return this.colors[this.index].top + "px";
        },
        background: function () {
            if (this.enlarge == false)
                return '';

            let c = this.selectedColor;
            return `hsl(${c.degrees}, ${c.saturation}%, ${c.lightness}%)`
        }

    },
    watch: {
        selectedPickerMode: function () {
            this.$parent.$emit('updateOtherPointers');
            this.$parent.$emit('updateFirstPointer');
        },
        pointer_clicked: function(isClicked){
            this.updateMoving(isClicked);
        }
    },
    destroyed: function () {
        this.removeColor(this.index);
    }
});

Vue.component('color-wheel', {
    template: "#color-wheel-template",
    data: () => {
        return {
            color_wheel: {},
            lightness_picker_el: null,
            timeout: null
        }
    },
    created: function () {
        // attach events to move picker inside color wheel
        document.addEventListener("mousedown", e => {
            if (e.target.id == 'lightness-picker')
                this.lightness_clicked = true;
        });

        document.addEventListener("mouseup", e => this.lightness_clicked = false);
        document.addEventListener("mousemove", this.moveLightness);

        // update wheel position and size on window resize
        window.addEventListener("resize", this.updateWheelPosition);

        // update selected index when number is pressed
        window.addEventListener('keydown', event => {
            switch (event.code) {
                case "Digit1":
                case "Digit2":
                case "Digit3":
                case "Digit4":
                    const index = parseInt(event.key);

                    if (index <= this.pointerCount)
                        this.updatePointerIndex(index - 1);
                    break;
            }
        });
    },
    mounted: function () {

        // get color wheel dimensions, position and radius
        this.color_wheel = this.$el.querySelector("#color-wheel").getBoundingClientRect();
        this.color_wheel.radius = this.color_wheel.height / 2;

        this.updateMode("comple");

        this.lightness_picker_el = this.$el.querySelector("#lightness-picker");


        this.$el.addEventListener('wheel', this.changeLightness);

        document.querySelector("#app").addEventListener("scroll", this.updateWheelPosition);
    },
    methods: {
        ...mapMethods(["updateColor", "updatePointerIndex", "initColors", "updateMode", "removeColor"]),
        changeLightness: function (e) {
            let rotate = this.currentColor.lightnessRotate;
            let factor = (this.ctrlPressed) ? 5 : 1;

            let newRotate = 0;

            if (e.deltaY < 0)
                newRotate = rotate + factor;
            else
                newRotate = rotate - factor;


            if (newRotate < 0)
                newRotate = 360;

            if (newRotate > 360)
                newRotate = 0;

            // get lightness percentage. if over 180
            const lightnessRotate = (newRotate > 180) ? 360 - newRotate : newRotate;

            const lightness = lightnessRotate * 100 / 180;


            this.updateColor(this.selectedPointerIndex, {
                lightness: Math.round(lightness),
                lightnessRotate: Math.round(newRotate)
            });

            // emit event to enlarge picker
            this.$emit('lightnessChange');

            e.preventDefault();
        },
        moveLightness: function (e) {
            if (!this.lightness_clicked)
                return;

            let left = e.clientX - this.color_wheel.x;
            let top = e.clientY - this.color_wheel.y;

            const dx = this.color_wheel.radius - left;
            const dy = this.color_wheel.radius - top;

            // get angle 
            let angle = Math.atan2(dy, dx);

            // -90 to start from from top center
            let degrees = angle * 180 / Math.PI - 90;

            // the first quarter will be over positive and the rest of the circle will negative degrees.
            // Adjust for that case
            if (degrees < 0)
                degrees = 360 - Math.abs(degrees);

            // get lightness percentage. if over 180
            const lightnessRotate = (degrees > 180) ? 360 - degrees : degrees;

            const lightness = lightnessRotate * 100 / 180;

            // emit event to enlarge picker
            this.$emit('lightnessChange');
            this.updateColor(this.selectedPointerIndex, {
                lightness: Math.round(lightness),
                lightnessRotate: Math.round(degrees)
            });
        },
        updateWheelPosition: function (e) {
            clearTimeout(this.timeout);
            this.timeout = setTimeout(() => {
                this.color_wheel = this.$el.querySelector("#color-wheel").getBoundingClientRect();
                this.color_wheel.radius = this.color_wheel.height / 2;
            }, 500);

        }
    },
    computed: {
        ...mapState(["colors", "pointer_count", "selected_pointer_index", "selected_picker_mode", "ctrl_pressed", "pointer_moving"]),
        currentColor() {
            return this.colors[this.selectedPointerIndex];
        },
        lightnessStyle: function () {
            let c = this.currentColor;

            const start = `hsl(${c.degrees}, ${c.saturation}%, 0%)`;
            const middle = `hsl(${c.degrees}, ${c.saturation}%, 50%)`;
            const end = `hsl(${c.degrees}, ${c.saturation}%, 90%)`;

            return {
                backgroundImage: `linear-gradient(180deg, ${start}, ${middle}, ${end})`
            }
        },
        lightnessRotation: function () {

            const rotate = this.currentColor.lightnessRotate;
            //const rotate = lightness * 180 / 100;
            return {
                transform: `rotate(${rotate}deg)`
            }
        },
        pointerCount() {
            return store.pointer_count();
        }
    }

});

Vue.component('color-theory-wheel', {
    template: "#color-theory-wheel-template",
    props: {
        mode: "split",
        title: "",
        static: false,
        wheelStyle: ""
    },
    data: () => {
        return {
            current_hover: 0,
            count: 12
        }
    },
    methods: {
        processHover: function (index) {
            if (this.static == true)
                return [];

            this.current_hover = index;
        }
    },
    computed: {
        ...mapState(["wheel_demo_indices"]),
        modeIndices: function () {
            return this.wheelDemoIndices[this.mode];
        },
        highlightIndices: function () {
            if (this.modeIndices == undefined)
                return [];

            return this.modeIndices.map(i => {
                let newCount = this.current_hover + i
                if (newCount >= this.count)
                    newCount = newCount - this.count;

                return newCount;
            })
        }
    },
    watch: {
        mode: function (newMode) {
            switch (newMode) {
                case "primary":
                case "secondary":
                case "tertiary":
                case "tempreature":
                    this.current_hover = 0;
                    break;
            }
        }
    }
});

Vue.component('colors-display', {
    template: "#colors-display-template",
    data: () => {
        return {
            entered: -1,
            dragged: -1,
            colors_models: [{
                name: "hsl",
                value: ""
            }, {
                name: "rgb",
                value: ""
            }, {
                name: "hex",
                value: ""
            }, {
                name: "hsv",
                value: ""
            }],
            current_model_index: 0,
            copy_message: ""
        }
    },
    mounted: function () {
        const clipboard = new ClipboardJS('.copy-value');

        clipboard.on('success', e => {
            this.copy_message = "copied!"

            e.clearSelection();
        });

        clipboard.on('error', e => {
            this.copy_message = "fAILED!"
        });
    },
    methods: {
        ...mapMethods(['swapColors']),
        getBackground: function (index) {
            const c = this.colors[index];

            return {
                "background-color": c.hsl
            }
        },

        dragstart: function (index, e) {
            this.dragged = index;
            e.dataTransfer.setData('text/plain', 'dummy');
        },
        dragend: function () {
            this.swapColors(this.dragged, this.entered);
            this.entered = -1;
        },
        dragenter: function (index) {
            this.entered = index;
        },
        colorModelSpinner: function () {
            const currentIndex = this.current_model_index;
            const models = this.colors_models;

            let nextIndex = currentIndex + 1;
            if (nextIndex > models.length - 1)
                nextIndex = 0;

            this.current_model_index = nextIndex;
        },
    },
    computed: {
        ...mapState(["colors", "selected_pointer_index", ]),
        tinycolor: function () {
            const c = this.colors[this.selectedPointerIndex];

            return tinycolor(`hsl(${c.degrees}, ${c.saturation}%, ${c.lightness}%)`);
        },
        currentModel: function () {
            const model_index = this.current_model_index;
            return this.colorsModelsValues[model_index];
        },
        colorsModelsValues: function () {
            //const colorObject = {};
            return this.colors_models.map(c => {
                return {
                    name: c.name,
                    value: this[c.name]
                };
            });
        },
        hsl: function () {
            return this.tinycolor.toHslString();
        },
        rgb: function () {
            return this.tinycolor.toRgbString();
        },
        hex: function () {
            return this.tinycolor.toHexString();
        },
        hsv: function () {
            return this.tinycolor.toHsvString();
        },
        pointerCount: function () {
            return store.pointer_count();
        },
        arrowStyle: function () {
            const pointer = this.selectedPointerIndex;
            const width = 100 / this.pointerCount;
            const left = (width * pointer) + (width / 2);

            return {
                left: `${left}%`
            }
        }
    }
});

Vue.component('pages-nav', {
    template: '#pages-nav-template',
    data() {
        return {
            current_page: 0,
            pages: [],
            hovered_dot_index: -1,
            hovered_dot_position: null,
            title_position: 0,
            container: null
        };
    },
    created: function () {
        window.addEventListener('keydown', event => {
            switch (event.code) {
                case "PageUp":
                    if(this.current_page > 0)
                        this.current_page--;

                    event.preventDefault();
                    break;

                case "PageDown":
                    if(this.current_page < 2)
                        this.current_page++;
                    event.preventDefault();
                    break;
            }
        });
    },
    mounted() {
        this.container = document.querySelector("#app");
        let divs = document.querySelectorAll("#app > div");

        for (i = 0; i < divs.length; ++i) {
            let element = divs[i];
            const obj = {
                index: i,
                title: element.getAttribute("data-title"),
                element: element
            }
            this.pages.push(obj);
        }

        
    },
    methods: {
        dotHover: function (index, event) {
            this.hovered_dot_index = index;

            const offsetTop = event.target.offsetTop;
            const height = event.target.getBoundingClientRect().height;

            this.title_position = offsetTop + (height / 2);
        }
    },
    computed: {
        pageTitle: function () {
            if (this.hovered_dot_index == -1)
                return "";

            return this.pages[this.hovered_dot_index].title;
        }
    },
    watch: {
        current_page: function (newVal) {
            let height = this.container.getBoundingClientRect().height;
            this.container.scrollTo({
                top: height * newVal,
                left: 0,
                behavior: 'smooth'
            });
        }
    }
});

Vue.component('about', {
    template: '#about-template',
    data() {
        return {
            info: ['This project provides a complete, easy and intuitive palette generator. Using the color wheel, you can create any type of palette and with live preview you can see how colors would match (or not) on a real website.',
                'In addition, keyboard shortcuts and mouse wheel are used to fine-tune selection and provide greater control over the end results.',
                'I have added a color theory summary to provide a general understanding of how colors are used.'
            ],
            shortcuts: [{
                    keys: ['up', '/', 'down'],
                    desc: "Decrease / Increase saturation by 1%"
                },
                {
                    keys: ['left', '/', 'right'],
                    desc: "Increase / Decrease hue by 1 degree"
                },
                {
                    keys: ['ctrl', '+', 'up', '/', 'down'],
                    desc: "Decrease / Increase saturation by 5%"
                },
                {
                    keys: ['ctrl', '+', 'left', '/', 'right'],
                    desc: "Increase / Decrease hue by 5 degrees"
                },
                {
                    keys: ["mouse-wheel"],
                    desc: "Increase / decrease lightness by 1 degree"
                },
                {
                    keys: ["Ctrl", "+", "mouse-wheel"],
                    desc: "Increase / decrease lightness by 5 degrees"
                },
                {
                    keys: ["1", "2", "3", "4"],
                    desc: "Select color pointer"
                },
                {
                    keys: ["ctrl", "+", "mouse-click-left"],
                    desc: "Custom color mode"
                },
                {
                    keys: ["page down", "/", "page up"],
                    desc: "Move between sections"
                },
                {
                    keys: ["ctrl", "+", "m"],
                    desc: "Cycle between color modes"
                }
            ],
            made_with: [{
                    title: "vue.js",
                    link: "https://vuejs.org/"
                },
                {
                    title: "Bootstrap",
                    link: "https://getbootstrap.com/"
                },
                {
                    title: "TinyColor",
                    link: "https://bgrins.github.io/TinyColor/"
                },
                {
                    title: "Charts.js",
                    link: "https://www.chartjs.org/"
                },
                {
                    title: "clipboard.js",
                    link: "https://clipboardjs.com/"
                },
                {
                    title: "Font Awesome",
                    link: "https://fontawesome.com/"
                },
                {
                    title: "Google fonts",
                    link: "https://fonts.google.com/"
                }
            ]
        };
    },

    mounted() {

    },
    methods: {

    },
    computed: {

    }
});


Vue.component('chart', {
    template: '<canvas ref="myChart" :width="width" :height="height"></canvas>',
    data() {
        return {
            chart: null
        };
    },
    props: {
        type: {
            type: String,
            default: "line"
        },
        width: {
            type: Number,
            validator: value => value > 0,
            default: 651
        },
        height: {
            type: Number,
            validator: value => value > 0,
            default: 350
        },
        labels: Array,
        datasets: {
            type: Array,
            required: true
        },
        options: Object
    },
    mounted() {
        this.chart = new Chart(this.$refs.myChart, {
            type: this.type,
            data: {
                labels: this.labels,
                datasets: this.datasets
            },
            options: this.options,

        });
    },
    beforeDestroy() {
        if (this.chart) {
            this.chart.destroy()
        }
    },
    watch: {
        datasets(newDatasets) {
            this.chart.data.datasets = newDatasets;
            this.chart.update();
        }
    },
});

Vue.component('demo', {
    template: "#demo-template",
    data: () => {
        return {
            settings: {
                darkmode: false,
                default_sidebar_bg: false,
                hide_text: false
            },
            chart: null,
            admin_cards: [{
                    title: "Total traffic",
                    number: "214,126",
                    percentage: "5.1",
                    icon_class: "fas fa-eye"
                },
                {
                    title: "New users",
                    number: "12,186",
                    percentage: "2.6",
                    icon_class: "fas fa-users"
                },
                {
                    title: "Sales",
                    number: "3,186",
                    percentage: "8.1",
                    icon_class: "fas fa-dollar-sign"
                }
            ],
            page_visits: [{
                name: "/color-wheel/",
                visitors: "7,548",
                unique: "657",
                rate: "31,85%",
                direction: "up"
            }, {
                name: "/color-wheel/theory.html",
                visitors: "4,548",
                unique: "201",
                rate: "40,25%",
                direction: "down"
            }, {
                name: "/color-wheel/index.html",
                visitors: "3,268",
                unique: "321",
                rate: "35,25%",
                direction: "up"
            }, {
                name: "/color-wheel/about.html",
                visitors: "2,548",
                unique: "186",
                rate: "42,25%",
                direction: "down"
            }, ],
            social_ref: [{
                name: "facebook",
                visitors: "7,548",
                percentage: "60"
            }, {
                name: "codepen",
                visitors: "10,548",
                percentage: "70"
            }, {
                name: "google",
                visitors: "6,548",
                percentage: "40"
            }, {
                name: "instagram",
                visitors: "2,548",
                percentage: "25"
            }],
            line_chart: {
                source: "traffic",
                labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
                traffic_chart: [{
                    label: 'Visitors',
                    fill: false,
                    data: [131800, 131150, 141004, 151042, 161074, 141878, 161768, 175987, 181897, 192872, 203224, 214126],
                    borderColor: "white",
                    borderWidth: 5,
                    pointRadius: 0,
                    borderCapStyle: "round"
                }],
                sales_chart: [{
                    label: 'Sales',
                    fill: false,
                    data: [2015, 45897, 4598, 15042, 16074, 45987, 12356, 78971, 87865, 12587, 14963, 12008],
                    borderColor: "white",
                    borderWidth: 5,
                    pointRadius: 0,
                    borderCapStyle: "round"
                }],
                options: {
                    tooltips: {
                        mode: 'index',
                        intersect: false
                    },
                    legend: {
                        display: false
                    },
                    animation: {
                        onComplete: function (ss) {
                            //console.log(ss);
                        }
                    },
                    scales: {
                        yAxes: [{
                            ticks: {
                                callback: function (value, index, values) {
                                    if (value == 0)
                                        return 0;


                                    return value.toString().slice(0, -3) + 'k';
                                },
                                padding: 10,
                                fontColor: "lightgray"
                            },
                            gridLines: {
                                borderDash: [2, 4],
                                zeroLineWidth: 0,
                                drawBorder: false,

                            }
                        }],
                        xAxes: [{
                            ticks: {
                                fontColor: "lightgray"
                            }
                        }]
                    }
                }
            }
        }
    },
    mounted: function () {
        this.style = document.documentElement.style;
    },
    methods: {
        updateData: function (type) {
            Vue.set(this.line_chart, "source", type);
        },
        mostReadable: function (color, grades) {
            const matchAgainst = Object.values(grades);
            return tinycolor.mostReadable(color, matchAgainst).toHslString();
        },
        getNewStyle: function () {
            if (this.selectedPickerMode == "single" || this.colors.length < 2)
                return;

            const newColors = {};
            const first = this.colors[0];
            const second = this.colors[1];
            const third = this.colors[2] || {};
            const fourth = this.colors[3] || {};

            let firstColor = tinycolor(first.hsl);

            // Header bg color and text color
            newColors['--demo-primary-bg'] = first.hsl;
            newColors['--demo-primary-color'] = this.mostReadable(first.hsl, first.palette);

            // Button colors (active, hover, .. etc)
            newColors['--demo-btn-bg'] = first.palette.darker;
            newColors['--demo-btn-border'] = first.palette.darkest;
            newColors['--demo-btn-color'] = (firstColor.isDark()) ? "white" : "black";
            newColors['--demo-btn-active-color'] = this.mostReadable(first.palette.lighter, first.palette);
            newColors['--demo-btn-active'] = first.palette.lighter;
            newColors['--demo-btn-active-border'] = first.palette.darkest;

            // header color
            newColors['--demo-header-card'] = second.hsl;
            newColors['--demo-header-card-text-1'] = this.mostReadable(second.hsl, second.palette);
            newColors['--demo-header-card-text-2'] = this.mostReadable(second.hsl, second.palette);
            newColors['--demo-text-success'] = this.mostReadable(second.hsl, first.palette);

            switch (this.selectedPickerMode) {
                case "comple":
                    if (this.settings.default_sidebar_bg == false) {
                        const sidebarHover = this.mostReadable(first.hsl, first.palette);
                        newColors['--demo-sidebar-bg'] = first.palette.lighter;
                        newColors['--demo-sidebar-hover'] = sidebarHover;
                        newColors['--demo-sidebar-hover-color'] = this.mostReadable(sidebarHover, first.palette);
                        newColors['--demo-sidebar-text-color'] = (firstColor.isDark()) ? "white" : "black";
                    }
                    break;

                case "square":
                case "tetra":
                    if(this.colors.length < 4)
                        return;

                    newColors['--demo-scrollbar-foreground'] = fourth.palette.darkest;
                    newColors['--demo-scrollbar-background'] = fourth.palette.lighter;


                case "split":
                case "analog":
                case "mono":
                case "tri":
                case "square":
                case "tetra":
                    if(this.colors.length < 3)
                        return;

                    const thirdColor = tinycolor(third.hsl);

                    if (this.settings.default_sidebar_bg == false) {
                        const sidebarHover = this.mostReadable(third.hsl, second.palette);
                        newColors['--demo-sidebar-bg'] = third.palette.lighter;
                        newColors['--demo-sidebar-hover'] = this.mostReadable(third.hsl, third.palette);
                        newColors['--demo-sidebar-hover-color'] = this.mostReadable(sidebarHover, third.palette);
                        newColors['--demo-sidebar-text-color'] = (thirdColor.isDark()) ? "white" : "black";
                    }

                    break;
            }

            return newColors
        }
    },
    computed: {
        ...mapState(["colors", "selected_picker_mode"]),
        linechartDataset: function () {
            if (this.line_chart.source == 'traffic')
                return this.line_chart.traffic_chart

            return this.line_chart.sales_chart;
        },

    }
});

new Vue({
    el: "#app",
    data: {
        wheel_mode: "comple",
        hide_text: false
    },
    created: function () {
        
        window.addEventListener('keyup', e => {
            this.updateCtrl(false);
        });

        window.addEventListener('keydown', e => {
            if (e.ctrlKey == true)
                this.updateCtrl(true);
        });

        window.addEventListener('keydown', e => {
            if (e.code == 'KeyM' && this.ctrlPressed)
               this.modeSpinner();
            
        });
    },
    methods: {
        updateMode: mutations.updateMode,
        updateCtrl: mutations.updateCtrl,

        modeSpinner: function () {

            if (this.isCustom == true) {
                this.updateMode(this.selectedPickerMode)
                return;
            }

            const currentMode = this.selectedPickerMode;
            const modeIndex = this.modes.findIndex(m => m.name == currentMode);
            const nextIndex = (modeIndex + 1 > this.modes.length - 1) ? 0 : modeIndex + 1;
            const nextMode = this.modes[nextIndex].name;

            this.updateMode(nextMode);
        },
        cancelCustom: function () {
            this.updateMode(this.selectedPickerMode);
        }
    },

    computed: {
        ...mapState(["picker_modes", "selected_picker_mode", "colors", "selected_pointer_index", "is_custom", "ctrl_pressed"]),
        modes() {
            let modes = [];
            this.pickerModes.map(m => {
                modes.push(m);
            });

            if (modes.length == 0)
                return [];

            return modes;
        },

        endColor: function () {

            const c = this.colors[this.selectedPointerIndex];

            return {
                "background-color": `hsl(${c.degrees}, ${c.saturation}%, ${c.lightness}%)`
            }
        },
        isStatic: function () {
            let static = false;
            switch (this.wheel_mode) {
                case "primary":
                case "secondary":
                case "tertiary":
                case "tempreature":
                    static = true;
                    break;
            }

            return static;
        },
        pickerModeTitle: function () {
            return store.picker_mode_title();
        }
    }
})
              
            
!
999px

Console