Completed assembly instructions, redone navbar, made blockly use new navbar
authorNick Downing <nick.downing@lifx.co>
Wed, 18 Mar 2020 16:39:36 +0000 (03:39 +1100)
committerNick Downing <nick.downing@lifx.co>
Wed, 18 Mar 2020 16:44:56 +0000 (03:44 +1100)
53 files changed:
_config/globals.json
assembly_instructions/a_axis_assembly.html.jst [new file with mode: 0644]
assembly_instructions/b_axis_assembly.html.jst [new file with mode: 0644]
assembly_instructions/base_assembly.html.jst [new file with mode: 0644]
assembly_instructions/c_axis_assembly.html.jst [new file with mode: 0644]
assembly_instructions/components_list.html.jst [moved from construction_zero.html.jst with 65% similarity]
assembly_instructions/d_e_axis_assembly.html.jst [new file with mode: 0644]
assembly_instructions/gripper_assembly.html.jst [new file with mode: 0644]
assembly_instructions/tapping_threads.html.jst [new file with mode: 0644]
blockly.html.jst
css/bootstrap-navbar-sidebar/aaa/navbar-fixed-left.less [new file with mode: 0644]
css/bootstrap-navbar-sidebar/aaa/navbar-fixed-right.less [new file with mode: 0644]
css/bootstrap-navbar-sidebar/aaa/navbar-fixed.less [new file with mode: 0644]
css/bootstrap-navbar-sidebar/aaa/variables.less [new file with mode: 0644]
css/bootstrap-navbar-sidebar/navbar-fixed-left.less [new file with mode: 0644]
css/bootstrap-navbar-sidebar/navbar-fixed-right.less [new file with mode: 0644]
css/bootstrap-navbar-sidebar/navbar-fixed.less [new file with mode: 0644]
css/bootstrap-navbar-sidebar/variables.less [new file with mode: 0644]
css/bootstrap.css.less
css/bootstrap/custom.less
css/bootstrap/navbar.less
css/bootstrap/variables.less
css/mixins/alerts.less [deleted file]
css/mixins/background-variant.less [deleted file]
css/mixins/border-radius.less [deleted file]
css/mixins/buttons.less [deleted file]
css/mixins/center-block.less [deleted file]
css/mixins/clearfix.less [deleted file]
css/mixins/forms.less [deleted file]
css/mixins/gradients.less [deleted file]
css/mixins/grid-framework.less [deleted file]
css/mixins/grid.less [deleted file]
css/mixins/hide-text.less [deleted file]
css/mixins/image.less [deleted file]
css/mixins/labels.less [deleted file]
css/mixins/list-group.less [deleted file]
css/mixins/nav-divider.less [deleted file]
css/mixins/nav-vertical-align.less [deleted file]
css/mixins/opacity.less [deleted file]
css/mixins/pagination.less [deleted file]
css/mixins/panels.less [deleted file]
css/mixins/progress-bar.less [deleted file]
css/mixins/reset-filter.less [deleted file]
css/mixins/reset-text.less [deleted file]
css/mixins/resize.less [deleted file]
css/mixins/responsive-visibility.less [deleted file]
css/mixins/size.less [deleted file]
css/mixins/tab-focus.less [deleted file]
css/mixins/table-row.less [deleted file]
css/mixins/text-emphasis.less [deleted file]
css/mixins/text-overflow.less [deleted file]
css/mixins/vendor-prefixes.less [deleted file]
navbar.jst

index 1ae082a..2de83b0 100644 (file)
@@ -4,18 +4,40 @@
     "/index.html",
     "/assembly_instructions/parts_list.html",
     "/assembly_instructions/overview.html",
-    "/construction_zero.html",
+    "/assembly_instructions/tapping_threads.html",
+    "/assembly_instructions/components_list.html",
+    "/assembly_instructions/base_assembly.html",
+    "/assembly_instructions/a_axis_assembly.html",
+    "/assembly_instructions/b_axis_assembly.html",
+    "/assembly_instructions/c_axis_assembly.html",
+    "/assembly_instructions/d_e_axis_assembly.html",
+    "/assembly_instructions/gripper_assembly.html",
     "/blockly.html"
   ],
   "page_to_title": {
     "/index.html": "Home",
     "/assembly_instructions/parts_list.html": "Parts List",
     "/assembly_instructions/overview.html": "Overview",
-    "/construction_zero.html": "Construction Zero",
+    "/assembly_instructions/tapping_threads.html": "Tapping Threads",
+    "/assembly_instructions/components_list.html": "Components List",
+    "/assembly_instructions/base_assembly.html": "Base Assembly",
+    "/assembly_instructions/a_axis_assembly.html": "A-Axis Assembly",
+    "/assembly_instructions/b_axis_assembly.html": "B-Axis Assembly",
+    "/assembly_instructions/c_axis_assembly.html": "C-Axis Assembly",
+    "/assembly_instructions/d_e_axis_assembly.html": "D & E-Axis Assembly",
+    "/assembly_instructions/gripper_assembly.html": "Gripper Assembly",
     "/blockly.html": "Blockly"
   },
   "page_to_breadcrumbs": {
     "/assembly_instructions/parts_list.html": "Assembly Instructions > Parts List",
-    "/assembly_instructions/overview.html": "Assembly Instructions > Overview"
+    "/assembly_instructions/overview.html": "Assembly Instructions > Overview",
+    "/assembly_instructions/tapping_threads.html": "Assembly Instructions > Tapping Threads",
+    "/assembly_instructions/components_list.html": "Assembly Instructions > Components List",
+    "/assembly_instructions/base_assembly.html": "Assembly Instructions > Base Assembly",
+    "/assembly_instructions/a_axis_assembly.html": "Assembly Instructions > A-Axis Assembly",
+    "/assembly_instructions/b_axis_assembly.html": "Assembly Instructions > B-Axis Assembly",
+    "/assembly_instructions/c_axis_assembly.html": "Assembly Instructions > C-Axis Assembly",
+    "/assembly_instructions/d_e_axis_assembly.html": "Assembly Instructions > d & E-Axis Assembly",
+    "/assembly_instructions/gripper_assembly.html": "Assembly Instructions > Gripper Assembly"
   }
 }
