You've already forked computing-box
feat(app): update branding, improve button animations, and complete PC Components simulator
- Replace logo with updated Computing:Box branding assets - Fix animations for Random and Reset buttons for smoother interaction - Implement full first version of the PC Components simulator - Update built output to reflect new assets, layout, and functionality - Remove legacy assets and outdated build files Signed-off-by: Alexander Lyall <alex@adcm.uk>
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
(()=>{const d=document.getElementById("bitsGrid"),h=document.getElementById("denaryNumber"),M=document.getElementById("binaryNumber"),f=document.getElementById("bitsInput"),m=document.getElementById("modeToggle"),E=document.getElementById("modeHint"),T=document.getElementById("lblUnsigned"),k=document.getElementById("lblTwos"),H=document.getElementById("btnCustomBinary"),G=document.getElementById("btnCustomDenary"),P=document.getElementById("btnShiftLeft"),V=document.getElementById("btnShiftRight"),q=document.getElementById("btnDec"),Z=document.getElementById("btnInc"),z=document.getElementById("btnClear"),I=document.getElementById("btnRandom"),O=document.getElementById("btnBitsUp"),W=document.getElementById("btnBitsDown"),R=document.getElementById("toolboxToggle"),w=document.getElementById("binaryPage");let i=b(Number(f?.value??8),1,64),s=new Array(i).fill(!1),u=null;function b(t,n,e){return Number.isFinite(t)?Math.max(n,Math.min(e,Math.trunc(t))):n}function l(){return!!m?.checked}function a(t){return 1n<<BigInt(t)}function y(t){return a(t)}function $(t){return a(t)-1n}function B(t){return-a(t-1)}function p(t){return a(t-1)-1n}function v(){let t=0n;for(let n=0;n<i;n++)s[n]&&(t+=a(n));return t}function g(t){const n=y(i),e=(t%n+n)%n;for(let o=0;o<i;o++)s[o]=(e>>BigInt(o)&1n)===1n}function L(){const t=v();return s[i-1]===!0?t-a(i):t}function x(t){const n=a(i);let e=t;e=(e%n+n)%n,g(e)}function j(){let t="";for(let n=i-1;n>=0;n--){t+=s[n]?"1":"0";const e=i-n;n!==0&&e%4===0&&(t+=" ")}return t.trimEnd()}function D(){E&&(l()?E.textContent="Tip: In two's complement, the left-most bit (MSB) represents a negative value.":E.textContent="Tip: In unsigned binary, all bits represent positive values.")}function A(){if(!d)return;const t=d.parentElement;if(!t)return;const n=t.getBoundingClientRect().width,o=b(Math.floor(n/100),1,12);d.style.setProperty("--cols",String(Math.min(o,i)))}function C(t){i=b(t,1,64),f&&(f.value=String(i));const n=s.slice();s=new Array(i).fill(!1);for(let e=0;e<Math.min(n.length,i);e++)s[e]=n[e];d.innerHTML="",d.classList.toggle("bitsFew",i<8);for(let e=i-1;e>=0;e--){const o=document.createElement("div");o.className="bit",o.innerHTML=`
|
||||
<div class="bulb" id="bulb-${e}" aria-hidden="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 2.25a6.75 6.75 0 0 0-6.75 6.75c0 2.537 1.393 4.75 3.493 5.922l.507.282v1.546h5.5v-1.546l.507-.282A6.75 6.75 0 0 0 12 2.25Zm-2.25 16.5v.75a2.25 2.25 0 0 0 4.5 0v-.75h-4.5Z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="bitVal" id="bitLabel-${e}"></div>
|
||||
<label class="switch" aria-label="Toggle bit ${e}">
|
||||
<input type="checkbox" data-index="${e}">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
`,d.appendChild(o)}d.querySelectorAll('input[type="checkbox"]').forEach(e=>{e.addEventListener("change",()=>{const o=Number(e.dataset.index);s[o]=e.checked,r()})}),A(),r()}function J(){for(let t=0;t<i;t++){const n=document.getElementById(`bitLabel-${t}`);if(!n)continue;let e;l()&&t===i-1?e=`-${a(i-1).toString()}`:e=a(t).toString(),n.textContent=e,n.style.setProperty("--len",e.length)}}function K(){d.querySelectorAll('input[type="checkbox"]').forEach(t=>{const n=Number(t.dataset.index);t.checked=!!s[n]})}function Q(){for(let t=0;t<i;t++){const n=document.getElementById(`bulb-${t}`);n&&n.classList.toggle("on",s[t]===!0)}}function X(){!h||!M||(l()?h.textContent=L().toString():h.textContent=v().toString(),M.textContent=j())}function r(){D(),T&&k&&(T.classList.toggle("activeMode",!l()),k.classList.toggle("activeMode",l())),J(),K(),Q(),X()}function Y(t){const n=String(t??"").replace(/\s+/g,"");if(!/^[01]+$/.test(n))return!1;const e=n.slice(-i).padStart(i,"0");for(let o=0;o<i;o++){const c=e[e.length-1-o];s[o]=c==="1"}return r(),!0}function _(t){const n=String(t??"").trim();if(!n)return!1;let e;try{if(!/^-?\d+$/.test(n))return!1;e=BigInt(n)}catch{return!1}if(l()){const o=B(i),c=p(i);if(e<o||e>c)return!1;x(e)}else{if(e<0n||e>$(i))return!1;g(e)}return r(),!0}function tt(){for(let t=i-1;t>=1;t--)s[t]=s[t-1];s[0]=!1,r()}function nt(){const t=s[i-1];for(let n=0;n<i-1;n++)s[n]=s[n+1];s[i-1]=l()?t:!1,r()}function et(){s=[],m&&(m.checked=!1),C(8)}function it(){if(l()){const t=B(i),n=p(i);let e=L()+1n;e>n&&(e=t),x(e)}else{const t=y(i);g((v()+1n)%t)}r()}function ot(){if(l()){const t=B(i),n=p(i);let e=L()-1n;e<t&&(e=n),x(e)}else{const t=y(i);g((v()-1n+t)%t)}r()}function st(t){if(t<=0n)return 0n;const n=t.toString(2).length,e=Math.ceil(n/8);for(;;){const o=new Uint8Array(e);crypto.getRandomValues(o);let c=0n;for(const ct of o)c=c<<8n|BigInt(ct);const U=BigInt(e*8-n);if(U>0n&&(c=c>>U),c<t)return c}}function lt(){const t=y(i),n=st(t);g(n),r()}function N(t){I&&I.classList.toggle("btnRandomRunning",!!t)}function rt(){u&&(clearInterval(u),u=null),N(!0);const t=Date.now(),n=1125;u=setInterval(()=>{lt(),Date.now()-t>=n&&(clearInterval(u),u=null,N(!1))},80)}function S(t){const n=b(t,1,64);C(n)}function F(t){if(!w)return;w.classList.toggle("toolboxCollapsed",!!t);const n=!t;R?.setAttribute("aria-expanded",n?"true":"false")}m?.addEventListener("change",r),H?.addEventListener("click",()=>{const t=prompt(`Enter binary (spaces allowed). Current width: ${i} bits`);t!==null&&(Y(t)||alert("Invalid binary"))}),G?.addEventListener("click",()=>{const t=prompt(l()?`Enter denary (${B(i).toString()} to ${p(i).toString()}):`:`Enter denary (0 to ${$(i).toString()}):`);t!==null&&(_(t)||alert("Invalid denary for current mode/bit width"))}),P?.addEventListener("click",tt),V?.addEventListener("click",nt),Z?.addEventListener("click",it),q?.addEventListener("click",ot),z?.addEventListener("click",et),I?.addEventListener("click",rt),O?.addEventListener("click",()=>S(i+1)),W?.addEventListener("click",()=>S(i-1)),f?.addEventListener("change",()=>S(Number(f.value))),R?.addEventListener("click",()=>{const t=w?.classList.contains("toolboxCollapsed");F(!t)}),window.addEventListener("resize",()=>{A()}),D(),C(i),F(!1)})();
|
||||
81
dist/binary/index.html
vendored
81
dist/binary/index.html
vendored
@@ -13,8 +13,81 @@
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
</script><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;800;900&display=swap" rel="stylesheet"><link rel="icon" type="image/x-icon" href="/images/favicon.ico"><link rel="stylesheet" href="/_astro/BaseLayout.DM-NXsTj.css">
|
||||
<link rel="stylesheet" href="/_astro/number-simulators.9peKc0z2.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo.webp" alt="Computing:Box logo"> <span class="brandName">Computing:Box</span> </a> <nav class="navLinks" aria-label="Site navigation"> <a href="/about">About</a> <a href="/binary">Binary</a> <a href="/hexadecimal">Hexadecimal</a> <a href="/hex-colours">Hex Colours</a> <a href="/logic-gates">Logic Gates</a> <a href="/pc-builder">PC Components</a> </nav> </div> </header> <main class="pageWrap"> <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> <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">Binary</div> <div id="binaryNumber" class="num binaryValue">00000000</div> </div> <div class="divider"></div> <section class="bitsWrap" aria-label="Bit switches"> <div class="bitsGrid" id="bitsGrid"></div> </section> </div> <aside id="toolboxPanel" class="panelCol" aria-label="Toolbox"> <div class="card"> <div class="cardTitle">Settings</div> <div class="toggleRow"> <div class="toggleLabel" id="lblUnsigned">Unsigned</div> <label class="switch" aria-label="Toggle mode"> <input id="modeToggle" type="checkbox"> <span class="slider"></span> </label> <div class="toggleLabel" id="lblTwos">Two's complement</div> </div> <div class="hint" id="modeHint">
|
||||
</script><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;800;900&display=swap" rel="stylesheet"><link rel="icon" type="image/x-icon" href="/images/favicon.ico"><link rel="stylesheet" href="/_astro/BaseLayout.B8W3SO34.css">
|
||||
<link rel="stylesheet" href="/_astro/number-simulators.6IzVRJBu.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo-small.webp" alt="Computing:Box logo"> <span class="brandName">Computing:Box</span> </a> <nav class="navLinks" aria-label="Site navigation"> <a href="/">Home</a> <a href="/about">About</a> <a href="/binary">Binary</a> <a href="/hexadecimal">Hexadecimal</a> <a href="/hex-colours">Hex Colours</a> <a href="/logic-gates">Logic Gates</a> <a href="/pc-builder">PC Components</a> </nav> </div> </header> <main class="pageWrap"> <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> <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">Binary</div> <div id="binaryNumber" class="num binaryValue">00000000</div> </div> <div class="divider"></div> <section class="bitsWrap" aria-label="Bit switches"> <div class="bitsGrid" id="bitsGrid"></div> </section> </div> <aside id="toolboxPanel" class="panelCol" aria-label="Toolbox"> <div class="card"> <div class="cardTitle">Settings</div> <div class="toggleRow"> <div class="toggleLabel" id="lblUnsigned">Unsigned</div> <label class="switch" aria-label="Toggle mode"> <input id="modeToggle" type="checkbox"> <span class="slider"></span> </label> <div class="toggleLabel" id="lblTwos">Two's complement</div> </div> <div class="hint" id="modeHint">
|
||||
Tip: In unsigned binary, all bits represent positive values.
|
||||
</div> <div class="subCard"> <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 id="bitsInput" class="bitInput" type="number" inputmode="numeric" min="1" max="64" step="1" value="8" aria-label="Number of bits"> </div> <button class="miniBtn" id="btnBitsUp" type="button" aria-label="Increase bits">+</button> </div> </div> </div> <div class="card"> <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="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> <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="btn btnReset btnWide" id="btnClear" type="button">Reset</button> </div> </aside> </section> </div> <script type="module" src="/_astro/binary.astro_astro_type_script_index_0_lang.C_c_A3x5.js"></script> </main> <footer class="siteFooter"> <div class="footerInner"> <div style="margin-top: 5px; display: flex; justify-content: center;"> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> <a href="/legal-code" style="margin-left: 32px; color: var(--muted); text-decoration: underline;">Legal Code</a> </div> <div>Computer Science Concept Simulators</div> <div> Version:
|
||||
<a href="#" target="_blank" rel="noopener noreferrer">dev</a> • © 2026 Computing:Box • Created with ♥ by Mr A Lyall</div> </div> </footer> </body></html>
|
||||
</div> <div class="subCard"> <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 id="bitsInput" class="bitInput" type="number" inputmode="numeric" min="1" max="64" step="1" value="8" aria-label="Number of bits"> </div> <button class="miniBtn" id="btnBitsUp" type="button" aria-label="Increase bits">+</button> </div> </div> </div> <div class="card"> <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="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> <div class="controlsRow"> <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="btn btnReset btnWide" id="btnClear" type="button">Reset</button> </div> </aside> </section> </div> <script type="module" src="/_astro/binary.astro_astro_type_script_index_0_lang.CNqn-vvz.js"></script> </main> <footer class="siteFooter"> <div class="footerInner"> <div style="margin-top: 5px; display: flex; justify-content: center;"> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> <a href="/legal-code" style="margin-left: 32px; color: var(--muted); text-decoration: underline;">Legal Code</a> </div> <div>Computer Science Concept Simulators</div> <div> Version:
|
||||
<a href="#" target="_blank" rel="noopener noreferrer">dev</a> • © 2026 Computing:Box • Created with ♥ by Mr A Lyall</div> </div> </footer> <script>
|
||||
function setupToolboxAccordions() {
|
||||
// Look for cards inside ANY of the three toolboxes!
|
||||
const cards = document.querySelectorAll('.panelCol .card, .pb-toolbox .card, .lg-toolbox .card');
|
||||
if (!cards.length) return;
|
||||
|
||||
// Your primary cards for each page
|
||||
const primaryCardNames = ['settings', 'info', 'components', 'system diagnostics'];
|
||||
|
||||
cards.forEach(card => {
|
||||
const titleEl = card.querySelector('.cardTitle');
|
||||
if (!titleEl) return;
|
||||
|
||||
const titleText = titleEl.textContent.trim().toLowerCase();
|
||||
const isPrimary = primaryCardNames.includes(titleText);
|
||||
|
||||
// 1. DYNAMICALLY WRAP THE CONTENT
|
||||
if (!card.querySelector('.cardBody')) {
|
||||
const body = document.createElement('div');
|
||||
body.className = 'cardBody';
|
||||
const inner = document.createElement('div');
|
||||
inner.className = 'cardBodyInner';
|
||||
body.appendChild(inner);
|
||||
|
||||
Array.from(card.childNodes).forEach(node => {
|
||||
if (node !== titleEl) {
|
||||
inner.appendChild(node);
|
||||
}
|
||||
});
|
||||
card.appendChild(body);
|
||||
}
|
||||
|
||||
// 2. APPLY DEFAULT STATE
|
||||
if (isPrimary) {
|
||||
card.classList.remove('collapsed');
|
||||
} else {
|
||||
card.classList.add('collapsed');
|
||||
}
|
||||
|
||||
// 3. CLICK LISTENERS
|
||||
if (card.dataset.accordionInit) return;
|
||||
card.dataset.accordionInit = "true";
|
||||
|
||||
titleEl.addEventListener('click', () => {
|
||||
const isCollapsing = !card.classList.contains('collapsed');
|
||||
|
||||
if (isCollapsing) {
|
||||
card.classList.add('collapsed');
|
||||
} else {
|
||||
if (isPrimary) {
|
||||
cards.forEach(c => {
|
||||
// Only close cards that share the same parent toolbox
|
||||
if (c !== card && c.closest(card.parentElement.tagName) === card.closest(card.parentElement.tagName)) {
|
||||
c.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cards.forEach(c => {
|
||||
if (c.closest(card.parentElement.tagName) !== card.closest(card.parentElement.tagName)) return;
|
||||
const cTitle = c.querySelector('.cardTitle')?.textContent.trim().toLowerCase() || '';
|
||||
if (primaryCardNames.includes(cTitle)) {
|
||||
c.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
card.classList.remove('collapsed');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setupToolboxAccordions();
|
||||
document.addEventListener('astro:page-load', setupToolboxAccordions);
|
||||
</script> </body> </html>
|
||||
9
dist/favicon.svg
vendored
9
dist/favicon.svg
vendored
@@ -1,9 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 749 B |
79
dist/hexadecimal/index.html
vendored
79
dist/hexadecimal/index.html
vendored
@@ -13,8 +13,81 @@
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
</script><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;800;900&display=swap" rel="stylesheet"><link rel="icon" type="image/x-icon" href="/images/favicon.ico"><link rel="stylesheet" href="/_astro/BaseLayout.DM-NXsTj.css">
|
||||
<link rel="stylesheet" href="/_astro/number-simulators.9peKc0z2.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo.webp" alt="Computing:Box logo"> <span class="brandName">Computing:Box</span> </a> <nav class="navLinks" aria-label="Site navigation"> <a href="/about">About</a> <a href="/binary">Binary</a> <a href="/hexadecimal">Hexadecimal</a> <a href="/hex-colours">Hex Colours</a> <a href="/logic-gates">Logic Gates</a> <a href="/pc-builder">PC Components</a> </nav> </div> </header> <main class="pageWrap"> <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;">
|
||||
</script><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;800;900&display=swap" rel="stylesheet"><link rel="icon" type="image/x-icon" href="/images/favicon.ico"><link rel="stylesheet" href="/_astro/BaseLayout.B8W3SO34.css">
|
||||
<link rel="stylesheet" href="/_astro/number-simulators.6IzVRJBu.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo-small.webp" alt="Computing:Box logo"> <span class="brandName">Computing:Box</span> </a> <nav class="navLinks" aria-label="Site navigation"> <a href="/">Home</a> <a href="/about">About</a> <a href="/binary">Binary</a> <a href="/hexadecimal">Hexadecimal</a> <a href="/hex-colours">Hex Colours</a> <a href="/logic-gates">Logic Gates</a> <a href="/pc-builder">PC Components</a> </nav> </div> </header> <main class="pageWrap"> <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 type="module" src="/_astro/hexadecimal.astro_astro_type_script_index_0_lang.C4Wx7oaX.js"></script> </main> <footer class="siteFooter"> <div class="footerInner"> <div style="margin-top: 5px; display: flex; justify-content: center;"> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> <a href="/legal-code" style="margin-left: 32px; color: var(--muted); text-decoration: underline;">Legal Code</a> </div> <div>Computer Science Concept Simulators</div> <div> Version:
|
||||
<a href="#" target="_blank" rel="noopener noreferrer">dev</a> • © 2026 Computing:Box • Created with ♥ by Mr A Lyall</div> </div> </footer> </body></html>
|
||||
<a href="#" target="_blank" rel="noopener noreferrer">dev</a> • © 2026 Computing:Box • Created with ♥ by Mr A Lyall</div> </div> </footer> <script>
|
||||
function setupToolboxAccordions() {
|
||||
// Look for cards inside ANY of the three toolboxes!
|
||||
const cards = document.querySelectorAll('.panelCol .card, .pb-toolbox .card, .lg-toolbox .card');
|
||||
if (!cards.length) return;
|
||||
|
||||
// Your primary cards for each page
|
||||
const primaryCardNames = ['settings', 'info', 'components', 'system diagnostics'];
|
||||
|
||||
cards.forEach(card => {
|
||||
const titleEl = card.querySelector('.cardTitle');
|
||||
if (!titleEl) return;
|
||||
|
||||
const titleText = titleEl.textContent.trim().toLowerCase();
|
||||
const isPrimary = primaryCardNames.includes(titleText);
|
||||
|
||||
// 1. DYNAMICALLY WRAP THE CONTENT
|
||||
if (!card.querySelector('.cardBody')) {
|
||||
const body = document.createElement('div');
|
||||
body.className = 'cardBody';
|
||||
const inner = document.createElement('div');
|
||||
inner.className = 'cardBodyInner';
|
||||
body.appendChild(inner);
|
||||
|
||||
Array.from(card.childNodes).forEach(node => {
|
||||
if (node !== titleEl) {
|
||||
inner.appendChild(node);
|
||||
}
|
||||
});
|
||||
card.appendChild(body);
|
||||
}
|
||||
|
||||
// 2. APPLY DEFAULT STATE
|
||||
if (isPrimary) {
|
||||
card.classList.remove('collapsed');
|
||||
} else {
|
||||
card.classList.add('collapsed');
|
||||
}
|
||||
|
||||
// 3. CLICK LISTENERS
|
||||
if (card.dataset.accordionInit) return;
|
||||
card.dataset.accordionInit = "true";
|
||||
|
||||
titleEl.addEventListener('click', () => {
|
||||
const isCollapsing = !card.classList.contains('collapsed');
|
||||
|
||||
if (isCollapsing) {
|
||||
card.classList.add('collapsed');
|
||||
} else {
|
||||
if (isPrimary) {
|
||||
cards.forEach(c => {
|
||||
// Only close cards that share the same parent toolbox
|
||||
if (c !== card && c.closest(card.parentElement.tagName) === card.closest(card.parentElement.tagName)) {
|
||||
c.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cards.forEach(c => {
|
||||
if (c.closest(card.parentElement.tagName) !== card.closest(card.parentElement.tagName)) return;
|
||||
const cTitle = c.querySelector('.cardTitle')?.textContent.trim().toLowerCase() || '';
|
||||
if (primaryCardNames.includes(cTitle)) {
|
||||
c.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
card.classList.remove('collapsed');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setupToolboxAccordions();
|
||||
document.addEventListener('astro:page-load', setupToolboxAccordions);
|
||||
</script> </body> </html>
|
||||
BIN
dist/images/computing-box-logo.svg
vendored
BIN
dist/images/computing-box-logo.svg
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB |
1017
dist/images/favicon.svg
vendored
1017
dist/images/favicon.svg
vendored
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 732 KiB |
77
dist/index.html
vendored
77
dist/index.html
vendored
@@ -13,7 +13,80 @@
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
</script><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;800;900&display=swap" rel="stylesheet"><link rel="icon" type="image/x-icon" href="/images/favicon.ico"><link rel="stylesheet" href="/_astro/BaseLayout.DM-NXsTj.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo.webp" alt="Computing:Box logo"> <span class="brandName">Computing:Box</span> </a> <nav class="navLinks" aria-label="Site navigation"> <a href="/about">About</a> <a href="/binary">Binary</a> <a href="/hexadecimal">Hexadecimal</a> <a href="/hex-colours">Hex Colours</a> <a href="/logic-gates">Logic Gates</a> <a href="/pc-builder">PC Components</a> </nav> </div> </header> <main class="pageWrap"> <div style="display: flex; align-items: center; justify-content: space-between; gap: 40px; min-height: 60vh; padding: 40px 0;"> <div style="flex: 1;"> <p style="color: var(--accent); font-weight: 800; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 10px;">Version 2.0 Now Live</p> <h1 class="brandName" style="font-size: 48px; line-height: 1.1; margin-bottom: 24px;">Understand Computing concepts better.</h1> <p style="font-size: 18px; color: var(--muted);">
|
||||
</script><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;800;900&display=swap" rel="stylesheet"><link rel="icon" type="image/x-icon" href="/images/favicon.ico"><link rel="stylesheet" href="/_astro/BaseLayout.B8W3SO34.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo-small.webp" alt="Computing:Box logo"> <span class="brandName">Computing:Box</span> </a> <nav class="navLinks" aria-label="Site navigation"> <a href="/">Home</a> <a href="/about">About</a> <a href="/binary">Binary</a> <a href="/hexadecimal">Hexadecimal</a> <a href="/hex-colours">Hex Colours</a> <a href="/logic-gates">Logic Gates</a> <a href="/pc-builder">PC Components</a> </nav> </div> </header> <main class="pageWrap"> <div style="display: flex; align-items: center; justify-content: space-between; gap: 40px; min-height: 60vh; padding: 40px 0;"> <div style="flex: 1;"> <p style="color: var(--accent); font-weight: 800; letter-spacing: 2px; text-transform: uppercase; margin-bottom: 10px;">Version 2.0 Now Live</p> <h1 class="brandName" style="font-size: 48px; line-height: 1.1; margin-bottom: 24px;">Understand Computing concepts better.</h1> <p style="font-size: 18px; color: var(--muted);">
|
||||
Interactive simulators for Binary, Hexadecimal, Logic Gates, and Computer Components designed for the UK curriculum.
|
||||
</p> <div style="display: flex; gap: 16px; margin-top: 32px;"> <a href="/about" class="btn btnAccent" style="text-decoration: none; padding: 14px 28px;">Learn More</a> <a href="/binary" class="btn" style="text-decoration: none; padding: 14px 28px;">Get Started</a> </div> </div> <div style="flex: 1; text-align: right;"> <img src="/images/computing-box-logo.webp" alt="Computing Box Logo" style="width: 100%; max-width: 450px; filter: drop-shadow(0 0 50px rgba(40, 240, 122, 0.15));"> </div> </div> </main> <footer class="siteFooter"> <div class="footerInner"> <div style="margin-top: 5px; display: flex; justify-content: center;"> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> <a href="/legal-code" style="margin-left: 32px; color: var(--muted); text-decoration: underline;">Legal Code</a> </div> <div>Computer Science Concept Simulators</div> <div> Version:
|
||||
<a href="#" target="_blank" rel="noopener noreferrer">dev</a> • © 2026 Computing:Box • Created with ♥ by Mr A Lyall</div> </div> </footer> </body></html>
|
||||
<a href="#" target="_blank" rel="noopener noreferrer">dev</a> • © 2026 Computing:Box • Created with ♥ by Mr A Lyall</div> </div> </footer> <script>
|
||||
function setupToolboxAccordions() {
|
||||
// Look for cards inside ANY of the three toolboxes!
|
||||
const cards = document.querySelectorAll('.panelCol .card, .pb-toolbox .card, .lg-toolbox .card');
|
||||
if (!cards.length) return;
|
||||
|
||||
// Your primary cards for each page
|
||||
const primaryCardNames = ['settings', 'info', 'components', 'system diagnostics'];
|
||||
|
||||
cards.forEach(card => {
|
||||
const titleEl = card.querySelector('.cardTitle');
|
||||
if (!titleEl) return;
|
||||
|
||||
const titleText = titleEl.textContent.trim().toLowerCase();
|
||||
const isPrimary = primaryCardNames.includes(titleText);
|
||||
|
||||
// 1. DYNAMICALLY WRAP THE CONTENT
|
||||
if (!card.querySelector('.cardBody')) {
|
||||
const body = document.createElement('div');
|
||||
body.className = 'cardBody';
|
||||
const inner = document.createElement('div');
|
||||
inner.className = 'cardBodyInner';
|
||||
body.appendChild(inner);
|
||||
|
||||
Array.from(card.childNodes).forEach(node => {
|
||||
if (node !== titleEl) {
|
||||
inner.appendChild(node);
|
||||
}
|
||||
});
|
||||
card.appendChild(body);
|
||||
}
|
||||
|
||||
// 2. APPLY DEFAULT STATE
|
||||
if (isPrimary) {
|
||||
card.classList.remove('collapsed');
|
||||
} else {
|
||||
card.classList.add('collapsed');
|
||||
}
|
||||
|
||||
// 3. CLICK LISTENERS
|
||||
if (card.dataset.accordionInit) return;
|
||||
card.dataset.accordionInit = "true";
|
||||
|
||||
titleEl.addEventListener('click', () => {
|
||||
const isCollapsing = !card.classList.contains('collapsed');
|
||||
|
||||
if (isCollapsing) {
|
||||
card.classList.add('collapsed');
|
||||
} else {
|
||||
if (isPrimary) {
|
||||
cards.forEach(c => {
|
||||
// Only close cards that share the same parent toolbox
|
||||
if (c !== card && c.closest(card.parentElement.tagName) === card.closest(card.parentElement.tagName)) {
|
||||
c.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cards.forEach(c => {
|
||||
if (c.closest(card.parentElement.tagName) !== card.closest(card.parentElement.tagName)) return;
|
||||
const cTitle = c.querySelector('.cardTitle')?.textContent.trim().toLowerCase() || '';
|
||||
if (primaryCardNames.includes(cTitle)) {
|
||||
c.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
card.classList.remove('collapsed');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setupToolboxAccordions();
|
||||
document.addEventListener('astro:page-load', setupToolboxAccordions);
|
||||
</script> </body> </html>
|
||||
Reference in New Issue
Block a user