Compare commits

...

36 Commits

Author SHA1 Message Date
release-bot
2deba8ba2f chore(release): bump version to v26.03.30.a [skip ci] 2026-03-30 12:58:34 +00:00
5aa972ab7f Merge pull request 'chore(deps): update dependency astro to v6.1.1' (#23) from renovate/astro-6.x-lockfile into main
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 11m15s
Reviewed-on: #23
2026-03-30 12:31:01 +00:00
renovate[bot]
1b9cf4b388 chore(deps): update dependency astro to v6.1.1 2026-03-26 20:31:51 +00:00
release-bot
50d97b4e55 chore(release): bump version to v26.03.21.g [skip ci] 2026-03-21 23:26:58 +00:00
59c0b50396 Merge branch 'main' of https://git.adcmnetworks.co.uk/alexander.lyall/computing-box.git
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 9m47s
2026-03-21 23:21:48 +00:00
f83331ed35 feat(build): update dist output with new branding, assets, and version display
- Update built pages to use webp logo and favicon assets
- Replace legacy svg references in generated dist files
- Add favicon and base layout styles to build output
- Introduce version display in footer across all generated pages
- Align dist output with updated BaseLayout structure
- Clean up footer markup formatting in layout

Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-21 23:21:02 +00:00
release-bot
7a5d423dcb chore(release): bump version to v26.03.21.f [skip ci] 2026-03-21 23:13:49 +00:00
c4296137b3 Merge branch 'main' of https://git.adcmnetworks.co.uk/alexander.lyall/computing-box.git
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 9m48s
2026-03-21 23:08:17 +00:00
d980671266 feat(ui): update branding assets and switch logo to webp format
- Add new webp logo and favicon assets
- Replace svg logo references with webp across layouts and pages
- Add favicon.ico and favicon.webp for browser compatibility
- Update BaseLayout to include favicon link

Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-21 23:08:04 +00:00
release-bot
52d129f50a chore(release): bump version to v26.03.21.e [skip ci] 2026-03-21 22:55:39 +00:00
c8b43a3f8f fix(release): exclude current tag from previous tag lookup and handle empty result
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 9m57s
- Exclude newly created tag from PREV_TAG detection to avoid self-referencing ranges
- Add fallback to prevent workflow failure when no previous tag exists
- Update Node version in workflow configuration

Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-21 22:50:21 +00:00
63e2c267fb Merge pull request 'chore(deps): update dependency node to v22.22.1' (#22) from renovate/node-22.x into main
Some checks failed
Changelog + Release on main / changelog_and_release (push) Failing after 39s
Reviewed-on: #22
2026-03-21 22:47:57 +00:00
renovate[bot]
14c2dfdb20 chore(deps): update dependency node to v22.22.1
All checks were successful
Pre-release on non-main branches / prerelease (push) Successful in 30s
2026-03-21 22:46:49 +00:00
68f1ed5d81 chore: add git-cliff configuration
Some checks failed
Changelog + Release on main / changelog_and_release (push) Failing after 33s
feat(release): implement incremental changelog and versioned release workflow

- Generate changelog from previous release tag to HEAD
- Replace full-history changelog with incremental git-cliff usage
- Add automatic version bump from date-based tag
- Commit and push version updates (package.json and lockfile)
- Refactor workflow order to align changelog, versioning, and build
- Improve Node setup and add version checks
- Introduce cliff.toml configuration for grouped changelog output
- Add generated version.json for runtime version display
- Update footer layout to include dynamic version and release link

Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-21 22:45:22 +00:00
release-bot
875ab670d5 chore(release): bump version to v26.03.21.d [skip ci] 2026-03-21 22:24:55 +00:00
43cef42c3b Merge pull request 'chore(deps): update actions/setup-node action to v6' (#21) from renovate/actions-setup-node-6.x into main
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 10m57s
Reviewed-on: #21
2026-03-21 22:18:31 +00:00
renovate[bot]
29dd867bcb chore(deps): update actions/setup-node action to v6
All checks were successful
Pre-release on non-main branches / prerelease (push) Successful in 42s
2026-03-21 22:17:06 +00:00
dba93b67fd Changed release action
Some checks are pending
Changelog + Release on main / changelog_and_release (push) Has started running
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-21 22:15:45 +00:00
5d23d0639e Added versioning information to footer of website. General updates to the release action
Some checks failed
Changelog + Release on main / changelog_and_release (push) Failing after 6m47s
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-21 22:04:49 +00:00
535c62b838 Updated astro to 6.0.8
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 1m46s
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-21 21:52:43 +00:00
bcac9f3310 Merge pull request 'chore(deps): update dependency astro to v6' (#20) from renovate/astro-6.x into main
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 33s
Reviewed-on: #20
2026-03-21 21:49:14 +00:00
renovate[bot]
3a624cb5cd chore(deps): update dependency astro to v6
All checks were successful
Pre-release on non-main branches / prerelease (push) Successful in 37s
2026-03-21 21:48:00 +00:00
12f605e987 Merge pull request 'chore(deps): update dependency astro to v5.18.1' (#18) from renovate/astro-5.x-lockfile into main
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 1m48s
Reviewed-on: #18
2026-03-21 21:42:36 +00:00
renovate[bot]
cc3d6f0e48 chore(deps): update dependency astro to v5.18.1
All checks were successful
Pre-release on non-main branches / prerelease (push) Successful in 40s
2026-03-12 14:31:45 +00:00
61b24dc309 Merge branch 'Version-2-Rebase'
All checks were successful
Changelog + Release on main / changelog_and_release (push) Successful in 28s
2026-03-01 18:26:10 +00:00
1ec16aecb3 Final Version 2.0 Beta release
All checks were successful
Pre-release on non-main branches / prerelease (push) Successful in 29s
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-01 18:16:42 +00:00
bb8e0c1969 Broken code
All checks were successful
Pre-release on non-main branches / prerelease (push) Successful in 29s
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-01 17:52:36 +00:00
d4ffe30f9b Merge branch 'main' of https://git.adcmnetworks.co.uk/alexander.lyall/computing-box.git
Some checks failed
Changelog + Release on main / changelog_and_release (push) Failing after 27s
2026-03-01 13:59:01 +00:00
93542748e6 Update readme
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-03-01 13:58:56 +00:00
98671cdeee (layout): add global navigation, header, footer, and new assets
♻️ (binary): refactor to use BaseLayout and remove inline boilerplate

Migrate

♻️ (binary): refactor UI layout and extract inline script to external file

Extract the inline

 feat(binary): add binary calculator script for interactive UI

Introduce `binary.

 (binary-tool): add random generation, bit width, and toolbox controls

Add functions for

♻️ refactor: remove unused unsignedBinary.js and binary.css files

Delete the unsigned

Wait, the prompt gave a specific list of GitMojis:
 * 🐛, Fix

 feat: add styles for binary converter UI components and controls

Add CSS classes for buttons, inputs
2026-03-01 13:58:19 +00:00
e74a20ca81 Merge pull request 'chore(deps): update actions/checkout action to v6' (#10) from renovate/actions-checkout-6.x into main
Some checks failed
Changelog + Release on main / changelog_and_release (push) Failing after 29s
Reviewed-on: #10
2026-03-01 13:48:26 +00:00
renovate[bot]
4b21391232 chore(deps): update actions/checkout action to v6 2026-03-01 13:46:41 +00:00
5708a184d5 Merge pull request 'chore: Configure Renovate' (#8) from renovate/configure into main
Some checks failed
Changelog + Release on main / changelog_and_release (push) Failing after 27s
Reviewed-on: #8
2026-03-01 13:39:02 +00:00
af131fc58a Fixed binary user interface
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-02-28 23:35:14 +00:00
renovate[bot]
4a0e4d306a Add renovate.json 2026-02-28 23:01:44 +00:00
aa9e071d40 Update dependencies and backup of project
Some checks failed
Changelog + Release on main / changelog_and_release (push) Failing after 37s
Signed-off-by: Alexander Lyall <alex@adcm.uk>
2026-02-28 23:01:39 +00:00
24 changed files with 1084 additions and 1610 deletions

View File

@@ -1,194 +0,0 @@
name: Pre-release on non-main branches
on:
push:
branches-ignore: [ main ]
workflow_dispatch:
jobs:
prerelease:
runs-on: ubuntu-latest
steps:
- name: Checkout (full history + tags)
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Stop if this is the bot changelog commit
shell: bash
run: |
set -e
msg="$(git log -1 --pretty=%B)"
echo "$msg" | tr -d '\r' | grep -qi "\[skip ci\]" && {
echo "Skipping (bot commit with [skip ci])"
exit 0
} || true
- name: Install git-cliff
shell: bash
run: |
set -e
GIT_CLIFF_VERSION="2.11.0"
URL="https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
curl -L "$URL" -o /tmp/git-cliff.tar.gz
tar -xzf /tmp/git-cliff.tar.gz -C /tmp
sudo install /tmp/git-cliff-*/git-cliff /usr/local/bin/git-cliff
git-cliff --version
- name: Generate CHANGELOG.md (in runner only)
shell: bash
run: |
set -e
git-cliff --config cliff.toml --output CHANGELOG.md
test -s CHANGELOG.md
- name: Extract newest changelog section for pre-release body
shell: bash
run: |
set -e
awk '
/^## / { if (seen) exit; seen=1 }
seen { print }
' CHANGELOG.md > RELEASE_NOTES.md
sed -i 's/[[:space:]]*$//' RELEASE_NOTES.md
test -s RELEASE_NOTES.md
- name: Create export zip (Computing:Box Website.zip)
shell: bash
run: |
set -e
if [ ! -d "dist" ]; then
echo "❌ dist/ folder not found in repo root"
ls -la
exit 1
fi
rm -f "Computing:Box Website.zip"
(cd dist && zip -r "../Computing:Box Website.zip" .)
test -s "Computing:Box Website.zip"
ls -lh "Computing:Box Website.zip"
- name: Prepare pre-release tag + name
shell: bash
run: |
set -e
# Get branch name from ref: refs/heads/feature/x -> feature/x
ref="${GITHUB_REF#refs/heads/}"
# Make it tag-safe: lowercase, / -> -, remove invalid chars, collapse repeats
safe_branch="$(echo "$ref" | tr '[:upper:]' '[:lower:]' | sed -E 's#[^a-z0-9._-]+#-#g; s#-+#-#g; s#(^-|-$)##g')"
VERSION="$(date -u +'%y.%m.%d')"
SHORT_SHA="$(git rev-parse --short HEAD)"
# Pre-release tag format:
# vYY.MM.DD-pre.<branch>.<sha>
TAG="v${VERSION}-pre.${safe_branch}.${SHORT_SHA}"
# Release name shown in UI
RELEASE_NAME="Computing:Box pre-release (${ref}) v${VERSION}"
echo "TAG=$TAG" >> "$GITHUB_ENV"
echo "RELEASE_NAME=$RELEASE_NAME" >> "$GITHUB_ENV"
echo "ZIP_PATH=Computing:Box Website.zip" >> "$GITHUB_ENV"
echo "BRANCH_NAME=$ref" >> "$GITHUB_ENV"
echo "Using tag: $TAG"
echo "Release name: $RELEASE_NAME"
- name: Create and push tag (CHANGELOG_PAT)
shell: bash
env:
CHANGELOG_PAT: ${{ secrets.CHANGELOG_PAT }}
run: |
set -e
git tag -f "$TAG"
origin_url="$(git remote get-url origin)"
# Convert SSH origin to HTTPS if needed
if echo "$origin_url" | grep -q "^git@"; then
host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')"
path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')"
origin_url="https://$host/$path"
fi
authed_url="$(echo "$origin_url" | sed -E "s#^https://#https://oauth2:${CHANGELOG_PAT}@#")"
git push "$authed_url" "refs/tags/$TAG" --force
- name: Create Gitea pre-release + upload asset (CHANGELOG_PAT)
shell: bash
env:
CHANGELOG_PAT: ${{ secrets.CHANGELOG_PAT }}
run: |
set -e
origin_url="$(git remote get-url origin)"
if echo "$origin_url" | grep -q "^git@"; then
host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')"
path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')"
origin_url="https://$host/$path"
fi
base="$(echo "$origin_url" | sed -E 's#(https?://[^/]+)/.*#\1#')"
repo_path="$(echo "$origin_url" | sed -E 's#https?://[^/]+/##')"
repo_path="$(echo "$repo_path" | sed -E 's/\.git$//')"
owner="$(echo "$repo_path" | cut -d/ -f1)"
repo="$(echo "$repo_path" | cut -d/ -f2-)"
api="$base/api/v1"
python3 - <<'PY'
import json, os
tag = os.environ["TAG"]
name = os.environ["RELEASE_NAME"]
branch = os.environ.get("BRANCH_NAME", "")
with open("RELEASE_NOTES.md", "r", encoding="utf-8") as f:
body = f.read()
# Add a small pre-release banner at the top
banner = f"⚠️ Pre-release build from branch `{branch}`\n\n"
payload = {
"tag_name": tag,
"target_commitish": branch if branch else "main",
"name": name,
"body": banner + body,
"draft": False,
"prerelease": True,
}
with open("release.json", "w", encoding="utf-8") as f:
json.dump(payload, f)
PY
curl -sS -X POST \
-H "Authorization: Bearer ${CHANGELOG_PAT}" \
-H "Content-Type: application/json" \
"${api}/repos/${owner}/${repo}/releases" \
--data-binary @release.json \
-o release_response.json
release_id="$(python3 - <<'PY'
import json
with open("release_response.json","r",encoding="utf-8") as f:
data=json.load(f)
rid=data.get("id")
if not rid:
raise SystemExit("No release id returned. Response:\n" + json.dumps(data, indent=2))
print(rid)
PY
)"
echo "Created pre-release id: $release_id"
curl -sS -X POST \
-H "Authorization: Bearer ${CHANGELOG_PAT}" \
"${api}/repos/${owner}/${repo}/releases/${release_id}/assets?name=Computing%3ABox%20Website.zip" \
-F "attachment=@${ZIP_PATH}" \
>/dev/null
echo "✅ Pre-release created: ${RELEASE_NAME} (tag: ${TAG}) with asset uploaded"

View File

@@ -15,7 +15,7 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Stop if this is the bot changelog commit - name: Stop if this is the bot changelog/version commit
shell: bash shell: bash
run: | run: |
set -e set -e
@@ -36,82 +36,11 @@ jobs:
sudo install /tmp/git-cliff-*/git-cliff /usr/local/bin/git-cliff sudo install /tmp/git-cliff-*/git-cliff /usr/local/bin/git-cliff
git-cliff --version git-cliff --version
- name: Generate CHANGELOG.md (Keep a Changelog)
shell: bash
run: |
set -e
git-cliff --config cliff.toml --output CHANGELOG.md
test -s CHANGELOG.md
- name: Commit and push CHANGELOG.md if changed (CHANGELOG_PAT)
shell: bash
env:
CHANGELOG_PAT: ${{ secrets.CHANGELOG_PAT }}
run: |
set -e
if git diff --quiet -- CHANGELOG.md; then
echo "No changelog changes."
else
git config user.name "changelog-bot"
git config user.email "changelog-bot@users.noreply.local"
git add CHANGELOG.md
git commit -m "docs(changelog): update changelog [skip ci]"
origin_url="$(git remote get-url origin)"
# Convert SSH origin to HTTPS if needed
if echo "$origin_url" | grep -q "^git@"; then
host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')"
path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')"
origin_url="https://$host/$path"
fi
authed_url="$(echo "$origin_url" | sed -E "s#^https://#https://oauth2:${CHANGELOG_PAT}@#")"
git push "$authed_url" HEAD:main
fi
- name: Extract newest changelog section for release body
shell: bash
run: |
set -e
# Extract the first "## ..." section (newest section) from CHANGELOG.md
# Includes the "## ..." heading and everything until the next "## ..." heading.
awk '
/^## / { if (seen) exit; seen=1 }
seen { print }
' CHANGELOG.md > RELEASE_NOTES.md
# Clean trailing whitespace/newlines a bit
sed -i 's/[[:space:]]*$//' RELEASE_NOTES.md
test -s RELEASE_NOTES.md
echo "---- RELEASE_NOTES.md ----"
head -n 60 RELEASE_NOTES.md
echo "--------------------------"
- name: Create export zip (Computing:Box Website.zip)
shell: bash
run: |
set -e
if [ ! -d "dist" ]; then
echo "❌ dist/ folder not found in repo root"
ls -la
exit 1
fi
rm -f "Computing:Box Website.zip"
(cd dist && zip -r "../Computing:Box Website.zip" .)
test -s "Computing:Box Website.zip"
ls -lh "Computing:Box Website.zip"
- name: Prepare YY.MM.DD letter-suffix tag + release name - name: Prepare YY.MM.DD letter-suffix tag + release name
shell: bash shell: bash
run: | run: |
set -e set -e
# Version: YY.MM.DD (UTC). Swap to `date +...` if you prefer UK-local runner time.
VERSION="$(date -u +'%y.%m.%d')" VERSION="$(date -u +'%y.%m.%d')"
PREFIX="v${VERSION}." PREFIX="v${VERSION}."
@@ -135,12 +64,216 @@ jobs:
TAG="${PREFIX}${next_letter}" TAG="${PREFIX}${next_letter}"
RELEASE_NAME="Computing:Box v${VERSION}.${next_letter}" RELEASE_NAME="Computing:Box v${VERSION}.${next_letter}"
origin_url="$(git remote get-url origin)"
if echo "$origin_url" | grep -q "^git@"; then
host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')"
path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')"
origin_url="https://$host/$path"
fi
base="$(echo "$origin_url" | sed -E 's#(https?://[^/]+)/.*#\1#')"
repo_path="$(echo "$origin_url" | sed -E 's#https?://[^/]+/##')"
repo_path="$(echo "$repo_path" | sed -E 's/\.git$//')"
RELEASE_URL="${base}/${repo_path}/releases/tag/${TAG}"
echo "TAG=$TAG" >> "$GITHUB_ENV" echo "TAG=$TAG" >> "$GITHUB_ENV"
echo "RELEASE_NAME=$RELEASE_NAME" >> "$GITHUB_ENV" echo "RELEASE_NAME=$RELEASE_NAME" >> "$GITHUB_ENV"
echo "ZIP_PATH=Computing:Box Website.zip" >> "$GITHUB_ENV" echo "ZIP_PATH=Computing:Box Website.zip" >> "$GITHUB_ENV"
echo "RELEASE_URL=$RELEASE_URL" >> "$GITHUB_ENV"
echo "Using tag: $TAG" echo "Using tag: $TAG"
echo "Release name: $RELEASE_NAME" echo "Release name: $RELEASE_NAME"
echo "Release URL: $RELEASE_URL"
- name: Find previous release tag
shell: bash
run: |
set -e
PREV_TAG="$(
git tag --list 'v*' \
| grep -E '^v[0-9]{2}\.[0-9]{2}\.[0-9]{2}[a-z]$' \
| grep -Fxv "$TAG" \
| sort -V \
| tail -n 1 \
|| true
)"
if [ -n "$PREV_TAG" ]; then
echo "PREV_TAG=$PREV_TAG" >> "$GITHUB_ENV"
echo "Previous release tag: $PREV_TAG"
else
echo "PREV_TAG=" >> "$GITHUB_ENV"
echo "No previous release tag found."
fi
- name: Generate CHANGELOG.md from previous release to HEAD
shell: bash
run: |
set -e
if [ -n "${PREV_TAG}" ]; then
echo "Generating changelog from ${PREV_TAG}..HEAD"
git-cliff --config cliff.toml "${PREV_TAG}..HEAD" --output CHANGELOG.md
else
echo "Generating changelog from full history"
git-cliff --config cliff.toml --output CHANGELOG.md
fi
test -s CHANGELOG.md
echo "---- CHANGELOG.md ----"
head -n 120 CHANGELOG.md
echo "----------------------"
- name: Commit and push CHANGELOG.md if changed (CHANGELOG_PAT)
shell: bash
env:
CHANGELOG_PAT: ${{ secrets.CHANGELOG_PAT }}
run: |
set -e
if git diff --quiet -- CHANGELOG.md; then
echo "No changelog changes."
else
git config user.name "changelog-bot"
git config user.email "changelog-bot@users.noreply.local"
git add CHANGELOG.md
git commit -m "docs(changelog): update changelog [skip ci]"
origin_url="$(git remote get-url origin)"
if echo "$origin_url" | grep -q "^git@"; then
host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')"
path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')"
origin_url="https://$host/$path"
fi
authed_url="$(echo "$origin_url" | sed -E "s#^https://#https://oauth2:${CHANGELOG_PAT}@#")"
git push "$authed_url" HEAD:main
fi
- name: Prepare release notes
shell: bash
run: |
set -e
cp CHANGELOG.md RELEASE_NOTES.md
test -s RELEASE_NOTES.md
echo "---- RELEASE_NOTES.md ----"
head -n 120 RELEASE_NOTES.md
echo "--------------------------"
- name: Derive semver package version from tag
shell: bash
run: |
set -e
PACKAGE_VERSION="$(echo "$TAG" | sed -E 's/^v([0-9]{2})\.0?([0-9]{1,2})\.0?([0-9]{1,2})([a-z])$/\1.\2.\3-\4/')"
if [ -z "$PACKAGE_VERSION" ]; then
echo "❌ Failed to derive PACKAGE_VERSION from TAG=$TAG"
exit 1
fi
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> "$GITHUB_ENV"
echo "Using package version: $PACKAGE_VERSION"
- name: Generate version file for Astro footer
shell: bash
run: |
set -e
mkdir -p src/generated
cat > src/generated/version.json <<EOF
{
"version": "${TAG}",
"url": "${RELEASE_URL}"
}
EOF
echo "Generated src/generated/version.json"
cat src/generated/version.json
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: 25
cache: npm
- name: Check Node version
shell: bash
run: |
node -v
npm -v
- name: Install dependencies
shell: bash
run: |
set -e
npm ci
- name: Update package.json and package-lock.json version
shell: bash
run: |
set -e
npm version "$PACKAGE_VERSION" --no-git-tag-version
echo "package.json version:"
node -p "require('./package.json').version"
echo "package-lock.json version:"
node -p "require('./package-lock.json').version"
- name: Commit and push version bump (CHANGELOG_PAT)
shell: bash
env:
CHANGELOG_PAT: ${{ secrets.CHANGELOG_PAT }}
run: |
set -e
if git diff --quiet -- package.json package-lock.json; then
echo "No version changes to commit."
else
git config user.name "release-bot"
git config user.email "release-bot@users.noreply.local"
git add package.json package-lock.json
git commit -m "chore(release): bump version to ${PACKAGE_VERSION} [skip ci]"
origin_url="$(git remote get-url origin)"
if echo "$origin_url" | grep -q "^git@"; then
host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')"
path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')"
origin_url="https://$host/$path"
fi
authed_url="$(echo "$origin_url" | sed -E "s#^https://#https://oauth2:${CHANGELOG_PAT}@#")"
git push "$authed_url" HEAD:main
fi
- name: Build Astro site
shell: bash
run: |
set -e
npm run build
test -d dist
- name: Create export zip (Computing:Box Website.zip)
shell: bash
run: |
set -e
if [ ! -d "dist" ]; then
echo "❌ dist/ folder not found in repo root"
ls -la
exit 1
fi
rm -f "Computing:Box Website.zip"
(cd dist && zip -r "../Computing:Box Website.zip" .)
test -s "Computing:Box Website.zip"
ls -lh "Computing:Box Website.zip"
- name: Create and push tag (CHANGELOG_PAT) - name: Create and push tag (CHANGELOG_PAT)
shell: bash shell: bash
@@ -153,7 +286,6 @@ jobs:
origin_url="$(git remote get-url origin)" origin_url="$(git remote get-url origin)"
# Convert SSH origin to HTTPS if needed
if echo "$origin_url" | grep -q "^git@"; then if echo "$origin_url" | grep -q "^git@"; then
host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')" host="$(echo "$origin_url" | sed -E 's#git@([^:]+):.*#\1#')"
path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')" path="$(echo "$origin_url" | sed -E 's#git@[^:]+:(.*)#\1#')"
@@ -198,7 +330,7 @@ jobs:
"tag_name": tag, "tag_name": tag,
"target_commitish": "main", "target_commitish": "main",
"name": name, "name": name,
"body": body, # newest section only "body": body,
"draft": False, "draft": False,
"prerelease": False, "prerelease": False,
} }

View File

@@ -28,18 +28,19 @@ An evolution of Bit:Box & CS:Box to incorporate different elements of the UK Com
- [X] XNOR Gate Simulator - [X] XNOR Gate Simulator
### Wave 3 CS:Box Features (Spring 2026) ### Wave 3 CS:Box Features (Spring 2026)
- [ ] New User Interface (Responsive) - [X] New User Interface (Responsive)
- [X] Two's Compliment Simulator - [X] Two's Compliment Simulator
- [X] Extended Binary Simulator (Custom bit sizes) - [X] Extended Binary Simulator (Custom bit sizes)
- [X] Unified Binary Simulator (Unsigned & Two's Completment combined) - [X] Unified Binary Simulator (Unsigned & Two's Completment combined)
- [ ] Extended Hexadecimal Simulator - [X] Extended Hexadecimal Simulator
- [ ] Unified Hexadecimal Simulator (For GCSE & A Level Specification) - [X] Unified Hexadecimal Simulator (For GCSE & A Level Specification)
- [ ] Enhanced Gate Simulator (Truth Table Creator) - [X] Enhanced Gate Simulator (Truth Table Creator)
- [ ] Compound Gate Simulator - [X] Compound Gate Simulator
- [ ] Computer Components Simulator - [X] Computer Components Simulator - Beta Available
## Version 1.0 Release Date: 1<sup>st</sup> September 2025 ## Version 1.0 Release Date: 1<sup>st</sup> September 2025
## Version 2.0 Release Date (Goal): 1<sup>st</sup> May 2026 ## Version 2.0 Release Date (Beta): 1<sup>st</sup> March 2026
## Version 2.0 Release Date (Full Release): 1<sup>st</sup> May 2026
Shield: [![CC BY-NC-SA 4.0][cc-by-nc-sa-shield]][cc-by-nc-sa] Shield: [![CC BY-NC-SA 4.0][cc-by-nc-sa-shield]][cc-by-nc-sa]

35
cliff.toml Normal file
View File

@@ -0,0 +1,35 @@
[changelog]
header = """
# Changelog
"""
body = """
{% for group, commits in commits | group_by(attribute="group") %}
## {{ group }}
{% for commit in commits %}
- {{ commit.message | upper_first }}
{% endfor %}
{% endfor %}
"""
footer = ""
[git]
conventional_commits = false
filter_unconventional = false
split_commits = false
topo_order = true
# IMPORTANT: match your tag format
tag_pattern = "^v[0-9]{2}\\.[0-9]{2}\\.[0-9]{2}[a-z]$"
commit_parsers = [
{ message = "^feat", group = "🚀 Features" },
{ message = "^fix", group = "🐛 Fixes" },
{ message = "^refactor", group = "♻️ Refactoring" },
{ message = "^docs", group = "📚 Documentation" },
{ message = "^chore", group = "💼 Other" },
# catch-all so NOTHING is dropped
{ message = ".*", group = "💼 Other" },
]

View File

@@ -13,8 +13,8 @@
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 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); 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="stylesheet" href="/_astro/about.CswAWODG.css"> </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/binary.9peKc0z2.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo.svg" 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"> <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">
Tip: In unsigned binary, all bits represent positive values. 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>Computer Science Concept Simulators</div> <div>© 2026 Computing:Box • Created with ♥ by Alexander Lyall</div> <div style="margin-top: 5px;"> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> </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="/legal-code" style="color: var(--muted); text-decoration: underline;">Legal Code</a> </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> </body></html>

View File

@@ -13,8 +13,8 @@
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 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); 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="stylesheet" href="/_astro/about.CswAWODG.css"> </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/binary.9peKc0z2.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo.svg" 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;"> <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;">
Hexadecimal represents numbers using base 16 (0-9, A-F). 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>Computer Science Concept Simulators</div> <div>© 2026 Computing:Box • Created with ♥ by Alexander Lyall</div> <div style="margin-top: 5px;"> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> </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="/legal-code" style="color: var(--muted); text-decoration: underline;">Legal Code</a> </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> </body></html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

6
dist/index.html vendored
View File

@@ -13,7 +13,7 @@
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 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); 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="stylesheet" href="/_astro/about.CswAWODG.css"></head> <body> <header class="siteNav"> <div class="navInner"> <a class="brand" href="/"> <img class="brandLogo" src="/images/computing-box-logo.svg" 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.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);">
Interactive simulators for Binary, Hexadecimal, Logic Gates, and Computer Components designed for the UK curriculum. 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.svg" 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>Computer Science Concept Simulators</div> <div>© 2026 Computing:Box • Created with ♥ by Alexander Lyall</div> <div style="margin-top: 5px;"> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> </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="/legal-code" style="color: var(--muted); text-decoration: underline;">Legal Code</a> </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> </body></html>

1868
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{ {
"name": "computing-box", "name": "computing-box",
"type": "module", "type": "module",
"version": "2.0.0", "version": "26.3.3-0.a",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"build": "astro build", "build": "astro build",
@@ -9,6 +9,6 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^5.18.0" "astro": "^6.0.8"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
public/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
public/images/favicon.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

View File

@@ -0,0 +1,4 @@
{
"version": "dev",
"url": "#"
}

View File

@@ -1,5 +1,9 @@
--- ---
import "../styles/global.css"; import "../styles/global.css";
import versionInfo from "../generated/version.json";
const version = versionInfo.version;
const releaseUrl = versionInfo.url;
const { title = "Computing:Box" } = Astro.props; const { title = "Computing:Box" } = Astro.props;
--- ---
@@ -29,12 +33,13 @@ const { title = "Computing:Box" } = Astro.props;
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <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 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" />
</head> </head>
<body> <body>
<header class="siteNav"> <header class="siteNav">
<div class="navInner"> <div class="navInner">
<a class="brand" href="/"> <a class="brand" href="/">
<img class="brandLogo" src="/images/computing-box-logo.svg" alt="Computing:Box logo" /> <img class="brandLogo" src="/images/computing-box-logo.webp" alt="Computing:Box logo" />
<span class="brandName">Computing:Box</span> <span class="brandName">Computing:Box</span>
</a> </a>
@@ -55,12 +60,13 @@ const { title = "Computing:Box" } = Astro.props;
<footer class="siteFooter"> <footer class="siteFooter">
<div class="footerInner"> <div class="footerInner">
<div>Computer Science Concept Simulators</div> <div style="margin-top: 5px; display: flex; justify-content: center;">
<div>© {new Date().getFullYear()} Computing:Box • Created with ♥ by Alexander Lyall</div> <a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a>
<div style="margin-top: 5px;"> <a href="/legal-code" style="margin-left: 32px; color: var(--muted); text-decoration: underline;">Legal Code</a>
<a href="/copyright" style="color: var(--muted); text-decoration: underline;">Copyright Notice</a> •
<a href="/legal-code" style="color: var(--muted); text-decoration: underline;">Legal Code</a>
</div> </div>
<div>Computer Science Concept Simulators</div>
<div> Version:
<a href={releaseUrl} target="_blank" rel="noopener noreferrer">{version}</a> • © {new Date().getFullYear()} Computing:Box • Created with ♥ by Mr A Lyall</div>
</div> </div>
</footer> </footer>
</body> </body>

View File

@@ -2,36 +2,54 @@
import BaseLayout from "../layouts/BaseLayout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
--- ---
<BaseLayout title="About | Computing:Box"> <BaseLayout title="About - Computing:Box">
<article style="max-width: 900px; margin: 0 auto;"> <article style="max-width: 1100px; margin: 0 auto; width: 100%;">
<div style="text-align: center; margin-bottom: 60px;">
<img src="/images/computing-box-logo.webp" alt="Computing:Box Logo" style="width: 250px; border-radius: 20px; box-shadow: 0 12px 40px rgba(0,0,0,0.5);" />
<h1 class="brandName" style="font-size: 42px; margin-top: 20px; color: var(--text);">The New Computing:Box Experience</h1>
</div>
<div class="card" style="margin-bottom: 40px;"> <div class="card" style="margin-bottom: 40px;">
<h1 class="brandName" style="font-size: 32px; color: var(--text); margin-bottom: 16px;">The New Computing:Box Experience</h1> <p style="color: var(--muted); font-size: 18px; line-height: 1.6; text-align: center;">
<p style="color: var(--muted); font-size: 18px; line-height: 1.6;"> Rebuilt from the ground up to provide a deeper, more professional simulation environment for the UK Computing Curriculum.
The platform has been rebuilt from the ground up to provide a deeper, more professional simulation environment.
We've introduced several key simulators and interface upgrades to support the modern Computing classroom:
</p> </p>
<div class="divider"></div> <div class="divider"></div>
<ul style="list-style: none; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<ul style="list-style: none; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> New User Interface (Responsive)</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> New User Interface (Responsive)</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Two's Complement Simulator</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Two's Complement Simulator</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Extended Binary Simulator (Custom bit sizes)</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Extended Binary Simulator (Custom sizes)</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Unified Binary Simulator (Unsigned & Two's Complement)</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Unified Binary Simulator</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Extended Hexadecimal Simulator</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Extended Hexadecimal Simulator</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Unified Hexadecimal Simulator (GCSE & A Level)</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Unified Hexadecimal Simulator</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Enhanced Gate Simulator (Truth Table Creator)</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Enhanced Gate Simulator (Truth Tables)</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Compound Gate Simulator</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Compound Gate Simulator</li>
<li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Computer Components Simulator</li> <li style="color: var(--text);"><span style="color: var(--accent);">✔</span> Computer Components Simulator</li>
</ul> </ul>
</div> </div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-bottom: 40px; align-items: center;">
<div class="card"> <div class="card">
<h2 class="brandName" style="font-size: 24px; margin-bottom: 12px;">Educational Impact</h2> <h2 class="brandName" style="font-size: 24px; color: var(--accent);">From Bit:Box to Computing:Box</h2>
<p style="color: var(--muted);"> <p style="color: var(--muted); line-height: 1.6;">Computing:Box began as Bit:Box, a digital version of a physical Binary Light Box created by Mr Davis. The original device used lightbulbs to show how binary numbers are built.</p>
Computing:Box is designed to help students learn computing concepts step by step, using clear visuals and simple interactions. </div>
By changing values and seeing results straight away, students can build understanding at their own pace. <img src="/images/BitBoxLogo.png" alt="Bit:Box Logo" style="width: 100%; border-radius: 16px; border: 1px solid var(--line);" />
</p> </div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-bottom: 40px; align-items: center;">
<img src="/images/computingbox-concept-illustration.webp" alt="Simulator Illustration" style="width: 100%; border-radius: 16px; border: 1px solid var(--line);" />
<div class="card">
<h2 class="brandName" style="font-size: 24px; color: var(--accent);">Learning by Doing</h2>
<p style="color: var(--muted); line-height: 1.6;">Students can interact with simulations, change values, and see results instantly. This helps them understand how concepts work rather than memorising rules.</p>
</div>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center;">
<div class="card">
<h2 class="brandName" style="font-size: 24px; color: var(--accent);">Educational Impact</h2>
<p style="color: var(--muted); line-height: 1.6;">Designed for use in lessons, independent study, and revision, helping students build confidence as they explore how computers work.</p>
</div>
<img src="/images/Educational_Impact.webp" alt="Classroom Impact" style="width: 100%; border-radius: 16px; border: 1px solid var(--line);" />
</div> </div>
</article> </article>
</BaseLayout> </BaseLayout>

View File

@@ -5,11 +5,7 @@ import BaseLayout from "../layouts/BaseLayout.astro";
<BaseLayout title="Copyright Notice | Computing:Box"> <BaseLayout title="Copyright Notice | Computing:Box">
<div class="card" style="max-width: 800px; margin: 0 auto;"> <div class="card" style="max-width: 800px; margin: 0 auto;">
<h1 class="brandName" style="color: var(--accent); margin-bottom: 20px;">Copyright Notice</h1> <h1 class="brandName" style="color: var(--accent); margin-bottom: 20px;">Copyright Notice</h1>
<p style="color: var(--text);"> <a href="https://www.computingbox.co.uk" style="color: var(--accent); text-decoration: none;">Computing:Box</a> © 2024 by <a href="https://www.mrlyall.uk/" style="color: var(--accent); text-decoration: none;">Mr A Lyall</a> is licensed under <strong><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" style="color: var(--accent); text-decoration: none;">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International</a></strong><img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt="" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" alt="" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="" style="max-width: 1em;max-height:1em;margin-left: .2em;">
<a href="https://www.computingbox.co.uk" style="color: var(--accent); text-decoration: none;">Computing:Box</a>
© 2024 by <a href="https://git.adcmnetworks.co.uk/alexander.lyall" style="color: var(--accent); text-decoration: none;">Alexander Lyall</a> is licensed under
<strong>Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International</strong>.
</p>
<div class="divider"></div> <div class="divider"></div>
@@ -22,9 +18,11 @@ import BaseLayout from "../layouts/BaseLayout.astro";
<h2 class="brandName" style="font-size: 20px;">Under the following terms:</h2> <h2 class="brandName" style="font-size: 20px;">Under the following terms:</h2>
<ul style="color: var(--muted); line-height: 1.6;"> <ul style="color: var(--muted); line-height: 1.6;">
<li><strong>Attribution</strong> — You must give appropriate credit, provide a link to the license, and indicate if changes were made.</li> <li class="cc-by"><strong>Attribution </strong>— You must give <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en#ref-appropriate-credit" style="color: var(--accent); margin-bottom: 20px;">appropriate credit</a>, provide a link to the license, and <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en#ref-indicate-changes" style="color: var(--accent); margin-bottom: 20px;">indicate if changes were made</a>. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.</li>
<li><strong>NonCommercial</strong> — You may not use the material for commercial purposes.</li> <li class="cc-nc"><strong>NonCommercial</strong> — You may not use the material for <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en#ref-commercial-purposes" style="color: var(--accent); margin-bottom: 20px;">commercial purposes</a>.</li>
<li><strong>ShareAlike</strong> — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.</li> <li class="cc-sa"><strong>ShareAlike</strong> — If you remix, transform, or build upon the material, you must distribute your contributions under the <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en#ref-same-license" style="color: var(--accent); margin-bottom: 20px;">same license</a> as the original.</li>
<li><strong>No additional restrictions</strong> — You may not apply legal terms or <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en#ref-technological-measures" style="color: var(--accent); margin-bottom: 20px;">technological measures</a> that legally restrict others from doing anything the license permits.</li>
</ul> </ul>
</div> </div>
</BaseLayout> </BaseLayout>

View File

@@ -17,7 +17,7 @@ import BaseLayout from "../layouts/BaseLayout.astro";
</div> </div>
<div style="flex: 1; text-align: right;"> <div style="flex: 1; text-align: right;">
<img src="/images/computing-box-logo.svg" alt="Computing Box Logo" style="width: 100%; max-width: 450px; filter: drop-shadow(0 0 50px rgba(40, 240, 122, 0.15));" /> <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>
</div> </div>
</BaseLayout> </BaseLayout>

View File

@@ -26,9 +26,7 @@ import "../styles/pc-builder.css";
</div> </div>
<div class="pb-viewport" id="viewport"> <div class="pb-viewport" id="viewport">
<svg class="pb-svg-layer pb-wire-internal" id="wireLayerInternal"></svg> <svg class="pb-svg-layer" id="wireLayer"></svg>
<svg class="pb-svg-layer pb-wire-external" id="wireLayerExternal"></svg>
</div> </div>
</div> </div>

View File

@@ -23,10 +23,10 @@
--text: #e8e8ee; --text: #e8e8ee;
--muted: #a9acb8; --muted: #a9acb8;
--line: rgba(255,255,255,.10); --line: rgba(255,255,255,.10);
--accent: #28f07a;
--ui-font: "Inter", system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; --ui-font: "Inter", system-ui, -apple-system, sans-serif;
--num-font: "DSEG7Classic", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
--bit-font: "SevenSegment", monospace; --bit-font: "SevenSegment", monospace;
--num-font: "DSEG7Classic"
} }
* { box-sizing: border-box; } * { box-sizing: border-box; }
@@ -34,8 +34,8 @@ html, body { height: 100%; }
body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--ui-font); display: flex; flex-direction: column; } body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--ui-font); display: flex; flex-direction: column; }
/* --- BASE LAYOUT --- */ /* --- BASE LAYOUT --- */
.siteNav { position: sticky; top: 0; z-index: 50; height: var(--nav-h); background: rgba(0,0,0,.10); border-bottom: 1px solid var(--line); backdrop-filter: blur(8px); } .siteNav { position: sticky; top: 0; z-index: 50; height: var(--nav-h); background: rgba(0,0,0,.10); border-bottom: 1px solid var(--line); backdrop-filter: blur(8px); margin-bottom: 25px; }
.navInner { height: 100%; max-width: 1400px; margin: 0 auto; padding: 0 20px; display: flex; align-items: center; justify-content: space-between; gap: 24px; } .navInner { height: 90px; max-width: 1400px; margin: 0 auto; padding: 0 20px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--text); } .brand { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--text); }
.brandLogo { width: 2.5em; height: 2.5em; image-rendering: pixelated; } .brandLogo { width: 2.5em; height: 2.5em; image-rendering: pixelated; }
.brandName { letter-spacing: .12em; font-weight: 900; font-size: 18px; } .brandName { letter-spacing: .12em; font-weight: 900; font-size: 18px; }
@@ -47,9 +47,39 @@ body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--
.siteFooter { border-top: 1px solid var(--line); background: rgba(0,0,0,.08); } .siteFooter { border-top: 1px solid var(--line); background: rgba(0,0,0,.08); }
.footerInner { max-width: 1400px; margin: 0 auto; padding: 18px 20px; color: var(--muted); font-size: 12px; letter-spacing: .08em; display: flex; flex-direction: column; gap: 6px; } .footerInner { max-width: 1400px; margin: 0 auto; padding: 18px 20px; color: var(--muted); font-size: 12px; letter-spacing: .08em; display: flex; flex-direction: column; gap: 6px; }
/* --- SHARED UI COMPONENTS (Used by ALL Simulators) --- */ /* --- APP LAYOUT --- */
.binaryPage {
--toolbox-w: 360px;
--toolbox-gap: 22px;
--toolbox-toggle-top: calc(var(--nav-h) + 16px);
--toolbox-top: calc(var(--toolbox-toggle-top) + 60px);
position: relative; padding-top: 16px; flex: 1; display: flex; flex-direction: column;
}
.binaryPage:not(.toolboxCollapsed) { padding-right: calc(var(--toolbox-w) + var(--toolbox-gap)); }
.binaryPage.toolboxCollapsed { padding-right: 0; }
.topGrid { display: flex; align-items: stretch; gap: 28px; flex: 1; }
.leftCol { flex: 1 1 auto; min-width: 0; container-type: inline-size; display: flex; flex-direction: column; }
/* --- READOUT FORMATTING --- */
.readoutContainer { display: flex; align-items: center; justify-content: center; gap: 64px; width: 100%; }
.readout { display: flex; flex-direction: column; align-items: center; gap: 16px; padding-top: 4px; }
.readoutBlock { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.label { font-family: var(--bit-font); letter-spacing: .14em; text-transform: uppercase; font-size: 18px; opacity: .75; margin: 0; }
.num { font-family: var(--num-font); color: #28f07a; text-shadow: 0 0 18px rgba(40,240,122,.35); letter-spacing: 2px; }
.denaryValue, .hexValue, .binaryValue { display: flex; gap: 16px; justify-content: center; white-space: pre-wrap; text-align: center; margin: 0; line-height: 1; }
.denaryValue { font-size: 56px; }
.hexValue { font-size: 48px; }
.binaryValue { font-size: 40px; }
.divider { height: 1px; background: rgba(255,255,255,.08); margin: 16px 0 16px; } .divider { height: 1px; background: rgba(255,255,255,.08); margin: 16px 0 16px; }
/* --- GRIDS & BITS --- */
.bitsWrap { width: 100%; }
.bitsGrid { --cols: 8; display: grid; grid-template-columns: repeat(var(--cols), minmax(92px, 1fr)); gap: 26px 22px; align-items: start; justify-items: center; }
.bitsGrid.bitsFew { justify-content: center; }
.bit { width: 100%; max-width: 140px; display: flex; flex-direction: column; align-items: center; gap: 8px; container-type: inline-size; }
.bitVal { font-family: var(--bit-font); font-size: min(32px, calc(140cqw / var(--len, 1))); letter-spacing: 2px; color: rgba(232,232,238,.85); white-space: nowrap; line-height: 1; }
.bulb { width: 44px; height: 44px; color: rgba(255,255,255,.15); margin-bottom: 8px; flex-shrink: 0; transition: 0.2s ease; background: transparent; display: flex; align-items: center; justify-content: center; } .bulb { width: 44px; height: 44px; color: rgba(255,255,255,.15); margin-bottom: 8px; flex-shrink: 0; transition: 0.2s ease; background: transparent; display: flex; align-items: center; justify-content: center; }
.bulb svg { width: 100%; height: 100%; display: block; } .bulb svg { width: 100%; height: 100%; display: block; }
.bulb.on { color: #ffd86b !important; filter: drop-shadow(0 0 14px rgba(255, 216, 107, 1)) !important; } .bulb.on { color: #ffd86b !important; filter: drop-shadow(0 0 14px rgba(255, 216, 107, 1)) !important; }
@@ -62,19 +92,137 @@ body { margin: 0; background: var(--bg); color: var(--text); font-family: var(--
.switch input:checked + .slider { background: rgba(40,240,122,.25); border-color: rgba(40,240,122,.30); } .switch input:checked + .slider { background: rgba(40,240,122,.25); border-color: rgba(40,240,122,.30); }
.switch input:checked + .slider::before { transform: translateX(28px); } .switch input:checked + .slider::before { transform: translateX(28px); }
/* --- HEXADECIMAL --- */
.hexGrid { --cols: 4; display: grid; grid-template-columns: repeat(var(--cols), minmax(160px, 1fr)); gap: 32px 20px; align-items: start; justify-items: center; width: 100%; }
.hexGrid.bitsFew { justify-content: center; }
.hexCol { display: flex; flex-direction: column; align-items: center; width: 100%; }
/* --- HEX COLOURS SPECIFIC --- */
.colorGroupWrap { display: flex; flex-wrap: nowrap; gap: 16px; justify-content: center; width: 100%; }
.colorGroup { display: flex; gap: 12px; padding: 12px; background: rgba(255,255,255,.02); border-radius: 20px; border: 1px solid rgba(255,255,255,.05); flex: 0 1 auto; min-width: 0; }
.colorPreviewSide { display: flex; gap: 24px; align-items: center; justify-content: center; }
.colorBoxWrap { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.colorBox { width: 60px; height: 60px; border-radius: 12px; border: 2px solid rgba(255,255,255,.15); box-shadow: 0 4px 16px rgba(0,0,0,.4); background-color: #000000; transition: background-color 0.2s ease; }
.colorBoxLabel { font-family: var(--ui-font); font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.text-red { color: #ff5555 !important; text-shadow: 0 0 18px rgba(255,85,85,.35) !important; }
.text-green { color: #28f07a !important; text-shadow: 0 0 18px rgba(40,240,122,.35) !important; }
.text-blue { color: #55aaff !important; text-shadow: 0 0 18px rgba(85,170,255,.35) !important; }
/* HEX CARD */
.hexCard { background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.08); border-radius: 16px; padding: 16px 14px; display: flex; flex-direction: column; align-items: center; gap: 16px; width: 100%; max-width: 190px; flex: 0 1 auto; min-width: 0; box-shadow: 0 4px 24px rgba(0,0,0,.2); backdrop-filter: blur(10px); }
.hexCardButtons { display: flex; gap: 10px; }
.hexCardBtn { width: 38px; height: 38px; border-radius: 10px; border: 1px solid rgba(255,255,255,.12); font-family: var(--bit-font); font-size: 16px; font-weight: 900; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; color: rgba(232,232,238,.92); transition: all 0.2s ease; }
.hexCardBtn.inc { background: rgba(40,240,122,.15); border-color: rgba(40,240,122,.25); }
.hexCardBtn.inc:hover { background: rgba(40,240,122,.25); border-color: rgba(40,240,122,.4); }
.hexCardBtn.dec { background: rgba(255,80,80,.18); border-color: rgba(255,80,80,.25); }
.hexCardBtn.dec:hover { background: rgba(255,80,80,.28); border-color: rgba(255,80,80,.4); }
.hexDigitDisplay { font-family: var(--num-font); font-size: 48px; color: #28f07a; text-shadow: 0 0 18px rgba(40,240,122,.35); line-height: 1; }
.hexNibbleRow { display: flex; gap: 10px; justify-content: center; width: 100%; }
.hexNibbleBit { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.hexNibbleBulb { width: 32px !important; height: 32px !important; margin-bottom: 2px !important; }
.hexNibbleLabel { font-family: var(--bit-font); font-size: 24px; color: rgba(232,232,238,.6); }
.hexColWeight { font-family: var(--bit-font); font-size: 40px; color: rgba(232,232,238,.6); margin-top: 14px; }
/* --- TOOLBOX --- */
.toolboxToggle { position: fixed; top: var(--toolbox-toggle-top); right: 22px; z-index: 90; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 12px; border: 1px solid rgba(255,255,255,.12); background: rgba(0,0,0,.15); backdrop-filter: blur(8px); color: rgba(232,232,238,.95); font-family: var(--bit-font); font-weight: 800; font-size: 16px; letter-spacing: .12em; text-transform: uppercase; cursor: pointer; }
.toolboxIcon { font-size: 20px; filter: drop-shadow(0 0 8px rgba(255,105,180,.35)); }
.toolboxToggle:hover { border-color: rgba(255,255,255,.22); }
.panelCol { position: fixed; top: var(--toolbox-top); right: 22px; width: var(--toolbox-w); z-index: 80; display: flex; flex-direction: column; gap: 16px; transform: translateX(0); opacity: 1; transition: transform 420ms cubic-bezier(.2,.9,.2,1), opacity 220ms ease; }
.binaryPage.toolboxCollapsed .panelCol { transform: translateX(calc(var(--toolbox-w) + 32px)); opacity: 0; pointer-events: none; }
.card { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.10); border-radius: 16px; padding: 16px; backdrop-filter: blur(10px); } .card { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.10); border-radius: 16px; padding: 16px; backdrop-filter: blur(10px); }
.cardTitle { font-family: var(--bit-font); font-weight: 900; letter-spacing: .14em; text-transform: uppercase; font-size: 18px; color: rgba(232,232,238,.9); margin-bottom: 12px; } .cardTitle { font-family: var(--bit-font); font-weight: 900; letter-spacing: .14em; text-transform: uppercase; font-size: 18px; color: rgba(232,232,238,.9); margin-bottom: 12px; }
.hint { font-family: var(--bit-font); font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: rgba(232,232,238,.55); margin-top: 10px; line-height: 1.35; } .hint { font-family: var(--bit-font); font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: rgba(232,232,238,.55); margin-top: 10px; line-height: 1.35; }
.toggleRow { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.toggleLabel { font-family: var(--bit-font); font-size: 16px; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; color: var(--muted); transition: color 0.2s, text-shadow 0.2s; }
.toggleLabel.activeMode { color: #28f07a; text-shadow: 0 0 12px rgba(40,240,122,.45); }
.subCard { margin-top: 12px; padding: 12px; border-radius: 14px; border: 1px solid rgba(255,255,255,.10); background: rgba(0,0,0,.12); }
.subTitle { font-family: var(--bit-font); font-weight: 900; letter-spacing: .14em; text-transform: uppercase; font-size: 16px; margin-bottom: 10px; opacity: .85; }
.bitWidthRow { display: flex; align-items: center; gap: 10px; }
.miniBtn { width: 44px; height: 44px; border-radius: 12px; border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.06); color: rgba(232,232,238,.9); font-family: var(--bit-font); font-weight: 900; font-size: 22px; cursor: pointer; }
.miniBtn:hover { border-color: rgba(255,255,255,.22); }
.bitInputWrap { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 10px; border-radius: 12px; border: 1px solid rgba(255,255,255,.10); background: rgba(255,255,255,.04); padding: 10px 12px; }
.bitInputLabel { font-family: var(--bit-font); font-size: 16px; letter-spacing: .12em; text-transform: uppercase; opacity: .7; }
.bitInput { width: 70px; text-align: right; font-family: var(--num-font); font-size: 28px; letter-spacing: 2px; color: #28f07a; background: transparent; border: none; outline: none; }
.btn { border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.06); color: rgba(232,232,238,.92); border-radius: 12px; padding: 10px 12px; font-family: var(--bit-font); font-size: 14px; letter-spacing: .12em; text-transform: uppercase; font-weight: 900; cursor: pointer; } .btn { border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.06); color: rgba(232,232,238,.92); border-radius: 12px; padding: 10px 12px; font-family: var(--bit-font); font-size: 14px; letter-spacing: .12em; text-transform: uppercase; font-weight: 900; cursor: pointer; }
.btn:hover { border-color: rgba(255,255,255,.22); } .btn:hover { border-color: rgba(255,255,255,.22); }
.btnAccent { background: rgba(40,240,122,.12); border-color: rgba(40,240,122,.22); } .btnAccent { background: rgba(40,240,122,.12); border-color: rgba(40,240,122,.22); }
.btnAccent:hover { border-color: rgba(40,240,122,.35); } .btnAccent:hover { border-color: rgba(40,240,122,.35); }
.btnHalf { width: calc(50% - 6px); } .btnHalf { width: calc(50% - 6px); }
.btnWide { width: 100%; } .btnWide { width: 100%; }
.controlsRow { display: flex; gap: 12px; margin-bottom: 12px; }
.toolRowCentered { display: flex; justify-content: center; gap: 10px; margin-bottom: 10px; }
.toolBtn { width: 46px; height: 46px; border-radius: 12px; border: 1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.06); color: rgba(232,232,238,.92); font-family: var(--bit-font); font-size: 16px; font-weight: 900; cursor: pointer; }
.toolDec { background: rgba(255,80,80,.20); border-color: rgba(255,80,80,.25); }
.toolInc { background: rgba(40,240,122,.18); border-color: rgba(40,240,122,.25); }
.btnReset { color: rgba(232,232,238,.95); } .btnReset { color: rgba(232,232,238,.95); }
.btnReset:hover { background: rgba(255,80,80,.18); border-color: rgba(255,80,80,.35); } .btnReset:hover { background: rgba(255,80,80,.18); border-color: rgba(255,80,80,.35); }
.toolboxToggle { position: fixed; top: var(--toolbox-toggle-top, calc(var(--nav-h) + 16px)); right: 22px; z-index: 90; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 12px; border: 1px solid rgba(255,255,255,.12); background: rgba(0,0,0,.15); backdrop-filter: blur(8px); color: rgba(232,232,238,.95); font-family: var(--bit-font); font-weight: 800; font-size: 16px; letter-spacing: .12em; text-transform: uppercase; cursor: pointer; } /* === CONTAINER QUERIES === */
.toolboxIcon { font-size: 20px; filter: drop-shadow(0 0 8px rgba(255,105,180,.35)); } @container (max-width: 1050px) {
.toolboxToggle:hover { border-color: rgba(255,255,255,.22); } .readoutContainer { gap: 40px; }
.colorGroupWrap { gap: 10px; }
.colorGroup { padding: 10px; gap: 8px; border-radius: 16px; }
.hexCard { padding: 12px 8px; width: 140px; gap: 12px; }
.hexDigitDisplay { font-size: 40px; }
.hexNibbleBulb { width: 24px !important; height: 24px !important; }
.hexNibbleLabel { font-size: 20px; }
.hexColWeight { font-size: 26px; margin-top: 10px; }
.hexCardBtn { width: 34px; height: 34px; font-size: 14px; }
}
@container (max-width: 800px) {
.readoutContainer { flex-direction: column; gap: 24px; }
.colorPreviewSide { padding-top: 0; }
.colorGroupWrap { gap: 6px; }
.colorGroup { padding: 6px; gap: 6px; border-radius: 12px; }
.hexCard { padding: 8px 4px; width: 90px; gap: 8px; border-radius: 10px; }
.hexDigitDisplay { font-size: 32px; }
.hexNibbleBulb { width: 16px !important; height: 16px !important; }
.hexNibbleLabel { font-size: 16px; }
.hexColWeight { font-size: 20px; margin-top: 6px; }
.hexCardBtn { width: 28px; height: 28px; font-size: 12px; }
.denaryValue, .hexValue, .binaryValue { font-size: 32px; gap: 10px; }
}
@media (max-width: 1100px) { .binaryPage { --toolbox-w: 330px; } .denaryValue { font-size: 48px; } .hexValue { font-size: 40px; } .binaryValue { font-size: 32px; } }
@media (max-width: 900px) { .binaryPage { --toolbox-w: 320px; } .bitsGrid { grid-template-columns: repeat(var(--cols), minmax(84px, 1fr)); } .hexGrid { grid-template-columns: repeat(var(--cols), minmax(130px, 1fr)); } }
.cc-sa:before {
background-image: url(https://creativecommons.org/wp-content/themes/vocabulary-theme/vocabulary/svg/cc/icons/cc-icons.svg#cc-sa);
float: left;
margin-left: -2.5em;
filter: invert(100%);
}
.cc-nc:before {
background-image: url(https://creativecommons.org/wp-content/themes/vocabulary-theme/vocabulary/svg/cc/icons/cc-icons.svg#cc-nc);
float: left;
margin-left: -2.5em;
filter: invert(100%);
}
.cc-by:before {
background-image: url(https://creativecommons.org/wp-content/themes/vocabulary-theme/vocabulary/svg/cc/icons/cc-icons.svg#cc-by);
float: left;
margin-left: -2.5em;
filter: invert(100%);
}
.cc-terms ul > li {
padding-left: 2.5em;
clear: both;
list-style: none;
margin-bottom: 2em;
min-height: 2em;
}
.cc-terms ul {
padding: 0;
font-size: 1.5rem;
font-style: normal;
font-weight: 400;
line-height: 150%;
margin: 0 0 2em 2em;
}