mixin list-item(percent)
a(href='#')
if (percent.endsWith('%'))
span.progress(style={width: percent})
span: block
span=percent
.container
.col#sidebar
nav
.header
a.brand(href='#'): i.fa.fa-rocket
button#menu: i.fa.fa-bars
ul
li.search
input.form-control#search(placeholder='Search...')
button.btn-search: i.fa.fa-lg.fa-search
li.nav-text Dashboards
li: a.active(href='#') Overview
li: a(href='#') Order history
li: a(href='#') Fluid layout
li: a(href='#') Icon nav
li.nav-text More
li: a(href='#') Toolkit docs
li: a(href='#') Bootstrap docs
li: a(href='#') Light UI
li: a(href='#') Example modal
li: .divider
.col
.row.fluid.header
.label
span Dashboards
h2 Overview
#date-range
input.form-control
div -
input.form-control
.divider
.row.fluid
.doughnut
.chart: canvas#test1
strong Traffic
h4 New vs Returning
.doughnut
.chart: canvas#test2
strong Revenue
h4 New vs Recurring
.doughnut
.chart: canvas#test3
strong Traffic
h4 Direct vs Referrals
.divider
h3 Quick Stats
.row.sparklines
.col.sparkline
.chart
.label
span Page Views
h2 1,293
.chart-container: canvas#test4
.col.sparkline
.chart
.label
span Downloads
h2 758
.chart-container: canvas#test5
.col.sparkline
.chart
.label
span Sign-ups
h2 1,293
.chart-container: canvas#test6
.col.sparkline
.chart
.label
span Downloads
h2 758
.chart-container: canvas#test7
.divider
.row.top
.col
.list
h6 Countries
+list-item('62.4%') United States
+list-item('15.0%') India
+list-item('5.0%') United Kingdom
+list-item('5.0%') Canada
+list-item('4.5%') Russia
+list-item('2.3%') Mexico
+list-item('1.7%') Spain
+list-item('1.5%') France
+list-item('1.4%') South Africa
+list-item('1.2%') Japan
a.btn.primary(href='#') All countries
.col.flex-start
.list
h6 Most visited pages
+list-item('3,929,481') / (Logged out)
+list-item('1,143,393') / (Logged in)
+list-item('938,287') /tour
+list-item('749,393') /features/something
+list-item('695,912') /features/another-thing
+list-item('501,938') /users/username
+list-item('392,842') /page-title
+list-item('298,183') /some/page-slug
+list-item('193,129') /another/directory/and/page-title
+list-item('93,382') /one-more/page/directory/file-name
a.btn.primary(href='#') View all pages
.row
.col.list-container
.list
h6 Devices and resolutions
+list-item('3,929,481') Desktop (1920x1080)
+list-item('1,143,393') Desktop (1366x768)
+list-item('938,287') Desktop (1440x900)
+list-item('749,393') Desktop (1280x800)
+list-item('695,912') Tablet (1024x768)
+list-item('501,938') Tablet (768x1024)
+list-item('392,842') Phone (320x480)
+list-item('298,183') Phone (720x450)
+list-item('193,129') Desktop (2560x1080)
+list-item('193,129') Desktop (2560x1080)
a.btn.primary(href='#') View all devices
View Compiled
// Uncomment a different theme and rerun to update the chart colors
// Pressing ctrl + shift + 7 manually reruns
@include theme($bg-dark-blue, $blue, $teal-a400);
//@include theme($bg-dark-red, $red, $amber);
//@include theme($bg-dark-purple, $deep-purple-a100, $light-blue-300, #AAB1C0);
// More accurate original colors
//$bg: #252830;
//$bg-light: #434857;
//$bg-drk: #1e2127;
//$text-hint: #999;
// js looks at the css vars to get the chart colors
:root {
--background: #{$bg};
--primary: #{$primary};
--secondary: #{$secondary};
}
html {
font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 1.15;
}
body {
display: flex;
justify-content: center;
padding-top: 50px;
line-height: 1.5;
font-size: 14px;
overflow-x: hidden;
}
h1, h2, h3, h4, h5, h6 {
font-family: inherit;
font-weight: 300;
line-height: 1.1;
}
h2 {
font-size: 32px;
}
h4 {
font-size: 24px;
}
hr {
border: none;
border-top: 1px solid $bg-light;
}
.form-control {
background-color: $bg-light;
color: $text;
padding: 8px 12px;
border: 1px solid rgba($black, 0.15);
border-radius: $border-radius;
line-height: 1.25;
font-size: 14px;
font-family: inherit;
outline: none;
transition: box-shadow $anim-duration, border-color $anim-duration;
box-sizing: content-box;
&:hover {
border-color: rgba($white, .3);
}
&:focus {
border-color: transparent;
box-shadow: 0 0 0 3px rgba($primary, .8);
}
&::placeholder, &::-moz-placeholder {
color: $text-hint;
opacity: 1;
}
}
.container {
display: flex;
max-width: 1100px;
}
.row {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
flex-shrink: 0;
&:not(.fluid) { margin: 0 -15px }
&.top { align-items: flex-start }
}
.col {
flex: 1 1 0px;
display: flex;
flex-direction: column;
padding: 0 15px;
}
.row.header {
margin-bottom: -15px;
}
.label span {
color: $text-hint;
font-size: 12px;
letter-spacing: 1px;
text-transform: uppercase;
margin-bottom: 5px;
line-height: 13px;
}
canvas {
max-width: 100%;
}
.doughnut {
flex: 0 0 33.33333%;
text-align: center;
.chart {
width: 75%;
margin: 0 auto 15px;
}
strong {
color: $text-hint;
font-size: 14px;
}
}
.sparklines {
margin: -15px !important;
}
.sparkline {
flex-grow: 1;
width: 25%;
padding: 0;
.label {
padding: 0 15px;
span {
color: $text-hint;
font-size: 12px;
letter-spacing: 2px;
text-transform: uppercase;
}
h2 {
font-size: 2rem;
}
}
.chart {
padding: 15px;
}
.chart-container {
height: 70px;
}
}
.list {
display: flex;
flex-direction: column;
margin-bottom: 1rem;
width: 100%;
background: transparent;
> * {
border: 1px solid $bg-light;
margin-bottom: -1px;
}
h6 {
padding: 1rem 1.25rem;
}
a {
position: relative;
padding: 0.75rem 1.25rem;
width: 100%;
display: flex;
justify-content: space-between;
box-sizing: border-box;
color: $text-hint;
text-decoration: none;
font-size: 14px;
line-height: 1.5;
.progress {
position: absolute;
top: 0;
bottom: 0;
left: 0;
z-index: -1;
display: block;
background-color: $bg-dark;
border-radius: inherit;
}
span:last-child { color: $text-hint }
&:hover, &:focus {
background: $bg-light;
}
&:active {
background: $primary;
color: $bg;
span:last-child { color: $bg }
}
}
> :first-child {
border-top-left-radius: $border-radius;
border-top-right-radius: $border-radius;
}
> :last-child {
border-bottom-left-radius: $border-radius;
border-bottom-right-radius: $border-radius;
}
+ a {
align-self: flex-start;
font-size: 14px;
line-height: 18px;
margin-bottom: 30px;
}
}
.btn {
display: inline-block;
text-decoration: none;
background: transparent;
border-radius: $border-radius;
padding: 8px 16px;
transition: background $anim-duration, color $anim-duration;
&.primary {
color: $primary;
border: 1px solid $primary;
&:hover {
background: $primary;
color: $white;
}
}
}
.divider {
position: relative;
font-size: 12px;
text-transform: uppercase;
text-align: center;
margin-top: 30px;
margin-bottom: 30px;
h3 {
position: relative;
display: inline-block;
vertical-align: middle;
background-color: $bg;
color: $text-hint;
padding: 0 12px;
}
&::before {
position: absolute;
top: 50%;
display: block;
content: "";
width: 100%;
height: 1px;
background-color: $bg-light;
}
}
nav {
display: flex;
flex-direction: column;
margin-right: 40px;
.header {
display: flex;
justify-content: space-between;
box-sizing: border-box;
min-width: 360px;
padding-bottom: 20px;
line-height: 37px;
}
.brand {
color: $bg-light;
text-decoration: none;
font-size: 40px;
transition: color $anim-duration;
&:hover { color: $text-hint }
&:focus { color: $primary }
}
ul {
li {
&.nav-text {
font-size: 12px;
color: $bg-light;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 5px;
padding: 0 15px;
}
a {
display: block;
padding: 7px 15px;
border-radius: $border-radius;
text-decoration: none;
line-height: 1.5;
color: $text-hint;
font-size: 14px;
&:hover { color: $text }
&.active {
background: $primary;
color: $bg;
cursor: default;
}
}
+ .nav-text {
margin-top: 20px;
}
}
}
}
.search {
position: relative;
}
#sidebar {
flex: 0 0 auto;
width: 245px;
}
#search {
padding: 8px 15px;
width: 100%;
box-sizing: border-box;
}
#date-range {
display: flex;
align-items: center;
justify-content: center;
input {
width: 70px;
height: 17px;
padding: 7px 5px;
&:first-child {
border-right-color: transparent;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
text-align: center;
}
&:last-child {
border-left-color: transparent;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
text-align: center;
}
&:hover {
border-color: rgba($white, .3);
}
&:focus {
border-color: transparent;
}
}
div {
display: inline-block;
width: 18px;
height: 33px;
background: $bg-light;
border: 1px solid rgba($black, 0.15);
border-left: none;
border-right: none;
text-align: center;
font-weight: bold;
font-size: 24px;
line-height: 29px;
z-index: -1;
}
}
#menu {
display: none;
background: transparent;
color: $bg-light;
padding-bottom: 2px;
border: 1px solid $bg-light;
border-radius: $border-radius;
font-size: 28px;
cursor: pointer;
transition: color $anim-duration, border-color $anim-duration;
&:hover, &:focus {
color: $text;
border-color: $text;
}
}
.btn-search {
background: transparent;
border: none;
color: $text;
position: absolute;
height: 100%;
top: 0;
right: 0;
}
@media (max-width: 1100px) {
.container {
width: 800px;
}
#sidebar {
width: 175px;
nav {
margin-right: 0;
}
}
.sparkline {
flex-basis: 50%;
width: 50%;
}
}
@media (max-width: 800px) {
body {
padding-top: 100px;
}
.container {
width: 575px;
flex-wrap: wrap;
> .col {
flex-basis: auto;
}
}
nav .header {
display: flex;
position: fixed;
width: 100%;
height: 70px;
background: $bg;
top: 0;
left: 0;
border-bottom: 1px solid $bg-light;
align-items: center;
z-index: 10;
padding: 0 15px;
#menu {
display: block;
}
}
nav {
&.open ul {
top: 70px;
}
ul {
position: fixed;
transition: top 500ms;
left: 0px;
top: -500px;
background: $bg;
width: 100%;
padding: 0;
z-index: 2;
padding: 15px 15px 0;
box-sizing: border-box;
border-bottom: 1px solid $bg-light;
.divider {
display: none;
}
}
}
#date-range {
position: fixed;
top: 0;
left: 0;
width: 100%;
min-width: 360px;
height: 70px;
z-index: 10;
pointer-events: none;
* {
pointer-events: all;
}
}
.list-container {
flex-basis: 100%;
width: 100%;
}
@media (max-height: 500px) {
nav ul {
overflow-y: scroll;
height: calc(100% - 70px);
}
}
}
@media (max-width: 575px) {
.container {
width: 100%;
min-width: 360px;
}
.doughnut {
flex-basis: 100%;
&:not(:last-child) { margin-bottom: 30px }
}
.sparkline {
flex-basis: 100%;
width: 100%;
}
}
// Date Picker Theme
.dark-theme {
&.pika-single {
color: $text;
background: $bg;
border: 1px solid $bg-light;
border-bottom-color: $bg-light;
}
.pika-label {
background-color: inherit;
}
.pika-prev, .is-rtl .pika-next {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAQAAACGG/bgAAAAQ0lEQVR4Ae3KIQ4AIBTD0N0/IeHGI3UIRA3ut/Zl+ltXc5++htVAmIAwAWECwgSEKbgthEoIlRAqIVRCqINQB9nDgQd7ktwFo6UpWQAAAABJRU5ErkJggg==');
}
.pika-next, .is-rtl .pika-prev {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAQAAACGG/bgAAAAP0lEQVQ4y+3TMQoAMAgEwfwfAvvjTZ1uGzuvHhBPPGczEG+FRqqRaqQaqUaqkX6QBmmjacvQ6qEVTjsh+xizebvlaWptGXZAAAAAAElFTkSuQmCC');
}
.pika-table th, .pika-week, .is-disabled .pika-button {
color: $text-hint;
}
.pika-button {
color: inherit;
background: inherit;
}
.is-today .pika-button {
font-weight: normal;
}
.is-selected .pika-button {
color: $text;
background: $primary;
}
}
View Compiled
// All this JS is for creating charts
// $mm is just a lightweight jQuery substitution library I made
// $mm should be mostly swappable for normal jQuery
// This part also creates the click effect
// See cdpn.io/e/XgYOPy for more details
let colors = {
background: $mm.cssVar('background'),
primary: $mm.cssVar('primary'),
secondary: $mm.cssVar('secondary'),
}
$mm.merge(burstOpts, {
colors: [colors.primary, colors.secondary],
zIndex: 10000
})
// Charts
$mm.fn.extend({
doughnut: function(attrData) {
var data = attrData.data ? attrData.data : {},
options = attrData.options ? attrData.options : {}
data.datasets = data.datasets.map(t => $mm.merge({
borderWidth: 2,
borderColor: colors.background,
hoverBorderColor: 'transparent'
}, t))
options = $mm.merge(true, {
cutoutPercentage: 80,
legend: {
display: false
},
title: {
position: 'bottom',
fontSize: 24
}
}, options)
return new Chart(this.getContext("2d"), {
type: 'doughnut',
data: data,
options: options
});
},
sparkline: function(attrData) {
var data = attrData.data ? attrData.data : {},
options = attrData.options ? attrData.options : {};
data.datasets = data.datasets.map(t => {
return $mm.merge({
fill: true,
backgroundColor: colors.primary + '18',
borderColor: colors.primary,
pointBorderColor: '#fff',
lineTension: 0.25,
pointRadius: 0
}, t)
})
let max = data.datasets.reduce((a, b) => Math.max(a, Math.max(...b.data)), 0)
options = $mm.merge(true, {
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [{ display: false }],
yAxes: [{ display: false, ticks: {min: 0, max: max + 5} }]
},
tooltips: {
enabled: false
}
}, options)
return new Chart(this, {
type: 'line',
data: data,
options: options
})
}
})
// Utility
$mm.extend({
randData: (n, max, min = 0) => Array.from({length: n}, () => $mm.randInt(max, min))
})
function formatDate (date) {
return date.toLocaleDateString('en-us')
}
let dateInputs = $mm.findAll('#date-range input')
let datePickers = [
new Pikaday({
field: dateInputs[0],
toString: formatDate,
theme: 'dark-theme'
}),
new Pikaday({
field: dateInputs[1],
toString: formatDate,
theme: 'dark-theme'
})
]
let date = new Date()
date.setDate(new Date().getDate() - 7)
datePickers[0].setDate(date)
datePickers[1].setDate(new Date())
$mm('#test1').doughnut({
data: {
labels: ['New', 'Returning'],
datasets: [{
backgroundColor: [colors.primary + 'D0', colors.secondary + 'D0'],
hoverBackgroundColor: [colors.primary, colors.secondary],
data: $mm.randData(2, 300, 50)
}]
}
})
$mm('#test2').doughnut({
data: {
labels: ['New', 'Recurring'],
datasets: [{
backgroundColor: [colors.primary + 'D0', colors.secondary + 'D0'],
hoverBackgroundColor: [colors.primary, colors.secondary],
data: $mm.randData(2, 300, 50)
}]
}
})
$mm('#test3').doughnut({
data: {
labels: ['Direct', 'Referrals'],
datasets: [{
backgroundColor: [colors.primary + 'D0', colors.secondary + 'D0'],
hoverBackgroundColor: [colors.primary, colors.secondary],
data: $mm.randData(2, 300, 50)
}]
}
})
let labels = Array.from({length: 10}, (v, i) => String.fromCharCode(97 + i))
$mm('#test4').sparkline({
data: {
labels: labels,
datasets: [{
data: $mm.randData(10, 100, 0)
}]
}
})
$mm('#test5').sparkline({
data: {
labels: labels,
datasets: [{
data: $mm.randData(10, 100, 0)
}]
}
})
$mm('#test6').sparkline({
data: {
labels: labels,
datasets: [{
data: $mm.randData(10, 100, 0)
}]
}
})
$mm('#test7').sparkline({
data: {
labels: labels,
datasets: [{
data: $mm.randData(10, 100, 0)
}]
}
})
$mm('#menu').on('click', e => {
$mm('#sidebar nav').toggleClass('open')
})