diff --git a/src/dev/pages/scaffold/scaffold.ejs b/src/dev/pages/scaffold/scaffold.ejs
index 640711730..43b1cf41a 100644
--- a/src/dev/pages/scaffold/scaffold.ejs
+++ b/src/dev/pages/scaffold/scaffold.ejs
@@ -1,5 +1,5 @@
-
+
Left
Right
Header
diff --git a/src/lib/core/styles/tokens/scaffold/_tokens.scss b/src/lib/core/styles/tokens/scaffold/_tokens.scss
new file mode 100644
index 000000000..bbe961d43
--- /dev/null
+++ b/src/lib/core/styles/tokens/scaffold/_tokens.scss
@@ -0,0 +1,13 @@
+@use 'sass:map';
+@use '../../utils';
+
+$tokens: (
+ height: utils.module-val(scaffold, height, 100%),
+ width: utils.module-val(scaffold, width, 100%),
+ overflow: utils.module-val(scaffold, overflow, hidden),
+ body-position: utils.module-val(scaffold, body-position, relative),
+) !default;
+
+@function get($key) {
+ @return map.get($tokens, $key);
+}
diff --git a/src/lib/scaffold/_core.scss b/src/lib/scaffold/_core.scss
new file mode 100644
index 000000000..5e3d4865b
--- /dev/null
+++ b/src/lib/scaffold/_core.scss
@@ -0,0 +1,93 @@
+@use './token-utils' as *;
+
+@forward './token-utils';
+
+@mixin host {
+ display: block;
+
+ width: #{token(width)};
+ height: #{token(height)};
+}
+
+@mixin base {
+ position: relative;
+
+ display: grid;
+ grid-template-areas:
+ 'left header right'
+ 'left body right'
+ 'left footer right';
+ grid-template-rows: auto 1fr auto;
+ grid-template-columns: auto 1fr auto;
+
+ height: #{token(height)};
+ width: #{token(width)};
+
+ overflow: #{token(overflow)};
+}
+
+@mixin header {
+ grid-area: header;
+ min-width: 0;
+ min-height: 0;
+}
+
+@mixin body {
+ position: #{token(body-position)};
+
+ display: grid;
+ grid-area: body;
+ grid-template-areas:
+ 'body-left body-header body-right'
+ 'body-left body-inner body-right'
+ 'body-left body-footer body-right';
+ grid-template-rows: auto 1fr auto;
+ grid-template-columns: auto 1fr auto;
+
+ width: #{token(width)};
+ min-width: 0;
+ min-height: 0;
+ overflow: hidden;
+}
+
+@mixin footer {
+ grid-area: footer;
+}
+
+@mixin body-header {
+ grid-area: body-header;
+}
+
+@mixin body-inner {
+ overflow: auto;
+ grid-area: body-inner;
+}
+
+@mixin body-footer {
+ grid-area: body-footer;
+}
+
+@mixin scrollable {
+ overflow: auto;
+}
+
+@mixin body-left {
+ grid-area: body-left;
+}
+
+@mixin body-right {
+ grid-area: body-right;
+}
+
+@mixin left {
+ grid-area: left;
+}
+
+@mixin right {
+ grid-area: right;
+}
+
+@mixin slotted-base {
+ min-width: 0;
+ min-height: 0;
+}
diff --git a/src/lib/scaffold/_mixins.scss b/src/lib/scaffold/_mixins.scss
deleted file mode 100644
index 1fa7b4769..000000000
--- a/src/lib/scaffold/_mixins.scss
+++ /dev/null
@@ -1,189 +0,0 @@
-@use '../theme';
-
-@mixin core-styles() {
- .forge-scaffold {
- @include base;
-
- &__header {
- @include header;
- }
-
- &__body {
- @include body;
-
- // These next 3 selectors are needed for IE 11 support
- ::slotted([slot=left]) {
- @include body-aside;
- @include left;
- }
-
- ::slotted([slot=right]) {
- @include body-aside;
- @include right;
- }
-
- ::slotted([slot=body-left]) {
- @include body-aside;
- @include body-left-aside;
- }
-
- ::slotted([slot=body-right]) {
- @include body-aside;
- @include body-right-aside;
- }
-
- ::slotted([slot=body-header]) {
- @include body-header;
- }
-
- ::slotted([slot=body]) {
- @include body-main;
- }
-
- ::slotted([slot=body-footer]) {
- @include body-footer;
- }
- }
-
- // These are the proper selectors to use for native Shadow DOM, but don't work in
- // IE 11 (see above duplicate selectors for IE support)
- ::slotted([slot=left]),
- ::slotted([slot=right]),
- ::slotted([slot=body-left]),
- ::slotted([slot=body-right]) {
- @include body-aside;
- }
-
- ::slotted([slot=body-left]) {
- @include body-left-aside;
- }
-
- ::slotted([slot=body-right]) {
- @include body-right-aside;
- }
-
- ::slotted([slot=footer]) {
- @include footer;
- }
-
- ::slotted([slot=left]) {
- @include left;
- }
-
- ::slotted([slot=right]) {
- @include right;
- }
- }
-}
-
-@mixin viewport-styles() {
- @include theme.css-custom-property(width, --forge-scaffold-width, 100vw);
- @include theme.css-custom-property(height, --forge-scaffold-height, 100vh);
-
- --forge-scaffold-height: 100vh;
- --forge-scaffold-width: 100vw;
-
- .forge-scaffold {
- @include theme.css-custom-property(height, --forge-scaffold-height, 100vh);
-
- --forge-scaffold-height: 100vh;
-
- &__body {
- @include theme.css-custom-property(width, --forge-scaffold-width, 100vw);
-
- --forge-scaffold-width: 100vw;
- }
- }
-}
-
-@mixin host() {
- @include theme.css-custom-property(width, --forge-scaffold-width, 100%);
- @include theme.css-custom-property(height, --forge-scaffold-height, 100%);
-
- box-sizing: border-box;
- display: block;
- position: relative;
-}
-
-@mixin base() {
- @include theme.css-custom-property(height, --forge-scaffold-height, 100%);
- @include theme.css-custom-property(position, --forge-scaffold-position, relative);
- @include theme.css-custom-property(overflow, --forge-scaffold-overflow, hidden);
-
- display: grid;
- grid-template-rows: auto 1fr auto;
- grid-template-columns: auto 1fr auto;
-}
-
-@mixin header() {
- grid-row: 1;
- grid-column: 2;
- min-width: 0;
-}
-
-@mixin body() {
- @include theme.css-custom-property(width, --forge-scaffold-width, 100%);
- @include theme.css-custom-property(position, --forge-scaffold-body-position, relative);
-
- display: grid;
- grid-template-rows: auto 1fr auto;
- grid-template-columns: auto 1fr auto;
- grid-row: 2;
- grid-column: 2;
- overflow: hidden;
-}
-
-@mixin body-header() {
- grid-row: 1;
- grid-column: 2;
-}
-
-@mixin body-main() {
- overflow: auto;
- grid-row: 2;
- grid-column: 2;
-}
-
-@mixin body-footer() {
- grid-row: 3;
- grid-column: 2;
-}
-
-@mixin footer() {
- grid-row: 3;
- grid-column: 2;
-}
-
-@mixin body-aside() {
- overflow: auto;
-}
-
-@mixin body-left-aside() {
- grid-column: 1;
-
- // When specifying a body-left slot, this allows the aside to span the last row
- grid-row: 1/4;
-}
-
-@mixin body-right-aside() {
- grid-column: 3;
-
- // When specifying a body-left slot, this allows the aside to span the last row
- grid-row: 1/4;
-}
-
-@mixin left() {
- grid-column: 1;
- grid-row: 1/5;
-}
-
-@mixin right() {
- grid-column: 3;
- grid-row: 1/5;
-}
-
-@mixin host() {
- display: block;
- height: 100%;
- width: 100%;
-}
diff --git a/src/lib/scaffold/_token-utils.scss b/src/lib/scaffold/_token-utils.scss
new file mode 100644
index 000000000..20ca17012
--- /dev/null
+++ b/src/lib/scaffold/_token-utils.scss
@@ -0,0 +1,25 @@
+@use '../core/styles/tokens/scaffold/tokens';
+@use '../core/styles/tokens/token-utils';
+
+$_module: scaffold;
+$_tokens: tokens.$tokens;
+
+@mixin provide-theme($theme) {
+ @include token-utils.provide-theme($_module, $_tokens, $theme);
+}
+
+@function token($name, $type: token) {
+ @return token-utils.token($_module, $_tokens, $name, $type);
+}
+
+@function declare($token) {
+ @return token-utils.declare($_module, $token);
+}
+
+@mixin override($token, $token-or-value, $type: token) {
+ @include token-utils.override($_module, $_tokens, $token, $token-or-value, $type);
+}
+
+@mixin tokens($includes: null, $excludes: null) {
+ @include token-utils.tokens($_module, $_tokens, $includes, $excludes);
+}
diff --git a/src/lib/scaffold/build.json b/src/lib/scaffold/build.json
deleted file mode 100644
index 69a8f23e3..000000000
--- a/src/lib/scaffold/build.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "$schema": "../../../node_modules/@tylertech/forge-cli/config/build-schema.json",
- "extends": "../build.json",
- "stylesheets": [
- "./forge-scaffold.scss"
- ]
-}
diff --git a/src/lib/scaffold/forge-scaffold.scss b/src/lib/scaffold/forge-scaffold.scss
deleted file mode 100644
index 3af33b416..000000000
--- a/src/lib/scaffold/forge-scaffold.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-@use './mixins';
-
-.forge-scaffold {
- @include mixins.base;
-
- &__header {
- @include mixins.header;
- }
-
- &__body {
- @include mixins.body;
-
- &-main {
- @include mixins.body-main;
- }
-
- &-footer {
- @include mixins.body-footer;
- }
- }
-
- &__left-aside,
- &__right-aside {
- @include mixins.body-aside;
- }
-
- &__left-aside {
- @include mixins.body-left-aside;
- }
-
- &__right-aside {
- @include mixins.body-right-aside;
- }
-
- &__footer {
- @include mixins.footer;
- }
-}
diff --git a/src/lib/scaffold/index.scss b/src/lib/scaffold/index.scss
new file mode 100644
index 000000000..98a38c0d9
--- /dev/null
+++ b/src/lib/scaffold/index.scss
@@ -0,0 +1 @@
+@forward './core';
diff --git a/src/lib/scaffold/index.ts b/src/lib/scaffold/index.ts
index 0cbd74c7a..87655baf5 100644
--- a/src/lib/scaffold/index.ts
+++ b/src/lib/scaffold/index.ts
@@ -1,5 +1,4 @@
import { defineCustomElement } from '@tylertech/forge-core';
-
import { ScaffoldComponent } from './scaffold';
export * from './scaffold-constants';
diff --git a/src/lib/scaffold/scaffold-constants.ts b/src/lib/scaffold/scaffold-constants.ts
index 6e2150a1d..17ad65cc0 100644
--- a/src/lib/scaffold/scaffold-constants.ts
+++ b/src/lib/scaffold/scaffold-constants.ts
@@ -2,6 +2,16 @@ import { COMPONENT_NAME_PREFIX } from '../constants';
const elementName: keyof HTMLElementTagNameMap = `${COMPONENT_NAME_PREFIX}scaffold`;
+const observedAttributes = {
+ VIEWPORT: 'viewport'
+};
+
+const attributes = {
+ ...observedAttributes
+};
+
export const SCAFFOLD_CONSTANTS = {
- elementName
+ elementName,
+ observedAttributes,
+ attributes
};
diff --git a/src/lib/scaffold/scaffold.html b/src/lib/scaffold/scaffold.html
index 9da801806..bd426dad7 100644
--- a/src/lib/scaffold/scaffold.html
+++ b/src/lib/scaffold/scaffold.html
@@ -1,10 +1,10 @@
-