diff --git a/assembly_instructions/a_axis_assembly.html.jst b/assembly_instructions/a_axis_assembly.html.jst
new file mode 100644 (file)
index 0000000..590e68e
--- /dev/null
@@ -0,0 +1,27 @@
+return async env => {
+  let navbar = await _require('/navbar.jst')
+  let page11 = await env.site.get_min_svg('/_svg/page11.svg')
+  let page12 = await env.site.get_min_svg('/_svg/page12.svg')
+  let page13 = await env.site.get_min_svg('/_svg/page13.svg')
+
+  await navbar(
+    env,
+    // head
+    async _out => {},
+    // body
+    async _out => {
+      h1 {'A-Axis Assembly'}
+
+      h3 {'Components Required'}
+      _out.push(page12)
+
+      h3 {'Before'}
+      _out.push(page13)
+
+      h3 {'After'}
+      _out.push(page11)
+    },
+    // scripts
+    async _out => {}
+  )
+}
diff --git a/assembly_instructions/b_axis_assembly.html.jst b/assembly_instructions/b_axis_assembly.html.jst
new file mode 100644 (file)
index 0000000..888ca46
--- /dev/null
@@ -0,0 +1,26 @@
+return async env => {
+  let navbar = await _require('/navbar.jst')
+  let page14 = await env.site.get_min_svg('/_svg/page14.svg')
+  let page15 = await env.site.get_min_svg('/_svg/page15.svg')
+  let page16 = await env.site.get_min_svg('/_svg/page16.svg')
+
+  await navbar(
+    env,
+    // head
+    async _out => {},
+    // body
+    async _out => {
+      h1 {'B-Axis Assembly'}
+
+      h3 {'Components Required'}
+      _out.push(page15)
+
+      h3 {'Before'}
+      _out.push(page16)
+      h3 {'After'}
+      _out.push(page14)
+    },
+    // scripts
+    async _out => {}
+  )
+}
diff --git a/assembly_instructions/base_assembly.html.jst b/assembly_instructions/base_assembly.html.jst
new file mode 100644 (file)
index 0000000..d8235ee
--- /dev/null
@@ -0,0 +1,27 @@
+return async env => {
+  let navbar = await _require('/navbar.jst')
+  let page8 = await env.site.get_min_svg('/_svg/page8.svg')
+  let page9 = await env.site.get_min_svg('/_svg/page9.svg')
+  let page10 = await env.site.get_min_svg('/_svg/page10.svg')
+
+  await navbar(
+    env,
+    // head
+    async _out => {},
+    // body
+    async _out => {
+      h1 {'Base Assembly'}
+
+      h3 {'Components Required'}
+      _out.push(page9)
+
+      h3 {'Before'}
+      _out.push(page10)
+
+      h3 {'After'}
+      _out.push(page8)
+    },
+    // scripts
+    async _out => {}
+  )
+}
diff --git a/assembly_instructions/c_axis_assembly.html.jst b/assembly_instructions/c_axis_assembly.html.jst
new file mode 100644 (file)
index 0000000..1a453e2
--- /dev/null
@@ -0,0 +1,27 @@
+return async env => {
+  let navbar = await _require('/navbar.jst')
+  let page17 = await env.site.get_min_svg('/_svg/page17.svg')
+  let page18 = await env.site.get_min_svg('/_svg/page18.svg')
+  let page19 = await env.site.get_min_svg('/_svg/page19.svg')
+
+  await navbar(
+    env,
+    // head
+    async _out => {},
+    // body
+    async _out => {
+      h1 {'C-Axis Assembly'}
+
+      h3 {'Components Required'}
+      _out.push(page18)
+
+      h3 {'Before'}
+      _out.push(page19)
+
+      h3 {'After'}
+      _out.push(page17)
+    },
+    // scripts
+    async _out => {}
+  )
+}
similarity index 65%
rename from construction_zero.html.jst
rename to assembly_instructions/components_list.html.jst
index b0e7d7a..1b6a829 100644 (file)
@@ -1,5 +1,6 @@
 return async env => {
   let navbar = await _require('/navbar.jst')
+  let page7 = await env.site.get_min_svg('/_svg/page7.svg')
 
   await navbar(
     env,
@@ -7,7 +8,8 @@ return async env => {
     async _out => {},
     // body
     async _out => {
-      h1 {'Construction Zero'}
+      h1 {'Components List'}
+      _out.push(page7)
     },
     // scripts
     async _out => {}
diff --git a/assembly_instructions/d_e_axis_assembly.html.jst b/assembly_instructions/d_e_axis_assembly.html.jst
new file mode 100644 (file)
index 0000000..38cc5f1
--- /dev/null
@@ -0,0 +1,27 @@
+return async env => {
+  let navbar = await _require('/navbar.jst')
+  let page20 = await env.site.get_min_svg('/_svg/page20.svg')
+  let page21 = await env.site.get_min_svg('/_svg/page21.svg')
+  let page22 = await env.site.get_min_svg('/_svg/page22.svg')
+
+  await navbar(
+    env,
+    // head
+    async _out => {},
+    // body
+    async _out => {
+      h1 {'D & E-Axis Assembly'}
+
+      h3 {'Components Required'}
+      _out.push(page21)
+
+      h3 {'Before'}
+      _out.push(page22)
+
+      h3 {'After'}
+      _out.push(page20)
+    },
+    // scripts
+    async _out => {}
+  )
+}
diff --git a/assembly_instructions/gripper_assembly.html.jst b/assembly_instructions/gripper_assembly.html.jst
new file mode 100644 (file)
index 0000000..232797a
--- /dev/null
@@ -0,0 +1,17 @@
+return async env => {
+  let navbar = await _require('/navbar.jst')
+  let page23 = await env.site.get_min_svg('/_svg/page23.svg')
+
+  await navbar(
+    env,
+    // head
+    async _out => {},
+    // body
+    async _out => {
+      h1 {'Gripper Assembly'}
+      _out.push(page23)
+    },
+    // scripts
+    async _out => {}
+  )
+}
diff --git a/assembly_instructions/tapping_threads.html.jst b/assembly_instructions/tapping_threads.html.jst
new file mode 100644 (file)
index 0000000..b74cb32
--- /dev/null
@@ -0,0 +1,34 @@
+return async env => {
+  let navbar = await _require('/navbar.jst')
+  let page5 = await env.site.get_min_svg('/_svg/page5.svg')
+  let page6 = await env.site.get_min_svg('/_svg/page6.svg')
+
+  await navbar(
+    env,
+    // head
+    async _out => {},
+    // body
+    async _out => {
+      h1 {'Tapping Threads'}
+      p {'You will need to produce threads in some of the Laser Cut parts.'}
+      p {'For example, a M3 x 0.5mm tap has a 3mm outside diameter with a distance between threads (pitch) of 0.5mm. We suggest using Gun Taps.'}
+
+      h4 {'Required Taps'}
+      'M3 X 0.5mm'
+      br {}
+      'M4 X 0.7mm'
+
+      h4 {'Tap Wrench / Holder'}
+      p {'In order to use a Tap, you will need something to hold it. You can buy Tap Wrenches from Engineering Suppliers or sometimes even hardware stores. If you don\'t want to buy a Tap Wrench we have provided a set of 3D printable files of very simple plastic Tap Holders, which are not as versatile as a commercial unit but will still do the job.'}
+
+      h4 {'Using a Tap'}
+      p {'To use a tap, choose one that is appropriate for the size of the bolt or the hole you want to thread. Place the tap into the Tap wrench or Holder and tighten it if required. Place the point of the Tap into the hole, making sure the Tap is square to the work. Whilst turning the Tap apply GENTLE pressure until the Tap begins to cut the thread and winds itself into the hole without pressure.'}
+      _out.push(page5)
+
+     h3 {'C1, C2, A1, A2'}
+     _out.push(page6)
+    },
+    // scripts
+    async _out => {}
+  )
+}
index 009b24f..1109a2c 100644 (file)
@@ -1,7 +1,7 @@
 return async env => {
-  let page = await _require('page.jst')
+  let navbar = await _require('navbar.jst')
 
-  await page(
+  await navbar(
     env,
     // head
     async _out => {
@@ -15,36 +15,50 @@ return async env => {
           value(name="A") {
             shadow(type="math_number") {
               field#toolboxA(name="NUM") {
-                '90'
+                '0'
               }
             }
           }
           value(name="B") {
             shadow(type="math_number") {
               field#toolboxB(name="NUM") {
-                '90'
+                '0'
               }
             }
           }
           value(name="C") {
             shadow(type="math_number") {
               field#toolboxC(name="NUM") {
-                '90'
+                '0'
               }
             }
           }
-        }
-        block(type="gripper") {
           value(name="D") {
             shadow(type="math_number") {
               field#toolboxD(name="NUM") {
-                '90'
+                '0'
+              }
+            }
+          }
+          value(name="E") {
+            shadow(type="math_number") {
+              field#toolboxE(name="NUM") {
+                '0'
+              }
+            }
+          }
+        }
+        block(type="gripper") {
+          value(name="F") {
+            shadow(type="math_number") {
+              field#toolboxF(name="NUM") {
+                '0'
               }
             }
           }
         }
         block(type="delay") {
-          value(name="millisec") {
+          value(name="millisecs") {
             shadow(type="math_number") {
               field(name="NUM") {
                 '1000'
@@ -110,105 +124,22 @@ return async env => {
     },
     // body
     async _out => {
-      div.container-fluid {
-        div.row(style="margin-top: 10px; margin-bottom: 0px;") {
-          div.col-md-3 {
-            h2(style="margin-top: 0px;") {
-              'MiRobot Demonstration'
-            }
-          }
-          div.col-md-5(style="text-align: right;") {
-            div.form-group.form-inline {
-              label(style="margin-right: 6px;") {
-                'Connected device:'
-              }
-              div.input-group {
-                input.form-control#connected-device(type="text" readonly="true") {}
-                span.input-group-btn { //div.input-group-append {
-                  button.btn.btn-outline-secondary#connect(type="button") {
-                    'Connect'
-                  }
-                }
-              }
-            }
-          }
-          div.col-md-2(style="text-align: right;") {
-            button.btn#home(type="button" style="width: 50%;") {
-              'Home'
-            }
-          }
-          div.col-md-2(style="text-align: right;") {
-            button.btn#run(type="button" style="width: 50%;") {
-              'Run'
-            }
-          }
-        }
-        div.row(style="margin-top: 0px; margin-bottom: 0px;") {
-          div.col-md-2(style="text-align: right;") {
-            div.form-group.form-inline {
-              label(style="margin-right: 6px;") {
-                'A:'
-              }
-              input.form-control#A(type="number" value="90" min="0" max="360" step="5" style="width: 50%;") {}
-            }
-          }
-          div.col-md-2(style="text-align: right;") {
-            div.form-group.form-inline {
-              label(style="margin-right: 6px;") {
-                'B:'
-              }
-              input.form-control#B(type="number" value="90" min="0" max="360" step="5" style="width: 50%;") {}
-            }
-          }
-          div.col-md-2(style="text-align: right;") {
-            div.form-group.form-inline {
-              label(style="margin-right: 6px;") {
-                'C:'
-              }
-              input.form-control#C(type="number" value="90" min="0" max="360" step="5" style="width: 50%;") {}
-            }
-          }
-          div.col-md-2(style="text-align: right;") {
-            div.form-group.form-inline {
-              label(style="margin-right: 6px;") {
-                'D:'
-              }
-              input.form-control#D(type="number" value="90" min="0" max="360" step="5" style="width: 50%;") {}
-            }
-          }
-          div.col-md-2(style="text-align: right;") {
-            div.form-group.form-inline {
-              label(style="margin-right: 6px;") {
-                'E:'
-              }
-              input.form-control#E(type="number" value="90" min="0" max="360" step="5" style="width: 50%;") {}
-            }
-          }
-          div.col-md-2(style="text-align: right;") {
-            div.form-group.form-inline {
-              label(style="margin-right: 6px;") {
-                'F:'
-              }
-              input.form-control#F(type="number" value="90" min="0" max="360" step="5" style="width: 50%;") {}
-            }
-          }
-        }
-        div.row(style="margin-top: 0px; margin-bottom: 0px;") {
-          div.col-md-12 {
-            div#blocklyArea(style="height: 525px;") {}
-          }
-        }
-      }
+      div#blocklyArea(style="height: 750px;") {}
       div#blocklyDiv(style="position: absolute;") {}
+    },
+    // scripts
+    async _out => {
       script {
         Blockly.defineBlocksWithJsonArray([
           {
             "type": "move_to",
-            "message0": "move to A %1 B %2 C %3",
+            "message0": "move to A %1 B %2 C %3 D %4 E %5",
             "args0": [
                {"type": "input_value", "name": "A", "check": "Number"},
                {"type": "input_value", "name": "B", "check": "Number"},
                {"type": "input_value", "name": "C", "check": "Number"},
+               {"type": "input_value", "name": "D", "check": "Number"},
+               {"type": "input_value", "name": "E", "check": "Number"}
             ],
             "inputsInline": true,
             "previousStatement": null,
@@ -219,7 +150,7 @@ return async env => {
             "type": "gripper",
             "message0": "gripper %1",
             "args0": [
-               {"type": "input_value", "name": "D", "check": "Number"},
+               {"type": "input_value", "name": "F", "check": "Number"},
             ],
             "inputsInline": true,
             "previousStatement": null,
@@ -248,11 +179,15 @@ return async env => {
               Blockly.JavaScript.ORDER_COMMA) || '0';
           var c = Blockly.JavaScript.valueToCode(block, 'C',
               Blockly.JavaScript.ORDER_COMMA) || '0';
+          var c = Blockly.JavaScript.valueToCode(block, 'D',
+              Blockly.JavaScript.ORDER_COMMA) || '0';
+          var c = Blockly.JavaScript.valueToCode(block, 'E',
+              Blockly.JavaScript.ORDER_COMMA) || '0';
           return 'await deviceMoveTo(' + a + ', ' + b + ', ' + c + ');\n'
         };
 
         Blockly.JavaScript['gripper'] = function(block) {
-          var d = Blockly.JavaScript.valueToCode(block, 'D',
+          var d = Blockly.JavaScript.valueToCode(block, 'F',
               Blockly.JavaScript.ORDER_COMMA) || '0';
           return 'await deviceGripper(' + d + ');\n'
         };
@@ -616,8 +551,6 @@ return async env => {
           }
         );
       }
-    },
-    // scripts
-    async _out => {}
+    }
   )
 }
diff --git a/css/bootstrap-navbar-sidebar/aaa/navbar-fixed-left.less b/css/bootstrap-navbar-sidebar/aaa/navbar-fixed-left.less
new file mode 100644 (file)
index 0000000..6726574
--- /dev/null
@@ -0,0 +1,34 @@
+@import "navbar-fixed";
+
+body {
+  //@include media-breakpoint-up($navbar-sidebar-breakpoint) {
+    margin-left: $navbar-sidebar-width;
+  //}
+}
+
+.navbar {
+  &.fixed-left {
+    @include navbar-sidebar;
+    //@include media-breakpoint-up($navbar-sidebar-breakpoint) {
+      right: auto;
+
+      .navbar-nav {
+        .nav-item {
+          .dropdown-toggle {
+            &:after {
+              border-top: $caret-width solid transparent;
+              border-left: $caret-width solid;
+              border-bottom: $caret-width solid transparent;
+              border-right: none;
+              vertical-align: baseline;
+            }
+          }
+
+          .dropdown-menu {
+            left: 100%;
+          }
+        }
+      }
+    //}
+  }
+}
diff --git a/css/bootstrap-navbar-sidebar/aaa/navbar-fixed-right.less b/css/bootstrap-navbar-sidebar/aaa/navbar-fixed-right.less
new file mode 100644 (file)
index 0000000..706d34c
--- /dev/null
@@ -0,0 +1,35 @@
+@import "navbar-fixed";
+
+body {
+  @include media-breakpoint-up($navbar-sidebar-breakpoint) {
+    margin-right: $navbar-sidebar-width;
+  }
+}
+
+.navbar {
+  &.fixed-right {
+    @include navbar-sidebar;
+    @include media-breakpoint-up($navbar-sidebar-breakpoint) {
+      left: auto;
+
+      .navbar-nav {
+        .nav-item {
+          .dropdown-toggle {
+            &:after {
+              border-top: $caret-width solid transparent;
+              border-left: none;
+              border-bottom: $caret-width solid transparent;
+              border-right: $caret-width solid;
+              vertical-align: baseline;
+            }
+          }
+
+          .dropdown-menu {
+            left: auto;
+            right: 100%;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/css/bootstrap-navbar-sidebar/aaa/navbar-fixed.less b/css/bootstrap-navbar-sidebar/aaa/navbar-fixed.less
new file mode 100644 (file)
index 0000000..b055678
--- /dev/null
@@ -0,0 +1,44 @@
+@import "variables";
+//@import "../node_modules/bootstrap/scss/mixins/breakpoints";
+
+body {
+  //padding-top: 90px;
+
+  //@include media-breakpoint-up($navbar-sidebar-breakpoint) {
+    padding-top: 0;
+  //}
+}
+
+@mixin navbar-sidebar {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  //z-index: $zindex-fixed;
+
+  //@include media-breakpoint-up($navbar-sidebar-breakpoint) {
+    bottom: 0;
+    width: $navbar-sidebar-width;
+    flex-flow: column nowrap;
+    align-items: flex-start;
+
+    .navbar-collapse {
+      flex-grow: 0;
+      flex-direction: column;
+      width: 100%;
+
+      .navbar-nav {
+        flex-direction: column;
+        width: 100%;
+
+        .nav-item {
+          width: 100%;
+
+          .dropdown-menu {
+            top: 0;
+          }
+        }
+      }
+    }
+  //}
+}
diff --git a/css/bootstrap-navbar-sidebar/aaa/variables.less b/css/bootstrap-navbar-sidebar/aaa/variables.less
new file mode 100644 (file)
index 0000000..fbaf679
--- /dev/null
@@ -0,0 +1,5 @@
+@import "../node_modules/bootstrap/scss/functions";
+@import "../node_modules/bootstrap/scss/variables";
+
+$navbar-sidebar-width: 232px;
+$navbar-sidebar-breakpoint: 'md';
diff --git a/css/bootstrap-navbar-sidebar/navbar-fixed-left.less b/css/bootstrap-navbar-sidebar/navbar-fixed-left.less
new file mode 100644 (file)
index 0000000..1884690
--- /dev/null
@@ -0,0 +1,34 @@
+@import "navbar-fixed";
+
+body {
+  @media(min-width: @navbar-sidebar-breakpoint) {
+    margin-left: @navbar-sidebar-width;
+  }
+}
+
+.navbar {
+  &.fixed-left {
+    .navbar-sidebar; //@include navbar-sidebar;
+    @media (min-width: @navbar-sidebar-breakpoint) {
+      right: auto;
+
+      .navbar-nav {
+        .nav-item {
+          .dropdown-toggle {
+            &:after {
+              border-top: @caret-width solid transparent;
+              border-left: @caret-width solid;
+              border-bottom: @caret-width solid transparent;
+              border-right: none;
+              vertical-align: baseline;
+            }
+          }
+
+          .dropdown-menu {
+            left: 100%;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/css/bootstrap-navbar-sidebar/navbar-fixed-right.less b/css/bootstrap-navbar-sidebar/navbar-fixed-right.less
new file mode 100644 (file)
index 0000000..afafb7b
--- /dev/null
@@ -0,0 +1,35 @@
+@import "navbar-fixed";
+
+body {
+  @include media-breakpoint-up(@navbar-sidebar-breakpoint) {
+    margin-right: @navbar-sidebar-width;
+  }
+}
+
+.navbar {
+  &.fixed-right {
+    @include navbar-sidebar;
+    @include media-breakpoint-up(@navbar-sidebar-breakpoint) {
+      left: auto;
+
+      .navbar-nav {
+        .nav-item {
+          .dropdown-toggle {
+            &:after {
+              border-top: @caret-width solid transparent;
+              border-left: none;
+              border-bottom: @caret-width solid transparent;
+              border-right: @caret-width solid;
+              vertical-align: baseline;
+            }
+          }
+
+          .dropdown-menu {
+            left: auto;
+            right: 100%;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/css/bootstrap-navbar-sidebar/navbar-fixed.less b/css/bootstrap-navbar-sidebar/navbar-fixed.less
new file mode 100644 (file)
index 0000000..09e5c5d
--- /dev/null
@@ -0,0 +1,45 @@
+@import "variables";
+//@import "../node_modules/bootstrap/scss/mixins/breakpoints";
+@zindex-fixed: @zindex-navbar-fixed;
+
+body {
+  padding-top: 90px;
+
+  @media(min-width: @navbar-sidebar-breakpoint) {
+    padding-top: 0;
+  }
+}
+
+.navbar-sidebar { //@mixin navbar-sidebar {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: @zindex-fixed;
+
+  @media(min-width: @navbar-sidebar-breakpoint) {
+    bottom: 0;
+    width: @navbar-sidebar-width;
+    flex-flow: column nowrap;
+    align-items: flex-start;
+
+    .navbar-collapse {
+      flex-grow: 0;
+      flex-direction: column;
+      width: 100%;
+
+      .navbar-nav {
+        flex-direction: column;
+        width: 100%;
+
+        .nav-item {
+          width: 100%;
+
+          .dropdown-menu {
+            top: 0;
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/css/bootstrap-navbar-sidebar/variables.less b/css/bootstrap-navbar-sidebar/variables.less
new file mode 100644 (file)
index 0000000..ed82036
--- /dev/null
@@ -0,0 +1,7 @@
+//@import "../node_modules/bootstrap/scss/functions";
+//@import "../node_modules/bootstrap/scss/variables";
+@import "../bootstrap/variables";
+@caret-width: @caret-width-base;
+
+@navbar-sidebar-width: 360px; //232px;
+@navbar-sidebar-breakpoint: @screen-md-min; //'md';
index 34f687d..383ca4f 100644 (file)
@@ -57,3 +57,4 @@
 
 // Nick
 @import "bootstrap/custom.less";
+@import "bootstrap-navbar-sidebar/navbar-fixed-left.less";
index b132bae..eca9ea4 100644 (file)
 }
 
 .mirobot-control {
-  margin-top: 10px;
-  margin-bottom: 10px;
-}
-
-.left-pane {
-  background: #eee;
+  > .row {
+    margin-top: 5px;
+    margin-bottom: 5px;
+  }
 }
 
 .footer {
   padding-top: 8px;
   padding-bottom: 8px;
 }
-
-.pad-16 {
-  padding-top: 16px;
-  padding-bottom: 16px;
-}
-
-.no-margin {
-  padding-top: 0px;
-  padding-bottom: 0px;
-  margin-top: 0px;
-  margin-bottom: 0px;
-} 
index da95e37..1e05f23 100644 (file)
   position: relative;
   min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)
   margin-bottom: @navbar-margin-bottom;
-  border: 1px solid transparent;
+  border: 0; // Nick 1px solid transparent;
 
   // Prevent floats from breaking the navbar
   &:extend(.clearfix all);
 
   @media (min-width: @grid-float-breakpoint) {
-    border-radius: @navbar-border-radius;
+    border-radius: 0; // Nick @navbar-border-radius;
   }
 }
 
   .navbar-vertical-align(34px);
   background-color: transparent;
   background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
-  border: 1px solid transparent;
-  border-radius: @border-radius-base;
+  border: 0; // Nick 1px solid transparent;
+  border-radius: 0; // Nick @border-radius-base;
 
   // We remove the `outline` here, but later compensate by attaching `:hover`
   // styles to `:focus`.
     display: block;
     width: 22px;
     height: 2px;
-    border-radius: 1px;
+    border-radius: 0; // Nick 1px;
   }
   .icon-bar + .icon-bar {
     margin-top: 4px;
 // Menu position and menu caret support for dropups via extra dropup class
 .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
   margin-bottom: 0;
-  .border-top-radius(@navbar-border-radius);
+  .border-top-radius(0); // Nick @navbar-border-radius);
   .border-bottom-radius(0);
 }
 
index caf1df9..48270b5 100644 (file)
@@ -14,8 +14,8 @@
 @gray-light:             lighten(@gray-base, 46.7%); // #777
 @gray-lighter:           lighten(@gray-base, 93.5%); // #eee
 
-@brand-primary:         #0a0; // Nick darken(#428bca, 6.5%); // #337ab7
-@brand-success:         #ff8000; // Nick #5cb85c;
+@brand-primary:         #337ab7; //#0a0; // Nick darken(#428bca, 6.5%); // #337ab7
+@brand-success:         #5cb85c; //#ff8000; // Nick #5cb85c;
 @brand-info:            #5bc0de;
 @brand-warning:         #f0ad4e;
 @brand-danger:          #d9534f;
 
 // Basics of a navbar
 @navbar-height:                    50px;
-@navbar-margin-bottom:             @line-height-computed;
-@navbar-border-radius:             0; // Nick @border-radius-base;
-@navbar-padding-horizontal:        0; // Nick floor((@grid-gutter-width / 2));
-@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);
+@navbar-margin-bottom:             0; //@line-height-computed;
+@navbar-border-radius:             @border-radius-base;
+@navbar-padding-horizontal:        0; //floor((@grid-gutter-width / 2));
+@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 8); // Nick 2);
 @navbar-collapse-max-height:       340px;
 
-@navbar-default-color:             #fff; // Nick #777;
-@navbar-default-bg:                #0a0; // Nick #f8f8f8;
+@navbar-default-color:             #000; //#fff; // Nick #777;
+@navbar-default-bg:                #eee; //#0a0; // Nick #f8f8f8;
 @navbar-default-border:            darken(@navbar-default-bg, 6.5%);
 
 // Navbar links
-@navbar-default-link-color:                #fff; // Nick #777;
-@navbar-default-link-hover-color:          #000; // Nick #333;
+@navbar-default-link-color:                #000; //#fff; // Nick #777;
+@navbar-default-link-hover-color:          #333; //#000; // Nick #333;
 @navbar-default-link-hover-bg:             #ccc; // Nick transparent;
 @navbar-default-link-active-color:         #fff; // Nick #555;
-@navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);
+@navbar-default-link-active-bg:            #ccc; //darken(@navbar-default-bg, 6.5%);
 @navbar-default-link-disabled-color:       #ccc;
 @navbar-default-link-disabled-bg:          transparent;
 
diff --git a/css/mixins/alerts.less b/css/mixins/alerts.less
deleted file mode 100644 (file)
index 396196f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Alerts
-
-.alert-variant(@background; @border; @text-color) {
-  background-color: @background;
-  border-color: @border;
-  color: @text-color;
-
-  hr {
-    border-top-color: darken(@border, 5%);
-  }
-  .alert-link {
-    color: darken(@text-color, 10%);
-  }
-}
diff --git a/css/mixins/background-variant.less b/css/mixins/background-variant.less
deleted file mode 100644 (file)
index a85c22b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// Contextual backgrounds
-
-.bg-variant(@color) {
-  background-color: @color;
-  a&:hover,
-  a&:focus {
-    background-color: darken(@color, 10%);
-  }
-}
diff --git a/css/mixins/border-radius.less b/css/mixins/border-radius.less
deleted file mode 100644 (file)
index ca05dbf..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Single side border-radius
-
-.border-top-radius(@radius) {
-  border-top-right-radius: @radius;
-   border-top-left-radius: @radius;
-}
-.border-right-radius(@radius) {
-  border-bottom-right-radius: @radius;
-     border-top-right-radius: @radius;
-}
-.border-bottom-radius(@radius) {
-  border-bottom-right-radius: @radius;
-   border-bottom-left-radius: @radius;
-}
-.border-left-radius(@radius) {
-  border-bottom-left-radius: @radius;
-     border-top-left-radius: @radius;
-}
diff --git a/css/mixins/buttons.less b/css/mixins/buttons.less
deleted file mode 100644 (file)
index b294d8c..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// Button variants
-//
-// Easily pump out default styles, as well as :hover, :focus, :active,
-// and disabled options for all buttons
-
-.button-variant(@color; @background; @border) {
-  color: @color;
-  background-color: @background;
-  border-color: @border;
-
-  &:focus,
-  &.focus {
-    color: @color;
-    background-color: darken(@background, 10%);
-        border-color: darken(@border, 25%);
-  }
-  &:hover {
-    color: @color;
-    background-color: darken(@background, 10%);
-        border-color: darken(@border, 12%);
-  }
-  &:active,
-  &.active,
-  .open > .dropdown-toggle& {
-    color: @color;
-    background-color: darken(@background, 10%);
-        border-color: darken(@border, 12%);
-
-    &:hover,
-    &:focus,
-    &.focus {
-      color: @color;
-      background-color: darken(@background, 17%);
-          border-color: darken(@border, 25%);
-    }
-  }
-  &:active,
-  &.active,
-  .open > .dropdown-toggle& {
-    background-image: none;
-  }
-  &.disabled,
-  &[disabled],
-  fieldset[disabled] & {
-    &:hover,
-    &:focus,
-    &.focus {
-      background-color: @background;
-          border-color: @border;
-    }
-  }
-
-  .badge {
-    color: @background;
-    background-color: @color;
-  }
-}
-
-// Button sizes
-.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
-  padding: @padding-vertical @padding-horizontal;
-  font-size: @font-size;
-  line-height: @line-height;
-  border-radius: @border-radius;
-}
diff --git a/css/mixins/center-block.less b/css/mixins/center-block.less
deleted file mode 100644 (file)
index d18d6de..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// Center-align a block level element
-
-.center-block() {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-}
diff --git a/css/mixins/clearfix.less b/css/mixins/clearfix.less
deleted file mode 100644 (file)
index 3f7a382..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Clearfix
-//
-// For modern browsers
-// 1. The space content is one way to avoid an Opera bug when the
-//    contenteditable attribute is included anywhere else in the document.
-//    Otherwise it causes space to appear at the top and bottom of elements
-//    that are clearfixed.
-// 2. The use of `table` rather than `block` is only necessary if using
-//    `:before` to contain the top-margins of child elements.
-//
-// Source: http://nicolasgallagher.com/micro-clearfix-hack/
-
-.clearfix() {
-  &:before,
-  &:after {
-    content: " "; // 1
-    display: table; // 2
-  }
-  &:after {
-    clear: both;
-  }
-}
diff --git a/css/mixins/forms.less b/css/mixins/forms.less
deleted file mode 100644 (file)
index 6f55ed9..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// Form validation states
-//
-// Used in forms.less to generate the form validation CSS for warnings, errors,
-// and successes.
-
-.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {
-  // Color the label and help text
-  .help-block,
-  .control-label,
-  .radio,
-  .checkbox,
-  .radio-inline,
-  .checkbox-inline,
-  &.radio label,
-  &.checkbox label,
-  &.radio-inline label,
-  &.checkbox-inline label  {
-    color: @text-color;
-  }
-  // Set the border and box shadow on specific inputs to match
-  .form-control {
-    border-color: @border-color;
-    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
-    &:focus {
-      border-color: darken(@border-color, 10%);
-      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);
-      .box-shadow(@shadow);
-    }
-  }
-  // Set validation states also for addons
-  .input-group-addon {
-    color: @text-color;
-    border-color: @border-color;
-    background-color: @background-color;
-  }
-  // Optional feedback icon
-  .form-control-feedback {
-    color: @text-color;
-  }
-}
-
-
-// Form control focus state
-//
-// Generate a customized focus state and for any input with the specified color,
-// which defaults to the `@input-border-focus` variable.
-//
-// We highly encourage you to not customize the default value, but instead use
-// this to tweak colors on an as-needed basis. This aesthetic change is based on
-// WebKit's default styles, but applicable to a wider range of browsers. Its
-// usability and accessibility should be taken into account with any change.
-//
-// Example usage: change the default blue border and shadow to white for better
-// contrast against a dark gray background.
-.form-control-focus(@color: @input-border-focus) {
-  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
-  &:focus {
-    border-color: @color;
-    outline: 0;
-    .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
-  }
-}
-
-// Form control sizing
-//
-// Relative text size, padding, and border-radii changes for form controls. For
-// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
-// element gets special love because it's special, and that's a fact!
-.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
-  height: @input-height;
-  padding: @padding-vertical @padding-horizontal;
-  font-size: @font-size;
-  line-height: @line-height;
-  border-radius: @border-radius;
-
-  select& {
-    height: @input-height;
-    line-height: @input-height;
-  }
-
-  textarea&,
-  select[multiple]& {
-    height: auto;
-  }
-}
diff --git a/css/mixins/gradients.less b/css/mixins/gradients.less
deleted file mode 100644 (file)
index 0b88a89..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// Gradients
-
-#gradient {
-
-  // Horizontal gradient, from left to right
-  //
-  // Creates two color stops, start and end, by specifying a color and position for each color stop.
-  // Color stops are not available in IE9 and below.
-  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
-    background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+
-    background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12
-    background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
-    background-repeat: repeat-x;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down
-  }
-
-  // Vertical gradient, from top to bottom
-  //
-  // Creates two color stops, start and end, by specifying a color and position for each color stop.
-  // Color stops are not available in IE9 and below.
-  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
-    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+
-    background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Opera 12
-    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
-    background-repeat: repeat-x;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down
-  }
-
-  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {
-    background-repeat: repeat-x;
-    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+
-    background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12
-    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
-  }
-  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
-    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
-    background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
-    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
-    background-repeat: no-repeat;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
-  }
-  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
-    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
-    background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
-    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);
-    background-repeat: no-repeat;
-    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
-  }
-  .radial(@inner-color: #555; @outer-color: #333) {
-    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);
-    background-image: radial-gradient(circle, @inner-color, @outer-color);
-    background-repeat: no-repeat;
-  }
-  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {
-    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
-    background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
-    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
-  }
-}
diff --git a/css/mixins/grid-framework.less b/css/mixins/grid-framework.less
deleted file mode 100644 (file)
index 8c23eed..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-// Framework grid generation
-//
-// Used only by Bootstrap to generate the correct number of grid classes given
-// any value of `@grid-columns`.
-
-.make-grid-columns() {
-  // Common styles for all sizes of grid columns, widths 1-12
-  .col(@index) { // initial
-    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
-    .col((@index + 1), @item);
-  }
-  .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
-    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
-    .col((@index + 1), ~"@{list}, @{item}");
-  }
-  .col(@index, @list) when (@index > @grid-columns) { // terminal
-    @{list} {
-      position: relative;
-      // Prevent columns from collapsing when empty
-      min-height: 1px;
-      // Inner gutter via padding
-      padding-left:  ceil((@grid-gutter-width / 2));
-      padding-right: floor((@grid-gutter-width / 2));
-    }
-  }
-  .col(1); // kickstart it
-}
-
-.float-grid-columns(@class) {
-  .col(@index) { // initial
-    @item: ~".col-@{class}-@{index}";
-    .col((@index + 1), @item);
-  }
-  .col(@index, @list) when (@index =< @grid-columns) { // general
-    @item: ~".col-@{class}-@{index}";
-    .col((@index + 1), ~"@{list}, @{item}");
-  }
-  .col(@index, @list) when (@index > @grid-columns) { // terminal
-    @{list} {
-      float: left;
-    }
-  }
-  .col(1); // kickstart it
-}
-
-.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
-  .col-@{class}-@{index} {
-    width: percentage((@index / @grid-columns));
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {
-  .col-@{class}-push-@{index} {
-    left: percentage((@index / @grid-columns));
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {
-  .col-@{class}-push-0 {
-    left: auto;
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {
-  .col-@{class}-pull-@{index} {
-    right: percentage((@index / @grid-columns));
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {
-  .col-@{class}-pull-0 {
-    right: auto;
-  }
-}
-.calc-grid-column(@index, @class, @type) when (@type = offset) {
-  .col-@{class}-offset-@{index} {
-    margin-left: percentage((@index / @grid-columns));
-  }
-}
-
-// Basic looping in LESS
-.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
-  .calc-grid-column(@index, @class, @type);
-  // next iteration
-  .loop-grid-columns((@index - 1), @class, @type);
-}
-
-// Create grid for specific class
-.make-grid(@class) {
-  .float-grid-columns(@class);
-  .loop-grid-columns(@grid-columns, @class, width);
-  .loop-grid-columns(@grid-columns, @class, pull);
-  .loop-grid-columns(@grid-columns, @class, push);
-  .loop-grid-columns(@grid-columns, @class, offset);
-}
diff --git a/css/mixins/grid.less b/css/mixins/grid.less
deleted file mode 100644 (file)
index df496d0..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-// Grid system
-//
-// Generate semantic grid columns with these mixins.
-
-// Centered container element
-.container-fixed(@gutter: @grid-gutter-width) {
-  margin-right: auto;
-  margin-left: auto;
-  padding-left:  floor((@gutter / 2));
-  padding-right: ceil((@gutter / 2));
-  &:extend(.clearfix all);
-}
-
-// Creates a wrapper for a series of columns
-.make-row(@gutter: @grid-gutter-width) {
-  margin-left:  ceil((@gutter / -2));
-  margin-right: floor((@gutter / -2));
-  &:extend(.clearfix all);
-}
-
-// Generate the extra small columns
-.make-xs-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  float: left;
-  width: percentage((@columns / @grid-columns));
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-}
-.make-xs-column-offset(@columns) {
-  margin-left: percentage((@columns / @grid-columns));
-}
-.make-xs-column-push(@columns) {
-  left: percentage((@columns / @grid-columns));
-}
-.make-xs-column-pull(@columns) {
-  right: percentage((@columns / @grid-columns));
-}
-
-// Generate the small columns
-.make-sm-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-
-  @media (min-width: @screen-sm-min) {
-    float: left;
-    width: percentage((@columns / @grid-columns));
-  }
-}
-.make-sm-column-offset(@columns) {
-  @media (min-width: @screen-sm-min) {
-    margin-left: percentage((@columns / @grid-columns));
-  }
-}
-.make-sm-column-push(@columns) {
-  @media (min-width: @screen-sm-min) {
-    left: percentage((@columns / @grid-columns));
-  }
-}
-.make-sm-column-pull(@columns) {
-  @media (min-width: @screen-sm-min) {
-    right: percentage((@columns / @grid-columns));
-  }
-}
-
-// Generate the medium columns
-.make-md-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-
-  @media (min-width: @screen-md-min) {
-    float: left;
-    width: percentage((@columns / @grid-columns));
-  }
-}
-.make-md-column-offset(@columns) {
-  @media (min-width: @screen-md-min) {
-    margin-left: percentage((@columns / @grid-columns));
-  }
-}
-.make-md-column-push(@columns) {
-  @media (min-width: @screen-md-min) {
-    left: percentage((@columns / @grid-columns));
-  }
-}
-.make-md-column-pull(@columns) {
-  @media (min-width: @screen-md-min) {
-    right: percentage((@columns / @grid-columns));
-  }
-}
-
-// Generate the large columns
-.make-lg-column(@columns; @gutter: @grid-gutter-width) {
-  position: relative;
-  min-height: 1px;
-  padding-left:  (@gutter / 2);
-  padding-right: (@gutter / 2);
-
-  @media (min-width: @screen-lg-min) {
-    float: left;
-    width: percentage((@columns / @grid-columns));
-  }
-}
-.make-lg-column-offset(@columns) {
-  @media (min-width: @screen-lg-min) {
-    margin-left: percentage((@columns / @grid-columns));
-  }
-}
-.make-lg-column-push(@columns) {
-  @media (min-width: @screen-lg-min) {
-    left: percentage((@columns / @grid-columns));
-  }
-}
-.make-lg-column-pull(@columns) {
-  @media (min-width: @screen-lg-min) {
-    right: percentage((@columns / @grid-columns));
-  }
-}
diff --git a/css/mixins/hide-text.less b/css/mixins/hide-text.less
deleted file mode 100644 (file)
index 2bb84a3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// CSS image replacement
-//
-// Heads up! v3 launched with only `.hide-text()`, but per our pattern for
-// mixins being reused as classes with the same name, this doesn't hold up. As
-// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.
-//
-// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
-
-// Deprecated as of v3.0.1 (has been removed in v4)
-.hide-text() {
-  font: ~"0/0" a;
-  color: transparent;
-  text-shadow: none;
-  background-color: transparent;
-  border: 0;
-}
-
-// New mixin to use as of v3.0.1
-.text-hide() {
-  .hide-text();
-}
diff --git a/css/mixins/image.less b/css/mixins/image.less
deleted file mode 100644 (file)
index f233cb3..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Image Mixins
-// - Responsive image
-// - Retina image
-
-
-// Responsive image
-//
-// Keep images from scaling beyond the width of their parents.
-.img-responsive(@display: block) {
-  display: @display;
-  max-width: 100%; // Part 1: Set a maximum relative to the parent
-  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
-}
-
-
-// Retina image
-//
-// Short retina mixin for setting background-image and -size. Note that the
-// spelling of `min--moz-device-pixel-ratio` is intentional.
-.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
-  background-image: url("@{file-1x}");
-
-  @media
-  only screen and (-webkit-min-device-pixel-ratio: 2),
-  only screen and (   min--moz-device-pixel-ratio: 2),
-  only screen and (     -o-min-device-pixel-ratio: 2/1),
-  only screen and (        min-device-pixel-ratio: 2),
-  only screen and (                min-resolution: 192dpi),
-  only screen and (                min-resolution: 2dppx) {
-    background-image: url("@{file-2x}");
-    background-size: @width-1x @height-1x;
-  }
-}
diff --git a/css/mixins/labels.less b/css/mixins/labels.less
deleted file mode 100644 (file)
index 9f7a67e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Labels
-
-.label-variant(@color) {
-  background-color: @color;
-
-  &[href] {
-    &:hover,
-    &:focus {
-      background-color: darken(@color, 10%);
-    }
-  }
-}
diff --git a/css/mixins/list-group.less b/css/mixins/list-group.less
deleted file mode 100644 (file)
index 03aa190..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// List Groups
-
-.list-group-item-variant(@state; @background; @color) {
-  .list-group-item-@{state} {
-    color: @color;
-    background-color: @background;
-
-    a&,
-    button& {
-      color: @color;
-
-      .list-group-item-heading {
-        color: inherit;
-      }
-
-      &:hover,
-      &:focus {
-        color: @color;
-        background-color: darken(@background, 5%);
-      }
-      &.active,
-      &.active:hover,
-      &.active:focus {
-        color: #fff;
-        background-color: @color;
-        border-color: @color;
-      }
-    }
-  }
-}
diff --git a/css/mixins/nav-divider.less b/css/mixins/nav-divider.less
deleted file mode 100644 (file)
index feb1e9e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Horizontal dividers
-//
-// Dividers (basically an hr) within dropdowns and nav lists
-
-.nav-divider(@color: #e5e5e5) {
-  height: 1px;
-  margin: ((@line-height-computed / 2) - 1) 0;
-  overflow: hidden;
-  background-color: @color;
-}
diff --git a/css/mixins/nav-vertical-align.less b/css/mixins/nav-vertical-align.less
deleted file mode 100644 (file)
index d458c78..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// Navbar vertical align
-//
-// Vertically center elements in the navbar.
-// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
-
-.navbar-vertical-align(@element-height) {
-  margin-top: ((@navbar-height - @element-height) / 2);
-  margin-bottom: ((@navbar-height - @element-height) / 2);
-}
diff --git a/css/mixins/opacity.less b/css/mixins/opacity.less
deleted file mode 100644 (file)
index 33ed25c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// Opacity
-
-.opacity(@opacity) {
-  opacity: @opacity;
-  // IE8 filter
-  @opacity-ie: (@opacity * 100);
-  filter: ~"alpha(opacity=@{opacity-ie})";
-}
diff --git a/css/mixins/pagination.less b/css/mixins/pagination.less
deleted file mode 100644 (file)
index 618804f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Pagination
-
-.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
-  > li {
-    > a,
-    > span {
-      padding: @padding-vertical @padding-horizontal;
-      font-size: @font-size;
-      line-height: @line-height;
-    }
-    &:first-child {
-      > a,
-      > span {
-        .border-left-radius(@border-radius);
-      }
-    }
-    &:last-child {
-      > a,
-      > span {
-        .border-right-radius(@border-radius);
-      }
-    }
-  }
-}
diff --git a/css/mixins/panels.less b/css/mixins/panels.less
deleted file mode 100644 (file)
index 49ee10d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Panels
-
-.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {
-  border-color: @border;
-
-  & > .panel-heading {
-    color: @heading-text-color;
-    background-color: @heading-bg-color;
-    border-color: @heading-border;
-
-    + .panel-collapse > .panel-body {
-      border-top-color: @border;
-    }
-    .badge {
-      color: @heading-bg-color;
-      background-color: @heading-text-color;
-    }
-  }
-  & > .panel-footer {
-    + .panel-collapse > .panel-body {
-      border-bottom-color: @border;
-    }
-  }
-}
diff --git a/css/mixins/progress-bar.less b/css/mixins/progress-bar.less
deleted file mode 100644 (file)
index f07996a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Progress bars
-
-.progress-bar-variant(@color) {
-  background-color: @color;
-
-  // Deprecated parent class requirement as of v3.2.0
-  .progress-striped & {
-    #gradient > .striped();
-  }
-}
diff --git a/css/mixins/reset-filter.less b/css/mixins/reset-filter.less
deleted file mode 100644 (file)
index 68cdb5e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// Reset filters for IE
-//
-// When you need to remove a gradient background, do not forget to use this to reset
-// the IE filter for IE9 and below.
-
-.reset-filter() {
-  filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
-}
diff --git a/css/mixins/reset-text.less b/css/mixins/reset-text.less
deleted file mode 100644 (file)
index 58dd4d1..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-.reset-text() {
-  font-family: @font-family-base;
-  // We deliberately do NOT reset font-size.
-  font-style: normal;
-  font-weight: normal;
-  letter-spacing: normal;
-  line-break: auto;
-  line-height: @line-height-base;
-  text-align: left; // Fallback for where `start` is not supported
-  text-align: start;
-  text-decoration: none;
-  text-shadow: none;
-  text-transform: none;
-  white-space: normal;
-  word-break: normal;
-  word-spacing: normal;
-  word-wrap: normal;
-}
diff --git a/css/mixins/resize.less b/css/mixins/resize.less
deleted file mode 100644 (file)
index 3acd3af..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// Resize anything
-
-.resizable(@direction) {
-  resize: @direction; // Options: horizontal, vertical, both
-  overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
-}
diff --git a/css/mixins/responsive-visibility.less b/css/mixins/responsive-visibility.less
deleted file mode 100644 (file)
index ecf1e97..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Responsive utilities
-
-//
-// More easily include all the states for responsive-utilities.less.
-.responsive-visibility() {
-  display: block !important;
-  table&  { display: table !important; }
-  tr&     { display: table-row !important; }
-  th&,
-  td&     { display: table-cell !important; }
-}
-
-.responsive-invisibility() {
-  display: none !important;
-}
diff --git a/css/mixins/size.less b/css/mixins/size.less
deleted file mode 100644 (file)
index a8be650..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-// Sizing shortcuts
-
-.size(@width; @height) {
-  width: @width;
-  height: @height;
-}
-
-.square(@size) {
-  .size(@size; @size);
-}
diff --git a/css/mixins/tab-focus.less b/css/mixins/tab-focus.less
deleted file mode 100644 (file)
index d12d236..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// WebKit-style focus
-
-.tab-focus() {
-  // WebKit-specific. Other browsers will keep their default outline style.
-  // (Initially tried to also force default via `outline: initial`,
-  // but that seems to erroneously remove the outline in Firefox altogether.)
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
diff --git a/css/mixins/table-row.less b/css/mixins/table-row.less
deleted file mode 100644 (file)
index 0f287f1..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Tables
-
-.table-row-variant(@state; @background) {
-  // Exact selectors below required to override `.table-striped` and prevent
-  // inheritance to nested tables.
-  .table > thead > tr,
-  .table > tbody > tr,
-  .table > tfoot > tr {
-    > td.@{state},
-    > th.@{state},
-    &.@{state} > td,
-    &.@{state} > th {
-      background-color: @background;
-    }
-  }
-
-  // Hover states for `.table-hover`
-  // Note: this is not available for cells or rows within `thead` or `tfoot`.
-  .table-hover > tbody > tr {
-    > td.@{state}:hover,
-    > th.@{state}:hover,
-    &.@{state}:hover > td,
-    &:hover > .@{state},
-    &.@{state}:hover > th {
-      background-color: darken(@background, 5%);
-    }
-  }
-}
diff --git a/css/mixins/text-emphasis.less b/css/mixins/text-emphasis.less
deleted file mode 100644 (file)
index 9e8a77a..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// Typography
-
-.text-emphasis-variant(@color) {
-  color: @color;
-  a&:hover,
-  a&:focus {
-    color: darken(@color, 10%);
-  }
-}
diff --git a/css/mixins/text-overflow.less b/css/mixins/text-overflow.less
deleted file mode 100644 (file)
index c11ad2f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// Text overflow
-// Requires inline-block or block for proper styling
-
-.text-overflow() {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
diff --git a/css/mixins/vendor-prefixes.less b/css/mixins/vendor-prefixes.less
deleted file mode 100644 (file)
index 2b5e74b..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-// Vendor Prefixes
-//
-// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
-// Autoprefixer in our Gruntfile. They have been removed in v4.
-
-// - Animations
-// - Backface visibility
-// - Box shadow
-// - Box sizing
-// - Content columns
-// - Hyphens
-// - Placeholder text
-// - Transformations
-// - Transitions
-// - User Select
-
-
-// Animations
-.animation(@animation) {
-  -webkit-animation: @animation;
-       -o-animation: @animation;
-          animation: @animation;
-}
-.animation-name(@name) {
-  -webkit-animation-name: @name;
-          animation-name: @name;
-}
-.animation-duration(@duration) {
-  -webkit-animation-duration: @duration;
-          animation-duration: @duration;
-}
-.animation-timing-function(@timing-function) {
-  -webkit-animation-timing-function: @timing-function;
-          animation-timing-function: @timing-function;
-}
-.animation-delay(@delay) {
-  -webkit-animation-delay: @delay;
-          animation-delay: @delay;
-}
-.animation-iteration-count(@iteration-count) {
-  -webkit-animation-iteration-count: @iteration-count;
-          animation-iteration-count: @iteration-count;
-}
-.animation-direction(@direction) {
-  -webkit-animation-direction: @direction;
-          animation-direction: @direction;
-}
-.animation-fill-mode(@fill-mode) {
-  -webkit-animation-fill-mode: @fill-mode;
-          animation-fill-mode: @fill-mode;
-}
-
-// Backface visibility
-// Prevent browsers from flickering when using CSS 3D transforms.
-// Default value is `visible`, but can be changed to `hidden`
-
-.backface-visibility(@visibility) {
-  -webkit-backface-visibility: @visibility;
-     -moz-backface-visibility: @visibility;
-          backface-visibility: @visibility;
-}
-
-// Drop shadows
-//
-// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
-// supported browsers that have box shadow capabilities now support it.
-
-.box-shadow(@shadow) {
-  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
-          box-shadow: @shadow;
-}
-
-// Box sizing
-.box-sizing(@boxmodel) {
-  -webkit-box-sizing: @boxmodel;
-     -moz-box-sizing: @boxmodel;
-          box-sizing: @boxmodel;
-}
-
-// CSS3 Content Columns
-.content-columns(@column-count; @column-gap: @grid-gutter-width) {
-  -webkit-column-count: @column-count;
-     -moz-column-count: @column-count;
-          column-count: @column-count;
-  -webkit-column-gap: @column-gap;
-     -moz-column-gap: @column-gap;
-          column-gap: @column-gap;
-}
-
-// Optional hyphenation
-.hyphens(@mode: auto) {
-  word-wrap: break-word;
-  -webkit-hyphens: @mode;
-     -moz-hyphens: @mode;
-      -ms-hyphens: @mode; // IE10+
-       -o-hyphens: @mode;
-          hyphens: @mode;
-}
-
-// Placeholder text
-.placeholder(@color: @input-color-placeholder) {
-  // Firefox
-  &::-moz-placeholder {
-    color: @color;
-    opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
-  }
-  &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+
-  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome
-}
-
-// Transformations
-.scale(@ratio) {
-  -webkit-transform: scale(@ratio);
-      -ms-transform: scale(@ratio); // IE9 only
-       -o-transform: scale(@ratio);
-          transform: scale(@ratio);
-}
-.scale(@ratioX; @ratioY) {
-  -webkit-transform: scale(@ratioX, @ratioY);
-      -ms-transform: scale(@ratioX, @ratioY); // IE9 only
-       -o-transform: scale(@ratioX, @ratioY);
-          transform: scale(@ratioX, @ratioY);
-}
-.scaleX(@ratio) {
-  -webkit-transform: scaleX(@ratio);
-      -ms-transform: scaleX(@ratio); // IE9 only
-       -o-transform: scaleX(@ratio);
-          transform: scaleX(@ratio);
-}
-.scaleY(@ratio) {
-  -webkit-transform: scaleY(@ratio);
-      -ms-transform: scaleY(@ratio); // IE9 only
-       -o-transform: scaleY(@ratio);
-          transform: scaleY(@ratio);
-}
-.skew(@x; @y) {
-  -webkit-transform: skewX(@x) skewY(@y);
-      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
-       -o-transform: skewX(@x) skewY(@y);
-          transform: skewX(@x) skewY(@y);
-}
-.translate(@x; @y) {
-  -webkit-transform: translate(@x, @y);
-      -ms-transform: translate(@x, @y); // IE9 only
-       -o-transform: translate(@x, @y);
-          transform: translate(@x, @y);
-}
-.translate3d(@x; @y; @z) {
-  -webkit-transform: translate3d(@x, @y, @z);
-          transform: translate3d(@x, @y, @z);
-}
-.rotate(@degrees) {
-  -webkit-transform: rotate(@degrees);
-      -ms-transform: rotate(@degrees); // IE9 only
-       -o-transform: rotate(@degrees);
-          transform: rotate(@degrees);
-}
-.rotateX(@degrees) {
-  -webkit-transform: rotateX(@degrees);
-      -ms-transform: rotateX(@degrees); // IE9 only
-       -o-transform: rotateX(@degrees);
-          transform: rotateX(@degrees);
-}
-.rotateY(@degrees) {
-  -webkit-transform: rotateY(@degrees);
-      -ms-transform: rotateY(@degrees); // IE9 only
-       -o-transform: rotateY(@degrees);
-          transform: rotateY(@degrees);
-}
-.perspective(@perspective) {
-  -webkit-perspective: @perspective;
-     -moz-perspective: @perspective;
-          perspective: @perspective;
-}
-.perspective-origin(@perspective) {
-  -webkit-perspective-origin: @perspective;
-     -moz-perspective-origin: @perspective;
-          perspective-origin: @perspective;
-}
-.transform-origin(@origin) {
-  -webkit-transform-origin: @origin;
-     -moz-transform-origin: @origin;
-      -ms-transform-origin: @origin; // IE9 only
-          transform-origin: @origin;
-}
-
-
-// Transitions
-
-.transition(@transition) {
-  -webkit-transition: @transition;
-       -o-transition: @transition;
-          transition: @transition;
-}
-.transition-property(@transition-property) {
-  -webkit-transition-property: @transition-property;
-          transition-property: @transition-property;
-}
-.transition-delay(@transition-delay) {
-  -webkit-transition-delay: @transition-delay;
-          transition-delay: @transition-delay;
-}
-.transition-duration(@transition-duration) {
-  -webkit-transition-duration: @transition-duration;
-          transition-duration: @transition-duration;
-}
-.transition-timing-function(@timing-function) {
-  -webkit-transition-timing-function: @timing-function;
-          transition-timing-function: @timing-function;
-}
-.transition-transform(@transition) {
-  -webkit-transition: -webkit-transform @transition;
-     -moz-transition: -moz-transform @transition;
-       -o-transition: -o-transform @transition;
-          transition: transform @transition;
-}
-
-
-// User select
-// For selecting text on the page
-
-.user-select(@select) {
-  -webkit-user-select: @select;
-     -moz-user-select: @select;
-      -ms-user-select: @select; // IE10+
-          user-select: @select;
-}
index 4751150..e259d2d 100644 (file)
@@ -11,150 +11,121 @@ return async (env, head, body, scripts) => {
     head,
     // body
     async _out => {
-      div(style="padding-left: calc(100vw - 100%);") {
-        div.container {
+      nav.navbar.navbar-default.fixed-left {
+        div.container-fluid.mirobot-control {
+          //  Brand and toggle get grouped for better mobile display 
+          div.navbar-header {
+            button.navbar-toggle.collapsed(type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false") {
+              span.sr-only {'Toggle navigation'}
+              span.icon-bar {}
+              span.icon-bar {}
+              span.icon-bar {}
+            }
+            _out.push(techedu_horizontal)
+          }
           div.row {
-            div.'col-sm-4'.left-pane {
-              div {
-                _out.push(techedu_horizontal)
-              }
-              div.mirobot-control {
-                div.container-fluid {
-                  div.row {
-                    div.'col-sm-7'.pad-8 {
-                      'MiRobot: '
-                      span#connection-status {'Disconnected'}
-                    }
-                    div.col-sm-5 {
-                      button.btn.btn-block.btn-primary.float-right#connect-disconnect(type="button") {'Connect'}
-                    }
-                  }
-                }
-              }
-              div.mirobot-control {
-                div.container-fluid {
-                  div.row {
-                    div.col-sm-7 {
-                      input.mirobot-slider#slider-a(type="range" min="-90" max="90" value="0") {}
-                    }
-                    div.col-sm-5 {
-                      'Axis A: '
-                      span#value-a {'0'}
-                    }
-                  }
-                }
-              }
-              div.mirobot-control {
-                div.container-fluid {
-                  div.row {
-                    div.col-sm-7 {
-                      input.mirobot-slider#slider-b(type="range" min="-50" max="75" value="0") {}
-                    }
-                    div.col-sm-5 {
-                      'Axis B: '
-                      span#value-b {'0'}
-                    }
-                  }
-                }
-              }
-              div.mirobot-control {
-                div.container-fluid {
-                  div.row {
-                    div.col-sm-7 {
-                      input.mirobot-slider#slider-c(type="range" min="0" max="90" value="0") {}
-                    }
-                    div.col-sm-5 {
-                      'Axis C: '
-                      span#value-c {'0'}
-                    }
-                  }
-                }
-              }
-              div.mirobot-control {
-                div.container-fluid {
-                  div.row {
-                    div.col-sm-7 {
-                      input.mirobot-slider#slider-d(type="range" min="-45" max="45" value="0") {}
-                    }
-                    div.col-sm-5 {
-                      'Axis D: '
-                      span#value-d {'0'}
-                    }
-                  }
-                }
-              }
-              div.mirobot-control {
-                div.container-fluid {
-                  div.row {
-                    div.col-sm-7 {
-                      input.mirobot-slider#slider-e(type="range" min="-45" max="45" value="0") {}
-                    }
-                    div.col-sm-5 {
-                      'Axis E: '
-                      span#value-e {'0'}
-                    }
+            div.'col-sm-7'.pad-8 {
+              'MiRobot: '
+              span#connection-status {'Disconnected'}
+            }
+            div.col-sm-5 {
+              button.btn.btn-block.btn-primary.float-right#connect-disconnect(type="button") {'Connect'}
+            }
+          }
+          div.row {
+            div.col-sm-7 {
+              input.mirobot-slider#slider-a(type="range" min="-90" max="90" value="0") {}
+            }
+            div.col-sm-5 {
+              'Axis A: '
+              span#value-a {'0'}
+            }
+          }
+          div.row {
+            div.col-sm-7 {
+              input.mirobot-slider#slider-b(type="range" min="-50" max="75" value="0") {}
+            }
+            div.col-sm-5 {
+              'Axis B: '
+              span#value-b {'0'}
+            }
+          }
+          div.row {
+            div.col-sm-7 {
+              input.mirobot-slider#slider-c(type="range" min="0" max="90" value="0") {}
+            }
+            div.col-sm-5 {
+              'Axis C: '
+              span#value-c {'0'}
+            }
+          }
+          div.row {
+            div.col-sm-7 {
+              input.mirobot-slider#slider-d(type="range" min="-45" max="45" value="0") {}
+            }
+            div.col-sm-5 {
+              'Axis D: '
+              span#value-d {'0'}
+            }
+          }
+          div.row {
+            div.col-sm-7 {
+              input.mirobot-slider#slider-e(type="range" min="-45" max="45" value="0") {}
+            }
+            div.col-sm-5 {
+              'Axis E: '
+              span#value-e {'0'}
+            }
+          }
+          div.row {
+            div.col-sm-7 {
+              input.mirobot-slider#slider-f(type="range" min="0" max="60" value="0") {}
+            }
+            div.col-sm-5 {
+              'Axis F: '
+              span#value-f {'0'}
+            }
+          }
+        }
+
+        //  Collect the nav links, forms, and other content for toggling 
+        div.collapse.navbar-collapse#bs-example-navbar-collapse-1 {
+          ul.nav.navbar-nav {
+            let navigation = globals.navigation
+            for (let i = 0; i < navigation.length; ++i) {
+              let page = navigation[i]
+              let title = globals.page_to_title[page] || page
+              if (page === env.parsed_url.pathname)
+                li.btn-block.active {
+                  a(href=page) {
+                    `${title}`
+                    span.sr-only {'(current)'}
                   }
                 }
-              }
-              div.mirobot-control {
-                div.container-fluid {
-                  div.row {
-                    div.col-sm-7 {
-                      input.mirobot-slider#slider-f(type="range" min="0" max="60" value="0") {}
-                    }
-                    div.col-sm-5 {
-                      'Axis F: '
-                      span#value-f {'0'}
-                    }
-                  }
+              else
+                li.btn-block {
+                  a(href=page) {`${title}`}
                 }
-              }
-              nav.navbar {
-                //  Brand and toggle get grouped for better mobile display 
-                //div.navbar-header {
-                //  button.navbar-toggle.collapsed(type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false") {
-                //    span.sr-only {'Toggle navigation'}
-                //    span.icon-bar {}
-                //    span.icon-bar {}
-                //    span.icon-bar {}
-                //  }
-                //  //a.navbar-brand(href="#") {'Brand'}
-                //}
-    
-                //  Collect the nav links, forms, and other content for toggling 
-                //div.collapse.navbar-collapse#bs-example-navbar-collapse-1 {
-                  ul { //.nav.navbar-nav.navbar-left {
-                    let navigation = globals.navigation
-                    for (let i = 0; i < navigation.length; ++i) {
-                      let page = navigation[i]
-                      let title = globals.page_to_title[page] || page
-                      if (page === env.parsed_url.pathname)
-                        li.active {
-                          a(href=page) {
-                            `${title}`
-                            span.sr-only {'(current)'}
-                          }
-                        }
-                      else
-                        li {
-                          a(href=page) {`${title}`}
-                        }
-                    }
-                  }
-                //}
-              }
-            }
-            div.col-sm-8 {
-              h5 {
-                _out.push(globals.page_to_breadcrumbs[env.parsed_url.pathname] || globals.page_to_title[env.parsed_url.pathname] || env.parsed_url.pathname)
-              } 
-              await body(_out)
             }
           }
+          //ul.nav.navbar-nav.navbar-right {
+          //  li.btn-block {
+          //    a#give-feedback {'Give feedback'}
+          //  }
+          //} 
         }
       }
-      div.footer(style="padding-left: calc(100vw - 100%);") {
-        div.container {
+      if (env.parsed_url.pathname === '/blockly.html')
+        await body(_out)
+      else
+        div.container-fluid {
+          h5 {
+            _out.push(globals.page_to_breadcrumbs[env.parsed_url.pathname] || globals.page_to_title[env.parsed_url.pathname] || env.parsed_url.pathname)
+          } 
+          await body(_out)
+        }
+      div.footer {
+        div.container-fluid {
           `Copyright © ${new XDate().getUTCFullYear()} Technology Education Pty Ltd.`
         }
       }