From 51b4b64eae4749542590785bca9d33d3ccdded69 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 19 May 2025 19:43:28 -0400
Subject: fixed text boxes to calculate height correctly.  removed usertag
 modification time in text.  fixed masonry and stacking views with pivots.

---
 .../CollectionStackingViewFieldColumn.tsx          | 30 ++++++++++++----------
 1 file changed, 17 insertions(+), 13 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingViewFieldColumn.tsx')

diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 345f60e75..8c7cb8276 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { DivHeight, DivWidth, returnEmptyString, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
@@ -50,14 +50,14 @@ interface CSVFieldColumnProps {
     addDocument: (doc: Doc | Doc[]) => boolean;
     createDropTarget: (ele: HTMLDivElement) => void;
     screenToLocalTransform: () => Transform;
-    refList: HTMLElement[];
+    colStackRefs: HTMLElement[];
+    colHeaderRefs: HTMLElement[];
 }
 
 @observer
 export class CollectionStackingViewFieldColumn extends ObservableReactComponent<CSVFieldColumnProps> {
     private dropDisposer?: DragManager.DragDropDisposer;
     private _disposers: { [name: string]: IReactionDisposer } = {};
-    private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
     @observable _background = 'inherit';
     @observable _paletteOn = false;
     @observable _heading = '';
@@ -72,6 +72,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
 
     _ele: HTMLElement | null = null;
     _eleMasonrySingle = React.createRef<HTMLDivElement>();
+    _headerRef: HTMLDivElement | null = null;
 
     protected onInternalPreDrop = (e: Event, de: DragManager.DropEvent, targetDropAction: dropActionType) => {
         const dragData = de.complete.docDragData;
@@ -93,13 +94,13 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
     createColumnDropRef = (ele: HTMLDivElement | null) => {
         this.dropDisposer?.();
         if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Doc, this.onInternalPreDrop.bind(this));
-        else if (this._eleMasonrySingle.current) this.props.refList.splice(this.props.refList.indexOf(this._eleMasonrySingle.current), 1);
+        else if (this._eleMasonrySingle.current) runInAction(() => this.props.colStackRefs.splice(this.props.colStackRefs.indexOf(this._eleMasonrySingle.current!), 1));
         this._ele = ele;
     };
 
     @action
     componentDidMount() {
-        this._eleMasonrySingle.current && this.props.refList.push(this._eleMasonrySingle.current);
+        this._eleMasonrySingle.current && this.props.colStackRefs.push(this._eleMasonrySingle.current);
         this._disposers.collapser = reaction(
             () => this._props.headingObject?.collapsed,
             collapsed => { this.collapsed = collapsed !== undefined ? BoolCast(collapsed) : false; }, // prettier-ignore
@@ -108,7 +109,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
     }
     componentWillUnmount() {
         this._disposers.collapser?.();
-        this._ele && this.props.refList.splice(this.props.refList.indexOf(this._ele), 1);
+        this._ele && runInAction(() => this.props.colStackRefs.splice(this.props.colStackRefs.indexOf(this._ele!), 1));
         this._ele = null;
     }
 
@@ -192,7 +193,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
         value = typeof value === 'string' ? `"${value}"` : value;
         embedding.viewSpecScript = ScriptField.MakeFunction(`doc.${this._props.pivotField} === ${value}`, { doc: Doc.name });
         if (embedding.viewSpecScript) {
-            DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([embedding]), e.clientX, e.clientY);
+            DragManager.StartDocumentDrag([this._headerRef!], new DragManager.DocumentDragData([embedding]), e.clientX, e.clientY);
             return true;
         }
         return false;
@@ -314,9 +315,14 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
             <div
                 key={heading}
                 className="collectionStackingView-sectionHeader"
-                ref={this._headerRef}
+                ref={r => {
+                    if (this._headerRef && this._props.colHeaderRefs.includes(this._headerRef)) this._props.colHeaderRefs.splice(this._props.colStackRefs.indexOf(this._headerRef), 1);
+                    r && this._props.colHeaderRefs.push(r);
+                    this._headerRef = r;
+                }}
                 style={{
-                    marginTop: this._props.yMargin,
+                    marginTop: 0,
+                    marginBottom: this._props.gridGap,
                     width: this._props.columnWidth,
                 }}>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
@@ -367,7 +373,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
                             ref={this._eleMasonrySingle}
                             className="collectionStackingView-masonrySingle"
                             style={{
-                                padding: `${columnYMargin}px ${0}px ${this._props.yMargin}px ${0}px`,
+                                padding: `${columnYMargin}px ${0}px ${0}px ${0}px`,
                                 margin: this._props.dontCenter.includes('x') ? undefined : 'auto',
                                 height: 'max-content',
                                 position: 'relative',
@@ -400,15 +406,13 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
 
     render() {
         TraceMobx();
-        const headings = this._props.headings();
         const heading = this._heading;
-        const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
         return (
             <div
                 className="collectionStackingViewFieldColumn"
                 key={heading}
                 style={{
-                    width: `${100 / (uniqueHeadings.length + (this._props.chromeHidden ? 0 : 1) || 1)}%`,
+                    width: this._props.columnWidth,
                     height: undefined,
                     background: this._background,
                 }}
-- 
cgit v1.2.3-70-g09d2


From 2d6307f6eaa0803aefabae9e9232506611365b66 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 13 Jun 2025 09:00:49 -0400
Subject: updated css and project to HTML5 standards.  fixed border rounding
 for images.

---
 .eslintrc.json                                     |  11 +-
 .stylelintrc.json                                  |  15 +++
 deploy/index.html                                  |   1 +
 package-lock.json                                  |  66 +++++++++
 package.json                                       |   5 +-
 .../components/src/components/Button/Button.scss   |  10 +-
 .../src/components/Button/Button.stories.tsx       | 149 +++++++++++----------
 .../src/components/Dropdown/Dropdown.scss          |   4 +-
 .../src/components/EditableText/EditableText.scss  |  10 +-
 .../src/components/FormInput/FormInput.scss        |   2 +-
 .../components/src/components/Overlay/Overlay.scss |   6 +-
 .../src/components/Toggle/Toggle.stories.tsx       |  54 ++++----
 .../components/src/global/globalCssVariables.scss  |   2 +-
 src/client/util/BranchingTrailManager.tsx          |   3 -
 src/client/util/CaptureManager.scss                |   6 +-
 src/client/util/CurrentUserUtils.ts                |   4 +-
 src/client/util/GroupManager.scss                  |  19 ++-
 src/client/util/GroupMemberView.scss               |  20 ++-
 src/client/util/LinkFollower.ts                    |   2 +-
 src/client/util/PingManager.ts                     |   2 +-
 src/client/util/SettingsManager.scss               |  30 ++---
 src/client/util/SharingManager.scss                |  51 ++++---
 src/client/util/TrackMovements.ts                  |   2 -
 src/client/util/clamp.js                           |  24 ++--
 src/client/util/convertToCSSPTValue.js             |   9 +-
 src/client/util/reportManager/ReportManager.scss   |  30 ++---
 src/client/util/reportManager/ReportManager.tsx    |   2 -
 src/client/views/ContextMenu.scss                  |  12 +-
 src/client/views/DashboardView.scss                |   8 +-
 src/client/views/DocumentDecorations.scss          |  32 ++---
 src/client/views/DocumentDecorations.tsx           |   4 +-
 src/client/views/EditableView.scss                 |   9 +-
 src/client/views/FilterPanel.scss                  |  54 +++-----
 src/client/views/GestureOverlay.scss               |   2 +-
 src/client/views/InkStroke.scss                    |   4 +-
 src/client/views/InkTangentHandles.tsx             |   2 -
 src/client/views/LightboxView.scss                 |  48 +++----
 src/client/views/Main.scss                         |   6 +-
 src/client/views/MainView.scss                     |  40 +++---
 src/client/views/MainView.tsx                      |   2 +-
 src/client/views/MetadataEntryMenu.scss            |  20 +--
 src/client/views/OverlayView.scss                  |  12 +-
 src/client/views/PreviewCursor.scss                |   4 +-
 src/client/views/PropertiesSection.tsx             |   1 -
 src/client/views/PropertiesView.scss               |  50 +++----
 src/client/views/SidebarAnnos.scss                 |  12 +-
 src/client/views/StyleProvider.scss                |  22 +--
 src/client/views/StyleProviderQuiz.scss            |   8 +-
 src/client/views/animationtimeline/Timeline.scss   |   4 +-
 .../views/animationtimeline/TimelineMenu.tsx       |   4 +-
 .../views/animationtimeline/TimelineOverview.tsx   |   5 +-
 .../views/collections/CollectionCardDeckView.scss  |   4 +-
 .../collections/CollectionCarousel3DView.scss      |  12 +-
 .../views/collections/CollectionCarouselView.scss  |  16 +--
 .../views/collections/CollectionDockingView.scss   | 132 +++++++++---------
 .../collections/CollectionMasonryViewFieldRow.tsx  |   4 +-
 .../collections/CollectionNoteTakingView.scss      |  30 ++---
 .../collections/CollectionStackedTimeline.scss     |  16 +--
 .../views/collections/CollectionStackingView.scss  |  34 ++---
 .../views/collections/CollectionStackingView.tsx   |   8 +-
 .../CollectionStackingViewFieldColumn.tsx          |   2 +-
 .../views/collections/CollectionTimeView.scss      |  13 +-
 .../views/collections/CollectionTreeView.scss      |   6 +-
 src/client/views/collections/CollectionView.scss   |   8 +-
 .../views/collections/FlashcardPracticeUI.scss     |   8 +-
 src/client/views/collections/KeyRestrictionRow.tsx |  72 ----------
 src/client/views/collections/TabDocView.scss       |   4 +-
 src/client/views/collections/TreeView.scss         |   4 +-
 .../CollectionFreeFormRemoteCursors.scss           |   2 +-
 .../collectionFreeForm/CollectionFreeFormView.scss |  32 ++---
 .../collectionFreeForm/FaceCollectionBox.scss      |  14 +-
 .../collectionFreeForm/MarqueeView.scss            |   6 +-
 .../collectionGrid/CollectionGridView.scss         |   6 +-
 .../collectionLinear/CollectionLinearView.scss     |   8 +-
 .../CollectionMulticolumnView.scss                 |   8 +-
 .../CollectionMultirowView.scss                    |   4 +-
 .../collectionMulticolumn/MulticolumnResizer.tsx   |   1 -
 .../collectionMulticolumn/MultirowHeightLabel.tsx  |   1 -
 .../collectionMulticolumn/MultirowResizer.tsx      |   3 +-
 .../collectionSchema/CollectionSchemaView.scss     |  10 +-
 src/client/views/linking/LinkMenuItem.scss         |   4 +-
 src/client/views/linking/LinkPopup.scss            |   6 +-
 src/client/views/linking/LinkPopup.tsx             |   1 -
 src/client/views/newlightbox/NewLightboxView.scss  |   4 +-
 .../components/Recommendation/Recommendation.scss  |   2 +-
 src/client/views/nodes/AudioBox.scss               |   4 +-
 .../nodes/CollectionFreeFormDocumentView.scss      |   4 +-
 src/client/views/nodes/ComparisonBox.scss          |  18 +--
 src/client/views/nodes/DataVizBox/DataVizBox.scss  |  10 +-
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.scss  |  26 ++--
 .../views/nodes/DataVizBox/SchemaCSVPopUp.scss     |   8 +-
 .../views/nodes/DataVizBox/components/Chart.scss   |   4 +-
 src/client/views/nodes/DocumentLinksButton.scss    |   4 +-
 src/client/views/nodes/DocumentView.scss           |  37 ++---
 .../views/nodes/FontIconBox/FontIconBadge.scss     |   2 +-
 .../views/nodes/FontIconBox/FontIconBox.scss       |  20 +--
 src/client/views/nodes/IconTagBox.scss             |   2 +-
 src/client/views/nodes/ImageBox.scss               |  26 ++--
 src/client/views/nodes/ImageBox.tsx                |   3 +-
 src/client/views/nodes/KeyValueBox.scss            |  10 +-
 src/client/views/nodes/KeyValuePair.scss           |   2 +-
 src/client/views/nodes/LabelBox.scss               |  12 +-
 src/client/views/nodes/LinkDocPreview.scss         |   2 +-
 src/client/views/nodes/LoadingBox.scss             |   4 +-
 src/client/views/nodes/MapBox/MapAnchorMenu.scss   |  37 ++---
 src/client/views/nodes/MapBox/MapBox.scss          |  10 +-
 src/client/views/nodes/PDFBox.scss                 |  34 ++---
 .../nodes/PhysicsBox/PhysicsSimulationBox.scss     |   4 +-
 .../views/nodes/RecordingBox/ProgressBar.scss      | 141 +++++++++----------
 .../views/nodes/RecordingBox/RecordingView.scss    |  12 +-
 src/client/views/nodes/ScreenshotBox.scss          |   8 +-
 src/client/views/nodes/ScriptingBox.scss           |   6 +-
 src/client/views/nodes/VideoBox.scss               |  10 +-
 src/client/views/nodes/WebBox.scss                 |  44 +++---
 src/client/views/nodes/audio/AudioWaveform.scss    |  10 +-
 .../nodes/chatbot/chatboxcomponents/ChatBox.scss   |  14 +-
 .../chatbot/chatboxcomponents/ProgressBar.scss     |  12 +-
 .../views/nodes/formattedText/DashFieldView.scss   |   2 +-
 .../views/nodes/formattedText/EquationEditor.scss  |  10 +-
 .../nodes/formattedText/FormattedTextBox.scss      |  54 ++++----
 .../formattedText/FormattedTextBoxComment.scss     |  16 +--
 .../views/nodes/formattedText/RichTextMenu.scss    |   4 +-
 .../views/nodes/formattedText/TooltipTextMenu.scss |   8 +-
 .../views/nodes/imageEditor/ImageEditor.scss       |  10 +-
 src/client/views/nodes/trails/PresBox.scss         | 104 +++++++-------
 src/client/views/nodes/trails/PresSlideBox.scss    |  10 +-
 src/client/views/pdf/AnchorMenu.scss               |  14 +-
 src/client/views/pdf/GPTPopup/GPTPopup.scss        |  10 +-
 src/client/views/pdf/PDFViewer.scss                |  10 +-
 src/client/views/topbar/TopBar.scss                |   2 +-
 src/debug/Viewer.tsx                               |   3 -
 src/fields/FieldLoader.scss                        |   2 +-
 src/server/ApiManagers/UploadManager.ts            |   2 +-
 src/server/PdfTypes.ts                             |   2 +-
 views/stylesheets/authentication.css               |  21 +--
 135 files changed, 1096 insertions(+), 1117 deletions(-)
 create mode 100644 .stylelintrc.json
 delete mode 100644 src/client/views/collections/KeyRestrictionRow.tsx

(limited to 'src/client/views/collections/CollectionStackingViewFieldColumn.tsx')

diff --git a/.eslintrc.json b/.eslintrc.json
index aba260657..187ddbdc7 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,6 +1,6 @@
 {
     "extends": ["airbnb", "prettier", "plugin:node/recommended", "plugin:import/react"],
-    "plugins": ["prettier", "import", "@typescript-eslint"],
+    "plugins": ["prettier", "import", "@typescript-eslint", "css-modules"],
     "ignorePatterns": ["solr-8.3.1/*", "deploy/*"], // <<< ignore all files in test folder
     "settings": {
         "import/parsers": {
@@ -14,7 +14,10 @@
                 "extensions": [".js", ".ts", ".tsx"]
             }
         },
-        "import/extensions": [".js", ".jsx", ".ts", ".tsx"]
+        "import/extensions": [".js", ".jsx", ".ts", ".tsx"],
+        "css-modules": {
+            "basePath": "src" // Adjust this to your project's base path
+        }
     },
     "rules": {
         "import/extensions": [
@@ -60,7 +63,9 @@
         "no-param-reassign": ["error", { "props": false }],
         // "import/no-cycle": 0,
         "no-alert": 0,
-        "radix": "off"
+        "radix": "off",
+        "css-modules/no-unused-class": "warn", // Warn for unused CSS classes
+        "css-modules/no-undef-class": "error" // Error for undefined CSS classes
     },
     "overrides": [
         {
diff --git a/.stylelintrc.json b/.stylelintrc.json
new file mode 100644
index 000000000..c9198c5dc
--- /dev/null
+++ b/.stylelintrc.json
@@ -0,0 +1,15 @@
+{
+    "extends": ["stylelint-config-standard-scss"],
+    "plugins": ["stylelint-scss"],
+    "rules": {
+        "unit-no-unknown": true,
+        "length-zero-no-unit": true,
+        "declaration-property-unit-required": {
+            "width": ["px", "%", "em", "rem", "vw", "vh"],
+            "height": ["px", "%", "em", "rem", "vw", "vh"]
+        },
+        "property-no-unknown": true,
+        "value-no-vendor-prefix": true,
+        "scss/at-rule-no-unknown": true
+    }
+}
diff --git a/deploy/index.html b/deploy/index.html
index 1c48f24bf..b469c7032 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -1,3 +1,4 @@
+<!doctype html>
 <html style="overflow: hidden">
     <head>
         <title>Dash</title>
diff --git a/package-lock.json b/package-lock.json
index 8e7219bdb..73b8b007b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
                 "@dash/components": "file:packages/components",
                 "@emotion/react": "^11.11.1",
                 "@emotion/styled": "^11.11.0",
+                "@eslint/css": "^0.8.1",
                 "@ffmpeg-installer/ffmpeg": "^1.1.0",
                 "@ffmpeg/core": "^0.12.5",
                 "@ffmpeg/ffmpeg": "^0.12.10",
@@ -109,6 +110,7 @@
                 "dompurify": "^3.1.7",
                 "dotenv": "^16.4.7",
                 "dropbox": "^10.34.0",
+                "eslint-plugin-css-modules": "^2.12.0",
                 "eslint-webpack-plugin": "^5.0.0",
                 "exif": "^0.6.0",
                 "exifr": "^7.1.3",
@@ -4083,6 +4085,33 @@
                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             }
         },
+        "node_modules/@eslint/css": {
+            "version": "0.8.1",
+            "resolved": "https://registry.npmjs.org/@eslint/css/-/css-0.8.1.tgz",
+            "integrity": "sha512-674JJD1q8sDlJORLep+gGnm3VRCQo/qLmKQgCIf2LnUK/tHf96StWjLX2IF3yyp3yeU9npZ6ixySMr2G256eiQ==",
+            "license": "Apache-2.0",
+            "dependencies": {
+                "@eslint/core": "^0.14.0",
+                "@eslint/css-tree": "^3.3.3",
+                "@eslint/plugin-kit": "^0.3.1"
+            },
+            "engines": {
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            }
+        },
+        "node_modules/@eslint/css-tree": {
+            "version": "3.6.1",
+            "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-3.6.1.tgz",
+            "integrity": "sha512-5DIsBME23tUQD5zHD+T38lC2DG4jB8x8JRa+yDncLne2TIZA0VuCpcSazOX1EC+sM/q8w24qeevXfmfsIxAeqA==",
+            "license": "MIT",
+            "dependencies": {
+                "mdn-data": "2.21.0",
+                "source-map-js": "^1.0.1"
+            },
+            "engines": {
+                "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+            }
+        },
         "node_modules/@eslint/eslintrc": {
             "version": "3.3.1",
             "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
@@ -21145,6 +21174,22 @@
                 }
             }
         },
+        "node_modules/eslint-plugin-css-modules": {
+            "version": "2.12.0",
+            "resolved": "https://registry.npmjs.org/eslint-plugin-css-modules/-/eslint-plugin-css-modules-2.12.0.tgz",
+            "integrity": "sha512-ruFBdad69ABrbCDCh5mXj7UzNmrvytfzPACjyvZWIAjFZAG8BXpYSbqmE8gU5wF+pIzV3jU2CWhLvfekXT/IgQ==",
+            "license": "MIT",
+            "dependencies": {
+                "gonzales-pe": "^4.3.0",
+                "lodash": "^4.17.2"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            },
+            "peerDependencies": {
+                "eslint": ">=2.0.0"
+            }
+        },
         "node_modules/eslint-plugin-react": {
             "version": "7.37.5",
             "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
@@ -23084,6 +23129,21 @@
             "integrity": "sha512-sIVQCiRWOymHbVD1Aw/T9/ijbPYAVGBlgGYd1N9MRKfcyBNSpjr87Vg9nSHm+RCT8ELrvK8IJYJV0QRJuVUkCQ==",
             "license": "MIT"
         },
+        "node_modules/gonzales-pe": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz",
+            "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==",
+            "license": "MIT",
+            "dependencies": {
+                "minimist": "^1.2.5"
+            },
+            "bin": {
+                "gonzales": "bin/gonzales.js"
+            },
+            "engines": {
+                "node": ">=0.6.0"
+            }
+        },
         "node_modules/google-auth-library": {
             "version": "9.15.1",
             "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz",
@@ -26886,6 +26946,12 @@
                 "url": "https://opencollective.com/unified"
             }
         },
+        "node_modules/mdn-data": {
+            "version": "2.21.0",
+            "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.21.0.tgz",
+            "integrity": "sha512-+ZKPQezM5vYJIkCxaC+4DTnRrVZR1CgsKLu5zsQERQx6Tea8Y+wMx5A24rq8A8NepCeatIQufVAekKNgiBMsGQ==",
+            "license": "CC0-1.0"
+        },
         "node_modules/mdurl": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
diff --git a/package.json b/package.json
index 5e17a419b..e9f9dc4df 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,8 @@
         "test": "mocha -r ts-node/register test/**/*.ts",
         "tsc": "tsc -t es5",
         "storybook": "npm -w @dash/components run storybook",
-        "build-storybook": "npm -w @dash/components run build-storybook"
+        "build-storybook": "npm -w @dash/components run build-storybook",
+        "lint:css": "stylelint '**/*.{css,scss}'"
     },
     "devDependencies": {
         "@eslint/js": "^9.10.0",
@@ -104,6 +105,7 @@
         "@dash/components": "file:packages/components",
         "@emotion/react": "^11.11.1",
         "@emotion/styled": "^11.11.0",
+        "@eslint/css": "^0.8.1",
         "@ffmpeg-installer/ffmpeg": "^1.1.0",
         "@ffmpeg/core": "^0.12.5",
         "@ffmpeg/ffmpeg": "^0.12.10",
@@ -193,6 +195,7 @@
         "dompurify": "^3.1.7",
         "dotenv": "^16.4.7",
         "dropbox": "^10.34.0",
+        "eslint-plugin-css-modules": "^2.12.0",
         "eslint-webpack-plugin": "^5.0.0",
         "exif": "^0.6.0",
         "exifr": "^7.1.3",
diff --git a/packages/components/src/components/Button/Button.scss b/packages/components/src/components/Button/Button.scss
index c86db9fad..c87198ddf 100644
--- a/packages/components/src/components/Button/Button.scss
+++ b/packages/components/src/components/Button/Button.scss
@@ -20,8 +20,8 @@
     pointer-events: all;
 
     &.icon {
-        padding: 0;
-        gap: 0;
+        padding: 0px;
+        gap: 0px;
     }
 
     .button-content {
@@ -44,8 +44,8 @@
         width: 100%;
         height: 100%;
         z-index: 0;
-        left: 0;
-        top: 0;
+        left: 0px;
+        top: 0px;
         position: absolute;
         transition: 0.4s;
     }
@@ -111,7 +111,7 @@
 
     .label {
         position: absolute;
-        bottom: 0;
+        bottom: 0px;
         width: 100%;
         display: flex;
         justify-content: center;
diff --git a/packages/components/src/components/Button/Button.stories.tsx b/packages/components/src/components/Button/Button.stories.tsx
index 3893d9ded..9e7e8cb05 100644
--- a/packages/components/src/components/Button/Button.stories.tsx
+++ b/packages/components/src/components/Button/Button.stories.tsx
@@ -1,94 +1,97 @@
-import { Meta, Story } from '@storybook/react'
-import React from 'react'
-import * as bi from 'react-icons/bi'
-import { Button, IButtonProps } from '..'
-import { Colors, Size } from '../../global/globalEnums'
-import { Type , getFormLabelSize } from '../../global'
+import { Meta, Story } from '@storybook/react';
+import React from 'react';
+import * as bi from 'react-icons/bi';
+import { Button, IButtonProps } from '..';
+import { Type } from '../../global';
+import { Size } from '../../global/globalEnums';
 
 export default {
-  title: 'Dash/Button',
-  component: Button,
-  argTypes: {},
-} as Meta<typeof Button>
+    title: 'Dash/Button',
+    component: Button,
+    argTypes: {},
+} as Meta<typeof Button>;
 
-const Template: Story<IButtonProps> = (args) => <Button {...args} />
+const Template: Story<IButtonProps> = args => <Button {...args} />;
 
-export const Primary = Template.bind({})
+export const Primary = Template.bind({});
 Primary.args = {
-  onClick: () => {},
-  text: 'Primary',
-  type: Type.PRIM,
-  style: {
-    fontWeight: 600
-  },
-  tooltip: 'Primary button'
-}
+    onClick: () => {},
+    text: 'Primary',
+    type: Type.PRIM,
+    style: {
+        fontWeight: 600,
+    },
+    tooltip: 'Primary button',
+};
 
-export const Secondary = Template.bind({})
+export const Secondary = Template.bind({});
 Secondary.args = {
-  onClick: () => {},
-  text: 'Secondary',
-  type: Type.SEC,
-  tooltip: 'Secondary button'
-}
+    onClick: () => {},
+    text: 'Secondary',
+    type: Type.SEC,
+    tooltip: 'Secondary button',
+    color: 'green',
+    background: 'yellow',
+};
 
-export const Tertiary = Template.bind({})
+export const Tertiary = Template.bind({});
 Tertiary.args = {
-  onClick: () => {},
-  text: 'Tertiary',
-  type: Type.TERT,
-  size: Size.SMALL,
-}
+    onClick: () => {},
+    text: 'Tertiary',
+    type: Type.TERT,
+    size: Size.SMALL,
+    background: 'yellow',
+};
 
-export const Small = Template.bind({})
+export const Small = Template.bind({});
 Small.args = {
-  onClick: () => {},
-  text: 'Small',
-  type: Type.PRIM,
-  size: Size.SMALL,
-}
+    onClick: () => {},
+    text: 'Small',
+    type: Type.PRIM,
+    size: Size.SMALL,
+};
 
-export const Medium = Template.bind({})
+export const Medium = Template.bind({});
 Medium.args = {
-  onClick: () => {},
-  text: 'Medium',
-  type: Type.PRIM,
-  size: Size.MEDIUM,
-}
+    onClick: () => {},
+    text: 'Medium',
+    type: Type.PRIM,
+    size: Size.MEDIUM,
+};
 
-export const Large = Template.bind({})
+export const Large = Template.bind({});
 Large.args = {
-  onClick: () => {},
-  text: 'Large',
-  type: Type.PRIM,
-  size: Size.LARGE,
-}
+    onClick: () => {},
+    text: 'Large',
+    type: Type.PRIM,
+    size: Size.LARGE,
+};
 
-export const ButtonWithLeftIcon = Template.bind({})
+export const ButtonWithLeftIcon = Template.bind({});
 ButtonWithLeftIcon.args = {
-  onClick: () => {},
-  text: 'New',
-  icon: <bi.BiPlus />,
-  iconPosition: 'left',
-  type: Type.PRIM,
-}
+    onClick: () => {},
+    text: 'New',
+    icon: <bi.BiPlus />,
+    iconPosition: 'left',
+    type: Type.PRIM,
+};
 
-export const ButtonWithRightIcon = Template.bind({})
+export const ButtonWithRightIcon = Template.bind({});
 ButtonWithRightIcon.args = {
-  onClick: () => {},
-  text: 'More',
-  iconPosition: 'right',
-  icon: <bi.BiMobile />,
-  type: Type.PRIM,
-}
+    onClick: () => {},
+    text: 'More',
+    iconPosition: 'right',
+    icon: <bi.BiMobile />,
+    type: Type.PRIM,
+};
 
-export const Label = Template.bind({})
+export const Label = Template.bind({});
 Label.args = {
-  onClick: () => {},
-  text: 'Label',
-  type: Type.PRIM,
-  style: {
-    fontWeight: 600
-  },
-  tooltip: 'Label button'
-}
\ No newline at end of file
+    onClick: () => {},
+    text: 'Label',
+    type: Type.PRIM,
+    style: {
+        fontWeight: 600,
+    },
+    tooltip: 'Label button',
+};
diff --git a/packages/components/src/components/Dropdown/Dropdown.scss b/packages/components/src/components/Dropdown/Dropdown.scss
index f9ea2711a..516c229a5 100644
--- a/packages/components/src/components/Dropdown/Dropdown.scss
+++ b/packages/components/src/components/Dropdown/Dropdown.scss
@@ -129,8 +129,8 @@
     .dropdown-toggle-mini {
         .toggle-caret {
             position: absolute;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
         }
     }
 }
diff --git a/packages/components/src/components/EditableText/EditableText.scss b/packages/components/src/components/EditableText/EditableText.scss
index 15965e97e..691b05590 100644
--- a/packages/components/src/components/EditableText/EditableText.scss
+++ b/packages/components/src/components/EditableText/EditableText.scss
@@ -16,18 +16,18 @@
         justify-content: center;
         align-items: center;
         height: 100%;
-        right: 0;
-        top: 0;
+        right: 0px;
+        top: 0px;
     }
 
     .editableText-background {
         width: 100%;
         height: 100%;
-        z-index: -1;
+        z-index: -1px;
         position: absolute;
         transition: 0.4s;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
     }
 
     &.primary {
diff --git a/packages/components/src/components/FormInput/FormInput.scss b/packages/components/src/components/FormInput/FormInput.scss
index 2554cbd01..187827724 100644
--- a/packages/components/src/components/FormInput/FormInput.scss
+++ b/packages/components/src/components/FormInput/FormInput.scss
@@ -58,7 +58,7 @@
 
     .formInput-label {
         position: absolute;
-        top: 0;
+        top: 0px;
         transform: translate(0px, 8px);
         display: block;
         transition: 0.2s;
diff --git a/packages/components/src/components/Overlay/Overlay.scss b/packages/components/src/components/Overlay/Overlay.scss
index 5ba4f802c..2c3d9530d 100644
--- a/packages/components/src/components/Overlay/Overlay.scss
+++ b/packages/components/src/components/Overlay/Overlay.scss
@@ -1,9 +1,9 @@
 .overlay-container {
     width: 100vw;
     height: 100vh;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     background: pink;
     position: absolute;
     pointer-events: none;
-}
\ No newline at end of file
+}
diff --git a/packages/components/src/components/Toggle/Toggle.stories.tsx b/packages/components/src/components/Toggle/Toggle.stories.tsx
index 28ab2e712..6adf63424 100644
--- a/packages/components/src/components/Toggle/Toggle.stories.tsx
+++ b/packages/components/src/components/Toggle/Toggle.stories.tsx
@@ -1,35 +1,37 @@
-import { Meta, Story } from '@storybook/react'
-import React from 'react'
-import * as bi from 'react-icons/bi'
-import { IToggleProps, Toggle, ToggleType } from './Toggle'
-import { Type , getFormLabelSize } from '../../global'
+import { Meta, Story } from '@storybook/react';
+import React from 'react';
+import * as bi from 'react-icons/bi';
+import { Type } from '../../global';
+import { IToggleProps, Toggle, ToggleType } from './Toggle';
 
 export default {
-  title: 'Dash/Toggle',
-  component: Toggle,
-  argTypes: {},
-} as Meta<typeof Toggle>
+    title: 'Dash/Toggle',
+    component: Toggle,
+    argTypes: {},
+} as Meta<typeof Toggle>;
 
