diff --git a/cms/envs/common.py b/cms/envs/common.py
index c6aaad60f8..2d8c46cc96 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -710,6 +710,10 @@ base_vendor_js = [
'edx-ui-toolkit/js/utils/string-utils.js',
'edx-ui-toolkit/js/utils/html-utils.js',
+ # Load Bootstrap and supporting libraries
+ 'common/js/vendor/tether.js',
+ 'common/js/vendor/bootstrap.js',
+
# Finally load RequireJS
'common/js/vendor/require.js'
]
diff --git a/cms/static/sass/_build-v1.scss b/cms/static/sass/_build-v1.scss
index b62a4f855d..e2efd973e5 100644
--- a/cms/static/sass/_build-v1.scss
+++ b/cms/static/sass/_build-v1.scss
@@ -10,7 +10,7 @@
// +Base - Utilities
// ====================
-@import 'partials/variables';
+@import 'cms/base/variables';
@import 'mixins';
@import 'mixins-inherited';
diff --git a/cms/static/sass/_build-v2.scss b/cms/static/sass/_build-v2.scss
index 0aecd11645..056d171968 100644
--- a/cms/static/sass/_build-v2.scss
+++ b/cms/static/sass/_build-v2.scss
@@ -6,10 +6,13 @@
// Configuration
@import 'config';
-// Extensions
-@import 'partials/variables';
+// +Base - Utilities
+// ====================
+@import 'partials/cms/base/variables';
@import 'mixins-v2';
@import 'base-v2';
+
+// Pattern Library styling
@import 'elements-v2/controls';
@import 'elements-v2/header';
@import 'elements-v2/navigation';
diff --git a/cms/static/sass/bootstrap/_base.scss b/cms/static/sass/bootstrap/_base.scss
new file mode 100644
index 0000000000..95c50d513d
--- /dev/null
+++ b/cms/static/sass/bootstrap/_base.scss
@@ -0,0 +1,11 @@
+// Open edX: Studio base styles
+// ============================
+//
+// Note: these styles replicate the Studio styles directly
+// rather than benefiting from any Bootstrap classes. Ideally
+// the code base should be rebuilt using Bootstrap and then
+// these styles will no longer be necessary.
+
+.is-hidden {
+ display: none;
+}
diff --git a/cms/static/sass/bootstrap/_components.scss b/cms/static/sass/bootstrap/_components.scss
new file mode 100644
index 0000000000..618b9b7b68
--- /dev/null
+++ b/cms/static/sass/bootstrap/_components.scss
@@ -0,0 +1,195 @@
+// Open edX: components
+// ====================
+
+// Skip nav
+.nav-skip,
+.transcript-skip {
+ font-size: 14px;
+ line-height: 14px;
+ display: inline-block;
+ position: absolute;
+ left: 0;
+ top: -($baseline*30);
+ overflow: hidden;
+ background: $white;
+ border-bottom: 1px solid $gray-lightest;
+ padding: ($baseline*0.75) ($baseline/2);
+
+ &:focus,
+ &:active {
+ position: relative;
+ top: auto;
+ width: auto;
+ height: auto;
+ margin: 0;
+ }
+}
+
+// Page banner
+.page-banner {
+ max-width: $studio-max-width;
+ margin: 0 auto;
+
+ .user-messages {
+ margin-top: $baseline;
+ }
+}
+
+// Alerts
+.alert {
+ .icon-alert {
+ margin-right: $baseline / 4;
+ }
+}
+
+// Sock
+.wrapper-sock {
+ @include clearfix();
+ position: relative;
+ margin: ($baseline*2) 0 0 0;
+ border-top: 1px solid $gray-light;
+ width: 100%;
+
+ .wrapper-inner {
+ display: none;
+ width: 100% !important;
+ border-bottom: 1px solid $white;
+ padding: 0 $baseline !important;
+ }
+
+ // sock - actions
+ .list-cta {
+ @extend %ui-depth1;
+ position: absolute;
+ top: -($baseline*0.75);
+ width: 100%;
+ margin: 0 auto;
+ text-align: center;
+ list-style: none;
+
+ .cta-show-sock {
+ @extend %ui-btn-pill;
+ @extend %t-action4;
+ background: $gray-lightest;
+ padding: ($baseline/2) $baseline;
+ color: $gray-light;
+
+ .icon {
+ margin-right: $baseline/4;
+ }
+
+ &:hover {
+ background: $brand-primary;
+ color: $white;
+ }
+ }
+ }
+
+ // sock - additional help
+ .sock {
+ @include clearfix();
+ @extend %t-copy-sub2;
+ max-width: $studio-max-width;
+ width: flex-grid(12);
+ margin: 0 auto;
+ padding: ($baseline*2) 0;
+ color: $gray-light;
+
+ // support body
+ header {
+
+ .title {
+ @extend %t-title4;
+ }
+
+ }
+
+ .list-actions {
+ list-style: none;
+ }
+
+ // shared elements
+ .support, .feedback {
+ .title {
+ @extend %t-title6;
+ color: $white;
+ margin-bottom: ($baseline/2);
+ }
+
+ .copy {
+ @extend %t-copy-sub2;
+ margin: 0 0 $baseline 0;
+ }
+
+ .list-actions {
+ @include clearfix();
+
+ .action-item {
+ float: left;
+ margin-right: $baseline/2;
+ margin-bottom: ($baseline/2);
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ .action {
+ @extend %t-action4;
+ display: block;
+
+ .icon {
+ @extend %t-icon4;
+ vertical-align: middle;
+ margin-right: $baseline/4;
+ }
+
+ &:hover, &:active {
+
+ }
+ }
+
+ .tip {
+ @extend %cont-text-sr;
+ }
+ }
+
+ .action-primary {
+ @extend %btn-primary-blue;
+ @extend %t-action3;
+ }
+ }
+ }
+
+ // studio support content
+ .support {
+ width: flex-grid(8,12);
+ float: left;
+ margin-right: flex-gutter();
+
+ .action-item {
+ width: flexgrid(4,8);
+ }
+ }
+
+ // studio feedback content
+ .feedback {
+ width: flex-grid(4,12);
+ float: left;
+
+ .action-item {
+ width: flexgrid(4,4);
+ }
+ }
+ }
+
+ // case: sock content is shown
+ &.is-shown {
+ border-color: $gray-dark;
+
+ .list-cta .cta-show-sock {
+ background: $gray-dark;
+ border-color: $gray-dark;
+ color: $white;
+ }
+ }
+}
diff --git a/cms/static/sass/bootstrap/_footer.scss b/cms/static/sass/bootstrap/_footer.scss
new file mode 100644
index 0000000000..bcbbd57cb6
--- /dev/null
+++ b/cms/static/sass/bootstrap/_footer.scss
@@ -0,0 +1,96 @@
+// Open edX: Studio footer
+// =======================
+//
+// Note: these styles replicate the Studio styles directly
+// rather than benefiting from any Bootstrap classes. Ideally
+// the header should be reimagined using Bootstrap and then
+// these styles will no longer be necessary.
+
+.wrapper-footer {
+ position: relative;
+ width: 100%;
+ margin: 0 0 $baseline 0;
+ padding: $baseline;
+
+ footer.primary {
+ @extend %t-copy-sub2;
+ @include clearfix();
+ max-width: $studio-max-width;
+ width: flex-grid(12);
+ margin: 0 auto;
+ color: $gray-light;
+
+ .footer-content-primary {
+ @include clearfix();
+ }
+
+ .colophon {
+ width: flex-grid(4, 12);
+ float: left;
+ margin-right: flex-gutter(2);
+ }
+
+ .nav-peripheral {
+ width: flex-grid(6, 12);
+ float: right;
+ text-align: right;
+
+ .nav-item {
+ display: inline-block;
+ margin-right: $baseline/4;
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ a {
+ border-radius: 2px;
+ padding: ($baseline/2) ($baseline/2);
+ background: transparent;
+
+ .icon {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: $baseline/4;
+ }
+ }
+ }
+ }
+
+ .footer-content-secondary {
+ @include clearfix();
+ margin-top: $baseline;
+ }
+
+ .footer-about-copyright, .footer-about-openedx {
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ // platform trademarks
+ .footer-about-copyright {
+ width: flex-grid(4, 12);
+ float: left;
+ margin-right: flex-gutter(2);
+ }
+
+ // platform Open edX logo and link
+ .footer-about-openedx {
+ float: right;
+ text-align: right;
+
+ a {
+ display: inline-block;
+
+ img {
+ display: block;
+ width: ($baseline* 6);
+ }
+
+ &:hover {
+ border-bottom: none;
+ }
+ }
+ }
+ }
+}
diff --git a/cms/static/sass/bootstrap/_header.scss b/cms/static/sass/bootstrap/_header.scss
new file mode 100644
index 0000000000..adac9cf019
--- /dev/null
+++ b/cms/static/sass/bootstrap/_header.scss
@@ -0,0 +1,568 @@
+// Open edX: Studio header
+// =======================
+//
+// Note: these styles replicate the Studio styles directly
+// rather than benefiting from any Bootstrap classes. Ideally
+// the header should be reimagined using Bootstrap and then
+// these styles will no longer be necessary.
+
+// studio - elements - global header
+// ====================
+
+.wrapper-header {
+ @extend %ui-depth3;
+ position: relative;
+ width: 100%;
+ box-shadow: 0 1px 2px 0 $shadow-l1;
+ margin: 0;
+ padding: 0 $baseline;
+ background: $white;
+
+ header.primary {
+ @include clearfix();
+ max-width: $studio-max-width;
+ width: flex-grid(12);
+ margin: 0 auto;
+ }
+
+ // ====================
+
+ // basic layout
+ .wrapper-l, .wrapper-r {
+ background: $white;
+ }
+
+ .wrapper-l {
+ float: left;
+ width: flex-grid(7,12);
+ }
+
+ .wrapper-r {
+ float: right;
+ width: flex-grid(4,12);
+ text-align: right;
+ }
+
+ .branding, .info-course, .nav-course, .nav-account, .nav-pitch {
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ .user-language-selector {
+ width: 120px;
+ display: inline-block;
+ margin: 0 10px 0 5px;
+ vertical-align: sub;
+
+ .language-selector {
+ width: 120px;
+ }
+ }
+
+ .nav-account {
+ width: auto;
+ }
+
+ // basic layout - nav items
+ nav {
+
+ > ol > .nav-item {
+ @extend %t-action3;
+ @extend %t-strong;
+ display: inline-block;
+ vertical-align: middle;
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+
+ .nav-item a {
+ color: $gray;
+
+ &:hover {
+ color: $link-hover-color;
+ }
+ }
+ }
+
+ // basic layout - dropdowns
+ .nav-dd {
+
+ .title {
+ @extend %t-action2;
+ @extend %ui-btn-dd-nav-primary;
+
+ .label, .fa-caret-down {
+
+ }
+
+ .label {
+
+ }
+
+ .fa-caret-down {
+ opacity: 0.25;
+ }
+
+ &:hover {
+
+ .fa-caret-down {
+ opacity: 1.0;
+ }
+ }
+
+ .nav-sub .nav-item {
+
+ .icon {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: ($baseline/4);
+ }
+ }
+ }
+ }
+
+ // ====================
+
+ // specific elements - branding
+ .branding {
+ padding: ($baseline*0.75) 0;
+
+ a {
+ display: block;
+
+ img {
+ max-height: ($baseline*2);
+ display: block;
+ }
+ }
+ }
+
+ // ====================
+
+ // specific elements - course name/info
+ .info-course {
+ margin-right: flex-gutter();
+ border-right: 1px solid $gray-lighter;
+ padding: ($baseline*0.75) flex-gutter() ($baseline*0.75) 0;
+
+ .course-org, .course-number {
+ font-size: 12px;
+ line-height: 12px;
+ display: inline-block;
+ vertical-align: middle;
+ max-width: 45%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ opacity: 1.0;
+ color: $gray-dark;
+ }
+
+ .course-org {
+ margin-right: $baseline/4;
+ }
+
+ .course-title {
+ @extend %t-action2;
+ @extend %t-strong;
+ display: block;
+ width: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+
+ // entire link
+ .course-link {
+ display: block;
+ color: $gray-dark;
+
+ &:hover {
+ color: $link-hover-color;
+ }
+ }
+ }
+
+ // ====================
+
+ // specific elements - course nav
+ .nav-course {
+ padding: ($baseline*0.75) 0;
+ }
+
+ // ====================
+
+ // specific elements - account-based nav
+ .nav-account {
+ position: relative;
+ padding: ($baseline*0.75) 0;
+
+ .nav-sub {
+ text-align: left;
+ }
+
+ .nav-account-help {
+
+ .wrapper-nav-sub {
+ width: ($baseline*10);
+ }
+ }
+
+ .nav-account-user {
+
+ .title {
+ max-width: ($baseline*6.5);
+
+ > .label {
+ display: inline-block;
+ max-width: 84%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ }
+ }
+
+ .settings-language-form {
+ margin-top: 4px;
+ .language-selector {
+ width: 130px;
+ }
+ }
+ }
+
+ // ====================
+
+ // specific elements - pitch/how it works nav
+ .nav-pitch {
+ position: relative;
+ padding: ($baseline*0.75) 0;
+
+ .nav-sub {
+ text-align: left;
+ }
+ }
+}
+
+// ====================
+
+// CASE: user signed in
+.is-signedin {
+
+ .wrapper-l {
+ width: flex-grid(8,12);
+ }
+
+ .wrapper-r {
+ width: flex-grid(4,12);
+ }
+
+ .branding {
+ margin-right: 2%;
+ }
+
+ .nav-account {
+ top: ($baseline/4);
+ }
+}
+
+// ====================
+
+// CASE: in course {
+.is-signedin.course {
+
+ .wrapper-header {
+
+ .wrapper-l {
+ width: flex-grid(9,12);
+ }
+
+ .wrapper-r {
+ width: flex-grid(3,12);
+ }
+
+ .branding {
+ margin-right: 2%;
+ }
+
+ .info-course {
+ width: 25%;
+ margin-right: 2%;
+ }
+
+ .nav-course {
+ width: 45%;
+ }
+ }
+}
+
+// ====================
+
+// CASE: user not signed in
+.not-signedin,
+.view-util {
+
+ .wrapper-header {
+
+ .wrapper-l {
+ width: flex-grid(2,12);
+ }
+
+ .wrapper-r {
+ width: flex-grid(10,12);
+ }
+
+ .branding {
+ width: 100%;
+ }
+
+ .nav-pitch {
+ top: ($baseline/4);
+
+ .nav-item {
+ margin-right: ($baseline/2);
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+
+ .action-signup {
+ padding: ($baseline/4) ($baseline/2);
+ text-transform: uppercase;
+ }
+
+ .action-signin {
+ padding: ($baseline/4) ($baseline/2);
+ text-transform: uppercase;
+ }
+ }
+ }
+}
+
+// dropdown
+.nav-dd {
+
+ .title {
+
+ .label, .fa-caret-down {
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ .ui-toggle-dd {
+ margin: 0;
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ // dropped down state
+ &.is-selected {
+
+ .ui-toggle-dd {
+ transform: rotate(-180deg);
+ transform-origin: 50% 50%;
+ }
+ }
+ }
+
+ .nav-item {
+ position: relative;
+
+ &:hover {
+
+ }
+
+ &.nav-course-settings {
+ .wrapper-nav-sub {
+ width: ($baseline*9);
+ }
+ }
+ }
+
+ .wrapper-nav-sub {
+ position: absolute;
+ top: ($baseline*2.5);
+ opacity: 0.0;
+ pointer-events: none;
+ width: ($baseline*8);
+ overflow: hidden;
+ height: 0;
+
+
+ // dropped down state
+ &.is-shown {
+ opacity: 1.0;
+ pointer-events: auto;
+ overflow: visible;
+ height: auto;
+ }
+ }
+
+ .nav-sub {
+ border-radius: 2px;
+ box-shadow: 0 1px 1px $shadow-l1;
+ position: relative;
+ width: 100%;
+ border: 1px solid $gray-light;
+ padding: ($baseline/2) ($baseline*0.75);
+ background: $white;
+
+ &:after, &:before {
+ bottom: 100%;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ }
+
+ // ui triangle/nub
+ &:after {
+ border-color: rgba(255, 255, 255, 0);
+ border-bottom-color: $white;
+ border-width: 10px;
+ }
+
+ &:before {
+ border-color: rgba(178, 178, 178, 0);
+ border-bottom-color: $gray-light;
+ border-width: 11px;
+ }
+
+ .nav-item {
+ @extend %t-action3;
+ @extend %t-regular;
+ display: block;
+ margin: 0 0 ($baseline/4) 0;
+ border-bottom: 1px solid $gray-lighter;
+ padding: 0 0($baseline/4) 0;
+
+ &:last-child {
+ margin-bottom: 0;
+ border-bottom: none;
+ padding-bottom: 0;
+ }
+
+ a {
+ display: block;
+
+ &:hover, &:active {
+ color: $brand-primary;
+ }
+ }
+ }
+ }
+
+ // CASE: left-hand side arrow/dd
+ &.ui-left {
+
+ .wrapper-nav-sub {
+ left: 0;
+ }
+
+ .nav-sub {
+ text-align: left;
+
+ // ui triangle/nub
+ &:after {
+ left: $baseline;
+ margin-left: -10px;
+ }
+
+ &:before {
+ left: $baseline;
+ margin-left: -11px;
+ }
+ }
+ }
+
+ // CASE: right-hand side arrow/dd
+ &.ui-right {
+
+ .wrapper-nav-sub {
+ left: none;
+ right: 0;
+ }
+
+ .nav-sub {
+
+ // ui triangle/nub
+ &:after {
+ right: $baseline;
+ margin-right: -10px;
+ }
+
+ &:before {
+ right: $baseline;
+ margin-right: -11px;
+ }
+ }
+ }
+}
+
+// ====================
+
+// STATE: active/current nav states
+
+.nav-item.is-current,
+body.howitworks .nav-not-signedin-hiw,
+
+// dashboard
+body.dashboard .nav-account-dashboard,
+
+// course content
+body.course.view-outline .nav-course-courseware .title,
+body.course.view-updates .nav-course-courseware .title,
+body.course.view-static-pages .nav-course-courseware .title,
+body.course.view-uploads .nav-course-courseware .title,
+body.course.view-textbooks .nav-course-courseware .title,
+body.course.view-video-uploads .nav-course-courseware .title,
+
+body.course.view-outline .nav-course-courseware-outline,
+body.course.view-updates .nav-course-courseware-updates,
+body.course.view-static-pages .nav-course-courseware-pages,
+body.course.view-uploads .nav-course-courseware-uploads,
+body.course.view-textbooks .nav-course-courseware-textbooks,
+body.course.view-video-uploads .nav-course-courseware-videos,
+
+// course settings
+body.course.schedule .nav-course-settings .title,
+body.course.grading .nav-course-settings .title,
+body.course.view-team .nav-course-settings .title,
+body.course.view-group-configurations .nav-course-settings .title,
+body.course.advanced .nav-course-settings .title,
+body.course.view-certificates .nav-course-settings .title,
+
+body.course.schedule .nav-course-settings-schedule,
+body.course.grading .nav-course-settings-grading,
+body.course.view-team .nav-course-settings-team,
+body.course.view-group-configurations .nav-course-settings-group-configurations,
+body.course.advanced .nav-course-settings-advanced,
+body.course.view-certificates .nav-course-settings-certificates,
+
+// course tools
+body.course.view-import .nav-course-tools .title,
+body.course.view-export .nav-course-tools .title,
+body.course.view-export-git .nav-course-tools .title,
+
+body.course.view-import .nav-course-tools-import,
+body.course.view-export .nav-course-tools-export,
+body.course.view-export-git .nav-course-tools-export-git,
+
+// content library settings
+body.course.view-team .nav-library-settings .title,
+
+body.course.view-team .nav-library-settings-team
+
+{
+ color: $brand-primary;
+
+ a {
+ color: $brand-primary;
+ pointer-events: none;
+ }
+}
diff --git a/cms/static/sass/bootstrap/_layouts.scss b/cms/static/sass/bootstrap/_layouts.scss
new file mode 100644
index 0000000000..debb3548d5
--- /dev/null
+++ b/cms/static/sass/bootstrap/_layouts.scss
@@ -0,0 +1,362 @@
+// Open edX: Studio layout
+// =======================
+//
+// Note: these styles replicate the Studio styles directly
+// rather than benefiting from any Bootstrap classes. Ideally
+// the layouts should be reimagined using Bootstrap and then
+// these styles will no longer be necessary.
+
+.content-wrapper {
+ margin-top: $baseline;
+
+ .course-tabs {
+ padding-bottom: 0;
+
+ .nav-item {
+ &.active, &:hover{
+ .nav-link {
+ border-bottom-color: $brand-primary;
+ color: $brand-primary;
+ }
+ }
+
+ .nav-link {
+ padding: $baseline/2 $baseline*3/4 $baseline*13/20;
+ border-style: solid;
+ border-width: 0 0 $baseline/5 0;
+ border-bottom-color: transparent;
+
+ @media (max-width: map-get($grid-breakpoints, md)) {
+ border: none;
+ text-align: left;
+ padding: 0 0 $baseline/2 0;
+ }
+ }
+ }
+ }
+
+ .main-container {
+ border: 1px solid $inverse-color;
+ background-color: $body-bg;
+
+ .page-header {
+ border-bottom: 1px solid $inverse-color;
+ padding: 20px;
+ }
+
+ .page-content {
+ padding: 20px;
+ }
+ }
+
+ &.container-fluid {
+ max-width: $studio-max-width;
+ }
+}
+
+// studio - elements - layouts
+// ====================
+
+// layout - basic
+// the wrapper around the viewable page area, excluding modal and other extra-view content
+.wrapper-view {
+
+}
+
+// ====================
+
+// layout - basic page header
+.wrapper-mast {
+ margin: ($baseline*1.5) 0 0 0;
+ padding: 0 $baseline;
+ position: relative;
+
+ .mast,
+ .metadata {
+ @include clearfix();
+ position: relative;
+ max-width: $studio-max-width;
+ width: flex-grid(12);
+ margin: 0 auto $baseline auto;
+ color: $gray-dark;
+ }
+
+ .mast {
+ border-bottom: 1px solid $gray-light;
+ padding-bottom: ($baseline/2);
+
+ // layout without actions
+ .page-header {
+ width: flex-grid(12);
+ }
+
+ // layout with actions
+ &.has-actions {
+ @include clearfix();
+
+ .page-header {
+ float: left;
+ width: flex-grid(6,12);
+ margin-right: flex-gutter();
+ }
+
+ .nav-actions {
+ position: relative;
+ bottom: -($baseline*0.75);
+ float: right;
+ width: flex-grid(6,12);
+ text-align: right;
+
+ .nav-item {
+ display: inline-block;
+ vertical-align: top;
+ margin-right: ($baseline/2);
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+
+ // buttons
+ .button {
+ @extend %btn-primary-blue;
+ @extend %sizing;
+
+ .action-button-text {
+ display: inline-block;
+ vertical-align: baseline;
+ }
+
+ .icon {
+ display: inline-block;
+ vertical-align: baseline;
+ }
+
+ // CASE: new/create button
+ &.new-button,
+ &.button-new {
+ @extend %btn-primary-green;
+ @extend %sizing;
+ }
+ }
+ }
+ }
+
+ // layout with actions
+ &.has-subtitle {
+
+ .nav-actions {
+ bottom: -($baseline*1.5);
+ }
+ }
+
+ // layout with breadcrumb navigation
+ &.has-navigation {
+
+ .nav-actions {
+ bottom: -($baseline*1.5);
+ }
+
+ .navigation-item {
+ @extend %cont-truncated;
+ display: inline-block;
+ vertical-align: bottom; // correct for extra padding in FF
+ max-width: 250px;
+ color: $gray-dark;
+
+ &.navigation-current {
+ @extend %ui-disabled;
+ color: $gray;
+ max-width: 250px;
+
+ &:before {
+ color: $gray;
+ }
+ }
+ }
+
+ .navigation-link:hover {
+ color: $brand-primary;
+ }
+
+ .navigation-item:before {
+ content: " / ";
+ margin: ($baseline/4);
+ color: $gray;
+
+ &:hover {
+ color: $gray;
+ }
+ }
+
+ .navigation .navigation-item:first-child:before {
+ content: "";
+ margin: 0;
+ }
+ }
+ }
+
+ // CASE: wizard-based mast
+ .mast-wizard {
+
+ .page-header-sub {
+ @extend %t-title4;
+ color: $gray;
+ font-weight: 300;
+ }
+
+ .page-header-super {
+ @extend %t-title4;
+ float: left;
+ width: flex-grid(12,12);
+ margin-top: ($baseline/2);
+ border-top: 1px solid $gray-lighter;
+ padding-top: ($baseline/2);
+ font-weight: 600;
+ }
+ }
+
+ // page metadata/action bar
+ .metadata {
+
+ }
+}
+
+// layout - basic page content
+.wrapper-content {
+ margin: 0;
+ padding: 0 $baseline;
+ position: relative;
+}
+
+.content {
+ @include clearfix();
+ @extend %t-copy-base;
+ max-width: $studio-max-width;
+ width: flex-grid(12);
+ margin: 0 auto;
+ color: $gray-dark;
+
+ header {
+ position: relative;
+ margin-bottom: $baseline;
+ border-bottom: 1px solid $gray-lighter;
+ padding-bottom: ($baseline/2);
+
+ .title-sub {
+ @extend %t-copy-sub1;
+ display: block;
+ margin: 0;
+ color: $gray-light;
+ }
+
+ .title-1 {
+ @extend %t-title3;
+ @extend %t-strong;
+ margin: 0;
+ padding: 0;
+ color: $gray-dark;
+ }
+ }
+}
+
+// 3/4 - 1/4 two col layout
+%two-col-1 {
+ .content-primary {
+ float: left;
+ margin-right: flex-gutter();
+ width: flex-grid(9,12);
+ box-shadow: none;
+ border: 0;
+ background-color: $white;
+ }
+
+ .content-supplementary {
+ float: left;
+ width: flex-grid(3,12);
+ }
+}
+
+
+// layout - primary content
+.content-primary {
+
+ .title-1 {
+ @extend %t-title3;
+ }
+
+ .title-2 {
+ @extend %t-title4;
+ margin: 0 0 ($baseline/2) 0;
+ }
+
+ .title-3 {
+ @extend %t-title6;
+ margin: 0 0 ($baseline/2) 0;
+ }
+
+ header {
+ @include clearfix();
+
+ .title-2 {
+ width: flex-grid(5, 12);
+ margin: 0 flex-gutter() 0 0;
+ float: left;
+ }
+
+ .tip {
+ @extend %t-copy-sub2;
+ width: flex-grid(7, 12);
+ float: right;
+ margin-top: ($baseline/2);
+ text-align: right;
+ color: $gray-dark;
+ }
+ }
+}
+
+// layout - supplemental content
+.content-supplementary {
+
+ > section {
+ margin: 0 0 $baseline 0;
+ }
+}
+
+// ====================
+
+// layout - grandfathered
+.main-wrapper {
+ position: relative;
+ margin: 0 ($baseline*2);
+}
+
+.inner-wrapper {
+ @include clearfix();
+ position: relative;
+ max-width: 1280px;
+ margin: auto;
+
+ > article {
+ clear: both;
+ }
+}
+
+.main-column {
+ clear: both;
+ float: left;
+ width: 70%;
+}
+
+.sidebar {
+ float: right;
+ width: 28%;
+}
+
+.left {
+ float: left;
+}
+
+.right {
+ float: right;
+}
diff --git a/cms/static/sass/bootstrap/_mixins.scss b/cms/static/sass/bootstrap/_mixins.scss
new file mode 100644
index 0000000000..b21f0d7f77
--- /dev/null
+++ b/cms/static/sass/bootstrap/_mixins.scss
@@ -0,0 +1,239 @@
+// common - utilities - mixins and extends
+// ====================
+//
+// Note: these mixins replicate the Studio mixins directly
+// to simplify the usage of Studio Sass partials. They
+// should be deprecated in favor of using native Bootstrap
+// functionality.
+
+
+// Table of Contents
+// * +Font Sizing - Mixin
+// * +Line Height - Mixin
+// * +Sizing - Mixin
+// * +Square - Mixin
+// * +Placeholder Styling - Mixin
+// * +Flex Support - Mixin
+// * +Flex Polyfill - Extends
+// * +UI - Wrapper - Extends
+// * +UI - Window - Extend
+// * +UI - Visual Link - Extend
+// * +UI - Functional Disable - Extend
+// * +UI - Visual Link - Extend
+// * +UI - Depth Levels - Extends
+// * +UI - Clear Children - Extends
+// * +UI - Buttons - Extends
+// * +UI - Well Archetype - Extends
+// * +Content - No List - Extends
+// * +Content - Hidden Image Text - Extend
+// * +Content - Screenreader Text - Extend
+// * +Content - Text Wrap - Extend
+// * +Content - Text Truncate - Extend
+// * +Icon - Font-Awesome - Extend
+// * +Icon - SSO icon images
+
+// +Font Sizing - Mixin
+// ====================
+@mixin font-size($sizeValue: 16){
+ font-size: $sizeValue + px;
+ font-size: ($sizeValue/10) + rem;
+}
+
+// +Line Height - Mixin
+// ====================
+@mixin line-height($fontSize: auto){
+ line-height: ($fontSize*1.48) + px;
+ line-height: (($fontSize/10)*1.48) + rem;
+}
+
+// +Sizing - Mixin
+// ====================
+@mixin size($width: $baseline, $height: $baseline) {
+ height: $height;
+ width: $width;
+}
+
+// +Square - Mixin
+// ====================
+@mixin square($size: $baseline) {
+ @include size($size);
+}
+
+// +Placeholder Styling - Mixin
+// ====================
+@mixin placeholder($color) {
+ :-moz-placeholder {
+ color: $color;
+ }
+ ::-webkit-input-placeholder {
+ color: $color;
+ }
+ :-ms-input-placeholder {
+ color: $color;
+ }
+}
+
+// +Flex Support - Mixin
+// ====================
+@mixin ui-flexbox() {
+ display: -webkit-box;
+ display: -moz-box;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+}
+
+// +Flex PolyFill - Extends
+// ====================
+
+// justify-content right for display:flex alignment in older browsers
+%ui-justify-right-flex {
+ -webkit-box-pack: flex-end;
+ -moz-box-pack: flex-end;
+ -ms-flex-pack: flex-end;
+ -webkit-justify-content: flex-end;
+ justify-content: flex-end;
+}
+
+// justify-content left for display:flex alignment in older browsers
+%ui-justify-left-flex {
+ -webkit-box-pack: flex-start;
+ -moz-box-pack: flex-start;
+ -ms-flex-pack: flex-start;
+ -webkit-justify-content: flex-start;
+ justify-content: flex-start;
+}
+
+// align items center for display:flex alignment in older browsers
+%ui-align-center-flex {
+ -webkit-flex-align: center;
+ -ms-flex-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+}
+
+
+// +UI - Wrapper - Extends
+// ====================
+// used for page/view-level wrappers (for centering/grids)
+%ui-wrapper {
+ @include clearfix();
+ width: 100%;
+}
+
+// +UI - Depth Levels - Extends
+// ====================
+%ui-depth0 { z-index: 0; }
+%ui-depth1 { z-index: 10; }
+%ui-depth2 { z-index: 100; }
+%ui-depth3 { z-index: 1000; }
+%ui-depth4 { z-index: 10000; }
+%ui-depth5 { z-index: 100000; }
+
+
+// +UI - Clear Children - Extends
+// ====================
+// extends - UI - utility - first child clearing
+%wipe-first-child {
+
+ &:first-child {
+ margin-top: 0;
+ border-top: none;
+ padding-top: 0;
+ }
+}
+
+// extends - UI - utility - last child clearing
+%wipe-last-child {
+
+ &:last-child {
+ margin-bottom: 0;
+ border-bottom: none;
+ padding-bottom: 0;
+ }
+}
+
+// +Content - No List - Extends
+// ====================
+// removes list styling/spacing when using uls, ols for navigation and less content-centric cases
+%cont-no-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ text-indent: 0;
+
+ li {
+ margin: 0;
+ padding: 0;
+ }
+}
+
+// +Content - Hidden Image Text - Extend
+// ====================
+// image-replacement hidden text
+%cont-text-hide {
+ text-indent: 100%;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+// +Content - Screenreader Text - Extend
+// ====================
+%cont-text-sr {
+ // clip has been deprecated but is still supported
+ clip: rect(1px 1px 1px 1px);
+ clip: rect(1px, 1px, 1px, 1px);
+ position: absolute;
+ margin: -1px;
+ height: 1px;
+ width: 1px;
+ border: 0;
+ padding: 0;
+ overflow: hidden;
+ // ensure there are spaces in sr text
+ word-wrap: normal;
+}
+
+// +Content - Text Wrap - Extend
+// ====================
+%cont-text-wrap {
+ word-wrap: break-word;
+}
+
+// +Content - Text Truncate - Extend
+// ====================
+%cont-truncated {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+// * +Icon - Font-Awesome - Extend
+// ====================
+%use-font-awesome {
+ display: inline-block;
+ font-family: FontAwesome;
+ -webkit-font-smoothing: antialiased;
+ speak: none;
+}
+
+%btn-no-style {
+ background: transparent;
+ border: 0;
+ padding: 0;
+ margin: 0;
+}
+
+
+// * +Icon - SSO icon images
+// ====================
+
+%sso-icon {
+ .icon-image {
+ width: auto;
+ height: auto;
+ max-height: 1.4em;
+ max-width: 1.4em;
+ margin-top: -2px;
+ }
+}
diff --git a/cms/static/sass/bootstrap/_navigation.scss b/cms/static/sass/bootstrap/_navigation.scss
new file mode 100644
index 0000000000..a45ae4c008
--- /dev/null
+++ b/cms/static/sass/bootstrap/_navigation.scss
@@ -0,0 +1,95 @@
+// Local overrides for bootstrap navigation bar theming
+.navigation-container {
+ border-bottom: 2px solid $brand-primary;
+ text-decoration: none;
+ background-color: $header-bg;
+
+ &.slim {
+ border-bottom: 1px solid $inverse-color;
+ box-shadow: 0 1px 5px 0 $black-t0;
+ }
+
+ .navbar {
+ margin: 0 auto;
+ max-width: map-get($container-max-widths, xl);
+
+ .logo.slim a {
+ height: $baseline*3/2;
+ margin-top: $baseline/5;
+ }
+
+ .course-header {
+ font-size: $font-size-lg;
+ margin: $baseline/2 $baseline/2 0 0;
+
+ .provider {
+ font-weight: $font-weight-bold;
+ }
+ }
+
+ .nav-item {
+ margin: 0 $baseline 0 0;
+ font-weight: $font-weight-normal;
+ font-family: $font-family-base;
+ text-transform: uppercase;
+ list-style: none;
+
+ .nav-link {
+ color: $brand-primary;
+ }
+
+ .user-image-frame {
+ max-width: $baseline*2;
+ border-radius: $border-radius;
+ }
+
+ // Dealing with creating a collapsed menu
+ &.nav-item-open-collapsed-only {
+ display: none;
+ }
+
+ @media (max-width: map-get($grid-breakpoints,md)) {
+ &.nav-item-open-collapsed, &.nav-item-open-collapsed-only {
+ display: initial;
+ margin: $baseline/4 $baseline/2;
+
+ a {
+ color: $brand-primary;
+ padding: 0;
+ text-decoration: none;
+
+ &:hover {
+ color: $input-border-color;
+ }
+ }
+ }
+ &.nav-item-hidden-collapsed {
+ display: none;
+ }
+ }
+ }
+
+ .btn-shopping-cart{
+ padding-top: 0.7rem; // $btn-padding-y-lg once themed
+ }
+
+ .navbar-right .nav-item {
+ @media (min-width: map-get($grid-breakpoints,md)) {
+ .nav-link {
+ text-transform: none;
+ color: $brand-inverse;
+ font-weight: $font-weight-bold;
+ cursor: pointer;
+ }
+ }
+
+ &.dropdown {
+ cursor: pointer;
+
+ .dropdown-item {
+ text-transform: initial;
+ }
+ }
+ }
+ }
+}
diff --git a/cms/static/sass/bootstrap/_variables.scss b/cms/static/sass/bootstrap/_variables.scss
new file mode 100644
index 0000000000..617175a4f0
--- /dev/null
+++ b/cms/static/sass/bootstrap/_variables.scss
@@ -0,0 +1,71 @@
+// Studio - bootstrap utilities - variables
+// ========================================
+
+// #Units: Unit variables
+// #GRID: Grid and layout variables
+// #COLORS: Base, palette and theme color definitions + application
+// #TYPOGRAPHY: Font definitions and scales
+// #ICONS: Icon specific colors + other styling
+
+// ----------------------------
+// #UNITS
+// ----------------------------
+$baseline: 20px !default;
+
+// ----------------------------
+// #GRID
+// ----------------------------
+$studio-max-width: 1180px !default;
+
+// ----------------------------
+// #COLORS
+// ----------------------------
+
+$studio-gray: palette(grayscale, base) !default;
+$studio-background-color: palette(grayscale, x-back) !default;
+$studio-container-background-color: $white !default;
+$studio-border-color: palette(grayscale, back) !default;
+$studio-label-color: palette(grayscale, black) !default;
+$studio-active-color: palette(primary, base) !default;
+$studio-preview-menu-color: #c8c8c8 !default;
+$success-color: palette(success, accent) !default;
+$success-color-hover: palette(success, text) !default;
+
+$button-bg-hover-color: $white !default;
+
+$white-transparent: rgba(255, 255, 255, 0) !default;
+$white-opacity-40: rgba(255, 255, 255, 0.4) !default;
+$white-opacity-60: rgba(255, 255, 255, 0.6) !default;
+$white-opacity-70: rgba(255, 255, 255, 0.7) !default;
+$white-opacity-80: rgba(255, 255, 255, 0.8) !default;
+
+$black: rgb(0,0,0) !default;
+$black-t0: rgba($black, 0.125) !default;
+$black-t1: rgba($black, 0.25) !default;
+$black-t2: rgba($black, 0.5) !default;
+$black-t3: rgba($black, 0.75) !default;
+
+$light-grey-transparent: rgba(200,200,200, 0) !default;
+$light-grey-solid: rgba(200,200,200, 1) !default;
+
+$header-bg: $white !default;
+$footer-bg: $white !default;
+
+// ----------------------------
+// #TYPOGRAPHY
+// ----------------------------
+$font-light: 300 !default;
+$font-regular: 400 !default;
+$font-semibold: 600 !default;
+$font-bold: 700 !default;
+
+// ----------------------------
+// #ICONS
+// ----------------------------
+// Icons
+$studio-dark-icon-color: $white !default;
+$studio-dark-icon-background-color: palette(grayscale, black) !default;
+
+$site-status-color: rgb(182,37,103) !default;
+
+$shadow-l1: rgba(0,0,0,0.1) !default;
diff --git a/cms/static/sass/bootstrap/studio-main.scss b/cms/static/sass/bootstrap/studio-main.scss
new file mode 100644
index 0000000000..de32b0257a
--- /dev/null
+++ b/cms/static/sass/bootstrap/studio-main.scss
@@ -0,0 +1,19 @@
+// -----------------------------
+// Studio main styles for Bootstrap
+// -----------------------------
+
+// Bootstrap theme
+@import 'bootstrap/theme';
+@import 'bootstrap/scss/bootstrap';
+
+// Variables
+@import 'mixins';
+@import 'variables';
+@import 'base';
+
+// Elements
+@import 'header';
+@import 'footer';
+@import 'navigation';
+@import 'layouts';
+@import 'components';
diff --git a/cms/static/sass/partials/bootstrap/_theme.scss b/cms/static/sass/partials/bootstrap/_theme.scss
new file mode 100644
index 0000000000..af3ef13da3
--- /dev/null
+++ b/cms/static/sass/partials/bootstrap/_theme.scss
@@ -0,0 +1,5 @@
+// Default bootstrap theming
+
+$body-bg: #f5f5f5 !default;
+
+@import 'edx-bootstrap/sass/open-edx/theme';
diff --git a/cms/static/sass/partials/_variables.scss b/cms/static/sass/partials/cms/base/_variables.scss
similarity index 100%
rename from cms/static/sass/partials/_variables.scss
rename to cms/static/sass/partials/cms/base/_variables.scss
diff --git a/cms/templates/base.html b/cms/templates/base.html
index f987897112..8e24b21021 100644
--- a/cms/templates/base.html
+++ b/cms/templates/base.html
@@ -44,7 +44,11 @@ from openedx.core.djangolib.js_utils import (
<%static:css group='style-vendor-tinymce-content'/>
<%static:css group='style-vendor-tinymce-skin'/>
- <%static:css group='${self.attr.main_css}'/>
+ % if uses_bootstrap:
+
+ % else:
+ <%static:css group='${self.attr.main_css}'/>
+ % endif
<%include file="widgets/segment-io.html" />
diff --git a/cms/templates/ux/reference/_note-usage.html b/cms/templates/ux/reference/_note-usage.html
deleted file mode 100644
index 2a5ebab8f5..0000000000
--- a/cms/templates/ux/reference/_note-usage.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
diff --git a/cms/templates/ux/reference/bootstrap/test.html b/cms/templates/ux/reference/bootstrap/test.html
new file mode 100644
index 0000000000..311a85a132
--- /dev/null
+++ b/cms/templates/ux/reference/bootstrap/test.html
@@ -0,0 +1,408 @@
+## Override the default styles_version to use Bootstrap
+<%! main_css = "css/bootstrap/studio-main.css" %>
+
+<%page expression_filter="h"/>
+
+<%!
+from openedx.core.djangoapps.util.user_messages import (
+ register_error_message,
+ register_info_message,
+ register_success_message,
+ register_warning_message,
+)
+%>
+
+<%
+register_info_message(request, _('This is a test message'))
+%>
+
+<%inherit file="/base.html" />
+<%block name="title">Bootstrap Test Page%block>
+<%block name="bodyclass">bootstrap-test%block>
+
+<%block name="content">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Course Start Date:
+
Jan 01, 2015 at 00:00 UTC
+
+
+
+
+
+
+
Course Outline
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
+
+ Release Status:
+
+
+
+
+ Released:
+
+
+ Jan 01, 2015 at 00:00 UTC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
+
+ Release Status:
+
+
+
+
+ Released:
+
+
+ Jan 01, 2015 at 00:00 UTC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%block>
diff --git a/cms/templates/ux/reference/index.html b/cms/templates/ux/reference/index.html
index a39951ade0..022cdc33cb 100644
--- a/cms/templates/ux/reference/index.html
+++ b/cms/templates/ux/reference/index.html
@@ -1,35 +1,24 @@
-## Override the default styles_version to the Pattern Library version (version 2)
-<%! main_css = "style-main-v2" %>
+## Override the default styles_version to use Bootstrap
+<%! main_css = "css/bootstrap/studio-main.css" %>
<%page expression_filter="h"/>
+
<%inherit file="../../base.html" />
-<%block name="view_notes">
- <%include file="_note-usage.html" />
-%block>
-
<%block name="title">UX Style Reference%block>
-<%block name="bodyclass">is-signedin course uploads view-container%block>
+<%block name="bodyclass">ux-reference%block>
<%block name="content">
- UX Style Reference
+ UX Style Reference
-
- -
-
-
-
-
+
diff --git a/cms/templates/ux/reference/pattern-library-test.html b/cms/templates/ux/reference/pattern-library/test.html
similarity index 100%
rename from cms/templates/ux/reference/pattern-library-test.html
rename to cms/templates/ux/reference/pattern-library/test.html
diff --git a/lms/templates/ux/reference/index.html b/lms/templates/ux/reference/index.html
index a9d1b8de3b..1dd042c83c 100644
--- a/lms/templates/ux/reference/index.html
+++ b/lms/templates/ux/reference/index.html
@@ -1,5 +1,8 @@
## mako
+## Override the default styles_version to use Bootstrap
+<%! main_css = "css/bootstrap/lms-main.css" %>
+
<%page expression_filter="h"/>
<%inherit file="/main.html" />
diff --git a/openedx/core/djangoapps/debug/views.py b/openedx/core/djangoapps/debug/views.py
index 983ecda81a..81b26e51d5 100644
--- a/openedx/core/djangoapps/debug/views.py
+++ b/openedx/core/djangoapps/debug/views.py
@@ -28,16 +28,27 @@ def show_reference_template(request, template):
e.g. /template/ux/reference/index.html?name=Foo
"""
try:
- uses_bootstrap = u'/bootstrap/' in request.path
uses_pattern_library = u'/pattern-library/' in request.path
is_v1 = u'/v1/' in request.path
+ uses_bootstrap = not uses_pattern_library and not is_v1
context = {
- "disable_courseware_js": not is_v1,
- "uses_pattern_library": uses_pattern_library,
- "uses_bootstrap": uses_bootstrap,
+ 'request': request,
+ 'disable_courseware_js': not is_v1,
+ 'uses_pattern_library': uses_pattern_library,
+ 'uses_bootstrap': uses_bootstrap,
}
context.update(request.GET.dict())
+ # Support dynamic rendering of messages
+ if request.GET.get('alert'):
+ register_info_message(request, request.GET.get('alert'))
+ if request.GET.get('success'):
+ register_success_message(request, request.GET.get('success'))
+ if request.GET.get('warning'):
+ register_warning_message(request, request.GET.get('warning'))
+ if request.GET.get('error'):
+ register_error_message(request, request.GET.get('error'))
+
# Add some messages to the course skeleton pages
if u'course-skeleton.html' in request.path:
register_info_message(request, _('This is a test message'))
@@ -47,4 +58,4 @@ def show_reference_template(request, template):
return render_to_response(template, context)
except TopLevelLookupException:
- return HttpResponseNotFound("Couldn't find template {template}".format(template=template))
+ return HttpResponseNotFound('Missing template {template}'.format(template=template))
diff --git a/package.json b/package.json
index 7fe27ecf41..2b2c6fb228 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"backbone.paginator": "~2.0.3",
"coffee-loader": "^0.7.3",
"coffee-script": "1.6.1",
- "edx-bootstrap": "~0.1.6",
+ "edx-bootstrap": "~0.1.7",
"edx-pattern-library": "0.18.1",
"edx-ui-toolkit": "1.5.2",
"exports-loader": "^0.6.4",
diff --git a/themes/edge.edx.org/cms/static/sass/partials/bootstrap/_theme.scss b/themes/edge.edx.org/cms/static/sass/partials/bootstrap/_theme.scss
new file mode 100644
index 0000000000..a6fe8cb699
--- /dev/null
+++ b/themes/edge.edx.org/cms/static/sass/partials/bootstrap/_theme.scss
@@ -0,0 +1,5 @@
+// Override theming for edx.org bootstrap
+
+$body-bg: #f5f5f5 !default;
+
+@import 'edx-bootstrap/sass/edx/theme';
diff --git a/themes/edx.org/cms/static/sass/partials/bootstrap/_theme.scss b/themes/edx.org/cms/static/sass/partials/bootstrap/_theme.scss
new file mode 100644
index 0000000000..a6fe8cb699
--- /dev/null
+++ b/themes/edx.org/cms/static/sass/partials/bootstrap/_theme.scss
@@ -0,0 +1,5 @@
+// Override theming for edx.org bootstrap
+
+$body-bg: #f5f5f5 !default;
+
+@import 'edx-bootstrap/sass/edx/theme';
diff --git a/themes/red-theme/cms/static/images/favicon.ico b/themes/red-theme/cms/static/images/favicon.ico
new file mode 100644
index 0000000000..5e784977e6
Binary files /dev/null and b/themes/red-theme/cms/static/images/favicon.ico differ
diff --git a/themes/red-theme/cms/static/images/studio-logo.png b/themes/red-theme/cms/static/images/studio-logo.png
new file mode 100644
index 0000000000..85ea048de2
Binary files /dev/null and b/themes/red-theme/cms/static/images/studio-logo.png differ
diff --git a/themes/red-theme/lms/static/sass/partials/base/_variables.scss b/themes/red-theme/cms/static/sass/partials/base/_variables.scss
similarity index 100%
rename from themes/red-theme/lms/static/sass/partials/base/_variables.scss
rename to themes/red-theme/cms/static/sass/partials/base/_variables.scss
diff --git a/themes/red-theme/cms/static/sass/partials/bootstrap/_theme.scss b/themes/red-theme/cms/static/sass/partials/bootstrap/_theme.scss
new file mode 100644
index 0000000000..7fb5406954
--- /dev/null
+++ b/themes/red-theme/cms/static/sass/partials/bootstrap/_theme.scss
@@ -0,0 +1,13 @@
+// Sample red theme to demonstrate SASS overrides
+
+// Theme colors
+//
+// Note: define colors needed by your theme first
+$red: #d9534f !default;
+$brand-primary: $red;
+
+// Theme fonts
+$font-family-sans-serif: cursive;
+
+// Initialize the Open edX bootstrap theme
+@import 'edx-bootstrap/sass/open-edx/theme';
diff --git a/themes/red-theme/cms/static/sass/partials/cms/base/_variables.scss b/themes/red-theme/cms/static/sass/partials/cms/base/_variables.scss
new file mode 100755
index 0000000000..9a779f5e13
--- /dev/null
+++ b/themes/red-theme/cms/static/sass/partials/cms/base/_variables.scss
@@ -0,0 +1,14 @@
+// Color overrides
+$white: rgb(255,255,255);
+$red: #d9534f !default;
+
+$footer-bg: $white;
+$header-bg: $white;
+$header-border-color: $red;
+
+$base-font-color: $red;
+$link-color: $red;
+$lms-active-color: $red;
+$lms-label-color: $red;
+
+@import 'cms/static/sass/partials/cms/base/variables';