diff --git a/src/css/detect.css b/src/css/detect.css
new file mode 100644
index 0000000..7fba46f
--- /dev/null
+++ b/src/css/detect.css
@@ -0,0 +1,183 @@
+/*Styles for the structure detection page*/
+/*Basic style*/
+.detect-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr 56px auto min-content;
+ grid-template-areas:
+ "image-view"
+ "result-view"
+ "detect-settings"
+ "menu-view";
+ justify-items: center;
+ height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
+ max-height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
+}
+
+.image-container {
+ grid-area: image-view;
+ width: 100%;
+ height: 100%;
+ min-width: 0;
+ min-height: 0;
+ position: relative;
+ display: flex;
+ align-self: stretch;
+}
+
+.popover-button-menu {
+ max-width: 90vw;
+ max-height: 90vh;
+ width: auto;
+}
+
+.segment-button-menu {
+ flex-wrap: nowrap;
+ flex-direction: column;
+ max-height: 100%;
+ min-height: 0px;
+}
+
+.chip-media {
+ background-color: var(--chip-media-background) !important;
+}
+
+.chip-results {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 5px;
+ padding: 10px;
+ --f7-chip-border-radius: 16px;
+ --f7-chip-media-size: 32px;
+ --f7-chip-font-weight: normal;
+ overflow-y: auto;
+ max-height: 100%;
+}
+
+.chip-results .chip {
+ padding-left: 8px;
+}
+
+.selected-chip {
+ font-weight: 500;
+ box-shadow: 4px 4px 1px var(--avn-theme-color);
+ transform: translate(-2px, -2px);
+}
+
+.detect-inputs {
+ display: flex;
+ align-items: center;
+ margin: 5px;
+ width: 100%;
+ max-width: 400px;
+ min-width: 192px;
+}
+
+.level-slide-vert {
+ display: none;
+}
+
+.image-menu {
+ grid-area: menu-view;
+ margin: 5px;
+ max-width: 400px;
+ min-width: 192px;
+}
+
+.image-menu .button {
+ aspect-ratio: 1;
+ height: auto;
+ padding: 5px;
+ flex: 1 1 0%;
+}
+
+.image-menu > .button > svg {
+ aspect-ratio: 1;
+ height: auto;
+ width: 100%;
+}
+
+.segment-button-menu .button {
+ padding: 8px;
+ aspect-ratio: 1;
+ width: auto;
+ flex: 1 1 0%;
+ max-height: 100px;
+ max-width: 100px;
+}
+
+/*Additional styles for small format landscape orientation*/
+@media (max-height: 450px) and (orientation: landscape) {
+ .detect-grid {
+ grid-template-columns: minmax(0,1fr) minmax(56px,max-content) auto auto;
+ grid-template-rows: calc(100vh - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom) - 64px);
+ grid-template-areas:
+ "image-view result-view detect-settings menu-view";
+ justify-items: stretch;
+ align-items: stretch;
+ height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
+ max-height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
+ position: relative;
+ }
+
+ .chip-results {
+ flex-direction: column;
+ max-height: 100%;
+ justify-self: start;
+ flex-wrap: nowrap;
+ }
+
+ .detect-inputs {
+ flex-direction: column;
+ min-width: 0;
+ max-width: 72px;
+ }
+
+ .level-slide-horz {
+ display: none;
+ }
+
+ .level-slide-vert {
+ display: block;
+ }
+
+
+ .image-container {
+ flex-direction: column;
+ }
+
+ .image-menu {
+ flex-direction: column;
+ aspect-ratio: .25;
+ width: auto;
+ min-width: 0;
+ height: 100%;
+ }
+
+ .image-menu .button {
+ aspect-ratio: 1;
+ width: auto;
+ height: 100%;
+ flex: 1 1 0%;
+ border-bottom: 1px solid var(--f7-segmented-raised-divider-color);
+ border-bottom-left-radius: 0px !important;
+ }
+
+ .segment-button-menu {
+ flex-direction: row;
+ max-height: 100%;
+ min-height: 0px;
+ }
+
+ .segment-button-menu .button {
+ height: auto;
+ flex: 1 1 0%;
+ max-height: 100px;
+ max-width: 100px;
+ }
+
+ .button > svg {
+ width: 100%;
+ height: auto;
+ }
+}
diff --git a/src/pages/camera-mixin.js b/src/pages/camera-mixin.js
new file mode 100644
index 0000000..a40539a
--- /dev/null
+++ b/src/pages/camera-mixin.js
@@ -0,0 +1,45 @@
+export default {
+ methods: {
+ async openCamera() {
+ var cameraLoaded = false
+ const devicesList = await navigator.mediaDevices.enumerateDevices()
+ this.videoDeviceAvailable = devicesList.some( d => d.kind == "videoinput")
+ if (this.videoDeviceAvailable) {
+ navigator.mediaDevices.getUserMedia({video: true})
+ var vidConstraint = {
+ video: {
+ width: {
+ ideal: 1920
+ },
+ height: {
+ ideal: 1080
+ },
+ facingMode: 'environment'
+ },
+ audio: false
+ }
+ const stream = await navigator.mediaDevices.getUserMedia(vidConstraint);
+ cameraLoaded = true
+ this.cameraStream = stream
+ }
+ return cameraLoaded
+ },
+ closeCamera () {
+ this.cameraStream.getTracks().forEach( t => t.stop())
+ this.videoAvailable = false
+ },
+ captureVidFrame() {
+ const vidViewer = this.$refs.vid_viewer
+ vidViewer.pause()
+ let tempCVS = document.createElement('canvas')
+ tempCVS.height = vidViewer.videoHeight || parseInt(vidViewer.style.height)
+ tempCVS.width = vidViewer.videoWidth || parseInt(vidViewer.style.width)
+ const tempCtx = tempCVS.getContext('2d')
+ tempCtx.drawImage(vidViewer, 0, 0)
+ this.getImage(tempCVS.toDataURL())
+ },
+ async videoStream() {
+ //TODO
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/pages/detect.vue b/src/pages/detect.vue
index 5800a42..d46a385 100644
--- a/src/pages/detect.vue
+++ b/src/pages/detect.vue
@@ -99,189 +99,7 @@
-
+