Breaking the Ice is an interactive science exhibit designed for pupils, teachers, and the public. It combines:
- A 3D visualization showing the evolution of Arctic sea ice thickness over time.
- A 2D quiz game with scientific questions related to sea ice and climate change.
The stand is designed for touch interaction (tablets, iPads, or touchscreen laptops), supported by a pull-up banner and live facilitators.
Live demo: https://breakingtheice.space/
Visitors should leave with:
- Better awareness of climate change and its impact on oceans.
- Stronger scientific inquiry skills through scenario-based questioning.
- Better understanding of human impact on marine ecosystems.
This repository contains the frontend for the interactive experience, built with Next.js and exported as a static site for GitHub Pages.
- Node.js 20+
- npm
npm ciThis project uses patch-package to persist a local fix for @carbonplan/zarr-layer.
- Patch file:
patches/@carbonplan+zarr-layer+0.5.0.patch - Applied automatically via the
postinstallscript inpackage.json
If the @carbonplan/zarr-layer version changes, regenerate the patch for the new version.
npm run devOpen http://localhost:3000 in your browser.
npm run buildBuild generates a production-ready static export in the out folder.
npm run formatUse this to normalize style and reduce noisy diffs.
npm run format:checknpm run lintLint catches potential bugs, accessibility issues, and consistency problems.
Running build, format checks, and lint before push helps you:
- Catch failures early (before CI fails on main).
- Keep code consistent and easier to review.
- Reduce risk of broken deployments to GitHub Pages.
Recommended pre-push sequence:
npm run format:check
npm run lint
npm run buildThis project deploys through GitHub Actions using:
- Workflow: .github/workflows/nextjs.yml
- Trigger: push to main (and manual workflow_dispatch)
- Build output: out
- Deployment target: GitHub Pages
Assets are managed in two layers:
- Static files live in the public folder (png, svg, etc.).
- Application references use a centralized map in app/components/assets.ts.
The assets map prepends NEXT_PUBLIC_BASE_PATH so paths continue to work in static export/deployment contexts.
Example pattern:
- Add file to public/
- Register it in app/components/assets.ts
- Use it from components via ASSETS.
This keeps paths consistent and avoids hardcoding strings across multiple components.
Quiz content is driven by:
- Data file: app/data/questions.json
- Type definition: app/types/quiz.ts
- Rendering component: app/components/QuestionsStage.tsx
Each question object should include:
- id: unique string (for example q1)
- title: displayed heading
- scenario: explanatory paragraph
- question: the actual prompt
- imageSource: Image source
- options: array of 3 option objects (See Option Object Description below)
- correctIndex: zero-based index of the correct option
- bg: stage background color (hex)
- media: optional array of one or two image paths (See Media Object Description below)
Each option object currently supports:
- image: optional image path
- text: option label shown on the card
- explanation: feedback text for learning context
- width: width of the image
- height: height of the image
Each media object currently supports:
- image: optional image path
- position: position of the image (front or back)
- transform: rotation of the image
- width: width of the image
- height: height of the image
- Add new image files or modify existing ones in the public folder
- Reference them in app/data/questions.json using paths like /my_image.png
- Update the width and height of the option image in the options array accordingly
- Add new image files or modify existing ones in the public folder
- Reference them in app/data/questions.json using paths like /my_image.png
- For media pairs, place them in the media array in the order you want them layered
- Update the width and height of the image in the media array accordingly
Run these commands before pushing:
npm run format:check
npm run lint
npm run build