-const Template: Story<IToggleProps> = (args) => <Toggle {...args} />
+const Template: Story<IToggleProps> = args => <Toggle {...args} />;
 
-export const Button = Template.bind({})
+export const Button = Template.bind({});
 Button.args = {
-  // text: 'Button',
-  type: Type.TERT,
-  icon: <bi.BiAbacus/>,
-  toggleType: ToggleType.BUTTON,
-  tooltip: 'Test tooltip'
-}
+    // text: 'Button',
+    type: Type.PRIM,
+    icon: <bi.BiAbacus />,
+    toggleType: ToggleType.BUTTON,
+    tooltip: 'Test tooltip',
+    color: 'green',
+    background: 'yellow',
+};
 
-export const Checkbox = Template.bind({})
+export const Checkbox = Template.bind({});
 Checkbox.args = {
-  type: Type.SEC,
-  toggleType: ToggleType.CHECKBOX
-}
+    type: Type.SEC,
+    toggleType: ToggleType.CHECKBOX,
+};
 
-export const Switch = Template.bind({})
+export const Switch = Template.bind({});
 Switch.args = {
-  text: 'Button',
-  type: Type.SEC,
-  toggleType: ToggleType.SWITCH
-}
\ No newline at end of file
+    text: 'Button',
+    type: Type.SEC,
+    toggleType: ToggleType.SWITCH,
+};
diff --git a/packages/components/src/global/globalCssVariables.scss b/packages/components/src/global/globalCssVariables.scss
index ebc44106d..99fe7fb11 100644
--- a/packages/components/src/global/globalCssVariables.scss
+++ b/packages/components/src/global/globalCssVariables.scss
@@ -59,7 +59,7 @@ $small-text: 9px;
 // $sans-serif: "Roboto Slab", sans-serif;
 
 // misc values
-$search-thumnail-size: 130;
+$search-thumnail-size: 130px;
 $topbar-height: 50px;
 $antimodemenu-height: 36px;
 
diff --git a/src/client/util/BranchingTrailManager.tsx b/src/client/util/BranchingTrailManager.tsx
index 65336812d..a0871514c 100644
--- a/src/client/util/BranchingTrailManager.tsx
+++ b/src/client/util/BranchingTrailManager.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable react/no-unused-class-component-methods */
-/* eslint-disable react/no-array-index-key */
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -52,7 +50,6 @@ export class BranchingTrailManager extends React.Component {
         this.slideHistoryStack = newArr;
     });
 
-    // eslint-disable-next-line react/sort-comp
     observeDocumentChange = (targetDoc: Doc, pres: PresBox) => {
         const presId = pres.Document[Id];
         if (this.prevPresId === presId) {
diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss
index e7cbb4287..9e81f2669 100644
--- a/src/client/util/CaptureManager.scss
+++ b/src/client/util/CaptureManager.scss
@@ -67,7 +67,7 @@
         font-weight: bold;
         text-align: left;
         color: black;
-        width: 80;
+        width: 80px;
         margin-right: 50px;
         margin-bottom: 5px;
     }
@@ -114,8 +114,8 @@
     .buttons {
         display: flex;
         position: absolute;
-        bottom: 0;
-        right: 15;
+        bottom: 0px;
+        right: 15px;
         justify-content: flex-end;
         align-items: center;
         height: 60px;
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index a25c491d9..45feb0b2f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -562,7 +562,7 @@ pie title Minerals in my tap water
         const reqdToolOps:DocumentOptions = {
             title: "My Tools", isSystem: true, ignoreClick: true, layout_boxShadow: "0 0",
             layout_explainer: "This is a palette of documents that can be created.", _layout_dontCenter: "y",
-            _layout_showTitle: "title", _width: 500, _yMargin: 20, _lockedPosition: true, _forceActive: true, _dragOnlyWithinContainer: true, layout_hideContextMenu: true, _chromeHidden: true, 
+            _layout_showTitle: "title", _width: 500, _lockedPosition: true, _forceActive: true, _dragOnlyWithinContainer: true, layout_hideContextMenu: true, _chromeHidden: true, 
         };
         return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdToolOps, [creatorBtns, userBtns]);
     }
@@ -994,7 +994,7 @@ pie title Minerals in my tap water
         const reqdOpts:DocumentOptions = {
             title: "My Imports", _forceActive: true, _layout_showTitle: "title", childLayoutString: ImportElementBox.LayoutString('data'),
             _dragOnlyWithinContainer: true, layout_hideContextMenu: true, childLimitHeight: 0, onClickScriptDisable:"never",
-            childDragAction: dropActionType.copy, _layout_autoHeight: true, _yMargin: 50, _gridGap: 15, layout_boxShadow: "0 0", _lockedPosition: true, isSystem: true, _chromeHidden: true,
+            childDragAction: dropActionType.copy, _layout_autoHeight: true, _gridGap: 15, layout_boxShadow: "0 0", _lockedPosition: true, isSystem: true,
             dontRegisterView: true, layout_explainer: "This is where documents that are Imported into Dash will go."
         };
         const myImports = DocUtils.AssignDocField(doc, field, (opts) => Docs.Create.MasonryDocument([], opts), reqdOpts, undefined, {onClick: "deselectAll()"});
diff --git a/src/client/util/GroupManager.scss b/src/client/util/GroupManager.scss
index 673af16ee..66f11c529 100644
--- a/src/client/util/GroupManager.scss
+++ b/src/client/util/GroupManager.scss
@@ -21,7 +21,6 @@
         }
 
         .group-input {
-
             input {
                 padding: 8px;
                 width: 100%;
@@ -33,13 +32,13 @@
                 border-color: inherit;
                 background: white;
                 color: black;
-                height: 30;
+                height: 30px;
             }
         }
 
         .select-users {
-            margin-right: 3;
-            max-height: 30;
+            margin-right: 3px;
+            max-height: 30px;
             width: 100%;
             display: inline-flex;
             flex-direction: row;
@@ -51,7 +50,6 @@
         }
     }
 
-
     button {
         align-self: center;
         outline: none;
@@ -108,7 +106,7 @@
 
         .sort-groups {
             text-align: left;
-            margin-left: 5;
+            margin-left: 5px;
             width: 50px;
             cursor: pointer;
             display: flex;
@@ -122,7 +120,7 @@
 
         .group-body {
             justify-content: space-between;
-            height: 225;
+            height: 225px;
 
             padding-right: 1em;
             justify-content: space-around;
@@ -149,8 +147,8 @@
                 button {
                     position: absolute;
                     width: 30%;
-                    right: 2;
-                    margin-top: 0;
+                    right: 2px;
+                    margin-top: 0px;
                 }
             }
 
@@ -161,7 +159,6 @@
                 min-width: 100%;
                 margin: 2px 0;
             }
-
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/util/GroupMemberView.scss b/src/client/util/GroupMemberView.scss
index d50569b26..cb1a4e098 100644
--- a/src/client/util/GroupMemberView.scss
+++ b/src/client/util/GroupMemberView.scss
@@ -6,7 +6,7 @@
     overflow: visible;
 
     hr {
-        margin-top: 20;
+        margin-top: 20px;
     }
 
     button {
@@ -31,7 +31,7 @@
     }
 
     .editing-header {
-        margin-bottom: 5;
+        margin-bottom: 5px;
 
         .group-title {
             font-weight: bold;
@@ -39,7 +39,7 @@
             text-align: center;
             border: none;
             outline: none;
-            height: 20;
+            height: 20px;
             text-overflow: ellipsis;
             background: none;
 
@@ -57,12 +57,12 @@
 
         .group-buttons {
             display: flex;
-            margin-top: 5;
-            margin-bottom: 25;
+            margin-top: 5px;
+            margin-bottom: 25px;
 
             .add-member-dropdown {
-                margin-right: 3;
-                max-height: 30;
+                margin-right: 3px;
+                max-height: 30px;
                 width: 250px;
                 display: inline-flex;
                 flex-direction: row;
@@ -108,11 +108,9 @@
 
             .remove-button {
                 position: absolute;
-                right: 10;
+                right: 10px;
                 cursor: pointer;
             }
         }
     }
-
-
-}
\ No newline at end of file
+}
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index 6081c3fae..a4f54f1cf 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -134,6 +134,6 @@ export class LinkFollower {
 
 // eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function followLink(doc: Doc, altKey: boolean) {
-    DocumentView.DeselectAll();
+    // DocumentView.DeselectAll();
     return LinkFollower.FollowLink(undefined, doc, altKey) ? undefined : { select: true };
 });
diff --git a/src/client/util/PingManager.ts b/src/client/util/PingManager.ts
index 0e4f8cab0..593978b4a 100644
--- a/src/client/util/PingManager.ts
+++ b/src/client/util/PingManager.ts
@@ -27,7 +27,7 @@ export class PingManager {
             this.IsBeating = status;
             setTimeout(this.showAlert, 100);
         });
-        Networking.PostToServer('/ping', { date: new Date() })
+        Networking.PostToServer('/DashPing', { date: new Date() })
             .then(res => {
                 SnappingManager.SetServerVersion((res as { message: string }).message);
                 !this.IsBeating && setIsBeating(true);
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index f81f17589..51b719200 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -26,7 +26,7 @@
         font-size: 16;
         font-weight: bold;
         text-align: left;
-        width: 80;
+        width: 80px;
         margin-right: 50px;
     }
 
@@ -81,7 +81,7 @@
 
         .acl-text {
             color: black;
-            margin-top: 2;
+            margin-top: 2px;
             text-align: left;
         }
     }
@@ -119,7 +119,7 @@
 
         .preferences-color-text {
             margin-top: 3px;
-            margin-right: 4;
+            margin-right: 4px;
             flex: 1 1 auto;
             text-align: left;
         }
@@ -134,8 +134,8 @@
         margin-top: 2px;
 
         .preferences-font-text {
-            margin-top: 4;
-            margin-right: 4;
+            margin-top: 4px;
+            margin-right: 4px;
             margin-bottom: 2px;
             text-align: left;
         }
@@ -149,7 +149,7 @@
         .font-select {
             height: 35px;
             font-size: 9;
-            margin-right: 6;
+            margin-right: 6px;
             border-radius: 5px;
             width: 65%;
 
@@ -171,9 +171,9 @@
     }
 
     .preferences-check {
-        margin-right: 4;
+        margin-right: 4px;
         margin-bottom: -3;
-        margin-left: 5;
+        margin-left: 5px;
         margin-top: -1px;
         display: inline-block;
         padding-left: 5px;
@@ -205,14 +205,14 @@
     .error-text {
         color: #c40233;
         font-size: 10;
-        margin-bottom: 4;
+        margin-bottom: 4px;
     }
 
     .success-text {
-        width: 300;
+        width: 300px;
         margin-left: -20;
         font-size: 10;
-        margin-bottom: 4;
+        margin-bottom: 4px;
         margin-top: -3;
         color: #009f6b;
     }
@@ -225,7 +225,7 @@
         text-transform: uppercase;
         letter-spacing: 2px;
         font-size: 19;
-        margin-top: 0;
+        margin-top: 0px;
         font-weight: bold;
     }
 
@@ -246,7 +246,7 @@
         font-style: normal;
         font-size: 15;
         font-weight: normal;
