diff --git a/package.json b/package.json
index d9e3d59c08ecdbf2adc92df5046aa149331bae1f..a49518cae8a9d196aa0c0b6411c5b5b1d2f78002 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
     "doc": "node ./scripts/doc/build.js",
     "prettier": "prettier --write '*.js' 'src/**/*.js'",
     "lint:js": "eslint '*.js' 'scripts/**/*.js' 'src/**/*.js'",
-    "lint:html": "htmlhint 'src/**/*.html'",
+    "lint:html": "htmlhint 'src/**/*.html' && node scripts/indent-linter.js 'src/**/*.html'",
     "lint": "npm run lint:js && npm run lint:html",
     "test": "npm run lint && npm run build"
   },
diff --git a/scripts/indent-linter.js b/scripts/indent-linter.js
new file mode 100644
index 0000000000000000000000000000000000000000..c56928d82dd5755c3350e2c0a913862298829517
--- /dev/null
+++ b/scripts/indent-linter.js
@@ -0,0 +1,40 @@
+const fs = require("fs");
+const glob = require("glob");
+
+function lintFile(filename) {
+  const file = fs.readFileSync(filename, { encoding: "utf8" });
+  const spaces = parseInt(process.argv[3] || "4", 10);
+  const lines = file.split("\n");
+  const errors = [];
+  let level = 0;
+  for (let i = 0; i < lines.length; i++) {
+    const line = lines[i];
+    const firstNonSpaceIndex = (line.match(/[^ ]/) || { index: 0 }).index;
+    const indentation = firstNonSpaceIndex;
+    if (indentation % spaces === 0 && (indentation - level) / spaces <= 1) {
+      if (indentation !== 0) {
+        level = indentation;
+      }
+    } else {
+      const expected = level + spaces;
+      const delta = indentation - expected;
+      const postfix = delta < 0 ? "fewer" : "extra";
+      errors.push(
+        `  ${i + 1}\tExpected ${expected / spaces} levels of indentation, saw ${Math.abs(delta)} space(s) ${postfix}.`
+      );
+    }
+  }
+  if (errors.length) {
+    console.log(filename);
+    console.log(errors.join("\n"));
+    console.log(`  ${errors.length} indentation error(s).\n`);
+  }
+  return errors.length;
+}
+
+glob(process.argv[2], (err, files) => {
+  console.log("");
+  const errorCount = files.map(lintFile).reduce((a, c) => a + c, 0);
+  console.log(`${errorCount} total indentation error(s).\n`);
+  process.exit(errorCount > 0 ? 1 : 0);
+});
diff --git a/src/avatar-selector.html b/src/avatar-selector.html
index 44e92f4e6d19b5d7cc2258e56cfa76c08a20558a..ca3eb4028aa3753b34210ce3c5e7e6570bed2130 100644
--- a/src/avatar-selector.html
+++ b/src/avatar-selector.html
@@ -2,13 +2,13 @@
 <html>
 
 <head>
-  <meta charset="utf-8">
-  <title>avatar selector</title>
-  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+    <meta charset="utf-8">
+    <title>avatar selector</title>
+    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
 </head>
 
 <body>
-  <div id="selector-root"></div>
+    <div id="selector-root"></div>
 </body>
 
 </html>
diff --git a/src/hub.html b/src/hub.html
index 99232684d4d2da80d13a3e953ffad076f3eeb748..bc6e329c4c2effbf7672c025f747b8d7b570c0d8 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -90,22 +90,22 @@
                         <template data-name="Neck">
                             <a-entity>
                                 <a-entity
-                                   class="nametag"
-                                   billboard
-                                   text="side: double; align: center; color: #ddd"
-                                   position="0 1 0"
-                                   scale="6 6 6"
-                               ></a-entity>
+                                    class="nametag"
+                                    billboard
+                                    text="side: double; align: center; color: #ddd"
+                                    position="0 1 0"
+                                    scale="6 6 6"
+                                ></a-entity>
                             </a-entity>
                         </template>
 
                         <template data-name="Chest">
-                          <a-entity personal-space-invader="radius: 0.2; useMaterial: true;" bone-visibility>
-                            <a-entity billboard>
-                              <a-entity mixin="rounded-text-button" block-button visible-while-frozen ui-class-while-frozen position="0 0 .35"> </a-entity>
-                              <a-entity visible-while-frozen text="value:Block; width:2.5; align:center;" position="0 0 0.36"></a-entity>
+                            <a-entity personal-space-invader="radius: 0.2; useMaterial: true;" bone-visibility>
+                                <a-entity billboard>
+                                    <a-entity mixin="rounded-text-button" block-button visible-while-frozen ui-class-while-frozen position="0 0 .35"> </a-entity>
+                                    <a-entity visible-while-frozen text="value:Block; width:2.5; align:center;" position="0 0 0.36"></a-entity>
+                                </a-entity>
                             </a-entity>
