feat: add landing-style start screen with four start modes

Phase 3 of turning the game into the company landing page.

- Replace the Iran-map briefing with a brand start screen over the
  orbiting 3D factory: logo, tagline and four ways in.
- Real world: safety notice, then GPS; if location is denied or
  missing, a friendly dialog offers offline play instead.
- Offline: start at Park Mellat beside the family car with the route
  to the factory, where the first purchase mission is.
- About Us: start in the factory yard. Products: start at the machine
  samples with the showroom open.
- Contact, address with map links, FAQ, careers, gallery and social
  links open in a sheet (bottom sheet on phones) from company config.
- Restart replays the chosen mode. Layout scrolls on short screens and
  respects safe areas.
- Add tests for the start screen, map links and theme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 08:39:22 +03:30
co-authored by Claude Opus 5.5
parent 611960511e
commit d9ae8a45da
28 changed files with 838 additions and 261 deletions
-24
View File
@@ -3,7 +3,6 @@ import { createState } from '../economy/gameState.js';
import { createPayment } from '../economy/payment.js';
import { createVendingMachine } from '../models/vending.js';
import { resetGarage } from './garage.js';
import { strings } from '../../i18n/fa.js';
import { COMPANY } from '../../config/company.js';
// Brand colours for materials and canvas drawings.
@@ -121,26 +120,3 @@ export function reset(context) {
context.keys.clear();
context.refreshHUD();
}
// ---------- Input ----------
/**
* Runs the start mission operation for this subsystem.
* @param {*} context - context.
* @returns {*} Operation result, when applicable.
*/
export function startMission(context) {
context.ui.patch('briefing', {
hidden: true,
});
context.ui.patch('hud', {
hidden: false,
});
const { dialogue } = strings;
context.say('robot', dialogue.showroomIntro, 'wink');
context.say('child', dialogue.childAsksFactory);
context.say('father', dialogue.fatherAnswersFactory);
context.say('child', dialogue.childAsksArrival);
context.say('father', dialogue.fatherAnswersArrival);
if (!context.isTouch && !context.real.on)
context.canvas.requestPointerLock?.()?.catch?.(() => {});
}