diff --git a/WORKLOG.md b/WORKLOG.md
index 1f63906f..14a4072c 100644
--- a/WORKLOG.md
+++ b/WORKLOG.md
@@ -11,6 +11,9 @@
* acp init
* DO postgres
+* only clear effects on post_resolve
+ electrify doesn't work if you ko the construct
+
## SOON
*SERVER*
* modules
diff --git a/client/assets/styles/account.less b/client/assets/styles/account.less
index a5e763c3..a73faaae 100644
--- a/client/assets/styles/account.less
+++ b/client/assets/styles/account.less
@@ -1,19 +1,16 @@
@import 'colours.less';
-.account-page {
- height: 100%;
+.account {
+ margin-top: 2em;
+ grid-area: bottom;
+
display: grid;
-
- grid-template-rows: minmax(min-content, 2fr) 1fr;
- grid-template-columns: 1fr;
-
- grid-template-areas:
- "team"
- "account";
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+ grid-gap: 0 1em;
button {
display: block;
- height: 3em;
+ // height: 3em;
width: 75%;
}
@@ -23,20 +20,20 @@
display: block;
}
- .team {
- grid-area: team;
- /* poor man's
*/
- border-bottom: 0.1em solid #444;
- }
+ .list {
+ letter-spacing: 0.25em;
+ text-transform: uppercase;
- .account {
- margin: 2em 2em 0 0;
- grid-area: account;
+ figure {
+ font-size: 125%;
+ display: flex;
+ flex-flow: column;
- display: grid;
- grid-template-columns: 1fr 1fr 1fr 1fr;
- grid-gap: 0 1em;
+ button {
+ width: 100%;
+ }
+ }
}
}
diff --git a/client/assets/styles/colours.less b/client/assets/styles/colours.less
index d7e0fc49..cfed8007 100644
--- a/client/assets/styles/colours.less
+++ b/client/assets/styles/colours.less
@@ -31,3 +31,33 @@ svg {
stroke: @blue;
}
}
+
+.green {
+ color: @green;
+ stroke: @green;
+}
+
+.red {
+ color: @red;
+ stroke: @red;
+}
+
+.red-fill {
+ fill: @red;
+}
+
+.blue {
+ color: @blue;
+ stroke: @blue;
+ stroke-linecap: round;
+}
+
+.gray {
+ color: #333;
+ stroke: #333;
+}
+
+.white {
+ color: @white;
+ stroke: @white;
+}
diff --git a/client/assets/styles/controls.less b/client/assets/styles/controls.less
index 5e4dbaad..0bc5c759 100644
--- a/client/assets/styles/controls.less
+++ b/client/assets/styles/controls.less
@@ -1,10 +1,17 @@
aside {
grid-area: ctrl;
display: grid;
+
+ grid-template-areas:
+ "timer controls"
+ "timer controls"
+ "timer controls";
+
+ grid-template-columns: min-content 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0.5em 0;
- padding: 1em;
+ padding: 1em 1em 1em 0;
div {
text-align: right;
@@ -28,6 +35,30 @@ aside {
border-color: forestgreen;
}
}
+
+ .timer-container {
+ grid-area: timer;
+
+ display: flex;
+ flex: 1 1 100%;
+
+ height: 100%;
+ min-height: 100%;
+
+ width: 0.25em;
+ max-width: 0.25em;
+
+ margin: 0 1em 0 0;
+ border: none;
+ }
+
+ .timer {
+ background: whitesmoke;
+ transition-property: all;
+ transition-duration: 0.25s;
+ transition-delay: 0;
+ transition-timing-function: ease;
+ }
}
.ready-btn:hover, .ready-btn:focus, .ready-btn:active {
diff --git a/client/assets/styles/footer.less b/client/assets/styles/footer.less
new file mode 100644
index 00000000..8ab8873a
--- /dev/null
+++ b/client/assets/styles/footer.less
@@ -0,0 +1,51 @@
+footer {
+ display: none;
+ flex-flow: row wrap;
+ grid-area: footer;
+ margin: 0;
+
+ button {
+ margin: 0;
+ border: none;
+ background: #222;
+ font-size: 1.5em;
+ padding: 0.25em;
+
+ &[disabled] {
+ color: #444;
+ }
+
+ &:not(:last-child) {
+ background: #222;
+ border-right: 1px solid black;
+ }
+
+ .ready {
+ background: forestgreen;
+ color: black;
+ }
+ }
+
+ .timer-container {
+ display: flex;
+ flex: 1 1 100%;
+ width: 100%;
+ height: 0.25em;
+ max-height: 0.25em;
+
+ border: none;
+ margin: 1em 0 0 0;
+ }
+
+ .timer {
+ background: whitesmoke;
+ transition-property: all;
+ transition-duration: 0.25s;
+ transition-delay: 0;
+ transition-timing-function: ease;
+ }
+}
+
+#nav-btn, #instance-nav {
+ display: none;
+}
diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less
index a2949889..e51237bc 100644
--- a/client/assets/styles/game.less
+++ b/client/assets/styles/game.less
@@ -323,15 +323,6 @@
pointer-events: none;
}
-/*@keyframes rotate {
- 0% {
- transform: rotateY(0deg);
- }
- 100% {
- transform: rotateY(50deg);
- }
-}
-*/
.resolving .skills button {
opacity: 0;
}
@@ -339,80 +330,9 @@
.skill-animation {
opacity: 0;
stroke-width: 5px;
+ height: 5em;
}
-/*
- COMBAT ANIMATIONS
-*/
-
-/* ----------------------------------------------
- * Generated by Animista on 2019-5-21 11:38:30
- * w: http://animista.net, t: @cssanimista
- * ---------------------------------------------- */
-
-
-/*.attack-cast {
- -webkit-animation: attack-cast 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
- animation: attack-cast 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
-}
-
-@-webkit-keyframes attack-cast {
- 0% {
- -webkit-transform: translateY(0);
- transform: translateY(0);
- opacity: 1;
- }
- 100% {
- -webkit-transform: translateY(-5em);
- transform: translateY(-5em);
- opacity: 0;
- }
-}
-@keyframes attack-cast {
- 0% {
- -webkit-transform: translateY(0);
- transform: translateY(0);
- opacity: 1;
- }
- 100% {
- -webkit-transform: translateY(-5em);
- transform: translateY(-5em);
- opacity: 0;
- }
-}
-
-.attack-hit {
- -webkit-animation: attack-hit 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
- animation: attack-hit 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
-}
-
-@-webkit-keyframes attack-hit {
- 0% {
- -webkit-transform: translateY(-5em) translateX(5em);
- transform: translateY(-5em) translateX(5em);
- opacity: 0;
- }
- 100% {
- -webkit-transform: translateY(0) translateX(0);
- transform: translateY(0) translateX(0);
- opacity: 1;
- }
-}
-@keyframes attack-hit {
- 0% {
- -webkit-transform: translateY(-5em) translateX(5em);
- transform: translateY(-5em) translateX(5em);
- opacity: 0;
- }
- 100% {
- -webkit-transform: translateY(0) translateX(0);
- transform: translateY(0) translateX(0);
- opacity: 1;
- }
-}
-*/
-
-
@media (max-width: 1000px) {
.game {
grid-template-areas:
diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less
index 40038876..4a4ee15b 100644
--- a/client/assets/styles/instance.less
+++ b/client/assets/styles/instance.less
@@ -421,6 +421,12 @@
margin-top: 1em;
grid-area: playername;
}
+
+ .team {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(min-content, 33%));
+ max-height: 100%;
+ }
}
/* Mobile Nav*/
diff --git a/client/assets/styles/menu.less b/client/assets/styles/menu.less
new file mode 100644
index 00000000..c0367cc6
--- /dev/null
+++ b/client/assets/styles/menu.less
@@ -0,0 +1,85 @@
+@import 'colours.less';
+
+.menu {
+ height: 100%;
+ display: grid;
+
+ grid-template-rows: minmax(min-content, 2fr) 1fr;
+ grid-template-columns: 1fr;
+
+ grid-template-areas:
+ "top"
+ "bottom";
+
+ .top {
+ padding: 0 0 0.5em 2em;
+ border-bottom: 0.1em solid #222;
+ box-sizing: border-box;
+ }
+
+ .team {
+ display: grid;
+ grid-area: top;
+ grid-template-columns: repeat(auto-fill, minmax(min-content, 33%));
+ max-height: 100%;
+
+ .team-select:not(:nth-child(3n)) {
+ margin-right: 0.5em;
+ }
+
+ .construct {
+ flex: 1 1 33%;
+
+ display: flex;
+ flex-flow: column;
+ text-align: center;
+ justify-content: center;
+
+ border: 1px solid black;
+ transition-property: border;
+ transition-duration: 0.25s;
+ transition-delay: 0;
+ transition-timing-function: ease;
+
+ button:not(:last-child) {
+ margin-bottom: 1em;
+ }
+
+ .avatar {
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ pointer-events: none;
+ height: 100%;
+ }
+ }
+ }
+
+ .inventory {
+ margin-top: 2em;
+ grid-area: bottom;
+
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+
+ h1 {
+ margin-bottom: 0.5em;
+ }
+
+ .list {
+ letter-spacing: 0.25em;
+ text-transform: uppercase;
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ grid-gap: 1em;
+ flex-flow: row wrap;
+ align-items: flex-end;
+ }
+
+ figure {
+ font-size: 125%;
+ display: flex;
+ flex-flow: column;
+ }
+ }
+}
diff --git a/client/assets/styles/nav.less b/client/assets/styles/nav.less
new file mode 100644
index 00000000..11184866
--- /dev/null
+++ b/client/assets/styles/nav.less
@@ -0,0 +1,98 @@
+nav {
+ grid-area: nav;
+ padding-left: 2em;
+ margin-right: 2em;
+ max-height: 100%;
+
+ h1 {
+ margin-bottom: 0.5em;
+ }
+
+ h2:first-child {
+ margin: 0;
+ }
+
+ h2 {
+ margin-top: 2em;
+ }
+
+ hr {
+ margin: 1em 0;
+ border-color: #444;
+ }
+
+ button {
+ text-overflow: ellipsis;
+ display: block;
+ color: #888;
+ flex: 1 1 100%;
+ padding: 0;
+ margin: 0;
+ border-width: 0px;
+ }
+
+ button.active {
+ color: whitesmoke;
+ }
+
+ button[disabled], button[disabled]:hover {
+ color: #333;
+ text-decoration: none;
+ }
+
+ button:hover {
+ color: whitesmoke;
+ text-decoration: underline;
+ }
+
+ button:focus, button:active {
+ color: whitesmoke;
+ }
+
+ .account-info {
+ display: flex;
+ }
+
+ .account-header {
+ letter-spacing: 0.05em;
+ flex: 1;
+ display: inline;
+ }
+
+ .account-info svg {
+ margin: 0.5em 0 0 1em;
+ height: 1em;
+ background-color: black;
+ stroke: whitesmoke;
+ }
+
+ .ping-path {
+ fill: none;
+ stroke-width: 4px;
+ stroke-dasharray: 121, 242;
+ animation: saw 2s infinite linear;
+
+ transition-property: stroke-color;
+ transition-duration: 0.25s;
+ transition-timing-function: ease;
+ }
+
+ .ping-text {
+ margin-left: 1em;
+ min-width: 3em;
+ display: inline-block;
+ }
+
+ .play-btn {
+ font-size: 150%;
+ }
+}
+
+@keyframes saw {
+ 0% {
+ stroke-dashoffset: 363;
+ }
+ 100% {
+ stroke-dashoffset: 0;
+ }
+}
diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less
index 12bde5a2..dedefa13 100644
--- a/client/assets/styles/styles.less
+++ b/client/assets/styles/styles.less
@@ -1,11 +1,6 @@
@import 'colours.less';
-/*
- GLOBAL
-*/
-
html, body, #mnml {
- /*width: 100%;*/
margin: 0;
background-color: black;
@@ -66,6 +61,7 @@ h4 {
}
hr {
+ color: #222;
margin: 1.5em 0;
width: 100%;
}
@@ -85,74 +81,11 @@ figure {
"nav main ctrl";
}
-nav {
- grid-area: nav;
- padding-left: 2em;
- margin-right: 2em;
- max-height: 100%;
-
- h1 {
- margin-bottom: 0.5em;
- }
-}
-
-nav h2:first-child {
- margin: 0;
-}
-
-nav h2 {
- margin-top: 2em;
-}
-
-nav hr {
- margin: 1em 0;
- border-color: #444;
-}
-
-nav button {
- text-overflow: ellipsis;
- display: block;
- color: #888;
- flex: 1 1 100%;
- padding: 0;
- margin: 0;
- border-width: 0px;
-}
-
-nav button.active {
- color: whitesmoke;
-}
-
-nav button[disabled], nav button[disabled]:hover {
- color: #333;
- text-decoration: none;
-}
-
-nav button:hover {
- color: whitesmoke;
- text-decoration: underline;
-}
-
-nav button:focus, nav button:active {
- color: whitesmoke;
-}
-
main {
padding: 1em;
grid-area: main;
}
-tr.right:focus, tr.right:hover {
- box-shadow: inset -0.5em 0 0 0 whitesmoke;
-}
-
-tr {
- transition-property: color, background;
- transition-duration: 0.25s;
- transition-delay: 0;
- transition-timing-function: ease;
-}
-
button, input {
font-family: 'Jura';
color: whitesmoke;
@@ -195,19 +128,6 @@ svg {
height: 2em;
}
-.skill-animation {
- height: 5em;
-}
-
-.team .avatar {
- object-fit: contain;
- max-width: 100%;
- max-height: 100%;
- width: auto;
- height: auto;
- pointer-events: none;
-}
-
table {
table-layout: fixed;
width: 100%;
@@ -250,56 +170,6 @@ button[disabled] {
border-color: #222;
}
-/*
- COLOURS
-*/
-
-.green {
- color: #1FF01F;
- stroke: #1FF01F;
-}
-
-.red {
- color: #a52a2a;
- stroke: #a52a2a;
-}
-
-.red-fill {
- fill: #a52a2a;
-}
-
-.blue {
- color: #3050f8;
- stroke: #3050f8;
- stroke-linecap: round;
-}
-
-.yellow {
- color: #FFD123;
- stroke: #FFD123;
-}
-
-.purple {
- color: #A25AC1;
- stroke: #A25AC1;
-}
-
-.cyan {
- color: #6AD1BF;
- stroke: #6AD1BF;
-}
-
-.gray {
- color: #333;
- stroke: #333;
-}
-
-.white {
- color: whitesmoke;
- stroke: whitesmoke;
-}
-
-
/*
LOGIN
*/
@@ -320,229 +190,6 @@ button[disabled] {
border-color: #888;
}
-/*
- account
-*/
-
-header {
- display: flex;
- flex-flow: row;
- grid-area: hd;
- margin-bottom: 1.5em;
-}
-
-.header-title {
- flex: 1;
- letter-spacing: 0.05em;
-}
-
-.account-info {
- display: flex;
-}
-
-.account-header {
- letter-spacing: 0.05em;
- flex: 1;
- display: inline;
-}
-
-.account-info svg {
- margin: 0.5em 0 0 1em;
- height: 1em;
- background-color: black;
- stroke: whitesmoke;
-}
-
-.ping-path {
- fill: none;
- stroke-width: 4px;
- stroke-dasharray: 121, 242;
- animation: saw 2s infinite linear;
-
- transition-property: stroke-color;
- transition-duration: 0.25s;
- transition-timing-function: ease;
-}
-
-.ping-text {
- margin-left: 1em;
- min-width: 3em;
- display: inline-block;
-}
-
-@keyframes saw {
- 0% {
- stroke-dashoffset: 363;
- }
- 100% {
- stroke-dashoffset: 0;
- }
-}
-
-/*
- TEAM
-*/
-
-.team {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(min-content, 33%));
- max-height: 100%;
-}
-
-.menu-construct {
- margin: 0.5em;
- flex: 1 1 auto;
-
- display: flex;
- flex-flow: column;
- text-align: center;
- justify-content: center;
-
- border: 1px solid black;
- transition-property: border;
- transition-duration: 0.25s;
- transition-delay: 0;
- transition-timing-function: ease;
-
- button:not(:last-child) {
- margin-bottom: 1em;
- }
-
- .avatar {
- background-size: contain;
- background-repeat: no-repeat;
- background-position: center;
- pointer-events: none;
- height: 100%;
- }
-}
-
-.spawn-btn.menu-construct {
- border: 1px solid #333;
- color: #333;
- display: flex;
- flex-flow: row wrap;
- align-content: center;
- justify-content: center;
-}
-
-.spawn-btn.menu-construct.selected {
- color: whitesmoke;
-}
-
-.spawn-btn.menu-construct:hover {
- border: 1px solid whitesmoke;
-}
-
-.spawn-btn input {
- flex: 1 1 100%;
- width: 100%;
- margin: 1em;
-}
-
-.spawn-btn button {
- flex: 1 1 100%;
- margin: 0.5em 1em;
- padding: 0 0.5em;
-}
-
-.spawn-btn input[disabled], .spawn-btn button[disabled] {
- opacity: 0
-}
-
-.play {
- height: 100%;
- display: grid;
-
- grid-template-rows: minmax(min-content, 2fr) 1fr;
- grid-template-columns: 1fr;
-
- grid-template-areas:
- "team"
- "inventory";
-
- .team {
- grid-area: team;
-
- /* poor man's
*/
- padding: 0.5em 2em 0 0;
- border-bottom: 0.1em solid #444;
-
- }
-
- .menu-construct {
- flex: 1 0 33%;
- }
-
- .inventory {
- margin: 2em 2em 0 0;
- grid-area: inventory;
-
- display: grid;
- grid-template-columns: 1fr 1fr;
-
- h1 {
- margin-bottom: 0.5em;
- }
-
- .list {
- letter-spacing: 0.25em;
- text-transform: uppercase;
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- grid-gap: 1em;
- flex-flow: row wrap;
- align-items: flex-end;
- }
-
- figure {
- font-size: 125%;
- display: flex;
- flex-flow: column;
- }
- }
-}
-
-.menu-instance-btn {
- flex: 1 1 100%;
- font-size: 1.2em;
-}
-
-.play-btn {
- font-size: 150%;
-}
-
-.refresh-btn {
- border: 1px solid #222;
- float: right;
- font-size: 1.5em;
-}
-
-.create-form {
- grid-area: create;
- flex: 1;
-
- justify-self: flex-end;
-
- display: flex;
- flex-flow: row wrap;
- margin-bottom: 1.5em;
-}
-
-.create-form button {
- flex: 1;
- font-size: 1.5em;
-}
-
-.create-form button:first-child {
- margin-right: 1em;
-}
-
-.create-form button:hover, .create-form button:focus {
- border-color: whitesmoke;
- text-decoration: none;
-}
-
figure.gray {
color: #333;
stroke-color: #333;
@@ -553,63 +200,11 @@ figure.gray {
fill: none;
}
-main .top button {
- width: 100%;
-}
-
.credits {
color: @yellow;
font-weight: 800;
}
-.timer-container {
- display: flex;
- flex: 1 1 100%;
- width: 100%;
- height: 0.25em;
- max-height: 0.25em;
-
- border: none;
- margin: 1em 0 0 0;
-}
-
-.timer {
- background: whitesmoke;
- transition-property: all;
- transition-duration: 0.25s;
- transition-delay: 0;
- transition-timing-function: ease;
-}
-
-footer {
- display: none;
- flex-flow: row wrap;
- grid-area: footer;
- margin: 0;
-}
-
-footer button {
- margin: 0;
- border: none;
- background: #222;
- font-size: 1.5em;
- padding: 0.25em;
-}
-
-footer button:disabled {
- color: #444;
-}
-
-footer button:not(:last-child) {
- background: #222;
- border-right: 1px solid black;
-}
-
-footer button .ready {
- background: forestgreen;
- color: black;
-}
-
@media (max-width: 1500px) {
#mnml {
font-size: 75%;
@@ -620,10 +215,6 @@ footer button .ready {
}
}
-#nav-btn, #instance-nav {
- display: none;
-}
-
.mobile-title {
display: none;
-}
+}
\ No newline at end of file
diff --git a/client/index.js b/client/index.js
index da09b74d..8c76e1ff 100644
--- a/client/index.js
+++ b/client/index.js
@@ -1,9 +1,12 @@
require('./assets/styles/styles.less');
+require('./assets/styles/menu.less');
+require('./assets/styles/nav.less');
+require('./assets/styles/footer.less');
+require('./assets/styles/account.less');
+require('./assets/styles/controls.less');
require('./assets/styles/instance.less');
require('./assets/styles/vbox.less');
require('./assets/styles/game.less');
-require('./assets/styles/controls.less');
-require('./assets/styles/account.less');
require('./assets/styles/styles.mobile.css');
require('./assets/styles/instance.mobile.css');
diff --git a/client/src/components/account.management.jsx b/client/src/components/account.management.jsx
index 102b846b..6bebfe10 100644
--- a/client/src/components/account.management.jsx
+++ b/client/src/components/account.management.jsx
@@ -1,6 +1,8 @@
const { connect } = require('preact-redux');
const preact = require('preact');
+const SpawnButton = require('./spawn.button');
+
const { postData } = require('./../utils');
const actions = require('../actions');
@@ -9,6 +11,7 @@ const addState = connect(
const {
account,
ping,
+ ws,
} = state;
@@ -16,10 +19,15 @@ const addState = connect(
postData('/logout').then(() => window.location.reload(true));
}
+ function sendConstructSpawn(name) {
+ return ws.sendMtxConstructSpawn(name);
+ }
+
return {
account,
ping,
logout,
+ sendConstructSpawn,
};
},
);
@@ -30,6 +38,7 @@ function AccountStatus(args) {
account,
ping,
logout,
+ sendConstructSpawn,
} = args;
if (!account) return null;
@@ -83,6 +92,14 @@ function AccountStatus(args) {
/>
+
+
+ spawn new construct
+
+
+
);
}
diff --git a/client/src/components/account.page.jsx b/client/src/components/account.page.jsx
index 17474fe8..021bb58b 100644
--- a/client/src/components/account.page.jsx
+++ b/client/src/components/account.page.jsx
@@ -23,7 +23,7 @@ function Account(args) {
} = args;
return (
-
+
diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx
index e63cea4a..a27e4e06 100644
--- a/client/src/components/game.ctrl.jsx
+++ b/client/src/components/game.ctrl.jsx
@@ -20,16 +20,22 @@ const addState = connect(
return ws.sendGameReady(game.id);
}
+ function getInstanceState() {
+ return ws.sendInstanceState(game.instance);
+ }
+
return {
game,
sendReady,
account,
+ getInstanceState,
animating,
};
},
function receiveDispatch(dispatch) {
function quit() {
+ dispatch(actions.setNav('transition'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
@@ -74,6 +80,7 @@ function Controls(args) {
animating,
sendReady,
quit,
+ getInstanceState,
} = args;
if (!game) return false;
@@ -81,11 +88,43 @@ function Controls(args) {
const opponent = game.players.find(t => t.id !== account.id);
const player = game.players.find(t => t.id === account.id);
+ function quitClick() {
+ getInstanceState();
+ quit();
+ }
+
+ const zero = Date.parse(game.phase_start);
+ const now = Date.now();
+ const end = Date.parse(game.phase_end);
+ const timerPct = game.phase_end
+ ? ((now - zero) / (end - zero) * 100)
+ : 100;
+
+ const displayColour = !game.phase_end
+ ? '#222'
+ : player.ready
+ ? 'forestgreen'
+ : timerPct > 80
+ ? 'red'
+ : 'whitesmoke';
+
+ const timerStyles = {
+ height: `${timerPct > 100 ? 100 : timerPct}%`,
+ background: displayColour,
+ };
+
+ const timer = (
+
+ );
+
const readyBtn = ;
- const quitBtn = ;
+ const quitBtn = ;
return (