-                          </a-entity>
                         </template>
 
                         <template data-name="Head">
@@ -115,22 +115,22 @@
                                 personal-space-invader="radius: 0.15; useMaterial: true;"
                                 bone-visibility
                             >
-                              <a-cylinder
-                                  static-body
-                                  radius="0.13"
-                                  height="0.2"
-                                  position="0 0.07 0.05"
-                                  visible="false"
-                              ></a-cylinder>
+                                <a-cylinder
+                                    static-body
+                                    radius="0.13"
+                                    height="0.2"
+                                    position="0 0.07 0.05"
+                                    visible="false"
+                                ></a-cylinder>
                             </a-entity>
                         </template>
 
                         <template data-name="LeftHand">
-                          <a-entity personal-space-invader="radius: 0.1" bone-visibility></a-entity>
+                            <a-entity personal-space-invader="radius: 0.1" bone-visibility></a-entity>
                         </template>
 
                         <template data-name="RightHand">
-                          <a-entity personal-space-invader="radius: 0.1" bone-visibility></a-entity>
+                            <a-entity personal-space-invader="radius: 0.1" bone-visibility></a-entity>
                         </template>
                     </a-entity>
                 </a-entity>
@@ -246,21 +246,21 @@
             ></a-mixin>
 
             <a-mixin id="controller-super-hands"
-                     super-hands="
-                         colliderEvent: collisions;
-                         colliderEventProperty: els;
-                         colliderEndEvent: collisions;
-                         colliderEndEventProperty: clearedEls;
-                         grabStartButtons: primary_hand_grab, secondary_hand_grab;
-                         grabEndButtons: primary_hand_release, secondary_hand_release;
-                         stretchStartButtons: primary_hand_grab, secondary_hand_grab;
-                         stretchEndButtons: primary_hand_release, secondary_hand_release;
-                         dragDropStartButtons: hand_grab, secondary_hand_grab;
-                         dragDropEndButtons: hand_release, secondary_hand_release;
-                         activateStartButtons: secondary_hand_grab, next_color, previous_color, increase_radius, decrease_radius, scroll_up, scroll_down, scroll_left, scroll_right;
-                         activateEndButtons: secondary_hand_release, vertical_scroll_release, horizontal_scroll_release, thumb_up;"
-                     collision-filter="collisionForces: false"
-                     physics-collider
+                super-hands="
+                    colliderEvent: collisions;
+                    colliderEventProperty: els;
+                    colliderEndEvent: collisions;
+                    colliderEndEventProperty: clearedEls;
+                    grabStartButtons: primary_hand_grab, secondary_hand_grab;
+                    grabEndButtons: primary_hand_release, secondary_hand_release;
+                    stretchStartButtons: primary_hand_grab, secondary_hand_grab;
+                    stretchEndButtons: primary_hand_release, secondary_hand_release;
+                    dragDropStartButtons: hand_grab, secondary_hand_grab;
+                    dragDropEndButtons: hand_release, secondary_hand_release;
+                    activateStartButtons: secondary_hand_grab, next_color, previous_color, increase_radius, decrease_radius, scroll_up, scroll_down, scroll_left, scroll_right;
+                    activateEndButtons: secondary_hand_release, vertical_scroll_release, horizontal_scroll_release, thumb_up;"
+                collision-filter="collisionForces: false"
+                physics-collider
             ></a-mixin>
         </a-assets>
 
@@ -315,134 +315,132 @@
             player-info
             cardboard-controls
         >