-        padding: 0;
+        padding: 0px;
 
         .padding {
             padding: 0 0 0 20px;
@@ -273,8 +273,8 @@
         align-items: center;
         flex-direction: column;
         bottom: 10px;
-        left: 0;
-        right: 0;
+        left: 0px;
+        right: 0px;
 
         .settings-username {
             padding-right: 0px;
diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss
index c9f86f0e1..553f3a184 100644
--- a/src/client/util/SharingManager.scss
+++ b/src/client/util/SharingManager.scss
@@ -4,7 +4,7 @@
 
     .select {
         text-align: justify;
-        text-align-last: end
+        text-align-last: end;
     }
 
     .sharing-contents {
@@ -36,15 +36,14 @@
         }
 
         .share-container {
-
             .share-setup {
                 display: flex;
                 margin-bottom: 20px;
                 align-items: center;
-                max-height: 28;
+                max-height: 28px;
 
                 .user-search {
-                    max-height: 30;
+                    max-height: 30px;
                     width: 90%;
                     display: inline-flex;
                     flex-direction: row;
@@ -68,7 +67,7 @@
                     text-align-last: end;
                     font-size: 13px;
                     min-width: 90px;
-                    height: 28;
+                    height: 28px;
                     margin-left: 2px;
                 }
 
@@ -99,8 +98,8 @@
                 display: flex;
                 float: right;
                 align-items: baseline;
-                margin-top: -12;
-                margin-bottom: 10;
+                margin-top: -12px;
+                margin-bottom: 10px;
 
                 .layoutDoc-acls,
                 .myDocs-acls {
@@ -109,7 +108,7 @@
                     label {
                         font-weight: normal;
                         font-style: italic;
-                        padding-right: 12;
+                        padding-right: 12px;
                     }
 
                     input {
@@ -127,13 +126,13 @@
             .group-container {
                 width: 50%;
                 display: flex;
-                top:0;
+                top: 0px;
                 flex-direction: column;
                 border-radius: 4px;
 
                 .user-sort {
                     text-align: left;
-                    margin-left: 10;
+                    margin-left: 10px;
                     width: 100%;
                     cursor: pointer;
                 }
@@ -180,7 +179,7 @@
             padding: 0 10;
             margin: 0 5;
             transition: transform 0.2s;
-            height: 25;
+            height: 25px;
         }
     }
 
@@ -205,7 +204,7 @@
 
         .people-with {
             font-size: 14px;
-            margin: 0;
+            margin: 0px;
             padding-top: 3px;
             font-style: normal;
         }
@@ -216,30 +215,30 @@
         }
     }
 
-    .title-individual{
+    .title-individual {
         height: 25px;
-        padding-left: 2;
+        padding-left: 2px;
         width: 97%;
         border-radius: 4px;
         margin-top: 10px;
         margin-left: -8px;
         font-size: 14;
-        margin-bottom: -4;
+        margin-bottom: -4px;
         border: 2px solid;
         border-bottom: none;
         align-items: center;
         display: flex;
     }
 
-    .title-group{
+    .title-group {
         height: 25px;
-        padding-left: 2;
+        padding-left: 2px;
         width: 97%;
         border-radius: 4px;
         margin-top: 10px;
         margin-left: -8px;
         font-size: 14;
-        margin-bottom: -4;
+        margin-bottom: -4px;
         border: 2px solid;
         border-bottom: none;
         align-items: center;
@@ -289,18 +288,17 @@
             text-align: right;
             margin-left: auto;
             margin-right: -12px;
-
         }
 
         .edit-actions {
             display: flex;
             position: absolute;
             align-items: flex-end;
-            right: -10;            
+            right: -10px;
         }
     }
 
-    .permissions-dropdown-None{
+    .permissions-dropdown-None {
         height: 100%;
         min-width: 85px;
         text-align: right;
@@ -325,7 +323,7 @@
         border-radius: 6px;
         border: 1px solid rgb(75, 75, 5);
     }
-    .permissions-dropdown-Augment{
+    .permissions-dropdown-Augment {
         height: 100%;
         min-width: 85px;
         text-align: right;
@@ -333,12 +331,11 @@
         padding: 0px;
         padding-left: 3px;
         background: rgb(208, 255, 208);
-        color:rgb(19, 80, 19);
+        color: rgb(19, 80, 19);
         border-radius: 6px;
         border: 1px solid rgb(19, 80, 19);
-
     }
-    .permissions-dropdown-View{
+    .permissions-dropdown-View {
         height: 100%;
         min-width: 85px;
         text-align: right;
@@ -350,7 +347,7 @@
         border-radius: 6px;
         border: 1px solid rgb(25, 25, 101);
     }
-    .permissions-dropdown-Not-Shared{
+    .permissions-dropdown-Not-Shared {
         height: 100%;
         min-width: 85px;
         text-align: right;
@@ -398,4 +395,4 @@
     //         padding-top: 12px;
     //     }
     // }
-}
\ No newline at end of file
+}
diff --git a/src/client/util/TrackMovements.ts b/src/client/util/TrackMovements.ts
index 7da0281c0..74a3be83d 100644
--- a/src/client/util/TrackMovements.ts
+++ b/src/client/util/TrackMovements.ts
@@ -98,7 +98,6 @@ export class TrackMovements {
 
         // new tab was added - need to add it
         if (tabbedFFViews.size > this.recordingFFViews.size) {
-            // eslint-disable-next-line no-restricted-syntax
             for (const DashDoc of tabbedDocs) {
                 if (!this.recordingFFViews.has(DashDoc)) {
                     if (isFFView(DashDoc)) {
@@ -112,7 +111,6 @@ export class TrackMovements {
         }
         // tab was removed - need to remove it from recordingFFViews
         else if (tabbedFFViews.size < this.recordingFFViews.size) {
-            // eslint-disable-next-line no-restricted-syntax
             for (const [doc] of this.recordingFFViews) {
                 if (!tabbedFFViews.has(doc)) {
                     this.removeRecordingFFView(doc);
diff --git a/src/client/util/clamp.js b/src/client/util/clamp.js
index 9c7fd78a4..8d74b5636 100644
--- a/src/client/util/clamp.js
+++ b/src/client/util/clamp.js
@@ -1,15 +1,15 @@
-"use strict";
+'use strict';
 
-Object.defineProperty(exports, "__esModule", {
-  value: true
+Object.defineProperty(exports, '__esModule', {
+    value: true,
 });
-exports.default = clamp;
 function clamp(min, val, max) {
-  if (val < min) {
-    return min;
-  }
-  if (val > max) {
-    return max;
-  }
-  return val;
-}
\ No newline at end of file
+    if (val < min) {
+        return min;
+    }
+    if (val > max) {
+        return max;
+    }
+    return val;
+}
+exports.default = clamp;
diff --git a/src/client/util/convertToCSSPTValue.js b/src/client/util/convertToCSSPTValue.js
index 66f8db5a1..032385d81 100644
--- a/src/client/util/convertToCSSPTValue.js
+++ b/src/client/util/convertToCSSPTValue.js
@@ -3,11 +3,8 @@
 Object.defineProperty(exports, '__esModule', {
     value: true,
 });
-exports.PT_TO_PX_RATIO = exports.PX_TO_PT_RATIO = undefined;
-exports.default = convertToCSSPTValue;
-exports.toClosestFontPtSize = toClosestFontPtSize;
 
-var SIZE_PATTERN = /([\d\.]+)(px|pt)/i;
+var SIZE_PATTERN = /([\d.]+)(px|pt)/i;
 
 var PX_TO_PT_RATIO = (exports.PX_TO_PT_RATIO = 0.7518796992481203); // 1 / 1.33.
 var PT_TO_PX_RATIO = (exports.PT_TO_PX_RATIO = 1.33);
@@ -39,3 +36,7 @@ function toClosestFontPtSize(styleValue) {
         return Math.abs(curr - originalPTValue) < Math.abs(prev - originalPTValue) ? curr : prev;
     }, Number.NEGATIVE_INFINITY);
 }
+
+exports.PT_TO_PX_RATIO = exports.PX_TO_PT_RATIO = undefined;
+exports.default = convertToCSSPTValue;
+exports.toClosestFontPtSize = toClosestFontPtSize;
diff --git a/src/client/util/reportManager/ReportManager.scss b/src/client/util/reportManager/ReportManager.scss
index 806741c22..65894fbd6 100644
--- a/src/client/util/reportManager/ReportManager.scss
+++ b/src/client/util/reportManager/ReportManager.scss
@@ -14,8 +14,8 @@
     }
 
     h2 {
-        margin: 0;
-        padding: 0;
+        margin: 0px;
+        padding: 0px;
         font-size: 24px;
     }
 }
@@ -27,8 +27,8 @@
     gap: 4px;
 
     h2 {
-        margin: 0;
-        padding: 0;
+        margin: 0px;
+        padding: 0px;
         padding-bottom: 8px;
         font-size: 24px;
     }
@@ -92,7 +92,7 @@
     outline: none;
     border-bottom: 1px solid;
     padding: 8px;
-    padding-left: 0;
+    padding-left: 0px;
     transition: all 0.2s ease;
     background: transparent;
 
@@ -178,15 +178,15 @@
         cursor: pointer;
         font-size: 14px;
         font-weight: 400;
-        padding: 0;
-        margin: 0;
+        padding: 0px;
+        margin: 0px;
     }
 
     .issue-title {
         font-size: 16px;
         font-weight: 500;
-        padding: 0;
-        margin: 0;
+        padding: 0px;
+        margin: 0px;
     }
 }
 
@@ -211,8 +211,8 @@
 
 .file-list {
     box-sizing: border-box;
-    margin: 0;
-    padding: 0;
+    margin: 0px;
+    padding: 0px;
     font-size: 14px;
     width: 100%;
     overflow-x: auto;
@@ -251,8 +251,8 @@
 
     .issue-title {
         font-size: 24px;
-        margin: 0;
-        padding: 0;
+        margin: 0px;
+        padding: 0px;
     }
 
     .issue-date {
@@ -314,8 +314,8 @@
     .report-media-content::after {
         content: '';
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         width: 100%;
         height: 100%;
         background-color: rgba(0, 0, 0, 0.5); /* Adjust the opacity as desired */
diff --git a/src/client/util/reportManager/ReportManager.tsx b/src/client/util/reportManager/ReportManager.tsx
index a6b5911f7..87e8a8bf1 100644
--- a/src/client/util/reportManager/ReportManager.tsx
+++ b/src/client/util/reportManager/ReportManager.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/no-unused-class-component-methods */
 import { Octokit } from '@octokit/core';
 import { Button, Dropdown, DropdownType, IconButton, Type } from '@dash/components';
 import { action, makeObservable, observable } from 'mobx';
@@ -31,7 +30,6 @@ export class ReportManager extends React.Component<object> {
     @observable private isOpen = false;
 
     @observable private query = '';
-    // eslint-disable-next-line react/sort-comp
     @action private setQuery = (q: string) => {
         this.query = q;
     };
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index d22c4d096..337c976cb 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -68,8 +68,8 @@
         width: 100%;
         height: 100%;
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         z-index: 0;
         filter: opacity(0);
     }
@@ -187,10 +187,10 @@
         display: flex;
 
         .close-menu {
-            margin-top: 0;
-            margin-bottom: 0;
-            margin-right: 0;
-            padding: 0;
+            margin-top: 0px;
+            margin-bottom: 0px;
+            margin-right: 0px;
+            padding: 0px;
             margin-left: auto;
             z-index: 999999999;
             width: 20px;
diff --git a/src/client/views/DashboardView.scss b/src/client/views/DashboardView.scss
index daa711bc4..d74441b9c 100644
--- a/src/client/views/DashboardView.scss
+++ b/src/client/views/DashboardView.scss
@@ -79,8 +79,8 @@ $dashboard-container-width: 250px;
         position: absolute;
         width: 100%;
         height: 100%;
-        left: 0;
-        top: 0;
+        left: 0px;
+        top: 0px;
         z-index: -1;
     }
 }
@@ -137,8 +137,8 @@ $dashboard-container-width: 250px;
         position: absolute;
         width: 100%;
         height: 100%;
-        left: 0;
-        top: 0;
+        left: 0px;
+        top: 0px;
         z-index: -1;
     }
 }
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index 55eb0b127..25a806abd 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -11,8 +11,8 @@ $resizeHandler: 8px;
     // Rotation handler
     .documentDecorations-rotation {
         border-radius: 100%;
-        height: 30;
-        width: 30;
+        height: 30px;
+        width: 30px;
         right: -40;
         bottom: -20;
         //top: calc(50% - 15px);
@@ -45,15 +45,15 @@ $resizeHandler: 8px;
         width: 100%;
         pointer-events: all;
         border-radius: 50%;
-        top: 30; // offset by height of documentButtonBar so that items can be clicked without overlap interference
+        top: 30px; // offset by height of documentButtonBar so that items can be clicked without overlap interference
         color: black;
     }
 }
 
 .documentDecorations-container {
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     transform-origin: 50% calc(50% + 10px);
     display: grid;
     grid-template-rows: $headerHeight $resizeHandler 1fr $resizeHandler;
@@ -121,7 +121,7 @@ $resizeHandler: 8px;
                 }
 
                 > svg {
-                    margin: 0;
+                    margin: 0px;
                 }
             }
 
@@ -150,7 +150,7 @@ $resizeHandler: 8px;
                 }
 
                 > svg {
-                    margin: 0;
+                    margin: 0px;
                 }
             }
             &:hover {
@@ -185,7 +185,7 @@ $resizeHandler: 8px;
             }
 
             > svg {
-                margin: 0;
+                margin: 0px;
             }
         }
 
@@ -246,7 +246,7 @@ $resizeHandler: 8px;
                 display: inline;
                 position: relative;
                 top: -2.5;
-                left: 35;
+                left: 35px;
                 zoom: 0.7;
             }
 
@@ -360,8 +360,8 @@ $resizeHandler: 8px;
         left: 7px;
         top: 7px;
         background: global.$medium-gray;
-        height: 10;
-        width: 10;
+        height: 10px;
+        width: 10px;
         opacity: 0.5;
         pointer-events: all;
         cursor: nwse-resize;
@@ -371,8 +371,8 @@ $resizeHandler: 8px;
         position: relative;
         background: black;
         color: rgb(145, 144, 144);
-        height: 20;
-        width: 20;
+        height: 20px;
+        width: 20px;
         pointer-events: all;
         margin: auto;
         display: flex;
@@ -380,8 +380,8 @@ $resizeHandler: 8px;
         border-radius: 100%;
         cursor: default;
         svg {
-            width: 10;
-            height: 10;
+            width: 10px;
+            height: 10px;
             margin: auto;
         }
     }
@@ -389,7 +389,7 @@ $resizeHandler: 8px;
     .documentDecorations-rotationPath {
         position: absolute;
         width: 100%;
-        height: 0;
+        height: 0px;
         transform: translate(0px, -25%);
         padding-bottom: 100%;
         border-radius: 100%;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 69c2467a3..2db334583 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -911,8 +911,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
                                         transform: `rotate(${rotation}deg)`,
                                         width: this.Bounds.r - this.Bounds.x + 'px',
                                         height: this.Bounds.b - this.Bounds.y + 'px',
-                                        left: this.Bounds.x,
-                                        top: this.Bounds.y,
+                                        left: this.Bounds.r,
+                                        top: this.Bounds.b,
                                         pointerEvents: 'none',
                                     }}>
                                     {this._isRotating ? null : (
diff --git a/src/client/views/EditableView.scss b/src/client/views/EditableView.scss
index fa4542ac4..333939d03 100644
--- a/src/client/views/EditableView.scss
+++ b/src/client/views/EditableView.scss
@@ -6,14 +6,14 @@
     overflow-y: auto;
     height: 100%;
     width: 100%;
-    min-width: 20;
+    min-width: 20px;
     text-overflow: ellipsis;
-    -ms-overflow-style: none; 
-    scrollbar-width: none; 
+    -ms-overflow-style: none;
+    scrollbar-width: none;
 }
 
 .editableView-container-editing::-webkit-scrollbar {
-    display: none; 
+    display: none;
 }
 
 .editableView-container-editing-oneLine {
@@ -44,4 +44,3 @@
     border: none;
     outline: none;
 }
-
diff --git a/src/client/views/FilterPanel.scss b/src/client/views/FilterPanel.scss
index 508b1ee1f..e32db000f 100644
--- a/src/client/views/FilterPanel.scss
+++ b/src/client/views/FilterPanel.scss
@@ -1,4 +1,3 @@
-
 .filterBox-flyout {
     display: block;
     text-align: left;
@@ -29,7 +28,7 @@
 
 // .filterBox-bottom {
 //     // position: fixed;
-//     // bottom: 0;
+//     // bottom: 0px;
 //     // width: 100%;
 // }
 
@@ -88,7 +87,7 @@
 //     padding-bottom: 20px;
 //     border-bottom: 2px solid black;
 //     position: fixed;
-//     top: 0;
+//     top: 0px;
 //     width: 100%;
 // }
 
@@ -154,8 +153,8 @@
     flex-direction: column;
     width: 100%;
     position: relative;
-    right: 0;
-    top: 0;
+    right: 0px;
+    top: 0px;
     z-index: 1;
     //  background-color:  #9f9f9f;
 
@@ -240,60 +239,52 @@
     transition: all 0.3s ease-out;
     display: flex;
     flex-direction: row;
-    padding: 5px; 
-
+    padding: 5px;
 
-    &:hover{
+    &:hover {
         border-color: #e9e9e9;
-        background-color: #6d6c6c
+        background-color: #6d6c6c;
     }
 
-    .hotKey-icon, .hotKey-close{
+    .hotKey-icon,
+    .hotKey-close {
         background-color: transparent;
         border-radius: 10%;
         padding: 5px;
 
-
-        &:hover{
+        &:hover {
             background-color: #616060;
         }
     }
 
-    .hotKey-close{
+    .hotKey-close {
         right: 30px;
-        position: fixed;  
+        position: fixed;
         padding-top: 10px;
-  
-}
+    }
 
-    .hotkey-title{
+    .hotkey-title {
         top: 6px;
         position: relative;
         cursor: text;
-
     }
 
-    .hotkey-title-input{
+    .hotkey-title-input {
         background-color: transparent;
         border: none;
         border-color: transparent;
         outline: none;
         cursor: text;
-
     }
 }
 
 .hotKeyButtons {
     position: relative;
     width: 100%;
-
 }
 
 .hotKey-icon-button {
-
-        background-color: transparent;
-
-
+    background-color: transparent;
 }
 
 .icon-panel {
@@ -305,24 +296,19 @@
     border-radius: 10%;
     background-color: #323232;
 
-    .icon-panel-button{
+    .icon-panel-button {
         background-color: #323232;
         border-radius: 10%;
 
-
-        &:hover{
-            background-color:#7a7878
+        &:hover {
+            background-color: #7a7878;
         }
     }
-
-
-
 }
 
-
 // .sliderBox-outerDiv {
 //     width: 30%;// width: calc(100% - 14px);   // 14px accounts for handles that are at the max value of the slider that would extend outside the box
-//     height: 40; // height: 100%;
+//     height: 40px; // height: 100%;
 //     border-radius: inherit;
 //     display: flex;
 //     flex-direction: column;
diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss
index bfe2d5c64..0fa3fd973 100644
--- a/src/client/views/GestureOverlay.scss
+++ b/src/client/views/GestureOverlay.scss
@@ -3,7 +3,7 @@
     height: 100%;
     position: absolute;
     touch-action: none;
-    top: 0;
+    top: 0px;
 
     .pointerBubbles {
         width: 100%;
diff --git a/src/client/views/InkStroke.scss b/src/client/views/InkStroke.scss
index c672824bf..0595283fc 100644
--- a/src/client/views/InkStroke.scss
+++ b/src/client/views/InkStroke.scss
@@ -8,8 +8,8 @@
     svg:not(:root) {
         overflow: visible !important;
         position: absolute;
-        left: 0;
-        top: 0;
+        left: 0px;
+        top: 0px;
     }
 }
 
diff --git a/src/client/views/InkTangentHandles.tsx b/src/client/views/InkTangentHandles.tsx
index 577acc4d1..0af46df5d 100644
--- a/src/client/views/InkTangentHandles.tsx
+++ b/src/client/views/InkTangentHandles.tsx
@@ -105,7 +105,6 @@ export class InkTangentHandles extends React.Component<InkHandlesProps> {
         return (
             <>
                 {tangentHandles.map((pts, i) => (
-                    // eslint-disable-next-line react/no-array-index-key
                     <svg height="10" width="10" key={`hdl${i}`}>
                         <circle
                             cx={pts.X}
@@ -135,7 +134,6 @@ export class InkTangentHandles extends React.Component<InkHandlesProps> {
                         />
                     );
                     return (
-                        // eslint-disable-next-line react/no-array-index-key
                         <svg height="100" width="100" key={`line${i}`}>
                             {tangentLine(pts.X1, pts.Y1, pts.X2, pts.Y2)}
                             {tangentLine(pts.X2, pts.Y2, pts.X3, pts.Y3)}
diff --git a/src/client/views/LightboxView.scss b/src/client/views/LightboxView.scss
index 3e65843df..7a481d887 100644
--- a/src/client/views/LightboxView.scss
+++ b/src/client/views/LightboxView.scss
@@ -1,12 +1,12 @@
 .lightboxView-navBtn {
     margin: auto;
     position: absolute;
-    right: 19;
-    top: 10;
+    right: 19px;
+    top: 10px;
     background: transparent;
-    border-radius: 8;
+    border-radius: 8px;
     opacity: 0.7;
-    width: 25;
+    width: 25px;
     flex-direction: column;
     display: flex;
     &:hover {
@@ -16,12 +16,12 @@
 .lightboxView-tabBtn {
     margin: auto;
     position: absolute;
-    right: 54;
-    top: 10;
+    right: 54px;
+    top: 10px;
     background: transparent;
-    border-radius: 8;
+    border-radius: 8px;
     opacity: 0.7;
-    width: 25;
+    width: 25px;
     flex-direction: column;
     display: flex;
     &:hover {
@@ -31,12 +31,12 @@
 .lightboxView-paletteBtn {
     margin: auto;
     position: absolute;
-    right: 89;
-    top: 10;
+    right: 89px;
+    top: 10px;
     background: transparent;
-    border-radius: 8;
+    border-radius: 8px;
     opacity: 0.7;
-    width: 25;
+    width: 25px;
     flex-direction: column;
     display: flex;
     &:hover {
@@ -47,12 +47,12 @@
 .lightboxView-penBtn {
     margin: auto;
     position: absolute;
-    right: 124;
-    top: 10;
+    right: 124px;
+    top: 10px;
     background: transparent;
-    border-radius: 8;
+    border-radius: 8px;
     opacity: 0.7;
-    width: 25;
+    width: 25px;
     flex-direction: column;
     display: flex;
     &:hover {
@@ -62,12 +62,12 @@
 .lightboxView-exploreBtn {
     margin: auto;
     position: absolute;
-    right: 159;
-    top: 10;
+    right: 159px;
+    top: 10px;
     background: transparent;
-    border-radius: 8;
+    border-radius: 8px;
     opacity: 0.7;
-    width: 25;
+    width: 25px;
     flex-direction: column;
     display: flex;
     &:hover {
@@ -76,8 +76,8 @@
 }
 .lightboxView-frame {
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     width: 100%;
     height: 100%;
     z-index: 1000;
@@ -91,9 +91,9 @@
             margin: auto;
             position: relative;
             background: transparent;
-            border-radius: 8;
+            border-radius: 8px;
             opacity: 0.7;
-            width: 35;
+            width: 35px;
             &:hover {
                 opacity: 1;
             }
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index bea1de435..df4160fc1 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -12,10 +12,10 @@ body {
     overflow: hidden;
     font-family: global.$sans-serif;
     font-size: global.$body-text;
-    margin: 0;
+    margin: 0px;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
 }
 
 // div {
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index db949285b..d5e6b8998 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -10,7 +10,7 @@ body {
 .dash-tooltip {
     font-size: 11px;
     padding: 2px;
-    max-width: 150;
+    max-width: 150px;
     line-height: 150%;
 }
 
@@ -49,8 +49,8 @@ body {
 
 .mainView-snapLines {
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     width: 100%;
     height: 100%;
     pointer-events: none;
@@ -61,8 +61,8 @@ body {
     height: 100%;
     position: absolute;
     pointer-events: all;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     z-index: 1;
     touch-action: none;
 }
@@ -86,8 +86,8 @@ body {
 .properties-container {
     height: 100%;
     position: absolute;
-    right: 0;
-    top: 0;
+    right: 0px;
+    top: 0px;
 }
 
 .mainView-propertiesDragger-minified,
@@ -98,7 +98,7 @@ body {
     width: 17px;
     position: absolute;
     top: 50%;
-    border-radius: 0;
+    border-radius: 0px;
     border-top-left-radius: 10px;
     border-bottom-left-radius: 10px;
     border-right: unset;
@@ -141,7 +141,7 @@ body {
     }
 
     .propertiesView {
-        left: 0;
+        left: 0px;
         position: absolute;
         z-index: 2;
         //   background-color: linen; //$light-gray;
@@ -165,7 +165,7 @@ body {
     }
 
     ::-webkit-scrollbar {
-        width: 0;
+        width: 0px;
     }
 }
 
@@ -173,19 +173,19 @@ body {
     width: 100%;
     height: 100%;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     overflow: hidden;
 }
 
 .buttonContainer {
     position: absolute;
-    bottom: 0;
+    bottom: 0px;
 
     .mainView-settings {
         // position: absolute;
-        // left: 0;
-        // bottom: 0;
+        // left: 0px;
+        // bottom: 0px;
         border-radius: 25%;
         margin-left: -5px;
         background: darkblue;
@@ -198,8 +198,8 @@ body {
 
 .mainView-logout {
     position: absolute;
-    right: 0;
-    bottom: 0;
+    right: 0px;
+    bottom: 0px;
     font-size: 8px;
 }
 
@@ -223,12 +223,12 @@ body {
     }
 
     .mainView-libraryFlyout-close {
-        right: 6;
-        top: 5;
+        right: 6px;
+        top: 5px;
         position: absolute;
         margin-right: 6px;
         z-index: 10;
-        margin-bottom: 10;
+        margin-bottom: 10px;
     }
 }
 
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 686f8ed88..13b14617c 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1039,7 +1039,7 @@ export class MainView extends ObservableReactComponent<object> {
 
     @computed get inkResources() {
         return (
-            <svg width={0} height={0}>
+            <svg width={0} height={0} style={{ display: 'block' }}>
                 <defs>
                     <filter id="inkSelectionHalo">
                         <feColorMatrix
diff --git a/src/client/views/MetadataEntryMenu.scss b/src/client/views/MetadataEntryMenu.scss
index 28de0b7a5..924476a30 100644
--- a/src/client/views/MetadataEntryMenu.scss
+++ b/src/client/views/MetadataEntryMenu.scss
@@ -3,7 +3,7 @@
     width: 310px;
     flex-direction: column;
 
-    input[type=checkbox] {
+    input[type='checkbox'] {
         margin-left: 5px;
     }
 }
@@ -11,7 +11,7 @@
 .metadataEntry-autoSuggester {
     width: 80%;
     height: 100%;
-    margin: 0;
+    margin: 0px;
     display: inline-block;
 }
 
@@ -20,13 +20,13 @@
 }
 
 .metadataEntry-keys {
-    max-height: 80;
-    overflow-y: auto; 
+    max-height: 80px;
+    overflow-y: auto;
     display: flex;
     flex-direction: column;
 }
 .metadataEntry-inputArea {
-    display:inline-block;
+    display: inline-block;
     flex-direction: row;
 }
 
@@ -53,8 +53,8 @@
 }
 
 .react-autosuggest__input--open {
-    border-bottom-left-radius: 0;
-    border-bottom-right-radius: 0;
+    border-bottom-left-radius: 0px;
+    border-bottom-right-radius: 0px;
 }
 
 .react-autosuggest__suggestions-container {
@@ -78,8 +78,8 @@
 }
 
 .react-autosuggest__suggestions-list {
-    margin: 0;
-    padding: 0;
+    margin: 0px;
+    padding: 0px;
     list-style-type: none;
 }
 
@@ -90,4 +90,4 @@
 
 .react-autosuggest__suggestion--highlighted {
     background-color: #ddd;
-}
\ No newline at end of file
+}
diff --git a/src/client/views/OverlayView.scss b/src/client/views/OverlayView.scss
index 2e8621b5b..44203e38f 100644
--- a/src/client/views/OverlayView.scss
+++ b/src/client/views/OverlayView.scss
@@ -1,7 +1,7 @@
 .overlayView {
     position: absolute;
     pointer-events: none;
-    top: 0;
+    top: 0px;
     width: 100vw;
     height: 100vh;
     z-index: 2002; // shouold be greater than LightboxView's z-index so that link lines and the presentation mini player appear
@@ -14,8 +14,8 @@
     overflow: hidden;
     display: flex;
     flex-direction: column;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     pointer-events: all;
     box-shadow: black 5px 5px 5px;
 }
@@ -46,7 +46,7 @@
     float: right;
     height: 20px;
     width: 20px;
-    padding: 0;
+    padding: 0px;
     background-color: inherit;
 }
 
@@ -62,6 +62,6 @@
 .overlayView-doc {
     z-index: 9002; //so that it appears above chroma
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
 }
diff --git a/src/client/views/PreviewCursor.scss b/src/client/views/PreviewCursor.scss
index 82488c750..eef120c58 100644
--- a/src/client/views/PreviewCursor.scss
+++ b/src/client/views/PreviewCursor.scss
@@ -2,8 +2,8 @@
     color: black;
     position: absolute;
     transform-origin: left top;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     pointer-events: none;
     opacity: 1;
     z-index: 1001;
diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx
index 12a46c7a4..9ea9c3a3d 100644
--- a/src/client/views/PropertiesSection.tsx
+++ b/src/client/views/PropertiesSection.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/require-default-props */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed } from 'mobx';
 import { observer } from 'mobx-react';
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 280de4893..de3012948 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -5,7 +5,7 @@
 }
 .propertiesView-presentationTrails-title-icon {
     position: absolute;
-    right: 4;
+    right: 4px;
 }
 .propertiesView-palette {
     cursor: pointer;
@@ -24,7 +24,7 @@
 }
 .propertiesView {
     height: 100%;
-    width: 250;
+    width: 250px;
     font-family: 'Roboto';
     font-size: 12px;
     cursor: auto;
@@ -61,7 +61,7 @@
     }
 
     .propertiesView-info {
-        margin-top: -5;
+        margin-top: -5px;
         float: right;
         font-size: 20;
         path {
@@ -78,10 +78,10 @@
             display: flex;
 
             button {
-                width: 15;
-                height: 15;
-                padding: 0;
-                margin-top: -5;
+                width: 15px;
+                height: 15px;
+                padding: 0px;
+                margin-top: -5px;
             }
         }
 
@@ -89,8 +89,8 @@
             display: flex;
 
             button {
-                width: 5;
-                height: 5;
+                width: 5px;
+                height: 5px;
             }
 
             input {
@@ -171,16 +171,16 @@
                 display: flex;
 
                 button {
-                    width: 15;
-                    height: 15;
-                    padding: 0;
-                    margin-top: -5;
+                    width: 15px;
+                    height: 15px;
+                    padding: 0px;
+                    margin-top: -5px;
                 }
             }
 
             button {
-                width: 5;
-                height: 5;
+                width: 5px;
+                height: 5px;
             }
 
             input {
@@ -301,8 +301,8 @@
         padding: 7px;
         border-radius: 7px;
         margin-right: 32px;
-        width: 32;
-        height: 32;
+        width: 32px;
+        height: 32px;
         padding-top: 9px;
         margin-left: 18px;
 
@@ -318,8 +318,8 @@
         padding: 7px;
         border-radius: 7px;
         margin-right: 32px;
-        width: 32;
-        height: 32;
+        width: 32px;
+        height: 32px;
         padding-top: 9px;
         padding-left: 10px;
 
@@ -334,8 +334,8 @@
         background-color: #333333;
         padding: 7px;
         border-radius: 7px;
-        width: 32;
-        height: 32;
+        width: 32px;
+        height: 32px;
         padding-top: 9px;
         padding-left: 10px;
 
@@ -410,7 +410,7 @@
 
 .color-palette {
     width: 160px;
-    height: 360;
+    height: 360px;
 }
 
 .strokeAndFill {
@@ -465,7 +465,7 @@
     .propertiesView-selectedList {
         min-width: max-content;
         width: 100%;
-        max-height: 180;
+        max-height: 180px;
         overflow: hidden;
         overflow-y: scroll;
         border-left: solid 1px darkgrey;
@@ -475,7 +475,7 @@
         .selectedList-items {
             font-size: 12;
             font-weight: 300;
-            margin-top: 1;
+            margin-top: 1px;
         }
     }
 }
@@ -500,7 +500,7 @@
 
         .width-range {
             margin-right: 1px;
-            margin-bottom: 6;
+            margin-bottom: 6px;
         }
     }
 
diff --git a/src/client/views/SidebarAnnos.scss b/src/client/views/SidebarAnnos.scss
index abfd04f11..c2b9dcce5 100644
--- a/src/client/views/SidebarAnnos.scss
+++ b/src/client/views/SidebarAnnos.scss
@@ -2,7 +2,7 @@
     position: absolute;
     width: 100%;
     height: 100%;
-    right: 0;
+    right: 0px;
     .sidebarAnnos-stacking {
         width: 100%;
         position: relative;
@@ -20,12 +20,12 @@
     .sidebarAnnos-filterUser-active {
         font-weight: bold;
         font-size: 10px;
-        padding-left: 5;
-        padding-right: 5;
+        padding-left: 5px;
+        padding-right: 5px;
         box-shadow: black 1px 1px 3px;
-        border-radius: 5;
-        margin: 2;
-        height: 15;
+        border-radius: 5px;
+        margin: 2px;
+        height: 15px;
         background-color: lightgrey;
     }
     .sidebarAnnos-filterUser,
diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss
index 99796f1fb..cbb1fd5d5 100644
--- a/src/client/views/StyleProvider.scss
+++ b/src/client/views/StyleProvider.scss
@@ -4,11 +4,11 @@
 .styleProvider-lock {
     z-index: 2; // has to be above title which is z-index 1
     font-size: 10;
-    width: 20;
-    height: 20;
+    width: 20px;
+    height: 20px;
     position: absolute;
-    right: -20;
-    top: 0;
+    right: -20px;
+    top: 0px;
     background: black;
     pointer-events: all;
     opacity: 0.3;
@@ -20,10 +20,10 @@
     cursor: default;
 }
 .styleProvider-filter {
-    right: 20;
+    right: 20px;
     .styleProvider-filterShift {
-        left: 0;
-        top: 0;
+        left: 0px;
+        top: 0px;
         position: absolute;
     }
     .dropdown-container {
@@ -33,10 +33,10 @@
 }
 .styleProvider-paint-selected,
 .styleProvider-paint {
-    top: 15;
+    top: 15px;
 }
 .styleProvider-paint-selected {
-    right: -40;
+    right: -40px;
 }
 .styleProvider-lock:hover,
 .styleProvider-filter:hover {
@@ -45,8 +45,8 @@
 
 .styleProvider-treeView-icon,
 .styleProvider-treeView-icon-active {
-    margin-left: 0;
-    margin-right: 0;
+    margin-left: 0px;
+    margin-right: 0px;
 }
 
 .styleProvider-treeView-icon {
diff --git a/src/client/views/StyleProviderQuiz.scss b/src/client/views/StyleProviderQuiz.scss
index 84b3f1fef..53ca34c1b 100644
--- a/src/client/views/StyleProviderQuiz.scss
+++ b/src/client/views/StyleProviderQuiz.scss
@@ -13,8 +13,8 @@
 
 .check-icon {
     position: absolute;
-    right: 40;
-    bottom: 10;
+    right: 40px;
+    bottom: 10px;
     color: green;
     display: inline-block;
     font-size: 20px;
@@ -23,8 +23,8 @@
 
 .redo-icon {
     position: absolute;
-    right: 10;
-    bottom: 10;
+    right: 10px;
+    bottom: 10px;
     color: black;
     display: inline-block;
     font-size: 20px;
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss
index e1d3b190c..3a50183d2 100644
--- a/src/client/views/animationtimeline/Timeline.scss
+++ b/src/client/views/animationtimeline/Timeline.scss
@@ -112,8 +112,8 @@ $timelineDark: #77a1aa;
         input {
             position: absolute;
             opacity: 0;
-            height: 0;
-            width: 0;
+            height: 0px;
+            width: 0px;
         }
 
         .round-toggle-slider {
diff --git a/src/client/views/animationtimeline/TimelineMenu.tsx b/src/client/views/animationtimeline/TimelineMenu.tsx
index 0d7873931..79283479c 100644
--- a/src/client/views/animationtimeline/TimelineMenu.tsx
+++ b/src/client/views/animationtimeline/TimelineMenu.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { IconLookup } from '@fortawesome/fontawesome-svg-core';
 import { faChartLine, faClipboard } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -19,7 +17,7 @@ export class TimelineMenu extends React.Component {
     @observable private _y = 0;
     @observable private _currentMenu: JSX.Element[] = [];
 
-    constructor(props: any) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         TimelineMenu.Instance = this;
diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx
index 7bf685c9e..fff756980 100644
--- a/src/client/views/animationtimeline/TimelineOverview.tsx
+++ b/src/client/views/animationtimeline/TimelineOverview.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/no-unused-prop-types */
 import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -14,7 +13,7 @@ interface TimelineOverviewProps {
     isAuthoring: boolean;
     parent: Timeline;
     changeCurrentBarX: (pixel: number) => void;
-    movePanX: (pixel: number) => any;
+    movePanX: (pixel: number) => void;
     time: number;
     tickSpacing: number;
     tickIncrement: number;
@@ -139,7 +138,7 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
         const percentVisible = this.visibleTime / this.props.time;
         const visibleBarWidth = percentVisible * this.activeOverviewWidth;
 
-        const percentScrubberStart = this.currentX / this.props.time;
+        // const percentScrubberStart = this.currentX / this.props.time;
         let scrubberStart = (this.props.currentBarX / this.props.totalLength) * this.activeOverviewWidth;
         if (scrubberStart > this.activeOverviewWidth) scrubberStart = this.activeOverviewWidth;
 
diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss
index e6cc398af..981e528cc 100644
--- a/src/client/views/collections/CollectionCardDeckView.scss
+++ b/src/client/views/collections/CollectionCardDeckView.scss
@@ -18,7 +18,7 @@
 }
 
 .collectionCardView-flashcardUI {
-    top: 0;
+    top: 0px;
     position: absolute;
     width: 100%;
     height: 100%;
@@ -33,7 +33,7 @@
 }
 .collectionCardView-cardSizeDragger {
     position: absolute;
-    top: 0;
+    top: 0px;
     width: 28px;
     height: 28px;
     > svg {
diff --git a/src/client/views/collections/CollectionCarousel3DView.scss b/src/client/views/collections/CollectionCarousel3DView.scss
index 13e6b54c2..361d88cb6 100644
--- a/src/client/views/collections/CollectionCarousel3DView.scss
+++ b/src/client/views/collections/CollectionCarousel3DView.scss
@@ -12,7 +12,7 @@
     position: absolute;
     top: global.$CAROUSEL3D_TOP * 1%;
     height: (global.$CAROUSEL3D_SIDE_SCALE * 100) * 1%;
-    align-items: center;
+    //align-items: center;
     transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955);
 
     .collectionCarousel3DView-item,
@@ -67,8 +67,8 @@
 .carousel3DView-fwd-scroll-hidden {
     position: absolute;
     display: flex;
-    width: 30;
-    height: 30;
+    width: 30px;
+    height: 30px;
     align-items: center;
     border-radius: 5px;
     justify-content: center;
@@ -78,7 +78,7 @@
 
 .carousel3DView-fwd,
 .carousel3DView-back {
-    top: 0;
+    top: 0px;
     background: transparent;
     width: calc((1 - #{global.$CAROUSEL3D_CENTER_SCALE} * 0.33) / 2 * 100%);
     height: 100%;
@@ -94,13 +94,13 @@
 .carousel3DView-fwd,
 .carousel3DView-fwd-scroll,
 .carousel3DView-fwd-scroll-hidden {
-    right: 0;
+    right: 0px;
 }
 
 .carousel3DView-back,
 .carousel3DView-back-scroll,
 .carousel3DView-back-scroll-hidden {
-    left: 0;
+    left: 0px;
 }
 
 .carousel3DView-fwd-scroll-hidden,
diff --git a/src/client/views/collections/CollectionCarouselView.scss b/src/client/views/collections/CollectionCarouselView.scss
index 962b590c8..4c999b6dd 100644
--- a/src/client/views/collections/CollectionCarouselView.scss
+++ b/src/client/views/collections/CollectionCarouselView.scss
@@ -6,10 +6,10 @@
     transform-origin: top left;
 
     .collectionCarouselView-caption {
-        height: 50;
+        height: 50px;
         display: inline-block;
         width: 100%;
-        bottom: 0;
+        bottom: 0px;
         position: absolute;
     }
     .collectionCarouselView-image {
@@ -18,8 +18,8 @@
         width: 100%;
         user-select: none;
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
     }
 }
 .collectionCarouselView-recentlyMissed {
@@ -34,8 +34,8 @@
 .carouselView-fwd {
     position: absolute;
     display: flex;
-    width: 30;
-    height: 30;
+    width: 30px;
+    height: 30px;
     align-items: center;
     border-radius: 5px;
     justify-content: center;
@@ -47,12 +47,12 @@
 }
 .carouselView-fwd {
     top: calc(50% - 15px);
-    right: 0;
+    right: 0px;
     transform-origin: right top;
 }
 .carouselView-back {
     top: calc(50% - 15px);
-    left: 0;
+    left: 0px;
     transform-origin: top left;
 }
 .carouselView-back:hover,
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 7c19d39da..de214e2ef 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -17,8 +17,8 @@
 }
 .lm_maximised {
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     z-index: 40;
 }
 .lm_maximise_placeholder {
@@ -62,8 +62,8 @@
     text-align: center;
 }
 .lm_header ul {
-    margin: 0;
-    padding: 0;
+    margin: 0px;
+    padding: 0px;
     list-style-type: none;
 }
 .lm_header .lm_tab {
@@ -81,11 +81,11 @@
     position: absolute;
 }
 .lm_header .lm_tab i.lm_left {
-    top: 0;
+    top: 0px;
     left: -2px;
 }
 .lm_header .lm_tab i.lm_right {
-    top: 0;
+    top: 0px;
     right: -2px;
 }
 .lm_header .lm_tab .lm_title {
@@ -97,8 +97,8 @@
     width: 14px;
     height: 14px;
     position: absolute;
-    top: 0;
-    right: 0;
+    top: 0px;
+    right: 0px;
     text-align: center;
 }
 .lm_stack.lm_left .lm_header,
@@ -118,14 +118,14 @@
 .lm_stack.lm_left .lm_header .lm_tabs,
 .lm_stack.lm_right .lm_header .lm_tabs {
     transform-origin: left top;
-    top: 0;
+    top: 0px;
     width: 1000px;
 }
 .lm_dragProxy.lm_left .lm_header .lm_controls,
 .lm_dragProxy.lm_right .lm_header .lm_controls,
 .lm_stack.lm_left .lm_header .lm_controls,
 .lm_stack.lm_right .lm_header .lm_controls {
-    bottom: 0;
+    bottom: 0px;
 }
 .lm_dragProxy.lm_left .lm_items,
 .lm_dragProxy.lm_right .lm_items,
@@ -136,7 +136,7 @@
 .lm_dragProxy.lm_left .lm_header .lm_tabs,
 .lm_stack.lm_left .lm_header .lm_tabs {
     transform: rotate(-90deg) scaleX(-1);
-    left: 0;
+    left: 0px;
 }
 .lm_dragProxy.lm_left .lm_header .lm_tabs .lm_tab,
 .lm_stack.lm_left .lm_header .lm_tabs .lm_tab {
@@ -156,7 +156,7 @@
 .lm_stack.lm_right .lm_header .lm_tabs {
     transform: rotate(90deg) scaleX(1);
     left: 100%;
-    margin-left: 0;
+    margin-left: 0px;
 }
 .lm_dragProxy.lm_right .lm_header .lm_controls,
 .lm_stack.lm_right .lm_header .lm_controls {
@@ -169,7 +169,7 @@
 }
 .lm_dragProxy.lm_bottom .lm_header .lm_tab,
 .lm_stack.lm_bottom .lm_header .lm_tab {
-    margin-top: 0;
+    margin-top: 0px;
     border-top: none;
 }
 .lm_dragProxy.lm_bottom .lm_header .lm_controls,
@@ -189,8 +189,8 @@
 }
 .lm_header .lm_controls .lm_tabdropdown:before {
     content: '';
-    width: 0;
-    height: 0;
+    width: 0px;
+    height: 0px;
     vertical-align: middle;
     display: inline-block;
     border-top: 5px dashed;
@@ -201,14 +201,14 @@
 .lm_header .lm_tabdropdown_list {
     position: absolute;
     top: 20px;
-    right: 0;
+    right: 0px;
     z-index: 5;
     overflow: hidden;
 }
 .lm_header .lm_tabdropdown_list .lm_tab {
     clear: both;
     padding-right: 10px;
-    margin: 0;
+    margin: 0px;
 }
 .lm_header .lm_tabdropdown_list .lm_tab .lm_title {
     width: 100px;
@@ -218,8 +218,8 @@
 }
 .lm_dragProxy {
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     z-index: 30;
 }
 .lm_dragProxy .lm_header {
@@ -238,32 +238,32 @@
     width: 100%;
     height: 100%;
     position: relative;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
 }
 .lm_transition_indicator {
     display: none;
     width: 20px;
     height: 20px;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     z-index: 20;
 }
 .lm_popin {
     width: 20px;
     height: 20px;
     position: absolute;
-    bottom: 0;
-    right: 0;
+    bottom: 0px;
+    right: 0px;
     z-index: 9999;
 }
 .lm_popin > * {
     width: 100%;
     height: 100%;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
 }
 .lm_popin > .lm_bg {
     z-index: 10;
@@ -307,7 +307,7 @@
     width: max-content;
     height: 100%;
     display: flex;
-    max-width: 100;
+    max-width: 100px;
     text-overflow: ellipsis;
 }
 
@@ -328,7 +328,7 @@
 ul.lm_tabs::before {
     content: ' ';
     position: absolute;
-    bottom: 0;
+    bottom: 0px;
     width: 100%;
     z-index: 1;
     pointer-events: none;
@@ -349,9 +349,9 @@ ul.lm_tabs::before {
     }
 }
 .lm_header .lm_tab.lm_active {
-    padding: 0;
+    padding: 0px;
     opacity: 1;
-    margin: 0;
+    margin: 0px;
     box-shadow: none;
     height: 27px;
     margin-right: 2px;
@@ -405,7 +405,7 @@ ul.lm_tabs::before {
 }
 
 .lm_drag_tab {
-    padding: 0;
+    padding: 0px;
     width: 15px !important;
     height: 15px !important;
     position: relative !important;
@@ -418,7 +418,7 @@ ul.lm_tabs::before {
 
 .lm_close_tab {
     display: inline-flex !important;
-    padding: 0;
+    padding: 0px;
     opacity: 1 !important;
     align-self: center;
     margin-right: 5px;
@@ -455,7 +455,7 @@ ul.lm_tabs::before {
         content: 'x';
         margin: auto;
         position: relative;
-        top: -2;
+        top: -2px;
         font-size: medium;
         font-family: sans-serif;
     }
@@ -478,8 +478,8 @@ ul.lm_tabs::before {
     width: 100%;
     height: 100%;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
 
     .collectionDockingView-drag {
         touch-action: none;
@@ -514,7 +514,7 @@ ul.lm_tabs::before {
         border-bottom-left-radius: 10px;
         background: #93939347;
         z-index: 100;
-        //left: -3;
+        //left: -3px;
         &:hover {
             background: gray;
             color: white !important;
@@ -524,7 +524,7 @@ ul.lm_tabs::before {
         content: '+';
         margin: auto;
         font-size: x-large;
-        top: -4;
+        top: -4px;
         position: relative;
     }
     .lm_maximise {
@@ -548,10 +548,10 @@ ul.lm_tabs::before {
     }
 
     .flexlayout__layout {
-        left: 0;
-        top: 0;
-        right: 0;
-        bottom: 0;
+        left: 0px;
+        top: 0px;
+        right: 0px;
+        bottom: 0px;
         position: absolute;
         overflow: hidden;
     }
@@ -691,8 +691,8 @@ ul.lm_tabs::before {
 
     .flexlayout__tabset_header {
         position: absolute;
-        left: 0;
-        right: 0;
+        left: 0px;
+        right: 0px;
         color: #eee;
         background-color: #212121;
         padding: 3px 3px 3px 5px;
@@ -702,17 +702,17 @@ ul.lm_tabs::before {
 
     .flexlayout__tab_header_inner {
         position: absolute;
-        left: 0;
-        top: 0;
-        bottom: 0;
+        left: 0px;
+        top: 0px;
+        bottom: 0px;
         width: 10000px;
     }
 
     .flexlayout__tab_header_outer {
         background-color: global.$dark-gray;
         position: absolute;
-        left: 0;
-        right: 0;
+        left: 0px;
+        right: 0px;
         /*top: 0px;*/
         /*height: 100px;*/
         overflow: hidden;
@@ -731,23 +731,23 @@ ul.lm_tabs::before {
         display: flex;
         flex-direction: row-reverse;
         align-items: center;
-        top: 0;
-        bottom: 0;
-        right: 0;
+        top: 0px;
+        bottom: 0px;
+        right: 0px;
     }
 
     .flexlayout__tab_toolbar_button-min {
         width: 20px;
         height: 20px;
         border: none;
-        outline-width: 0;
+        outline-width: 0px;
     }
 
     .flexlayout__tab_toolbar_button-max {
         width: 20px;
         height: 20px;
         border: none;
-        outline-width: 0;
+        outline-width: 0px;
     }
 
     .flexlayout__popup_menu_item {
@@ -870,9 +870,9 @@ ul.lm_tabs::before {
         display: flex;
         flex-direction: column-reverse;
         align-items: center;
-        bottom: 0;
-        left: 0;
-        right: 0;
+        bottom: 0px;
+        left: 0px;
+        right: 0px;
     }
 
     .flexlayout__border_toolbar_right {
@@ -880,9 +880,9 @@ ul.lm_tabs::before {
         display: flex;
         flex-direction: column-reverse;
         align-items: center;
-        bottom: 0;
-        left: 0;
-        right: 0;
+        bottom: 0px;
+        left: 0px;
+        right: 0px;
     }
 
     .flexlayout__border_toolbar_top {
@@ -890,9 +890,9 @@ ul.lm_tabs::before {
         display: flex;
         flex-direction: row-reverse;
         align-items: center;
-        top: 0;
-        bottom: 0;
-        right: 0;
+        top: 0px;
+        bottom: 0px;
+        right: 0px;
     }
 
     .flexlayout__border_toolbar_bottom {
@@ -900,8 +900,8 @@ ul.lm_tabs::before {
         display: flex;
         flex-direction: row-reverse;
         align-items: center;
-        top: 0;
-        bottom: 0;
-        right: 0;
+        top: 0px;
+        bottom: 0px;
+        right: 0px;
     }
 }
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index d1f7971d4..164c6e831 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -7,6 +7,7 @@ import { emptyFunction, numberRange } from '../../../Utils';
 import { Doc } from '../../../fields/Doc';
 import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { ScriptField } from '../../../fields/ScriptField';
+import { StrCast } from '../../../fields/Types';
 import { Docs } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { CompileScript } from '../../util/Scripting';
@@ -16,6 +17,7 @@ import { undoBatch, undoable } from '../../util/UndoManager';
 import { EditableView } from '../EditableView';
 import { ObservableReactComponent } from '../ObservableReactComponent';
 import { DocumentView } from '../nodes/DocumentView';
+import { ImportElementBox } from '../nodes/importBox/ImportElementBox';
 import { CollectionStackingView } from './CollectionStackingView';
 import './CollectionStackingView.scss';
 
@@ -254,7 +256,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
         const rows = Math.max(1, Math.min(this._props.docList.length, Math.floor(this._props.panelWidth() / this._props.columnWidth())));
         return this.collapsed ? null : (
             <div style={{ position: 'relative' }}>
-                {!this._props.chromeHidden ? (
+                {!this._props.chromeHidden && !StrCast(this._props.Doc.childLayoutString).includes(ImportElementBox.name) ? (
                     <div className="collectionStackingView-addDocumentButton">
                         <EditableView GetValue={returnEmptyString} SetValue={this.addDocument} textCallback={this.textCallback} contents="+ NEW" />
                     </div>
diff --git a/src/client/views/collections/CollectionNoteTakingView.scss b/src/client/views/collections/CollectionNoteTakingView.scss
index 0d24a56b5..231085338 100644
--- a/src/client/views/collections/CollectionNoteTakingView.scss
+++ b/src/client/views/collections/CollectionNoteTakingView.scss
@@ -82,7 +82,7 @@
     height: 100%;
     width: 100%;
     position: absolute;
-    top: 0;
+    top: 0px;
     overflow-y: auto;
     overflow-x: hidden;
     transition: top 0.5s;
@@ -130,8 +130,8 @@
         display: flex;
         flex-direction: column;
         align-items: center;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         width: 100%;
         position: absolute;
         margin: auto;
@@ -152,20 +152,20 @@
     }
 
     .collectionNoteTakingView-columnDragger {
-        width: 15;
-        height: 15;
+        width: 15px;
+        height: 15px;
         position: absolute;
-        margin-left: -5;
+        margin-left: -5px;
     }
 
     .collectionNoteTakingView-sectionDelete {
         display: none;
         position: absolute;
-        right: 0;
+        right: 0px;
         width: max-content;
         height: max-content;
-        top: 10;
-        padding: 2;
+        top: 10px;
+        padding: 2px;
     }
 
     // Documents in NoteTaking view
@@ -210,8 +210,8 @@
         height: 5px;
 
         &.active {
-            margin-left: 0;
-            margin-right: 0;
+            margin-left: 0px;
+            margin-right: 0px;
             background: red;
         }
     }
@@ -303,8 +303,8 @@
 
         .collectionNoteTakingView-sectionColor {
             position: absolute;
-            left: 0;
-            top: 0;
+            left: 0px;
+            top: 0px;
             height: 100%;
             display: none;
 
@@ -345,8 +345,8 @@
 
         .collectionNoteTakingView-sectionOptions {
             position: absolute;
-            right: 0;
-            top: 0;
+            right: 0px;
+            top: 0px;
             height: 100%;
             display: none;
 
diff --git a/src/client/views/collections/CollectionStackedTimeline.scss b/src/client/views/collections/CollectionStackedTimeline.scss
index d05c0ffde..e71df2164 100644
--- a/src/client/views/collections/CollectionStackedTimeline.scss
+++ b/src/client/views/collections/CollectionStackedTimeline.scss
@@ -38,7 +38,7 @@
         height: 100%;
         background-color: global.$dark-gray;
         opacity: 0.3;
-        top: 0;
+        top: 0px;
     }
 
     .collectionStackedTimeline-trim-controls {
@@ -49,8 +49,8 @@
         display: flex;
         justify-content: space-between;
         max-width: 100%;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
 
         .collectionStackedTimeline-trim-handle {
             background-color: global.$medium-blue;
@@ -106,18 +106,18 @@
         .collectionStackedTimeline-resizer {
             background: global.$dark-gray;
             position: absolute;
-            top: 0;
+            top: 0px;
             height: 100%;
             width: 10px;
             pointer-events: all;
             z-index: 100;
         }
         .collectionStackedTimeline-resizer {
-            right: 0;
+            right: 0px;
             cursor: e-resize;
         }
         .collectionStackedTimeline-left-resizer {
-            left: 0;
+            left: 0px;
             cursor: w-resize;
         }
     }
@@ -126,8 +126,8 @@
         position: absolute;
         width: 100%;
         height: 100%;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         pointer-events: none;
     }
 }
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index d6e4943ff..2cf361847 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -16,10 +16,10 @@
     width: 100%;
 
     .collectionStackingView-columnDragger {
-        width: 28;
-        height: 28;
-        position: absolute;
-        margin-left: -5;
+        width: 28px;
+        height: 28px;
+        position: relative;
+        margin-left: -5px;
         z-index: 10;
         > svg {
             width: 100%;
@@ -55,7 +55,7 @@
         height: 100%;
         width: 100%;
         position: absolute;
-        top: 0;
+        top: 0px;
         overflow-y: auto;
         overflow-x: hidden;
         transition: top 0.5s;
@@ -93,8 +93,8 @@
         .collectionStackingView-masonryGrid {
             width: 100%;
             display: grid;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
         }
 
         .collectionStackingView-masonrySingle {
@@ -115,8 +115,8 @@
             position: absolute;
             display: flex;
             flex-direction: column;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
             width: 100%;
             position: absolute;
         }
@@ -159,12 +159,12 @@
         width: 100%;
         display: none;
         position: absolute;
-        top: 0;
+        top: 0px;
         cursor: default;
 
         &.active {
-            margin-left: 0;
-            margin-right: 0;
+            margin-left: 0px;
+            margin-right: 0px;
             background: red;
         }
     }
@@ -262,8 +262,8 @@
 
         .collectionStackingView-sectionColor {
             position: absolute;
-            left: 0;
-            top: 0;
+            left: 0px;
+            top: 0px;
             height: 100%;
             display: none;
 
@@ -304,8 +304,8 @@
 
         .collectionStackingView-sectionOptions {
             position: absolute;
-            right: 0;
-            top: 0;
+            right: 0px;
+            top: 0px;
             height: 100%;
             display: none;
 
@@ -339,7 +339,7 @@
         .collectionStackingView-sectionDelete {
             position: absolute;
             right: 0px;
-            top: 0;
+            top: 0px;
             height: 100%;
             display: none;
         }
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4a0ddc631..bdeb7d944 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -64,7 +64,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     @observable _cursor: CSS.Property.Cursor = 'ew-resize';
     // gets reset whenever we scroll. Not sure what it is
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
-    // does this mean whether the browser is hidden? Or is chrome something else entirely?
+    // whether ui/editing controls are shown
     @computed get chromeHidden() {
         return this._props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
     }
@@ -566,7 +566,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         return (
             <div key={(heading?.heading ?? '') + 'head'}>
                 {this._props.isContentActive() && !this.isStackingView && !this.chromeHidden ? this.columnDragger : null}
-                <div style={{ top: this.yMargin }}>
+                <div style={{ position: 'relative' }}>
                     <CollectionMasonryViewFieldRow
                         showHandle={first}
                         Doc={this.Document}
@@ -715,9 +715,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                             background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string,
                             pointerEvents: this._props.pointerEvents?.() ?? this.backgroundEvents,
                         }}
-                        onScroll={action(e => {
-                            this._scroll = e.currentTarget.scrollTop;
-                        })}
+                        onScroll={action(e => (this._scroll = e.currentTarget.scrollTop))}
                         onDrop={this.onExternalDrop.bind(this)}
                         onContextMenu={this.onContextMenu}
                         onWheel={e => this.isContentActive() && e.stopPropagation()}>
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 8c7cb8276..8c535534a 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -4,6 +4,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { DivHeight, DivWidth, returnEmptyString, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
 import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { DocData } from '../../../fields/DocSymbols';
 import { RichTextField } from '../../../fields/RichTextField';
 import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { ScriptField } from '../../../fields/ScriptField';
@@ -26,7 +27,6 @@ import { EditableView } from '../EditableView';
 import { DocumentView } from '../nodes/DocumentView';
 import { ObservableReactComponent } from '../ObservableReactComponent';
 import './CollectionStackingView.scss';
-import { DocData } from '../../../fields/DocSymbols';
 
 // So this is how we are storing a column
 interface CSVFieldColumnProps {
diff --git a/src/client/views/collections/CollectionTimeView.scss b/src/client/views/collections/CollectionTimeView.scss
index d995cbcd2..d56999974 100644
--- a/src/client/views/collections/CollectionTimeView.scss
+++ b/src/client/views/collections/CollectionTimeView.scss
@@ -27,7 +27,7 @@
         transform: rotate(45deg);
         display: inline-block;
         background: gray;
-        bottom: 0;
+        bottom: 0px;
         margin-bottom: -17px;
         border-radius: 9px;
         opacity: 0.25;
@@ -67,9 +67,9 @@
         pointer-events: all;
         padding: 5px;
         border: 1px solid black;
-        display:none;
+        display: none;
         span {
-            margin-left : 10px;
+            margin-left: 10px;
         }
     }
 
@@ -86,8 +86,9 @@
     }
 }
 
-.collectionTimeView:hover, .collectionTimeView-pivot:hover {
+.collectionTimeView:hover,
+.collectionTimeView-pivot:hover {
     .pivotKeyEntry {
-        display:unset;
+        display: unset;
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 2a03ea708..95faaa3f0 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -11,7 +11,7 @@
     height: 100%;
     width: 100%;
     position: relative;
-    top: 0;
+    top: 0px;
     // background: global.$light-gray;
     font-size: 13px;
     overflow: auto;
@@ -33,12 +33,12 @@
     }
 
     .no-indent {
-        padding-left: 0;
+        padding-left: 0px;
         //width: max-content;
     }
 
     .no-indent-outline {
-        padding-left: 0;
+        padding-left: 0px;
         width: 100%;
     }
 
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index 06c324bd0..837219e1d 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -1,7 +1,7 @@
 @use '../global/globalCssVariables.module.scss' as global;
 
 .collectionView {
-    border-width: 0;
+    border-width: 0px;
     border-color: global.$light-gray;
     border-style: solid;
     border-radius: 0 0 global.$border-radius global.$border-radius;
@@ -18,7 +18,7 @@
         position: absolute;
         top: 55%;
         border: 1px black solid;
-        border-radius: 0;
+        border-radius: 0px;
         border-top-left-radius: 20px;
         border-bottom-left-radius: 20px;
         border-right: unset;
@@ -31,8 +31,8 @@
         width: 200px;
         height: 100%;
         position: absolute;
-        right: 0;
-        top: 0;
+        right: 0px;
+        top: 0px;
         border-left: solid 1px;
         z-index: 1;
 
diff --git a/src/client/views/collections/FlashcardPracticeUI.scss b/src/client/views/collections/FlashcardPracticeUI.scss
index 210c6798f..0cc4711b3 100644
--- a/src/client/views/collections/FlashcardPracticeUI.scss
+++ b/src/client/views/collections/FlashcardPracticeUI.scss
@@ -8,8 +8,8 @@
 .FlashcardPracticeUI-check {
     position: absolute;
     display: flex;
-    width: 30;
-    height: 30;
+    width: 30px;
+    height: 30px;
     align-items: center;
     border-radius: 5px;
     justify-content: center;
@@ -39,7 +39,7 @@
     display: flex;
     top: 0px;
     left: 0px;
-    width: 30;
+    width: 30px;
     transform-origin: top left;
     border-radius: 5px;
     color: rgba(255, 255, 255, 0.5);
@@ -49,7 +49,7 @@
         width: 100%;
         display: flex;
         flex-direction: column;
-        top: 0;
+        top: 0px;
         position: relative;
         .FlashcardPracticeUI-quiz,
         .FlashcardPracticeUI-practice {
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
deleted file mode 100644
index 7dc08389b..000000000
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/* eslint-disable react/button-has-type */
-import { observable, runInAction } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-
-interface IKeyRestrictionProps {
-    contains: boolean;
-    script: (value: string) => void;
-    field: string;
-    value: string;
-}
-
-@observer
-export default class KeyRestrictionRow extends React.Component<IKeyRestrictionProps> {
-    @observable private _key = this.props.field;
-    @observable private _value = this.props.value;
-    @observable private _contains = this.props.contains;
-
-    render() {
-        if (this._key && this._value) {
-            let parsedValue: string | number = `"${this._value}"`;
-            const parsed = parseInt(this._value);
-            let type = 'string';
-            if (!isNaN(parsed)) {
-                parsedValue = parsed;
-                type = 'number';
-            }
-            const scriptText = `${this._contains ? '' : '!'}(((doc.${this._key} && (doc.${this._key} as ${type})${type === 'string' ? '.includes' : '<='}(${parsedValue}))) ||
-                ((doc.data_ext && doc.data_ext.${this._key}) && (doc.data_ext.${this._key} as ${type})${type === 'string' ? '.includes' : '<='}(${parsedValue}))))`;
-            // let doc = new Doc();
-            // ((doc.data_ext && doc.data_ext!.text) && (doc.data_ext!.text as string).includes("hello"));
-            this.props.script(scriptText);
-        } else {
-            this.props.script('');
-        }
-
-        return (
-            <div className="collectionViewBaseChrome-viewSpecsMenu-row">
-                <input
-                    className="collectionViewBaseChrome-viewSpecsMenu-rowLeft"
-                    value={this._key}
-                    onChange={e =>
-                        runInAction(() => {
-                            this._key = e.target.value;
-                        })
-                    }
-                    placeholder="KEY"
-                />
-                <button
-                    className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
-                    style={{ background: this._contains ? '#77dd77' : '#ff6961' }}
-                    onClick={() =>
-                        runInAction(() => {
-                            this._contains = !this._contains;
-                        })
-                    }>
-                    {this._contains ? 'CONTAINS' : 'DOES NOT CONTAIN'}
-                </button>
-                <input
-                    className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
-                    value={this._value}
-                    onChange={e =>
-                        runInAction(() => {
-                            this._value = e.target.value;
-                        })
-                    }
-                    placeholder="VALUE"
-                />
-            </div>
-        );
-    }
-}
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index 931cdac2b..b705d17f3 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -92,6 +92,6 @@ input.lm_title {
 .miniMap-hidden {
     cursor: pointer;
     position: absolute;
-    bottom: 5;
-    right: 5;
+    bottom: 5px;
+    right: 5px;
 }
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index 78794d112..542b0cc87 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -136,8 +136,8 @@
         width: 100%;
         height: 100%;
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         z-index: 0;
         filter: opacity(0);
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
index 7951aff65..32cf3586f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
@@ -18,5 +18,5 @@
     color: black;
     // fontStyle: "italic",
     margin-left: -12;
-    margin-top: 4;
+    margin-top: 4px;
 }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index 6c47a71b0..ac1ef7d65 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -2,8 +2,8 @@
 
 .collectionfreeformview-none {
     position: inherit;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     width: 100%;
     height: 100%;
     transform-origin: left top;
@@ -12,10 +12,10 @@
     border-radius: inherit;
 }
 .collectionFreeForm-groupDropper {
-    width: 10000;
-    height: 10000;
-    left: -5000;
-    top: -5000;
+    width: 10000px;
+    height: 10000px;
+    left: -5000px;
+    top: -5000px;
     position: absolute;
     background: transparent;
     pointer-events: all;
@@ -24,8 +24,8 @@
 .collectionfreeformview-grid {
     transform-origin: top left;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     pointer-events: none;
 }
 
@@ -219,8 +219,8 @@
     border-radius: inherit;
     box-sizing: border-box;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     width: 100%;
     height: 100%;
     align-items: center;
@@ -264,7 +264,7 @@
 .collectionFreeform-infoUI {
     position: absolute;
     display: block;
-    top: 0;
+    top: 0px;
 
     color: white;
     background-color: #5075ef;
@@ -275,19 +275,19 @@
     padding: 10px;
     .collectionFreeform-infoUI-close {
         position: absolute;
-        top: -10;
-        left: -10;
+        top: -10px;
+        left: -10px;
     }
 
     .collectionFreeform-infoUI-msg {
         position: relative;
-        max-width: 500;
-        margin: 10;
+        max-width: 500px;
+        margin: 10px;
     }
     .collectionFreeform-infoUI-button {
         border-radius: 50px;
         font-size: 12px;
-        padding: 6;
+        padding: 6px;
         position: relative;
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss
index 0a001d84c..d0685e419 100644
--- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss
+++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.scss
@@ -2,7 +2,7 @@
     display: flex;
     height: max-content;
     flex-direction: column;
-    top: 0;
+    top: 0px;
     position: absolute;
     width: 100%;
     height: 100%;
@@ -31,9 +31,9 @@
     }
     .face-document-top {
         position: relative;
-        top: 0;
+        top: 0px;
         width: 100%;
-        left: 0;
+        left: 0px;
     }
 
     .face-document-image-container {
@@ -69,8 +69,8 @@
 
             .remove-item {
                 position: absolute;
-                bottom: -5;
-                right: -5;
+                bottom: -5px;
+                right: -5px;
                 background-color: rgba(0, 0, 0, 0.5); // Optional: to add a background behind the icon for better visibility
                 border-radius: 30%;
                 width: 10px; // Adjust size as needed
@@ -98,7 +98,7 @@
 .faceCollectionBox {
     width: 100%;
     height: 100%;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     position: absolute;
 }
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.scss b/src/client/views/collections/collectionFreeForm/MarqueeView.scss
index 7c9d0f6e1..af787ed00 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.scss
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.scss
@@ -1,7 +1,7 @@
 .marqueeView {
     position: inherit;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     width: 100%;
     height: 100%;
     overflow: hidden;
@@ -20,7 +20,7 @@
     pointer-events: none;
     .marquee-legend {
         bottom: -18px;
-        left: 0;
+        left: 0px;
         position: absolute;
         font-size: 9;
         white-space: nowrap;
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss
index 4edaf9745..b95d3ea44 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.scss
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss
@@ -39,8 +39,8 @@
             background: #d3d3d3;
 
             position: absolute;
-            height: 3;
-            left: 5;
+            height: 3px;
+            left: 5px;
             transform-origin: left;
             transform: rotate(90deg);
             outline: none;
@@ -133,7 +133,7 @@
 input::-webkit-outer-spin-button,
 input::-webkit-inner-spin-button {
     -webkit-appearance: none;
-    margin: 0;
+    margin: 0px;
 }
 
 /* Firefox */
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.scss b/src/client/views/collections/collectionLinear/CollectionLinearView.scss
index 0dfaed38a..0053d3e60 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.scss
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.scss
@@ -47,7 +47,7 @@
             background: global.$medium-blue;
             display: flex;
             border-radius: 10px;
-            height: 35;
+            height: 35px;
             transform: translate3d(6px, 0px, 0px);
             align-content: center;
             justify-content: center;
@@ -95,11 +95,11 @@
             pointer-events: all;
             cursor: pointer;
             background-color: global.$medium-blue;
-            padding: 5;
+            padding: 5px;
             border-radius: 2px;
             height: 100%;
-            min-width: 25;
-            margin: 0;
+            min-width: 25px;
+            margin: 0px;
             color: global.$white;
             display: flex;
             font-weight: 100;
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
index 9ed247d50..1dc46102f 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
@@ -1,8 +1,8 @@
 .collectionMulticolumnView_drop {
     height: 100%;
     width: 100%;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     position: absolute;
 
     .collectionMulticolumnView_contents {
@@ -18,8 +18,8 @@
             align-items: center;
             position: relative;
             > .iconButton-container {
-                top: 0;
-                left: 0;
+                top: 0px;
+                left: 0px;
                 position: absolute;
             }
 
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
index 91779065d..eb157d155 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
@@ -1,8 +1,8 @@
 .collectionMultirowView_drop {
     height: 100%;
     width: 100%;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     position: absolute;
 
     .collectionMultirowView_contents {
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
index 10a6fa2e9..2ff99f134 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/require-default-props */
 import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
index 66215f109..4f57e1656 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/require-default-props */
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
index 918365700..1954b4743 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/require-default-props */
 import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -66,7 +65,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
                 style={{
                     pointerEvents: this.props.isContentActive?.() ? 'all' : 'none',
                     height: this.props.height,
-                    backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor) as string,
+                    backgroundColor: !this.props.isContentActive?.() ? '' : (this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor) as string),
                 }}>
                 <div className="multiRowResizer-hdl" onPointerDown={e => this.registerResizing(e)} />
             </div>
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
index 53c0823ea..e975ae6f6 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss
@@ -18,7 +18,7 @@
 
         .schema-add {
             position: relative;
-            height: 35;
+            height: 35px;
             display: flex;
             align-items: center;
             top: -10px;
@@ -147,7 +147,7 @@
     flex-direction: row;
     justify-content: space-between;
     align-items: center;
-    padding: 0;
+    padding: 0px;
     z-index: 1;
     border: 1px solid global.$medium-gray;
 
@@ -231,7 +231,7 @@
     overflow-x: hidden;
     overflow-y: auto;
     display: inline-flex;
-    padding: 0;
+    padding: 0px;
     align-items: center;
     input[type='text'] {
         border: unset;
@@ -272,8 +272,8 @@
 
     .row-menu-infos {
         position: absolute;
-        top: 3;
-        left: 3;
+        top: 3px;
+        left: 3px;
         z-index: 1;
         display: flex;
         justify-content: flex-end;
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index 3cd60c87f..cc8c168cf 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -114,7 +114,7 @@
     .linkMenu-deleteButton {
         width: 20px;
         height: 20px;
-        margin: 0;
+        margin: 0px;
         margin-right: 4px;
         padding-right: 6px;
         border-radius: 50%;
@@ -134,7 +134,7 @@
         }
 
         &:last-child {
-            margin-right: 0;
+            margin-right: 0px;
         }
 
         &:hover {
diff --git a/src/client/views/linking/LinkPopup.scss b/src/client/views/linking/LinkPopup.scss
index 4bfb4b0b9..f8d724767 100644
--- a/src/client/views/linking/LinkPopup.scss
+++ b/src/client/views/linking/LinkPopup.scss
@@ -1,7 +1,9 @@
 .linkPopup-container {
     background: white;
-    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
-    top: 0;
+    box-shadow:
+        0 10px 20px rgba(0, 0, 0, 0.19),
+        0 6px 6px rgba(0, 0, 0, 0.23);
+    top: 0px;
     height: 200px;
     width: 200px;
     // padding: 15px;
diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx
index b654f9bd0..760850241 100644
--- a/src/client/views/linking/LinkPopup.tsx
+++ b/src/client/views/linking/LinkPopup.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/require-default-props */
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { returnEmptyFilter, returnFalse, returnTrue } from '../../../ClientUtils';
diff --git a/src/client/views/newlightbox/NewLightboxView.scss b/src/client/views/newlightbox/NewLightboxView.scss
index 76c34bcf9..c76a7d60d 100644
--- a/src/client/views/newlightbox/NewLightboxView.scss
+++ b/src/client/views/newlightbox/NewLightboxView.scss
@@ -2,8 +2,8 @@
 
 .newLightboxView-frame {
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     width: 100%;
     height: 100%;
     background: #474545bb;
diff --git a/src/client/views/newlightbox/components/Recommendation/Recommendation.scss b/src/client/views/newlightbox/components/Recommendation/Recommendation.scss
index cf6b5ccb1..09d3ccc62 100644
--- a/src/client/views/newlightbox/components/Recommendation/Recommendation.scss
+++ b/src/client/views/newlightbox/components/Recommendation/Recommendation.scss
@@ -135,7 +135,7 @@
         font-size: 10px;
         width: 100%;
         background: newstyles.$blue-l1;
-        border-radius: 0;
+        border-radius: 0px;
         padding: 10px;
 
         .concepts-container {
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
index 933a383ea..c25c09af9 100644
--- a/src/client/views/nodes/AudioBox.scss
+++ b/src/client/views/nodes/AudioBox.scss
@@ -138,7 +138,7 @@
 
     input[type='range']::-webkit-slider-thumb {
         box-shadow: 0;
-        border: 0;
+        border: 0px;
         height: 10px;
         width: 10px;
         border-radius: 10px;
@@ -168,7 +168,7 @@
             .audiobox-button {
                 width: 15px;
                 height: 15px;
-                margin: 0;
+                margin: 0px;
 
                 svg {
                     width: 10px;
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.scss b/src/client/views/nodes/CollectionFreeFormDocumentView.scss
index 7f0a39550..300533df8 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.scss
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.scss
@@ -3,7 +3,7 @@
     position: absolute;
     background-color: transparent;
     touch-action: manipulation;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     pointer-events: none;
 }
diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss
index d2ba9796b..cbbd6bde3 100644
--- a/src/client/views/nodes/ComparisonBox.scss
+++ b/src/client/views/nodes/ComparisonBox.scss
@@ -18,7 +18,7 @@
     }
     .input-box {
         position: absolute;
-        top: 50;
+        top: 50px;
         padding: 10px;
         width: 100%;
         height: 70%;
@@ -33,7 +33,7 @@
         padding-right: 5px;
         border-radius: 2px;
         height: 17%;
-        bottom: 0;
+        bottom: 0px;
         overflow: hidden;
         display: flex;
         width: 100%;
@@ -101,7 +101,7 @@
         position: absolute;
         display: inline-block;
         margin-top: 150px;
-        bottom: 0;
+        bottom: 0px;
     }
 
     .dropup-content {
@@ -145,8 +145,8 @@
 
     .clip-div {
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         height: 100%;
         overflow: hidden;
 
@@ -180,8 +180,8 @@
 
     .afterBox-cont {
         position: absolute;
-        top: 0;
-        right: 0;
+        top: 0px;
+        right: 0px;
         height: 100%;
         width: 100%;
         overflow: hidden;
@@ -331,8 +331,8 @@
     justify-content: space-between;
     height: max-content;
     position: absolute;
-    bottom: 0;
-    right: 2;
+    bottom: 0px;
+    right: 2px;
     flex-direction: row-reverse;
     display: flex;
     cursor: pointer;
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.scss b/src/client/views/nodes/DataVizBox/DataVizBox.scss
index 9825d926f..32a01355e 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.scss
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.scss
@@ -37,25 +37,25 @@
         margin-left: 10px;
         margin-bottom: -10px;
     }
-    
+
     .displaySchemaLive {
         margin-bottom: 20px;
     }
 
     .dataviz-sidebar {
         position: absolute;
-        right: 0;
-        top: 0;
+        right: 0px;
+        top: 0px;
         height: 100%;
     }
     .button-container {
         pointer-events: unset;
     }
 
-    .dataVizBox-annotationLayer{
+    .dataVizBox-annotationLayer {
         position: absolute;
         transform-origin: left top;
-        top: 0;
+        top: 0px;
         width: 100%;
         pointer-events: none;
         mix-blend-mode: multiply;
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
index 6eb7fa96a..e2261b9e2 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.scss
@@ -110,12 +110,12 @@
     &::before {
         content: '';
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         border-bottom: 20px solid rgb(50, 50, 50);
         border-left: 12px solid transparent;
         border-right: 12px solid transparent;
-        height: 0;
+        height: 0px;
         width: 50px;
     }
 
@@ -127,7 +127,7 @@
         border-bottom: 22px solid rgb(180, 180, 180);
         border-left: 12px solid transparent;
         border-right: 12px solid transparent;
-        height: 0;
+        height: 0px;
         width: 52px;
         z-index: -1;
     }
@@ -418,8 +418,8 @@
 }
 
 .div {
-    width: 200;
-    height: 200;
+    width: 200px;
+    height: 200px;
     border: solid 1px white;
 }
 
@@ -588,7 +588,7 @@
 }
 
 .docCreatorMenu-configuration-bar {
-    width: 200;
+    width: 200px;
     gap: 5px;
     display: flex;
     flex-direction: row;
@@ -709,8 +709,8 @@
         width: 100%;
         aspect-ratio: 1;
         //height: auto;
-        // max-width: 240;
-        // max-height: 240;
+        // max-width: 240px;
+        // max-height: 240px;
         border: 1px solid rgb(180, 180, 180);
         border-radius: 5px;
         background-color: rgb(34, 34, 37);
@@ -718,8 +718,8 @@
         scrollbar-width: none;
 
         &.small {
-            max-width: 100;
-            max-height: 100;
+            max-width: 100px;
+            max-height: 100px;
         }
 
         .docCreatorMenu-layout-preview-item {
@@ -1009,8 +1009,8 @@
             }
 
             &:hover .operator-dropdown-current {
-                border-bottom-right-radius: 0;
-                border-bottom-left-radius: 0;
+                border-bottom-right-radius: 0px;
+                border-bottom-left-radius: 0px;
             }
 
             &:hover .operator-dropdown-option {
diff --git a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.scss b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.scss
index 63a693918..0acc2c847 100644
--- a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.scss
+++ b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.scss
@@ -13,7 +13,7 @@ $highlightedText: #82e0ff;
     min-height: 200px;
     border-radius: 15px;
     padding: 15px;
-    padding-bottom: 0;
+    padding-bottom: 0px;
     z-index: 999;
     display: flex;
     flex-direction: column;
@@ -40,7 +40,7 @@ $highlightedText: #82e0ff;
         font-size: 12px;
         font-weight: 400;
         letter-spacing: 1px;
-        margin: 0;
+        margin: 0px;
         padding-right: 5px;
     }
 
@@ -124,8 +124,8 @@ $highlightedText: #82e0ff;
         .img-container::after {
             content: '';
             position: absolute;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
             width: 100%;
             height: 100%;
             background-color: rgba(0, 0, 0, 0.5);
diff --git a/src/client/views/nodes/DataVizBox/components/Chart.scss b/src/client/views/nodes/DataVizBox/components/Chart.scss
index ff1fa343d..a22e1153c 100644
--- a/src/client/views/nodes/DataVizBox/components/Chart.scss
+++ b/src/client/views/nodes/DataVizBox/components/Chart.scss
@@ -91,7 +91,7 @@
         margin: 5px;
         margin-left: 25px;
         margin-right: 10px;
-        margin-bottom: 0;
+        margin-bottom: 0px;
         .tableBox-table {
             height: 100%;
             width: 100%;
@@ -101,7 +101,7 @@
                     text-overflow: ellipsis;
                     width: 100%;
                     white-space: pre;
-                    max-width: 150;
+                    max-width: 150px;
                     overflow: hidden;
                     margin-left: 2px;
                 }
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index e1b83dc59..43b1e083f 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -17,8 +17,8 @@
 }
 
 .documentLinksButton-cont {
-    min-width: 20;
-    min-height: 20;
+    min-width: 20px;
+    min-height: 20px;
     position: absolute;
 }
 
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index c4351a200..98ca76339 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -1,6 +1,7 @@
 @use '../global/globalCssVariables.module.scss' as global;
 
 .documentView-effectsWrapper {
+    height: 100%;
     border-radius: inherit;
     transition: inherit;
 }
@@ -14,13 +15,13 @@
     width: 100%;
     height: 100%;
     position: absolute;
-    top: 0;
+    top: 0px;
 }
 
 .documentView-node {
     position: inherit;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     width: 100%;
     height: 100%;
     border-radius: inherit;
@@ -55,7 +56,7 @@
     .documentView-htmlOverlay {
         position: absolute;
         display: flex;
-        top: 0;
+        top: 0px;
         height: 100%;
         width: 100%;
         .documentView-htmlOverlayInner {
@@ -79,9 +80,9 @@
     .documentView-audioBackground {
         display: inline-block;
         width: 25px;
-        height: 25;
+        height: 25px;
         position: absolute;
-        top: 0;
+        top: 0px;
         left: 50%;
         border-radius: 25px;
         background: white;
@@ -130,7 +131,7 @@
             width: 30px;
             border-radius: 50%;
             position: absolute;
-            right: -15;
+            right: -15px;
             opacity: 0.9;
             pointer-events: auto;
             background-color: #9dca96;
@@ -147,8 +148,8 @@
 
     .documentView-anchorCont {
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         width: 100%;
         height: 100%;
         display: inline-block;
@@ -160,8 +161,8 @@
         position: absolute;
         width: 100%;
         height: 100%;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
     }
 
     .documentView-styleWrapper {
@@ -183,9 +184,9 @@
         .documentView-titleWrapper-hover {
             color: global.$black;
             transform-origin: top left;
-            top: 0;
+            top: 0px;
             width: 100%;
-            height: 14;
+            height: 14px;
             opacity: 0.5;
             text-align: center;
             text-overflow: ellipsis;
@@ -211,7 +212,7 @@
 
         .documentView-captionWrapper {
             position: absolute;
-            bottom: 0;
+            bottom: 0px;
             width: 100%;
             overflow-y: auto;
             transform-origin: bottom left;
@@ -275,20 +276,20 @@
 .documentView-noAIWidgets {
     transform-origin: top left;
     position: absolute;
-    bottom: 0;
+    bottom: 0px;
     pointer-events: none;
 }
 .documentView-widgetDecorations {
     transform-origin: top right;
     position: absolute;
-    top: 0;
-    right: 0;
+    top: 0px;
+    right: 0px;
 }
 
 .documentView-editorView-history {
     position: absolute;
     transform-origin: top right;
-    right: 0;
+    right: 0px;
     top: 0;
     overflow-y: scroll;
     scrollbar-width: thin;
diff --git a/src/client/views/nodes/FontIconBox/FontIconBadge.scss b/src/client/views/nodes/FontIconBox/FontIconBadge.scss
index 2ff5c651f..e741936db 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBadge.scss
+++ b/src/client/views/nodes/FontIconBox/FontIconBadge.scss
@@ -6,7 +6,7 @@
     color: black;
     display: block;
     position: absolute;
-    right: 5;
+    right: 5px;
     border-radius: 50%;
     text-align: center;
 }
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.scss b/src/client/views/nodes/FontIconBox/FontIconBox.scss
index 8bc68c131..52eebba54 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.scss
@@ -42,7 +42,7 @@
         letter-spacing: normal;
         background-color: inherit;
         border-radius: 8px;
-        padding: 0;
+        padding: 0px;
         width: 100%;
         font-family: 'system-ui';
         text-transform: uppercase;
@@ -96,22 +96,22 @@
                 display: inline-block;
                 width: 100%;
                 height: 25px;
-                margin: 0;
+                margin: 0px;
             }
 
             .switch input {
                 opacity: 0;
-                width: 0;
-                height: 0;
+                width: 0px;
+                height: 0px;
             }
 
             .slider {
                 position: absolute;
                 cursor: pointer;
-                top: 0;
-                left: 0;
-                right: 0;
-                bottom: 0;
+                top: 0px;
+                left: 0px;
+                right: 0px;
+                bottom: 0px;
                 background-color: lightgrey;
                 -webkit-transition: 0.4s;
                 transition: 0.4s;
@@ -223,7 +223,7 @@
             height: fit-content;
             color: black;
             top: 100%;
-            left: 0;
+            left: 0px;
             z-index: 21;
             background-color: #e3e3e3;
             box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
@@ -430,7 +430,7 @@
         border-radius: 0px 7px 7px 0px;
         width: 13px;
         height: 100%;
-        right: 0;
+        right: 0px;
     }
 
     .menuButton-dropdown-header {
diff --git a/src/client/views/nodes/IconTagBox.scss b/src/client/views/nodes/IconTagBox.scss
index d6cf95958..c0977dfc5 100644
--- a/src/client/views/nodes/IconTagBox.scss
+++ b/src/client/views/nodes/IconTagBox.scss
@@ -15,7 +15,7 @@
         width: 20px;
         height: 20px;
         margin: auto;
-        padding: 0;
+        padding: 0px;
         border-radius: 50%;
         background-color: global.$dark-gray;
         background-color: transparent;
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index 5a6292fab..90ede69dc 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -3,14 +3,14 @@
     width: 100%;
     height: 100%;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     transform-origin: top left;
 
     .imageBox-annotationLayer {
         position: absolute;
         transform-origin: left top;
-        top: 0;
+        top: 0px;
         width: 100%;
         pointer-events: none;
         mix-blend-mode: multiply; // bcz: makes text fuzzy!
@@ -24,8 +24,8 @@
 
 #upload-icon {
     position: absolute;
-    bottom: 0;
-    right: 0;
+    bottom: 0px;
+    right: 0px;
     width: 20px;
     height: 20px;
 }
@@ -51,8 +51,8 @@
 
 .imageBox-dot {
     position: absolute;
-    bottom: 10;
-    left: 0;
+    bottom: 10px;
+    left: 0px;
     border-radius: 10px;
     width: 20px;
     height: 20px;
@@ -131,8 +131,8 @@
     position: absolute;
     color: white;
     background: black;
-    right: 0;
-    bottom: 0;
+    right: 0px;
+    bottom: 0px;
     z-index: 2;
     transform-origin: bottom right;
     cursor: default;
@@ -142,13 +142,13 @@
     }
 }
 .imageBox-regenerateDropTarget {
-    right: 35;
+    right: 35px;
     transform-origin: 70px 35px;
 }
 
 .imageBox-fader img {
     position: absolute;
-    left: 0;
+    left: 0px;
 }
 
 .imageBox-fadeBlocker-hover {
@@ -223,7 +223,7 @@
         max-width: 90%;
         width: 100%;
         .imageBox-aiView-similarity {
-            max-width: 65;
+            max-width: 65px;
             overflow: hidden;
             text-overflow: ellipsis;
             width: 100%;
@@ -250,7 +250,7 @@
     z-index: 10000;
 
     h3 {
-        margin-top: 0;
+        margin-top: 0px;
     }
 
     input {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 8ed59c6e1..616046d5d 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -962,8 +962,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     rejectDrop = (de: DragManager.DropEvent, subView?: DocumentView | undefined) => (this.dataDoc[this.fieldKey] === undefined ? true : (this._props.rejectDrop?.(de, subView) ?? false));
     render() {
         TraceMobx();
-        const borderRad = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BorderRounding) as string;
-        const borderRadius = borderRad?.includes('px') ? `${Number(borderRad.split('px')[0]) / (this._props.NativeDimScaling?.() || 1)}px` : borderRad;
+        const borderRadius = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BorderRounding) as string;
         return (
             <>
                 <div
diff --git a/src/client/views/nodes/KeyValueBox.scss b/src/client/views/nodes/KeyValueBox.scss
index 441fceba4..80ace6ae0 100644
--- a/src/client/views/nodes/KeyValueBox.scss
+++ b/src/client/views/nodes/KeyValueBox.scss
@@ -93,9 +93,9 @@ $header-height: 30px;
     height: 30px;
     width: 5px;
     z-index: 20;
-    right: 0;
-    top: 0;
-    border-radius: 0;
+    right: 0px;
+    top: 0px;
+    border-radius: 0px;
     background: black;
     pointer-events: all;
 }
@@ -105,8 +105,8 @@ $header-height: 30px;
     float: left;
     height: 37px;
     z-index: 20;
-    right: 0;
-    top: 0;
+    right: 0px;
+    top: 0px;
     background: transparent;
     pointer-events: none;
 }
diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss
index 913ab641c..154fbdcfa 100644
--- a/src/client/views/nodes/KeyValuePair.scss
+++ b/src/client/views/nodes/KeyValuePair.scss
@@ -17,7 +17,7 @@
         }
         .keyValuePair-td-key-check {
             position: relative;
-            margin: 0;
+            margin: 0px;
         }
         .keyValuePair-keyField {
             width: 100%;
diff --git a/src/client/views/nodes/LabelBox.scss b/src/client/views/nodes/LabelBox.scss
index 889cdc0ca..e1974d6a0 100644
--- a/src/client/views/nodes/LabelBox.scss
+++ b/src/client/views/nodes/LabelBox.scss
@@ -24,8 +24,8 @@
 
 .answer-icon {
     position: absolute;
-    right: 8;
-    bottom: 5;
+    right: 8px;
+    bottom: 5px;
     color: black;
     display: inline-block;
     font-size: 10px;
@@ -36,8 +36,8 @@
 
 .q-icon {
     position: absolute;
-    right: 6;
-    bottom: 5;
+    right: 6px;
+    bottom: 5px;
     color: white;
     display: inline-block;
     font-size: 10px;
@@ -48,8 +48,8 @@
 
 .edit-icon {
     position: absolute;
-    right: 20;
-    bottom: 5;
+    right: 20px;
+    bottom: 5px;
     display: inline-block;
     font-size: 10px;
     cursor: pointer;
diff --git a/src/client/views/nodes/LinkDocPreview.scss b/src/client/views/nodes/LinkDocPreview.scss
index 28216394d..7d99247e7 100644
--- a/src/client/views/nodes/LinkDocPreview.scss
+++ b/src/client/views/nodes/LinkDocPreview.scss
@@ -42,7 +42,7 @@
 
             .linkDocPreview-button {
                 display: inline-flex;
-                margin: 0;
+                margin: 0px;
                 margin-right: 3px;
                 border-radius: 50%;
                 pointer-events: auto;
diff --git a/src/client/views/nodes/LoadingBox.scss b/src/client/views/nodes/LoadingBox.scss
index cabd4de05..5a8f49000 100644
--- a/src/client/views/nodes/LoadingBox.scss
+++ b/src/client/views/nodes/LoadingBox.scss
@@ -26,7 +26,7 @@
     }
     .loadingBox-spinner {
         position: absolute;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
     }
 }
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.scss b/src/client/views/nodes/MapBox/MapAnchorMenu.scss
index c36d98afe..217576203 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.scss
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.scss
@@ -6,19 +6,19 @@
 }
 .anchorMenu-highlighter {
     padding-right: 5px;
-    .antimodeMenu-button  {
-        padding: 0;
-        padding: 0;
+    .antimodeMenu-button {
+        padding: 0px;
+        padding: 0px;
         padding-right: 0px;
         padding-left: 0px;
         width: 5px;
     }
 }
-.anchor-color-preview-button {  
-    width: 25px !important;  
+.anchor-color-preview-button {
+    width: 25px !important;
     .anchor-color-preview {
         display: flex;
-        flex-direction:  column;
+        flex-direction: column;
         padding-right: 3px;
         width: unset !important;
         .color-preview {
@@ -72,12 +72,11 @@
         }
     }
 
-    .MuiInputBase-input{
+    .MuiInputBase-input {
         color: white !important;
     }
-    
-    
-    .css-1t8l2tu-MuiInputBase-input-MuiOutlinedInput-input.Mui-disabled{
+
+    .css-1t8l2tu-MuiInputBase-input-MuiOutlinedInput-input.Mui-disabled {
         -webkit-text-fill-color: #b3b2b2 !important;
     }
 
@@ -91,7 +90,7 @@
             gap: 5px;
         }
 
-        .selected-route-details-container{
+        .selected-route-details-container {
             display: flex;
             flex-direction: column;
             gap: 3px;
@@ -99,33 +98,25 @@
             align-items: flex-start;
             padding: 5px;
         }
-
-
     }
 
-    .customized-marker-container{
+    .customized-marker-container {
         display: flex;
         flex-direction: column;
         gap: 10px;
 
-        .current-marker-container{
+        .current-marker-container {
             display: flex;
             align-items: center;
             gap: 5px;
         }
 
-        .all-markers-container{
+        .all-markers-container {
             display: flex;
-            align-items:  center;
+            align-items: center;
             gap: 10px;
             flex-wrap: wrap;
             max-width: 400px;
         }
     }
-
-
-
-
 }
-
-
diff --git a/src/client/views/nodes/MapBox/MapBox.scss b/src/client/views/nodes/MapBox/MapBox.scss
index bd4b51038..89d381070 100644
--- a/src/client/views/nodes/MapBox/MapBox.scss
+++ b/src/client/views/nodes/MapBox/MapBox.scss
@@ -21,7 +21,7 @@
     .mapBox-infoWindow {
         background-color: white;
         opacity: 0.75;
-        padding: 12;
+        padding: 12px;
         font-size: 17;
     }
     .mapBox-searchbar {
@@ -119,7 +119,7 @@
                 width: 100%;
 
                 label {
-                    margin-bottom: 0;
+                    margin-bottom: 0px;
                 }
 
                 .speed-label {
@@ -197,12 +197,12 @@
     }
     .mapBox-sidebar {
         position: absolute;
-        right: 0;
+        right: 0px;
         height: 100%;
     }
 
     .mapBox-sidebar-handle {
-        top: 0;
+        top: 0px;
         //top: calc(50% - 17.5px);  // use this to center vertically -- make sure it looks okay for slide views
         width: 10px;
         height: 100%;
@@ -215,7 +215,7 @@
         left: 50%;
         margin-left: 120px;
         right: unset !important;
-        margin-top: -10;
+        margin-top: -10px;
         height: max-content;
     }
     .searchbox {
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index f09a2630a..e34ca61d4 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -17,8 +17,8 @@
         height: 100%;
         z-index: 1;
         pointer-events: none;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
 
         // glr: This should really be the same component as text and PDFs
         .pdfBox-sidebarBtn {
@@ -72,16 +72,16 @@
             align-items: center;
             height: 20px;
             background: none;
-            padding: 0;
+            padding: 0px;
             position: absolute;
             pointer-events: all;
             color: white;
-            bottom: 0;
-            right: 0;
+            bottom: 0px;
+            right: 0px;
 
             .pdfBox-overlayButton-arrow {
-                width: 0;
-                height: 0;
+                width: 0px;
+                height: 0px;
                 border-top: 10px solid transparent;
                 border-bottom: 10px solid transparent;
                 border-right: 15px solid #121721;
@@ -122,8 +122,8 @@
 
         .pdfBox-settingsCont {
             position: absolute;
-            right: 0;
-            top: 3;
+            right: 0px;
+            top: 3px;
             pointer-events: all;
 
             .pdfBox-settingsButton {
@@ -133,11 +133,11 @@
                 align-items: center;
                 height: 20px;
                 background: none;
-                padding: 0;
+                padding: 0px;
 
                 .pdfBox-settingsButton-arrow {
-                    width: 0;
-                    height: 0;
+                    width: 0px;
+                    height: 0px;
                     border-top: 10px solid transparent;
                     border-bottom: 10px solid transparent;
                     border-right: 15px solid #121721;
@@ -189,7 +189,7 @@
             width: calc(100% - 40px);
             height: 20px;
             background: #121721;
-            bottom: 0;
+            bottom: 0px;
             display: flex;
             justify-content: center;
             align-items: center;
@@ -253,13 +253,13 @@
 .pdfBox-container {
     position: absolute;
     transform-origin: top left;
-    top: 0;
+    top: 0px;
 }
 .pdfBox-sidebarContainer {
     position: absolute;
     height: 100%;
-    right: 0;
-    top: 0;
+    right: 0px;
+    top: 0px;
 }
 
 .pdfBox-interactive {
@@ -290,7 +290,7 @@
         }
 
         .pdfBox-settingsButton-arrow {
-            height: 60;
+            height: 60px;
             border-top: 30px solid transparent;
             border-bottom: 30px solid transparent;
             border-right: 30px solid #121721;
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.scss b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.scss
index ac2c611c7..78aa526bf 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.scss
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.scss
@@ -29,8 +29,8 @@
         .wedge {
             pointer-events: none;
             position: absolute;
-            left: 0;
-            top: 0;
+            left: 0px;
+            top: 0px;
         }
     }
 
diff --git a/src/client/views/nodes/RecordingBox/ProgressBar.scss b/src/client/views/nodes/RecordingBox/ProgressBar.scss
index 28ad25ffa..ec01f0241 100644
--- a/src/client/views/nodes/RecordingBox/ProgressBar.scss
+++ b/src/client/views/nodes/RecordingBox/ProgressBar.scss
@@ -1,36 +1,34 @@
-
 .progressbar {
-  touch-action: none;
-  vertical-align: middle;
-  text-align: center;
-
-  align-items: center;
-  cursor: default;
-
-
-      position: absolute;
-      display: flex;
-      justify-content: flex-start;
-      bottom: 2px;
-      width: 99%;
-      height: 30px;
-      background-color: gray;
-
-      &.done {
-            top: 0;
-            width: 0px;
-            height: 5px;
-            background-color: red;
-            z-index: 2;
-      }
-
-      &.mark {
-            top: 0;
-            background-color: transparent;
-            border-right: 2px solid white;
-            z-index: 3;
-            pointer-events: none; 
-      }
+    touch-action: none;
+    vertical-align: middle;
+    text-align: center;
+
+    align-items: center;
+    cursor: default;
+
+    position: absolute;
+    display: flex;
+    justify-content: flex-start;
+    bottom: 2px;
+    width: 99%;
+    height: 30px;
+    background-color: gray;
+
+    &.done {
+        top: 0px;
+        width: 0px;
+        height: 5px;
+        background-color: red;
+        z-index: 2;
+    }
+
+    &.mark {
+        top: 0px;
+        background-color: transparent;
+        border-right: 2px solid white;
+        z-index: 3;
+        pointer-events: none;
+    }
 }
 
 .progressbar-disabled {
@@ -43,37 +41,41 @@
 
 // citation: https://codepen.io/_Master_/pen/PRdjmQ
 @keyframes blinker {
-  from {opacity: 1.0;}
-  to {opacity: 0.0;}
+    from {
+        opacity: 1;
+    }
+    to {
+        opacity: 0;
+    }
 }
 .blink {
-	text-decoration: blink;
-	animation-name: blinker;
-	animation-duration: 0.6s;
-	animation-iteration-count:infinite;
-	animation-timing-function:ease-in-out;
-	animation-direction: alternate;
+    text-decoration: blink;
+    animation-name: blinker;
+    animation-duration: 0.6s;
+    animation-iteration-count: infinite;
+    animation-timing-function: ease-in-out;
+    animation-direction: alternate;
 }
 
 .segment {
-  border: 3px solid black;
-  background-color: red;
-  margin: 1px;
-  padding: 0;
-  cursor: pointer;
-  transition-duration: .5s;
-  user-select: none;
-
-  vertical-align: middle;
-  text-align: center;
+    border: 3px solid black;
+    background-color: red;
+    margin: 1px;
+    padding: 0px;
+    cursor: pointer;
+    transition-duration: 0.5s;
+    user-select: none;
+
+    vertical-align: middle;
+    text-align: center;
 }
 
 .segment-expanding {
-border-color: red;
-  background-color: white;
-  transition-duration: 0s;
-  opacity: .75;
-  pointer-events: none;
+    border-color: red;
+    background-color: white;
+    transition-duration: 0s;
+    opacity: 0.75;
+    pointer-events: none;
 }
 
 .segment-expanding:hover {
@@ -82,10 +84,10 @@ border-color: red;
 }
 
 .segment-disabled {
-  pointer-events: none;
-  opacity: 0.5;
-  transition-duration: 0s;
-  /* Hide the text. */
+    pointer-events: none;
+    opacity: 0.5;
+    transition-duration: 0s;
+    /* Hide the text. */
     text-indent: 100%;
     white-space: nowrap;
     overflow: hidden;
@@ -99,25 +101,26 @@ border-color: red;
 }
 
 .segment:first-child {
-  margin-left: 2px;
+    margin-left: 2px;
 }
 .segment:last-child {
-  margin-right: 2px;
+    margin-right: 2px;
 }
 
 .segment:hover {
     background-color: white;
 }
 
-.segment:hover, .segment-selected {
-  margin: 0px;
-  border: 4px solid red;
-  border-radius: 2px;
+.segment:hover,
+.segment-selected {
+    margin: 0px;
+    border: 4px solid red;
+    border-radius: 2px;
 }
 
 .segment-selected {
-  border: 4px solid #202020;
-  background-color: red;
-  opacity: .75;
-  cursor: grabbing;
+    border: 4px solid #202020;
+    background-color: red;
+    opacity: 0.75;
+    cursor: grabbing;
 }
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.scss b/src/client/views/nodes/RecordingBox/RecordingView.scss
index f2d5a980d..15b48c111 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.scss
+++ b/src/client/views/nodes/RecordingBox/RecordingView.scss
@@ -28,7 +28,7 @@ video {
     justify-content: center;
     //   overflow: hidden;
     border-radius: 10px;
-    margin: 0;
+    margin: 0px;
 }
 
 .video-wrapper:hover .controls {
@@ -108,7 +108,7 @@ video {
     .timer {
         font-size: 15px;
         color: white;
-        margin: 0;
+        margin: 0px;
     }
 
     .dot {
@@ -148,7 +148,7 @@ video {
         height: 80%;
         width: 80%;
         align-self: center;
-        margin: 0;
+        margin: 0px;
 
         &:hover {
             height: 85%;
@@ -163,7 +163,7 @@ video {
         height: 70%;
         width: 70%;
         align-self: center;
-        margin: 0;
+        margin: 0px;
 
         // &:hover {
         //   width: 40px;
@@ -178,8 +178,8 @@ video {
     flex-direction: row;
     align-content: center;
     position: relative;
-    top: 0;
-    bottom: 0;
+    top: 0px;
+    bottom: 0px;
 
     &.video-edit-wrapper {
         // right: 50% - 15;
diff --git a/src/client/views/nodes/ScreenshotBox.scss b/src/client/views/nodes/ScreenshotBox.scss
index 1e9b64a0b..1714d87c2 100644
--- a/src/client/views/nodes/ScreenshotBox.scss
+++ b/src/client/views/nodes/ScreenshotBox.scss
@@ -32,10 +32,10 @@
 
 .screenshotBox-uiButtons {
     position: absolute;
-    right: 25;
-    top: 0;
-    width: 22;
-    height: 25;
+    right: 25px;
+    top: 0px;
+    width: 22px;
+    height: 25px;
 
     .screenshotBox-recorder {
         color: white;
diff --git a/src/client/views/nodes/ScriptingBox.scss b/src/client/views/nodes/ScriptingBox.scss
index 9789da55a..de70dbe74 100644
--- a/src/client/views/nodes/ScriptingBox.scss
+++ b/src/client/views/nodes/ScriptingBox.scss
@@ -82,14 +82,14 @@
                 }
 
                 .rta__autocomplete--top {
-                    margin-top: 0;
+                    margin-top: 0px;
                     margin-bottom: 1em;
                     max-height: 100px;
                 }
 
                 .rta__list {
-                    margin: 0;
-                    padding: 0;
+                    margin: 0px;
+                    padding: 0px;
                     background: #fff;
                     border: 1px solid #dfe2e5;
                     border-radius: 3px;
diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss
index b5405f0fb..27f419198 100644
--- a/src/client/views/nodes/VideoBox.scss
+++ b/src/client/views/nodes/VideoBox.scss
@@ -3,8 +3,8 @@
 .mini-viewer {
     cursor: grab;
     position: absolute;
-    right: 10;
-    top: 10;
+    right: 10px;
+    top: 10px;
     opacity: 0.1;
     transition: all 0.4s;
     color: white;
@@ -38,7 +38,7 @@
     .videoBox-annotationLayer {
         position: relative;
         transform-origin: left top;
-        top: 0;
+        top: 0px;
         width: 100%;
         pointer-events: none;
         mix-blend-mode: multiply; // bcz: makes text fuzzy!
@@ -81,8 +81,8 @@
 // }
 
 .videoBox-ui-wrapper {
-    width: 0;
-    height: 0;
+    width: 0px;
+    height: 0px;
     position: relative;
     z-index: 2000;
 }
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 05d5babf9..e7c9cf095 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -3,8 +3,8 @@
 .webBox {
     height: 100%;
     width: 100%;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     position: relative;
     display: flex;
     overflow: hidden;
@@ -28,8 +28,8 @@
         height: 100%;
         z-index: 1;
         pointer-events: none;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         overflow: hidden;
 
         .webBox-overlayButton {
@@ -39,16 +39,16 @@
             align-items: center;
             height: 20px;
             background: none;
-            padding: 0;
+            padding: 0px;
             position: absolute;
             pointer-events: all;
             color: white;
-            bottom: 0;
-            right: 0;
+            bottom: 0px;
+            right: 0px;
 
             .webBox-overlayButton-arrow {
-                width: 0;
-                height: 0;
+                width: 0px;
+                height: 0px;
                 border-top: 10px solid transparent;
                 border-bottom: 10px solid transparent;
                 border-right: 15px solid #121721;
@@ -92,7 +92,7 @@
             width: calc(100% - 40px);
             height: 20px;
             background: #121721;
-            bottom: 0;
+            bottom: 0px;
             display: flex;
             justify-content: center;
             align-items: center;
@@ -137,7 +137,7 @@
     .webBox-annotationLayer {
         position: absolute;
         transform-origin: left top;
-        top: 0;
+        top: 0px;
         width: 100%;
         pointer-events: none;
         mix-blend-mode: multiply; // bcz: makes text fuzzy!
@@ -156,8 +156,8 @@
 
         .webBox-htmlSpan {
             position: absolute;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
             cursor: text;
             padding: 15px;
             height: 100%;
@@ -171,8 +171,8 @@
         .webBox-cont-interactive {
             padding: 0vw;
             position: absolute;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
             width: 100%;
             height: 100%;
             transform-origin: top left;
@@ -181,8 +181,8 @@
                 width: 100%;
                 height: 100%;
                 position: absolute;
-                top: 0;
-                left: 0;
+                top: 0px;
+                left: 0px;
                 body {
                     ::selection {
                         color: white;
@@ -203,8 +203,8 @@
             height: 100%;
             position: absolute;
             transform-origin: top left;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
             overflow: auto;
 
             .webBox-innerContent {
@@ -224,7 +224,7 @@
     }
 
     .webBox-buttons {
-        margin-left: 44;
+        margin-left: 44px;
         background: lightGray;
         width: 100%;
     }
@@ -232,8 +232,8 @@
     .webBox-annotationToggle {
         z-index: 901;
         position: absolute;
-        top: 2;
-        left: 2;
+        top: 2px;
+        left: 2px;
         cursor: pointer;
         box-shadow: black 0.3em 0.3em 1em;
         border-radius: 5px;
diff --git a/src/client/views/nodes/audio/AudioWaveform.scss b/src/client/views/nodes/audio/AudioWaveform.scss
index 6cbd1759a..c6b0da9c8 100644
--- a/src/client/views/nodes/audio/AudioWaveform.scss
+++ b/src/client/views/nodes/audio/AudioWaveform.scss
@@ -1,17 +1,17 @@
-.audioWaveform  {
+.audioWaveform {
     position: relative;
     width: 100%;
     height: 200%;
     overflow: hidden;
     z-index: -1000;
-    bottom: 0;
+    bottom: 0px;
     pointer-events: none;
     div {
         height: 100% !important;
-        width: 100%  !important;
+        width: 100% !important;
     }
-    canvas { 
+    canvas {
         height: 100% !important;
-        width: 100%  !important;
+        width: 100% !important;
     }
 }
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss
index 3d27fa887..4db5cec3d 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss
@@ -28,7 +28,7 @@ $transition: all 0.2s ease-in-out;
         box-shadow: 0 1px 4px $shadow-color;
 
         h2 {
-            margin: 0;
+            margin: 0px;
             font-size: 1.5em;
             font-weight: 500;
         }
@@ -126,7 +126,7 @@ $transition: all 0.2s ease-in-out;
         animation: fadeIn 0.3s ease-in-out;
 
         p {
-            margin: 0;
+            margin: 0px;
             font-size: 14px;
         }
 
@@ -263,10 +263,10 @@ $transition: all 0.2s ease-in-out;
 
 .uploading-overlay {
     position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
     background-color: rgba(255, 255, 255, 0.8);
     display: flex;
     justify-content: center;
@@ -285,7 +285,7 @@ $transition: all 0.2s ease-in-out;
 
 @media (max-width: 768px) {
     .chat-box {
-        border-radius: 0;
+        border-radius: 0px;
     }
 
     .message {
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ProgressBar.scss b/src/client/views/nodes/chatbot/chatboxcomponents/ProgressBar.scss
index ff5be4a38..77d452830 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ProgressBar.scss
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ProgressBar.scss
@@ -21,8 +21,8 @@
     background-color: #4a90e2;
     opacity: 0.6;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     animation: bounce 2s infinite ease-in-out;
 }
 
@@ -42,10 +42,10 @@
 
 .uploading-overlay {
     position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
     background-color: rgba(255, 255, 255, 0.8);
     display: flex;
     align-items: center;
diff --git a/src/client/views/nodes/formattedText/DashFieldView.scss b/src/client/views/nodes/formattedText/DashFieldView.scss
index 3734ad9cc..1b2f76bbe 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.scss
+++ b/src/client/views/nodes/formattedText/DashFieldView.scss
@@ -17,7 +17,7 @@
         min-width: 12px;
         position: relative;
         display: inline-block;
-        margin: 0;
+        margin: 0px;
         transform: scale(0.7);
         background-color: rgba(155, 155, 155, 0.24);
     }
diff --git a/src/client/views/nodes/formattedText/EquationEditor.scss b/src/client/views/nodes/formattedText/EquationEditor.scss
index b0c17e56e..602135a30 100644
--- a/src/client/views/nodes/formattedText/EquationEditor.scss
+++ b/src/client/views/nodes/formattedText/EquationEditor.scss
@@ -32,7 +32,7 @@
     margin-left: -1px;
     position: relative;
     z-index: 1;
-    padding: 0;
+    padding: 0px;
     display: -moz-inline-box;
     display: inline-block;
 }
@@ -128,8 +128,8 @@
 .mq-math-mode * {
     font-size: inherit;
     line-height: inherit;
-    margin: 0;
-    padding: 0;
+    margin: 0px;
+    padding: 0px;
     border-color: black;
     -webkit-user-select: none;
     -moz-user-select: none;
@@ -178,7 +178,7 @@
     margin-left: 0.1em;
 }
 .mq-math-mode .mq-roman var.mq-f {
-    margin: 0;
+    margin: 0px;
 }
 .mq-math-mode big {
     font-size: 200%;
@@ -323,7 +323,7 @@
     padding: 0.1em;
 }
 .mq-math-mode .mq-sqrt-prefix {
-    padding-top: 0;
+    padding-top: 0px;
     position: relative;
     top: 0.1em;
     vertical-align: top;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 547a2efa8..d5e566226 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -46,7 +46,7 @@
 }
 
 audiotag {
-    left: 0;
+    left: 0px;
     position: absolute;
     cursor: pointer;
     border-radius: 10px;
@@ -62,7 +62,7 @@ audiotag:hover {
 .formattedTextBox {
     touch-action: none;
     background: inherit;
-    padding: 0;
+    padding: 0px;
     border-width: 0px;
     border-color: global.$medium-gray;
     box-sizing: border-box;
@@ -77,14 +77,14 @@ audiotag:hover {
     width: 100%;
     position: relative;
     transform-origin: left top;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
 }
 
 .formattedTextBox-cont {
     touch-action: none;
     background: inherit;
-    padding: 0;
+    padding: 0px;
     border-width: 0px;
     border-radius: inherit;
     border-color: global.$medium-gray;
@@ -111,7 +111,7 @@ audiotag:hover {
 .answer-tooltip {
     font-size: 15px;
     padding: 2px;
-    max-width: 150;
+    max-width: 150px;
     line-height: 150%;
     position: relative;
 }
@@ -122,10 +122,10 @@ audiotag:hover {
     position: absolute;
     color: white;
     background: black;
-    right: 0;
-    bottom: 0;
-    width: 15;
-    height: 22;
+    right: 0px;
+    bottom: 0px;
+    width: 15px;
+    height: 22px;
     cursor: default;
 }
 
@@ -139,8 +139,8 @@ audiotag:hover {
 
 .formattedTextBox-sidebar-handle {
     position: absolute;
-    top: 0;
-    right: 0;
+    top: 0px;
+    right: 0px;
     width: 20px;
     height: 20px;
     font-size: 11px;
@@ -168,7 +168,7 @@ audiotag:hover {
     height: 100%;
     display: inline-block;
     position: absolute;
-    right: 0;
+    right: 0px;
     overflow: hidden;
 
     .collectionfreeformview-container {
@@ -302,8 +302,8 @@ footnote::before {
     position: absolute;
     top: -0.5em;
     content: ' ';
-    height: 0;
-    width: 0;
+    height: 0px;
+    width: 0px;
 }
 
 .formattedTextBox-inlineComment {
@@ -346,7 +346,7 @@ footnote::before {
 .prosemirror-linkBtn {
     background: unset;
     color: unset;
-    padding: 0;
+    padding: 0px;
     text-transform: unset;
     letter-spacing: unset;
     font-size: unset;
@@ -357,7 +357,7 @@ footnote::before {
     background-color: dimgray;
     margin-top: 1.5em;
     z-index: 1;
-    padding: 5;
+    padding: 5px;
     border-radius: 2px;
 }
 .prosemirror-hrefoptions {
@@ -396,7 +396,7 @@ footnote::before {
     blockquote {
         padding: 10px 10px;
         font-size: smaller;
-        margin: 0;
+        margin: 0px;
         font-style: italic;
         background: lightgray;
         border-left: solid 2px dimgray;
@@ -415,7 +415,7 @@ footnote::before {
         p {
             font-family: inherit;
         }
-        margin-left: 0;
+        margin-left: 0px;
     }
     .bullet1 {
         p {
@@ -439,7 +439,7 @@ footnote::before {
             display: inline-block;
             font-family: inherit;
         }
-        margin-left: 0;
+        margin-left: 0px;
         background-color: inherit;
     }
     .decimal2-ol {
@@ -506,7 +506,7 @@ footnote::before {
             display: inline-block;
             font-family: inherit;
         }
-        margin-left: 0;
+        margin-left: 0px;
         padding-left: 1.2em;
         background-color: inherit;
     }
@@ -661,7 +661,7 @@ footnote::before {
     .formattedTextBox-cont {
         touch-action: none;
         background: inherit;
-        padding: 0;
+        padding: 0px;
         border-width: 0px;
         border-radius: inherit;
         border-color: global.$medium-gray;
@@ -706,7 +706,7 @@ footnote::before {
         height: 100%;
         display: inline-block;
         position: absolute;
-        right: 0;
+        right: 0px;
 
         .collectionfreeformview-container {
             position: relative;
@@ -832,8 +832,8 @@ footnote::before {
         position: absolute;
         top: -0.5em;
         content: ' ';
-        height: 0;
-        width: 0;
+        height: px;
+        width: 0px;
     }
 
     .formattedTextBox-inlineComment {
@@ -892,7 +892,7 @@ footnote::before {
                 display: inline;
                 font-family: inherit;
             }
-            margin-left: 0;
+            margin-left: 0px;
         }
         .decimal2-ol {
             counter-reset: deci2;
@@ -952,7 +952,7 @@ footnote::before {
                 display: inline;
                 font-family: inherit;
             }
-            margin-left: 0;
+            margin-left: 0px;
             padding-left: 1.2em;
         }
         .multi2-ol {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index bc0810f22..92f3e3290 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -11,8 +11,8 @@
     -webkit-transform: translateX(-50%);
     transform: translateX(-50%);
     box-shadow: 3px 3px 1.5px grey;
-    max-width: 400;
-    max-height: 235;
+    max-width: 400px;
+    max-height: 235px;
     height: max-content;
     .formattedTextBox-tooltipText {
         height: max-content;
@@ -22,26 +22,26 @@
 
 .formattedTextBox-tooltip:before {
     content: '';
-    height: 0;
-    width: 0;
+    height: 0px;
+    width: 0px;
     position: absolute;
     left: 50%;
     margin-left: -5px;
     bottom: -6px;
     border: 5px solid transparent;
-    border-bottom-width: 0;
+    border-bottom-width: 0px;
     border-top-color: silver;
 }
 
 .formattedTextBox-tooltip:after {
     content: '';
-    height: 0;
-    width: 0;
+    height: 0px;
+    width: 0px;
     position: absolute;
     left: 50%;
     margin-left: -5px;
     bottom: -4.5px;
     border: 5px solid transparent;
-    border-bottom-width: 0;
+    border-bottom-width: 0px;
     border-top-color: white;
 }
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.scss b/src/client/views/nodes/formattedText/RichTextMenu.scss
index fcc816447..7c747de1e 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.scss
+++ b/src/client/views/nodes/formattedText/RichTextMenu.scss
@@ -23,7 +23,7 @@
     .dropdown {
         position: absolute;
         top: 35px;
-        left: 0;
+        left: 0px;
         background-color: #323232;
         color: global.$light-gray;
         border: 1px solid #4d4d4d;
@@ -47,7 +47,7 @@
             }
 
             &:last-child {
-                margin-bottom: 0;
+                margin-bottom: 0px;
             }
         }
     }
diff --git a/src/client/views/nodes/formattedText/TooltipTextMenu.scss b/src/client/views/nodes/formattedText/TooltipTextMenu.scss
index 87320943d..8980a93a2 100644
--- a/src/client/views/nodes/formattedText/TooltipTextMenu.scss
+++ b/src/client/views/nodes/formattedText/TooltipTextMenu.scss
@@ -195,7 +195,7 @@
         left: 1px;
         width: 24px;
         height: 4px;
-        margin-top: 0;
+        margin-top: 0px;
     }
 }
 
@@ -221,7 +221,7 @@
     display: inline-block;
     width: 1em;
     height: 1em;
-    stroke-width: 0;
+    stroke-width: 0px;
     stroke: currentColor;
     fill: currentColor;
     margin-right: 15px;
@@ -231,7 +231,7 @@
     display: inline-block;
     width: 1em;
     height: 1em;
-    stroke-width: 3;
+    stroke-width: 3px;
     fill: greenyellow;
     margin-right: 15px;
 }
@@ -270,7 +270,7 @@
     &.ProseMirror-menu-dropdown {
         width: 10px;
         height: 25px;
-        margin: 0;
+        margin: 0px;
         padding: 0 2px;
         background-color: #323232;
         text-align: center;
diff --git a/src/client/views/nodes/imageEditor/ImageEditor.scss b/src/client/views/nodes/imageEditor/ImageEditor.scss
index c691e6a18..942a7d4c6 100644
--- a/src/client/views/nodes/imageEditor/ImageEditor.scss
+++ b/src/client/views/nodes/imageEditor/ImageEditor.scss
@@ -4,8 +4,8 @@ $scale: 0.5;
 
 .imageEditorContainer {
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     z-index: 9999;
     height: 100vh;
     width: 100vw;
@@ -78,7 +78,7 @@ $scale: 0.5;
         .sideControlsContainer {
             width: 160px;
             position: absolute;
-            left: 0;
+            left: 0px;
             height: 100%;
 
             .sideControls {
@@ -129,8 +129,8 @@ $scale: 0.5;
 
             .originalImageLabel {
                 position: absolute;
-                bottom: 10;
-                left: 10;
+                bottom: 10px;
+                left: 10px;
                 color: #ffffff;
                 font-size: 0.8rem;
                 letter-spacing: 1px;
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
index e24b47bd1..8875f7012 100644
--- a/src/client/views/nodes/trails/PresBox.scss
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -229,7 +229,7 @@
             .toolbar-transition {
                 display: flex;
                 font-size: 10;
-                width: 100;
+                width: 100px;
                 background-color: rgba(0, 0, 0, 0);
                 min-width: max-content;
 
@@ -358,7 +358,7 @@
         font-weight: 200;
         padding: 8px;
         border-radius: 4px;
-        // height: 20;
+        // height: 20px;
         // display: flex;
         // margin-left: 5px;
         // margin-top: 5px;
@@ -371,8 +371,8 @@
     }
 
     .ribbon-propertyUpDown {
-        height: 20;
-        width: 20;
+        height: 20px;
+        width: 20px;
         margin-top: 5px;
         display: grid;
         grid-template-rows: 10px 10px;
@@ -486,7 +486,7 @@
             -moz-user-select: none;
             -ms-user-select: none;
             user-select: none;
-            margin: 0;
+            margin: 0px;
             margin-right: 3px;
             border-radius: 100%;
             height: 15px;
@@ -658,9 +658,9 @@
             height: 25px;
             color: white;
             width: 100%;
-            max-width: 120;
-            padding-left: 10;
-            padding-right: 10;
+            max-width: 120px;
+            padding-left: 10px;
+            padding-right: 10px;
             border-radius: 10px;
             background-color: global.$medium-gray;
         }
@@ -683,9 +683,9 @@
             height: 25px;
             color: global.$light-gray;
             width: 100%;
-            max-width: 120;
-            padding-left: 10;
-            padding-right: 10;
+            max-width: 120px;
+            padding-left: 10px;
+            padding-right: 10px;
             border-radius: 10px;
             background-color: global.$black;
         }
@@ -745,9 +745,9 @@
 
     .selectedList {
         display: block;
-        min-width: 50;
-        max-width: 120;
-        height: 70;
+        min-width: 50px;
+        max-width: 120px;
+        height: 70px;
         overflow-y: scroll;
 
         .selectedList-items {
@@ -760,7 +760,7 @@
         cursor: pointer;
         font-size: 10.5;
         font-weight: 300;
-        height: 20;
+        height: 20px;
         background-color: global.$medium-gray;
         color: white;
         display: flex;
@@ -788,7 +788,7 @@
         cursor: pointer;
         font-size: 10.5;
         font-weight: 200;
-        height: 20;
+        height: 20px;
         background-color: global.$white;
         display: inline-flex;
         color: global.$black;
@@ -813,7 +813,7 @@
     }
 
     svg.svg-inline--fa.fa-thumbtack.fa-w-12.toolbar-thumbtack {
-        right: 40;
+        right: 40px;
         position: absolute;
         transform: rotate(45deg);
     }
@@ -850,7 +850,7 @@
             background-color: global.$light-gray;
             border-radius: 5px;
             font-size: 10;
-            height: 25;
+            height: 25px;
             color: global.$black;
             padding-left: 5px;
             align-items: center;
@@ -868,8 +868,8 @@
                 display: block;
                 padding-left: 10px;
                 padding-right: 5px;
-                padding-top: 3;
-                padding-bottom: 3;
+                padding-top: 3px;
+                padding-bottom: 3px;
                 opacity: 0.8;
             }
 
@@ -959,8 +959,8 @@
     border-radius: 4px;
     padding-left: 7px;
     padding-right: 7px;
-    border-bottom-right-radius: 0;
-    border-top-right-radius: 0;
+    border-bottom-right-radius: 0px;
+    border-top-right-radius: 0px;
 }
 
 .presBox-button-right {
@@ -976,8 +976,8 @@
     border-radius: 4px;
     padding-left: 7px;
     padding-right: 7px;
-    border-bottom-left-radius: 0;
-    border-top-left-radius: 0;
+    border-bottom-left-radius: 0px;
+    border-top-left-radius: 0px;
 }
 
 .presBox-button-right.active {
@@ -1043,8 +1043,8 @@
         cursor: pointer;
         align-self: center;
         justify-self: center;
-        margin-top: 5;
-        margin-bottom: 5;
+        margin-top: 5px;
+        margin-bottom: 5px;
         position: relative;
         height: 55px;
         min-width: 90px;
@@ -1063,7 +1063,7 @@
             padding-left: 3px;
             margin-left: 3px;
             margin-right: 3px;
-            height: 13;
+            height: 13px;
             font-size: 12;
             display: flex;
             background-color: global.$white;
@@ -1076,7 +1076,7 @@
             margin-left: 3px;
             margin-right: 3px;
             font-weight: 400;
-            height: 13;
+            height: 13px;
             font-size: 9;
             display: flex;
             background-color: global.$white;
@@ -1089,11 +1089,11 @@
             padding-left: 3px;
             margin-left: 3px;
             margin-right: 3px;
-            height: 13;
+            height: 13px;
             font-size: 10;
             display: flex;
             background-color: global.$white;
-            height: 33;
+            height: 33px;
             text-align: left;
             font-size: 8px;
         }
@@ -1112,7 +1112,7 @@
 
     .presBox-viewPicker {
         cursor: pointer;
-        height: 25;
+        height: 25px;
         position: relative;
         display: inline-block;
         grid-column: 1;
@@ -1184,9 +1184,9 @@
     }
 
     .collectionViewBaseChrome-viewPicker {
-        min-width: 50;
+        min-width: 50px;
         width: 5%;
-        height: 25;
+        height: 25px;
         position: relative;
         display: inline-block;
         left: 8px;
@@ -1210,11 +1210,11 @@
 }
 
 .presBox-backward {
-    left: 5;
+    left: 5px;
 }
 
 .presBox-forward {
-    right: 5;
+    right: 5px;
 }
 
 // CSS adjusted for mobile devices
@@ -1233,8 +1233,8 @@
 
         .presBox-button {
             margin-top: 5%;
-            height: 250;
-            width: 300;
+            height: 250px;
+            width: 300px;
             font-size: 100;
             display: flex;
             align-items: center;
@@ -1256,7 +1256,7 @@
     }
 
     .presBox-cont .presBox-listCont {
-        top: 50;
+        top: 50px;
         height: calc(100% - 80px);
     }
 
@@ -1269,8 +1269,8 @@
 .miniPres {
     cursor: grab;
     position: absolute;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     opacity: 0.5;
     transition: all 0.4s;
     color: global.$white;
@@ -1298,7 +1298,7 @@
     .presPanel-button-text {
         cursor: pointer;
         display: flex;
-        height: 20;
+        height: 20px;
         width: max-content;
         font-family: Roboto;
         font-weight: 400;
@@ -1327,8 +1327,8 @@
         grid-template-columns: auto auto auto;
         justify-content: space-around;
         font-size: 11;
-        margin-left: 7;
-        width: 30;
+        margin-left: 7px;
+        width: 30px;
         height: 85%;
         background-color: rgba(91, 157, 221, 0.4);
         border-radius: 5px;
@@ -1337,8 +1337,8 @@
     .presPanel-button {
         cursor: pointer;
         display: flex;
-        height: 20;
-        min-width: 20;
+        height: 20px;
+        min-width: 20px;
         margin-left: 3px;
         margin-right: 3px;
         border-radius: 100%;
@@ -1361,8 +1361,8 @@
 //     cursor: grab;
 //     position: absolute;
 //     overflow: hidden;
-//     right: 10;
-//     top: 10;
+//     right: 10px;
+//     top: 10px;
 //     opacity: 0.1;
 //     transition: all 0.4s;
 //     /* border: solid 1px; */
@@ -1380,7 +1380,7 @@
 //         .miniPres-button-text {
 //             cursor: pointer;
 //             display: flex;
-//             height: 20;
+//             height: 20px;
 //             font-weight: 400;
 //             min-width: 100%;
 //             border-radius: 5px;
@@ -1397,8 +1397,8 @@
 //             grid-template-columns: auto auto auto;
 //             justify-content: space-around;
 //             font-size: 11;
-//             margin-left: 7;
-//             width: 30;
+//             margin-left: 7px;
+//             width: 30px;
 //             height: 85%;
 //             background-color: rgba(91, 157, 221, 0.4);
 //             border-radius: 5px;
@@ -1413,8 +1413,8 @@
 //         .miniPres-button {
 //             cursor: pointer;
 //             display: flex;
-//             height: 20;
-//             min-width: 20;
+//             height: 20px;
+//             min-width: 20px;
 //             border-radius: 100%;
 //             align-items: center;
 //             justify-content: center;
diff --git a/src/client/views/nodes/trails/PresSlideBox.scss b/src/client/views/nodes/trails/PresSlideBox.scss
index 9ac2b5a94..740bcae5f 100644
--- a/src/client/views/nodes/trails/PresSlideBox.scss
+++ b/src/client/views/nodes/trails/PresSlideBox.scss
@@ -117,8 +117,8 @@ $slide-active: #5b9fdd;
         height: 100%;
         position: absolute;
         border-radius: 3px;
-        top: 0;
-        left: 0;
+        top: 0px;
+        left: 0px;
         z-index: 1;
         overflow: hidden;
     }
@@ -209,7 +209,7 @@ $slide-active: #5b9fdd;
     position: absolute;
     /* grid-row: 3; */
     /* grid-column: 1/8; */
-    top: 28;
+    top: 28px;
     display: block;
     background: #92adb9;
     width: 100%;
@@ -276,7 +276,7 @@ $slide-active: #5b9fdd;
     cursor: pointer;
     position: absolute;
     border-radius: 100px;
-    bottom: 0;
+    bottom: 0px;
     left: -18;
     z-index: 300;
     width: 15px;
@@ -302,7 +302,7 @@ $slide-active: #5b9fdd;
     color: #d5dce2;
     position: absolute;
     left: -15px;
-    top: 1;
+    top: 1px;
     font-weight: 600;
     font-size: 12;
 }
diff --git a/src/client/views/pdf/AnchorMenu.scss b/src/client/views/pdf/AnchorMenu.scss
index 6990bdcf1..98eeaf80e 100644
--- a/src/client/views/pdf/AnchorMenu.scss
+++ b/src/client/views/pdf/AnchorMenu.scss
@@ -6,19 +6,19 @@
 }
 .anchorMenu-highlighter {
     padding-right: 5px;
-    .antimodeMenu-button  {
-        padding: 0;
-        padding: 0;
+    .antimodeMenu-button {
+        padding: 0px;
+        padding: 0px;
         padding-right: 0px;
         padding-left: 0px;
         width: 5px;
     }
 }
-.anchor-color-preview-button {  
-    width: 25px !important;  
+.anchor-color-preview-button {
+    width: 25px !important;
     .anchor-color-preview {
         display: flex;
-        flex-direction:  column;
+        flex-direction: column;
         padding-right: 3px;
         width: unset !important;
         .color-preview {
@@ -51,4 +51,4 @@
             border: 2px solid white;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss
index f6fa45221..85c1f6759 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.scss
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss
@@ -20,8 +20,8 @@ $headingHeight: 32px;
     left: 75px;
     width: 100%;
     height: 100%;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     border-top: solid gray 20px;
     border-radius: 16px;
     z-index: 999;
@@ -58,7 +58,7 @@ $headingHeight: 32px;
         font-size: 12px;
         font-weight: 400;
         letter-spacing: 1px;
-        margin: 0;
+        margin: 0px;
         padding-right: 5px;
     }
 
@@ -214,8 +214,8 @@ $headingHeight: 32px;
         .img-container::after {
             content: '';
             position: absolute;
-            top: 0;
-            left: 0;
+            top: 0px;
+            left: 0px;
             width: 100%;
             height: 100%;
             background-color: rgba(0, 0, 0, 0.5);
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index a54505443..dafa908a2 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -3,8 +3,8 @@
     width: 100%;
     position: absolute;
     display: inline-block;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
 }
 
 :root {
@@ -16,8 +16,8 @@
     position: absolute;
     width: 100%;
     height: 100%;
-    top: 0;
-    left: 0;
+    top: 0px;
+    left: 0px;
     position: absolute;
     overflow-y: auto;
     overflow-x: hidden;
@@ -99,7 +99,7 @@
     .pdfViewerDash-annotationLayer {
         position: absolute;
         transform-origin: left top;
-        top: 0;
+        top: 0px;
         width: 100%;
         pointer-events: none;
         mix-blend-mode: multiply; // bcz: makes text fuzzy!
diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss
index 35a3da312..ca177c746 100644
--- a/src/client/views/topbar/TopBar.scss
+++ b/src/client/views/topbar/TopBar.scss
@@ -125,7 +125,7 @@
 
         .topbar-lozenge-user,
         .topbar-lozenge {
-            height: 23;
+            height: 23px;
             font-size: 12;
             color: white;
             font-family: 'Roboto';
diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx
index f3295a6c6..354ed11d6 100644
--- a/src/debug/Viewer.tsx
+++ b/src/debug/Viewer.tsx
@@ -1,8 +1,5 @@
 /* eslint-disable react/no-unescaped-entities */
-/* eslint-disable react/button-has-type */
 /* eslint-disable no-use-before-define */
-/* eslint-disable react/no-array-index-key */
-/* eslint-disable no-redeclare */
 import { action, configure, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
diff --git a/src/fields/FieldLoader.scss b/src/fields/FieldLoader.scss
index 9a23c3e4f..62d85a763 100644
--- a/src/fields/FieldLoader.scss
+++ b/src/fields/FieldLoader.scss
@@ -1,7 +1,7 @@
 .fieldLoader {
     z-index: 10000;
     width: 200px;
-    height: 30;
+    height: 30px;
     background: lightblue;
     position: absolute;
     left: calc(50% - 99px);
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 7c55e4a42..1e68a4e30 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -18,7 +18,7 @@ export default class UploadManager extends ApiManager {
     protected initialize(register: Registration): void {
         register({
             method: Method.POST,
-            subscription: '/ping',
+            subscription: '/DashPing',
             secureHandler: async ({ /* req, */ res }) => {
                 _success(res, { message: DashVersion, date: new Date() });
             },
diff --git a/src/server/PdfTypes.ts b/src/server/PdfTypes.ts
index fb435a677..458df7b26 100644
--- a/src/server/PdfTypes.ts
+++ b/src/server/PdfTypes.ts
@@ -2,7 +2,7 @@ export interface PDFInfo {
     PDFFormatVersion: string;
     IsAcroFormPresent: boolean;
     IsXFAPresent: boolean;
-    [key: string]: any;
+    [key: string]: unknown;
 }
 export interface PDFMetadata {
     parse(): void;
diff --git a/views/stylesheets/authentication.css b/views/stylesheets/authentication.css
index ff1f4aace..dbd1043a4 100644
--- a/views/stylesheets/authentication.css
+++ b/views/stylesheets/authentication.css
@@ -110,10 +110,10 @@ body {
     text-align: center;
     position: absolute;
     margin: auto;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    right: 0;
+    top: 0px;
+    bottom: 0px;
+    left: 0px;
+    right: 0px;
     width: 400px;
     background-color: white;
     border-radius: 8px;
@@ -122,10 +122,10 @@ body {
 
 .inner {
     position: absolute;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    right: 0;
+    top: 0px;
+    bottom: 0px;
+    left: 0px;
+    right: 0px;
     width: 230px;
     margin: auto;
 }
@@ -141,7 +141,8 @@ body {
     font-size: 16px;
 }
 
-.outermost, .online-container {
+.outermost,
+.online-container {
     display: flex;
     flex-direction: row;
     height: 98vh;
@@ -220,4 +221,4 @@ span.user-type {
 
 #inactive-inner {
     border-bottom-right-radius: 8px;
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3-70-g09d2


From 35bd9e51f7cef551382025a5459d68eddd8f028b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 23 Jun 2025 13:26:59 -0400
Subject: fixed invalidations to not trigger creating new refs when ref= was
 assigned to an anonymous function.  fixed scribble erase to not delete
 everything it overlaps, just things it intersects with or contains.  fixed
 ink to have a Math mode and fixed math recognition myscript calls.

---
 src/Utils.ts                                       |   3 +
 src/client/util/CurrentUserUtils.ts                |   4 +
 src/client/views/EditableView.tsx                  |   5 +-
 src/client/views/GestureOverlay.tsx                |   4 +-
 src/client/views/InkTranscription.tsx              | 182 +++++++++++----------
 src/client/views/InkingStroke.tsx                  |   2 +-
 src/client/views/LightboxView.tsx                  |   3 +-
 src/client/views/MainView.tsx                      |  36 ++--
 src/client/views/UndoStack.tsx                     |   3 +-
 src/client/views/animationtimeline/Timeline.tsx    |   3 +-
 .../views/collections/CollectionNoteTakingView.tsx |   3 +-
 .../views/collections/CollectionStackingView.tsx   |  10 +-
 .../CollectionStackingViewFieldColumn.tsx          |  12 +-
 .../views/collections/CollectionTreeView.tsx       |   3 +-
 src/client/views/collections/TreeView.tsx          |   3 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  53 +++---
 .../collectionFreeForm/FaceCollectionBox.tsx       |   3 +-
 .../collections/collectionFreeForm/MarqueeView.tsx |  39 ++---
 .../collectionLinear/CollectionLinearView.tsx      |   5 +-
 .../collectionSchema/CollectionSchemaView.tsx      |  24 ++-
 .../collectionSchema/SchemaCellField.tsx           |   4 +-
 .../collectionSchema/SchemaColumnHeader.tsx        |   9 +-
 .../collectionSchema/SchemaTableCell.tsx           |   3 +-
 src/client/views/global/globalScripts.ts           |   2 +-
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   |   7 +-
 .../DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx   |   3 +-
 .../nodes/DataVizBox/components/Histogram.tsx      |  11 +-
 .../nodes/DataVizBox/components/LineChart.tsx      |  11 +-
 .../views/nodes/DataVizBox/components/PieChart.tsx |  15 +-
 src/client/views/nodes/DiagramBox.tsx              |   6 +-
 src/client/views/nodes/DocumentContentsView.tsx    |   4 +-
 src/client/views/nodes/DocumentView.tsx            |  22 +--
 src/client/views/nodes/EquationBox.tsx             |   3 +-
 src/client/views/nodes/FunctionPlotBox.tsx         |   3 +-
 src/client/views/nodes/LabelBox.tsx                |  38 +++--
 src/client/views/nodes/LinkBox.tsx                 |  23 +--
 src/client/views/nodes/LinkDocPreview.tsx          |   9 +-
 src/client/views/nodes/ScreenshotBox.tsx           |  18 +-
 src/client/views/nodes/calendarBox/CalendarBox.tsx |  35 ++--
 .../nodes/chatbot/chatboxcomponents/ChatBox.tsx    |  14 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   8 +-
 src/client/views/nodes/trails/PresBox.tsx          |  51 +++---
 src/client/views/pdf/GPTPopup/GPTPopup.tsx         |   3 +-
 src/fields/InkField.ts                             |   1 +
 44 files changed, 358 insertions(+), 345 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingViewFieldColumn.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 724725c23..e96b8e231 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -202,6 +202,9 @@ export function aggregateBounds(boundsList: { x: number; y: number; width?: numb
 export function intersectRect(r1: { left: number; top: number; width: number; height: number }, r2: { left: number; top: number; width: number; height: number }) {
     return !(r2.left > r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top);
 }
+export function rectContains(r1: { left: number; top: number; width: number; height: number }, r2: { left: number; top: number; width: number; height: number }) {
+    if (r1.left < r2.left && r1.left + r1.width > r2.left + r2.width && r1.top < r2.top && r1.top + r1.height > r2.top + r2.height) return true;
+}
 
 export function stringHash(s?: string) {
     return !s ? undefined : Math.abs(s.split('').reduce((a, b) => (n => n & n)((a << 5) - a + b.charCodeAt(0)), 0));
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 45feb0b2f..9fbc82bef 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -796,6 +796,7 @@ pie title Minerals in my tap water
                     { title: "Pen",      toolTip: "Pen (Ctrl+P)",           btnType: ButtonType.ToggleButton, icon: "pen-nib",     toolType: InkInkTool.Pen,         ignoreClick: true, scripts: {onClick:'{ return setActiveTool(this.toolType, true, _readOnly_);}' }},
                     { title: "Highlight",toolTip: "Highlight (Ctrl+H)",     btnType: ButtonType.ToggleButton, icon: "highlighter", toolType: InkInkTool.Highlight,   ignoreClick: true, scripts: {onClick:'{ return setActiveTool(this.toolType, true, _readOnly_);}' }},
                     { title: "Write",    toolTip: "Write (Ctrl+Shift+P)",   btnType: ButtonType.ToggleButton, icon: "pen",         toolType: InkInkTool.Write,       ignoreClick: true, scripts: {onClick:'{ return setActiveTool(this.toolType, true, _readOnly_);}' },  funcs: {hidden:"IsNoviceMode()" }},      
+                    { title: "Math",     toolTip: "Math",                   btnType: ButtonType.ToggleButton, icon: "calculator",  toolType: InkInkTool.Math,        ignoreClick: true, scripts: {onClick:'{ return setActiveTool(this.toolType, true, _readOnly_);}' },  funcs: {hidden:"IsNoviceMode()" }},      
                 ]},
             { title: "Width",      toolTip: "Stroke width",                 btnType: ButtonType.NumberSliderButton,                toolType: InkProperty.StrokeWidth,ignoreClick: true, scripts: {script: '{ return setInkProperty(this.toolType, value, _readOnly_);}'}, funcs: {hidden:"!activeInkTool()"}, numBtnMin: 1, linearView_btnWidth:40},
             { title: "Color",      toolTip: "Stroke color",                 btnType: ButtonType.ColorButton,  icon: "pen",         toolType: InkProperty.StrokeColor,ignoreClick: true, scripts: {script: '{ return setInkProperty(this.toolType, value, _readOnly_);}'}, funcs: {hidden:"!activeInkTool()"}},
@@ -1032,6 +1033,9 @@ pie title Minerals in my tap water
         doc[`active${InkInkTool.Write}Color`]      ?? (doc[`active${InkInkTool.Write}Color`] = "rgb(255, 0, 0)");
         doc[`active${InkInkTool.Write}Width`]      ?? (doc[`active${InkInkTool.Write}Width`] = 1);
         doc[`active${InkInkTool.Write}Bezier`]     ?? (doc[`active${InkInkTool.Write}Bezier`] = "0");
+        doc[`active${InkInkTool.Math}Color`]       ?? (doc[`active${InkInkTool.Math}Color`] = "rgb(0, 0, 255)");
+        doc[`active${InkInkTool.Math}Width`]       ?? (doc[`active${InkInkTool.Math}Width`] = 1);
+        doc[`active${InkInkTool.Math}Bezier`]      ?? (doc[`active${InkInkTool.Math}Bezier`] = "0");
         doc[`active${InkInkTool.Highlight}Color`]  ?? (doc[`active${InkInkTool.Highlight}Color`] = 'transparent');
         doc[`active${InkInkTool.Highlight}Width`]  ?? (doc[`active${InkInkTool.Highlight}Width`] = 20);
         doc[`active${InkInkTool.Highlight}Bezier`] ?? (doc[`active${InkInkTool.Highlight}Bezier`] = "0");
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index d9447b7ec..deeabaa28 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -236,6 +236,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
         return this._editing;
     };
 
+    setInputRef = (r: HTMLInputElement | HTMLTextAreaElement | null) => (this._inputref = r);
     renderEditor() {
         return this._props.autosuggestProps ? (
             <Autosuggest
@@ -255,7 +256,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
         ) : this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? (
             <input
                 className="editableView-input"
-                ref={r => { this._inputref = r; }} // prettier-ignore
+                ref={this.setInputRef}
                 style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minWidth: 20, background: this._props.background }}
                 placeholder={this._props.placeholder}
                 onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
@@ -270,7 +271,7 @@ export class EditableView extends ObservableReactComponent<EditableProps> {
         ) : (
             <textarea
                 className="editableView-input"
-                ref={r => { this._inputref = r; }} // prettier-ignore
+                ref={this.setInputRef}
                 style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, background: this._props.background }}
                 placeholder={this._props.placeholder}
                 onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 777a34ebc..8488c5293 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -3,7 +3,7 @@ import { action, computed, makeObservable, observable, runInAction } from 'mobx'
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { setupMoveUpEvents } from '../../ClientUtils';
-import { emptyFunction, intersectRect } from '../../Utils';
+import { emptyFunction, intersectRect, rectContains } from '../../Utils';
 import { Doc } from '../../fields/Doc';
 import { InkData, InkField, InkTool } from '../../fields/InkField';
 import { NumCast } from '../../fields/Types';
@@ -166,7 +166,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
      */
     docsInBoundingBox = (boundingBox: { topLeft: number[]; bottomRight: number[] }, childDocs: Doc[]): Doc[] => {
         const rect = { left: boundingBox.topLeft[0], top: boundingBox.topLeft[1], width: boundingBox.bottomRight[0] - boundingBox.topLeft[0], height: boundingBox.bottomRight[1] - boundingBox.topLeft[1] };
-        return childDocs.filter(doc => intersectRect(rect, { left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) }));
+        return childDocs.filter(doc => rectContains(rect, { left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) }));
     };
     /**
      * Determines if what the array of cusp/intersection data corresponds to a scribble.
diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx
index 6220033d4..32ca5f56b 100644
--- a/src/client/views/InkTranscription.tsx
+++ b/src/client/views/InkTranscription.tsx
@@ -32,7 +32,7 @@ export class InkTranscription extends React.Component {
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
     @observable _iinkEditor: any = undefined;
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    private lastJiix: any;
+    @observable _iinkMathEditor: any = undefined;
     private currGroup?: Doc;
     private collectionFreeForm?: CollectionFreeFormView;
 
@@ -44,7 +44,7 @@ export class InkTranscription extends React.Component {
     @action
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
     setMathRef = async (r: any) => {
-        if (!this._textRegister && r) {
+        if (!this._mathRegister && r) {
             const options = {
                 configuration: {
                     server: {
@@ -55,19 +55,17 @@ export class InkTranscription extends React.Component {
                         protocol: 'WEBSOCKET',
                     },
                     recognition: {
-                        type: 'TEXT',
-                        lang: 'en_US',
-                        text: {
-                            mimeTypes: ['application/vnd.myscript.jiix'] as 'application/vnd.myscript.jiix'[],
+                        type: 'MATH',
+                        math: {
+                            mimeTypes: ['application/x-latex'] as unknown as 'application/vnd.myscript.jiix'[],
                         },
                     },
                 },
             };
-            await iink.Editor.load(r, 'INKV2', options);
-
-            this._textRegister = r;
+            this._iinkMathEditor = await iink.Editor.load(r, 'INKV2', options);
+            this._mathRegister = r;
             // eslint-disable-next-line @typescript-eslint/no-explicit-any
-            r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef));
+            r?.addEventListener('exported', (e: any) => this.exportInk(e));
 
             return (this._textRef = r);
         }
@@ -97,12 +95,14 @@ export class InkTranscription extends React.Component {
             this._iinkEditor = await iink.Editor.load(r, 'INKV2', options);
             this._textRegister = r;
             // eslint-disable-next-line @typescript-eslint/no-explicit-any
-            r?.addEventListener('exported', (e: any) => this.exportInk(e, this._textRef));
+            r?.addEventListener('exported', (e: any) => this.exportInk(e));
 
             return (this._textRef = r);
         }
     };
 
+    _ffview: CollectionFreeFormView | undefined;
+
     /**
      * Handles processing Dash Doc data for ink transcription.
      *
@@ -110,7 +110,7 @@ export class InkTranscription extends React.Component {
      * @param inkDocs the ink docs contained within the selected group
      * @param math boolean whether to do math transcription or not
      */
-    transcribeInk = (groupDoc: Doc | undefined, inkDocs: Doc[], math: boolean) => {
+    transcribeInk = (ffview: CollectionFreeFormView, groupDoc: Doc | undefined, inkDocs: Doc[], math: boolean) => {
         if (!groupDoc) return;
         const validInks = inkDocs.filter(s => s.type === DocumentType.INK);
 
@@ -126,13 +126,10 @@ export class InkTranscription extends React.Component {
                 strokes.push(d.inkData.map(pd => inkStroke.ptToScreen({ X: pd.X, Y: pd.Y })));
                 times.push(authorTime);
             });
+        this._ffview = ffview;
         this.currGroup = groupDoc;
         const pointerData = strokes.map((stroke, i) => this.inkJSON(stroke, times[i]));
-        if (math) {
-            this._iinkEditor.importPointEvents(pointerData);
-        } else {
-            this._iinkEditor.importPointEvents(pointerData);
-        }
+        (math ? this._iinkMathEditor : this._iinkEditor).importPointEvents(pointerData);
     };
     convertPointsToString(points: InkData[]): string {
         return points[0].map(point => `new Point(${point.X}, ${point.Y})`).join(',');
@@ -204,83 +201,92 @@ export class InkTranscription extends React.Component {
      * @param ref the ref to the editor
      */
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
-    exportInk = async (e: any, ref: any) => {
-        const exports = e.detail['application/vnd.myscript.jiix'];
-        if (exports) {
-            if (exports['type'] == 'Math') {
-                const latex = exports['application/x-latex'];
-                if (this.currGroup) {
-                    this.currGroup.text = latex;
-                    this.currGroup.title = latex;
-                }
+    exportInk = (e: { detail: { [key: string]: string } }) => {
+        const exports = e.detail;
+        if (exports['application/x-latex']) {
+            const latex = exports['application/x-latex'];
+            if (this.currGroup) {
+                this.currGroup.text = latex;
+                this.currGroup.title = latex;
+            }
 
-                ref.editor.clear();
-            } else if (exports['type'] == 'Text') {
-                if (exports['application/vnd.myscript.jiix']) {
-                    this.lastJiix = JSON.parse(exports['application/vnd.myscript.jiix']);
-                    // map timestamp to strokes
-                    const timestampWord = new Map<number, string>();
-                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
-                    this.lastJiix.words.map((word: any) => {
-                        if (word.items) {
-                            word.items.forEach((i: { id: string; timestamp: string; X: Array<number>; Y: Array<number>; F: Array<number> }) => {
-                                const ms = Date.parse(i.timestamp);
-                                timestampWord.set(ms, word.label);
-                            });
-                        }
+            this._ffview?.addDocument(
+                Docs.Create.EquationDocument(latex, {
+                    title: '',
+                    x: this.currGroup?.x as number,
+                    y: (this.currGroup?.y as number) + (this.currGroup?.height as number),
+                    nativeHeight: 40,
+                    _height: 50,
+                    nativeWidth: 40,
+                    _width: 50,
+                })
+            );
+            // this.showRecogBox(latex as string);
+            this._iinkMathEditor.clear();
+        } else if (exports['application/vnd.myscript.jiix']) {
+            const lastJiix = exports['application/vnd.myscript.jiix'] as unknown as { words: string[]; label: string };
+            // map timestamp to strokes
+            const timestampWord = new Map<number, string>();
+            // eslint-disable-next-line @typescript-eslint/no-explicit-any
+            lastJiix.words.map((word: any) => {
+                if (word.items) {
+                    word.items.forEach((i: { id: string; timestamp: string; X: Array<number>; Y: Array<number>; F: Array<number> }) => {
+                        const ms = Date.parse(i.timestamp);
+                        timestampWord.set(ms, word.label);
                     });
-
-                    const wordInkDocMap = new Map<string, Doc[]>();
-                    if (this.currGroup) {
-                        const docList = DocListCast(this.currGroup.data);
-                        docList.forEach((inkDoc: Doc) => {
-                            // just having the times match up and be a unique value (actual timestamp doesn't matter)
-                            const ms = (DateCast(inkDoc.author_date)?.getDate().getTime() ?? 0) + 14400000;
-                            const word = timestampWord.get(ms);
-                            if (!word) {
-                                return;
-                            }
-                            const entry = wordInkDocMap.get(word);
-                            if (entry) {
-                                entry.push(inkDoc);
-                                wordInkDocMap.set(word, entry);
-                            } else {
-                                const newEntry = [inkDoc];
-                                wordInkDocMap.set(word, newEntry);
-                            }
-                        });
-                        if (this.lastJiix.words.length > 1) this.subgroupsTranscriptions(wordInkDocMap);
-                    }
                 }
-                const text = exports['label'];
+            });
 
-                if (this.currGroup && text) {
-                    DocumentView.getDocumentView(this.currGroup)?.ComponentView?.updateIcon?.();
-                    const image = await this.getIcon();
-                    const { href } = (image as URLField).url;
-                    const hrefParts = href.split('.');
-                    const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`;
-                    let response;
-                    try {
-                        const hrefBase64 = await imageUrlToBase64(hrefComplete);
-                        response = await gptHandwriting(hrefBase64);
-                    } catch {
-                        console.error('Error getting image');
-                    }
-                    const textBoxText = 'iink: ' + text + '\n' + '\n' + 'ChatGPT: ' + response;
-                    this.currGroup.transcription = response;
-                    this.currGroup.title = response;
-                    if (!this.currGroup.hasTextBox) {
-                        const newDoc = Docs.Create.TextDocument(textBoxText, { title: '', x: this.currGroup.x as number, y: (this.currGroup.y as number) + (this.currGroup.height as number) });
-                        newDoc.height = 200;
-                        this.collectionFreeForm?.addDocument(newDoc);
-                        this.currGroup.hasTextBox = true;
+            const wordInkDocMap = new Map<string, Doc[]>();
+            if (this.currGroup) {
+                DocListCast(this.currGroup.data).forEach((inkDoc: Doc) => {
+                    // just having the times match up and be a unique value (actual timestamp doesn't matter)
+                    const ms = (DateCast(inkDoc.author_date)?.getDate().getTime() ?? 0) + 14400000;
+                    const word = timestampWord.get(ms);
+                    if (word) {
+                        const entry = wordInkDocMap.get(word);
+                        if (entry) {
+                            entry.push(inkDoc);
+                            wordInkDocMap.set(word, entry);
+                        } else {
+                            const newEntry = [inkDoc];
+                            wordInkDocMap.set(word, newEntry);
+                        }
                     }
-                    ref.editor.clear();
-                }
+                });
+                if (lastJiix.words.length > 1) this.subgroupsTranscriptions(wordInkDocMap);
             }
+            this.showRecogBox(lastJiix.label);
+            this._iinkEditor.clear();
         }
     };
+    private showRecogBox(text: string) {
+        if (this.currGroup) {
+            let response;
+            // DocumentView.getDocumentView(this.currGroup)?.ComponentView?.updateIcon?.();
+            // const image = await this.getIcon();
+            // const { href } = (image as URLField).url;
+            // const hrefParts = href.split('.');
+            // const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`;
+            // try {
+            //     const hrefBase64 = await imageUrlToBase64(hrefComplete);
+            //     response = await gptHandwriting(hrefBase64);
+            // } catch {
+            //     console.error('Error getting image');
+            // }
+            const textBoxText = 'iink: ' + text + '\n' + '\n' + 'ChatGPT: ' + response;
+
+            this.currGroup.transcription = response;
+            this.currGroup.title = response;
+            if (!this.currGroup.hasTextBox) {
+                const newDoc = Docs.Create.TextDocument(textBoxText, { title: '', x: this.currGroup.x as number, y: (this.currGroup.y as number) + (this.currGroup.height as number) });
+                newDoc.height = 200;
+                this.collectionFreeForm?.addDocument(newDoc);
+                this.currGroup.hasTextBox = true;
+            }
+        }
+    }
+
     /**
      * gets the icon of the collection that was just made
      * @returns the image of the collection
@@ -299,7 +305,7 @@ export class InkTranscription extends React.Component {
      */
     createInkGroup() {
         // TODO nda - if document being added to is a inkGrouping then we can just add to that group
-        if (Doc.ActiveTool === InkTool.Ink && Doc.ActiveInk === InkInkTool.Write) {
+        if (Doc.ActiveTool === InkTool.Ink && [InkInkTool.Write, InkInkTool.Math].includes(Doc.ActiveInk)) {
             CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => {
                 // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those
                 const selected = ffView.unprocessedDocs;
@@ -309,7 +315,7 @@ export class InkTranscription extends React.Component {
                 );
                 ffView.unprocessedDocs = [];
 
-                InkTranscription.Instance.transcribeInk(newCollection, selected, false);
+                InkTranscription.Instance.transcribeInk(ffView, newCollection, selected, Doc.ActiveInk === InkInkTool.Math);
             });
         }
         CollectionFreeFormView.collectionsWithUnprocessedInk.clear();
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 253db08de..4b651af7d 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -124,7 +124,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
             );
             ffView.unprocessedDocs = [];
 
-            InkTranscription.Instance.transcribeInk(newCollection, selected, false);
+            InkTranscription.Instance.transcribeInk(ffView, newCollection, selected, false);
         }
     };
 
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 0eb21b943..62b1180ec 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -244,6 +244,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
             </div>
         </div>
     );
+    setStickerRef = (r: StickerPalette | null) => (this._annoPaletteView = r);
     render() {
         let downx = 0;
         let downy = 0;
@@ -317,7 +318,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
                             </GestureOverlay>
                         </div>
 
-                        {this._showPalette && <StickerPalette ref={r => (this._annoPaletteView = r)} Doc={DocCast(Doc.UserDoc().myLightboxDrawings)} />}
+                        {this._showPalette && DocCast(Doc.UserDoc().myLightboxDrawings) && <StickerPalette ref={this.setStickerRef} Doc={DocCast(Doc.UserDoc().myLightboxDrawings)!} />}
                         {this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length ? true : false, this.previous)}
                         {this.renderNavBtn(
                             this._props.PanelWidth - Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]),
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 13b14617c..867a5a304 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -921,19 +921,19 @@ export class MainView extends ObservableReactComponent<object> {
         );
     }
 
+    setMainDashRef = (r: HTMLDivElement | null) =>
+        r &&
+        new ResizeObserver(
+            action(() => {
+                this._dashUIWidth = r.getBoundingClientRect().width;
+                this._dashUIHeight = r.getBoundingClientRect().height;
+            })
+        ).observe(r);
     @computed get mainDashboardArea() {
         return !this.userDoc ? null : (
             <div
                 className="mainView-dashboardArea"
-                ref={r => {
-                    r &&
-                        new ResizeObserver(
-                            action(() => {
-                                this._dashUIWidth = r.getBoundingClientRect().width;
-                                this._dashUIHeight = r.getBoundingClientRect().height;
-                            })
-                        ).observe(r);
-                }}
+                ref={this.setMainDashRef}
                 style={{
                     color: 'black',
                     height: `calc(100% - ${this.topOfDashUI + this.topMenuHeight()}px)`,
@@ -1072,6 +1072,14 @@ export class MainView extends ObservableReactComponent<object> {
     };
 
     lightboxMaxBorder = [200, 50];
+    setMainViewRef = (r: HTMLDivElement | null) =>
+        r &&
+        new ResizeObserver(
+            action(() => {
+                this._windowWidth = r.getBoundingClientRect().width;
+                this._windowHeight = r.getBoundingClientRect().height;
+            })
+        ).observe(r);
     render() {
         return (
             <div
@@ -1085,15 +1093,7 @@ export class MainView extends ObservableReactComponent<object> {
                         ele.scrollTop = ele.scrollLeft = 0;
                     })(document.getElementById('root')!)
                 }
-                ref={r => {
-                    r &&
-                        new ResizeObserver(
-                            action(() => {
-                                this._windowWidth = r.getBoundingClientRect().width;
-                                this._windowHeight = r.getBoundingClientRect().height;
-                            })
-                        ).observe(r);
-                }}>
+                ref={this.setMainViewRef}>
                 {this.inkResources}
                 <DictationOverlay />
                 <SharingManager />
diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx
index 067020a62..3755b1ec1 100644
--- a/src/client/views/UndoStack.tsx
+++ b/src/client/views/UndoStack.tsx
@@ -9,6 +9,7 @@ import './UndoStack.scss';
 
 @observer
 export class UndoStack extends React.Component<object> {
+    setRef = (r: HTMLDivElement | null) => r?.scroll({ behavior: 'auto', top: (r?.scrollHeight ?? 0) + 20 });
     render() {
         const background = UndoManager.batchCounter.get() ? 'yellow' : SettingsManager.userVariantColor;
         const color = UndoManager.batchCounter.get() ? 'black' : SettingsManager.userColor;
@@ -25,7 +26,7 @@ export class UndoStack extends React.Component<object> {
                             popup={
                                 <div
                                     className="undoStack-commandsContainer"
-                                    ref={r => r?.scroll({ behavior: 'auto', top: (r?.scrollHeight ?? 0) + 20 })}
+                                    ref={this.setRef}
                                     style={{
                                         background,
                                         color,
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index 814e9a7a0..c2bd01334 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -533,6 +533,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps & { Doc: D
         this._totalLength = RegionHelpers.convertPixelTime(this._time, 'mili', 'pixel', this._tickSpacing, this._tickIncrement);
     };
 
+    setTrackRef = (r: Track) => this.mapOfTracks.push(r);
     /**
      * if you have any question here, just shoot me an email or text.
      * basically the only thing you need to edit besides render methods in track (individual track lines) and keyframe (green region)
@@ -554,7 +555,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps & { Doc: D
                                 {[...this.children, this._props.Doc].map(doc => (
                                     <Track
                                         key={doc[Id]}
-                                        ref={ref => this.mapOfTracks.push(ref)}
+                                        ref={this.setTrackRef}
                                         timeline={this}
                                         animatedDoc={doc}
                                         currentBarX={this._currentBarX}
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 7f639a11e..7a4408931 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -256,9 +256,10 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         const height = () => this.getDocHeight(doc);
         let dref: Opt<DocumentView>;
         const noteTakingDocTransform = () => this.getDocTransform(doc, dref);
+        const setRef = (r: DocumentView | null) => (dref = r || undefined);
         return (
             <DocumentView
-                ref={r => (dref = r || undefined)}
+                ref={setRef}
                 Document={doc}
                 TemplateDataDocument={doc.isTemplateDoc || doc.isTemplateForField ? this._props.TemplateDataDocument : undefined}
                 pointerEvents={this.blockPointerEventsWhenDragging}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index bdeb7d944..fbdd23315 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import * as CSS from 'csstype';
-import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { ClientUtils, DivHeight, returnNone, returnZero, setupMoveUpEvents, smoothScroll } from '../../../ClientUtils';
@@ -391,10 +391,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     });
 
     // This following three functions must be from the view Mehek showed
-    columnDividerDown = (e: React.PointerEvent) => {
-        runInAction(() => {
-            this._cursor = 'grabbing';
-        });
+    columnDividerDown = action((e: React.PointerEvent) => {
+        this._cursor = 'grabbing';
         const batch = UndoManager.StartBatch('stacking width');
         setupMoveUpEvents(
             this,
@@ -406,7 +404,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             }),
             emptyFunction
         );
-    };
+    });
     @action
     onDividerMove = (e: PointerEvent) => {
         this.Document._layout_columnWidth = Math.max(10, (this._props.DocumentView?.().screenToViewTransform().transformPoint(e.clientX, 0)[0] ?? 0) - this.xMargin);
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 8c535534a..b5efa7a72 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -304,6 +304,12 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
         ContextMenu.Instance.displayMenu(pt[0], pt[1], undefined, true);
     };
 
+    setRef = (r: HTMLDivElement | null) => {
+        if (this._headerRef && this._props.colHeaderRefs.includes(this._headerRef)) this._props.colHeaderRefs.splice(this._props.colStackRefs.indexOf(this._headerRef), 1);
+        r && this._props.colHeaderRefs.push(r);
+        this._headerRef = r;
+    };
+
     @computed get innards() {
         TraceMobx();
         const key = this._props.pivotField;
@@ -315,11 +321,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
             <div
                 key={heading}
                 className="collectionStackingView-sectionHeader"
-                ref={r => {
-                    if (this._headerRef && this._props.colHeaderRefs.includes(this._headerRef)) this._props.colHeaderRefs.splice(this._props.colStackRefs.indexOf(this._headerRef), 1);
-                    r && this._props.colHeaderRefs.push(r);
-                    this._headerRef = r;
-                }}
+                ref={this.setRef}
                 style={{
                     marginTop: 0,
                     marginBottom: this._props.gridGap,
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index bee5d016d..4625965b4 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -407,6 +407,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
     remAnnotationDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, `${this._props.fieldKey}_annotations`) || false;
     moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => this.moveDocument(doc, targetCollection, addDocument) || false;
 
+    setRef = (r: HTMLDivElement | null) => !this.Document.treeView_HasOverlay && r && this.createTreeDropTarget(r);
     @observable _headerHeight = 0;
     @computed get content() {
         const background = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string;
@@ -428,7 +429,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
                 <div
                     className="collectionTreeView-contents"
                     key="tree"
-                    ref={r => !this.Document.treeView_HasOverlay && r && this.createTreeDropTarget(r)}
+                    ref={this.setRef}
                     style={{
                         ...(!titleBar ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}),
                         color: color(),
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 5b2f1ff81..f84c7d3c0 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1294,6 +1294,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
                     return null;
                 }
 
+                const setRef = (r: TreeView | null) => treeViewRefs.set(child, r || undefined);
                 const dentDoc = (editTitle: boolean, newParent: Doc, addAfter: Doc | undefined, parent: TreeView | CollectionTreeView | undefined) => {
                     if (parent instanceof TreeView && parent._props.treeView.fileSysMode && !newParent.isFolder) return;
                     const fieldKey = Doc.LayoutDataKey(newParent);
@@ -1317,7 +1318,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
                 return (
                     <TreeView
                         key={child[Id]}
-                        ref={r => treeViewRefs.set(child, r || undefined)}
+                        ref={setRef}
                         Document={pair.layout}
                         dataDoc={pair.data}
                         treeViewParent={treeViewParent}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 32ace463d..6e9e503f4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -562,7 +562,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 const B = this.screenToFreeformContentsXf.transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
                 const inkDoc = this.createInkDoc(points, B);
                 if (Doc.ActiveInk === InkInkTool.Highlight) inkDoc.$backgroundColor = 'transparent';
-                if (Doc.ActiveInk === InkInkTool.Write) {
+                if ([InkInkTool.Write, InkInkTool.Math].includes(Doc.ActiveInk)) {
                     this.unprocessedDocs.push(inkDoc);
                     CollectionFreeFormView.collectionsWithUnprocessedInk.add(this);
                 }
@@ -2220,18 +2220,41 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         );
     };
 
+    @computed get inkEraser() {
+        return (
+            Doc.ActiveTool === InkTool.Eraser &&
+            Doc.ActiveEraser === InkEraserTool.Radius &&
+            this._showEraserCircle && (
+                <div
+                    onPointerMove={this.onCursorMove}
+                    style={{
+                        position: 'fixed',
+                        left: this._eraserX,
+                        top: this._eraserY,
+                        width: (ActiveEraserWidth() + 5) * 2,
+                        height: (ActiveEraserWidth() + 5) * 2,
+                        borderRadius: '50%',
+                        border: '1px solid gray',
+                        transform: 'translate(-50%, -50%)',
+                    }}
+                />
+            )
+        );
+    }
+
+    setRef = (r: HTMLDivElement | null) => {
+        this.createDashEventsTarget(r);
+        this.fixWheelEvents(r, this._props.isContentActive, this.onPassiveWheel);
+        r?.addEventListener('mouseleave', this.onMouseLeave);
+        r?.addEventListener('mouseenter', this.onMouseEnter);
+    };
     render() {
         TraceMobx();
         return (
             <div
                 className="collectionfreeformview-container"
                 id={this._paintedId}
-                ref={r => {
-                    this.createDashEventsTarget(r);
-                    this.fixWheelEvents(r, this._props.isContentActive, this.onPassiveWheel);
-                    r?.addEventListener('mouseleave', this.onMouseLeave);
-                    r?.addEventListener('mouseenter', this.onMouseEnter);
-                }}
+                ref={this.setRef}
                 onWheel={this.onPointerWheel}
                 onClick={this.onClick}
                 onPointerDown={this.onPointerDown}
@@ -2246,21 +2269,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     width: `${100 / this.nativeDimScaling}%`,
                     height: this._props.getScrollHeight?.() ?? `${100 / this.nativeDimScaling}%`,
                 }}>
-                {Doc.ActiveTool === InkTool.Eraser && Doc.ActiveEraser === InkEraserTool.Radius && this._showEraserCircle && (
-                    <div
-                        onPointerMove={this.onCursorMove}
-                        style={{
-                            position: 'fixed',
-                            left: this._eraserX,
-                            top: this._eraserY,
-                            width: (ActiveEraserWidth() + 5) * 2,
-                            height: (ActiveEraserWidth() + 5) * 2,
-                            borderRadius: '50%',
-                            border: '1px solid gray',
-                            transform: 'translate(-50%, -50%)',
-                        }}
-                    />
-                )}
+                {this.inkEraser}
                 {this.paintFunc ? (
                     <FormattedTextBox {...this.props} /> // need this so that any live dashfieldviews will update the underlying text that the code eval reads
                 ) : this._lightboxDoc ? (
diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
index 142085e14..c31558dff 100644
--- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
+++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
@@ -150,6 +150,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
         FaceRecognitionHandler.UniqueFaceRemoveFaceImage(imgDoc, this.Document);
     }, 'remove doc from face');
 
+    setRef = (r: HTMLDivElement | null) => this.fixWheelEvents(r, this._props.isContentActive);
     render() {
         return (
             <div className="face-document-item" ref={ele => this.createDropTarget(ele!)}>
@@ -176,7 +177,7 @@ export class UniqueFaceBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         style={{
                             pointerEvents: this._props.isContentActive() ? undefined : 'none',
                         }}
-                        ref={r => this.fixWheelEvents(r, this._props.isContentActive)}>
+                        ref={this.setRef}>
                         {FaceRecognitionHandler.UniqueFaceImages(this.Document).map((doc, i) => {
                             const [name, type] = ImageCastToNameType(doc?.[Doc.LayoutDataKey(doc)]) ?? ['-missing-', '.png'];
                             return (
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index ff78b332a..4191aaca8 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -762,29 +762,26 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
         }
         e.stopPropagation();
     };
+    setRef = (r: HTMLDivElement | null) => {
+        r?.addEventListener('dashDragMovePause', this.onDragMovePause as EventListenerOrEventListenerObject);
+        this.MarqueeRef = r;
+    };
     render() {
         return (
-            <>
-                <div
-                    className="marqueeView"
-                    ref={r => {
-                        r?.addEventListener('dashDragMovePause', this.onDragMovePause as EventListenerOrEventListenerObject);
-                        this.MarqueeRef = r;
-                    }}
-                    style={{
-                        overflow: StrCast(this._props.Document._overflow),
-                        cursor: Doc.ActiveTool === InkTool.Ink || this._visible ? 'crosshair' : 'pointer',
-                    }}
-                    onDragOver={e => e.preventDefault()}
-                    onScroll={e => {
-                        e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0;
-                    }}
-                    onClick={this.onClick}
-                    onPointerDown={this.onPointerDown}>
-                    {this._visible ? this.marqueeDiv : null}
-                    {this.props.children}
-                </div>
-            </>
+            <div
+                className="marqueeView"
+                ref={this.setRef}
+                style={{
+                    overflow: StrCast(this._props.Document._overflow),
+                    cursor: Doc.ActiveTool === InkTool.Ink || this._visible ? 'crosshair' : 'pointer',
+                }}
+                onDragOver={e => e.preventDefault()}
+                onScroll={e => (e.currentTarget.scrollTop = (e.currentTarget.scrollLeft = 0))} // prettier-ignore
+                onClick={this.onClick}
+                onPointerDown={this.onPointerDown}>
+                {this._visible ? this.marqueeDiv : null}
+                {this.props.children}
+            </div>
         );
     }
 }
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index d0a1e6f0d..435f618d9 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -158,14 +158,13 @@ export class CollectionLinearView extends CollectionSubView() {
 
         let dref: Opt<HTMLDivElement>;
         const docXf = () => this.getTransform(dref);
+        const setRef = (r: HTMLDivElement | null) => (dref = r || undefined);
         // const scalable = pair.layout.onClick || pair.layout.onDragStart;
         return hidden ? null : (
             <div
                 className={preview ? 'preview' : `collectionLinearView-docBtn`}
                 key={doc[Id]}
-                ref={r => {
-                    dref = r || undefined;
-                }}
+                ref={setRef}
                 style={{
                     pointerEvents: 'all',
                     width: NumCast(doc._width),
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 6442385c0..2576bdf9b 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -1043,17 +1043,16 @@ export class CollectionSchemaView extends CollectionSubView() {
         if (!this._oldKeysWheel?.scrollTop && e.deltaY <= 0) e.preventDefault();
         e.stopPropagation();
     };
+    setRef = (r: HTMLDivElement | null) => {
+        this._oldKeysWheel?.removeEventListener('wheel', this.onKeysPassiveWheel);
+        this._oldKeysWheel = r;
+        r?.addEventListener('wheel', this.onKeysPassiveWheel, { passive: false });
+    };
     _oldKeysWheel: HTMLDivElement | null = null;
     @computed get keysDropdown() {
         return (
             <div className="schema-key-search">
-                <div
-                    className="schema-key-list"
-                    ref={r => {
-                        this._oldKeysWheel?.removeEventListener('wheel', this.onKeysPassiveWheel);
-                        this._oldKeysWheel = r;
-                        r?.addEventListener('wheel', this.onKeysPassiveWheel, { passive: false });
-                    }}>
+                <div className="schema-key-list" ref={this.setRef}>
                     {this._menuKeys.map(key => (
                         <div
                             key={key}
@@ -1294,6 +1293,9 @@ export class CollectionSchemaView extends CollectionSubView() {
     screenToLocal = () => this.ScreenToLocalBoxXf().translate(-this.tableWidth, 0);
     previewWidthFunc = () => this.previewWidth;
     displayedDocsFunc = () => this.docsWithDrag.docs;
+    setColHdrRef = (r: SchemaColumnHeader | null) => r && this._headerRefs.push(r);
+    setPreviewRef = (r: HTMLDivElement | null) => (this._previewRef = r);
+
     render() {
         return (
             <div
@@ -1331,7 +1333,7 @@ export class CollectionSchemaView extends CollectionSubView() {
                         {this.columnKeys.map((key, index) => (
                             <SchemaColumnHeader
                                 //cleanupField={this.cleanupComputedField}
-                                ref={r => r && this._headerRefs.push(r)}
+                                ref={this.setColHdrRef}
                                 keysDropdown={this.keysDropdown}
                                 schemaView={this}
                                 columnWidth={() => CollectionSchemaView._minColWidth} //TODO: update
@@ -1379,11 +1381,7 @@ export class CollectionSchemaView extends CollectionSubView() {
                 </div>
                 {this.previewWidth > 0 && <div className="schema-preview-divider" style={{ width: CollectionSchemaView._previewDividerWidth }} onPointerDown={this.onDividerDown} />}
                 {this.previewWidth > 0 && (
-                    <div
-                        style={{ width: `${this.previewWidth}px` }}
-                        ref={ref => {
-                            this._previewRef = ref;
-                        }}>
+                    <div style={{ width: `${this.previewWidth}px` }} ref={this.setPreviewRef}>
                         {Array.from(this._selectedDocs).lastElement() && (
                             <DocumentView
                                 Document={Array.from(this._selectedDocs).lastElement()}
diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx
index 9ad94cb31..412daa105 100644
--- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx
@@ -341,12 +341,14 @@ export class SchemaCellField extends ObservableReactComponent<SchemaCellFieldPro
         return <span className="editableView-static">{this._props.fieldContents ? <FieldView {...this._props.fieldContents} /> : ''}</span>;
     };
 
+    setRef = (r: HTMLDivElement | null) => (this._inputref = r);
+
     renderEditor = () => {
         return (
             <div
                 contentEditable
                 className="schemaField-editing"
-                ref={r => (this._inputref = r)}
+                ref={this.setRef}
                 style={{ minHeight: `min(100%, ${(this._props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20 }}
                 onBlur={() => (this._props.refSelectModeInfo.enabled ? setTimeout(() => this.setIsFocused(true), 1000) : this.finalizeEdit(false, true, false))}
                 onInput={this.onChange}
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 134f2ed31..64bfab856 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -118,6 +118,10 @@ export class SchemaColumnHeader extends ObservableReactComponent<SchemaColumnHea
         return { color, fieldProps, cursor };
     };
 
+    setRef = (r: EditableView | null) => {
+        this._inputRef = r;
+        this._props.autoFocus && r?.setIsFocused(true);
+    };
     @computed get editableView() {
         const { color, fieldProps } = this.renderProps(this._props);
 
@@ -133,10 +137,7 @@ export class SchemaColumnHeader extends ObservableReactComponent<SchemaColumnHea
                     width: '100%',
                 }}>
                 <EditableView
-                    ref={r => {
-                        this._inputRef = r;
-                        this._props.autoFocus && r?.setIsFocused(true);
-                    }}
+                    ref={this.setRef}
                     oneLine={true}
                     allowCRs={false}
                     contents={''}
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 8b34b4139..02e0d8100 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -185,6 +185,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
         return eqSymbol + modField;
     };
 
+    setRef = (r: SchemaCellField | null) => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true);
     @computed get defaultCellContent() {
         const { color, textDecoration, fieldProps, pointerEvents } = SchemaTableCell.renderProps(this._props);
 
@@ -204,7 +205,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
                     Doc={this._props.Doc}
                     highlightCells={(text: string) => this._props.highlightCells(this.adjustSelfReference(text))}
                     getCells={(text: string) => this._props.eqHighlightFunc(this.adjustSelfReference(text))}
-                    ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)}
+                    ref={this.setRef}
                     oneLine={this._props.oneLine}
                     contents={undefined}
                     fieldContents={fieldProps}
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index cb3adae10..e098d50d8 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -408,7 +408,7 @@ function setActiveTool(tool: InkTool | InkEraserTool | InkInkTool | Gestures, ke
     }
     runInAction(() => {
         const eraserTool = tool === InkTool.Eraser ? Doc.ActiveEraser : [InkEraserTool.Stroke, InkEraserTool.Radius, InkEraserTool.Segment].includes(tool as InkEraserTool) ? (tool as InkEraserTool) : undefined;
-        const inkTool = tool === InkTool.Ink ? Doc.ActiveInk : [InkInkTool.Pen, InkInkTool.Write, InkInkTool.Highlight].includes(tool as InkInkTool) ? (tool as InkInkTool) : undefined;
+        const inkTool = tool === InkTool.Ink ? Doc.ActiveInk : [InkInkTool.Pen, InkInkTool.Write, InkInkTool.Math, InkInkTool.Highlight].includes(tool as InkInkTool) ? (tool as InkInkTool) : undefined;
         if (GestureOverlay.Instance) {
             SnappingManager.SetKeepGestureMode(keepPrim);
         }
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 9369ff98a..0b7033e57 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -420,6 +420,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         }
     };
 
+    setRef = (r: LineChart | Histogram | PieChart | null) => (this._vizRenderer = r ?? undefined);
     // toggles for user to decide which chart type to view the data in
     @computed get renderVizView() {
         const scale = this._props.NativeDimScaling?.() || 1;
@@ -437,9 +438,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         if (!this.records.length) return 'no data/visualization';
         switch (this.dataVizView) {
             case DataVizView.TABLE:     return <TableBox  {...sharedProps} Doc={this.Document} specHighlightedRow={this._specialHighlightedRow} docView={this.DocumentView} selectAxes={this.selectAxes} selectTitleCol={this.selectTitleCol}/>;
-            case DataVizView.LINECHART: return <LineChart {...sharedProps} Doc={this.Document} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => {this._vizRenderer = r ?? undefined;}} vizBox={this} />;
-            case DataVizView.HISTOGRAM: return <Histogram {...sharedProps} Doc={this.Document} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => {this._vizRenderer = r ?? undefined;}} />;
-            case DataVizView.PIECHART:  return <PieChart  {...sharedProps} Doc={this.Document} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => {this._vizRenderer = r ?? undefined;}} 
+            case DataVizView.LINECHART: return <LineChart {...sharedProps} Doc={this.Document} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={this.setRef} vizBox={this} />;
+            case DataVizView.HISTOGRAM: return <Histogram {...sharedProps} Doc={this.Document} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={this.setRef} />;
+            case DataVizView.PIECHART:  return <PieChart  {...sharedProps} Doc={this.Document} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={this.setRef} 
             margin={{ top: 10, right: 15, bottom: 15, left: 15 }} />;
             default:
         } // prettier-ignore
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
index fb083ea75..8f6ecab57 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu/DocCreatorMenu.tsx
@@ -540,6 +540,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
         ]; //prettier-ignore
     }
 
+    setRef = (r: HTMLDivElement) => (this._ref = r);
     render() {
         const topButton = (icon: string, opt: string, func: () => void, tag: string) => (
             <div className={`top-button-container ${tag} ${opt === this._menuContent ? 'selected' : ''}`}>
@@ -558,7 +559,7 @@ export class DocCreatorMenu extends ObservableReactComponent<DocCreateMenuProps>
                 {!this._shouldDisplay ? undefined : (
                     <div
                         className="docCreatorMenu-cont"
-                        ref={r => (this._ref = r)}
+                        ref={this.setRef}
                         style={{
                             display: '',
                             left: this._pageX,
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index a7c4a00b0..f51683991 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -413,6 +413,10 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
         });
     };
 
+    setChartRef = (r: HTMLDivElement | null) => {
+        this._histogramRef = r;
+        r && this.drawChart(this._histogramData, this.width, this.height);
+    };
     render() {
         if (!this.selectedBins) this.layoutDoc.dataViz_histogram_selectedBins = new List<string>();
 
@@ -446,12 +450,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
                             size={Size.XSMALL}
                         />
                     </div>
-                    <div
-                        ref={r => {
-                            this._histogramRef = r;
-                            r && this.drawChart(this._histogramData, this.width, this.height);
-                        }}
-                    />
+                    <div ref={this.setChartRef} />
                     {selected !== 'none' ? (
                         <div className="selected-data">
                             Selected: {selected}
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
index 80fadf178..732681e05 100644
--- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
@@ -347,6 +347,10 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
             .style('pointer-events', 'none')
             .style('transform', `translate(${xScale(d0.x) - this.width}px,${yScale(d0.y)}px)`);
     }
+    setLineRef = (r: HTMLDivElement | null) => {
+        this._lineChartRef = r;
+        this.drawChart([this._lineChartData], this.rangeVals, this.width, this.height);
+    };
 
     render() {
         const selectedPt = this._currSelected ? `{ ${this._props.axes[0]}: ${this._currSelected.x} ${this._props.axes[1]}: ${this._currSelected.y} }` : 'none';
@@ -378,12 +382,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
                             fillWidth
                         />
                     </div>
-                    <div
-                        ref={r => {
-                            this._lineChartRef = r;
-                            this.drawChart([this._lineChartData], this.rangeVals, this.width, this.height);
-                        }}
-                    />
+                    <div ref={this.setLineRef} />
                     {selectedPt !== 'none' ? (
                         <div className="selected-data">
                             {`Selected: ${selectedPt}`}
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index 0ae70786f..cf476b8d0 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -373,10 +373,10 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
         const sliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '') : sliceTitle;
 
         const sliceColors = Cast(this._props.layoutDoc.dataViz_pie_sliceColors, listSpec('string'), null);
-        sliceColors.forEach(each => {
+        sliceColors?.forEach(each => {
             if (each.split('::')[0] === sliceName) sliceColors.splice(sliceColors.indexOf(each), 1);
         });
-        sliceColors.push(StrCast(sliceName + '::' + color));
+        sliceColors?.push(StrCast(sliceName + '::' + color));
     };
 
     @action changeHistogramCheckBox = () => {
@@ -384,6 +384,10 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
         this.drawChart(this._pieChartData, this.width, this.height);
     };
 
+    setChartRef = (r: HTMLDivElement | null) => {
+        this._piechartRef = r;
+        this.drawChart(this._pieChartData, this.width, this.height);
+    };
     render() {
         let titleAccessor = 'dataViz_pie_title';
         if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
@@ -443,12 +447,7 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
                             Organize data as histogram
                         </div>
                     ) : null}
-                    <div
-                        ref={r => {
-                            this._piechartRef = r;
-                            this.drawChart(this._pieChartData, this.width, this.height);
-                        }}
-                    />
+                    <div ref={this.setChartRef} />
                     {selected !== 'none' ? (
                         <div className="selected-data">
                             Selected: {selected}
diff --git a/src/client/views/nodes/DiagramBox.tsx b/src/client/views/nodes/DiagramBox.tsx
index 7cfccf0dc..6a31f64ce 100644
--- a/src/client/views/nodes/DiagramBox.tsx
+++ b/src/client/views/nodes/DiagramBox.tsx
@@ -185,6 +185,8 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         return '( )';
     };
 
+    setRef = (r: HTMLDivElement | null) => this.fixWheelEvents(r, this._props.isContentActive);
+    setDiagramBoxRef = (r: HTMLDivElement | null) => r && this.renderMermaidAsync.call(this, this.removeWords(this.mermaidcode), r);
     render() {
         return (
             <div
@@ -192,7 +194,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 style={{
                     pointerEvents: this._props.isContentActive() ? undefined : 'none',
                 }}
-                ref={r => this.fixWheelEvents(r, this._props.isContentActive)}>
+                ref={this.setRef}>
                 <div className="DIYNodeBox-searchbar">
                     <input type="text" value={this._inputValue} onKeyDown={action(e => e.key === 'Enter' && this.generateMermaidCode())} onChange={action(e => (this._inputValue = e.target.value))} />
                     <button type="button" onClick={this.generateMermaidCode}>
@@ -208,7 +210,7 @@ export class DiagramBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     ) : this._generating ? (
                         <div className="loading-circle" />
                     ) : (
-                        <div className="diagramBox" ref={r => r && this.renderMermaidAsync.call(this, this.removeWords(this.mermaidcode), r)}>
+                        <div className="diagramBox" ref={this.setDiagramBoxRef}>
                             {this._errorMessage || 'Type a prompt to generate a diagram'}
                         </div>
                     )}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 504c1491e..32741a0fe 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -261,9 +261,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
                 jsx={layoutFrame}
                 showWarnings
                 // eslint-disable-next-line @typescript-eslint/no-explicit-any
-                onError={(test: any) => {
-                    console.log('DocumentContentsView:' + test, bindings, layoutFrame);
-                }}
+                onError={(test: any) => console.log('DocumentContentsView:' + test, bindings, layoutFrame)}
             />
         );
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index fe95f15af..bd71115db 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -701,16 +701,18 @@ export class DocumentViewInternal extends DocComponent<DocumentViewProps & Field
 
     aiContentsWidth = () => (this.aiContentsHeight() * (this._props.NativeWidth?.() || 1)) / (this._props.NativeHeight?.() || 1);
     aiContentsHeight = () => Math.max(10, this._props.PanelHeight() - (this._aiWinHeight + (this.tagsOverlayFunc() ? 22 : 0)) * this.uiBtnScaling);
+    setAiRef = action((r: HTMLDivElement | null) => this.historyRef(this._oldHistoryWheel, (this._oldHistoryWheel = r)));
+
     @computed get aiEditor() {
         return (
             <div
                 className="documentView-editorView"
+                ref={this.setAiRef}
                 style={{
                     background: SnappingManager.userVariantColor,
                     width: `${100 / this.uiBtnScaling}%`, //
                     transform: `scale(${this.uiBtnScaling})`,
-                }}
-                ref={r => this.historyRef(this._oldHistoryWheel, (this._oldHistoryWheel = r))}>
+                }}>
                 <div className="documentView-editorView-resizer" />
                 {this._componentView?.componentAIView?.() ?? null}
                 {this._props.DocumentView?.() ? <TagsView background={this.backgroundBoxColor} Views={[this._props.DocumentView?.()]} /> : null}
@@ -1507,18 +1509,16 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
             .translate(-(this._docViewInternal?.aiShift() ?? 0), 0)
             .scale((this._docViewInternal?.aiScale() ?? 1) / this.nativeScaling);
 
+    setHtmlOverlayRef = (r: HTMLDivElement | null) => {
+        const val = r?.style.display !== 'none'; // if the outer overlay has been displayed, trigger the innner div to start it's opacity fade in transition
+        if (r && val !== this._enableHtmlOverlayTransitions) {
+            setTimeout(action(() => (this._enableHtmlOverlayTransitions = val)));
+        }
+    };
     htmlOverlay = () => {
         const effect = StrCast(this._htmlOverlayEffect?.presentation_effect, StrCast(this._htmlOverlayEffect?.followLinkAnimEffect));
         return (
-            <div
-                className="documentView-htmlOverlay"
-                ref={r => {
-                    const val = r?.style.display !== 'none'; // if the outer overlay has been displayed, trigger the innner div to start it's opacity fade in transition
-                    if (r && val !== this._enableHtmlOverlayTransitions) {
-                        setTimeout(action(() => (this._enableHtmlOverlayTransitions = val)));
-                    }
-                }}
-                style={{ display: !this._htmlOverlayText ? 'none' : undefined }}>
+            <div className="documentView-htmlOverlay" ref={this.setHtmlOverlayRef} style={{ display: !this._htmlOverlayText ? 'none' : undefined }}>
                 <div className="documentView-htmlOverlayInner" style={{ transition: `all 500ms`, opacity: this._enableHtmlOverlayTransitions ? 0.9 : 0 }}>
                     {DocumentViewInternal.AnimationEffect(
                         <div className="webBox-textHighlight">
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index e0ab04692..2ce24b688 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -116,12 +116,13 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
             this.layoutDoc._nativeHeight = mathHeight;
         }
     };
+    setRef = (r: HTMLDivElement) => r && this._ref.current?.element.current && this.updateSize(this._ref.current?.element.current);
     render() {
         TraceMobx();
         const scale = this._props.NativeDimScaling?.() || 1;
         return (
             <div
-                ref={r => r && this._ref.current?.element.current && this.updateSize(this._ref.current?.element.current)}
+                ref={this.setRef}
                 className="equationBox-cont"
                 onKeyDown={e => e.stopPropagation()}
                 onPointerDown={e => !e.ctrlKey && e.stopPropagation()}
diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx
index 8e4b64851..e4d37e006 100644
--- a/src/client/views/nodes/FunctionPlotBox.tsx
+++ b/src/client/views/nodes/FunctionPlotBox.tsx
@@ -121,11 +121,12 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
         }
         // if (this.layout_autoHeight) this.tryUpdateScrollHeight();
     };
+    setRef = (r: HTMLDivElement | null) => r && this.createGraph(r);
     @computed get theGraph() {
         return (
             <div
                 id={`${this._plotId}`}
-                ref={r => r && this.createGraph(r)}
+                ref={this.setRef}
                 style={{ position: 'absolute', width: '100%', height: '100%' }}
                 onPointerDown={e => {
                     e.stopPropagation();
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index e1ecc2018..c5948cbbd 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -169,6 +169,25 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
         }
     };
 
+    setRef = (r: HTMLDivElement | null) => {
+        this._divRef?.removeEventListener('beforeinput', this.beforeInput);
+        this._divRef = r;
+        if (this._divRef) {
+            this._divRef.addEventListener('beforeinput', this.beforeInput);
+
+            if (DocumentView.SelectOnLoad === this.Document) {
+                DocumentView.SetSelectOnLoad(undefined);
+                this._liveTextUndo = FormattedTextBox.LiveTextUndo;
+                FormattedTextBox.LiveTextUndo = undefined;
+                this._divRef.focus();
+            }
+            this.fitTextToBox(this._divRef);
+            if (this.Title) {
+                this.resetCursor();
+            }
+        } else this._timeout && clearTimeout(this._timeout);
+    };
+
     render() {
         TraceMobx();
         const boxParams = this.fitTextToBox(undefined); // this causes mobx to trigger re-render when data changes
@@ -228,24 +247,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             __html: `<span class="textFitted textFitAlignVert" style="display: inline-block; text-align: center; font-size: 100px; height: 0px;">${this.Title?.startsWith('#') ? '' : (this.Title ?? '')}</span>`,
                         }}
                         contentEditable={this._props.onClickScript?.() ? undefined : true}
-                        ref={r => {
-                            this._divRef?.removeEventListener('beforeinput', this.beforeInput);
-                            this._divRef = r;
-                            if (this._divRef) {
-                                this._divRef.addEventListener('beforeinput', this.beforeInput);
-
-                                if (DocumentView.SelectOnLoad === this.Document) {
-                                    DocumentView.SetSelectOnLoad(undefined);
-                                    this._liveTextUndo = FormattedTextBox.LiveTextUndo;
-                                    FormattedTextBox.LiveTextUndo = undefined;
-                                    this._divRef.focus();
-                                }
-                                this.fitTextToBox(this._divRef);
-                                if (this.Title) {
-                                    this.resetCursor();
-                                }
-                            } else this._timeout && clearTimeout(this._timeout);
-                        }}
+                        ref={this.setRef}
                     />
                 </div>
             </div>
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 78c8a686c..d31fadf77 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -99,6 +99,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
         }
     };
 
+    setRef = (r: HTMLDivElement | null) => (this._divRef = r);
     render() {
         TraceMobx();
 
@@ -149,28 +150,18 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
             const aid = targetAhyperlinks?.find(alink => container?.contains(alink))?.id ?? targetAhyperlinks?.lastElement()?.id;
             const bid = targetBhyperlinks?.find(blink => container?.contains(blink))?.id ?? targetBhyperlinks?.lastElement()?.id;
             if (!aid || !bid) {
-                setTimeout(
-                    action(() => {
-                        this._forceAnimate += 0.01;
-                    })
-                );
+                setTimeout(action(() => (this._forceAnimate += 0.01)));
                 return null;
             }
             if (foundParent) {
                 setTimeout(
-                    action(() => {
-                        this._forceAnimate += 0.01;
-                    }),
+                    action(() => (this._forceAnimate += 0.01)),
                     1
                 );
             }
-
-            if (at || bt)
-                setTimeout(
-                    action(() => {
-                        this._forceAnimate += 0.01;
-                    })
-                ); // this forces an update during a transition animation
+            if (at || bt) {
+                setTimeout(action(() => (this._forceAnimate += 0.01))); // this forces an update during a transition animation
+            }
             const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting) as { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean };
             const highlightColor = highlight?.highlightIndex ? highlight?.highlightColor : undefined;
             const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
@@ -217,7 +208,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                 id={this.DocumentView?.().DocUniqueId}
                                 className="linkBox-label"
                                 tabIndex={-1}
-                                ref={r => (this._divRef = r)}
+                                ref={this.setRef}
                                 onPointerDown={e => e.stopPropagation()}
                                 onFocus={() => {
                                     RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, this.dataDoc);
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 5b07b303a..1d6f41c65 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -250,6 +250,10 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
         );
     }
 
+    setDocViewRef = (r: DocumentView | null) => {
+        const targetanchor = this._linkDoc && this._linkSrc && Doc.getOppositeAnchor(this._linkDoc, this._linkSrc);
+        targetanchor && this._targetDoc !== targetanchor && r?._props.focus?.(targetanchor, {});
+    };
     @computed get docPreview() {
         return (!this._linkDoc || !this._targetDoc || !this._linkSrc) && !this._toolTipText ? null : (
             <div className="linkDocPreview-inner">
@@ -279,10 +283,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
                         this._toolTipText
                     ) : (
                         <DocumentView
-                            ref={r => {
-                                const targetanchor = this._linkDoc && this._linkSrc && Doc.getOppositeAnchor(this._linkDoc, this._linkSrc);
-                                targetanchor && this._targetDoc !== targetanchor && r?._props.focus?.(targetanchor, {});
-                            }}
+                            ref={this.setDocViewRef}
                             Document={this._targetDoc!}
                             moveDocument={returnFalse}
                             styleProvider={this._props.styleProvider}
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 603dcad5c..4677e0e61 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -171,19 +171,21 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         ContextMenu.Instance.addItem({ description: 'Options...', subitems, icon: 'video' });
     };
 
+    setRef = (r: HTMLVideoElement | null) => {
+        this._videoRef = r;
+        setTimeout(() => {
+            if (this.layoutDoc.mediaState === mediaState.PendingRecording && this._videoRef) {
+                this.toggleRecording();
+            }
+        }, 100);
+    };
+
     @computed get content() {
         return (
             <video
                 className="videoBox-content"
                 key="video"
-                ref={r => {
-                    this._videoRef = r;
-                    setTimeout(() => {
-                        if (this.layoutDoc.mediaState === mediaState.PendingRecording && this._videoRef) {
-                            this.toggleRecording();
-                        }
-                    }, 100);
-                }}
+                ref={this.setRef}
                 autoPlay={this._screenCapture}
                 style={{ width: this._screenCapture ? '100%' : undefined, height: this._screenCapture ? '100%' : undefined }}
                 onCanPlay={this.videoLoad}
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index a4183a11a..a2fa83b5a 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -298,10 +298,9 @@ export class CalendarBox extends CollectionSubView() {
                         ev.preventDefault();
                     });
                 }}
-
                 // for dragging and dropping (mirror)
 
-                eventDragStart={(arg) => {
+                eventDragStart={arg => {
                     const mirror = arg.el.cloneNode(true) as HTMLElement;
                     const rect = arg.el.getBoundingClientRect();
 
@@ -312,25 +311,24 @@ export class CalendarBox extends CollectionSubView() {
                     mirror.classList.add('custom-drag-mirror');
                     mirror.style.width = `${rect.width}px`;
                     mirror.style.height = `${rect.height}px`;
-                  
+
                     document.body.appendChild(mirror);
-                  
+
                     const moveListener = (ev: MouseEvent) => {
-                      mirror.style.left = `${ev.clientX}px`;
-                      mirror.style.top = `${ev.clientY}px`;
+                        mirror.style.left = `${ev.clientX}px`;
+                        mirror.style.top = `${ev.clientY}px`;
                     };
-                  
+
                     window.addEventListener('mousemove', moveListener);
 
                     // hide the actual box
                     arg.el.style.visibility = 'hidden';
                     arg.el.style.opacity = '0';
-                  
+
                     (arg.el as any)._mirrorElement = mirror;
                     (arg.el as any)._moveListener = moveListener;
                 }}
-                
-                eventDragStop={(arg) => {
+                eventDragStop={arg => {
                     const el = arg.el as any;
                     const mirror = el._mirrorElement;
                     const moveListener = el._moveListener;
@@ -338,15 +336,18 @@ export class CalendarBox extends CollectionSubView() {
                     // show the actual box
                     el.style.visibility = 'visible';
                     el.style.opacity = '1';
-                    
+
                     if (mirror) document.body.removeChild(mirror);
                     if (moveListener) window.removeEventListener('mousemove', moveListener);
                 }}
-                  
             />
         );
     }
 
+    setRef = (r: HTMLDivElement | null) => {
+        this.createDashEventsTarget(r);
+        this.fixWheelEvents(r, this._props.isContentActive);
+    };
     render() {
         const scale = this._props.ScreenToLocalTransform().Scale;
         const scaledWidth = this._props.PanelWidth();
@@ -361,11 +362,8 @@ export class CalendarBox extends CollectionSubView() {
                     height: scaledHeight,
                     overflow: 'hidden',
                     position: 'relative',
-                  }}
-                ref={r => {
-                    this.createDashEventsTarget(r);
-                    this.fixWheelEvents(r, this._props.isContentActive);
                 }}
+                ref={this.setRef}
                 onPointerDown={e => {
                     setTimeout(
                         action(() => {
@@ -383,9 +381,8 @@ export class CalendarBox extends CollectionSubView() {
                         transformOrigin: 'top left',
                         width: scaledWidth / scale,
                         height: scaledHeight / scale,
-                    }}
-                >
-                {this.renderCalendar}
+                    }}>
+                    {this.renderCalendar}
                 </div>
             </div>
         );
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
index 6c3da8977..8043111b9 100644
--- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
+++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx
@@ -974,6 +974,8 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     };
 
     _dictation: DictationButton | null = null;
+    setInputRef = (r: HTMLInputElement) => (this._textInputRef = r);
+    setDictationRef = (r: DictationButton) => (this._dictation = r);
     /**
      * Renders the chat interface, including the message list, input field, and other UI elements.
      */
@@ -1002,9 +1004,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
                 <form onSubmit={this.askGPT} className="chat-input">
                     <input
-                        ref={r => {
-                            this._textInputRef = r;
-                        }}
+                        ref={this.setInputRef}
                         type="text"
                         name="messageInput"
                         autoComplete="off"
@@ -1023,13 +1023,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                             </svg>
                         )}
                     </button>
-                    <DictationButton
-                        ref={r => {
-                            this._dictation = r;
-                        }}
-                        setInput={this.setChatInput}
-                        inputRef={this._textInputRef}
-                    />
+                    <DictationButton ref={this.setDictationRef} setInput={this.setChatInput} inputRef={this._textInputRef} />
                 </form>
                 {/* Popup for citation */}
                 {this._citationPopup.visible && (
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 07cb795f1..255ee1afe 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -2129,6 +2129,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
         }
     };
 
+    setRef = (r: HTMLDivElement | null) => this.fixWheelEvents(r, this._props.isContentActive, this.onPassiveWheel);
+    setScrollRef = (r: HTMLDivElement | null) => (this._scrollRef = r);
     render() {
         TraceMobx();
         const scale = this.nativeScaling();
@@ -2143,7 +2145,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
         ) : styleFromLayout?.height === '0px' ? null : (
             <div
                 className="formattedTextBox"
-                ref={r => this.fixWheelEvents(r, this._props.isContentActive, this.onPassiveWheel)}
+                ref={this.setRef}
                 style={{
                     ...(this._props.dontScale
                         ? {}
@@ -2181,9 +2183,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
                     onDoubleClick={this.onDoubleClick}>
                     <div
                         className="formattedTextBox-outer"
-                        ref={r => {
-                            this._scrollRef = r;
-                        }}
+                        ref={this.setScrollRef}
                         style={{
                             width: this.noSidebar ? '100%' : `calc(100% - ${this.sidebarWidthPercent})`,
                             overflow: this.layoutDoc._createDocOnCR || this.layoutDoc._layout_hideScroll ? 'hidden' : this.layout_autoHeight ? 'visible' : undefined,
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index cb2a1f13f..04b312ca5 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1743,6 +1743,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         return <div />;
     }
 
+    setAiEffectsRef = (r: HTMLTextAreaElement | null) =>
+        setTimeout(() => {
+            if (r && !r.textContent) {
+                r.style.height = '';
+                r.style.height = r.scrollHeight + 'px';
+            }
+        });
+
+    setAnimDictationRef = (r: DictationButton | null) => (this._animationDictation = r);
     /**
      * This chatbox is for getting slide effect transition suggestions from gpt and visualizing them
      */
@@ -1755,14 +1764,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         <ReactTextareaAutosize
                             placeholder="Use AI to suggest effects. Leave blank for random results."
                             className="pres-chatbox"
-                            ref={r => {
-                                setTimeout(() => {
-                                    if (r && !r.textContent) {
-                                        r.style.height = '';
-                                        r.style.height = r.scrollHeight + 'px';
-                                    }
-                                });
-                            }}
+                            ref={this.setAiEffectsRef}
                             value={this._animationChat}
                             onChange={e => {
                                 e.currentTarget.style.height = '';
@@ -1784,12 +1786,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         color={SnappingManager.userVariantColor}
                         onClick={this.customizeAnimations}
                     />
-                    <DictationButton
-                        ref={r => {
-                            this._animationDictation = r;
-                        }}
-                        setInput={this.setAnimationChat}
-                    />
+                    <DictationButton ref={this.setAnimDictationRef} setInput={this.setAnimationChat} />
                 </div>
                 <div style={{ alignItems: 'center' }}>
                     Click a box to use the effect.
@@ -1821,6 +1818,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         );
     }
 
+    setPropertiesRef = (r: HTMLTextAreaElement | null) =>
+        setTimeout(() => {
+            if (r && !r.textContent) {
+                r.style.height = '';
+                r.style.height = r.scrollHeight + 'px';
+            }
+        });
+
+    setSlideDictationRef = (r: DictationButton | null) => (this._slideDictation = r);
+
     @computed get transitionDropdown() {
         const { activeItem } = this;
         // Retrieving spring timing properties
@@ -1855,14 +1862,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                 <ReactTextareaAutosize
                                     placeholder="Describe how to modify the slide properties."
                                     className="pres-chatbox"
-                                    ref={r => {
-                                        setTimeout(() => {
-                                            if (r && !r.textContent) {
-                                                r.style.height = '';
-                                                r.style.height = r.scrollHeight + 'px';
-                                            }
-                                        });
-                                    }}
+                                    ref={this.setPropertiesRef}
                                     value={this._chatInput}
                                     onChange={e => {
                                         e.currentTarget.style.height = '';
@@ -1874,12 +1874,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                         e.stopPropagation();
                                     }}
                                 />
-                                <DictationButton
-                                    ref={r => {
-                                        this._slideDictation = r;
-                                    }}
-                                    setInput={this.setChatInput}
-                                />
+                                <DictationButton ref={this.setSlideDictationRef} setInput={this.setChatInput} />
                             </div>
                             <Button
                                 style={{ alignSelf: 'flex-end' }}
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index 568e48edf..660284397 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -515,6 +515,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
         </div>
     );
 
+    setDictationRef = (r: DictationButton | null) => (this._askDictation = r);
     promptBox = (heading: string, value: string, onChange: (e: string) => string, placeholder: string) => (
         <>
             <div className="gptPopup-sortBox">
@@ -541,7 +542,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
                     background={SettingsManager.userVariantColor}
                     onClick={() => this.callGpt(this._mode)}
                 />
-                <DictationButton ref={r => (this._askDictation = r)} setInput={onChange} />
+                <DictationButton ref={this.setDictationRef} setInput={onChange} />
             </div>
         </>
     );
diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts
index d1dda106a..f2c09b6b7 100644
--- a/src/fields/InkField.ts
+++ b/src/fields/InkField.ts
@@ -18,6 +18,7 @@ export enum InkInkTool {
     Pen = 'Pen',
     Highlight = 'Highlight',
     Write = 'Write',
+    Math = 'Math',
 }
 
 export enum InkEraserTool {
-- 
cgit v1.2.3-70-g09d2

