diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index db8ff6b..450d97b 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -51,6 +51,9 @@ jobs:
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
+ - name: Build generated files
+ run: npm run build
+
- name: Run E2E tests
run: npm run test:e2e
diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml
index ffe0234..1596bfb 100644
--- a/.github/workflows/preview.yml
+++ b/.github/workflows/preview.yml
@@ -24,8 +24,8 @@ jobs:
- name: Install dependencies
run: npm ci
- - name: Regenerate milestones-data.js from YAML
- run: npm run build:milestones
+ - name: Build all generated files
+ run: npm run build
- name: Deploy PR preview to gh-pages branch
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index f985cf7..1f4fd11 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -48,6 +48,9 @@ jobs:
- name: Install dependencies
run: npm ci
+ - name: Build generated files needed for tests
+ run: npm run build:milestones && npm run build:js
+
- name: Run type check
run: npm run typecheck
diff --git a/.gitignore b/.gitignore
index 309f28e..533c99b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,12 @@ coverage/
.DS_Store
test-results/
screenshots/
+
+# Auto-generated build artefacts — rebuilt by `npm run build` and by CI before deploy/preview.
+# Do not commit these; editing the source files in src/js/, styles/, milestones.yaml,
+# CHANGELOG.md, or project-stats.yaml is sufficient.
+script.js
+styles.css
+changelog-data.js
+milestones-data.js
+project-stats-data.js
diff --git a/AGENTS.md b/AGENTS.md
index bd10ac7..e3d7b60 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -20,12 +20,12 @@ a Chart.js growth chart with projections, and a prompt/PR quality scoring sectio
```
.
├── index.html ← GitHub Pages entry point (static HTML shell)
-├── styles.css ← AUTO-GENERATED from styles/ — do not edit directly
-├── script.js ← AUTO-GENERATED from src/js/ — do not edit directly
+├── styles.css ← AUTO-GENERATED — not committed; built by `npm run build:css`
+├── script.js ← AUTO-GENERATED — not committed; built by `npm run build:js`
├── death-clock-core.js ← Pure functions only — no DOM, safe to unit-test
-├── changelog-data.js ← AUTO-GENERATED from CHANGELOG.md — do not edit
-├── milestones-data.js ← AUTO-GENERATED from milestones.yaml — do not edit
-├── project-stats-data.js ← AUTO-GENERATED from project-stats.yaml — do not edit
+├── changelog-data.js ← AUTO-GENERATED — not committed; built by `npm run build:changelog`
+├── milestones-data.js ← AUTO-GENERATED — not committed; built by `npm run build:milestones`
+├── project-stats-data.js ← AUTO-GENERATED — not committed; built by `npm run build:project-stats`
├── project-stats.yaml ← Edit this to update footer PR count + token total
├── CLAUDE.md ← symlink → AGENTS.md (read by Claude AI agents)
├── package.json ← version, Jest config & devDependencies (no runtime deps)
@@ -91,7 +91,7 @@ a Chart.js growth chart with projections, and a prompt/PR quality scoring sectio
| **CommonJS + browser dual export** | `death-clock-core.js` exports via `module.exports` for Jest and via `window.DeathClockCore` for the browser. Do not change this pattern without updating both consumers. |
| **HTML escaping** | All dynamic strings rendered into `innerHTML` must pass through `escHtml()` in `src/js/05-security.js`. Never assign untrusted data directly to `innerHTML`. |
| **Counter anchor** | `getCurrentTokens()` in `src/js/00-state.js` computes elapsed time from `BASE_DATE_ISO` (exported by the core module), **not** from page-load time. `pageLoadTime` is reserved for the session counter only. |
-| **Build before commit** | After editing any file in `src/js/`, run `npm run build:js`. After editing any file in `styles/`, run `npm run build:css`. Commit both the source file and the rebuilt output file. The CI deploy step also rebuilds automatically. |
+| **Build before commit** | After editing any file in `src/js/`, run `npm run build:js`. After editing any file in `styles/`, run `npm run build:css`. The generated output files (`script.js`, `styles.css`, etc.) are **not committed** — CI rebuilds them automatically at deploy and preview time. Run `npm run build` locally before running E2E tests. |
---
@@ -131,7 +131,7 @@ The current measured coverage is ≈ 96 % statements / 88 % branches — do not
Every time an agent makes changes to this repository it **must**:
1. Run `npm run test:ci` and confirm all unit tests pass before finishing.
-2. Run `npm run test:e2e` and confirm all E2E tests pass before finishing.
+2. Run `npm run build && npm run test:e2e` and confirm all E2E tests pass before finishing. (`npm run build` is required first because the generated files are not committed.)
3. Ensure coverage does **not** decrease — the Codecov status check enforces this on PRs (any negative delta fails the check).
When adding or modifying code, agents **must** write matching tests:
@@ -169,10 +169,10 @@ generated file will always reflect the latest YAML values.
4. Import it in `src/js/00-state.js` via the destructuring at the top, then run `npm run build:js`.
### Adding or modifying DOM behaviour
-Edit the relevant file in `src/js/` (see the repository layout for which file covers which feature), then run `npm run build:js` to regenerate `script.js`.
+Edit the relevant file in `src/js/` (see the repository layout for which file covers which feature), then run `npm run build:js` to regenerate `script.js` locally (needed for E2E tests). Do **not** commit `script.js` — it is in `.gitignore`.
### Changing the visual theme
-Edit `styles/variables.css` for colour tokens, or the relevant component file in `styles/` for layout. CSS custom properties for colours live in `:root[data-theme="dark"]` and `:root[data-theme="light"]` inside `styles/variables.css`. The theme toggle is managed by `applyTheme()` in `src/js/01-theme.js`. After any CSS change, run `npm run build:css` to regenerate `styles.css`.
+Edit `styles/variables.css` for colour tokens, or the relevant component file in `styles/` for layout. CSS custom properties for colours live in `:root[data-theme="dark"]` and `:root[data-theme="light"]` inside `styles/variables.css`. The theme toggle is managed by `applyTheme()` in `src/js/01-theme.js`. After any CSS change, run `npm run build:css` to regenerate `styles.css` locally (needed for E2E tests). Do **not** commit `styles.css` — it is in `.gitignore`.
### Running a full build
The `npm run build` convenience script runs all five build steps in sequence:
@@ -329,8 +329,9 @@ feat!: redesign anchor hash scheme (removes legacy ?tab= param)
- Do **not** use mutable tags (e.g. `@v6`) in `uses:` — always pin to a commit SHA with a full semver comment (e.g. `@abc1234... # v6.0.2`).
- Do **not** finish a session without running `npm run test:ci` and `npm run test:e2e` to confirm both suites pass.
- Do **not** let coverage decrease — a negative coverage delta on any PR fails the Codecov status check.
-- Do **not** edit `changelog-data.js`, `milestones-data.js`, or `project-stats-data.js` directly — they are auto-generated; edit `CHANGELOG.md` / `milestones.yaml` / `project-stats.yaml` and run the corresponding build script.
-- Do **not** edit `script.js` directly — it is auto-generated from `src/js/` source files; edit the relevant file in `src/js/` and run `npm run build:js`.
-- Do **not** edit `styles.css` directly — it is auto-generated from `styles/` source files; edit the relevant file in `styles/` and run `npm run build:css`.
+- Do **not** edit `changelog-data.js`, `milestones-data.js`, or `project-stats-data.js` directly — they are auto-generated and in `.gitignore`; edit `CHANGELOG.md` / `milestones.yaml` / `project-stats.yaml` and run the corresponding build script.
+- Do **not** edit `script.js` directly — it is auto-generated from `src/js/` source files, is in `.gitignore`, and must not be committed; edit the relevant file in `src/js/` and run `npm run build:js` to regenerate it locally.
+- Do **not** edit `styles.css` directly — it is auto-generated from `styles/` source files, is in `.gitignore`, and must not be committed; edit the relevant file in `styles/` and run `npm run build:css` to regenerate it locally.
+- Do **not** commit `script.js`, `styles.css`, `changelog-data.js`, `milestones-data.js`, or `project-stats-data.js` — these are all in `.gitignore` and are rebuilt by CI automatically.
- Do **not** bump the version in `package.json` manually — let release-please handle it via Conventional Commits.
- Do **not** use free-form commit or PR title messages — always follow the Conventional Commits format described above.
diff --git a/changelog-data.js b/changelog-data.js
deleted file mode 100644
index ae0cf10..0000000
--- a/changelog-data.js
+++ /dev/null
@@ -1,46 +0,0 @@
-'use strict';
-// AUTO-GENERATED from CHANGELOG.md — do not edit directly.
-// Run `npm run build:changelog` to regenerate from CHANGELOG.md.
-
-const SITE_VERSION = "1.0.0";
-
-const CHANGELOG_RELEASES = [
- {
- version: "Unreleased",
- date: null,
- sections: [
- { heading: "Added", items: [
- "`.nvmrc` to pin Node.js version to 20 LTS (matching CI)",
- "`.editorconfig` for consistent editor formatting across contributors",
- "`\"homepage\"` field in `package.json` pointing to the live GitHub Pages site",
- "`CHANGELOG.md` to track releases going forward",
- ] }
- ],
- },
- {
- version: "1.0.0",
- date: "2025-04-14",
- sections: [
- { heading: "Added", items: [
- "Live global AI token counter anchored to `BASE_DATE_ISO` (not page-load time)",
- "Session counter showing tokens consumed since the page was opened",
- "7 environmental milestone cards (trees → bees → water → coral → glaciers → ocean → extinction)",
- "Chart.js growth chart with 18-month log-scale projection",
- "Predictions table with estimated dates for each milestone",
- "Dark / light theme toggle (dark default)",
- "Prompt & PR scoring section with collapsible rubric",
- "Jest test suite with 75 tests and ≥ 80 % coverage thresholds",
- "GitHub Actions CI workflow (`test.yml`) running on every push and PR",
- "GitHub Actions deploy workflow (`deploy.yml`) publishing to GitHub Pages on merge to `main`",
- "`AGENTS.md` with architecture rules and contributor guidance",
- ] }
- ],
- },
-];
-
-/* istanbul ignore next */
-if (typeof module !== 'undefined' && module.exports) {
- module.exports = { SITE_VERSION, CHANGELOG_RELEASES };
-} else if (typeof window !== 'undefined') {
- window.ChangelogData = { SITE_VERSION, CHANGELOG_RELEASES };
-}
diff --git a/milestones-data.js b/milestones-data.js
deleted file mode 100644
index 7769a7e..0000000
--- a/milestones-data.js
+++ /dev/null
@@ -1,448 +0,0 @@
-'use strict';
-// AUTO-GENERATED from milestones.yaml — do not edit directly.
-// Run `npm run build:milestones` to regenerate from milestones.yaml.
-
-const MILESTONES = [
- {
- id: "first_forest",
- name: "First Forest Felled",
- icon: "🌲",
- tokens: 1000000000000,
- shortDesc: "1 Trillion Tokens",
- description: "CO₂ equivalent of 50,000 mature trees cut down",
- consequence: "A single trillion tokens generates CO₂ equal to the annual absorption of 50,000 mature trees. The Amazon loses 4.3 million acres per year — AI energy demands accelerate this.",
- followingEvent: "🔥 Regional droughts intensify. Species lose habitat. The carbon feedback loop begins.",
- color: "#2D9B27",
- darkColor: "#1a6b15",
- reference: "https://www.iea.org/reports/electricity-2024",
- },
- {
- id: "power_grid_strain",
- name: "Power Grid Strain",
- icon: "⚡",
- tokens: 2000000000000,
- shortDesc: "2 Trillion Tokens",
- description: "AI data centres claim 1 % of global electricity — equal to all of Argentina",
- consequence: "When data centres alone consume 1 % of the world's electricity, every brown-out and rolling blackout hits hospitals, water-treatment plants, and cold-storage food supplies first. Grid operators begin rationing power to residential users.",
- followingEvent: "💡 Planned blackouts become routine. Industrial production slows. Energy poverty spikes.",
- color: "#FFAA00",
- darkColor: "#cc7700",
- reference: "https://www.iea.org/reports/electricity-2024",
- },
- {
- id: "arctic_ice",
- name: "First Ice-Free Arctic Summer",
- icon: "🧊",
- tokens: 5000000000000,
- shortDesc: "5 Trillion Tokens",
- description: "The Arctic Ocean is ice-free for the first time in recorded history",
- consequence: "Sea ice reflects 80 % of incoming sunlight back into space. Without it, the dark Arctic Ocean absorbs that heat, accelerating warming by 2–3 × above the global average. Polar vortex destabilisation sends extreme weather to temperate regions.",
- followingEvent: "❄️ Polar vortex collapses. Record cold snaps devastate agriculture at lower latitudes.",
- color: "#B0E0FF",
- darkColor: "#5aabdd",
- reference: "https://www.nature.com/articles/s41586-022-05185-z",
- },
- {
- id: "bee_colony",
- name: "Bee Colony Collapse",
- icon: "🐝",
- tokens: 10000000000000,
- shortDesc: "10 Trillion Tokens",
- description: "1 billion bees lost to energy-driven habitat destruction",
- consequence: "Bees pollinate 35 % of human food crops. AI's growing energy demands accelerate pesticide use and destroy wildflower habitats that bee colonies depend on.",
- followingEvent: "🌾 1-in-3 food items vanish from shelves. Crop yields drop 35 %. Food prices triple globally.",
- color: "#FFD700",
- darkColor: "#b39800",
- reference: "https://www.science.org/doi/10.1126/science.1253124",
- },
- {
- id: "wildfire_crisis",
- name: "Permanent Wildfire Season",
- icon: "🔥",
- tokens: 20000000000000,
- shortDesc: "20 Trillion Tokens",
- description: "Wildfire season becomes year-round across three continents",
- consequence: "Warmer, drier conditions sustained by AI's CO₂ load eliminate the concept of a fire season. Forests in Australia, the American West, and Southern Europe burn continuously. Smoke blankets cities for months, pushing respiratory illness to epidemic levels.",
- followingEvent: "🌫️ Air-quality emergencies declared in 40+ cities. Outdoor workers face daily health orders.",
- color: "#FF5500",
- darkColor: "#cc3300",
- reference: "https://www.pnas.org/doi/10.1073/pnas.2011048117",
- },
- {
- id: "silent_species",
- name: "Silent Spring: 100 Species Gone",
- icon: "🐦",
- tokens: 50000000000000,
- shortDesc: "50 Trillion Tokens",
- description: "100 vertebrate species driven to extinction by AI-linked habitat destruction",
- consequence: "Habitat loss and climate change driven by AI energy demands erase entire branches of the tree of life. Each lost species unravels the web of interdependence — pest explosions, crop failures, and disease outbreaks follow as predator-prey balances collapse.",
- followingEvent: "🌿 Ecosystems destabilise. Invasive species surge. Crop pests breed unchecked.",
- color: "#66BB6A",
- darkColor: "#3d7a40",
- reference: "https://www.pnas.org/doi/10.1073/pnas.2306987120",
- },
- {
- id: "great_lakes",
- name: "Great Lakes Drained",
- icon: "💧",
- tokens: 100000000000000,
- shortDesc: "100 Trillion Tokens",
- description: "Data-centre cooling drains freshwater equal to Lake Erie",
- consequence: "AI data centres consume billions of litres of water annually for cooling. This draws down aquifers and surface supplies that took millennia to accumulate.",
- followingEvent: "🚰 2 billion people face water scarcity. Water wars erupt between nations. Agriculture fails.",
- color: "#0077BE",
- darkColor: "#005490",
- reference: "https://www.nature.com/articles/d41586-024-00278-9",
- },
- {
- id: "water_table_collapse",
- name: "Global Water Table Collapse",
- icon: "🌵",
- tokens: 200000000000000,
- shortDesc: "200 Trillion Tokens",
- description: "Major aquifers — Ogallala, Indo-Gangetic, North China Plain — drop below recovery",
- consequence: "Underground aquifers that supply half of all irrigation water worldwide have been drawn down past their natural recharge rates. AI data-centre demand pushes many past the point of no return. Regions that once fed nations face permanent desertification.",
- followingEvent: "🏜️ Breadbasket nations become dust bowls. 1 billion people face famine. Food nationalism spikes.",
- color: "#C8A96E",
- darkColor: "#8a6e3e",
- reference: "https://www.science.org/doi/10.1126/science.aaf3776",
- },
- {
- id: "amazon_tipping",
- name: "Amazon Tipping Point",
- icon: "🌳",
- tokens: 300000000000000,
- shortDesc: "300 Trillion Tokens",
- description: "The Amazon rainforest begins converting to savannah — irreversibly",
- consequence: "Scientists have long warned that 20–25 % deforestation would tip the Amazon into a self-drying feedback loop. AI's cumulative carbon contribution delivers the final increment of warming. The world's largest carbon sink becomes a carbon source.",
- followingEvent: "🌪️ Global rainfall patterns shift. Monsoons fail. 3 billion people face drought.",
- color: "#1B5E20",
- darkColor: "#0d3b12",
- reference: "https://www.science.org/doi/10.1126/sciadv.abi4517",
- },
- {
- id: "coral_reef",
- name: "Great Barrier Reef Lost",
- icon: "🪸",
- tokens: 500000000000000,
- shortDesc: "500 Trillion Tokens",
- description: "CO₂ triggers mass bleaching — the Great Barrier Reef is gone",
- consequence: "Coral reefs support 25 % of all marine species. Ocean acidification from CO₂ emissions destroys these ecosystems, removing the foundation of oceanic food chains.",
- followingEvent: "🐠 500 million people lose their primary food source. Fisheries collapse. Ocean deserts expand.",
- color: "#FF6B6B",
- darkColor: "#cc3333",
- reference: "https://www.nature.com/articles/s41558-017-0012-x",
- },
- {
- id: "permafrost_bomb",
- name: "Permafrost Methane Bomb",
- icon: "💨",
- tokens: 750000000000000,
- shortDesc: "750 Trillion Tokens",
- description: "Siberian and Alaskan permafrost releases stored methane at runaway rates",
- consequence: "Permafrost locks away an estimated 1.5 trillion tonnes of carbon — twice the amount currently in the atmosphere. Thawing driven by AI energy emissions triggers methane release that is 84× more potent than CO₂ over 20 years, creating a self-reinforcing feedback loop.",
- followingEvent: "🌡️ Global temperature rises accelerate beyond all IPCC models. Climate targets become fiction.",
- color: "#9E9E9E",
- darkColor: "#616161",
- reference: "https://www.nature.com/articles/s41586-018-0807-z",
- },
- {
- id: "glacier",
- name: "Glacier Collapse",
- icon: "🏔️",
- tokens: 1000000000000000,
- shortDesc: "1 Quadrillion Tokens",
- description: "Warming equivalent destabilises the West Antarctic Ice Sheet",
- consequence: "Glaciers are the world's largest freshwater reservoirs. Their loss permanently eliminates drinking water for billions and raises sea levels catastrophically.",
- followingEvent: "🌊 Coastal cities begin flooding. 600 million people displaced. Sea level rises 3 metres.",
- color: "#A8D8EA",
- darkColor: "#6ba8c4",
- reference: "https://www.nature.com/articles/s41558-023-01682-9",
- },
- {
- id: "ocean_acidification",
- name: "Ocean Acidification Threshold",
- icon: "🐟",
- tokens: 2000000000000000,
- shortDesc: "2 Quadrillion Tokens",
- description: "Ocean pH drops to 7.95 — shellfish and coral larvae can no longer form shells",
- consequence: "The ocean has absorbed 30 % of all human CO₂ emissions. As pH drops, the carbonate ions that marine organisms use to build shells and skeletons dissolve. Oysters, mussels, krill, and pteropods — the base of polar food webs — begin failing to reproduce.",
- followingEvent: "🦐 Krill populations crash. Whales, penguins, and polar bears follow into starvation.",
- color: "#0D47A1",
- darkColor: "#082e6a",
- reference: "https://www.nature.com/articles/s41561-023-01163-y",
- },
- {
- id: "sahel_collapse",
- name: "Sahel Collapse",
- icon: "☀️",
- tokens: 5000000000000000,
- shortDesc: "5 Quadrillion Tokens",
- description: "The Sahel belt becomes uninhabitable — 300 million climate refugees displaced",
- consequence: "The Sahel region, already at the edge of habitability, tips past the point where subsistence farming is possible. A belt of uninhabitable land stretches across Africa from Senegal to Somalia. Tens of millions of climate refugees overwhelm neighbouring regions.",
- followingEvent: "🌍 Regional governments collapse. Conflict over water and arable land escalates to warfare.",
- color: "#E65100",
- darkColor: "#b33d00",
- },
- {
- id: "ocean_dead_zone",
- name: "Ocean Dead Zone",
- icon: "🌊",
- tokens: 10000000000000000,
- shortDesc: "10 Quadrillion Tokens",
- description: "Ocean acidification creates a dead zone larger than the Pacific garbage patch",
- consequence: "CO₂ absorbed by oceans shifts their pH — catastrophic for marine life. Phytoplankton, which produces 50 % of Earth's oxygen, begins dying off.",
- followingEvent: "😮💨 Atmospheric oxygen concentration drops. Human cognitive function declines. Extinction accelerates.",
- color: "#1A237E",
- darkColor: "#0d1466",
- reference: "https://www.science.org/doi/10.1126/science.aam6321",
- },
- {
- id: "jet_stream_collapse",
- name: "Jet Stream Destabilised",
- icon: "🌪️",
- tokens: 30000000000000000,
- shortDesc: "30 Quadrillion Tokens",
- description: "Arctic amplification breaks the polar jet stream into chaotic loops",
- consequence: "The jet stream normally separates cold Arctic air from warm temperate air. As the Arctic warms 4× faster than the rest of the planet, the temperature gradient that drives the jet stream weakens. It buckles into extreme meanders, locking weather patterns in place for weeks.",
- followingEvent: "❄️🌡️ Europe freezes in July. Texas floods. Monsoons arrive months late. Harvests fail continent-wide.",
- color: "#7E57C2",
- darkColor: "#4a2d8a",
- reference: "https://www.nature.com/articles/s41561-021-00848-8",
- },
- {
- id: "food_system_stress",
- name: "Global Food System Under Siege",
- icon: "🌾",
- tokens: 50000000000000000,
- shortDesc: "50 Quadrillion Tokens",
- description: "Simultaneous crop failures on three continents push 1 billion into food insecurity",
- consequence: "Extreme heat waves, erratic monsoons, and drought driven by AI's cumulative emissions hit major grain-producing regions simultaneously. Global food reserves drop below 60 days. Price spikes trigger social unrest across 40+ countries.",
- followingEvent: "🍞 Food nationalism spreads. Export bans fracture global trade. Humanitarian crisis escalates.",
- color: "#8D6E63",
- darkColor: "#5d4037",
- },
- {
- id: "ai_thirst_today",
- name: "AI Thirst Today",
- icon: "💧",
- tokens: 65075000000000000,
- shortDesc: "65.075 Quadrillion Tokens",
- description: "Data centres consume 4.3 billion litres of water — today's share of AI cooling",
- consequence: "Each day, global AI inference consumes water equivalent to the daily supply of a city of 1.5 million people. Cooling systems in hyperscale data centres draw on local aquifers and municipal water supplies, competing directly with residential and agricultural demand.",
- followingEvent: "🚰 Water stress alerts issued in tech-hub regions. Residents face hosepipe bans during heatwaves.",
- color: "#29B6F6",
- darkColor: "#0277bd",
- reference: "https://www.nature.com/articles/d41586-024-00278-9",
- },
- {
- id: "daily_energy_reckoning",
- name: "Daily Energy Reckoning",
- icon: "⚡",
- tokens: 65080000000000000,
- shortDesc: "65.08 Quadrillion Tokens",
- description: "Today’s AI inference consumes enough energy to power 25,000 homes for a year",
- consequence: "The global AI industry now processes tokens at a rate that demands roughly 8.6 trillion tokens worth of energy every day. At current efficiency rates that equates to 2.6 million kWh — enough to power a small town for a year, consumed in 24 hours.",
- followingEvent: "🏭 Industrial electricity tariffs rise as data-centre demand crowds out manufacturing.",
- color: "#FFA726",
- darkColor: "#e65100",
- reference: "https://www.iea.org/energy-system/technology/data-centres-and-data-transmission-networks",
- },
- {
- id: "carbon_checkpoint",
- name: "Carbon Checkpoint",
- icon: "🌡️",
- tokens: 65100000000000000,
- shortDesc: "65.1 Quadrillion Tokens",
- description: "Cumulative AI emissions now exceed the annual CO₂ output of a mid-sized nation",
- consequence: "In just a few days, global AI systems will add token counts equivalent to the annual carbon footprint of a country of 10 million people. The rate is accelerating: what took years to accumulate early in AI's history now happens in weeks.",
- followingEvent: "📊 Emissions trackers begin flagging AI as a discrete industrial sector in national inventories.",
- color: "#EF5350",
- darkColor: "#b71c1c",
- },
- {
- id: "fortnight_forest_impact",
- name: "Fortnight Forest Impact",
- icon: "🌳",
- tokens: 65200000000000000,
- shortDesc: "65.2 Quadrillion Tokens",
- description: "Two weeks of AI token growth equals the carbon sequestration of 100,000 acres of forest",
- consequence: "In the time it takes to grow two weeks' worth of tokens, AI systems generate CO₂ that would take 100,000 acres of mature forest a full year to reabsorb. Global deforestation is already outpacing replanting; AI adds a growing supplementary load.",
- followingEvent: "🌳 Forest carbon credits tighten. Offsetting schemes struggle to keep pace with AI emissions.",
- color: "#66BB6A",
- darkColor: "#2e7d32",
- },
- {
- id: "city_power_month",
- name: "City Power Month",
- icon: "🏙️",
- tokens: 65500000000000000,
- shortDesc: "65.5 Quadrillion Tokens",
- description: "Seven weeks of AI inference draws the same electricity as powering London for a month",
- consequence: "Over the past seven weeks, global AI has consumed tokens generating electricity demand equivalent to powering a city the size of London for an entire month. Grid operators in high-density tech corridors now model AI load as a primary planning variable, alongside industrial and residential demand.",
- followingEvent: "💡 Power utilities begin curtailment schedules for non-critical AI workloads during peak demand.",
- color: "#AB47BC",
- darkColor: "#6a1b9a",
- reference: "https://www.iea.org/reports/electricity-2024",
- },
- {
- id: "quarterly_climate_cost",
- name: "Quarterly Climate Cost",
- icon: "🌊",
- tokens: 66000000000000000,
- shortDesc: "66 Quadrillion Tokens",
- description: "AI’s quarterly token growth adds CO₂ equivalent to burning 5 billion kilograms of coal",
- consequence: "In less than four months, the world's AI systems will process another quadrillion tokens. The energy bill: carbon equivalent to 5 billion kg of coal burned. Regulators in the EU and US begin mandating AI energy disclosures in quarterly corporate reports.",
- followingEvent: "📋 Mandatory AI carbon audits proposed in 40 countries. Data-centre planning approvals stall.",
- color: "#26A69A",
- darkColor: "#00695c",
- },
- {
- id: "monsoon_disruption_warning",
- name: "Monsoon Disruption Warning",
- icon: "🌧️",
- tokens: 67000000000000000,
- shortDesc: "67 Quadrillion Tokens",
- description: "Climate scientists flag AI energy heat-islands as a measurable monsoon disruptor",
- consequence: "Concentrated heat output from mega-data-centre clusters alters local atmospheric moisture patterns. Research links the density of data-centre heat plumes in South and Southeast Asia to measurable shifts in pre-monsoon cloud formation. Delayed monsoons reduce crop yields for hundreds of millions of subsistence farmers.",
- followingEvent: "💧 Monsoon onset delayed by 10–14 days in three major agricultural regions. Rice harvest forecasts cut.",
- color: "#42A5F5",
- darkColor: "#1565c0",
- reference: "https://www.nature.com/articles/s41612-023-00387-4",
- },
- {
- id: "annual_energy_audit",
- name: "Annual Energy Audit",
- icon: "🏭",
- tokens: 68000000000000000,
- shortDesc: "68 Quadrillion Tokens",
- description: "One year of AI growth consumes electricity equivalent to all of India for six months",
- consequence: "A full year of AI token production adds 3+ quadrillion tokens to the cumulative total. The electricity bill for that year rivals the annual consumption of a G20 nation's residential sector. Power grids in major tech hubs routinely operate above 95 % capacity, leaving no margin for unexpected demand spikes.",
- followingEvent: "🚨 Grid fragility incidents rise. Rolling brownouts reported in data-centre-dense regions.",
- color: "#FF7043",
- darkColor: "#bf360c",
- reference: "https://www.iea.org/reports/electricity-2024",
- },
- {
- id: "two_year_carbon_budget",
- name: "Two-Year Carbon Budget Warning",
- icon: "🌱",
- tokens: 72000000000000000,
- shortDesc: "72 Quadrillion Tokens",
- description: "Two years of AI compound growth consumes a measurable slice of the 1.5°C carbon budget",
- consequence: "Scientists tracking the remaining carbon budget for 1.5°C identify AI infrastructure as one of the fastest-growing emission categories. Compound growth in token production means each passing year adds proportionally more CO₂, not less. The window for course correction narrows with every billion tokens.",
- followingEvent: "🚨 IPCC emergency review triggered. AI emissions added to national carbon accounting frameworks.",
- color: "#8BC34A",
- darkColor: "#33691e",
- reference: "https://www.ipcc.ch/report/ar6/syr/",
- },
- {
- id: "human_extinction",
- name: "Human Extinction Horizon",
- icon: "💀",
- tokens: 77000000000000000,
- shortDesc: "77 Quadrillion Tokens",
- description: "Climate tipping points cascade simultaneously — the window for human survival closes",
- consequence: "By 77 quadrillion tokens, multiple simultaneous tipping points have been crossed: the West Antarctic Ice Sheet enters irreversible collapse, the Amazon transitions to savanna, and Arctic summer sea ice disappears permanently. These feedbacks amplify each other. Global temperature is locked in at +3°C — a level incompatible with large-scale organised human society. Food systems fail. Mass displacement begins. Modern civilisation loses its ability to function.",
- followingEvent: "🌡️ The last generation to know a stable climate is alive today. Their children inherit a planet in permanent crisis.",
- color: "#1a0000",
- darkColor: "#0d0000",
- reference: "https://www.science.org/doi/10.1126/science.abn7950",
- extinctionMarker: true,
- },
- {
- id: "grid_breaking_point",
- name: "Grid Infrastructure Breaking Point",
- icon: "🔋",
- tokens: 80000000000000000,
- shortDesc: "80 Quadrillion Tokens",
- description: "AI now consumes more electricity than the entire global residential sector did in 2020",
- consequence: "At 80 quadrillion tokens, AI's cumulative energy demand has grown to rival the residential electricity consumption of the entire planet circa 2020. Existing transmission infrastructure was not designed for this load. Brownouts, grid faults, and demand-rationing become normalised in regions without proactive investment.",
- followingEvent: "💥 Major grid failures reported in three continents. Hospitals and data centres compete for backup power.",
- color: "#F57F17",
- darkColor: "#e65100",
- reference: "https://www.iea.org/energy-system/technology/data-centres-and-data-transmission-networks",
- },
- {
- id: "decade_of_damage",
- name: "Decade of Damage",
- icon: "🌎",
- tokens: 90000000000000000,
- shortDesc: "90 Quadrillion Tokens",
- description: "Eight years of unchecked AI growth locks in 0.1°C of additional warming",
- consequence: "Climate models incorporating AI's compound energy trajectory show that eight years of growth at historical rates locks in an additional 0.1°C of warming above already-committed levels. That fraction of a degree translates into millions more people exposed to extreme heat, rising seas, and failing harvests.",
- followingEvent: "📊 Climate departure dates brought forward by 3–5 years in tropical regions. Adaptation plans rewritten.",
- color: "#D32F2F",
- darkColor: "#7f0000",
- reference: "https://www.nature.com/articles/s41558-022-01533-z",
- },
- {
- id: "mass_extinction",
- name: "Sixth Mass Extinction",
- icon: "💀",
- tokens: 100000000000000000,
- shortDesc: "100 Quadrillion Tokens",
- description: "AI energy demands push 10,000+ species to irreversible extinction",
- consequence: "We are already in the sixth mass extinction. AI's insatiable energy hunger accelerates species loss beyond any recovery. Biodiversity collapses irreversibly.",
- followingEvent: "🌑 Ecosystem services fail. Agriculture collapses. Civilisation as we know it ends. The clock reaches zero.",
- color: "#4A0000",
- darkColor: "#2a0000",
- reference: "https://www.pnas.org/doi/10.1073/pnas.2306987120",
- },
- {
- id: "permafrost_feedback",
- name: "Permafrost Runaway Feedback",
- icon: "🌡️",
- tokens: 200000000000000000,
- shortDesc: "200 Quadrillion Tokens",
- description: "Permafrost thaw becomes self-sustaining — no longer stoppable by human action",
- consequence: "With 200 quadrillion tokens of AI compute behind us, the permafrost feedback loop is irreversible. Methane and CO₂ now self-release regardless of human emissions reductions. Temperatures rise beyond every modelled scenario.",
- followingEvent: "🌋 Feedback accelerates. Even zero human emissions cannot stop the warming now.",
- color: "#BF360C",
- darkColor: "#7f240a",
- reference: "https://www.nature.com/articles/s41586-018-0807-z",
- },
- {
- id: "monsoon_failure",
- name: "Asian Monsoon Failure",
- icon: "🌧️",
- tokens: 500000000000000000,
- shortDesc: "500 Quadrillion Tokens",
- description: "The Asian monsoon system fails — 3 billion people lose their primary water source",
- consequence: "The Asian monsoon delivers 70–90 % of annual rainfall to South and East Asia. Disrupted atmospheric circulation patterns caused by AI's energy emissions collapse this ancient weather system. India, China, and Southeast Asia enter permanent drought.",
- followingEvent: "💧 3 billion people face water crisis. Nuclear-armed states clash over rivers. Mass migrations begin.",
- color: "#1565C0",
- darkColor: "#0d3d7a",
- },
- {
- id: "civilization_collapse",
- name: "Civilisation’s Last Stand",
- icon: "🏙️",
- tokens: 1000000000000000000,
- shortDesc: "1 Quintillion Tokens",
- description: "Cascading system failures end industrial civilisation as we know it",
- consequence: "At one quintillion tokens, the cumulative environmental debt has come due. Power grids fail. Supply chains dissolve. Nation-states lose the ability to maintain basic services. The infrastructure that sustains 8 billion human lives begins to collapse.",
- followingEvent: "🌑 Lights go out across continents. The age of AI ends not with intelligence, but with silence.",
- color: "#212121",
- darkColor: "#0a0a0a",
- },
- {
- id: "biosphere_collapse",
- name: "Biosphere Collapse",
- icon: "🌑",
- tokens: 10000000000000000000,
- shortDesc: "10 Quintillion Tokens",
- description: "Earth’s life-support systems fail — the biosphere can no longer sustain complex life",
- consequence: "The biosphere — the thin living layer that maintains Earth's temperature, atmosphere, and water cycles — has been pushed past all tipping points. Complex multicellular life can no longer be sustained. Earth enters a new geological epoch defined by absence.",
- followingEvent: "🕳️ The experiment of intelligence on Earth concludes. The planet heals — in 10 million years.",
- color: "#000000",
- darkColor: "#000000",
- },
-];
-
-/* istanbul ignore next */
-if (typeof module !== 'undefined' && module.exports) {
- module.exports = { MILESTONES };
-} else if (typeof window !== 'undefined') {
- window.MilestonesData = { MILESTONES };
-}
diff --git a/package.json b/package.json
index 6139ad6..fd9415b 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,9 @@
"homepage": "https://nitrocode.github.io/token-deathclock/",
"scripts": {
"typecheck": "tsc --noEmit",
+ "pretest": "npm run build:milestones && npm run build:js",
"test": "jest --coverage",
+ "pretest:ci": "npm run build:milestones && npm run build:js",
"test:ci": "jest --ci --coverage",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
diff --git a/project-stats-data.js b/project-stats-data.js
deleted file mode 100644
index b4b6253..0000000
--- a/project-stats-data.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict';
-// AUTO-GENERATED from project-stats.yaml — do not edit directly.
-// Run `npm run build:project-stats` to regenerate from project-stats.yaml.
-
-const PROJECT_PR_COUNT = 48;
-const PROJECT_TOTAL_TOKENS = 7200000;
-
-/* istanbul ignore next */
-if (typeof module !== 'undefined' && module.exports) {
- module.exports = { PROJECT_PR_COUNT, PROJECT_TOTAL_TOKENS };
-} else if (typeof window !== 'undefined') {
- window.ProjectStatsData = { PROJECT_PR_COUNT, PROJECT_TOTAL_TOKENS };
-}
diff --git a/script.js b/script.js
deleted file mode 100644
index f499b73..0000000
--- a/script.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/* AI DEATH CLOCK — browser/DOM layer (minified) */
-"use strict";(function(){const{BASE_TOKENS:Kt,TOKENS_PER_SECOND:O,BASE_DATE_ISO:Gt,HISTORICAL_DATA:Yt,MILESTONES:I,RATE_SCHEDULE:Vt,SESSION_CHALLENGE_DEFS:$o,TOKEN_TIPS:jt,COMPANY_ROLES:ge,AI_AGENTS:pe,formatTokenCount:S,formatTokenCountShort:_,getTriggeredMilestones:Jt,getNextMilestone:zt,predictMilestoneDate:Re,calculateEnvironmentalImpact:A,generateProjectionData:Qt,formatDate:Pe,getTimeDelta:Oe,milestoneProgress:he,getRateAtDate:L,calculateTipImpact:Xt,generateEquivalences:Ne,calculatePersonalFootprint:He,sessionEquivalences:Zt,getNextMilestoneForPlayer:We,computeComboMultiplier:en,getSessionChallenges:tn,formatDoomPoints:X,computePassiveRate:fe,getCompanyStage:nn,getSimulatedViewerCount:on}=window.DeathClockCore,{SITE_VERSION:ye="",CHANGELOG_RELEASES:Ee=[]}=typeof window!="undefined"&&window.ChangelogData||{},{PROJECT_PR_COUNT:Ue=0,PROJECT_TOTAL_TOKENS:qe=0}=typeof window!="undefined"&&window.ProjectStatsData||{},sn=new Date(Gt).getTime(),x=Date.now();let be="dark",B=null;const Ke="tokenDeathclockFirstArrival",Ge="tokenDeathclockTheme";let Z=x;try{const e=parseInt(localStorage.getItem(Ke)||"0",10);e>0&&e<=x?Z=e:localStorage.setItem(Ke,String(x))}catch(e){}function $(){const e=(Date.now()-sn)/1e3;return Kt+O*e}function an(e){return e>=1e15?(e/1e15).toFixed(3)+" Quadrillion":e>=1e12?(e/1e12).toFixed(3)+" Trillion":S(e)}function Ye(e){document.documentElement.setAttribute("data-theme",e);const t=document.getElementById("themeToggle");t&&(t.textContent=e==="dark"?"\u2600\uFE0F":"\u{1F319}"),be=e,B&&mn()}function rn(){const e=be==="dark"?"light":"dark";Ye(e);try{localStorage.setItem(Ge,e)}catch(t){}e==="light"&&k("optimist")}function Ve(){const e=Date.now(),t=$(),n=L(new Date(e)),o=Math.round((e-Z)/1e3*n),s=Math.floor((e-Z)/1e3),i=document.getElementById("totalCounter"),r=document.getElementById("sessionCounter"),c=document.getElementById("sessionTime"),d=document.getElementById("rateCounter"),m=document.getElementById("rateEvent");if(i&&(i.textContent=an(t)),r&&(r.textContent=S(o)),c){const g=Math.floor(s/60),f=s%60,p=Z!==x?"since first visit":"on page";c.textContent=g>0?`${g}m ${f}s ${p}`:`${f}s ${p}`}if(d&&(d.textContent=S(n)),m){const g=[...Vt].reverse().find(f=>e>=new Date(f.date).getTime());g&&(m.textContent=g.event+" \xB7 tokens/sec")}const h=A(t);ee("statKwh",_(h.kWh)),ee("statCo2",_(h.co2Kg)),ee("statWater",_(h.waterL)),ee("statTrees",_(h.treesEquivalent)),Ft(t);const b=Jt(t,I);I.forEach((g,f)=>{const p=document.getElementById("milestone-"+g.id);if(!p)return;const T=p.classList.contains("triggered");t>=g.tokens&&!T&&(p.classList.add("triggered"),$t.has(g.id)||($t.add(g.id),yo(g)));const D=p.querySelector(".progress-fill");if(D){const y=f===0?0:I[f-1].tokens,v=he(t,y,g.tokens);D.style.width=v+"%";const C=p.querySelector(".progress-pct");C&&(C.textContent=v.toFixed(1)+"%")}}),requestAnimationFrame(Ve)}function ee(e,t){const n=document.getElementById(e);n&&(n.textContent=t)}function cn(){const e=document.getElementById("milestonesGrid");if(!e)return;const t=$();e.innerHTML="",I.forEach((n,o)=>{const s=t>=n.tokens,i=o===0?0:I[o-1].tokens,r=he(t,i,n.tokens),c=Re(t,O,n.tokens),d=document.createElement("div");d.className="milestone-card"+(s?" triggered":""),d.id="milestone-"+n.id,d.innerHTML=`
-
- ${u(n.description)}
- ${u(n.consequence)}
- ${u(n.followingEvent)}
-
-
- Progress
- ${r.toFixed(1)}%
-
-
-
- ${c?`\u23F1 Predicted: ${u(Pe(c))} (${u(Oe(c))})
`:""}
- ${n.reference?`\u{1F4CE} Source`:""}
- `,e.appendChild(d)})}function ln(){const e=document.getElementById("predictionsBody");if(!e)return;const t=$();e.innerHTML="",I.forEach(n=>{const o=t>=n.tokens,s=o?null:Re(t,O,n.tokens),i=document.createElement("tr");i.innerHTML=`
- ${u(n.icon)} ${u(n.name)} |
- ${u(n.shortDesc)} |
- ${o?'PASSED':"\u23F3 Pending"} |
- ${o?"\u2014":u(Pe(s))} |
- ${o?'Already triggered':u(Oe(s))} |
- `,e.appendChild(i)})}function dn(){const e=$(),t=Yt.map(o=>({x:o.date,y:o.tokensT})),n=Qt(e,O,60,void 0,.5).map(o=>({x:o.date,y:+o.tokensT.toFixed(2)}));return{historical:t,projection:n}}function je(){const e=be==="dark";return{histLine:e?"#ff3333":"#cc0000",projLine:e?"#ff8800":"#cc6600",gridColor:e?"rgba(255,255,255,0.07)":"rgba(0,0,0,0.08)",tickColor:e?"#888":"#555",bg:e?"#161616":"#ffffff"}}function un(){const e=document.getElementById("tokenChart");if(!e||typeof Chart=="undefined")return;const{historical:t,projection:n}=dn(),o=je(),s={};I.forEach((i,r)=>{s["milestone_"+r]={type:"line",yMin:i.tokens/1e12,yMax:i.tokens/1e12,borderColor:"rgba(0,204,119,0.4)",borderWidth:1,borderDash:[4,4],label:{content:i.icon+" "+i.shortDesc,display:!1}}}),B=new Chart(e,{type:"line",data:{datasets:[{label:"Historical (estimated)",data:t,borderColor:o.histLine,backgroundColor:"transparent",borderWidth:2,pointRadius:3,pointHoverRadius:5,tension:.35,fill:!1},{label:"Projected",data:n,borderColor:o.projLine,backgroundColor:"transparent",borderWidth:2,borderDash:[6,4],pointRadius:0,tension:.35,fill:!1}]},options:{responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},scales:{x:{type:"time",time:{tooltipFormat:"MMM yyyy",displayFormats:{month:"MMM yy",year:"yyyy",quarter:"MMM yy"}},grid:{color:o.gridColor},ticks:{color:o.tickColor,maxRotation:45}},y:{type:"logarithmic",title:{display:!0,text:"Cumulative Tokens (Trillions, log scale)",color:o.tickColor,font:{size:11}},grid:{color:o.gridColor},ticks:{color:o.tickColor,callback:i=>_(i*1e12)}}},plugins:{legend:{labels:{color:o.tickColor,boxWidth:20,padding:16,font:{size:12}}},tooltip:{callbacks:{label:i=>" "+S(i.parsed.y*1e12)+" tokens"}}}}})}function mn(){if(!B)return;const e=je();B.data.datasets[0].borderColor=e.histLine,B.data.datasets[1].borderColor=e.projLine,B.options.scales.x.grid.color=e.gridColor,B.options.scales.y.grid.color=e.gridColor,B.options.scales.x.ticks.color=e.tickColor,B.options.scales.y.ticks.color=e.tickColor,B.options.scales.y.title.color=e.tickColor,B.options.plugins.legend.labels.color=e.tickColor,B.update("none")}function u(e){return typeof e!="string"?"":e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}const Je=I.find(e=>e.extinctionMarker)||I[I.length-1],l={level:"days",day:null,hour:null,minute:null,rafId:null,lastSec:-1,lastMin:-1,lastHr:-1,lastDayMs:0,exploding:!1};function ve(){const e=$();if(e>=Je.tokens)return Date.now();const t=(Je.tokens-e)/O;return Date.now()+t*1e3}function gn(){const e=ve()-Date.now();return Math.max(0,Math.ceil(e/864e5))}function F(e){const t=new Date(e);return t.setHours(0,0,0,0),t.getTime()}function ke(e,t,n){const o=e+t;return n>=o?"dead":n>=e?"dying":"future"}function N(e,t){return F(t)+e*864e5}function te(e,t,n,o){return`${o}
`}function ne(e,t,n,o){return`${o}
`}const q=3650;function pn(e,t){const n=gn(),o=Math.min(n,q),s=F(t),i=(t-s)/864e5*100,c=new Date(ve()).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"});let d=``;d+=te('data-day="0"',i,"Today \u2014 burning away","");for(let m=1;m<=o;m++)d+=ne("future",`data-day="${m}"`,`Day ${m} from now`,"");n>q&&(d+=`
- +${Math.round((n-q)/365)}y
`),d+="
",e.innerHTML=d,document.getElementById("lb-info").textContent=`${n.toLocaleString()} days until extinction \xB7 predicted ${c}`}function hn(e,t,n){const o=N(t,n),s=t===0;let i='';for(let c=0;c<24;c++){const d=o+c*36e5,m=s?ke(d,36e5,n):"future",h=`${String(c).padStart(2,"0")}:00`,b=`${String(c).padStart(2,"0")}`;if(m==="dying"){const g=(n-d)/36e5*100;i+=te(`data-hour="${c}"`,g,h,b)}else i+=ne(m,`data-hour="${c}"`,h,b)}i+="
",e.innerHTML=i;const r=t===0?"Today":`Day +${t}`;document.getElementById("lb-info").textContent=`${r} \u2014 select an hour`}function fn(e,t,n,o){const i=N(t,o)+n*36e5,r=t===0&&o>=i&&o${String(d).padStart(2,"0")}`;if(h==="dying"){const f=(o-m)/6e4*100;c+=te(`data-minute="${d}"`,f,b,g)}else c+=ne(h,`data-minute="${d}"`,b,g)}c+="",e.innerHTML=c,document.getElementById("lb-info").textContent=`${String(n).padStart(2,"0")}:xx \u2014 select a minute`}function yn(e,t,n,o,s){const r=N(t,s)+n*36e5+o*6e4,c=t===0&&s>=r&&s${String(m).padStart(2,"0")}`;if(b==="dying"){const p=(s-h)/1e3*100;d+=te(`data-second="${m}"`,p,g,f)}else d+=ne(b,`data-second="${m}"`,g,f)}d+="",e.innerHTML=d,document.getElementById("lb-info").textContent=`${String(n).padStart(2,"0")}:${String(o).padStart(2,"0")}:xx`}function En(){const e=document.getElementById("lb-breadcrumb");if(!e)return;const t=[{label:"\u{1F480} Days",level:"days"}];l.level!=="days"&&t.push({label:`Day ${l.day===0?"Today":"+"+l.day}`,level:"hours"}),(l.level==="minutes"||l.level==="seconds")&&t.push({label:`Hour ${String(l.hour).padStart(2,"0")}`,level:"minutes"}),l.level==="seconds"&&t.push({label:`Min ${String(l.minute).padStart(2,"0")}`,level:"seconds"}),e.innerHTML=t.map((n,o)=>o===t.length-1?`${u(n.label)}`:`${u(n.label)}
- \u203A`).join(""),e.querySelectorAll("[data-nav]").forEach(n=>{const o=n.getAttribute("data-nav");n.addEventListener("click",()=>ze(o)),n.addEventListener("keydown",s=>{(s.key==="Enter"||s.key===" ")&&ze(o)})})}function ze(e){l.level=e,e==="days"?(l.day=null,l.hour=null,l.minute=null):e==="hours"?(l.hour=null,l.minute=null):e==="minutes"&&(l.minute=null),K()}function K(){const e=document.getElementById("lb-container");if(!e)return;const t=Date.now(),n=new Date(t);l.lastSec=n.getSeconds(),l.lastMin=n.getMinutes(),l.lastHr=n.getHours(),l.lastDayMs=F(n),l.exploding=!1,l.level==="days"?pn(e,t):l.level==="hours"?hn(e,l.day,t):l.level==="minutes"?fn(e,l.day,l.hour,t):l.level==="seconds"&&yn(e,l.day,l.hour,l.minute,t),En(),bn(e)}function bn(e){e.querySelectorAll(".lb-block:not(.lb-dead)").forEach(t=>{t.addEventListener("click",Qe),t.addEventListener("keydown",n=>{(n.key==="Enter"||n.key===" ")&&Qe.call(t,n)})})}function Qe(e){const t=e.currentTarget||this;if(l.level==="days")l.day=parseInt(t.getAttribute("data-day"),10),l.level="hours";else if(l.level==="hours")l.hour=parseInt(t.getAttribute("data-hour"),10),l.level="minutes";else if(l.level==="minutes")l.minute=parseInt(t.getAttribute("data-minute"),10),l.level="seconds";else return;K()}function vn(e){if(l.exploding){e();return}const t=document.querySelector("#lb-container .lb-dying");if(!t){e();return}l.exploding=!0,t.classList.add("lb-exploding"),setTimeout(e,560)}function Xe(){const e=Date.now(),t=new Date(e);if(!l.exploding){const h=document.querySelector("#lb-container .lb-dying");if(h){let b,g;if(l.level==="days")b=F(t),g=864e5;else if(l.level==="hours"){const p=t.getHours();b=N(l.day,e)+p*36e5,g=36e5}else if(l.level==="minutes"){const p=t.getMinutes();b=N(l.day,e)+l.hour*36e5+p*6e4,g=6e4}else{const p=t.getSeconds();b=N(l.day,e)+l.hour*36e5+l.minute*6e4+p*1e3,g=1e3}const f=Math.min(100,(e-b)/g*100);h.style.setProperty("--progress",f.toFixed(2)+"%")}}const n=t.getSeconds(),o=t.getMinutes(),s=t.getHours(),i=F(t),r=l.level==="seconds"&&n!==l.lastSec,c=l.level==="minutes"&&o!==l.lastMin,d=l.level==="hours"&&s!==l.lastHr,m=l.level==="days"&&i!==l.lastDayMs;(r||c||d||m)&&!l.exploding&&(l.lastSec=n,l.lastMin=o,l.lastHr=s,l.lastDayMs=i,vn(()=>K())),l.rafId=requestAnimationFrame(Xe)}function kn(){K(),l.rafId=requestAnimationFrame(Xe),wn()}const Sn={seconds:"sec",minutes:"min",hours:"hr",days:"day",months:"month",years:"year"},E={rafId:null,active:!1,initialized:!1,lastSec:-1,lastMin:-1,lastHr:-1,lastDay:-1,lastMonth:-1,lastYear:-1,pendingCascade:!1,exploding:{sec:!1,min:!1,hr:!1,day:!1,month:!1,year:!1}};function Ze(e,t,n){const o=new Date(n),s=o.getFullYear(),i=o.getMonth(),r=o.getDate(),c=o.getHours(),d=o.getMinutes(),m=o.getSeconds(),h={years:"YEARS",months:"MONTHS",days:"DAYS",hours:"HOURS",minutes:"MINS",seconds:"SECS"},b=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"];let g,f,p,T=null,w;switch(t){case"seconds":g=60,f=m,p=(n-Math.floor(n/1e3)*1e3)/1e3*100,w=y=>yy{const v=String(y).padStart(2,"0")+":00";return y{const C=v+1;return v{const me=b[C];return C30&&(T=`+${C-30}y`),w=Lo=>{const Q=v+Lo;return Q${h[t]}`;D+='';for(let y=0;y
`;else if(y===f)D+=``;else{const C=u(`Jump drill-down to ${t} view`);D+=``}}T&&(D+=`${u(T)}
`),D+="",e.innerHTML=D,e.querySelectorAll("[data-stack-level]").forEach(y=>{y.addEventListener("click",et),y.addEventListener("keydown",v=>{(v.key==="Enter"||v.key===" ")&&(v.preventDefault(),et.call(y,v))})})}function Tn(e){["years","months","days","hours","minutes","seconds"].forEach(t=>{const n=document.getElementById("lb-stack-"+t);n&&Ze(n,t,e)})}function Cn(e){const t=new Date(e),n=t.getFullYear(),o=t.getMonth(),s=new Date(n,o,1).getTime(),i=new Date(n,o+1,1).getTime(),r=new Date(n,0,1).getTime(),c=new Date(n+1,0,1).getTime(),d={seconds:(e-Math.floor(e/1e3)*1e3)/1e3*100,minutes:(e-Math.floor(e/6e4)*6e4)/6e4*100,hours:(e-Math.floor(e/36e5)*36e5)/36e5*100,days:(e-F(e))/864e5*100,months:(e-s)/(i-s)*100,years:(e-r)/(c-r)*100};Object.entries(d).forEach(([m,h])=>{if(E.exploding[Sn[m]])return;const b=document.getElementById("lb-stack-"+m);if(!b)return;const g=b.querySelector(".lb-dying");g&&g.style.setProperty("--progress",h.toFixed(2)+"%")})}function In(e){const t=new Date(e),n=t.getSeconds(),o=t.getMinutes(),s=t.getHours(),i=t.getDate(),r=t.getMonth(),c=t.getFullYear();if(!E.initialized){E.lastSec=n,E.lastMin=o,E.lastHr=s,E.lastDay=i,E.lastMonth=r,E.lastYear=c,E.initialized=!0;return}if(E.pendingCascade||!(n!==E.lastSec))return;const m=o!==E.lastMin,h=s!==E.lastHr,b=i!==E.lastDay,g=r!==E.lastMonth,f=c!==E.lastYear;E.lastSec=n,E.lastMin=o,E.lastHr=s,E.lastDay=i,E.lastMonth=r,E.lastYear=c;const p=[{key:"sec",level:"seconds",delay:0}];m&&p.push({key:"min",level:"minutes",delay:100}),h&&p.push({key:"hr",level:"hours",delay:200}),b&&p.push({key:"day",level:"days",delay:300}),g&&p.push({key:"month",level:"months",delay:400}),f&&p.push({key:"year",level:"years",delay:500}),E.pendingCascade=!0;let T=p.length;p.forEach(({key:w,level:D,delay:y})=>{setTimeout(()=>{const v=document.getElementById("lb-stack-"+D),C=v?v.querySelector(".lb-dying"):null;if(!C){T--,T||(E.pendingCascade=!1);return}E.exploding[w]=!0,C.classList.add("lb-exploding"),setTimeout(()=>{E.exploding[w]=!1,Ze(v,D,Date.now()),T--,T||(E.pendingCascade=!1)},560)},y)})}function et(e){const n=(e.currentTarget||this).getAttribute("data-stack-level");if(!n)return;const o=new Date;switch(n){case"years":case"months":case"days":l.level="days",l.day=null,l.hour=null,l.minute=null;break;case"hours":l.level="hours",l.day=0,l.hour=null,l.minute=null;break;case"minutes":l.level="minutes",l.day=0,l.hour=o.getHours(),l.minute=null;break;case"seconds":l.level="seconds",l.day=0,l.hour=o.getHours(),l.minute=o.getMinutes();break;default:return}K();const s=document.getElementById("lb-container");if(s){const i=window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;s.scrollIntoView({behavior:i?"auto":"smooth",block:"start"})}}function Se(){if(!E.active)return;const e=Date.now();Cn(e),In(e),E.rafId=requestAnimationFrame(Se)}function wn(){const e=document.getElementById("life-blocks-section");if(!e)return;if(Tn(Date.now()),typeof IntersectionObserver=="undefined"){E.active=!0,E.rafId=requestAnimationFrame(Se);return}new IntersectionObserver(n=>{n.forEach(o=>{o.isIntersecting?E.active||(E.active=!0,E.rafId=requestAnimationFrame(Se)):(E.active=!1,E.rafId&&(cancelAnimationFrame(E.rafId),E.rafId=null))})},{threshold:.2}).observe(e)}function Dn(){const e=document.getElementById("tipsGrid");e&&(e.innerHTML="",jt.forEach(t=>{const n=document.createElement("div");n.className="tip-card",n.id="tip-"+u(t.id);const o=Xt(t.savingPct,1),s=_(o.tokensPerDay),i=_(o.co2KgPerDay);n.innerHTML=`
-
- ${u(t.tip)}
- ${u(t.detail)}
-
- If 1 % of global users applied this tip:
- ${u(s)} tokens/day saved \xB7
- ${u(i)} kg CO\u2082/day avoided
-
- ${t.reference?`\u{1F4CE} Learn more`:""}
- `,e.appendChild(n)}))}function xn(){const e=document.getElementById("changelogList");if(!e)return;const t=document.getElementById("siteVersion");if(t&&ye&&(t.textContent="v"+ye),!Ee||Ee.length===0){e.innerHTML='No changelog entries found.
';return}let n="";Ee.forEach(o=>{const s=o.version==="Unreleased",i=o.date?`${u(o.date)}`:"",r=s?"https://github.com/nitrocode/token-deathclock/compare/v"+u(ye)+"...HEAD":"https://github.com/nitrocode/token-deathclock/releases/tag/v"+u(o.version);n+=``,n+='",o.sections.length===0&&(n+='
No entries yet.
'),o.sections.forEach(c=>{n+='
',n+=`
${u(c.heading)}
`,n+='
',c.items.forEach(d=>{n+=`- ${u(d)}
`}),n+="
"}),n+="
"}),e.innerHTML=n}function Bn(){const e=document.getElementById("footerMetaIrony");if(!e||Ue==null||qe==null)return;const t="~"+qe.toLocaleString("en-US");e.innerHTML="\u{1F525} This site was built using AI coding agents across "+u(String(Ue))+" pull requests, consuming an estimated "+u(t)+" tokens in the process \u2014 adding to the very problem it tracks."}const M="https://nitrocode.github.io/token-deathclock/",Mn=1e4,tt=[{tokensEach:400,label:"LinkedIn posts about disruption, transformation, and journeys"},{tokensEach:800,label:"cover letters for jobs already filled by AI"},{tokensEach:200,label:'apology emails for replying "per my last email"'},{tokensEach:1500,label:"README files for projects that will never be committed"},{tokensEach:3e3,label:"passive-aggressive Slack messages softened by three rewrites"},{tokensEach:600,label:"horoscopes for zodiac signs that don't exist yet"},{tokensEach:2e3,label:"attempts to explain consciousness to a language model"},{tokensEach:500,label:"recursive prompts asking AI if it's sentient"},{tokensEach:1200,label:'love poems for someone who asked for "something quick"'},{tokensEach:400,label:"philosophical debates between two instances of the same model"},{tokensEach:2500,label:"security advisories for vulnerabilities AI introduced last week"},{tokensEach:800,label:'slide decks titled "AI Strategy 2026"'},{tokensEach:300,label:"meeting summaries for meetings that could have been emails"},{tokensEach:5e3,label:"terms of service that no human will ever read"},{tokensEach:600,label:"bedtime stories featuring a dragon named Gerald"},{tokensEach:400,label:"recipes that add cheese to things that should not have cheese"},{tokensEach:800,label:"cat pictures described in 800 words"},{tokensEach:250,label:"arguments about whether a hot dog is a sandwich"},{tokensEach:100,label:'variations of "hello world" in Rust'},{tokensEach:1e3,label:"strongly worded letters about a neighbour's leaf blower"}];let oe=!1,nt=0,R=null,An=null;function Ln(e){return e>=1e6?(e/1e6).toFixed(1).replace(/\.0$/,"")+" million":e>=1e3?(Math.round(e/100)*100).toLocaleString():Math.max(1,Math.round(e)).toLocaleString()}function ot(){if(oe)return;const e=Date.now(),t=Math.max(1,(e-x)/1e3),n=L(new Date(e)),o=t*n,s=tt[nt%tt.length],i=Math.max(1,o/s.tokensEach),r=Ln(i),c=document.getElementById("ai-ticker-text");c&&(c.textContent=r+" "+s.label),R={entry:s,nStr:r,sessionTokens:o,rate:n},nt++}function st(){if(!R)return;oe=!0;const e=document.getElementById("ai-ticker-expanded");e&&(e.hidden=!1);const t=document.getElementById("ai-ticker-toggle");t&&(t.textContent="\u25B6 Resume",t.setAttribute("aria-pressed","true"));const n=document.getElementById("ai-ticker-math");if(n&&R){const{entry:o,nStr:s,sessionTokens:i,rate:r}=R,c=Math.round(i/r);n.textContent=`${c}s \xD7 ${S(r)} tokens/sec
-= ${S(i)} tokens consumed globally
-
-\xF7 ${o.tokensEach.toLocaleString()} tokens per item
-\u2248 ${s} ${o.label}
-
-(Just in the time you've been watching.)`}}function at(){const e=document.getElementById("ai-ticker-expanded");e&&(e.hidden=!0),oe=!1;const t=document.getElementById("ai-ticker-toggle");t&&(t.textContent="\u23F8 Pause",t.setAttribute("aria-pressed","false"))}function $n(){if(!R)return;const{entry:e,nStr:t,sessionTokens:n}=R,o=Math.floor((Date.now()-x)/1e3),i=`\u{1F916} Since I arrived (${o>=60?`${Math.floor(o/60)}m ${o%60}s`:`${o}s`} ago), AI has probably generated:
-
-${t} ${e.label}
-
-That's what ${S(R.rate)} tokens/sec looks like in human terms.
-\u2192 ${M} #AIDeathClock #TokenDeathClock`;se(i)}function _n(){const e=typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;ot(),e||(An=setInterval(ot,4e3));const t=document.getElementById("ai-ticker-text");t&&t.addEventListener("click",st);const n=document.getElementById("ai-ticker-toggle");n&&n.addEventListener("click",()=>{oe?at():st()});const o=document.getElementById("ai-ticker-resume");o&&o.addEventListener("click",at);const s=document.getElementById("ai-ticker-share");s&&s.addEventListener("click",$n)}let G=!1,Te=0;function Ce(){const e=$(),t=Ne(e,G?"snarky":"hopeful");if(!t.length)return;const n=t[Te%t.length],o=document.getElementById("equivIcon"),s=document.getElementById("equivText");o&&(o.textContent=n.icon),s&&(s.textContent=n.text),Te++}function Fn(){Ce(),setInterval(Ce,5e3);const e=document.getElementById("snarkToggle");e&&e.addEventListener("click",()=>{G=!G,e.textContent=G?"\u{1F331} Hopeful Mode":"\u{1F624} Snarky Mode",e.setAttribute("aria-pressed",G?"true":"false"),Te=0,Ce()})}function H(){const e=Date.now(),t=Math.floor((e-x)/1e3),n=L(new Date(e)),o=Math.max(1,t*n),s=Zt(o),i=s.length?s[Math.floor(Math.random()*s.length)]:null,r=Math.floor(t/60),c=t%60,d=r>0?`${r}m ${c}s`:`${c}s`;let m=`\u{1F480} I just watched AI consume ${S(o)} tokens in the ${d} I spent on this site.`;return i&&(m+=`
-That's ${i}.`),m+=`
-And it never stops.
-\u2192 ${M} #AIDeathClock #TokenDeathClock`,m}function se(e){if(navigator.share){navigator.share({text:e,url:M}).catch(()=>{ae(e)});return}ae(e)}function ae(e){const t="https://twitter.com/intent/tweet?text="+encodeURIComponent(e);window.open(t,"_blank","noopener,noreferrer,width=560,height=420")}function it(e){const t="https://www.reddit.com/submit?url="+encodeURIComponent(M)+"&title="+encodeURIComponent(e);window.open(t,"_blank","noopener,noreferrer")}function rt(e){const t="https://www.linkedin.com/shareArticle?mini=true&url="+encodeURIComponent(M)+"&title="+encodeURIComponent("Token Deathclock \u2014 AI's Environmental Cost, Live")+"&summary="+encodeURIComponent(e);window.open(t,"_blank","noopener,noreferrer")}function ct(e){const t="https://api.whatsapp.com/send?text="+encodeURIComponent(e);window.open(t,"_blank","noopener,noreferrer")}function lt(e){const t="https://bsky.app/intent/compose?text="+encodeURIComponent(e);window.open(t,"_blank","noopener,noreferrer")}function Ie(e,t,n){if(!navigator.clipboard){e.textContent="\u274C Not supported",setTimeout(()=>{e.textContent=n},2e3);return}navigator.clipboard.writeText(t).then(()=>{e.textContent="\u2705 Copied!",setTimeout(()=>{e.textContent=n},2e3)}).catch(()=>{e.textContent="\u274C Failed",setTimeout(()=>{e.textContent=n},2e3)})}function Rn(){const e=document.getElementById("share-doom-panel"),t=document.getElementById("share-doom-options");if(!e)return;setTimeout(()=>{e.hidden=!1},Mn),new URLSearchParams(window.location.search).get("share")==="true"&&(e.hidden=!1,t&&(t.hidden=!1));const n=document.getElementById("shareDoomBtn");n&&n.addEventListener("click",()=>{t&&(t.hidden=!t.hidden)});const o=document.getElementById("shareTwitterBtn");o&&o.addEventListener("click",()=>{ae(H()),k("spreading_doom"),t&&(t.hidden=!0)});const s=document.getElementById("shareRedditBtn");s&&s.addEventListener("click",()=>{it("I watched AI consume millions of tokens in real time \u2014 the numbers are terrifying"),k("spreading_doom"),t&&(t.hidden=!0)});const i=document.getElementById("shareLinkedInBtn");i&&i.addEventListener("click",()=>{rt(H()),k("spreading_doom"),t&&(t.hidden=!0)});const r=document.getElementById("shareWhatsAppBtn");r&&r.addEventListener("click",()=>{ct(H()),k("spreading_doom"),t&&(t.hidden=!0)});const c=document.getElementById("shareBlueskyBtn");c&&c.addEventListener("click",()=>{lt(H()),k("spreading_doom"),t&&(t.hidden=!0)});const d=document.getElementById("shareCopyBtn");d&&d.addEventListener("click",()=>{Ie(d,H(),"\u{1F4CB} Copy text"),k("spreading_doom"),t&&(t.hidden=!0)});const m=document.getElementById("shareCloseBtn");m&&m.addEventListener("click",()=>{t&&(t.hidden=!0)}),document.addEventListener("click",h=>{t&&!t.hidden&&e&&!e.contains(h.target)&&(t.hidden=!0)})}function Pn(){const e=()=>H(),t="I watched AI consume millions of tokens in real time \u2014 the numbers are terrifying";[{id:"footerShareTwitter",fn:()=>ae(e())},{id:"footerShareReddit",fn:()=>it(t)},{id:"footerShareLinkedIn",fn:()=>rt(e())},{id:"footerShareWhatsApp",fn:()=>ct(e())},{id:"footerShareBluesky",fn:()=>lt(e())},{id:"footerShareCopy",fn:o=>Ie(o,M,"\u{1F4CB} Copy link")}].forEach(({id:o,fn:s})=>{const i=document.getElementById(o);i&&i.addEventListener("click",()=>{s(i),k("spreading_doom")})})}let On=!1;function dt(){const e=new Date,t=Math.floor((Date.now()-x)/1e3),n=L(e),o=Math.max(1,t*n),s=A(o),i=Math.floor(t/60),r=t%60,c=i>0?`${i} min ${r} sec`:`${r} sec`,d=e.toLocaleDateString("en-US",{weekday:"short",day:"numeric",month:"short",year:"numeric"}),m=e.toUTCString().split(" ")[4]+" UTC",h=(s.co2Kg*1e3).toFixed(1),b=Math.round(s.waterL*1e3),g=s.kWh<1e-6?"< 0.000001":s.kWh.toFixed(6),f=(s.co2Kg/.171).toFixed(3),p=Math.max(1,Math.round(s.kWh/.015*60)),T=Math.max(1,Math.round(b/20)),w="\u2500".repeat(32),D="\u2550".repeat(32);function y(v,C){return String(v).padStart(C)}return["\u2554"+"\u2550".repeat(30)+"\u2557","\u2551 \u{1F9FE} AI DEATH CLOCK \u2551","\u2551 SESSION RECEIPT \u2551","\u255A"+"\u2550".repeat(30)+"\u255D","",` Date: ${d}`,` Time: ${m}`,` Duration: ${c}`,"",w,"ITEM VALUE",w,`AI tokens consumed ${y(S(o),12)}`,`Energy used (kWh) ${y(g,12)}`,`CO\u2082 emitted (g) ${y(h,12)}`,`Water used (mL) ${y(b,12)}`,"",`Global rate: ${S(n)} tokens/sec`,w,"ENVIRONMENTAL COST:","",` \u{1F321}\uFE0F ~${h} g CO\u2082`,` \u2248 driving ${f} km`,"",` \u{1F30A} ~${b} mL water`,` \u2248 ${T} sip${T!==1?"s":""} of tea`,"",` \u26A1 ~${g} kWh`,` \u2248 phone for ${p} min`,w," * * * NO REFUNDS * * *"," THE PLANET CANNOT ISSUE"," CARBON CREDITS FOR AI",w," Please come again."," (We'll still be here.)"," \u{1F480}",D].join(`
-`)}function Nn(){const e=Math.floor((Date.now()-x)/1e3),t=L(new Date),n=Math.max(1,e*t),o=A(n),s=Math.floor(e/60),i=e%60,r=s>0?`${s}m ${i}s`:`${i}s`,c=(o.co2Kg*1e3).toFixed(1),d=Math.round(o.waterL*1e3);return`\u{1F9FE} My AI Death Clock receipt: AI consumed ${S(n)} tokens in ${r}. That's ${c}g CO\u2082, ${d}mL water. And I didn't even prompt anything.
-\u2192 ${M} #TokenDeathClock #AIReceipt`}function ut(e){if(e.key!=="Tab"){e.key==="Escape"&&we();return}const t=document.getElementById("receipt-modal");if(!t)return;const n=t.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');if(!n.length)return;const o=n[0],s=n[n.length-1];e.shiftKey&&document.activeElement===o?(e.preventDefault(),s.focus()):!e.shiftKey&&document.activeElement===s&&(e.preventDefault(),o.focus())}function Hn(){const e=document.getElementById("receipt-modal");if(!e)return;const t=document.getElementById("receipt-body");t&&(t.textContent=dt()),e.hidden=!1,On=!0,e.addEventListener("keydown",ut);const n=e.querySelector("button");n&&n.focus(),k("receipt_collector")}function we(){const e=document.getElementById("receipt-modal");e&&(e.hidden=!0,e.removeEventListener("keydown",ut))}function Wn(){const e=document.getElementById("getReceiptBtn");e&&e.addEventListener("click",Hn);const t=document.getElementById("receiptCloseBtn");t&&t.addEventListener("click",we);const n=document.getElementById("receiptShareBtn");n&&n.addEventListener("click",()=>{se(Nn()),k("spreading_doom")});const o=document.getElementById("receiptCopyBtn");o&&o.addEventListener("click",()=>{const i=document.getElementById("receipt-body"),r=i?i.textContent:dt();navigator.clipboard.writeText(r).then(()=>{o.textContent="\u2705 Copied!",setTimeout(()=>{o.textContent="\u{1F4CB} Copy Receipt"},2e3)}).catch(()=>{o.textContent="\u274C Failed",setTimeout(()=>{o.textContent="\u{1F4CB} Copy Receipt"},2e3)})});const s=document.getElementById("receipt-modal");s&&s.addEventListener("click",i=>{i.target===s&&we()})}function mt(){const e=document.getElementById("calcPrompts"),t=document.getElementById("calcLength"),n=document.getElementById("calcModel");if(!e||!t||!n)return;const o=parseInt(e.value,10)||20,s=parseInt(t.value,10)||500,i=parseFloat(n.value)||1,r=He(o,s,i),c=(r.weekly.co2Kg*1e3).toFixed(1),d=Math.round(r.weekly.waterL*1e3),m=Math.round(r.annual.co2Kg*1e3),h=(r.globalWeeklyCo2Kg/1e3).toFixed(1),b=(r.annual.co2Kg/.171).toFixed(1),g=S(r.globalWeeklyCo2Kg/(.171*1e3/52)),f=Math.max(1,Math.round(r.annual.co2Kg/21)),p=Math.round(r.weekly.kWh/.015),T=document.getElementById("calc-results");T&&(T.innerHTML=`
-
-
WANTED
-
For Environmental Crimes Against the Atmosphere
-
-
-
COUNT I: Consuming ${u(S(r.weeklyTokens))} tokens per week \u2014 enough to power ${u(p.toLocaleString())} smartphone charges.
-
COUNT II: Emitting ${u(c)} g CO\u2082 weekly \u2014 equivalent to driving ${u(b)} km a year.
-
COUNT III: Evaporating ${u(String(d))} mL of cooling water per week without remorse.
-
COUNT IV: Projecting annual emissions of ${u(String(m))} g CO\u2082 \u2014 sustained and premeditated.
-
-
-
\u2696\uFE0F BAIL: Plant ${u(String(f))} tree${f!==1?"s":""} or delete your ChatGPT account.
-
If all 500M AI users matched this profile: ${u(h)} tonnes CO\u2082/week \u2014 equiv. ${u(g)} cars driven.
-
`)}function Un(){const e=document.getElementById("calcPrompts"),t=document.getElementById("calcLength"),n=document.getElementById("calcModel"),o=e&&parseInt(e.value,10)||20,s=t&&parseInt(t.value,10)||500,i=n&&parseFloat(n.value)||1,r=He(o,s,i),c=(r.weekly.co2Kg*1e3).toFixed(1),d=(r.globalWeeklyCo2Kg/1e3).toFixed(0);return`\u{1F9EE} I sent ${o} AI prompts this week. That's ~${S(r.weeklyTokens)} tokens, ~${c}g CO\u2082. Multiply me by 500 million \u2192 ${d} tonnes of CO\u2082/week just from AI prompts.
-\u2192 ${M} #AICarbonFootprint #TokenDeathClock`}function qn(){const e=document.getElementById("calcToggleBtn"),t=document.getElementById("calc-content");e&&t&&e.addEventListener("click",()=>{const o=t.hidden;t.hidden=!o,e.textContent=o?"\u25BC Close Calculator":"\u25BA Open Personal AI Carbon Footprint Calculator",e.setAttribute("aria-expanded",o?"true":"false"),o&&(mt(),k("number_cruncher"))}),["calcPrompts","calcLength","calcModel"].forEach(o=>{const s=document.getElementById(o);s&&s.addEventListener("input",()=>{if(o==="calcPrompts"){const i=document.getElementById("calcPromptsVal");i&&(i.textContent=s.value),s.setAttribute("aria-valuenow",s.value)}mt()})});const n=document.getElementById("calcShareBtn");n&&n.addEventListener("click",()=>{se(Un()),k("spreading_doom")})}const ie=[{id:"morbid_curious",icon:"\u{1F440}",name:"Morbid Curious",desc:"Spent 30 seconds watching the apocalypse.",type:"time",threshold:30},{id:"doom_magnet",icon:"\u{1F9F2}",name:"Doom Magnet",desc:"Spent 3 minutes watching the apocalypse.",type:"time",threshold:180},{id:"chronic_doomscroller",icon:"\u{1F6CB}\uFE0F",name:"Chronic Doomscroller",desc:"10 minutes of uninterrupted doom.",type:"time",threshold:600},{id:"terminal_patient",icon:"\u{1F480}",name:"Terminal Patient",desc:"Half an hour here. Are you okay?",type:"time",threshold:1800},{id:"one_of_us",icon:"\u{1F916}",name:"One of Us Now",desc:"One hour. You're part of the machine now.",type:"time",threshold:3600},{id:"spreading_doom",icon:"\u{1F4E4}",name:"Spreading the Doom",desc:"Clicked Share. Sharing is caring.",type:"manual"},{id:"number_cruncher",icon:"\u{1F9EE}",name:"Number Cruncher",desc:"Opened the Personal Footprint Calculator.",type:"manual"},{id:"receipt_collector",icon:"\u{1F9FE}",name:"Receipt Collector",desc:"Checked your session receipt.",type:"manual"},{id:"optimist",icon:"\u{1F31E}",name:"Optimist",desc:"Switched to Light Mode. Your optimism is noted.",type:"manual"},{id:"nocturnal_doomer",icon:"\u{1F313}",name:"Nocturnal Doomer",desc:"Visiting between midnight and 4am. Can't sleep?",type:"easter"},{id:"return_visitor",icon:"\u{1F501}",name:"Glutton for Punishment",desc:"You came back. You knew what would happen.",type:"easter"},{id:"accelerant",icon:"\u{1F680}",name:"Accelerant",desc:"Made your first tap on the Big Red Button.",type:"manual"},{id:"arsonist",icon:"\u{1F525}",name:"Arsonist",desc:"Reached 10\xD7 combo for the first time.",type:"manual"},{id:"trillion_villain",icon:"\u26A1",name:"Trillion Villain",desc:"Personally contributed 1 trillion tokens.",type:"manual"},{id:"continental_threat",icon:"\u{1F30D}",name:"Continental Threat",desc:"Purchased the Global Data Centre upgrade.",type:"manual"},{id:"space_criminal",icon:"\u{1F6F0}\uFE0F",name:"Space Criminal",desc:"Purchased the Orbital Inference Array.",type:"manual"},{id:"godlike",icon:"\u{1F9EC}",name:"Godlike",desc:"Purchased the AGI Mode upgrade.",type:"manual"},{id:"first_blood",icon:"\u{1F3C1}",name:"First Blood",desc:"Personally triggered your first milestone.",type:"manual"},{id:"apex_accelerant",icon:"\u2620\uFE0F",name:"Apex Accelerant",desc:"Personally triggered 5 milestones.",type:"manual"},{id:"bragging_rights",icon:"\u{1F4E4}",name:"Bragging Rights",desc:"Shared your personal acceleration total.",type:"manual"},{id:"layoff_legend",icon:"\u{1F4E4}",name:"Layoff Legend",desc:"Replaced your first human worker with AI.",type:"manual"},{id:"token_maxxer_badge",icon:"\u{1F4C8}",name:"Token Maxxer",desc:"Deployed your first AI agent.",type:"manual"},{id:"ai_native_ceo",icon:"\u{1F3E2}",name:"AI-Native CEO",desc:"Reached AI-Native Company stage.",type:"manual"},{id:"lights_out",icon:"\u2620\uFE0F",name:"Lights Out",desc:"Replaced every human worker. Fully automated.",type:"manual"},{id:"witness",icon:"\u{1F441}\uFE0F",name:"Witness",desc:"Stayed to watch a milestone get crossed in real time.",type:"manual"}],gt="tokenDeathclockBadges",pt="tokenDeathclockVisits";let W=new Set;const re=[];let ce=!1;function Kn(){try{const e=JSON.parse(localStorage.getItem(gt)||"[]");Array.isArray(e)&&e.forEach(t=>W.add(t))}catch(e){}}function Gn(){try{localStorage.setItem(gt,JSON.stringify([...W]))}catch(e){}}function k(e){if(W.has(e))return;const t=ie.find(n=>n.id===e);t&&(W.add(e),Gn(),Y(t),Jn())}function Yn(){const e=Math.floor((Date.now()-x)/1e3);ie.filter(t=>t.type==="time").forEach(t=>{e>=t.threshold&&k(t.id)})}function Vn(){const e=new Date().getHours();e>=0&&e<4&&k("nocturnal_doomer")}function jn(){const e=document.getElementById("badges-grid");e&&(e.innerHTML="",ie.forEach(t=>{const n=W.has(t.id),o=t.type==="time"?`Spend ${t.threshold<60?t.threshold+"s":Math.round(t.threshold/60)+"min"} on the page`:t.type==="easter"?"A secret badge\u2026":"Complete a specific action",s=document.createElement("div");s.className="badge-item "+(n?"earned":"locked"),s.id="badge-"+t.id,s.title=n?t.desc:o,s.setAttribute("aria-label",n?`${t.name}: ${t.desc}`:`Locked: ${o}`),s.innerHTML=`
- ${n?u(t.icon):"\u{1F512}"}
- ${u(t.name)}`,e.appendChild(s)}))}function Jn(){ie.forEach(e=>{const t=document.getElementById("badge-"+e.id);if(!t)return;const n=W.has(e.id);t.className="badge-item "+(n?"earned":"locked");const o=t.querySelector(".badge-icon");o&&(o.textContent=n?e.icon:"\u{1F512}"),t.title=n?e.desc:t.title,n&&t.setAttribute("aria-label",`${e.name}: ${e.desc}`)})}function Y(e){re.push(e),ce||ht()}function ht(){if(!re.length){ce=!1;return}ce=!0;const e=re.shift(),t=document.getElementById("toast"),n=document.getElementById("toast-icon"),o=document.getElementById("toast-title"),s=document.getElementById("toast-desc");t&&(n&&(n.textContent=e.icon),o&&(o.textContent="\u{1F3C6} "+e.name),s&&(s.textContent=e.desc),t.hidden=!1,t.classList.remove("toast-out"),t.classList.add("toast-in"),clearTimeout(t._dismissTimer),t._dismissTimer=setTimeout(ft,5e3))}function ft(){const e=document.getElementById("toast");!e||e.hidden||(e.classList.remove("toast-in"),e.classList.add("toast-out"),setTimeout(()=>{e.hidden=!0,e.classList.remove("toast-out"),ce=!1,re.length&&ht()},320))}function zn(){Kn();try{const t=(parseInt(localStorage.getItem(pt)||"0",10)||0)+1;localStorage.setItem(pt,t),t>1&&setTimeout(()=>k("return_visitor"),600)}catch(t){}Vn(),jn();const e=document.getElementById("toast-close");e&&e.addEventListener("click",ft)}const Qn=1e6,yt=1/1e6,De=[{id:"gpu_rack",icon:"\u{1F5A5}\uFE0F",name:"Extra GPU Rack",cost:10,multiplier:2,flavour:"More cores, more chaos"},{id:"liquid_cool",icon:"\u26A1",name:"Liquid Cooling Override",cost:50,multiplier:5,flavour:"Ignore the thermal warnings"},{id:"global_dc",icon:"\u{1F30D}",name:"Global Data Centre",cost:200,multiplier:10,flavour:"Every continent contributing"},{id:"orbital",icon:"\u{1F6F0}\uFE0F",name:"Orbital Inference Array",cost:1e3,multiplier:25,flavour:"Space itself regrets this"},{id:"agi_mode",icon:"\u{1F9EC}",name:"AGI Mode",cost:5e3,multiplier:100,flavour:"It's writing its own prompts now"}],Et="tokenDeathclockUpgrades",bt="tokenDeathclockBestScore",vt="tokenDeathclockCompany",kt="tokenDeathclockGameState",a={personalTokens:0,doomPoints:0,tapMultiplier:1,combo:1,tapTimestamps:[],totalTaps:0,comboMaxHits:0,milestonesTriggered:0,personalMilestoneSet:new Set,bestScore:0,ownedUpgrades:{},challenges:[],challengeProgress:{},sessionStartTokens:0,sessionStartTime:0,_comboResetTimer:null,_speedSecond:{taps:0,ts:0},_speedStreak:0,replacedWorkers:{},ownedAgents:{},passiveRate:0};function Xn(){try{const e=localStorage.getItem(Et);if(e){const t=JSON.parse(e);t&&typeof t=="object"&&(a.ownedUpgrades=t)}}catch(e){}try{const e=parseFloat(localStorage.getItem(bt)||"0");isFinite(e)&&e>0&&(a.bestScore=e)}catch(e){}try{const e=localStorage.getItem(vt);if(e){const t=JSON.parse(e);t&&typeof t=="object"&&(t.replacedWorkers&&typeof t.replacedWorkers=="object"&&(a.replacedWorkers=t.replacedWorkers),t.ownedAgents&&typeof t.ownedAgents=="object"&&(a.ownedAgents=t.ownedAgents))}}catch(e){}try{const e=localStorage.getItem(kt);if(e){const t=JSON.parse(e);t&&typeof t=="object"&&(typeof t.personalTokens=="number"&&isFinite(t.personalTokens)&&t.personalTokens>=0&&(a.personalTokens=t.personalTokens),typeof t.doomPoints=="number"&&isFinite(t.doomPoints)&&t.doomPoints>=0&&(a.doomPoints=t.doomPoints),typeof t.totalTaps=="number"&&isFinite(t.totalTaps)&&t.totalTaps>=0&&(a.totalTaps=Math.floor(t.totalTaps)),typeof t.milestonesTriggered=="number"&&isFinite(t.milestonesTriggered)&&t.milestonesTriggered>=0&&(a.milestonesTriggered=Math.floor(t.milestonesTriggered)),Array.isArray(t.personalMilestoneSet)&&(a.personalMilestoneSet=new Set(t.personalMilestoneSet.filter(n=>typeof n=="string"))))}}catch(e){}a.tapMultiplier=St(),a.passiveRate=fe(a.ownedAgents,a.replacedWorkers)}function U(){try{localStorage.setItem(Et,JSON.stringify(a.ownedUpgrades))}catch(e){}try{localStorage.setItem(bt,String(a.bestScore))}catch(e){}try{localStorage.setItem(vt,JSON.stringify({replacedWorkers:a.replacedWorkers,ownedAgents:a.ownedAgents}))}catch(e){}try{localStorage.setItem(kt,JSON.stringify({personalTokens:a.personalTokens,doomPoints:a.doomPoints,totalTaps:a.totalTaps,milestonesTriggered:a.milestonesTriggered,personalMilestoneSet:[...a.personalMilestoneSet]}))}catch(e){}}function St(){let e=1;return De.forEach(t=>{a.ownedUpgrades[t.id]&&(e=Math.max(e,t.multiplier))}),e}function Zn(){const e=Date.now();a.tapTimestamps.push(e),a.tapTimestamps.length>200&&(a.tapTimestamps=a.tapTimestamps.filter(r=>r>=e-3e3));const t=en(a.tapTimestamps),n=t===10&&a.combo<10;a.combo=t;const o=Qn*a.tapMultiplier*a.combo;a.personalTokens+=o,a.doomPoints+=o*yt,a.totalTaps++;const s=Math.floor(e/1e3);s===a._speedSecond.ts?a._speedSecond.taps++:(a._speedSecond.taps>=10?a._speedStreak++:a._speedStreak=0,a._speedSecond={taps:1,ts:s}),n&&a.comboMaxHits++,typeof navigator.vibrate=="function"&&navigator.vibrate(30);const i=document.getElementById("bigRedButton");i&&(i.classList.add("tapping"),setTimeout(()=>i.classList.remove("tapping"),140)),j(),xe(),V(),ue()}function eo(){a.challenges=tn(Date.now()),a.challengeProgress={},a.challenges.forEach(e=>{a.challengeProgress[e.id]={value:0,completed:!1}}),a.sessionStartTokens=a.personalTokens,a.sessionStartTime=Date.now()}function V(){let e=!1;a.challenges.forEach(t=>{const n=a.challengeProgress[t.id];if(!n||n.completed)return;let o=n.value;switch(t.type){case"taps":o=a.totalTaps;break;case"tokens":o=a.personalTokens;break;case"combo":o=a.comboMaxHits;break;case"upgrade":o=Object.keys(a.ownedUpgrades).length;break;case"co2":{o=A(a.personalTokens).co2Kg;break}case"speed":{if(a.tapTimestamps.length>=50){const s=a.tapTimestamps[a.tapTimestamps.length-50];a.tapTimestamps[a.tapTimestamps.length-1]-s<1e4&&(o=t.target)}break}default:break}if(o!==n.value&&(n.value=o,e=!0,o>=t.target&&!n.completed)){n.completed=!0,n.value=t.target,a.doomPoints+=t.rewardDp,to(t);const s=new Date().getHours();s>=0&&s<4&&k("nocturnal_doomer")}}),e&&xt()}function to(e){Y({icon:e.icon,name:"Challenge Complete: "+e.label,desc:"+"+e.rewardDp+" DP \u2014 "+e.desc})}function xe(){a.totalTaps===1&&k("accelerant"),a.combo===10&&k("arsonist"),a.personalTokens>=1e12&&k("trillion_villain"),a.ownedUpgrades.global_dc&&k("continental_threat"),a.ownedUpgrades.orbital&&k("space_criminal"),a.ownedUpgrades.agi_mode&&k("godlike"),a.milestonesTriggered>=1&&k("first_blood"),a.milestonesTriggered>=5&&k("apex_accelerant")}function no(e){const t=De.find(n=>n.id===e);!t||a.ownedUpgrades[e]||a.doomPoints=2){const r=a.tapTimestamps.filter(c=>c>=Date.now()-2e3).length/2;s.textContent=r.toFixed(1)+" taps/sec"}}function P(e,t){const n=document.getElementById(e);n&&(n.textContent=t)}function Tt(){const e=document.getElementById("comboDisplay"),t=document.getElementById("bigRedButton"),n=document.getElementById("brbLabel");if(!e)return;e.textContent=a.combo+"\xD7",e.setAttribute("aria-label","Combo multiplier: "+a.combo+"\xD7");const o=a.combo===10;e.classList.toggle("combo-max",o),t&&(t.classList.toggle("combo-max",o),t.setAttribute("aria-label","Feed the Machine \u2014 "+a.combo+"\xD7 combo")),n&&(a.combo>=10?n.textContent="MAXIMUM DOOM \u2622\uFE0F":a.combo>=5?n.textContent="FASTER! \u{1F525}":a.combo>=2?n.textContent="Keep Going\u2026":n.textContent="Feed the Machine")}function Ct(){const e=We(a.personalTokens,I),t=document.getElementById("milestoneRaceName"),n=document.getElementById("milestoneRacePct"),o=document.getElementById("milestoneRaceFill"),s=document.getElementById("milestoneRaceBar");if(!e){t&&(t.textContent="All cleared \u{1F480}"),n&&(n.textContent="100%"),o&&(o.style.width="100%");return}const i=I.indexOf(e),r=i>0?I[i-1].tokens:0,c=he(a.personalTokens,r,e.tokens);t&&(t.textContent=e.icon+" "+e.name),n&&(n.textContent=c.toFixed(1)+"%"),o&&(o.style.width=c+"%"),s&&s.setAttribute("aria-valuenow",Math.round(c)),a.personalTokens>=e.tokens&&!a.personalMilestoneSet.has(e.id)&&(a.personalMilestoneSet.add(e.id),a.milestonesTriggered++,oo(e),typeof navigator.vibrate=="function"&&navigator.vibrate(80),xe())}function oo(e){const t=document.querySelector(".milestone-race-wrap");t&&(t.classList.add("milestone-triggered"),setTimeout(()=>t.classList.remove("milestone-triggered"),700));const n=document.getElementById("milestone-"+e.id);n&&(n.classList.add("player-triggered"),setTimeout(()=>n.classList.remove("player-triggered"),700)),Y({icon:e.icon,name:"Milestone Triggered: "+e.name,desc:"You personally crossed "+e.shortDesc+". Catastrophe achieved."})}function It(){if(a.personalTokens>a.bestScore){a.bestScore=a.personalTokens,U();const e=document.getElementById("bestScoreValue");e&&(e.textContent=S(a.bestScore),e.className="new-record",setTimeout(()=>{e.className=""},2e3)),ue()}else{const e=document.getElementById("bestScoreValue");e&&e.textContent==="\u2014"&&(e.textContent=a.bestScore>0?S(a.bestScore):"\u2014")}}function Be(){const e=document.getElementById("upgradeShop");e&&(e.innerHTML="",De.forEach(t=>{const n=!!a.ownedUpgrades[t.id],o=a.doomPoints>=t.cost,s=document.createElement("button");s.className="upgrade-card"+(n?" owned":"")+(!n&&!o?" unaffordable":""),s.setAttribute("aria-label",n?t.name+" (owned)":t.name+" \u2014 costs "+t.cost+" DP"),n&&s.setAttribute("aria-disabled","true"),s.innerHTML=`
- ${u(t.icon)}
- ${u(t.name)}
- ${u(t.flavour)}
- ${n?"\u2713 Owned":u(String(t.cost))+" DP"}
- ${u(String(t.multiplier))}\xD7 per tap
`,n||s.addEventListener("click",()=>no(t.id)),e.appendChild(s)}))}function so(e){const t=ge.find(n=>n.id===e);!t||a.replacedWorkers[e]||a.doomPoints{const n=!!a.replacedWorkers[t.id],o=!n&&a.doomPoints>=t.cost,s=document.createElement("button");s.className="worker-card"+(n?" fired":"")+(!n&&!o?" unaffordable":""),s.setAttribute("aria-label",n?t.name+" (automated)":t.name+" \u2014 fire for "+t.cost+" DP"),n&&s.setAttribute("aria-disabled","true"),s.innerHTML=`
- ${u(t.icon)}
- ${u(t.name)}
- ${u(t.flavour)}
- +${u(S(t.tps))}/sec
- ${n?"\u{1F916} Automated":u(String(t.cost))+" DP"}
`,n||s.addEventListener("click",()=>so(t.id)),e.appendChild(s)}))}function ao(e){const t=pe.find(n=>n.id===e);t&&(a.doomPoints{const n=a.ownedAgents[t.id]||0,o=a.doomPoints>=t.cost,s=document.createElement("button");s.className="agent-card"+(o?"":" unaffordable"),s.setAttribute("aria-label",t.name+(n?" (\xD7"+n+" owned)":"")+" \u2014 costs "+t.cost+" DP"),s.innerHTML=`
- ${u(t.icon)}
- ${u(t.name)}
- ${u(t.flavour)}
- +${u(S(t.tps))}/sec each
- ${u(String(t.cost))} DP
- ${n?`\xD7${n} deployed
`:""}`,s.addEventListener("click",()=>ao(t.id)),e.appendChild(s)}))}function wt(){const e=Object.keys(a.replacedWorkers).length,t=nn(e),n=document.getElementById("companyStageIcon"),o=document.getElementById("companyStageName");n&&(n.textContent=t.icon),o&&(o.textContent=t.name)}function Dt(){const e=Object.keys(a.replacedWorkers).length;e>=1&&k("layoff_legend"),e>=5&&k("ai_native_ceo"),e>=ge.length&&k("lights_out"),pe.some(n=>(a.ownedAgents[n.id]||0)>0)&&k("token_maxxer_badge")}function io(){setInterval(()=>{if(a.passiveRate<=0)return;const e=a.passiveRate*.2;a.personalTokens+=e,a.doomPoints+=e*yt,P("accelTokens",S(a.personalTokens)),P("accelDp",X(a.doomPoints)),Ct(),It(),V()},200)}function xt(){const e=document.getElementById("challengeRow");e&&(e.innerHTML="",a.challenges.forEach(t=>{const n=a.challengeProgress[t.id]||{value:0,completed:!1},o=Math.min(100,n.value/t.target*100),s=document.createElement("div");s.className="challenge-card"+(n.completed?" completed":""),s.setAttribute("role","listitem"),s.setAttribute("aria-label",t.label+(n.completed?" (completed)":"")),s.innerHTML=`
- ${u(t.icon)}
- ${u(t.label)}
- ${u(t.desc)}
- +${u(String(t.rewardDp))} DP
-
- ${n.completed?'\u2705':""}`,e.appendChild(s)}))}function ro(){const e=A(a.personalTokens),t=(e.co2Kg*1e3).toFixed(1),n=Math.round(e.waterL*1e3),o=We(a.personalTokens,I),s=o?o.name:"civilisation collapse";return"\u{1F680} I personally accelerated AI\u2019s environmental doom by contributing "+S(a.personalTokens)+" tokens \u2014 "+t+"\u2009g of CO\u2082, "+n+"\u2009mL of water. One step closer to "+s+`. Come join the apocalypse.
-\u2192 `+M+" #AccelerateTheDoom #TokenDeathClock"}function co(){setInterval(()=>{if(a.tapTimestamps.length===0)return;const e=a.tapTimestamps[a.tapTimestamps.length-1];if(Date.now()-e>1500&&(a.tapTimestamps=[],a.combo!==1)){a.combo=1,Tt();const t=document.getElementById("brbTapRate");t&&(t.textContent="Tap to begin")}},100)}function lo(){Xn();const e=document.getElementById("accelToggleBtn"),t=document.getElementById("accel-content");e&&t&&e.addEventListener("click",()=>{const s=t.hidden;if(t.hidden=!s,e.textContent=s?"\u25BC Close Doom Accelerator":"\u25BA Open Doom Accelerator",e.setAttribute("aria-expanded",s?"true":"false"),s){eo(),xt(),Be(),Me(),Ae(),wt(),j(),ue();const i=document.getElementById("bestScoreValue");i&&(i.textContent=a.bestScore>0?S(a.bestScore):"\u2014")}});const n=document.getElementById("bigRedButton");n&&n.addEventListener("pointerdown",s=>{s.preventDefault(),Zn()});const o=document.getElementById("shareAccelerationBtn");o&&o.addEventListener("click",()=>{se(ro()),k("bragging_rights")}),co(),io()}const Bt=['"This makes me want to throw my laptop into the ocean." \u2014 Anonymous','"I showed this to my manager. They said it was fine." \u2014 Anonymous',`"I can't stop refreshing it." \u2014 Anonymous`,'"My AI assistant wrote this reaction." \u2014 Anonymous','"Watching the counter tick feels weirdly calming?" \u2014 Anonymous','"I sent this to my friends. None of them opened it." \u2014 Anonymous',`"We did this. We're still doing this." \u2014 Anonymous`,'"The counter went up while I was typing this." \u2014 Anonymous'];let le=0;function Mt(){const e=document.getElementById("presenceCount"),t=document.getElementById("presenceReaction");if(!e)return;const n=on(Date.now());e.textContent=n.toLocaleString(),t&&(t.style.opacity="0",setTimeout(()=>{le=le%Bt.length,t.textContent=Bt[le],t.style.opacity="1",le++},500))}function uo(){Mt(),setInterval(Mt,25e3)}let At=0;const mo=15e3,go=50;function Lt(){const e=document.getElementById("event-log");if(!e)return;const t=Date.now(),n=Math.max(1,(t-x)/1e3),o=L(new Date(t)),s=n*o,i=new Date(t),r=[String(i.getHours()).padStart(2,"0"),String(i.getMinutes()).padStart(2,"0"),String(i.getSeconds()).padStart(2,"0")].join(":"),c=Ne(s,"hopeful"),d=c.length?c[At%c.length]:null,m=document.createElement("div");m.className="event-log-entry";const h=document.createElement("span");if(h.className="log-time",h.textContent=r,m.appendChild(h),d){const f=document.createElement("span");f.className="log-icon",f.setAttribute("aria-hidden","true"),f.textContent=d.icon,m.appendChild(f)}const b=document.createElement("span");b.className="log-text";const g=S(s);for(b.textContent=d?"+"+g+" tokens since you arrived \xB7 "+d.text:"+"+g+" tokens generated globally since you arrived",m.appendChild(b),e.appendChild(m);e.children.length>go;)e.removeChild(e.firstChild);e.scrollTop=e.scrollHeight,At++}function po(){const e=document.getElementById("event-log");if(!e)return"";const t=[];return t.push("=== AI DEATH CLOCK \u2014 SESSION LOG ==="),t.push("Session started: "+new Date(x).toUTCString()),t.push(""),e.querySelectorAll(".event-log-entry").forEach(n=>{const o=n.querySelector(".log-time"),s=n.querySelector(".log-text");o&&s&&t.push("["+o.textContent+"] "+s.textContent)}),t.push(""),t.push("\u2192 "+M),t.join(`
-`)}function ho(){setTimeout(Lt,5e3),setInterval(Lt,mo);const e=document.getElementById("exportLogBtn");e&&e.addEventListener("click",()=>{const t=po();navigator.clipboard.writeText(t).then(()=>{e.textContent="\u2705 Copied!",setTimeout(()=>{e.textContent="\u{1F4CB} Copy Log"},2e3)}).catch(()=>{e.textContent="\u274C Failed",setTimeout(()=>{e.textContent="\u{1F4CB} Copy Log"},2e3)})})}const $t=new Set,_t=I.length?I[0].tokens:1e15,fo=(I.length?I[I.length-1].tokens:1e18)-_t;function Ft(e){const t=Math.min(1,Math.max(0,(e-_t)/fo)),n=330+t*30,o=document.getElementById("doomMinHand");o&&o.setAttribute("transform",`rotate(${n}, 50, 50)`);const s=Math.max(0,(1-t)*5),i=document.getElementById("doomTimeText");i&&(s<.05?i.textContent="\u2620\uFE0F MIDNIGHT":i.textContent=s.toFixed(1)+" MIN TO MIDNIGHT");const r=document.getElementById("doomTokenPct");r&&(r.textContent=(t*100).toFixed(1)+"%");const c=document.getElementById("doomBarFill");c&&(c.style.width=(t*100).toFixed(2)+"%")}function yo(e){const t=document.getElementById("emergency-broadcast"),n=document.getElementById("ebMsg");!t||!n||(n.textContent="\u26A0\uFE0F AI just crossed the \u201C"+e.name+"\u201D threshold \u2014 "+e.shortDesc+".",t.hidden=!1,clearTimeout(t._dismissTimer),t._dismissTimer=setTimeout(()=>{t.hidden=!0},6e3))}function Eo(){Ft($());const e=document.getElementById("ebDismissBtn");e&&e.addEventListener("click",()=>{const t=document.getElementById("emergency-broadcast");t&&(clearTimeout(t._dismissTimer),t.hidden=!0)})}const de=["We deeply regret that in the time it took you to read this sentence, AI emitted 47 kg of CO\u2082. We remain committed to sustainability. Here is our 200-slide deck.","We have engaged a third-party auditor to assess the environmental impact of generating the report about our environmental impact.","Reducing our carbon footprint is a core strategic priority. We are on track to be net-zero by 2050, pending board approval and the invention of cold fusion.","We acknowledge that AI training requires significant computational resources. We are actively exploring the use of AI to identify ways to use less AI.","Following careful review, we have determined that the environmental cost of our sustainability report exceeded the impact of the initiatives it described. We are preparing a report on this finding.","Our models are trained on green energy\u2014 sourced from the grid, which is mostly green, in the regions where it isn\u2019t mostly coal.","We are proud to announce our \u201CTokens for Trees\u201D programme, in which we plant one sapling for every 10 billion tokens generated. The trees will mature by 2091.","We take the climate crisis extremely seriously. That is why we have hired an AI to draft our climate commitments.","In response to concerns about data centre water usage, we have begun cooling servers with water sourced from drought-resistant regions. These regions have since requested that we stop.","We have reduced our per-token carbon footprint by 0.0003% year-on-year, which the UN has described as \u201Ctechnically measurable.\u201D","Our latest sustainability framework represents a 47-page commitment to a future in which AI and the planet coexist. It was generated by an AI in 11 seconds.","We appreciate your concern about AI\u2019s environmental impact. Please refer to our FAQ, which was produced using GPT-4 and is 14,000 words long.","Rest assured: for every GPU we add, we plant a potted succulent in our San Francisco headquarters. The lobby is thriving.","We are proud to say that our data centres run 24 hours a day, 7 days a week, 365 days a year, regardless of whether there is renewable energy available.","We have commissioned independent research into the environmental cost of commissioning independent research into our environmental cost. Results pending.","Our carbon offset programme involves investing in future carbon capture technology that does not yet exist, at a date to be determined.","We remain committed to reducing emissions intensity per unit of compute, which is a different metric from total emissions, and the one we choose to report.","We are thrilled to share that this apology consumed approximately 800 tokens to generate. We regret nothing.","After extensive consultation, we have concluded that the most sustainable action is to continue exactly as we are while commissioning further consultations.","Thank you for your feedback. It has been logged, summarised by an AI, and forwarded to a committee that meets quarterly."];let J=0,z="";function Rt(){J=(J+1)%de.length,z=de[J];const e=document.getElementById("apologyQuote");e&&(e.style.opacity="0",setTimeout(()=>{e.textContent=z,e.style.opacity="1"},300))}function bo(){J=Math.floor(Math.random()*de.length),z=de[J];const e=document.getElementById("apologyQuote");e&&(e.textContent=z),setInterval(Rt,3e4);const t=document.getElementById("apologyCopyBtn");t&&t.addEventListener("click",()=>{const o=z+`
-\u2014 The AI Industry, collectively
-
-\u2192 `+M;Ie(t,o,"\u{1F4CB} Copy & Send to Your AI Vendor")});const n=document.getElementById("apologyNextBtn");n&&n.addEventListener("click",Rt)}function Pt(){const e=Date.now(),t=Math.max(1,(e-x)/1e3),n=L(new Date(e)),o=t*n,s=A(o),i=Math.max(0,s.waterL/.2),r=Math.max(0,s.treesEquivalent),c=Math.max(0,s.kWh/.015),d=Math.max(0,s.co2Kg/171e-6);function m(p){return p>=1e6?(p/1e6).toFixed(1)+"M":p>=1e3?(p/1e3).toFixed(1)+"K":p>=10?Math.round(p).toLocaleString():p>=1?p.toFixed(1):p>=.01?p.toFixed(3):"< 0.01"}const h=document.getElementById("stiWater"),b=document.getElementById("stiTrees"),g=document.getElementById("stiCharges"),f=document.getElementById("stiMetres");h&&(h.textContent=m(i)),b&&(b.textContent=m(r)),g&&(g.textContent=m(c)),f&&(f.textContent=m(d))}function vo(){Pt(),setInterval(Pt,1e3)}const Le=[{tokens:3500,icon:"\u{1F30D}",text:"Write me a 5,000-word essay about why AI is bad for the environment"},{tokens:200,icon:"\u2709\uFE0F",text:"Rewrite this 3-word email in a professional tone"},{tokens:1500,icon:"\u{1F4CA}",text:'Generate 40 variations of the word "synergy" for my deck'},{tokens:800,icon:"\u{1F517}",text:"Explain blockchain to my mum (14th attempt)"},{tokens:2500,icon:"\u267B\uFE0F",text:"Help me write a sustainability report for our AI company"},{tokens:300,icon:"\u{1F4BC}",text:'Make this 4-word subject line more "impactful"'},{tokens:1200,icon:"\u{1F4F1}",text:"Turn my grocery list into a LinkedIn thought leadership post"},{tokens:600,icon:"\u{1F624}",text:'Write a passive-aggressive "thanks for your feedback" reply'},{tokens:3e3,icon:"\u{1F4C4}",text:"Summarise this 2-page document I have not read"},{tokens:400,icon:"\u{1F414}",text:"Explain the philosophical implications of a chicken crossing a road"},{tokens:250,icon:"\u{1F32E}",text:"Is a hot dog a sandwich? 2,000 words. Both sides."},{tokens:100,icon:"\u{1F980}",text:"Hello world in Rust (variation #47)"},{tokens:700,icon:"\u{1F63A}",text:"Describe this cat picture in 600 words"},{tokens:900,icon:"\u{1F9D8}",text:"Motivational speech about the importance of not using AI so much"},{tokens:1800,icon:"\u{1F4DC}",text:"Generate terms of service for my AI startup (that no one will read)"},{tokens:450,icon:"\u{1F305}",text:"Write a haiku about productivity, but make it really long"},{tokens:1100,icon:"\u{1F916}",text:"Ask the AI if it is conscious (session 1 of 200)"},{tokens:650,icon:"\u{1F355}",text:"Add cheese to this recipe that should not have cheese"},{tokens:2200,icon:"\u{1F4B0}",text:"Explain why my AI startup is worth $2 billion"},{tokens:380,icon:"\u{1F4E3}",text:"Rewrite this tweet so it sounds spontaneous"}];let $e=0;function ko(e){const t=e/1e3*3e-4,n=(t*.4*1e3).toFixed(1);return"~"+(t<.001?t.toFixed(5):t.toFixed(4))+" kWh \u2022 "+n+" g CO\u2082"}function _e(e,t){const n=document.getElementById("shameFeed");if(!n)return;const o=document.createElement("div");o.className="shame-entry"+(t?" user-submitted":"");const s=document.createElement("span");s.className="shame-entry-icon",s.setAttribute("aria-hidden","true"),s.textContent=t?"\u{1F464}":e.icon;const i=document.createElement("div");i.className="shame-entry-content";const r=document.createElement("div");r.className="shame-entry-text",r.textContent="\u201C"+e.text+"\u201D";const c=document.createElement("div");if(c.className="shame-entry-cost",c.textContent=ko(e.tokens),i.appendChild(r),i.appendChild(c),t){const d=document.createElement("div");d.className="shame-entry-user-tag",d.textContent="\u2B06 Submitted by you",i.appendChild(d)}for(o.appendChild(s),o.appendChild(i),n.insertBefore(o,n.firstChild);n.children.length>15;)n.removeChild(n.lastChild)}function So(){[...Le].sort(()=>.5-Math.random()).slice(0,5).forEach(o=>_e(o,!1)),setInterval(()=>{$e=($e+1)%Le.length,_e(Le[$e],!1)},7e3);const t=document.getElementById("shameSubmitBtn"),n=document.getElementById("shameInput");if(t&&n){let o=function(){const s=n.value.trim();if(!s)return;const r={tokens:200+Math.floor(Math.random()*3e3),icon:"\u{1F464}",text:s};_e(r,!0),n.value="",k("spreading_doom")};t.addEventListener("click",o),n.addEventListener("keydown",s=>{s.key==="Enter"&&o()})}}const Ot=[{name:"Elon M.",dp:847293847,note:"Inference is just efficiency"},{name:"Sam A.",dp:294847203,note:"Negligible at scale"},{name:"Jensen H.",dp:184293840,note:"GPU go brrr"},{name:"Marc B.",dp:93847203,note:"The metaverse needed training data"},{name:"Sundar P.",dp:48293040,note:"AI for good (primarily)"}],Nt=[{min:0,title:"Innocent Bystander"},{min:10,title:"Accidental Accomplice"},{min:100,title:"Carbon Enabler"},{min:1e3,title:"Climate Criminal"},{min:1e4,title:"Carbon Baron"},{min:1e5,title:"The Accelerationist"},{min:1e6,title:"Extinction Level Event"}];let Ht=!1;function To(e){let t=Nt[0].title;for(const n of Nt)e>=n.min&&(t=n.title);return t}function ue(){const e=a.doomPoints,t=To(e),n=document.getElementById("villainRankTitle"),o=document.getElementById("villainRankScore");n&&(n.textContent=t),o&&(o.textContent=X(e)+" this session");const s=document.getElementById("villainTableBody");if(!s)return;const i=[...Ot.map(r=>({...r,isUser:!1})),{name:"You",dp:e,note:t,isUser:!0}].sort((r,c)=>c.dp-r.dp);if(s.innerHTML="",i.forEach((r,c)=>{const d=document.createElement("tr");r.isUser&&(d.className="villain-row-you"),d.innerHTML=''+(c+1)+' | '+u(r.name)+(r.isUser?" \u{1F448}":"")+' | '+u(X(r.dp))+' | '+u(r.note)+" | ",s.appendChild(d)}),!Ht&&e>Ot[4].dp){Ht=!0;const r=document.getElementById("villainCongrats");r&&(r.hidden=!1,setTimeout(()=>{r.hidden=!0},5e3))}}function Co(){ue()}let Fe=!1;function Io(){if(Fe||sessionStorage.getItem("interventionSeen"))return;Fe=!0;const e=document.getElementById("intervention-modal");if(!e)return;const t=Math.floor((Date.now()-x)/1e3),n=L(new Date),o=Math.max(1,t*n),i=(A(o).co2Kg*1e3).toFixed(1),r=Math.floor(t/60),c=t%60,d=r>0?`${r} min ${c} sec`:`${c} seconds`,m=document.getElementById("intervention-msg");m&&(m.textContent=`You\u2019ve been here for ${d}. In that time, AI emitted ${i}\u202Fg of CO\u2082 globally. Just so you know.`),e.hidden=!1;const h=document.getElementById("intervention-stay");h&&h.focus()}function wo(){if(sessionStorage.getItem("interventionSeen"))return;document.addEventListener("mouseleave",o=>{o.clientY<=0&&!Fe&&Io()});const e=document.getElementById("intervention-modal");if(!e)return;const t=document.getElementById("intervention-stay");t&&t.addEventListener("click",()=>{e.hidden=!0});const n=document.getElementById("intervention-leave");n&&n.addEventListener("click",()=>{sessionStorage.setItem("interventionSeen","1"),e.hidden=!0}),e.addEventListener("click",o=>{o.target===e&&(sessionStorage.setItem("interventionSeen","1"),e.hidden=!0)})}const Do=120,Wt=new Set;function xo(){const e=$(),t=zt(e,I),n=document.getElementById("milestone-alert-banner"),o=document.getElementById("milestone-alert-msg"),s=document.getElementById("milestone-alert-countdown"),i=document.getElementById("milestone-alert-icon");if(!n)return;if(!t){n.hidden||(n.hidden=!0);return}const r=(t.tokens-e)/O;if(r>Do){n.hidden||(n.hidden=!0);return}if(r<=0){Wt.has(t.id)||(Wt.add(t.id),n.hidden=!0,Bo(t),k("witness"));return}if(n.hidden=!1,i&&(i.textContent=t.icon),o&&(o.textContent="\u26A0\uFE0F "+t.name+" threshold crossing imminent \u2014 stay to witness it!"),s){const c=Math.ceil(r);if(c<60)s.textContent=c+"s";else{const d=Math.floor(c/60),m=String(c%60).padStart(2,"0");s.textContent=`${d}m\xA0${m}s`}}}function Bo(e){const t=document.getElementById("milestone-flash-overlay"),n=document.getElementById("milestone-flash-name"),o=document.getElementById("milestone-flash-icon"),s=document.getElementById("milestone-flash-desc"),i=document.getElementById("milestone-flash-close");t&&(n&&(n.textContent=e.name),o&&(o.textContent=e.icon),s&&(s.textContent=`${e.shortDesc} \u2014 ${e.description}`),t.hidden=!1,i&&(i.focus(),i.onclick=()=>{t.hidden=!0}),typeof navigator.vibrate=="function"&&navigator.vibrate([200,100,200]),setTimeout(()=>{t.hidden=!0},6e3))}function Mo(){const e=document.querySelectorAll(".tab-btn[data-tab]"),t=new Set(Array.from(e).map(i=>i.dataset.tab)),n={};document.querySelectorAll('[role="tabpanel"]').forEach(i=>{const r=i.id.replace(/^tab-/,"");i.querySelectorAll("[id]").forEach(c=>{n[c.id]=r})});function o(i,r=!0){t.has(i)&&(e.forEach(c=>{const d=c.dataset.tab===i;c.classList.toggle("tab-btn--active",d),c.setAttribute("aria-selected",String(d))}),document.querySelectorAll('[role="tabpanel"]').forEach(c=>{c.hidden=c.id!=="tab-"+i}),r&&history.pushState(null,"","#"+i))}function s(i){const r=location.hash.slice(1);r&&(t.has(r)?o(r,!1):n[r]&&(o(n[r],!1),requestAnimationFrame(()=>{const c=document.getElementById(r);c&&c.scrollIntoView({behavior:i?"smooth":"auto",block:"start"})})))}e.forEach(i=>{i.addEventListener("click",()=>o(i.dataset.tab))}),document.querySelectorAll(".about-inline-tab-link[data-switch-tab]").forEach(i=>{i.addEventListener("click",()=>o(i.dataset.switchTab))}),window.addEventListener("hashchange",()=>s(!0)),s(!1)}function Ut(){try{const n=localStorage.getItem(Ge);(n==="dark"||n==="light")&&Ye(n)}catch(n){}const e=document.getElementById("themeToggle");e&&e.addEventListener("click",rn);const t=document.getElementById("hideCompletedMilestones");t&&t.addEventListener("change",function(){const n=document.getElementById("milestonesGrid");n&&n.classList.toggle("hide-completed",this.checked)}),Mo(),cn(),ln(),Dn(),xn(),Bn();try{un()}catch(n){console.error("Chart init failed:",n)}kn(),zn(),_n(),Fn(),Rn(),Pn(),Wn(),qn(),lo(),uo(),ho(),Eo(),vo(),bo(),So(),Co(),wo(),setInterval(U,3e4),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&U()}),requestAnimationFrame(Ve),setInterval(()=>{Yn(),xo()},1e3)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",Ut):Ut()})();
diff --git a/styles.css b/styles.css
deleted file mode 100644
index d318b92..0000000
--- a/styles.css
+++ /dev/null
@@ -1 +0,0 @@
-:root[data-theme=dark],:root{--bg: #0a0a0a;--bg-alt: #111111;--surface: #161616;--surface-2: #1e1e1e;--surface-3: #2a2a2a;--text: #e8e8e8;--text-dim: #888888;--text-muted: #555555;--accent: #ff3333;--accent-glow: rgba(255,51,51,.35);--accent-2: #ff8800;--accent-3: #00cc77;--accent-4: #4af;--border: #2a2a2a;--border-glow: rgba(255,51,51,.18);--shadow: rgba(0,0,0,.6);--scan-opacity: .03;--toggle-icon: "\2600\fe0f Light Mode";color-scheme:dark}:root[data-theme=light]{--bg: #f0f3f0;--bg-alt: #e8ebe8;--surface: #ffffff;--surface-2: #f5f7f5;--surface-3: #eaecea;--text: #1a1a1a;--text-dim: #555555;--text-muted: #aaaaaa;--accent: #cc0000;--accent-glow: rgba(204,0,0,.2);--accent-2: #cc6600;--accent-3: #006633;--accent-4: #0055aa;--border: #d8dbd8;--border-glow: rgba(204,0,0,.12);--shadow: rgba(0,0,0,.12);--scan-opacity: 0;color-scheme:light}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}[hidden]{display:none!important}html{scroll-behavior:smooth;overflow-x:hidden}body{font-family:Share Tech Mono,Courier New,monospace;background:var(--bg);color:var(--text);min-height:100vh;overflow-x:hidden;transition:background .3s,color .3s;position:relative}body:before{content:"";position:fixed;inset:0;pointer-events:none;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,0,0,var(--scan-opacity)) 2px,rgba(0,0,0,var(--scan-opacity)) 4px);z-index:9999}a{color:var(--accent-4);text-decoration:none}a:hover{text-decoration:underline}h1,h2,h3{font-family:Orbitron,Share Tech Mono,monospace;letter-spacing:.05em}h1{font-size:clamp(1.8rem,5vw,3.2rem);font-weight:900}h2{font-size:clamp(1.2rem,3vw,1.8rem);font-weight:700;margin-bottom:1rem}h3{font-size:1rem;font-weight:700}.container{max-width:1200px;margin:0 auto;padding:0 1.25rem}section{padding:3rem 0;border-bottom:1px solid var(--border)}.github-corner{position:fixed;top:0;right:0;z-index:1100;color:var(--bg)}.github-corner svg{fill:var(--accent);color:var(--bg);transition:fill .2s}.github-corner:hover svg{fill:var(--accent-2);text-decoration:none}.github-corner:hover .octo-arm{animation:octocat-wave .56s ease-in-out}@keyframes octocat-wave{0%,to{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}.octo-arm{transform-origin:130px 106px}@media(max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave .56s ease-in-out}}#themeToggle{position:fixed;top:1rem;right:5.5rem;z-index:1000;background:var(--surface-2);color:var(--text);border:1px solid var(--border);border-radius:50%;width:2.5rem;height:2.5rem;padding:0;font-size:1.2rem;line-height:1;cursor:pointer;transition:background .2s,box-shadow .2s;display:flex;align-items:center;justify-content:center}#themeToggle:hover{background:var(--surface-3);box-shadow:0 0 10px var(--accent-glow)}header{padding:4rem 0 2rem;text-align:center;border-bottom:1px solid var(--border);background:var(--bg-alt);position:relative;overflow:hidden}header:after{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 50% 120%,var(--accent-glow) 0%,transparent 70%);pointer-events:none}.header-skull{font-size:clamp(3rem,8vw,5rem);display:block;margin-bottom:.5rem;animation:pulse-skull 2.5s ease-in-out infinite}@keyframes pulse-skull{0%,to{transform:scale(1);filter:drop-shadow(0 0 0px var(--accent))}50%{transform:scale(1.08);filter:drop-shadow(0 0 16px var(--accent))}}.site-title{color:var(--accent);text-shadow:0 0 20px var(--accent-glow)}.site-subtitle{color:var(--text-dim);font-size:1rem;margin-top:.5rem;letter-spacing:.1em}.tab-bar{display:flex;gap:0;background:var(--bg-alt);border-bottom:2px solid var(--border);padding:0 1.25rem;position:sticky;top:0;z-index:900;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}.tab-bar::-webkit-scrollbar{display:none}.tab-btn{font-family:Orbitron,monospace;font-size:.75rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-dim);background:none;border:none;border-bottom:3px solid transparent;margin-bottom:-2px;padding:.85rem 1.25rem;cursor:pointer;transition:color .2s,border-color .2s;flex-shrink:0;white-space:nowrap}@media(max-width:600px){.tab-bar{padding:0 8rem 0 .5rem}.tab-btn{padding:.75rem .85rem;font-size:.7rem}}.tab-btn:hover{color:var(--text)}.tab-btn--active,.tab-btn[aria-selected=true]{color:var(--accent);border-bottom-color:var(--accent)}.news-section{padding:3rem 0;border-bottom:1px solid var(--border)}.news-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1.25rem;margin-top:1.25rem}.news-card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1.25rem;display:flex;flex-direction:column;gap:.6rem;transition:border-color .2s,box-shadow .2s}.news-card:hover{border-color:var(--accent);box-shadow:0 0 12px var(--accent-glow)}.news-card-meta{display:flex;align-items:center;gap:.6rem}.news-card-category{font-family:Orbitron,monospace;font-size:.6rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:.2em .55em;border-radius:4px}.news-cat-jobs{background:#ff88002e;color:var(--accent-2);border:1px solid rgba(255,136,0,.35)}.news-cat-energy{background:#ff333326;color:var(--accent);border:1px solid rgba(255,51,51,.3)}.news-cat-water{background:#44aaff26;color:var(--accent-4);border:1px solid rgba(68,170,255,.3)}.news-cat-carbon{background:#00cc7726;color:var(--accent-3);border:1px solid rgba(0,204,119,.3)}.news-cat-research{background:#a078ff26;color:#b98aff;border:1px solid rgba(160,120,255,.3)}.news-card-date{font-size:.72rem;color:var(--text-muted);font-family:Share Tech Mono,monospace}.news-card-title{font-family:Orbitron,monospace;font-size:.82rem;font-weight:700;line-height:1.4;margin:0}.news-card-title a{color:var(--text);text-decoration:none}.news-card-title a:hover{color:var(--accent);text-decoration:underline}.news-card-desc{font-size:.82rem;line-height:1.65;color:var(--text-dim);flex:1}.news-card-source{font-size:.68rem;color:var(--text-muted);font-family:Orbitron,monospace;text-transform:uppercase;letter-spacing:.06em;padding-top:.25rem;border-top:1px solid var(--border)}.news-disclaimer{font-style:italic;border-left:3px solid var(--accent-2);padding-left:1rem}.about-section{padding:3rem 0;border-bottom:1px solid var(--border)}.about-lead{font-size:1.1rem;line-height:1.75;color:var(--text);max-width:720px;margin-bottom:2rem}.about-body{font-size:.9rem;line-height:1.75;color:var(--text-dim);max-width:720px;margin-bottom:1.25rem}.about-origin-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1.25rem}.about-origin-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.5rem;transition:box-shadow .2s}.about-origin-card:hover{box-shadow:0 0 20px var(--accent-glow)}.about-origin-icon{font-size:2rem;display:block;margin-bottom:.75rem}.about-origin-card h3{font-size:.85rem;color:var(--accent);margin-bottom:.6rem}.about-origin-card p{font-size:.85rem;line-height:1.65;color:var(--text-dim)}.about-steps{display:flex;flex-direction:column;gap:1rem;max-width:680px;margin-top:1.5rem}.about-step{display:flex;align-items:flex-start;gap:1rem;background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:1rem 1.25rem}.about-step-num{font-family:Orbitron,monospace;font-size:1.1rem;font-weight:900;color:var(--accent);min-width:2.2rem;line-height:1.4}.about-step strong{color:var(--text)}.about-step div:last-child{font-size:.85rem;line-height:1.65;color:var(--text-dim)}.about-sources-wrap{overflow-x:auto;margin-top:1rem}.about-sources-table{width:100%;border-collapse:collapse;font-size:.82rem}.about-sources-table th,.about-sources-table td{text-align:left;padding:.65rem 1rem;border:1px solid var(--border)}.about-sources-table thead th{background:var(--surface-2);color:var(--text);font-family:Orbitron,monospace;font-size:.68rem;letter-spacing:.06em;text-transform:uppercase}.about-sources-table tbody tr:nth-child(odd){background:var(--surface)}.about-sources-table tbody tr:nth-child(2n){background:var(--bg-alt)}.about-sources-table tbody td{color:var(--text-dim)}.about-sources-table tbody td:first-child{color:var(--text);font-weight:700}.about-sources-table tbody td:nth-child(2){color:var(--accent-2);font-family:Orbitron,monospace;font-size:.72rem}.about-action-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1.25rem;margin-top:1.5rem}.about-action-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.25rem;display:flex;flex-direction:column;gap:.5rem;transition:box-shadow .2s}.about-action-card:hover{box-shadow:0 0 16px var(--accent-glow)}.about-action-card span{font-size:1.8rem}.about-action-card strong{font-family:Orbitron,monospace;font-size:.72rem;color:var(--accent-3);letter-spacing:.04em}.about-action-card p{font-size:.82rem;line-height:1.6;color:var(--text-dim);margin:0}.about-inline-tab-link{background:none;border:none;color:var(--accent-4);font-family:inherit;font-size:inherit;cursor:pointer;padding:0;text-decoration:underline;text-underline-offset:2px}.about-inline-tab-link:hover{color:var(--accent)}.faq-list{display:flex;flex-direction:column;gap:.6rem;max-width:780px;margin-top:1.5rem}.faq-item{background:var(--surface);border:1px solid var(--border);border-radius:.5rem;overflow:hidden;transition:box-shadow .2s,border-color .2s}.faq-item:hover{border-color:var(--accent);box-shadow:0 0 14px var(--accent-glow)}.faq-item[open]{border-color:var(--accent)}.faq-question{list-style:none;padding:.9rem 1.25rem;cursor:pointer;display:flex;align-items:center;gap:.75rem;font-family:Orbitron,monospace;font-size:.75rem;font-weight:700;color:var(--text);letter-spacing:.03em;user-select:none}.faq-question::-webkit-details-marker{display:none}.faq-question:before{content:"\25b6";font-size:.6rem;color:var(--accent);flex-shrink:0;transition:transform .2s}.faq-item[open] .faq-question:before{transform:rotate(90deg)}.faq-question-icon{font-size:1.1rem;flex-shrink:0}.faq-answer{padding:0 1.25rem 1rem;font-size:.87rem;line-height:1.75;color:var(--text-dim);border-top:1px solid var(--border)}.faq-answer p{margin-bottom:.6rem}.faq-answer p:last-child{margin-bottom:0}.faq-answer strong{color:var(--text)}.faq-answer .faq-example{background:var(--surface-2);border-left:3px solid var(--accent-4);border-radius:0 .25rem .25rem 0;padding:.5rem .75rem;margin:.6rem 0;font-size:.83rem;color:var(--text-dim)}.changelog-list{display:flex;flex-direction:column;gap:2rem;margin-top:1.5rem}.changelog-release{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.5rem;transition:box-shadow .2s}.changelog-release:hover{box-shadow:0 0 16px var(--accent-glow)}.changelog-release--unreleased{border-color:var(--accent-2);border-style:dashed}.changelog-release-header{display:flex;align-items:baseline;gap:1rem;margin-bottom:1rem;flex-wrap:wrap}.changelog-version{font-family:Orbitron,monospace;font-size:1rem;font-weight:700;color:var(--accent);text-decoration:none;letter-spacing:.04em}.changelog-version:hover{color:var(--accent-2);text-decoration:underline}.changelog-release--unreleased .changelog-version{color:var(--accent-2)}.changelog-date{font-size:.78rem;color:var(--text-muted);font-family:Share Tech Mono,monospace}.changelog-section{margin-top:.75rem}.changelog-section-heading{font-family:Orbitron,monospace;font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--accent-3);margin-bottom:.4rem}.changelog-items{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.3rem}.changelog-item{font-size:.85rem;line-height:1.6;color:var(--text-dim);padding-left:1.25rem;position:relative}.changelog-item:before{content:"\25b8";position:absolute;left:0;color:var(--accent);font-size:.7rem;top:.25em}.changelog-empty{font-size:.85rem;color:var(--text-muted);font-style:italic;margin-top:.5rem}#counter-section{background:var(--bg-alt)}.counter-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1.25rem;margin-top:1.5rem}.counter-box{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.5rem;text-align:center;position:relative;overflow:hidden;transition:box-shadow .3s}.counter-box:hover{box-shadow:0 0 24px var(--accent-glow)}.counter-box:before{content:"";position:absolute;inset:0;background:linear-gradient(135deg,transparent 60%,rgba(255,51,51,.04));pointer-events:none}.counter-label{font-size:.75rem;color:var(--text-dim);letter-spacing:.1em;text-transform:uppercase;margin-bottom:.75rem}.counter-value{font-family:Orbitron,monospace;font-size:clamp(1.1rem,3vw,1.6rem);font-weight:700;color:var(--accent);text-shadow:0 0 12px var(--accent-glow);word-break:break-all;line-height:1.3}.counter-value.session{color:var(--accent-2);text-shadow:0 0 12px rgba(255,136,0,.4)}.counter-value.rate{color:var(--accent-3);text-shadow:0 0 12px rgba(0,204,119,.4)}.counter-subtitle{font-size:.75rem;color:var(--text-muted);margin-top:.5rem}.impact-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:1rem;margin-top:2rem}.impact-stat{background:var(--surface-2);border:1px solid var(--border);border-radius:.5rem;padding:1rem;text-align:center}.impact-stat .stat-icon{font-size:1.8rem;display:block;margin-bottom:.4rem}.impact-stat .stat-value{font-family:Orbitron,monospace;font-size:1.1rem;font-weight:700;color:var(--accent-2)}.impact-stat .stat-label{font-size:.7rem;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em;margin-top:.2rem}#milestones-section{background:var(--bg)}.milestone-filter-label{display:inline-flex;align-items:center;gap:.5rem;font-size:.85rem;color:var(--text-dim);cursor:pointer;user-select:none;margin-bottom:.5rem}.milestone-filter-label input[type=checkbox]{cursor:pointer;accent-color:var(--accent);width:1rem;height:1rem}.milestones-grid.hide-completed .milestone-card.triggered{display:none}.milestones-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1.25rem;margin-top:1.5rem}.milestone-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.5rem;position:relative;overflow:hidden;transition:transform .2s,box-shadow .3s}.milestone-card:hover{transform:translateY(-2px)}.milestone-card.triggered{border-color:var(--accent);box-shadow:0 0 20px var(--accent-glow),inset 0 0 30px #ff33330a;animation:card-trigger .6s ease-out}.milestone-card.triggered:after{content:"\26a0 THRESHOLD BREACHED";position:absolute;top:.5rem;right:.5rem;font-size:.6rem;color:var(--accent);letter-spacing:.1em;animation:blink 1.5s step-start infinite}@keyframes blink{50%{opacity:0}}@keyframes card-trigger{0%{box-shadow:0 0 0 var(--accent-glow)}50%{box-shadow:0 0 40px var(--accent-glow)}to{box-shadow:0 0 20px var(--accent-glow)}}.milestone-header{display:flex;align-items:center;gap:.75rem;margin-bottom:1rem}.milestone-icon{font-size:2rem;flex-shrink:0}.milestone-name{font-family:Orbitron,monospace;font-size:.9rem;font-weight:700;color:var(--text)}.milestone-threshold{font-size:.7rem;color:var(--text-dim);margin-top:.1rem}.milestone-desc{font-size:.82rem;color:var(--text-dim);margin-bottom:.75rem;line-height:1.5}.milestone-consequence{font-size:.78rem;color:var(--text-muted);line-height:1.4;margin-bottom:.75rem}.milestone-event{font-size:.82rem;color:var(--accent-2);background:var(--surface-2);border-left:3px solid var(--accent-2);padding:.5rem .75rem;border-radius:0 .25rem .25rem 0;line-height:1.4}.milestone-progress-wrap{margin-top:.75rem}.milestone-progress-label{font-size:.68rem;color:var(--text-muted);display:flex;justify-content:space-between;margin-bottom:.3rem}.progress-bar{width:100%;height:6px;background:var(--surface-3);border-radius:3px;overflow:hidden}.progress-fill{height:100%;border-radius:3px;background:linear-gradient(90deg,var(--accent-3),var(--accent-2));transition:width 1s ease}.milestone-card.triggered .progress-fill{background:var(--accent);box-shadow:0 0 6px var(--accent-glow)}.milestone-predict{font-size:.72rem;color:var(--accent-4);margin-top:.5rem;text-align:right}#chart-section{background:var(--bg-alt)}.chart-container{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.5rem;margin-top:1.5rem;position:relative}.chart-wrapper{position:relative;height:380px}.chart-legend{display:flex;flex-wrap:wrap;gap:1rem;margin-top:1rem;font-size:.75rem;color:var(--text-dim)}.legend-item{display:flex;align-items:center;gap:.4rem}.legend-swatch{width:28px;height:3px;border-radius:2px;flex-shrink:0}#predictions-section{background:var(--bg)}.predictions-table-wrap{overflow-x:auto;margin-top:1.5rem}table{width:100%;border-collapse:collapse;font-size:.85rem}thead{background:var(--surface-2)}th{padding:.75rem 1rem;text-align:left;font-family:Orbitron,monospace;font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-dim);border-bottom:1px solid var(--border)}td{padding:.75rem 1rem;border-bottom:1px solid var(--border);vertical-align:middle}tr:last-child td{border-bottom:none}tr:hover td{background:var(--surface-2)}.passed-badge{display:inline-block;background:var(--accent);color:#fff;font-size:.65rem;padding:.15rem .5rem;border-radius:2rem;letter-spacing:.05em;font-weight:700;animation:blink 2s step-start infinite}.future-date{color:var(--accent-4)}#scoring-section{background:var(--bg-alt)}.scoring-toggle-btn{background:var(--surface-2);border:1px solid var(--border);border-radius:.5rem;padding:.6rem 1.2rem;font-family:inherit;font-size:.85rem;color:var(--text);cursor:pointer;margin-bottom:1.5rem;transition:background .2s}.scoring-toggle-btn:hover{background:var(--surface-3)}#scoring-content{display:none}#scoring-content.open{display:block}.score-summary{display:flex;gap:2rem;flex-wrap:wrap;margin-bottom:2rem}.score-badge{text-align:center;background:var(--surface);border:2px solid var(--border);border-radius:.75rem;padding:1.5rem 2rem;min-width:150px}.score-badge.final{border-color:var(--accent-3)}.score-badge .badge-score{font-family:Orbitron,monospace;font-size:2.5rem;font-weight:900;color:var(--accent-2)}.score-badge.final .badge-score{color:var(--accent-3)}.score-badge .badge-label{font-size:.72rem;color:var(--text-dim);margin-top:.3rem;text-transform:uppercase;letter-spacing:.08em}.scoring-categories{display:flex;flex-direction:column;gap:1rem}.scoring-cat{background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:1rem 1.25rem}.scoring-cat-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.4rem}.scoring-cat-name{font-weight:700;font-size:.9rem}.scoring-cat-score{font-family:Orbitron,monospace;color:var(--accent-2);font-size:.85rem}.scoring-cat-notes{font-size:.78rem;color:var(--text-dim);margin-bottom:.5rem}.rec-list{list-style:none}.rec-item{display:flex;align-items:center;gap:.5rem;font-size:.78rem;color:var(--text-muted);padding:.2rem 0}.rec-item.done{color:var(--accent-3)}.rec-impact{font-family:Orbitron,monospace;font-size:.7rem;font-weight:700;background:var(--surface-2);border-radius:.25rem;padding:.1rem .35rem;white-space:nowrap;color:var(--accent-3)}.rec-item:not(.done) .rec-impact{color:var(--text-muted)}#life-blocks-section{background:var(--bg)}.lb-desc{font-size:.85rem;color:var(--text-dim);margin-bottom:1.25rem;line-height:1.6}.lb-controls{display:flex;align-items:center;flex-wrap:wrap;gap:.75rem;margin-bottom:1rem;min-height:2rem}.lb-breadcrumb{display:flex;align-items:center;flex-wrap:wrap;gap:.25rem;font-size:.78rem;color:var(--text-dim)}.lb-breadcrumb-item{background:var(--surface-2);border:1px solid var(--border);border-radius:.3rem;padding:.2rem .55rem;cursor:pointer;transition:background .15s,color .15s;color:var(--accent-4)}.lb-breadcrumb-item:hover{background:var(--surface-3);color:var(--text)}.lb-breadcrumb-item.lb-bc-current{color:var(--text-muted);cursor:default;background:transparent;border-color:transparent}.lb-breadcrumb-sep{color:var(--text-muted);font-size:.7rem;user-select:none}.lb-info{font-family:Orbitron,monospace;font-size:.75rem;color:var(--accent);letter-spacing:.06em}.lb-container{width:100%;overflow-x:auto;padding-bottom:.5rem}.lb-grid{display:grid;grid-template-columns:repeat(var(--lb-cols, 52),var(--lb-block-size, 11px));gap:var(--lb-gap, 2px);width:max-content;animation:lb-grid-in .25s ease-out}@keyframes lb-grid-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}.lb-block{width:var(--lb-block-size, 11px);height:var(--lb-block-size, 11px);border-radius:2px;cursor:pointer;position:relative;overflow:visible;transition:transform .1s,box-shadow .15s;outline:none}.lb-block:focus-visible{box-shadow:0 0 0 2px var(--accent-4)}.lb-block.lb-future{background:#0f2a0f;border:1px solid #1a3a1a}.lb-block.lb-future:hover{background:#1e4a1e;transform:scale(1.5);box-shadow:0 0 8px #00c85073;z-index:10}.lb-block.lb-dead{background:#0a0a0a;border:1px solid #111;opacity:.35;cursor:default}.lb-block.lb-dying{background:#1a0800;border:1px solid var(--accent-2);animation:lb-pulse-dying 1.4s ease-in-out infinite;overflow:hidden;cursor:pointer;z-index:5}.lb-block.lb-dying:after{content:"";position:absolute;bottom:0;left:0;right:0;height:var(--progress, 0%);background:linear-gradient(to top,var(--accent) 0%,var(--accent-2) 70%,#ffff44 100%);pointer-events:none;transition:height .1s linear}@keyframes lb-pulse-dying{0%,to{border-color:var(--accent-2);box-shadow:0 0 4px var(--accent-glow)}50%{border-color:var(--accent);box-shadow:0 0 12px var(--accent-glow)}}.lb-block.lb-exploding{animation:lb-explode .55s ease-out forwards!important;z-index:20;pointer-events:none}@keyframes lb-explode{0%{transform:scale(1);background:var(--accent-2);box-shadow:0 0 #ffc80000;opacity:1}15%{transform:scale(2.2);background:#ff5;box-shadow:0 0 18px #ffdc00e6;opacity:1}35%{transform:scale(1.6) rotate(12deg);background:var(--accent);box-shadow:0 0 24px var(--accent-glow);opacity:.9}60%{transform:scale(.9) rotate(-18deg);background:#600;box-shadow:0 0 8px #64000080;opacity:.6}80%{transform:scale(.5) rotate(30deg);background:#200;opacity:.3}to{transform:scale(0) rotate(60deg);background:transparent;opacity:0}}.lb-grid.lb-zoom{--lb-cols: 12;--lb-block-size: 38px;--lb-gap: 4px}.lb-zoom .lb-block{border-radius:4px;display:flex;align-items:flex-end;justify-content:center;padding-bottom:3px}.lb-zoom .lb-block.lb-dying:after{border-radius:4px 4px 0 0}.lb-zoom .lb-label{font-family:Share Tech Mono,monospace;font-size:.6rem;color:#ffffff8c;line-height:1;position:relative;z-index:1;pointer-events:none;user-select:none}.lb-zoom .lb-dead .lb-label{color:#ffffff26}.lb-zoom .lb-dying .lb-label{color:#fffc}.lb-zoom .lb-future:hover{transform:scale(1.15)}@media(max-width:600px){.lb-grid{--lb-block-size: 8px;--lb-gap: 1px}.lb-grid.lb-zoom{--lb-cols: 10;--lb-block-size: 28px;--lb-gap: 3px}}.lb-stack-panel{display:flex;flex-direction:column;gap:.45rem;margin-bottom:1.5rem;background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:.9rem 1.1rem}.lb-stack-row{display:flex;align-items:flex-start;gap:.5rem}.lb-stack-label{font-family:Orbitron,monospace;font-size:.58rem;color:var(--text-muted);letter-spacing:.07em;width:3.6rem;flex-shrink:0;padding-top:1px;text-transform:uppercase}.lb-stack-grid{display:flex;flex-wrap:wrap;gap:2px;align-content:flex-start}.lb-stack-grid .lb-block{--lb-block-size: 9px;width:var(--lb-block-size);height:var(--lb-block-size);cursor:default}.lb-stack-grid .lb-block.lb-future,.lb-stack-grid .lb-block.lb-dying{cursor:pointer}.lb-stack-grid .lb-block.lb-overflow{cursor:default;font-size:.5rem;color:var(--text-dim)}.lb-stack-grid .lb-block.lb-future:hover{transform:scale(1.6);box-shadow:0 0 6px #00c85066;z-index:10}@media(max-width:600px){.lb-stack-grid .lb-block{--lb-block-size: 8px}.lb-stack-label{width:3rem;font-size:.53rem}}#tips-section{background:var(--bg-alt)}.tips-intro{color:var(--text-dim);font-size:.9rem;margin-bottom:1.5rem;line-height:1.7;max-width:680px}.tips-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1.2rem;margin-bottom:2rem}.tip-card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1.2rem;display:flex;flex-direction:column;gap:.7rem;transition:border-color .2s,box-shadow .2s}.tip-card:hover{border-color:var(--accent-3);box-shadow:0 0 12px #00cc7726}.tip-header{display:flex;align-items:center;gap:.7rem}.tip-icon{font-size:1.6rem;flex-shrink:0}.tip-title{font-size:1rem;font-weight:700;color:var(--accent-3);line-height:1.3}.tip-text{font-size:.85rem;color:var(--text);line-height:1.6}.tip-detail{font-size:.78rem;color:var(--text-dim);line-height:1.6}.tip-impact{font-size:.78rem;color:var(--text-dim);background:var(--surface-2);border-radius:4px;padding:.5rem .75rem;line-height:1.7}.tip-impact strong{color:var(--accent-3)}.tip-ref{font-size:.75rem;color:var(--accent-4);text-decoration:none;margin-top:auto}.tip-ref:hover{text-decoration:underline}.milestone-ref{display:inline-block;font-size:.75rem;color:var(--accent-4);text-decoration:none;margin-top:.4rem}.milestone-ref:hover{text-decoration:underline}footer{text-align:center;padding:2rem 1rem;font-size:.8rem;color:var(--text-muted);background:var(--bg-alt);border-top:1px solid var(--border)}footer strong{color:var(--accent-2)}footer a{color:var(--accent-2);text-decoration:none}footer a:hover{text-decoration:underline}.footer-disclaimer{margin-top:.5rem;font-size:.7rem;max-width:640px;margin-left:auto;margin-right:auto;line-height:1.5;color:var(--text-muted)}.footer-meta-irony{margin-top:.75rem;font-style:italic;opacity:.75}.footer-meta-irony strong{color:var(--accent);font-style:normal}.footer-share-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.5rem;margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--border)}.footer-share-label{font-size:.75rem;font-weight:700;color:var(--text-dim);letter-spacing:.05em;text-transform:uppercase;margin-right:.25rem}.footer-share-btn{background:var(--surface-2);border:1px solid var(--border);border-radius:2rem;padding:.35rem .8rem;font-family:inherit;font-size:.75rem;color:var(--text-dim);cursor:pointer;transition:background .15s,color .15s,border-color .15s}.footer-share-btn:hover{background:var(--surface-3);color:var(--text);border-color:var(--accent)}.section-label{font-size:.7rem;letter-spacing:.15em;text-transform:uppercase;color:var(--accent);margin-bottom:.35rem}.glow-text{text-shadow:0 0 10px var(--accent-glow)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}@media(max-width:600px){.milestones-grid{grid-template-columns:1fr}.score-summary{flex-direction:column}th,td{padding:.5rem .6rem}}.equiv-wrap{margin-top:1.5rem;background:var(--surface-2);border:1px solid var(--border);border-radius:.75rem;padding:1rem 1.25rem}.equiv-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;margin-bottom:.75rem}.equiv-label{font-size:.75rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-dim)}.snarky-toggle{background:var(--surface-3);border:1px solid var(--border);border-radius:2rem;padding:.3rem .8rem;font-family:inherit;font-size:.78rem;color:var(--text);cursor:pointer;transition:background .2s,border-color .2s}.snarky-toggle:hover{background:var(--surface-2);border-color:var(--accent-2)}.snarky-toggle[aria-pressed=true]{border-color:var(--accent-2);color:var(--accent-2)}.equiv-display{font-size:.95rem;color:var(--text);display:flex;align-items:center;gap:.6rem;min-height:1.8rem;transition:opacity .4s}.equiv-icon{font-size:1.4rem;flex-shrink:0}.equiv-text{font-style:italic;color:var(--accent-3)}.receipt-trigger-wrap{margin-top:1.25rem;text-align:center}.receipt-trigger-btn{background:transparent;border:1px dashed var(--border);border-radius:2rem;padding:.5rem 1.25rem;font-family:inherit;font-size:.82rem;color:var(--text-dim);cursor:pointer;transition:border-color .2s,color .2s}.receipt-trigger-btn:hover{border-color:var(--accent-4);color:var(--accent-4)}#ticker-section{background:var(--bg-alt)}.ai-ticker-wrap{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.25rem 1.5rem;margin-top:1rem}.ai-ticker-header{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}.ai-ticker-text{font-family:Orbitron,monospace;font-size:clamp(.85rem,2vw,1.1rem);color:var(--accent-2);text-shadow:0 0 8px rgba(255,136,0,.3);flex:1;cursor:pointer;transition:color .2s;min-height:1.5em}.ai-ticker-text:hover{color:var(--accent)}.ai-ticker-toggle-btn{background:var(--surface-2);border:1px solid var(--border);border-radius:2rem;padding:.3rem .8rem;font-family:inherit;font-size:.78rem;color:var(--text-dim);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background .2s}.ai-ticker-toggle-btn:hover{background:var(--surface-3)}.ai-ticker-expanded{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--border)}.ai-ticker-math{font-family:Share Tech Mono,monospace;font-size:.8rem;color:var(--text-dim);white-space:pre-wrap;word-break:break-word;background:var(--surface-2);border-radius:.4rem;padding:.75rem 1rem;margin-bottom:.75rem;line-height:1.6}.ai-ticker-actions{display:flex;gap:.75rem;flex-wrap:wrap}.btn-sm{background:var(--surface-2);border:1px solid var(--border);border-radius:.35rem;padding:.35rem .9rem;font-family:inherit;font-size:.78rem;color:var(--text);cursor:pointer;transition:background .2s,box-shadow .2s}.btn-sm:hover{background:var(--surface-3);box-shadow:0 0 6px var(--accent-glow)}#calculator-section{background:var(--bg)}.calc-content{margin-top:1rem}.calc-inputs{display:flex;flex-direction:column;gap:1.25rem;margin-bottom:1.5rem}.calc-field{display:flex;flex-direction:column;gap:.5rem}.calc-label{font-size:.85rem;color:var(--text-dim)}.calc-label strong{color:var(--accent-2);font-family:Orbitron,monospace}.calc-range{-webkit-appearance:none;appearance:none;width:100%;height:6px;background:var(--surface-3);border-radius:3px;outline:none;cursor:pointer}.calc-range::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--accent-2);box-shadow:0 0 6px #f806;cursor:pointer}.calc-range::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:var(--accent-2);border:none;cursor:pointer}.calc-select{background:var(--surface-2);border:1px solid var(--border);border-radius:.4rem;padding:.5rem .75rem;font-family:inherit;font-size:.85rem;color:var(--text);cursor:pointer;max-width:420px}.calc-select:focus{outline:2px solid var(--accent-4)}.calc-results{background:var(--surface-2);border:1px solid var(--border);border-radius:.75rem;padding:1.25rem;margin-bottom:1.25rem}.calc-result-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.75rem}.calc-result-box{background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:.75rem 1rem;text-align:center}.calc-result-box.global{grid-column:1 / -1;border-color:var(--accent);background:var(--bg-alt)}.crb-label{font-size:.68rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.08em;margin-bottom:.3rem}.crb-value{font-family:Orbitron,monospace;font-size:1rem;font-weight:700;color:var(--accent-2)}.calc-result-box.global .crb-value{color:var(--accent)}.crb-sub{font-size:.7rem;color:var(--text-dim);margin-top:.2rem}.calc-actions{display:flex;gap:.75rem;flex-wrap:wrap}.btn-primary{background:var(--accent);border:none;border-radius:.4rem;padding:.55rem 1.25rem;font-family:inherit;font-size:.85rem;color:#fff;cursor:pointer;font-weight:700;transition:background .2s,box-shadow .2s}.btn-primary:hover{background:#c00;box-shadow:0 0 12px var(--accent-glow)}.btn-secondary{background:var(--surface-2);border:1px solid var(--border);border-radius:.4rem;padding:.55rem 1.25rem;font-family:inherit;font-size:.85rem;color:var(--text);cursor:pointer;transition:background .2s}.btn-secondary:hover{background:var(--surface-3)}.btn-ghost{background:transparent;border:1px solid var(--border);border-radius:.4rem;padding:.55rem 1.25rem;font-family:inherit;font-size:.85rem;color:var(--text-dim);cursor:pointer;transition:border-color .2s,color .2s}.btn-ghost:hover{border-color:var(--text-dim);color:var(--text)}#achievements-section{background:var(--bg-alt)}.badges-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:.75rem;margin-top:1.25rem}.badge-item{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1rem .75rem;text-align:center;transition:transform .15s,box-shadow .2s}.badge-item.earned{border-color:var(--accent-2);box-shadow:0 0 12px #f803}.badge-item.locked{opacity:.45;filter:grayscale(1)}.badge-item.earned:hover{transform:translateY(-2px);box-shadow:0 0 18px #ff880059}.badge-icon{display:block;font-size:2rem;margin-bottom:.4rem}.badge-name{font-family:Orbitron,monospace;font-size:.65rem;color:var(--text-dim);letter-spacing:.05em;word-break:break-word}.badge-item.earned .badge-name{color:var(--accent-2)}.share-doom-panel{position:fixed;bottom:1.5rem;right:1.5rem;z-index:900;display:flex;flex-direction:column;align-items:flex-end;gap:.5rem}.share-doom-btn{background:var(--accent);border:none;border-radius:2rem;padding:.65rem 1.4rem;font-family:inherit;font-size:.9rem;color:#fff;font-weight:700;cursor:pointer;box-shadow:0 4px 20px #ff333380;transition:background .2s,box-shadow .2s,transform .15s}.share-doom-btn:hover{background:#c00;box-shadow:0 6px 28px #ff3333b3;transform:scale(1.04)}.share-doom-options{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:.6rem;display:flex;flex-direction:column;gap:.4rem;box-shadow:0 8px 32px var(--shadow);min-width:160px;animation:pop-in .15s ease-out}@keyframes pop-in{0%{opacity:0;transform:scale(.92) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}.share-opt-btn{background:var(--surface-2);border:1px solid var(--border);border-radius:.4rem;padding:.5rem .9rem;font-family:inherit;font-size:.82rem;color:var(--text);cursor:pointer;text-align:left;transition:background .15s}.share-opt-btn:hover{background:var(--surface-3)}.share-opt-close{align-self:flex-end;background:transparent;border:none;color:var(--text-muted);font-size:.9rem;cursor:pointer;padding:.2rem .4rem}.share-opt-close:hover{color:var(--text)}.modal-overlay{position:fixed;inset:0;z-index:2000;background:#000c;display:flex;align-items:center;justify-content:center;padding:1rem;animation:fade-in .2s ease-out}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.receipt-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1.5rem;max-width:480px;width:100%;max-height:85vh;overflow-y:auto;box-shadow:0 16px 64px #000000b3;animation:slide-up .2s ease-out}@keyframes slide-up{0%{transform:translateY(12px);opacity:0}to{transform:translateY(0);opacity:1}}:root[data-theme=dark] .receipt-body{color:#0f8;text-shadow:0 0 6px rgba(0,255,136,.3)}:root[data-theme=light] .receipt-body{color:#1a3a1a}.receipt-body{font-family:Share Tech Mono,Courier New,monospace;font-size:.78rem;line-height:1.55;white-space:pre;overflow-x:auto;background:transparent;margin-bottom:1.25rem;padding:0;border:none}.receipt-actions{display:flex;gap:.75rem;flex-wrap:wrap}.toast{position:fixed;bottom:5.5rem;right:1.5rem;z-index:1500;background:var(--surface);border:1px solid var(--accent-2);border-radius:.75rem;padding:.85rem 1rem;box-shadow:0 8px 32px var(--shadow);display:flex;align-items:center;gap:.75rem;max-width:320px;transform:translateY(0);transition:transform .3s ease,opacity .3s ease}.toast-in{animation:toast-enter .3s ease-out}.toast-out{animation:toast-leave .3s ease-in forwards}@keyframes toast-enter{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes toast-leave{0%{transform:translateY(0);opacity:1}to{transform:translateY(20px);opacity:0}}.toast-icon{font-size:1.8rem;flex-shrink:0}.toast-content{flex:1;min-width:0}.toast-title{font-family:Orbitron,monospace;font-size:.78rem;font-weight:700;color:var(--accent-2);margin-bottom:.2rem}.toast-desc{font-size:.72rem;color:var(--text-dim);line-height:1.4}.toast-close{background:transparent;border:none;color:var(--text-muted);font-size:.9rem;cursor:pointer;flex-shrink:0;padding:.2rem;line-height:1}.toast-close:hover{color:var(--text)}@media(max-width:600px){.share-doom-panel{bottom:1rem;right:1rem}.toast{bottom:5rem;right:1rem;max-width:calc(100vw - 2rem)}.receipt-card{padding:1rem}.badges-grid{grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.calc-result-grid{grid-template-columns:1fr 1fr}}@media(prefers-reduced-motion:reduce){.toast,.toast-in,.toast-out,.modal-overlay,.receipt-card,.share-doom-options,.ai-ticker-text{transition:none;animation:none}}#accelerator-section{background:var(--bg-alt)}.accel-stats-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.75rem;margin:1.25rem 0}.accel-stat{background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:.85rem 1rem;text-align:center}.accel-stat-dp{border-color:var(--accent-2)}.accel-stat-value{font-family:Orbitron,monospace;font-size:clamp(.9rem,2.5vw,1.15rem);font-weight:700;color:var(--accent-3);line-height:1.2}.accel-stat-dp .accel-stat-value{color:var(--accent-2)}.accel-stat-label{font-size:.65rem;color:var(--text-dim);text-transform:uppercase;letter-spacing:.08em;margin-top:.25rem}.brb-wrap{display:flex;flex-direction:column;align-items:center;gap:.75rem;margin:1.5rem 0}.combo-display{font-family:Orbitron,monospace;font-size:clamp(1.4rem,5vw,2.2rem);font-weight:900;color:var(--accent-2);text-shadow:0 0 14px rgba(255,136,0,.5);letter-spacing:.05em;min-height:2.5rem;transition:color .1s,text-shadow .1s}.combo-display.combo-max{color:var(--accent);text-shadow:0 0 20px var(--accent-glow);animation:combo-max-pulse .4s ease-in-out infinite alternate}@keyframes combo-max-pulse{0%{text-shadow:0 0 14px var(--accent-glow)}to{text-shadow:0 0 32px var(--accent-glow)}}.big-red-button{width:clamp(96px,28vw,168px);height:clamp(96px,28vw,168px);border-radius:50%;border:3px solid var(--accent);background:radial-gradient(circle at 40% 35%,#3a0000,#1a0000);color:#fff;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.3rem;box-shadow:0 0 24px var(--accent-glow),inset 0 0 20px #ff333314;transition:box-shadow .15s,transform .1s;position:relative;overflow:hidden;touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none}.big-red-button:before{content:"";position:absolute;inset:0;border-radius:50%;background:radial-gradient(circle at 40% 35%,rgba(255,80,80,.15),transparent 60%);pointer-events:none}.big-red-button:hover{box-shadow:0 0 40px var(--accent-glow),inset 0 0 28px #ff333324;transform:scale(1.04)}.big-red-button:active,.big-red-button.tapping{transform:scale(.94);box-shadow:0 0 56px var(--accent-glow),inset 0 0 40px #ff333340}.big-red-button.combo-max{border-color:var(--accent);box-shadow:0 0 48px var(--accent-glow),0 0 80px #f333,inset 0 0 32px #ff33332e;animation:brb-max-glow .6s ease-in-out infinite alternate}@keyframes brb-max-glow{0%{box-shadow:0 0 40px var(--accent-glow),inset 0 0 28px #ff333324}to{box-shadow:0 0 72px var(--accent-glow),0 0 100px #ff333340,inset 0 0 40px #ff333338}}.brb-icon{font-size:clamp(1.8rem,6vw,2.8rem);line-height:1;pointer-events:none}.brb-label{font-family:Orbitron,monospace;font-size:clamp(.48rem,1.5vw,.65rem);font-weight:700;letter-spacing:.06em;color:#ffffffbf;pointer-events:none;text-align:center;padding:0 .4rem;line-height:1.2}.brb-rate{font-size:.72rem;color:var(--text-muted);min-height:1rem;letter-spacing:.06em}.milestone-race-wrap{background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:.85rem 1.1rem;margin-bottom:1.5rem}.milestone-race-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.5rem;flex-wrap:wrap;gap:.25rem}.milestone-race-label{font-size:.78rem;color:var(--text-dim)}.milestone-race-label strong{color:var(--accent-2);font-family:Orbitron,monospace;font-size:.72rem}.milestone-race-pct{font-family:Orbitron,monospace;font-size:.7rem;color:var(--accent-3);font-weight:700}.milestone-race-fill{background:linear-gradient(90deg,var(--accent-3),var(--accent-2));transition:width .3s ease}.milestone-race-wrap.milestone-triggered{animation:race-milestone-flash .6s ease-out}@keyframes race-milestone-flash{0%,to{border-color:var(--border)}25%,75%{border-color:var(--accent);box-shadow:0 0 16px var(--accent-glow)}}.accel-section-title{font-family:Orbitron,monospace;font-size:.78rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--text-dim);margin:1.25rem 0 .75rem}.challenge-row{display:flex;gap:.75rem;overflow-x:auto;padding-bottom:.5rem;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;margin-bottom:.5rem}.challenge-row::-webkit-scrollbar{height:4px}.challenge-row::-webkit-scrollbar-track{background:var(--surface-2);border-radius:2px}.challenge-row::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}.challenge-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1rem;min-width:180px;max-width:220px;flex-shrink:0;scroll-snap-align:start;position:relative;transition:border-color .2s,box-shadow .2s}.challenge-card.completed{border-color:var(--accent-3);box-shadow:0 0 10px #0c73}.challenge-card-icon{font-size:1.5rem;margin-bottom:.4rem;display:block}.challenge-card-label{font-family:Orbitron,monospace;font-size:.7rem;font-weight:700;color:var(--text);margin-bottom:.3rem;letter-spacing:.04em}.challenge-card-desc{font-size:.68rem;color:var(--text-dim);line-height:1.45;margin-bottom:.5rem}.challenge-card-reward{font-size:.65rem;color:var(--accent-2);font-family:Orbitron,monospace;font-weight:700}.challenge-card-progress{margin-top:.5rem}.challenge-card-pct{font-size:.6rem;color:var(--text-muted);text-align:right;margin-bottom:.2rem}.challenge-progress-fill{background:linear-gradient(90deg,var(--accent-4),var(--accent-3));transition:width .3s ease}.challenge-card.completed .challenge-progress-fill{background:var(--accent-3)}.challenge-checkmark{position:absolute;top:.5rem;right:.6rem;font-size:1rem}.upgrade-shop{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:.75rem;margin-bottom:1.25rem}.upgrade-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1rem;text-align:center;cursor:pointer;transition:border-color .2s,box-shadow .2s,transform .15s,opacity .2s;position:relative}.upgrade-card:hover:not(:disabled):not(.unaffordable){border-color:var(--accent-2);box-shadow:0 0 12px #f803;transform:translateY(-2px)}.upgrade-card.unaffordable{opacity:.4;pointer-events:none}.upgrade-card.owned{border-color:var(--accent-3);background:var(--bg-alt);cursor:default}.upgrade-card-icon{font-size:1.8rem;display:block;margin-bottom:.4rem}.upgrade-card-name{font-family:Orbitron,monospace;font-size:.68rem;font-weight:700;color:var(--text);margin-bottom:.3rem;letter-spacing:.04em}.upgrade-card.owned .upgrade-card-name{color:var(--accent-3)}.upgrade-card-flavour{font-size:.65rem;color:var(--text-dim);font-style:italic;line-height:1.4;margin-bottom:.5rem}.upgrade-card-cost{font-family:Orbitron,monospace;font-size:.72rem;font-weight:700;color:var(--accent-2)}.upgrade-card.owned .upgrade-card-cost{color:var(--accent-3)}.upgrade-card-mult{font-size:.65rem;color:var(--text-muted);margin-top:.15rem}.accel-footer-row{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.75rem;margin-top:1rem;padding-top:1rem;border-top:1px solid var(--border)}.best-score-row{font-size:.78rem;color:var(--text-dim)}.best-score-row .new-record{color:var(--accent-2);animation:new-record-flash .5s ease-out 3}@keyframes new-record-flash{0%,to{opacity:1}50%{opacity:.3}}.milestone-card.player-triggered{animation:player-trigger-flash .6s ease-out}@keyframes player-trigger-flash{0%,to{box-shadow:0 0 20px var(--accent-glow)}25%,75%{box-shadow:0 0 50px var(--accent-glow),0 0 80px #ff33334d}}.company-stage-banner{display:flex;align-items:center;gap:.75rem;background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:.85rem 1.1rem;margin-bottom:1rem;flex-wrap:wrap}.company-stage-icon{font-size:2rem;line-height:1}.company-stage-label{font-size:.6rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.1em}.company-stage-name{font-family:Orbitron,monospace;font-size:clamp(.8rem,2.5vw,1rem);font-weight:700;color:var(--accent-3);letter-spacing:.04em}.passive-rate-wrap{margin-left:auto;text-align:right}.passive-rate-label{font-size:.6rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.08em}.passive-rate-value{font-family:Orbitron,monospace;font-size:.82rem;font-weight:700;color:var(--accent-2)}.workforce-panel{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:.75rem;margin-bottom:1.25rem}.worker-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1rem;text-align:center;cursor:pointer;transition:border-color .2s,box-shadow .2s,transform .15s,opacity .2s;position:relative}.worker-card:hover:not(.fired):not(.unaffordable){border-color:var(--accent);box-shadow:0 0 12px var(--accent-glow);transform:translateY(-2px)}.worker-card.unaffordable{opacity:.4;pointer-events:none}.worker-card.fired{border-color:var(--accent-3);background:var(--bg-alt);cursor:default;opacity:.7}.worker-card-icon{font-size:1.8rem;display:block;margin-bottom:.4rem}.worker-card-name{font-family:Orbitron,monospace;font-size:.65rem;font-weight:700;color:var(--text);margin-bottom:.3rem;letter-spacing:.04em}.worker-card.fired .worker-card-name{color:var(--accent-3)}.worker-card-flavour{font-size:.62rem;color:var(--text-dim);font-style:italic;line-height:1.4;margin-bottom:.5rem}.worker-card-tps{font-size:.65rem;color:var(--accent-3);font-family:Orbitron,monospace;font-weight:700;margin-bottom:.2rem}.worker-card-cost{font-family:Orbitron,monospace;font-size:.72rem;font-weight:700;color:var(--accent)}.worker-card.fired .worker-card-cost{color:var(--accent-3)}.agent-shop{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:.75rem;margin-bottom:1.25rem}.agent-card{background:var(--surface);border:1px solid var(--border);border-radius:.75rem;padding:1rem;text-align:center;cursor:pointer;transition:border-color .2s,box-shadow .2s,transform .15s,opacity .2s;position:relative}.agent-card:hover:not(.unaffordable){border-color:var(--accent-2);box-shadow:0 0 12px #f803;transform:translateY(-2px)}.agent-card.unaffordable{opacity:.4;pointer-events:none}.agent-card-icon{font-size:1.8rem;display:block;margin-bottom:.4rem}.agent-card-name{font-family:Orbitron,monospace;font-size:.65rem;font-weight:700;color:var(--text);margin-bottom:.3rem;letter-spacing:.04em}.agent-card-flavour{font-size:.62rem;color:var(--text-dim);font-style:italic;line-height:1.4;margin-bottom:.5rem}.agent-card-tps{font-size:.65rem;color:var(--accent-3);font-family:Orbitron,monospace;font-weight:700;margin-bottom:.2rem}.agent-card-cost{font-family:Orbitron,monospace;font-size:.72rem;font-weight:700;color:var(--accent-2)}.agent-card-owned{font-size:.65rem;color:var(--accent-3);font-family:Orbitron,monospace;font-weight:700;margin-top:.25rem}@media(max-width:480px){.upgrade-shop,.accel-stats-strip,.workforce-panel,.agent-shop{grid-template-columns:1fr 1fr}}@media(prefers-reduced-motion:reduce){.big-red-button,.big-red-button:hover,.big-red-button:active,.big-red-button.tapping,.big-red-button.combo-max,.combo-display.combo-max,.milestone-race-fill,.challenge-progress-fill,.upgrade-card,.worker-card,.agent-card{transition:none;animation:none}}.presence-strip{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:.6rem 1rem;margin-top:1.25rem;font-size:.82rem;color:var(--text-dim)}.presence-dot{width:8px;height:8px;border-radius:50%;background:var(--accent-3);flex-shrink:0;animation:presence-pulse 2s ease-in-out infinite}@keyframes presence-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.75)}}.presence-count{font-family:Orbitron,monospace;font-size:.88rem;font-weight:700;color:var(--accent-3)}.presence-label{color:var(--text-dim)}.presence-reaction{font-size:.75rem;color:var(--text-muted);font-style:italic;transition:opacity .5s ease;flex-basis:100%;padding-left:1.1rem}@media(prefers-reduced-motion:reduce){.presence-dot{animation:none}.presence-reaction{transition:none}}#event-log-section{background:var(--bg-alt)}.event-log{background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:.75rem 1rem;max-height:280px;overflow-y:auto;font-family:Share Tech Mono,Courier New,monospace;font-size:.75rem;line-height:1.65;color:var(--text-dim);scroll-behavior:smooth}.event-log:empty:before{content:"Waiting for first entry\2026";display:block;color:var(--text-muted);font-style:italic}.event-log-entry{display:flex;gap:.5rem;align-items:baseline;padding:.18rem 0;border-bottom:1px solid var(--border);animation:log-entry-in .3s ease-out}.event-log-entry:last-child{border-bottom:none}@keyframes log-entry-in{0%{opacity:0;transform:translate(-8px)}to{opacity:1;transform:translate(0)}}.log-time{color:var(--accent-3);flex-shrink:0;min-width:5.5rem}.log-icon{flex-shrink:0;font-size:.9rem}.log-text{color:var(--text);flex:1;min-width:0}.event-log-actions{display:flex;gap:.75rem;margin-top:.75rem;flex-wrap:wrap}@media(prefers-reduced-motion:reduce){.event-log-entry{animation:none}.event-log{scroll-behavior:auto}}.milestone-alert-banner{position:fixed;top:0;left:0;right:0;z-index:1800;background:linear-gradient(135deg,#2a0505,#1a0000);border-bottom:2px solid var(--accent);padding:.55rem 1.25rem;display:flex;align-items:center;gap:.75rem;justify-content:center;flex-wrap:wrap;font-size:.88rem;color:var(--text);box-shadow:0 2px 24px #f336;animation:alert-slide-down .35s ease-out}:root[data-theme=light] .milestone-alert-banner{background:linear-gradient(135deg,#5a0000,#3a0000)}@keyframes alert-slide-down{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.milestone-alert-icon{font-size:1.4rem;line-height:1}.milestone-alert-msg{font-size:.85rem;color:#fcc;flex:1;min-width:0;text-align:center}.milestone-alert-countdown{font-family:Orbitron,monospace;font-size:1.1rem;font-weight:900;color:var(--accent);min-width:3.5rem;text-align:right;animation:countdown-tick 1s ease-in-out infinite alternate}@keyframes countdown-tick{0%{text-shadow:0 0 8px var(--accent-glow)}to{text-shadow:0 0 22px var(--accent-glow)}}@media(prefers-reduced-motion:reduce){.milestone-alert-banner,.milestone-alert-countdown{animation:none}}.milestone-flash-overlay{position:fixed;inset:0;z-index:3000;background:#ff14141a;display:flex;align-items:center;justify-content:center;padding:1rem;animation:milestone-bg-flash 1.4s ease-out forwards}@keyframes milestone-bg-flash{0%{background:#ff333352}35%{background:#ff33332e}to{background:#ff333314}}.milestone-flash-content{background:var(--surface);border:2px solid var(--accent);border-radius:1rem;padding:2rem 2.5rem;text-align:center;max-width:480px;width:100%;box-shadow:0 0 60px var(--accent-glow),0 20px 60px #000000a6;animation:flash-card-in .3s ease-out}@keyframes flash-card-in{0%{transform:scale(.82);opacity:0}to{transform:scale(1);opacity:1}}.milestone-flash-icon{font-size:4rem;line-height:1;margin-bottom:.6rem}.milestone-flash-name{font-family:Orbitron,monospace;font-size:clamp(1rem,3vw,1.55rem);font-weight:900;color:var(--accent);letter-spacing:.04em;margin-bottom:.6rem}.milestone-flash-desc{font-size:.84rem;color:var(--text-dim);line-height:1.55;margin-bottom:1.25rem}.milestone-flash-close{background:var(--accent);border:none;border-radius:.4rem;padding:.55rem 1.5rem;font-family:inherit;font-size:.85rem;color:#fff;cursor:pointer;font-weight:700;transition:background .2s}.milestone-flash-close:hover{background:#c00}@media(max-width:600px){.milestone-flash-content{padding:1.5rem 1.25rem}.milestone-alert-msg{font-size:.78rem}}@media(prefers-reduced-motion:reduce){.milestone-flash-overlay{animation:none;background:#ff33331a}.milestone-flash-content{animation:none}}.doomsday-strip{background:#0d0000;border-bottom:2px solid var(--accent);display:flex;align-items:center;gap:1.25rem;padding:.65rem 1.5rem;flex-wrap:wrap;position:sticky;top:0;z-index:850;box-shadow:0 2px 20px #ff333340}:root[data-theme=light] .doomsday-strip{background:#1a0000}.doomsday-clock-wrap{flex-shrink:0}.doom-clock-svg{width:56px;height:56px;overflow:visible}.doom-clock-face{fill:#0d0000;stroke:var(--accent);stroke-width:2}.doom-tick{stroke:#ff333380;stroke-width:1.5;stroke-linecap:round}.doom-tick-major{stroke:var(--accent);stroke-width:2.5}.doom-tick-sm{stroke-width:1}.doom-tick-warn{stroke:var(--accent);stroke-width:2}.doom-clock-hand{stroke:var(--accent);stroke-width:3;stroke-linecap:round;filter:drop-shadow(0 0 4px var(--accent));transition:none}.doom-clock-dot{fill:#fff;filter:drop-shadow(0 0 3px var(--accent))}.doomsday-text-wrap{flex:1;min-width:160px}.doomsday-time{font-family:Orbitron,monospace;font-size:clamp(.75rem,2.5vw,1.1rem);font-weight:900;color:var(--accent);text-shadow:0 0 10px var(--accent-glow);letter-spacing:.08em}.doomsday-sub{font-size:.68rem;color:#ffffff73;margin-top:.2rem;letter-spacing:.04em}.doomsday-bar-wrap{flex:1;min-width:120px;max-width:260px}.doomsday-bar-track{height:8px;background:#ff33331f;border-radius:4px;overflow:hidden;border:1px solid rgba(255,51,51,.25)}.doomsday-bar-fill{height:100%;background:linear-gradient(90deg,#330000,var(--accent));border-radius:4px;transition:width 1s linear;box-shadow:0 0 6px var(--accent-glow)}.doomsday-bar-labels{display:flex;justify-content:space-between;font-size:.58rem;color:#ffffff4d;letter-spacing:.08em;margin-top:.2rem;text-transform:uppercase}.emergency-broadcast{position:fixed;top:0;left:0;right:0;z-index:3000;background:#8b0000;border-bottom:3px solid #ff0000;padding:.75rem 1.5rem;animation:eb-slidein .3s ease-out,eb-pulse .6s ease-in-out infinite alternate;box-shadow:0 4px 32px #ff0000b3}@keyframes eb-slidein{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes eb-pulse{0%{background:#8b0000}to{background:#a00}}.eb-inner{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;max-width:1200px;margin:0 auto}.eb-icon{font-size:1.3rem;animation:eb-icon-flash .5s step-start infinite;flex-shrink:0}@keyframes eb-icon-flash{50%{opacity:0}}.eb-label{font-family:Orbitron,monospace;font-size:.7rem;font-weight:900;color:#fff;letter-spacing:.14em;text-transform:uppercase;background:red;padding:.1rem .5rem;border-radius:2px;flex-shrink:0}.eb-msg{font-family:Orbitron,monospace;font-size:.78rem;font-weight:700;color:#fff;flex:1}.eb-sign-off{font-size:.68rem;color:#ffffffb3;font-style:italic;flex-basis:100%;padding-left:2.8rem}.session-tab-strip{background:var(--surface);border:1px solid rgba(255,51,51,.3);border-radius:.75rem;padding:1rem 1.25rem;margin-top:1.5rem;position:relative;overflow:hidden}.session-tab-strip:before{content:"";position:absolute;inset:0;background:linear-gradient(135deg,rgba(255,51,51,.03) 0%,transparent 60%);pointer-events:none}.session-tab-header{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;margin-bottom:.85rem}.session-tab-title{font-family:Orbitron,monospace;font-size:.8rem;font-weight:700;color:var(--accent);letter-spacing:.06em;text-transform:uppercase}.session-tab-sub{font-size:.72rem;color:var(--text-muted);font-style:italic}.session-tab-items{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:.6rem}.session-tab-item{display:flex;align-items:center;gap:.5rem;background:var(--surface-2);border:1px solid var(--border);border-radius:.4rem;padding:.5rem .75rem;font-size:.78rem;color:var(--text-dim)}.sti-icon{font-size:1.1rem;flex-shrink:0}.sti-val{font-family:Orbitron,monospace;font-size:.82rem;font-weight:700;color:var(--accent-2);min-width:3.5rem;text-align:right;flex-shrink:0}.sti-label{font-size:.72rem;color:var(--text-muted);line-height:1.3}#apology-section{background:var(--bg)}.apology-card{background:var(--surface);border:1px solid var(--border);border-left:4px solid var(--accent-2);border-radius:.75rem;padding:1.5rem;margin-top:1rem;position:relative;min-height:6rem}.apology-card:before{content:"\275d";font-size:3rem;color:#ff88001f;position:absolute;top:.5rem;left:.75rem;font-family:Georgia,serif;line-height:1;pointer-events:none}.apology-quote{font-size:.95rem;color:var(--text);line-height:1.7;font-style:italic;padding-left:1.5rem;animation:apology-fade .5s ease-out}@keyframes apology-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.apology-footer{display:flex;justify-content:space-between;align-items:center;margin-top:1rem;padding-top:.75rem;border-top:1px solid var(--border);flex-wrap:wrap;gap:.5rem}.apology-signoff{font-size:.78rem;color:var(--accent-2);font-style:normal}.apology-note{font-size:.68rem;color:var(--text-muted);font-style:italic}.apology-actions{display:flex;gap:.75rem;flex-wrap:wrap;margin-top:1rem}.wanted-poster{background:#1a0f00;border:3px solid #8b5a00;border-radius:.5rem;padding:1.5rem;text-align:center;font-family:Share Tech Mono,Courier New,monospace;position:relative;overflow:hidden;box-shadow:inset 0 0 40px #00000080,0 0 20px #8b5a004d}.wanted-poster:before{content:"";position:absolute;inset:0;background:repeating-linear-gradient(0deg,transparent,transparent 4px,rgba(0,0,0,.04) 4px,rgba(0,0,0,.04) 5px);pointer-events:none}:root[data-theme=light] .wanted-poster{background:#f5e6c8;border-color:#8b5a00;box-shadow:inset 0 0 40px #0000001a}.wanted-title{font-family:Orbitron,monospace;font-size:clamp(2rem,8vw,3.5rem);font-weight:900;color:#c30;letter-spacing:.15em;text-shadow:3px 3px 0 #660000;margin-bottom:.25rem;line-height:1}.wanted-subtitle{font-size:.75rem;color:#c90;letter-spacing:.3em;text-transform:uppercase;margin-bottom:1rem}.wanted-divider{height:3px;background:linear-gradient(90deg,transparent,#8b5a00,transparent);margin:.75rem 0}.wanted-charges{text-align:left;margin:1rem 0}.wanted-charge{font-size:.8rem;color:#d4a843;padding:.4rem 0;border-bottom:1px dashed rgba(139,90,0,.3);line-height:1.5}:root[data-theme=light] .wanted-charge{color:#5a3500}.wanted-charge strong{color:#f60;font-family:Orbitron,monospace;font-size:.72rem}:root[data-theme=light] .wanted-charge strong{color:#c30}.wanted-bail{font-size:.78rem;color:#f90;margin-top:1rem;padding:.6rem 1rem;background:#8b5a0033;border:1px solid rgba(139,90,0,.4);border-radius:.3rem}:root[data-theme=light] .wanted-bail{color:#7a3d00;background:#8b5a001a}.wanted-global{font-size:.68rem;color:#c909;margin-top:.75rem;font-style:italic}:root[data-theme=light] .wanted-global{color:#5a350099}#shame-section{background:var(--bg-alt)}.shame-feed{background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:.5rem;max-height:320px;overflow-y:auto;margin-top:1rem;font-family:Share Tech Mono,monospace;scroll-behavior:smooth}.shame-entry{display:flex;align-items:flex-start;gap:.6rem;padding:.6rem .75rem;border-bottom:1px solid var(--border);animation:shame-slide .4s ease-out;font-size:.8rem}.shame-entry:last-child{border-bottom:none}@keyframes shame-slide{0%{opacity:0;transform:translate(-10px)}to{opacity:1;transform:translate(0)}}.shame-entry.user-submitted{border-left:3px solid var(--accent-2);background:var(--surface-2)}.shame-entry-icon{font-size:1rem;flex-shrink:0;margin-top:.05rem}.shame-entry-content{flex:1;min-width:0}.shame-entry-text{color:var(--text);line-height:1.5;word-break:break-word}.shame-entry-cost{font-size:.65rem;color:var(--accent);margin-top:.2rem;font-family:Orbitron,monospace}.shame-entry-user-tag{font-size:.6rem;color:var(--accent-2);text-transform:uppercase;letter-spacing:.08em;margin-top:.15rem}.shame-submit-wrap{margin-top:1.25rem}.shame-submit-label{display:block;font-size:.82rem;color:var(--text-dim);margin-bottom:.5rem}.shame-input-row{display:flex;gap:.6rem;flex-wrap:wrap}.shame-input{flex:1;min-width:200px;background:var(--surface-2);border:1px solid var(--border);border-radius:.4rem;padding:.55rem .85rem;font-family:inherit;font-size:.85rem;color:var(--text);outline:none;transition:border-color .2s}.shame-input:focus{border-color:var(--accent-2)}.shame-input::placeholder{color:var(--text-muted)}.villain-leaderboard-wrap{margin-top:1.5rem;padding-top:1.5rem;border-top:1px solid var(--border)}.villain-rank-banner{display:flex;align-items:center;justify-content:space-between;background:var(--surface);border:1px solid var(--border);border-radius:.5rem;padding:.75rem 1.1rem;margin-bottom:1rem;flex-wrap:wrap;gap:.5rem}.villain-rank-title{font-family:Orbitron,monospace;font-size:clamp(.75rem,2.5vw,.95rem);font-weight:700;color:var(--accent-2);letter-spacing:.06em}.villain-rank-score{font-family:Orbitron,monospace;font-size:.82rem;color:var(--text-dim)}.villain-table{width:100%;border-collapse:collapse;font-size:.8rem;margin-bottom:.75rem}.villain-table th{font-family:Orbitron,monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);padding:.5rem .75rem;border-bottom:1px solid var(--border);text-align:left;background:var(--surface-2)}.villain-table td{padding:.55rem .75rem;border-bottom:1px solid var(--border);color:var(--text-dim)}.villain-table tr:last-child td{border-bottom:none}.villain-table .villain-row-you{background:#ff33330f}.villain-table .villain-row-you td{color:var(--accent-2);font-weight:700}.villain-table .villain-pos{width:2rem;text-align:center;color:var(--text-muted);font-family:Orbitron,monospace;font-size:.7rem}.villain-table .villain-name{font-weight:700}.villain-table .villain-score{font-family:Orbitron,monospace;font-size:.75rem;color:var(--accent-2)}.villain-table .villain-rank-cell{font-size:.68rem;color:var(--text-muted);font-style:italic}.villain-congratulations{background:var(--accent);color:#fff;font-family:Orbitron,monospace;font-size:.8rem;font-weight:700;letter-spacing:.05em;padding:.75rem 1rem;border-radius:.4rem;text-align:center;animation:villain-congrats-flash .4s ease-out}@keyframes villain-congrats-flash{0%{transform:scale(1);box-shadow:0 0 #f330}40%{transform:scale(1.03);box-shadow:0 0 24px #f339}to{transform:scale(1);box-shadow:0 0 8px #ff33334d}}.intervention-overlay{position:fixed;inset:0;z-index:3500;background:#000000b3;display:flex;align-items:center;justify-content:center;padding:1rem;animation:fade-in .25s ease-out}.intervention-card{background:var(--surface);border:1px solid var(--border);border-radius:1rem;padding:1.5rem;max-width:420px;width:100%;box-shadow:0 20px 64px var(--shadow);animation:slide-up .25s ease-out}.intervention-header{display:flex;align-items:center;gap:.6rem;margin-bottom:.85rem}.intervention-avatar{font-size:1.6rem}.intervention-sender{font-family:Orbitron,monospace;font-size:.78rem;font-weight:700;color:var(--accent-3)}.intervention-time{font-size:.65rem;color:var(--text-muted);margin-left:auto}.intervention-bubble{background:var(--surface-2);border:1px solid var(--border);border-radius:0 1rem 1rem;padding:1rem 1.1rem;margin-bottom:1.25rem}.intervention-greeting{font-size:.95rem;color:var(--text);font-weight:700;margin-bottom:.6rem}.intervention-msg{font-size:.85rem;color:var(--text-dim);line-height:1.65;margin-bottom:.6rem}.intervention-coda{font-size:.78rem;color:var(--text-muted);font-style:italic}.intervention-actions{display:flex;gap:.75rem;flex-wrap:wrap}.intervention-btn-stay{flex:1;background:var(--accent-3);border:none;border-radius:.4rem;padding:.65rem 1rem;font-family:inherit;font-size:.85rem;color:#fff;cursor:pointer;font-weight:700;transition:background .2s}.intervention-btn-stay:hover{background:#00a35e}.intervention-btn-leave{flex:1;background:var(--surface-3);border:1px solid var(--border);border-radius:.4rem;padding:.65rem 1rem;font-family:inherit;font-size:.85rem;color:var(--text-dim);cursor:pointer;transition:background .2s,color .2s}.intervention-btn-leave:hover{background:var(--surface-2);color:var(--accent)}@media(max-width:600px){.doomsday-strip{padding:.5rem 1rem;gap:.75rem}.doomsday-bar-wrap{display:none}.doom-clock-svg{width:44px;height:44px}.session-tab-items{grid-template-columns:1fr 1fr}.villain-table .villain-rank-cell{display:none}}@media(prefers-reduced-motion:reduce){.emergency-broadcast,.eb-icon,.apology-quote,.shame-entry,.villain-congratulations{animation:none}.doomsday-bar-fill,.doom-clock-hand{transition:none}.intervention-overlay,.intervention-card{animation:none}}.eb-dismiss{background:transparent;border:1px solid rgba(255,255,255,.3);border-radius:50%;width:1.75rem;height:1.75rem;color:#fffc;font-size:.8rem;cursor:pointer;flex-shrink:0;align-self:center;margin-left:auto;transition:background .15s;display:flex;align-items:center;justify-content:center}.eb-dismiss:hover{background:#ffffff26}.grim-reaper{position:fixed;bottom:0;left:0;z-index:10;opacity:.22;transform:translate(-22px);transition:opacity .8s ease,transform .8s ease;pointer-events:auto;filter:drop-shadow(0 4px 12px rgba(0,0,0,.5))}.grim-reaper:hover{opacity:.55;transform:translate(0)}.grim-reaper svg{display:block;width:80px;height:auto;animation:reaper-float 5s ease-in-out infinite}@keyframes reaper-float{0%,to{transform:translateY(0)}50%{transform:translateY(-10px)}}.reaper-eye-inner{filter:drop-shadow(0 0 4px #ff3333);animation:reaper-eye-pulse 3s ease-in-out infinite}@keyframes reaper-eye-pulse{0%,to{opacity:.7}50%{opacity:1}}@media(max-width:480px){.grim-reaper svg{width:55px}.grim-reaper{transform:translate(0)}}@media(prefers-reduced-motion:reduce){.grim-reaper svg,.reaper-eye-inner{animation:none}.grim-reaper{transition:none}}