-          <a-entity
-              id="player-hud"
-              hud-controller="head: #player-camera;"
-              vr-mode-toggle-visibility
-              vr-mode-toggle-playing__hud-controller
-          >
-            <a-entity in-world-hud="haptic:#player-right-controller;raycaster:#player-right-controller;" rotation="30 0 0">
-              <a-rounded height="0.08" width="0.5" color="#000000" position="-0.20 0.125 0" radius="0.040" opacity="0.35" class="hud bg"></a-rounded>
-              <a-entity id="hud-hub-entry-link" text=" value:; width:1.1; align:center;" position="0.05 0.165 0"></a-entity>
-              <a-rounded height="0.13" width="0.59" color="#000000" position="-0.24 -0.065 0" radius="0.065" opacity="0.35" class="hud bg"></a-rounded>
-              <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Mute Mic; activeTooltipText: Unmute Mic; image: #mute-off; hoverImage: #mute-off-hover; activeImage: #mute-on; activeHoverImage: #mute-on-hover" scale="0.1 0.1 0.1" position="-0.17 0 0.001" class="ui hud mic" material="alphaTest:0.1;" hoverable></a-image>
-              <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Pause; activeTooltipText: Resume; image: #freeze-off; hoverImage: #freeze-off-hover; activeImage: #freeze-on; activeHoverImage: #freeze-on-hover" scale="0.2 0.2 0.2" position="0 0 0.005" class="ui hud freeze" hoverable></a-image>
-              <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Pen; activeTooltipText: Pen; image: #spawn-pen; hoverImage: #spawn-pen-hover; activeImage: #spawn-pen; activeHoverImage: #spawn-pen-hover" scale="0.1 0.1 0.1" position="0.17 0 0.001" class="ui hud penhud" material="alphaTest:0.1;" hoverable></a-image>
-              <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Camera; activeTooltipText: Camera; image: #spawn-camera; hoverImage: #spawn-camera-hover; activeImage: #spawn-camera; activeHoverImage: #spawn-camera-hover" scale="0.1 0.1 0.1" position="0.28 0 0.001" class="ui hud cameraBtn" material="alphaTest:0.1;" hoverable></a-image>
-              <a-rounded visible="false" id="hud-tooltip" height="0.08" width="0.3" color="#000000" position="-0.15 -0.2 0" rotation="-20 0 0" radius="0.025" opacity="0.35" class="hud bg">
-                <a-entity text="value: Mute Mic; align:center;" position="0.15 0.04 0.001" ></a-entity>
-              </a-rounded>
+            <a-entity
+                id="player-hud"
+                hud-controller="head: #player-camera;"
+                vr-mode-toggle-visibility
+                vr-mode-toggle-playing__hud-controller
+            >
+                <a-entity in-world-hud="haptic:#player-right-controller;raycaster:#player-right-controller;" rotation="30 0 0">
+                    <a-rounded height="0.08" width="0.5" color="#000000" position="-0.20 0.125 0" radius="0.040" opacity="0.35" class="hud bg"></a-rounded>
+                    <a-entity id="hud-hub-entry-link" text=" value:; width:1.1; align:center;" position="0.05 0.165 0"></a-entity>
+                    <a-rounded height="0.13" width="0.59" color="#000000" position="-0.24 -0.065 0" radius="0.065" opacity="0.35" class="hud bg"></a-rounded>
+                    <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Mute Mic; activeTooltipText: Unmute Mic; image: #mute-off; hoverImage: #mute-off-hover; activeImage: #mute-on; activeHoverImage: #mute-on-hover" scale="0.1 0.1 0.1" position="-0.17 0 0.001" class="ui hud mic" material="alphaTest:0.1;" hoverable></a-image>
+                    <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Pause; activeTooltipText: Resume; image: #freeze-off; hoverImage: #freeze-off-hover; activeImage: #freeze-on; activeHoverImage: #freeze-on-hover" scale="0.2 0.2 0.2" position="0 0 0.005" class="ui hud freeze" hoverable></a-image>
+                    <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Pen; activeTooltipText: Pen; image: #spawn-pen; hoverImage: #spawn-pen-hover; activeImage: #spawn-pen; activeHoverImage: #spawn-pen-hover" scale="0.1 0.1 0.1" position="0.17 0 0.001" class="ui hud penhud" material="alphaTest:0.1;" hoverable></a-image>
+                    <a-image icon-button="tooltip: #hud-tooltip; tooltipText: Camera; activeTooltipText: Camera; image: #spawn-camera; hoverImage: #spawn-camera-hover; activeImage: #spawn-camera; activeHoverImage: #spawn-camera-hover" scale="0.1 0.1 0.1" position="0.28 0 0.001" class="ui hud cameraBtn" material="alphaTest:0.1;" hoverable></a-image>
+                    <a-rounded visible="false" id="hud-tooltip" height="0.08" width="0.3" color="#000000" position="-0.15 -0.2 0" rotation="-20 0 0" radius="0.025" opacity="0.35" class="hud bg">
+                        <a-entity text="value: Mute Mic; align:center;" position="0.15 0.04 0.001" ></a-entity>
+                    </a-rounded>
+                </a-entity>
+            </a-entity>
+
+            <a-entity
+                id="player-camera"
+                class="camera"
+                camera
+                personal-space-bubble="radius: 0.4;"
+                pitch-yaw-rotator
+            >
+                <a-entity
+                    id="gaze-teleport"
+                    position = "0.15 0 0"
+                    teleport-controls="
+                        cameraRig: #player-rig;
+                        teleportOrigin: #player-camera;
+                        button: gaze-teleport_;
+                        collisionEntities: [nav-mesh];
+                        drawIncrementally: true;
+                        incrementalDrawMs: 300;
+                        hitOpacity: 0.3;
+                        missOpacity: 0.1;
+                        curveShootingSpeed: 12;"
+                    action-to-event__start-teleport="path: /actions/startTeleport; event: gaze-teleport_down"
+                    action-to-event__stop-teleport="path: /actions/stopTeleport; event: gaze-teleport_up"
+                ></a-entity>
             </a-entity>
