Completed Wave 3 features:
All checks were successful
Pre-release on non-main branches / prerelease (push) Successful in 27s

- [X] New User Interface (Responsive)
- [X] Two's Compliment Simulator
- [X] Extended Binary Simulator (Custom bit sizes)
- [X] Unified Binary Simulator (Unsigned & Two's Completment combined)
- [X] Extended Hexadecimal Simulator
- [X] Unified Hexadecimal Simulator (For GCSE & A Level Specification)
- [X] Enhanced Gate Simulator (Truth Table Creator)
- [X] Compound Gate Simulator
- [ ] Computer Components Simulator

Signed-off-by: Alexander Lyall <alex@adcm.uk>
This commit is contained in:
2026-03-01 16:22:58 +00:00
parent 4facee954c
commit ffab71cfcc
57 changed files with 3602 additions and 3488 deletions

View File

@@ -1,24 +1,27 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import "../styles/binary.css";
---
<BaseLayout title="Binary Simulator">
<button id="toolboxToggle" class="toolboxToggle" type="button" aria-expanded="true">
<span class="toolboxIcon" aria-hidden="true">🧰</span>
<span class="toolboxLabel">TOOLBOX</span>
</button>
<BaseLayout title="Binary Simulator | Computing:Box">
<div class="binaryPage" id="binaryPage">
<button
id="toolboxToggle"
class="toolboxToggle"
type="button"
aria-expanded="true"
>
<span class="toolboxIcon" aria-hidden="true">🧰</span>
<span class="toolboxText">TOOLBOX</span>
</button>
<main class="wrap">
<section class="topGrid">
<!-- LEFT -->
<div>
<div class="leftCol">
<div class="readout">
<div class="label">Denary</div>
<div id="denaryNumber" class="num denaryValue">0</div>
<div class="label">Binary</div>
<div id="binaryNumber" class="num binaryValue">0000 0000</div>
<div id="binaryNumber" class="num binaryValue">00000000</div>
</div>
<div class="divider"></div>
@@ -28,9 +31,7 @@ import "../styles/binary.css";
</section>
</div>
<!-- RIGHT TOOLBOX -->
<aside id="toolbox" class="panelCol" aria-label="Toolbox">
<!-- SETTINGS -->
<aside id="toolboxPanel" class="panelCol" aria-label="Toolbox">
<div class="card">
<div class="cardTitle">Settings</div>
@@ -40,7 +41,7 @@ import "../styles/binary.css";
<input id="modeToggle" type="checkbox" />
<span class="slider"></span>
</label>
<div class="toggleLabel" id="lblTwos">Two&rsquo;s complement</div>
<div class="toggleLabel" id="lblTwos">Two's complement</div>
</div>
<div class="hint" id="modeHint">
@@ -51,7 +52,6 @@ import "../styles/binary.css";
<div class="subTitle">Bit width</div>
<div class="bitWidthRow">
<button class="miniBtn" id="btnBitsDown" type="button" aria-label="Decrease bits"></button>
<div class="bitInputWrap">
<div class="bitInputLabel">Bits</div>
<input
@@ -66,47 +66,36 @@ import "../styles/binary.css";
aria-label="Number of bits"
/>
</div>
<button class="miniBtn" id="btnBitsUp" type="button" aria-label="Increase bits">+</button>
</div>
</div>
</div>
<!-- CUSTOM -->
<div class="card">
<div class="cardTitle">Custom</div>
<div class="twoBtnRow">
<button class="btn btnAccent" id="btnCustomBinary" type="button">Custom Binary</button>
<button class="btn btnAccent" id="btnCustomDenary" type="button">Custom Denary</button>
<div class="cardTitle">Custom Number</div>
<div class="controlsRow">
<button class="btn btnAccent btnHalf" id="btnCustomBinary" type="button">Custom Binary</button>
<button class="btn btnAccent btnHalf" id="btnCustomDenary" type="button">Custom Denary</button>
</div>
<button class="toolBtn toolWide toolRandom" id="btnRandom" type="button">
Random
</button>
<button class="btn btnWide" id="btnRandom" type="button">Random</button>
<div class="hint">Random runs briefly then stops automatically.</div>
</div>
<!-- TOOLS -->
<div class="card">
<div class="cardTitle">Tools</div>
<div class="toolsTopRow">
<button class="toolBtn toolArrow toolDown" id="btnDec" type="button" aria-label="Decrement"></button>
<button class="toolBtn toolArrow toolUp" id="btnInc" type="button" aria-label="Increment">▲</button>
<div class="toolRowCentered">
<button class="toolBtn toolSpin toolDec" id="btnDec" type="button" aria-label="Decrement">▼</button>
<button class="toolBtn toolSpin toolInc" id="btnInc" type="button" aria-label="Increment"></button>
</div>
<div class="twoBtnRow">
<button class="btn" id="btnShiftLeft" type="button">Left Shift</button>
<button class="btn" id="btnShiftRight" type="button">Right Shift</button>
<div class="toolRow2">
<button class="btn btnHalf" id="btnShiftLeft" type="button">Left Shift</button>
<button class="btn btnHalf" id="btnShiftRight" type="button">Right Shift</button>
</div>
<button class="toolBtn toolWide toolReset" id="btnClear" type="button">Reset</button>
<button class="btn btnReset btnWide" id="btnClear" type="button">Reset</button>
</div>
</aside>
</section>
</main>
</div>
<script type="module" src="/src/scripts/binary.js"></script>
</BaseLayout>
<script src="../scripts/binary.js"></script>
</BaseLayout>

View File

@@ -0,0 +1,99 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
---
<BaseLayout title="Hex Colours Simulator | Computing:Box">
<div class="binaryPage" id="colorPage">
<button
id="toolboxToggle"
class="toolboxToggle"
type="button"
aria-expanded="true"
>
<span class="toolboxIcon" aria-hidden="true">🧰</span>
<span class="toolboxText">TOOLBOX</span>
</button>
<section class="topGrid">
<div class="leftCol">
<div class="readoutContainer">
<div class="readout">
<div class="readoutBlock">
<div class="label">Denary (R, G, B)</div>
<div id="denaryNumber" class="num denaryValue">
<span class="text-red">0</span>
<span class="text-green">0</span>
<span class="text-blue">0</span>
</div>
</div>
<div class="readoutBlock">
<div class="label">Hexadecimal</div>
<div id="hexNumber" class="num hexValue">
<span class="text-red"><span style="color:var(--muted)">#</span>00</span>
<span class="text-green">00</span>
<span class="text-blue">00</span>
</div>
</div>
<div class="readoutBlock">
<div class="label">Binary</div>
<div id="binaryNumber" class="num binaryValue">
<span class="text-red">00000000</span>
<span class="text-green">00000000</span>
<span class="text-blue">00000000</span>
</div>
</div>
</div>
<div class="colorPreviewSide">
<div class="colorBoxWrap">
<div id="previewColor" class="colorBox"></div>
<div class="colorBoxLabel">Colour</div>
</div>
<div class="colorBoxWrap">
<div id="previewInverted" class="colorBox"></div>
<div class="colorBoxLabel">Inverted</div>
</div>
</div>
</div>
<div class="divider"></div>
<section class="bitsWrap" aria-label="Hex Colour Cards">
<div class="colorGroupWrap" id="colorGrid"></div>
</section>
</div>
<aside id="toolboxPanel" class="panelCol" aria-label="Toolbox">
<div class="card">
<div class="cardTitle">Info</div>
<div class="hint" style="margin-top: 0;">
Hexadecimal colours are made of 3 channels (Red, Green, Blue). Each channel is an 8-bit value ranging from 00 to FF (0 to 255).
</div>
</div>
<div class="card">
<div class="cardTitle">Colour Tools</div>
<div class="controlsRow">
<button class="btn btnAccent btnHalf" id="btnCustomHex" type="button">Custom Hex</button>
<button class="btn btnAccent btnHalf" id="btnCustomRGB" type="button">Custom RGB</button>
</div>
<div class="controlsRow">
<button class="btn btnAccent btnWide" id="btnInvert" type="button">Invert Colour</button>
</div>
<button class="btn btnWide" id="btnRandom" type="button">Random Colour</button>
<div class="hint">Random runs briefly then stops automatically.</div>
</div>
<div class="card">
<div class="cardTitle">Tools</div>
<button class="btn btnReset btnWide" id="btnClear" type="button">Reset</button>
</div>
</aside>
</section>
</div>
<script src="../scripts/hexColours.js"></script>
</BaseLayout>

View File

@@ -1,8 +1,94 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import HexSimulator from "../components/simulators/HexSimulator.astro";
---
<BaseLayout title="Hexadecimal | Computing:Box">
<HexSimulator />
</BaseLayout>
<BaseLayout title="Hexadecimal Simulator | Computing:Box">
<div class="binaryPage" id="hexPage">
<button
id="toolboxToggle"
class="toolboxToggle"
type="button"
aria-expanded="true"
>
<span class="toolboxIcon" aria-hidden="true">🧰</span>
<span class="toolboxText">TOOLBOX</span>
</button>
<section class="topGrid">
<div class="leftCol">
<div class="readout">
<div class="label">Denary</div>
<div id="denaryNumber" class="num denaryValue">0</div>
<div class="label">Hexadecimal</div>
<div id="hexNumber" class="num hexValue">00</div>
<div class="label">Binary</div>
<div id="binaryNumber" class="num binaryValue">00000000</div>
</div>
<div class="divider"></div>
<section class="bitsWrap" aria-label="Hexadecimal sliders">
<div class="hexGrid" id="hexGrid"></div>
</section>
</div>
<aside id="toolboxPanel" class="panelCol" aria-label="Toolbox">
<div class="card">
<div class="cardTitle">Settings</div>
<div class="hint" style="margin-top: 0; margin-bottom: 14px;">
Hexadecimal represents numbers using base 16 (0-9, A-F).
</div>
<div class="subCard">
<div class="subTitle">Digit width</div>
<div class="bitWidthRow">
<button class="miniBtn" id="btnDigitsDown" type="button" aria-label="Decrease digits"></button>
<div class="bitInputWrap">
<div class="bitInputLabel">Digits</div>
<input
id="digitsInput"
class="bitInput"
type="number"
inputmode="numeric"
min="1"
max="16"
step="1"
value="2"
aria-label="Number of hex digits"
/>
</div>
<button class="miniBtn" id="btnDigitsUp" type="button" aria-label="Increase digits">+</button>
</div>
</div>
</div>
<div class="card">
<div class="cardTitle">Custom Number</div>
<div class="controlsRow">
<button class="btn btnAccent btnHalf" id="btnCustomHex" type="button">Custom Hex</button>
<button class="btn btnAccent btnHalf" id="btnCustomDenary" type="button">Custom Denary</button>
</div>
<div class="controlsRow">
<button class="btn btnAccent btnWide" id="btnCustomBinary" type="button">Custom Binary</button>
</div>
<button class="btn btnWide" id="btnRandom" type="button">Random</button>
<div class="hint">Random runs briefly then stops automatically.</div>
</div>
<div class="card">
<div class="cardTitle">Tools</div>
<div class="toolRowCentered">
<button class="toolBtn toolSpin toolDec" id="btnDec" type="button" aria-label="Decrement">▼</button>
<button class="toolBtn toolSpin toolInc" id="btnInc" type="button" aria-label="Increment">▲</button>
</div>
<button class="btn btnReset btnWide" id="btnClear" type="button">Reset</button>
</div>
</aside>
</section>
</div>
<script src="../scripts/hexadecimal.js"></script>
</BaseLayout>

View File

@@ -0,0 +1,63 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import "../styles/logic-gates.css";
---
<BaseLayout title="Logic Gate Builder | Computing:Box">
<div class="binaryPage" id="logicPage">
<button id="toolboxToggle" class="toolboxToggle" type="button" aria-expanded="true">
<span class="toolboxIcon" aria-hidden="true">🧰</span>
<span class="toolboxText">TOOLBOX</span>
</button>
<section class="topGrid" style="display:flex; flex-direction:column; height: 100%;">
<div class="readout">
<div class="readoutBlock">
<div class="label" style="margin-bottom: 8px;">Interactive Simulator</div>
<div class="num denaryValue" style="font-size: 56px; line-height: 1;">LOGIC GATES</div>
</div>
<div style="color: var(--muted); font-size: 15px; font-family: var(--ui-font); text-align: center; max-width: 800px; margin-top: 12px;">
Drag items from the toolbox to the board. Drag from output ports to input ports to wire. Click a wire or node and press <kbd style="background:rgba(255,255,255,0.1); padding:2px 6px; border-radius:4px; font-family:var(--ui-font);">Delete</kbd> to remove it.
</div>
</div>
<div class="divider"></div>
<div class="lg-workspace" id="workspace">
<svg class="lg-svg-layer" id="wireLayer"></svg>
</div>
</section>
<aside id="toolboxPanel" class="panelCol" aria-label="Toolbox">
<div class="card">
<div class="cardTitle">Components</div>
<div class="tb-icon-grid" id="toolboxGrid">
</div>
</div>
<div class="card">
<div class="cardTitle">Live Truth Table</div>
<details open>
<summary class="tt-summary">Show / Hide Table</summary>
<div style="font-family: var(--ui-font); font-size: 12px; color: var(--muted); margin-bottom: 12px;">Auto-generates based on current wiring. (Max 6 inputs)</div>
<div class="tt-table-wrap" id="truthTableContainer">
</div>
</details>
</div>
<div class="card">
<div class="cardTitle">Tools</div>
<button class="btn btnReset btnWide" id="btnClearBoard" type="button" style="margin-bottom:0;">Clear Board</button>
</div>
</aside>
</div>
<script src="../scripts/logicGates.js"></script>
</BaseLayout>