Challenge mode functionality complete; layout updates

This commit is contained in:
Gene Mecija 2020-02-10 17:51:09 -08:00
parent dd077e6d12
commit 113e4a2348
20 changed files with 1100 additions and 272 deletions

View file

@ -40,8 +40,8 @@ export default React.memo(function App() {
<MorseBufferContextProvider>
<WordListPickerContextProvider>
<WordFeederContextProvider>
<GameClockContextProvider>
<ChallengeContextProvider>
<GameClockContextProvider>
<SidebarLeft />
<div id="main-interface">
<div id="mainOptions">
@ -82,8 +82,8 @@ export default React.memo(function App() {
<div id="settings-icon" onClick={toggleRight}><i class="ri-settings-3-line"></i></div>
</div> */}
</ChallengeContextProvider>
</GameClockContextProvider>
</ChallengeContextProvider>
</WordFeederContextProvider>
</WordListPickerContextProvider>
</MorseBufferContextProvider>

View file

@ -1,12 +1,8 @@
import React, {useContext} from 'react';
import '../css/App.css';
import morseCode from '../data/morse-reverse.json'
import ChallengeWord from '../components/ChallengeWord'
import ChallengeBufferDisplay from '../components/ChallengeBufferDisplay';
import { MorseBufferContext } from '../contexts/morseBufferContext';
import { WordFeederContext } from '../contexts/wordFeederContext';
import GameClock from '../components/GameClock';
import { GameClockContext } from '../contexts/gameClockContext';
import { KeyTypeContext } from '../contexts/keyTypeContext';
import StraightKey from '../components/StraightKey';
import ElectronicKey from '../components/ElectronicKey';
@ -14,102 +10,21 @@ import ChallengeControls from '../components/ChallengeControls';
import { ChallengeContext } from '../contexts/challengeContext';
export default React.memo(function ChallengeMode(props) {
console.log('CHALLENGE MODE');
const {word, getNextWord} = useContext(WordFeederContext)
const {clockIsRunning} = useContext(GameClockContext)
const {morseCharBuffer, setMorseCharBuffer} = useContext(MorseBufferContext)
export default React.memo(function ChallengeMode() {
const {keyType} = useContext(KeyTypeContext)
const {completeChallenge, cancelChallenge} = useContext(ChallengeContext)
let morseArray = morseCharBuffer.split('_').filter(l => l !== '')
let challengeWordClass = ''
let correctCharIndexes = [] // Indexes of correct letters in Challenge Word
let incorrectMorseIndexes = [] // Indexes of incorrect morse characters in morse character buffer
let offset = 0
let challengeLetters
// If no more words in wordlist, feeder returns first word in an array
if (typeof word === 'object') {
completeChallenge()
challengeLetters = word[0].split('')
}
else {
challengeLetters = word.split('')
}
// Iterate through the morse character buffer and compare with each letter of challenge word
morseArray.forEach((item, index) => {
if (morseCharBuffer.slice(-1) === '_') { // If end of morse character
let morseLetter = morseCode[morseArray[index]] || '[?]'
let challengeLetter = challengeLetters[index-offset].toLowerCase()
if (morseLetter === challengeLetter) {
correctCharIndexes.push(index-offset)
document.getElementById('challengeWord').childNodes[index-offset].classList.add('correct')
// incorrectCharIndex = null
}
else {
// incorrectCharIndex = index-offset
incorrectMorseIndexes.push(index)
if (incorrectMorseIndexes.length > 0) {
setMorseCharBuffer(prev => {
let newState = prev.split('_').filter(l => l !== '')
newState.splice(incorrectMorseIndexes[0], 1)
newState = newState.join('_') + '_'
return newState
})
incorrectMorseIndexes.splice(1,incorrectMorseIndexes.length)
}
offset = incorrectMorseIndexes.length
}
}
})
function timeout(delay) {
new Promise((resolve) => {
setTimeout(() => {
resolve()
}, delay)
})
}
// Next word once all correct
if (correctCharIndexes.length === challengeLetters.length) {
//
challengeWordClass = 'correct'
setTimeout(() => {
setMorseCharBuffer('')
morseArray = []
incorrectMorseIndexes = []
correctCharIndexes = []
offset = 0
}, 800)
setTimeout(() => {
getNextWord()
if (document.getElementById('challengeWord') !== null) {
document.getElementById('challengeWord').childNodes.forEach(node => {
node.classList = "cLetter"
})
}
}, 1000)
}
const {challengeState, cancelChallenge, morseArray, incorrectMorseIndexes, challengeWordClass} = useContext(ChallengeContext)
return (
<>
{clockIsRunning ? (keyType === "straight" ?
{challengeState === 'started' ? (keyType === "straight" ?
<StraightKey /> : <ElectronicKey />) : <></>
}
<ChallengeControls cancelChallenge={cancelChallenge} />
<GameClock />
<ChallengeWord className={challengeWordClass} word={word} />
<div id="challenge-header">
<GameClock />
<ChallengeControls cancelChallenge={cancelChallenge} />
</div>
<ChallengeWord challengeWordClass={challengeWordClass} />
<ChallengeBufferDisplay morseArray={morseArray} incorrectMorseIndexes={incorrectMorseIndexes} />
</>
)

View file

@ -5,18 +5,18 @@ import { ChallengeContext } from "../contexts/challengeContext"
export default (function ChallengeComplete(props) {
const {gameClockTime} = useContext(GameClockContext)
const {cancelChallenge} = useContext(ChallengeContext)
const {setChallengeState} = useContext(ChallengeContext)
function _continue() {
// setGameClockTime(0)
// props.setChallengeState('ready')
cancelChallenge()
setChallengeState('ready')
}
return (
<div id="challengeComplete" className="notify">
<h2>Challenge Complete</h2>
Challenge completed in {gameClockTime} seconds!
<span id="notify-title">Challenge Complete</span>
<span id="message">Challenge completed in {gameClockTime} seconds!</span>
<button id="continue" onClick={_continue}>Continue</button>
</div>

View file

@ -4,7 +4,7 @@ export default (function ChallengeControls(props) {
return (
<div id="challengeControls">
<button onClick={props.cancelChallenge}>Exit</button>
<button onClick={props.cancelChallenge}>Exit Challenge</button>
</div>
)
})

View file

@ -8,7 +8,7 @@ export default (function ChallengeReady() {
return (
<div id="challengeReady" className="notify">
<h2>Challenge Options</h2>
<span id="notify-title">Challenge Options</span>
<WordListPicker />
<button id="startChallenge" onClick={startChallenge}>Start Challenge</button>
</div>

View file

@ -1,9 +1,9 @@
import React, { useContext } from "react"
import { WordFeederContext } from "../contexts/wordFeederContext"
import { ChallengeContext } from "../contexts/challengeContext"
export default React.memo(function ChallengeWord(props) {
let challengeWordClass= props.className
const {word} = useContext(WordFeederContext)
let challengeLetters
@ -21,6 +21,6 @@ export default React.memo(function ChallengeWord(props) {
})
return (
<div id="challengeWord" className={challengeWordClass}>{spannedWord}</div>
<div id="challengeWord" className={props.challengeWordClass}>{spannedWord}</div>
)
})

View file

@ -1,13 +1,14 @@
import React, {useContext} from "react"
import { GameClockContext } from "../contexts/gameClockContext";
function GameClock(props) {
export default (function GameClock(props) {
const {gameClockTime} = useContext(GameClockContext)
return (
<div id="gameClock">{gameClockTime}</div>
)
}
const minutes = Math.floor(gameClockTime / 60)
const seconds = gameClockTime % 60
export default GameClock
return (
<div id="gameClock">Time Elapsed: <span id="clockTime">{minutes} minutes {seconds} seconds</span></div>
)
})

View file

@ -16,20 +16,15 @@ export default React.memo(function Info() {
<h2>Dits and Dahs</h2>
<p>
<span className="bold">Dit</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('.')}></i><br />
Denoted as a dot (.), dits are short tones and are base unit of morse code.<br />
<span className="bold">Dah</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('-')}></i><br />
Denoted as a dash (-), dahs are long tones the length of three dits.
<span className="bold">Dit</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('.')}></i> Denoted as a dot (.), dits are short tones and are base unit of morse code.<br />
<span className="bold">Dah</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('-')}></i> Denoted as a dash (-), dahs are long tones the length of three dits.
</p>
<h2>Spacing</h2 >
<p>
<span className="bold">Intra-character Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('...')}></i><br />
Silence between dits and dahs the length of one dit. Three dits separated by one-dit-long spaces is an "S".<br />
<span className="bold">Inter-character Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('. . .')}></i><br />
Silence the length of three dits. Three dits separated by three-dit-long spaces is "EEE".<br />
<span className="bold">Inter-word Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('. /. /.')}></i><br />
Silence the length of seven dits. Three dits separated by seven-dit-long spaces is "E E E".
<span className="bold">Intra-character Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('...')}></i> Silence between dits and dahs the length of one dit. Three dits separated by one-dit-long spaces is an "S".<br />
<span className="bold">Inter-character Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('. . .')}></i> Silence the length of three dits. Three dits separated by three-dit-long spaces is "EEE".<br />
<span className="bold">Inter-word Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('././.')}></i> Silence the length of seven dits. Three dits separated by seven-dit-long spaces is "E E E".
</p>
<h2>Speed</h2>

View file

@ -41,9 +41,9 @@ export default (function MorseHistoryTextBox() {
// } catch {}
return (
<>
<div id="morse-history">
<div id="morseHistory-textbox">{text}</div>
<button onClick={clearHistory}>Clear History</button>
</>
<button id="clear-history" onClick={clearHistory}>Clear History</button>
</div>
)
})

View file

@ -50,7 +50,8 @@ export default (function PlayMorseInput() {
<h2>Translate To Morse</h2>
</div>
<div id="input">
<input type="text" id='morseInput' value={inputValue} onChange={handleChange} placeholder="Type here." maxLength="25"/> <i className="ri-volume-up-fill" onClick={handlePlay}></i>
<input type="text" id='morseInput' value={inputValue} onChange={handleChange} placeholder="Type here." maxLength="25"/> <i className="ri-play-fill" onClick={handlePlay}></i>
<i class="ri-stop-fill" onClick={() => playMorseWord('')}></i>
</div>
<div id="morseTranslation">
<span id="morseTrans">

View file

@ -18,7 +18,7 @@ export default (function SidebarLeft() {
} else if (e.target.id === 'nav-legend') {
setSidebarContent('nav-legend')
} else {
setSidebarContent('nav-options')
setSidebarContent('nav-play')
}
let navItems = document.querySelector(".navbar").childNodes
@ -35,6 +35,9 @@ export default (function SidebarLeft() {
<div className="sidebar" id="left">
<div id="sidebar-container">
<div className="navbar">
<div id="nav-play" className="nav-item" onClick={navClicked}>
Play
</div>
<div id="nav-learn" className="nav-item selected" onClick={navClicked}>
Learn
</div>

View file

@ -29,12 +29,19 @@ export default React.memo(function WordListPicker() {
let wordLists = ['alphabet', 'numbers', 'common100', 'test', 'short']
let options = wordLists.map((wl, index) => (<option value={wl} key={index}>{wl.substr(0,1).toUpperCase() + wl.substr(1)}</option>))
const metadata = {
'alphabet': {description: 'Each letter of the alphabet', count: 26},
'numbers': {description: '0-9', count: 10},
'common100': {description: '100 most common words', count: 100},
'test': {description: 'A test list', count: 5},
'short': {description: 'A short list', count: 1}
}
return (
<div id="challengeOptions">
<div id="wordListPicker" className="mode-picker">
<div id="title">
Word List
Word List:
</div>
<div id="input">
<select id="wordlist-picker" defaultValue={wordListCategory} onChange={handleClick}>
@ -42,9 +49,10 @@ export default React.memo(function WordListPicker() {
</select>
</div>
</div>
<div id="wordOrderPicker" className="mode-picker">
<div id="title">
Word Order
Word Order:
</div>
<div id="buttons">
<button id="sequential" className="selected" onClick={handleClick}>
@ -55,6 +63,23 @@ export default React.memo(function WordListPicker() {
</button>
</div>
</div>
<div id="wordlist-description" className="mode-picker">
<div id="title">
Description:
</div>
<div id="info">
{metadata[wordListCategory]['description']}
</div>
</div>
<div id="wordlist-count" className="mode-picker">
<div id="title">
# of List Items:
</div>
<div id="info">
{metadata[wordListCategory]['count']}
</div>
</div>
</div>
)
})

View file

@ -1,22 +1,42 @@
import React, {useState, useContext} from "react"
import { GameClockContext } from "./gameClockContext"
import { WordFeederContext } from "./wordFeederContext"
// import { KeyTypeContext } from "./keyTypeContext"
import { KeyTypeContext } from "./keyTypeContext";
import { MorseBufferContext } from "./morseBufferContext";
import morseCode from '../data/morse-reverse.json'
const ChallengeContext = React.createContext()
function ChallengeContextProvider(props) {
console.log('ChallengeContextProvider');
const [challengeState, setChallengeState] = useState('ready')
const {startGameClock, stopGameClock, setGameClockTime, intervals} = useContext(GameClockContext)
const {resetFeeder} = useContext(WordFeederContext)
const {word, getNextWord} = useContext(WordFeederContext)
const {morseCharBuffer, setMorseCharBuffer} = useContext(MorseBufferContext)
let morseArray = morseCharBuffer.split('_').filter(l => l !== '')
let challengeWordClass = ''
let correctCharIndexes = [] // Indexes of correct letters in Challenge Word
let incorrectMorseIndexes = [] // Indexes of incorrect morse characters in morse character buffer
let offset = 0
let challengeLetters
function startChallenge() {
setGameClockTime(0)
console.log('STARTCHALLENGE');
let countdown
let count = 3
// Challenge countdown setup
document.getElementById('challengeReady').classList.add('starting')
document.getElementById('challengeReady').innerHTML = `<span id="message">Challenge starting in</span><span id="count">${count}</span>`
// Start Challenge countdown
countdown = setInterval(() => {
count--
if (count === 0) {
@ -25,7 +45,7 @@ function ChallengeContextProvider(props) {
clearInterval(countdown)
setTimeout(() => {
document.getElementById('challenge-overlay').classList.add('hide')
startGameClock()
// Start Challenge
setChallengeState('started')
}, 900);
}
@ -34,31 +54,92 @@ function ChallengeContextProvider(props) {
}
function completeChallenge() {
stopGameClock()
setChallengeState('completed')
for (let i = 0; i < intervals.length; i++) {
clearInterval(intervals[i]);
if (challengeState !== 'completed') {
setChallengeState('completed')
resetFeeder()
showOverlay()
}
resetFeeder()
const challengeOverlay = document.getElementById('challenge-overlay')
challengeOverlay.classList.remove('fade')
challengeOverlay.classList.remove('hide')
}
function cancelChallenge() {
stopGameClock()
for (let i = 0; i < intervals.length; i++) {
clearInterval(intervals[i]);
if (challengeState !== 'cancelled') {
setChallengeState('cancelled')
resetFeeder()
showOverlay()
}
setChallengeState('ready')
resetFeeder()
setGameClockTime(0)
}
function showOverlay() {
const challengeOverlay = document.getElementById('challenge-overlay')
challengeOverlay.classList.remove('fade')
challengeOverlay.classList.remove('hide')
}
// If no more words in wordlist, feeder returns first word in an array
if (typeof word === 'object') {
completeChallenge()
challengeLetters = word[0].split('')
}
else {
challengeLetters = word.split('')
}
// Iterate through the morse character buffer and compare with each letter of challenge word
morseArray.forEach((item, index) => {
if (morseCharBuffer.slice(-1) === '_') { // If end of morse character
let morseLetter = morseCode[morseArray[index]] || '[?]'
let challengeLetter = challengeLetters[index-offset].toLowerCase()
if (morseLetter === challengeLetter) {
correctCharIndexes.push(index-offset)
console.log('morseCharBuffer', morseCharBuffer);
document.getElementById('challengeWord').childNodes[index-offset].classList.add('correct')
// incorrectCharIndex = null
}
else {
// incorrectCharIndex = index-offset
incorrectMorseIndexes.push(index)
if (incorrectMorseIndexes.length > 0) {
setMorseCharBuffer(prev => {
let newState = prev.split('_').filter(l => l !== '')
newState.splice(incorrectMorseIndexes[0], 1)
newState = newState.join('_') + '_'
return newState
})
incorrectMorseIndexes.splice(1,incorrectMorseIndexes.length)
}
offset = incorrectMorseIndexes.length
}
}
})
// Next word once all correct
if (correctCharIndexes.length === challengeLetters.length) {
challengeWordClass = 'correct'
setTimeout(() => {
setMorseCharBuffer('')
morseArray = []
incorrectMorseIndexes = []
offset = 0
if (document.getElementById('challengeWord') !== null) {
document.getElementById('challengeWord').childNodes.forEach(node => {
node.classList = "cLetter"
})
}
}, 800)
setTimeout(() => {
if (correctCharIndexes.length > 0) {
correctCharIndexes = []
getNextWord()
}
}, 1000)
}
return (
<ChallengeContext.Provider value={{
@ -66,7 +147,10 @@ function ChallengeContextProvider(props) {
setChallengeState: setChallengeState,
startChallenge: startChallenge,
completeChallenge: completeChallenge,
cancelChallenge: cancelChallenge
cancelChallenge: cancelChallenge,
challengeWordClass: challengeWordClass,
morseArray: morseArray,
incorrectMorseIndexes: incorrectMorseIndexes
}}>
{props.children}
</ChallengeContext.Provider>

View file

@ -1,19 +1,20 @@
import React, {useState} from "react"
import React, {useState, useContext, useEffect} from "react"
import { ChallengeContext } from "./challengeContext"
// import { KeyTypeContext } from "./keyTypeContext"
const GameClockContext = React.createContext()
function GameClockContextProvider(props) {
const [gameClockTime, setGameClockTime] = useState(0)
const [clockIsRunning, setClockIsRunning] = useState(false)
// const [gameClockTimer, setGameClockTimer] = useState(0)
// let intervals = []
const [intervals, setIntervals] = useState([])
const {challengeState, setChallengeState} = useContext(ChallengeContext)
function startGameClock() {
console.log('before clock');
if (!clockIsRunning) {
console.log('after clock');
setClockIsRunning(true)
setIntervals(prev => [...prev, (setInterval(() => {
if (document.getElementById('gameClock') === null) {
@ -40,6 +41,27 @@ function GameClockContextProvider(props) {
clearInterval(intervals[i]);
}
}
useEffect(() => {
switch (challengeState) {
case 'ready':
setGameClockTime(0)
cleanup()
break
case 'started':
startGameClock()
break
case 'completed':
stopGameClock()
break
case 'cancelled':
stopGameClock()
setChallengeState('ready')
break
default:
return
}
}, [challengeState])
return (

View file

@ -3,6 +3,7 @@ import React, {useState} from "react"
const KeyTypeContext = React.createContext()
function KeyTypeContextProvider(props) {
console.log('KeyTypeContextProvider');
const [keyType, setKeyType] = useState('straight')

View file

@ -3,6 +3,7 @@ import { WordListPickerContext } from "./wordListPickerContext"
const WordFeederContext = React.createContext()
function WordFeederContextProvider(props) {
// let wordList = ['hi', 'morse', 'code', 'hello', 'gene']
const {wordList, wordListShuffled} = useContext(WordListPickerContext)

View file

@ -160,6 +160,10 @@ html, body {
border-color: #508090;
}
#main-content .sidebar#left #sidebar-container .navbar .nav-item#nav-play {
display: none;
}
#main-content .sidebar#left #sidebar-container #info-icon {
width: -webkit-fit-content;
width: -moz-fit-content;
@ -239,7 +243,7 @@ html, body {
height: fit-content;
padding: 2.5em;
font-family: "Roboto", sans-serif;
font-size: 0.9rem;
font-size: 1.2rem;
line-height: 1.5em;
opacity: 100%;
-webkit-transition: all 500ms ease-in-out;
@ -481,7 +485,22 @@ i[class*="ri-"] {
margin-bottom: 45px;
}
#playMorseInput i:hover {
#playMorseInput #input {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: auto;
}
#playMorseInput #input i {
font-size: 1.3em;
display: inline-block;
}
#playMorseInput #input i:hover {
color: goldenrod;
}
@ -491,7 +510,7 @@ i[class*="ri-"] {
border: 1px solid #ddd;
height: 1.5rem;
font-size: 0.9em;
width: 70%;
width: auto;
}
#playMorseInput #morseTrans {
@ -614,6 +633,8 @@ i[class*="ri-"] {
}
#morseButton {
-ms-touch-action: manipulation;
touch-action: manipulation;
width: 100px;
height: 100px;
margin-top: 30px;
@ -781,18 +802,26 @@ i[class*="ri-"] {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 1.5rem;
height: 250px;
background: #fefefe;
margin-top: 30%;
width: 45%;
padding: 1.7em;
height: 40%;
background: #eee;
margin-top: 25%;
border-radius: 5px;
-webkit-box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5);
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5);
border: 3px solid #666;
}
#challenge-overlay #challengeReady #notify-title, #challenge-overlay #challengeComplete #notify-title {
font-size: 2.5em;
font-weight: bold;
}
#challenge-overlay #challengeReady #message, #challenge-overlay #challengeComplete #message {
font-size: 2em;
font-weight: bold;
display: inline-block;
text-align: center;
font-size: 1.7em;
}
#challenge-overlay #challengeReady #count, #challenge-overlay #challengeComplete #count {
@ -817,13 +846,24 @@ i[class*="ri-"] {
margin-right: 10px;
font-size: 0.75em;
color: #333;
max-width: 250px;
}
#challenge-overlay #challengeReady button#startChallenge, #challenge-overlay #challengeReady button#continue, #challenge-overlay #challengeComplete button#startChallenge, #challenge-overlay #challengeComplete button#continue {
font-size: 1.2em;
width: 100%;
font-size: 1.7em;
font-weight: bold;
padding: 0.3em;
background: #666;
color: goldenrod;
text-transform: uppercase;
letter-spacing: 0.3rem;
}
#challenge-overlay #challengeReady button#startChallenge:active, #challenge-overlay #challengeReady button#continue:active, #challenge-overlay #challengeComplete button#startChallenge:active, #challenge-overlay #challengeComplete button#continue:active {
-webkit-transform: translateY(3px);
transform: translateY(3px);
-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
}
#challenge-overlay #challengeReady button.selected, #challenge-overlay #challengeComplete button.selected {
@ -832,6 +872,7 @@ i[class*="ri-"] {
}
#challenge-overlay #challengeReady #challengeOptions, #challenge-overlay #challengeComplete #challengeOptions {
width: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@ -842,12 +883,13 @@ i[class*="ri-"] {
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
#challenge-overlay #challengeReady #challengeOptions .mode-picker, #challenge-overlay #challengeComplete #challengeOptions .mode-picker {
width: 90%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@ -865,7 +907,7 @@ i[class*="ri-"] {
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#title, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#title {
font-weight: bold;
font-size: 1.08em;
font-size: 1.4em;
height: 100%;
display: -webkit-box;
display: -ms-flexbox;
@ -889,45 +931,68 @@ i[class*="ri-"] {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
height: 100%;
}
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#input, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#input {
margin-left: 10px;
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#buttons button, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#buttons button {
font-size: 1rem;
}
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#info, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#info {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
font-size: 1.2em;
height: 100%;
}
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#input input, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#input input {
width: 50px;
-webkit-appearance: textfield;
-moz-appearance: textfield;
appearance: textfield;
text-align: center;
border-radius: 3px;
border: 1px solid #ddd;
height: 1.3rem;
font-size: 0.75em;
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#input, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#input {
margin-left: 10px;
margin-top: 0.25em;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#input select, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#input select {
height: 1.4rem;
height: auto;
font-size: 1rem;
}
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#input button, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#input button {
width: 20px;
height: 20px;
border-radius: 3px;
#challenge-header {
width: 100%;
padding: 1em;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
}
#challenge-overlay #challengeReady #challengeOptions .mode-picker div#input button i, #challenge-overlay #challengeComplete #challengeOptions .mode-picker div#input button i {
position: relative;
left: -1px;
font-size: 1.1em;
font-weight: bold;
#challenge-header #gameClock {
font-size: 1.3em;
}
#challenge-header #challengeControls button {
border: 0px;
border-radius: 5px;
padding: 0.3em;
font-size: 1.2em;
color: #555;
}
#challenge-header #challengeControls button:hover {
color: maroon;
}
#challengeWord {
@ -1209,12 +1274,29 @@ i[class*="ri-"] {
border-radius: 3px;
}
#morseHistory-textbox {
#morse-history {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: end;
-ms-flex-align: end;
align-items: flex-end;
width: 80%;
max-width: 500px;
}
#morse-history #morseHistory-textbox {
background: #f8f8f8;
border-radius: 5px;
min-height: 4em;
width: 80%;
max-width: 500px;
width: 100%;
padding: 0.5em;
font-family: Courier;
font-size: 1.5rem;
@ -1227,7 +1309,7 @@ i[class*="ri-"] {
flex-wrap: wrap;
}
#morseHistory-textbox span {
#morse-history #morseHistory-textbox span {
margin: 5px;
background: #fdfdfd;
height: 1.5rem;
@ -1347,4 +1429,284 @@ i[class*="ri-"] {
margin-left: 4px;
margin-right: 4px;
}
@media only screen and (max-width: 415px) {
html, body, #root, #main-interface {
width: 100vw;
overflow: hidden;
}
#header {
font-size: 2.1em;
line-height: 1.2em;
height: auto;
}
#playerAndLegend {
padding: 0 !important;
overflow-x: hidden;
width: 100vw;
}
#playerAndLegend #legend {
width: 100vw;
}
#legend {
margin-top: 0px;
background: #eee;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: space-evenly;
-ms-flex-pack: space-evenly;
justify-content: space-evenly;
}
#legend #legend-title {
margin-left: 0em;
font-size: 1.5em;
font-weight: bold;
margin-bottom: 0.3em;
}
#legend #legend-items {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
height: -webkit-fit-content;
height: -moz-fit-content;
height: fit-content;
margin-bottom: 10px;
}
#legend #legend-items .item, #legend #legend-items span {
cursor: pointer;
}
#legend #legend-items .item {
font-family: "Courier", monospace;
font-size: 0.7em;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 20%;
margin: 5px;
padding: 0.3em;
border: 1px solid #ccc;
border-radius: 3px;
-webkit-transition: all 50ms ease-in-out;
transition: all 50ms ease-in-out;
background: #ddd;
border: 0px;
background: #eee;
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
}
#legend #legend-items .item span {
-webkit-transition: all 50ms ease-in-out;
transition: all 50ms ease-in-out;
}
#legend #legend-items .item:active {
-webkit-transform: scale(0.95);
transform: scale(0.95);
border-color: rgba(112, 128, 144, 0.6);
background: #ddd;
}
#legend #legend-items .item:active span:first-child {
background: rgba(112, 128, 144, 0.6);
}
#legend #legend-items .item:hover {
border-color: rgba(112, 128, 144, 0.6);
background: #ddd;
}
#legend #legend-items .item:hover span:first-child {
background: rgba(112, 128, 144, 0.6);
}
#legend #legend-items .item span:first-child {
display: inline-block;
padding: 1px;
width: 1.5em;
background: #d6d6d6;
border-radius: 2px;
font-size: 1.5em;
-webkit-transition: all 75ms ease-in-out;
transition: all 75ms ease-in-out;
}
#legend #legend-items .item span:last-child {
font-weight: bold;
font-size: 1em;
display: inline-block;
padding-left: 5px;
width: 100%;
}
#main-content {
top: 2.5em;
width: 100vw;
}
#main-content .sidebar#left {
min-width: 100vw;
-webkit-transition: all 500ms ease-in-out;
transition: all 500ms ease-in-out;
}
#main-content .sidebar#left.hide {
left: calc(-100vw + 40px);
top: 50px;
overflow-y: hidden;
background: transparent;
-webkit-box-shadow: 0px 0px 0px transparent;
box-shadow: 0px 0px 0px transparent;
}
#main-content .sidebar#left.hide #sidebar-container #sidebar-content #info {
opacity: 0%;
overflow-y: hidden;
}
#main-content .sidebar#left.hide #sidebar-container #info-icon {
background: white;
}
#main-content .sidebar#left.hide #sidebar-container #info-icon::after {
content: ">";
}
#main-content .sidebar#left #sidebar-container {
width: 100%;
padding: 0em;
}
#main-content .sidebar#left #sidebar-container .navbar {
width: 100%;
}
#main-content .sidebar#left #sidebar-container .navbar .nav-item {
width: 25%;
}
#main-content .sidebar#left #sidebar-container .navbar .nav-item#nav-play {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
#main-content .sidebar#left #sidebar-container #info-icon {
display: none;
}
#main-content .sidebar#left #sidebar-container #sidebar-content #info {
width: 100%;
padding: 1em;
}
#main-content #main-interface {
width: 100vw;
left: 0;
}
#main-content #main-interface #morseBufferDisplay {
margin-bottom: 0px;
height: -webkit-fit-content;
height: -moz-fit-content;
height: fit-content;
}
#main-content #main-interface #morseBufferDisplay #overlay {
-webkit-box-shadow: inset 20px 0px 20px -5px #eee;
box-shadow: inset 20px 0px 20px -5px #eee;
}
#main-content #main-interface #morseBufferDisplay #alphanumeric-container {
text-align: center;
max-width: 75%;
display: inline-block;
overflow: hidden;
padding-top: 0px;
}
#main-content #main-interface #morseBufferDisplay #alphanumeric-container #alphanumeric {
height: 4rem;
padding-top: 0.45rem;
font-size: 3rem;
margin-bottom: 0px;
border-radius: 3px;
float: right;
}
#main-content #main-interface * {
z-index: 1000;
}
#main-content #main-interface.expandLeft {
left: 0;
width: 100vw;
}
#main-content #main-interface #morse-history {
width: 95%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: end;
-ms-flex-pack: end;
justify-content: flex-end;
}
#main-content #main-interface #morse-history #morseHistory-textbox {
width: 100%;
overflow-y: scroll;
padding: 5px;
margin: 0px;
min-height: 2.3em;
}
#main-content #main-interface #morse-history #clear-history {
border: 0px;
}
#main-content #main-interface #morseButton {
margin-top: 5px;
}
#main-content #main-interface #mainOptions {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
height: 10em;
width: 100vw;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #title, #main-content #main-interface #mainOptions #options-right .mode-picker #title {
-webkit-box-pack: end;
-ms-flex-pack: end;
justify-content: flex-end;
width: 5em;
font-weight: bold;
font-size: 1em;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #title span#range, #main-content #main-interface #mainOptions #options-right .mode-picker #title span#range {
display: none;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #buttons button, #main-content #main-interface #mainOptions #options-right .mode-picker #buttons button {
margin: 5px;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #input, #main-content #main-interface #mainOptions #options-right .mode-picker #input {
font-size: 0.8em;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #input input, #main-content #main-interface #mainOptions #options-right .mode-picker #input input {
height: 1.1rem;
font-size: 0.8rem;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #input select, #main-content #main-interface #mainOptions #options-right .mode-picker #input select {
height: 1.4rem;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #input button, #main-content #main-interface #mainOptions #options-right .mode-picker #input button {
width: 1.2em;
height: 1.2em;
border-radius: 3px;
font-size: 1em;
}
#main-content #main-interface #mainOptions #options-left .mode-picker #input button i, #main-content #main-interface #mainOptions #options-right .mode-picker #input button i {
left: -7px;
top: -3px;
font-size: 1rem;
}
#main-content #main-interface #mainOptions #options-left .mode-picker button, #main-content #main-interface #mainOptions #options-right .mode-picker button {
font-size: 0.8em;
color: #333;
}
}
/*# sourceMappingURL=App.css.map */