-          </a-entity>
-
-          <a-entity
-              id="player-camera"
-              class="camera"
-              camera
-              personal-space-bubble="radius: 0.4;"
-              pitch-yaw-rotator
-          >
+
             <a-entity
-                id="gaze-teleport"
-                position = "0.15 0 0"
+                id="player-left-controller"
+                class="left-controller"
+                hand-controls2="left"
+                tracked-controls
                 teleport-controls="
                     cameraRig: #player-rig;
                     teleportOrigin: #player-camera;
-                    button: gaze-teleport_;
+                    button: left-teleport_;
                     collisionEntities: [nav-mesh];
                     drawIncrementally: true;
                     incrementalDrawMs: 300;
                     hitOpacity: 0.3;
                     missOpacity: 0.1;
                     curveShootingSpeed: 12;"
-                action-to-event__start-teleport="path: /actions/startTeleport; event: gaze-teleport_down"
-                action-to-event__stop-teleport="path: /actions/stopTeleport; event: gaze-teleport_up"
-            ></a-entity>
-          </a-entity>
-
-          <a-entity
-              id="player-left-controller"
-              class="left-controller"
-              hand-controls2="left"
-              tracked-controls
-              teleport-controls="
-                  cameraRig: #player-rig;
-                  teleportOrigin: #player-camera;
-                  button: left-teleport_;
-                  collisionEntities: [nav-mesh];
-                  drawIncrementally: true;
-                  incrementalDrawMs: 300;
-                  hitOpacity: 0.3;
-                  missOpacity: 0.1;
-                  curveShootingSpeed: 12;"
-              haptic-feedback
-              body="type: static; shape: none;"
-              mixin="controller-super-hands"
-              controls-shape-offset
-              action-to-event__a="path: /actions/leftHandStartTeleport; event: left-teleport_down;"
-              action-to-event__b="path: /actions/leftHandStopTeleport; event: left-teleport_up;"
-              action-to-event__c="path: /actions/leftHandGrab; event: primary_hand_grab;"
-              action-to-event__d="path: /actions/leftHandDrop; event: primary_hand_release;"
-          >
-          </a-entity>
-
-          <a-entity
-              id="player-right-controller"
-              class="right-controller"
-              hand-controls2="right"
-              tracked-controls
-              teleport-controls="
-                  cameraRig: #player-rig;
-                  teleportOrigin: #player-camera;
-                  button: right-teleport_;
-                  collisionEntities: [nav-mesh];
-                  drawIncrementally: true;
-                  incrementalDrawMs: 300;
-                  hitOpacity: 0.3;
-                  missOpacity: 0.1;
-                  curveShootingSpeed: 12;"
-              haptic-feedback
-              body="type: static; shape: none;"
-              mixin="controller-super-hands"
-              controls-shape-offset
-              action-to-event__a="path: /actions/rightHandStartTeleport; event: right-teleport_down;"
-              action-to-event__b="path: /actions/rightHandStopTeleport; event: right-teleport_up;"
-              action-to-event__c="path: /actions/rightHandGrab; event: primary_hand_grab;"
-              action-to-event__d="path: /actions/rightHandDrop; event: primary_hand_release;"
-          >
-          </a-entity>
-
-          <a-entity gltf-model-plus="inflate: true;"
-                    class="model">
-            <template data-name="RootScene">
-              <a-entity
-                  ik-controller
-                  hand-pose__left
-                  hand-pose__right
-                  hand-pose-controller__left="networkedAvatar:#player-rig;eventSrc:#player-left-controller"
-                  hand-pose-controller__right="networkedAvatar:#player-rig;eventSrc:#player-right-controller"
-              ></a-entity>
-            </template>
+                haptic-feedback
+                body="type: static; shape: none;"
+                mixin="controller-super-hands"
+                controls-shape-offset
+                action-to-event__a="path: /actions/leftHandStartTeleport; event: left-teleport_down;"
+                action-to-event__b="path: /actions/leftHandStopTeleport; event: left-teleport_up;"
+                action-to-event__c="path: /actions/leftHandGrab; event: primary_hand_grab;"
+                action-to-event__d="path: /actions/leftHandDrop; event: primary_hand_release;"
+            >
+            </a-entity>
 
-            <template data-name="Neck">
-              <a-entity>
-                <a-entity class="nametag" visible="false" text ></a-entity>
-              </a-entity>
-            </template>
+            <a-entity
+                id="player-right-controller"
+                class="right-controller"
+                hand-controls2="right"
+                tracked-controls
+                teleport-controls="
+                    cameraRig: #player-rig;
+                    teleportOrigin: #player-camera;
+                    button: right-teleport_;
+                    collisionEntities: [nav-mesh];
+                    drawIncrementally: true;
+                    incrementalDrawMs: 300;
+                    hitOpacity: 0.3;
+                    missOpacity: 0.1;
+                    curveShootingSpeed: 12;"
+                haptic-feedback
+                body="type: static; shape: none;"
+                mixin="controller-super-hands"
+                controls-shape-offset
+                action-to-event__a="path: /actions/rightHandStartTeleport; event: right-teleport_down;"
+                action-to-event__b="path: /actions/rightHandStopTeleport; event: right-teleport_up;"
+                action-to-event__c="path: /actions/rightHandGrab; event: primary_hand_grab;"
+                action-to-event__d="path: /actions/rightHandDrop; event: primary_hand_release;"
+            >
+            </a-entity>
 
-            <template data-name="Head">
-              <a-entity id="player-head" visible="false" bone-visibility></a-entity>
-            </template>
+            <a-entity gltf-model-plus="inflate: true;" class="model">
+                <template data-name="RootScene">
+                    <a-entity
+                        ik-controller
+                        hand-pose__left
+                        hand-pose__right
+                        hand-pose-controller__left="networkedAvatar:#player-rig;eventSrc:#player-left-controller"
+                        hand-pose-controller__right="networkedAvatar:#player-rig;eventSrc:#player-right-controller"
+                    ></a-entity>
+                </template>
+
+                <template data-name="Neck">
+                    <a-entity>
+                        <a-entity class="nametag" visible="false" text ></a-entity>
+                    </a-entity>
+                </template>
 
-            <template data-name="LeftHand">
-              <a-entity bone-visibility></a-entity>
-            </template>
+                <template data-name="Head">
+                    <a-entity id="player-head" visible="false" bone-visibility></a-entity>
+                </template>
 
-            <template data-name="RightHand">
-              <a-entity bone-visibility></a-entity>
-            </template>
+                <template data-name="LeftHand">
+                    <a-entity bone-visibility></a-entity>
+                </template>
 
-          </a-entity>
+                <template data-name="RightHand">
+                    <a-entity bone-visibility></a-entity>
+                </template>
+            </a-entity>
         </a-entity>
 
         <!-- Environment -->
diff --git a/src/spoke.html b/src/spoke.html
index 4cdea285a2a48fe96ef7ae28b8bc8826f328bd4b..2a93ef9d2327135e17ec2481a1f767d7d0b1efdd 100644
--- a/src/spoke.html
+++ b/src/spoke.html
@@ -20,7 +20,7 @@
 </head>
 
 <body>
-  <div id="ui-root"></div>
+    <div id="ui-root"></div>
 </body>
 
 </html>
diff --git a/src/spoke.js b/src/spoke.js
index c82a3c898a3c4080af29f8046f20f09a7ca3a9f6..d1f4fb3aa7322667d62faa8edf2b57adc296f48a 100644
--- a/src/spoke.js
+++ b/src/spoke.js
@@ -77,7 +77,7 @@ class SpokeLanding extends Component {
         query: `
           {
             repository(owner: "mozillareality", name: "spoke") {
-          releases(
+              releases(
                 orderBy: { field: CREATED_AT, direction: DESC },
                 first: 5
               ) {