File diff suppressed because one or more lines are too long

View file

@ -113,12 +113,12 @@ function useMorsePlayer() {
timeouts.push(setTimeout(() => {
}, delay))
delay += ditMaxTime*3
delay += ditMaxTime*2
} else if (char === '/') {
timeouts.push(setTimeout(() => {
}, delay))
delay += ditMaxTime*7
delay += ditMaxTime*6
}
}

View file

@ -141,6 +141,7 @@ html, body {
// margin-top: 450px;
// box-shadow: inset 0px 3px 3px rgba(0,0,0,0.3);
.nav-item {
// border: 1px solid black;
padding: 10px;
@ -162,6 +163,9 @@ html, body {
&.selected {
border-color: rgb(80, 128, 144);
}
&#nav-play {
display: none;
}
}
}
@ -220,7 +224,7 @@ html, body {
height: fit-content;
padding: 2.5em;
font-family: $main-font;
font-size: 0.9rem;
font-size: 1.2rem;
line-height: 1.5em;
opacity: 100%;
// overflow-y: scroll;
@ -545,30 +549,44 @@ i[class*="ri-"] {
}
#playMorseInput {
// border: 1px solid #bbb;
background: #ddd;
width: 400px;
height: 10em;
padding: 1em;
// border: 1px solid #bbb;
border-radius: 5px;
display: flex;
flex-direction: column;
align-items: center;
// justify-content: center;
margin-bottom: 45px;
// overflow: hidden;
i:hover {
color: goldenrod;
}
#input input {
padding-left: 3px;
border-radius: 3px;
border: 1px solid #ddd;
height: 1.5rem;
font-size: 0.9em;
width: 70%;
#input {
// border: 1px solid red;
display: flex;
align-items: center;
width: auto;
i {
// background: blue;
font-size: 1.3em;
display: inline-block;
&:hover {
color: goldenrod;
}
}
input {
padding-left: 3px;
border-radius: 3px;
border: 1px solid #ddd;
height: 1.5rem;
font-size: 0.9em;
width: auto;
}
}
#morseTrans {
@ -692,6 +710,9 @@ i[class*="ri-"] {
$button-diameter: 100px;
$button-radius: 50px;
#morseButton {
touch-action: manipulation; // Disable double-tap to zoom on mobile devices
width: $button-diameter;
height: $button-diameter;
margin-top: 30px;
@ -886,19 +907,25 @@ $button-radius: 50px;
justify-content: space-evenly;
align-items: center;
// width: 400px;
padding: 1.5rem;
height: 250px;
// background: $main-bg-color-light;
background: #fefefe;
margin-top: 30%;
width: 45%;
padding: 1.7em;
height: 40%;
background: $main-bg-color-light;
// background: #fefefe;
margin-top: 25%;
border-radius: 5px;
box-shadow: 0px 5px 15px rgba(0,0,0,0.5);
border: 3px solid #666;
#message {
font-size: 2em;
#notify-title {
font-size: 2.5em;
font-weight: bold;
}
#message {
display: inline-block;
text-align: center;
font-size: 1.7em;
}
#count {
font-size: 4.5em;
font-weight: bold;
@ -917,41 +944,55 @@ $button-radius: 50px;
font-size: 0.75em;
color: $main-font-color-light;
max-width: 250px;
// max-width: 250px;
&#startChallenge, &#continue {
font-size: 1.2em;
width: 100%;
font-size: 1.7em;
font-weight: bold;
padding: 0.3em;
background: #666;
color: goldenrod;
text-transform: uppercase;
letter-spacing: 0.3rem;
// &:hover {
// text-shadow: 0px 0px 7px rgba(255,255,255,0.3);
// }
&:active {
transform: translateY(3px);
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
}
}
&.selected {
box-shadow: $main-box-shadow-light-selected;
}
}
#challengeOptions {
// border: 1px solid blue;
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
// border: 1px solid blue;
align-items: center;
.mode-picker {
// border: 1px solid green;
// width: 300px;
width: 90%;
display: flex;
// align-self: flex-start;s
align-content: center;
justify-content: flex-start;
div {
padding: 5px;
height: 2.4em;
}
div#title {
font-weight: bold;
font-size: 1.08em;
// border: 1px solid red;
font-weight: bold;
font-size: 1.4em;
height: 100%;
// width: 40%;
display: flex;
padding-left: 0px;
justify-content: flex-start;
@ -962,36 +1003,61 @@ $button-radius: 50px;
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
button {
font-size: 1rem;
// &:hover {
// color: goldenrod;
// }
// &:active {
// box-shadow: $main-box-shadow-light-selected;
// }
}
}
div#info {
// border: 1px solid black;
display: flex;
align-items: center;
font-size: 1.2em;
height: 100%;
}
div#input {
margin-left: 10px;
margin-top: 0.25em;
display: flex;
align-items: center;
input {
width: 50px;
appearance: textfield;
text-align: center;
border-radius: 3px;
border: 1px solid #ddd;
height: 1.3rem;
font-size: 0.75em;
}
justify-content: center;
select {
height: 1.4rem;
}
button {
width: 20px;
height: 20px;
border-radius: 3px;
// line-height: 10px;
i {
position: relative;
left: -1px;
// top: -2px;
font-size: 1.1em;
font-weight: bold;
}
height: auto;
// padding: 5px;
font-size: 1rem;
}
// input {
// width: 50px;
// appearance: textfield;
// text-align: center;
// border-radius: 3px;
// border: 1px solid #ddd;
// height: 1.3rem;
// font-size: 0.75em;
// }
// button {
// width: 20px;
// height: 20px;
// border-radius: 3px;
// // line-height: 10px;
// i {
// position: relative;
// left: -1px;
// // top: -2px;
// font-size: 1.1em;
// font-weight: bold;
// }
// }
}
}
}
@ -999,6 +1065,29 @@ $button-radius: 50px;
}
#challenge-header {
width: 100%;
padding: 1em;
display: flex;
justify-content: space-between;
#gameClock {
font-size: 1.3em;
}
#challengeControls {
button {
border: 0px;
border-radius: 5px;
padding: 0.3em;
font-size: 1.2em;
color: #555;
&:hover {
color: maroon;
}
}
}
}
#challengeWord {
display: flex;
justify-content: center;
@ -1276,30 +1365,37 @@ $button-radius: 50px;
// font-family: 'Verdana';
// font-size: 1.5em;
// }
#morseHistory-textbox {
// border: 1px solid cyan;
background: #f8f8f8;
border-radius: 5px;
min-height: 4em;
#morse-history {
// border: 1px solid blue;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
width: 80%;
max-width: 500px;
padding: 0.5em;
font-family: Courier;
font-size: 1.5rem;
display: flex;
align-content: flex-start;
flex-wrap: wrap;
span {
margin: 5px;
background: #fdfdfd;
height: 1.5rem;
padding: 4px;
padding-top: 0px;
padding-bottom: 0px;
border-radius: $main-border-radius;
box-shadow: $main-box-shadow-dark;
#morseHistory-textbox {
// border: 1px solid cyan;
background: #f8f8f8;
border-radius: 5px;
min-height: 4em;
width: 100%;
padding: 0.5em;
font-family: Courier;
font-size: 1.5rem;
display: flex;
align-content: flex-start;
flex-wrap: wrap;
span {
margin: 5px;
background: #fdfdfd;
height: 1.5rem;
padding: 4px;
padding-top: 0px;
padding-bottom: 0px;
border-radius: $main-border-radius;
box-shadow: $main-box-shadow-dark;
}
}
}
@ -1424,4 +1520,326 @@ $button-radius: 50px;
margin-right: 4px;
}
}
}
// @media screen and (max-width: 415px) {
@media only screen and (max-width: 415px) {
html, body, #root, #main-interface {
width: 100vw;
overflow: hidden;
}
#header {
font-size: 2.1em;
line-height: 1.2em;
height: auto;
}
#playerAndLegend {
// border: 1px solid blue;
padding: 0 !important;
overflow-x: hidden;
width: 100vw;
#legend {
// margin-left: 2em;
width: 100vw;
}
}
#legend {
margin-top: 0px;
// width: 100%;
// border: 1px solid orange;
background: $main-bg-color-light;
display: flex;
flex-direction: column;
justify-content: space-evenly;
#legend-title {
// border: 1px solid purple;
margin-left: 0em;
font-size: 1.5em;
font-weight: bold;
margin-bottom: 0.3em;
}
#legend-items {
// border: 1px solid blue;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
width: fit-content;
height: fit-content;
margin-bottom: 10px;
.item, span {
cursor: pointer;
}
// &#letters .item {
// width: 17%;
// }
// &#numbers .item {
// width: 18%;
// }
// &#special .item {
// width: 20%;
// }
.item {
font-family: $ditDah-font;
font-size: 0.7em;
// height: 2em;
// height: 2em;
display: flex;
align-items: center;
// justify-content: space-between;
width: 20%;
margin: 5px;
padding: 0.3em;
border: 1px solid #ccc;
border-radius: 3px;
transition: all 50ms ease-in-out;
background: #ddd;
border: 0px;
background: $main-bg-color-light;
box-shadow: $main-box-shadow-light;
span {
transition: all 50ms ease-in-out;
}
&:active {
transform: scale(0.95);
border-color: rgba(112, 128, 144,0.6);
background: #ddd;
span:first-child {
background: rgba(112, 128, 144,0.6);
}
}
&:hover {
border-color: rgba(112, 128, 144,0.6);
background: #ddd;
span:first-child {
background: rgba(112, 128, 144,0.6);
}
}
// button {
// width: 20px;
// height: 20px;
// margin: 4px;
// border: 0px;
// border-radius: 2px;
// box-shadow: $main-box-shadow-light;
// &:active {
// transform: translateY(3px);
// box-shadow: 0px 0px 2px rgba(0,0,0,0.3);
// }
// }
span:first-child {
display: inline-block;
padding: 1px;
width: 1.5em;
background: #d6d6d6;
border-radius: 2px;
font-size: 1.5em;
transition: all 75ms ease-in-out;
}
span:last-child {
// background: #08c;
// font-family: $ditDah-font;
font-weight: bold;
font-size: 1em;
display: inline-block;
padding-left: 5px;
width: 100%;
}
}
}
}
#main-content {
top: 2.5em;
width: 100vw;
.sidebar#left {
min-width: 100vw;
// z-index: -5;
transition: all 500ms ease-in-out;
&.hide {
left: calc(-100vw + 40px);
top: 50px;
overflow-y: hidden;
background: transparent;
box-shadow: 0px 0px 0px transparent;
#sidebar-container {
#sidebar-content #info {
opacity: 0%;
overflow-y: hidden;
}
#info-icon {
// top: calc(100vh - 7em);
background: white;
&::after {
content: ">";
}
}
}
}
#sidebar-container {
width: 100%;
padding: 0em;
.navbar {
width: 100%;
// z-index: 11000;
.nav-item {
width: 25%;
// z-index: 11000;
&#nav-play {
display: flex;
justify-content: center;
}
}
}
#info-icon {
display: none;
}
#sidebar-content {
#info {
width: 100%;
padding: 1em;
}
}
}
}
#main-interface {
width: 100vw;
left: 0;
#morseBufferDisplay {
// background: white;
margin-bottom: 0px;
height: fit-content;
#overlay {
// background: blue;
box-shadow: inset 20px 0px 20px -5px $main-bg-color-light;
}
#alphanumeric-container {
// border: 1px solid red;
text-align: center;
max-width: 75%;
display: inline-block;
overflow: hidden;
padding-top: 0px;
#alphanumeric {
// border: 1px solid blue;
height: 4rem;
padding-top: 0.45rem;
font-size: 3rem;
margin-bottom: 0px;
border-radius: $main-border-radius;
// box-shadow: $main-box-shadow-light;
float: right;
}
}
}
* {
z-index: 1000;
}
&.expandLeft {
left: 0;
width: 100vw;
}
#morse-history {
// border: 1px solid blue;
width: 95%;
display: flex;
justify-content: flex-end;
#morseHistory-textbox {
// border: 1px solid blue;
width: 100%;
overflow-y: scroll;
padding: 5px;
margin: 0px;
min-height: 2.3em;
}
#clear-history {
border: 0px;
}
}
#morseButton {
margin-top: 5px;
}
#mainOptions {
// border: 1px solid red;
flex-direction: column;
height: 10em;
width: 100vw;
#options-left, #options-right {
.mode-picker {
#title {
// border: 1px solid red;
justify-content: flex-end;
width: 5em;
font-weight: bold;
font-size: 1em;
span#range {
display: none;
}
}
#buttons {
button {
margin: 5px;
}
}
#input {
font-size: 0.8em;
input {
height: 1.1rem;
font-size: 0.8rem;
}
select {
height: 1.4rem;
}
button {
width: 1.2em;
height: 1.2em;
border-radius: 3px;
font-size: 1em;
i {
left: -7px;
top: -3px;
font-size: 1rem;
}
}
}
button {
font-size: 0.8em;
color: $main-font-color-light;
}
}
}
}
}
}
}