Update data
This commit is contained in:
parent
a4103b0896
commit
273d7a83ee
15 changed files with 716 additions and 316 deletions
|
|
@ -3,7 +3,6 @@ import {
|
|||
hex,
|
||||
vfrac,
|
||||
type Activity,
|
||||
type AdScene,
|
||||
type Storyboard,
|
||||
type TravelTimeFilter,
|
||||
type VideoConfig,
|
||||
|
|
@ -629,30 +628,6 @@ const AD_DEFAULT_FILTERS: Record<string, [number, number] | string[]> = {
|
|||
'Outstanding primary schools within 2km': [0, 10],
|
||||
};
|
||||
|
||||
/**
|
||||
* Stable Unsplash CDN photo URLs. Each one is a 720-wide JPEG fetched at
|
||||
* record time. The CDN serves with permissive CORS, no auth needed, and
|
||||
* the IDs are stable URLs (Unsplash does not rotate them). If any photo
|
||||
* stops resolving, dom.ts hides the broken image and the rest of the
|
||||
* scene still renders, so a 404 here degrades to text-only rather than
|
||||
* breaking the ad. To swap a photo, search unsplash.com for the theme
|
||||
* and paste the `photo-{id}` slug from the URL bar.
|
||||
*/
|
||||
const PHOTO = {
|
||||
terracedRow: 'https://images.unsplash.com/photo-1769344694490-66fb22a8d8cf?w=720&q=80&auto=format&fit=crop',
|
||||
brickStreet: 'https://images.unsplash.com/photo-1689867373120-355ce130d485?w=720&q=80&auto=format&fit=crop',
|
||||
woodAccentHouses: 'https://images.unsplash.com/photo-1753198412280-b4a9729c1c51?w=720&q=80&auto=format&fit=crop',
|
||||
colourfulRow: 'https://images.unsplash.com/photo-1718579019220-98697dc2fd72?w=720&q=80&auto=format&fit=crop',
|
||||
busyTraffic: 'https://images.unsplash.com/photo-1645718171033-574c88494de2?w=720&q=80&auto=format&fit=crop',
|
||||
cityTraffic: 'https://images.unsplash.com/photo-1714128949057-f7ac4cb71e6c?w=720&q=80&auto=format&fit=crop',
|
||||
trafficLight: 'https://images.unsplash.com/photo-1680276553514-357f2edc46a1?w=720&q=80&auto=format&fit=crop',
|
||||
leafySuburb: 'https://images.unsplash.com/photo-1663651884092-a2449ed3671a?w=720&q=80&auto=format&fit=crop',
|
||||
suburbHomes: 'https://images.unsplash.com/photo-1768301346584-86e781872b82?w=720&q=80&auto=format&fit=crop',
|
||||
trainPlatform: 'https://images.unsplash.com/photo-1684934899514-772e03714de5?w=720&q=80&auto=format&fit=crop',
|
||||
trainClock: 'https://images.unsplash.com/photo-1657441629839-874d398b6e04?w=720&q=80&auto=format&fit=crop',
|
||||
keysFrontDoor: 'https://images.unsplash.com/photo-1741156386380-0236c72eb6f9?w=720&q=80&auto=format&fit=crop',
|
||||
};
|
||||
|
||||
const linger = (durationMs = 360): Activity[] => [{ kind: 'wait', durationMs }];
|
||||
|
||||
/**
|
||||
|
|
@ -781,15 +756,6 @@ const ttDragAct = (toMin: number, durationMs = 1400): Activity => ({
|
|||
toFraction: toMin / TT_SLIDER_MAX,
|
||||
durationMs,
|
||||
});
|
||||
const showScene = (scene: AdScene): Activity => ({
|
||||
kind: 'showAdScene',
|
||||
scene,
|
||||
durationMs: 0,
|
||||
});
|
||||
const hideScene = (durationMs = 320): Activity => ({
|
||||
kind: 'hideAdScene',
|
||||
durationMs,
|
||||
});
|
||||
const wait = (durationMs: number): Activity => ({ kind: 'wait', durationMs });
|
||||
const mapZoomIn = (durationMs = 1400, steps = 5): Activity => ({
|
||||
kind: 'mapZoom',
|
||||
|
|
@ -860,17 +826,18 @@ const LONDON_VIEW = { lat: 51.4672, lon: -0.1276, zoom: 10.5 };
|
|||
const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
||||
// -------------------------------------------------------------------
|
||||
// 01 — Search by sentence. Type the prompt on camera, narration runs
|
||||
// simultaneously. Filters relevant: commute + crime + schools.
|
||||
// simultaneously. Filters relevant: price + commute + crime + noise.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-01-london-prompt',
|
||||
city: 'london',
|
||||
promptText:
|
||||
'Two bed in London, 35 min to centre, lower crime, lower noise',
|
||||
'London flat under £600k, 35 min to centre, lower crime, lower noise',
|
||||
filters: {
|
||||
'Property type': ['Flats/Maisonettes'],
|
||||
'Estimated current price': [0, 600000],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 50],
|
||||
'Road noise score (mean dB)': [0, 60],
|
||||
'Noise (dB)': [0, 58],
|
||||
},
|
||||
travelTimeFilters: [
|
||||
{ mode: 'transit', slug: 'london', label: 'London city centre', max: 35 },
|
||||
|
|
@ -879,20 +846,20 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
posterTimeS: 8,
|
||||
cues: [
|
||||
{
|
||||
text: 'Describe the London home you actually want.',
|
||||
text: 'Stop searching listing by listing. Search by the area brief.',
|
||||
during: [typeAct(
|
||||
'Two bed in London, 35 min to centre, lower crime, lower noise',
|
||||
'London flat under £600k, 35 min to centre, lower crime, lower noise',
|
||||
2800
|
||||
)],
|
||||
tail: [wait(200)],
|
||||
},
|
||||
{
|
||||
text: 'Hit search. The map answers in one second.',
|
||||
text: 'Price, commute, crime and noise land on the map together.',
|
||||
during: [submitAct(1100)],
|
||||
tail: [wait(700)],
|
||||
},
|
||||
{
|
||||
text: 'Every lit postcode fits all five rules at once.',
|
||||
text: 'Every lit postcode is somewhere worth checking first.',
|
||||
tail: [wait(600)],
|
||||
},
|
||||
],
|
||||
|
|
@ -914,16 +881,16 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
posterTimeS: 5.5,
|
||||
cues: [
|
||||
{
|
||||
text: 'Watch what one slider does to your shortlist.',
|
||||
text: 'Your commute limit should change the map, not your patience.',
|
||||
tail: [wait(200)],
|
||||
},
|
||||
{
|
||||
text: 'Drag forty minutes down to fifteen.',
|
||||
text: 'Drag forty minutes down to fifteen minutes.',
|
||||
during: [ttDragAct(15, 1900)],
|
||||
tail: [wait(700)],
|
||||
},
|
||||
{
|
||||
text: 'Half the map just lost its place.',
|
||||
text: 'The reachable postcodes disappear in front of you.',
|
||||
tail: [wait(600)],
|
||||
},
|
||||
],
|
||||
|
|
@ -946,17 +913,17 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
posterTimeS: 10,
|
||||
cues: [
|
||||
{
|
||||
text: 'Type the brief. Map fills with matching areas.',
|
||||
text: 'Type a family brief and watch matching areas appear.',
|
||||
during: [typeAct('Family home in London, decent schools nearby', 2400), submitAct(900)],
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'Zoom past the hexagons. Real postcodes break open.',
|
||||
text: 'Zoom from area patterns into actual postcodes.',
|
||||
during: [mapZoomIn(3000, 10)],
|
||||
tail: [wait(400)],
|
||||
},
|
||||
{
|
||||
text: 'Tap one. Sold prices, schools, crime, noise.',
|
||||
text: 'Tap one for sold prices and street-level context.',
|
||||
during: [
|
||||
{ kind: 'cursorScale', scale: 1.3, durationMs: 200 },
|
||||
clickHex(900),
|
||||
|
|
@ -992,7 +959,7 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
posterTimeS: 6,
|
||||
cues: [
|
||||
{
|
||||
text: 'Four hundred grand. London. Thirty minute commute.',
|
||||
text: 'London under four hundred thousand, with a thirty minute commute.',
|
||||
during: [typeAct(
|
||||
'Flat in London under £400k, 30 min to centre, lower crime',
|
||||
2800
|
||||
|
|
@ -1000,61 +967,57 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
tail: [wait(400)],
|
||||
},
|
||||
{
|
||||
text: 'Watch the filters stack and the map shrink.',
|
||||
text: 'The active filters stack up as the map tightens.',
|
||||
during: [scrollFilters(280, 900)],
|
||||
tail: [wait(600)],
|
||||
},
|
||||
{
|
||||
text: 'Every lit postcode hits all four rules.',
|
||||
text: 'Now the cheap-looking areas have to pass the brief.',
|
||||
tail: [wait(500)],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 05 — Two streets apart. Photo split is the hook. Caption stays
|
||||
// SHORT so it does not compete with the overlay's title text.
|
||||
// 05 — Two streets apart. Product-led now: noise + crime filters are
|
||||
// typed and submitted on screen instead of masking the product with
|
||||
// generic street photos.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-05-two-streets-apart',
|
||||
city: 'london',
|
||||
promptText: 'Quieter London, lower road noise',
|
||||
promptText: 'Quiet London streets, lower noise, lower serious crime',
|
||||
filters: {
|
||||
'Road noise score (mean dB)': [0, 58],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 50],
|
||||
'Noise (dB)': [0, 55],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 45],
|
||||
},
|
||||
initialZoom: 10.6,
|
||||
posterTimeS: 4,
|
||||
cues: [
|
||||
{
|
||||
text: 'Two homes. Four hundred metres apart.',
|
||||
during: [showScene({
|
||||
mode: 'split',
|
||||
accent: 'rose',
|
||||
kicker: 'Two streets',
|
||||
title: 'Same price tag.',
|
||||
images: [PHOTO.terracedRow, PHOTO.busyTraffic],
|
||||
left: { title: 'Street A', meta: 'Quiet', tone: 'good' },
|
||||
right: { title: 'Street B', meta: 'Main road', tone: 'bad' },
|
||||
transparent: false,
|
||||
})],
|
||||
text: 'Two streets can look identical in a listing photo.',
|
||||
during: [typeAct(
|
||||
'Quiet London streets, lower noise, lower serious crime',
|
||||
2500
|
||||
), submitAct(900)],
|
||||
tail: [wait(400)],
|
||||
},
|
||||
{
|
||||
text: 'Filter noise and serious crime before you book a viewing.',
|
||||
during: [scrollFilters(220, 800)],
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'Same price. Completely different lives.',
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'The map knows the difference. The photos do not.',
|
||||
during: [hideScene(360)],
|
||||
tail: [wait(700)],
|
||||
text: 'Now the quieter pockets are the ones left on screen.',
|
||||
during: [mapZoomIn(1300, 4)],
|
||||
tail: [wait(600)],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 06 — Commute tax. Photo hook (train platform) opens; cue 1 hides
|
||||
// the overlay and the travel-time slider drags from 60 → 20 min.
|
||||
// 06 — Commute tax. Starts on the live commute layer and immediately
|
||||
// proves the point with the travel-time slider.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-06-london-commute-tax',
|
||||
|
|
@ -1068,38 +1031,30 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
posterTimeS: 4,
|
||||
cues: [
|
||||
{
|
||||
text: 'Twenty minutes or sixty. Same asking price.',
|
||||
during: [showScene({
|
||||
mode: 'title',
|
||||
accent: 'amber',
|
||||
kicker: 'Commute tax',
|
||||
image: PHOTO.trainClock,
|
||||
title: 'Cheap, until you count the hours.',
|
||||
})],
|
||||
tail: [wait(400)],
|
||||
text: 'A cheap home gets expensive when the commute is wrong.',
|
||||
tail: [wait(300)],
|
||||
},
|
||||
{
|
||||
text: 'Drag the slider. Watch the map shrink.',
|
||||
during: [hideScene(320), ttDragAct(20, 1800)],
|
||||
text: 'Drag sixty minutes down to twenty and watch the map shrink.',
|
||||
during: [ttDragAct(20, 1900)],
|
||||
tail: [wait(700)],
|
||||
},
|
||||
{
|
||||
text: 'Time is the bill you pay every week.',
|
||||
text: 'That weekly time bill is visible before the viewing.',
|
||||
tail: [wait(600)],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 07 — Quiet near London. Leafy-suburb photo opens; cue 1 hides it
|
||||
// and the dashboard (already filtered for low noise) is revealed.
|
||||
// 07 — Quiet near London. Uses the real prod Noise (dB) feature.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-07-quiet-near-london',
|
||||
city: 'london',
|
||||
promptText: 'Quieter London, lower road noise, good transit',
|
||||
filters: {
|
||||
'Road noise score (mean dB)': [0, 56],
|
||||
'Noise (dB)': [0, 55],
|
||||
'Estimated current price': [0, 700000],
|
||||
},
|
||||
travelTimeFilters: [
|
||||
|
|
@ -1109,30 +1064,25 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
posterTimeS: 4,
|
||||
cues: [
|
||||
{
|
||||
text: 'Quiet streets, near London. They do exist.',
|
||||
during: [showScene({
|
||||
mode: 'title',
|
||||
accent: 'teal',
|
||||
image: PHOTO.leafySuburb,
|
||||
title: 'Yes, they exist.',
|
||||
})],
|
||||
text: 'Quiet near London is searchable, not just hopeful.',
|
||||
during: [typeAct('Quieter London, lower road noise, good transit', 2500), submitAct(900)],
|
||||
tail: [wait(400)],
|
||||
},
|
||||
{
|
||||
text: 'You just have to filter for noise, not price.',
|
||||
during: [hideScene(320), scrollFilters(220, 800)],
|
||||
text: 'Filter for noise alongside price and travel time.',
|
||||
during: [scrollFilters(220, 800)],
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'The hidden pockets light up.',
|
||||
text: 'The calmer pockets show up before you go anywhere.',
|
||||
tail: [wait(500)],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 08 — The postcode comes with the keys. Keys photo opens; map shows
|
||||
// London filtered for family-friendly area.
|
||||
// 08 — The postcode comes with the keys. Keeps the memorable premise,
|
||||
// but shows the product doing the work instead of a keys stock photo.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-08-postcode-with-the-keys',
|
||||
|
|
@ -1142,99 +1092,104 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
'Estimated current price': [0, 750000],
|
||||
'Outstanding primary schools within 2km': [1, 10],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 50],
|
||||
'Noise (dB)': [0, 58],
|
||||
},
|
||||
travelTimeFilters: [
|
||||
{ mode: 'transit', slug: 'london', label: 'London city centre', max: 45 },
|
||||
],
|
||||
initialZoom: 10.5,
|
||||
posterTimeS: 3,
|
||||
cues: [
|
||||
{
|
||||
text: 'You can renovate the kitchen.',
|
||||
during: [showScene({
|
||||
mode: 'title',
|
||||
accent: 'lime',
|
||||
image: PHOTO.keysFrontDoor,
|
||||
title: 'You keep the postcode forever.',
|
||||
})],
|
||||
text: 'You can change the kitchen. You inherit the postcode.',
|
||||
during: [typeAct(
|
||||
'Family London, lower crime, good schools, lower noise',
|
||||
2500
|
||||
), submitAct(900)],
|
||||
tail: [wait(400)],
|
||||
},
|
||||
{
|
||||
text: 'You can not renovate the commute or the noise.',
|
||||
text: 'So check commute, crime, schools and noise first.',
|
||||
during: [scrollFilters(320, 900)],
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'Pick the area first. The keys come second.',
|
||||
during: [hideScene(320)],
|
||||
during: [mapZoomIn(1200, 4)],
|
||||
tail: [wait(600)],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 09 — Waitrose distance. Niche filter that maps to social-class
|
||||
// proxy. We type the brief, scroll the filter pane to surface the
|
||||
// Waitrose-distance card explicitly.
|
||||
// 09 — Amenities. Waitrose is the memorable example, but the copy
|
||||
// frames it as practical amenity filtering rather than a throwaway gag.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-09-london-waitrose',
|
||||
city: 'london',
|
||||
promptText:
|
||||
'London postcodes within walking distance of a Waitrose',
|
||||
'London postcodes near Waitrose, tube and parks under £800k',
|
||||
filters: {
|
||||
'Distance to nearest Waitrose (km)': [0, 1],
|
||||
'Distance to nearest tube station (km)': [0, 1.2],
|
||||
'Distance to nearest park (km)': [0, 0.8],
|
||||
'Estimated current price': [0, 800000],
|
||||
},
|
||||
initialZoom: 10.4,
|
||||
posterTimeS: 7,
|
||||
cues: [
|
||||
{
|
||||
text: 'How close is your nearest Waitrose. Yes, really.',
|
||||
text: 'Amenities should be filters, not guesses from the photos.',
|
||||
during: [typeAct(
|
||||
'London postcodes within walking distance of a Waitrose',
|
||||
'London postcodes near Waitrose, tube and parks under £800k',
|
||||
2800
|
||||
), submitAct(900)],
|
||||
tail: [wait(400)],
|
||||
},
|
||||
{
|
||||
text: 'The map highlights the lucky postcodes.',
|
||||
during: [scrollFilters(180, 800)],
|
||||
text: 'Waitrose, tube, parks and price can all count together.',
|
||||
during: [scrollFilters(300, 900)],
|
||||
tail: [wait(600)],
|
||||
},
|
||||
{
|
||||
text: 'It is a real filter, not a meme.',
|
||||
text: 'Now you know which postcodes actually match that lifestyle.',
|
||||
tail: [wait(500)],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 10 — Reform-voting councils. % Reform UK vote share as a filter.
|
||||
// Politically tense — kept matter-of-fact, no spin in the copy.
|
||||
// 10 — Local politics. Matter-of-fact and product-led; lower threshold
|
||||
// keeps the map populated while still surfacing the Reform UK feature.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-10-reform-councils',
|
||||
city: 'london',
|
||||
city: 'leeds',
|
||||
promptText:
|
||||
'Areas where the council voted heavily for Reform UK',
|
||||
'Areas with higher Reform UK vote share and lower prices',
|
||||
filters: {
|
||||
'% Reform UK': [25, 100],
|
||||
'% Reform UK': [15, 100],
|
||||
'Estimated current price': [0, 350000],
|
||||
},
|
||||
initialZoom: 9.5,
|
||||
initialZoom: 10.5,
|
||||
posterTimeS: 7,
|
||||
cues: [
|
||||
{
|
||||
text: 'Want to know which way your future council voted.',
|
||||
text: 'Local politics is part of the neighbourhood data too.',
|
||||
during: [typeAct(
|
||||
'Areas where the council voted heavily for Reform UK',
|
||||
'Areas with higher Reform UK vote share and lower prices',
|
||||
2600
|
||||
)],
|
||||
tail: [wait(300)],
|
||||
},
|
||||
{
|
||||
text: 'Run the filter. See the map.',
|
||||
text: 'Run the filter and see which areas stay in view.',
|
||||
during: [submitAct(900), scrollFilters(180, 700)],
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'Politics shapes the area too.',
|
||||
text: 'No spin. Just another local signal before you buy.',
|
||||
tail: [wait(500)],
|
||||
},
|
||||
],
|
||||
|
|
@ -1247,76 +1202,67 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
name: 'ad-11-leeds-families',
|
||||
city: 'leeds',
|
||||
promptText:
|
||||
'Three bed near Leeds, outstanding primary nearby, lower crime',
|
||||
'Leeds family areas, good primary schools nearby, lower crime',
|
||||
filters: {
|
||||
'Estimated current price': [0, 380000],
|
||||
'Outstanding primary schools within 2km': [2, 10],
|
||||
'Good+ primary schools within 2km': [2, 10],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 45],
|
||||
},
|
||||
initialZoom: 11.0,
|
||||
posterTimeS: 6,
|
||||
cues: [
|
||||
{
|
||||
text: 'Leeds, but only the school-run friendly bits.',
|
||||
text: 'Find Leeds areas that work for the school run.',
|
||||
during: [typeAct(
|
||||
'Three bed near Leeds, outstanding primary nearby, lower crime',
|
||||
'Leeds family areas, good primary schools nearby, lower crime',
|
||||
2500
|
||||
), submitAct(900)],
|
||||
tail: [wait(300)],
|
||||
},
|
||||
{
|
||||
text: 'Two outstanding primaries within walking distance.',
|
||||
text: 'School quality and serious crime sit beside price.',
|
||||
during: [scrollFilters(220, 800)],
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'Every lit postcode is a real candidate.',
|
||||
text: 'Every lit postcode is a better place to start.',
|
||||
tail: [wait(500)],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 12 — Pricing scarcity. Real prod numbers (verified via /api/pricing
|
||||
// at render time): the £0.99 tier is sold out (50/50); the current
|
||||
// £9.99 tier has 17 slots left before the next jump to £29.99. We
|
||||
// surface those numbers in a structured rank scene over the live
|
||||
// dashboard, since recording on the /pricing route would require a
|
||||
// dashboard URL override and we want to ship this iteration.
|
||||
// 12 — Pricing/value. Keeps the current £9.99 founder-price hook, but
|
||||
// proves value through the product instead of a static scarcity card.
|
||||
// -------------------------------------------------------------------
|
||||
{
|
||||
name: 'ad-12-pricing-scarcity',
|
||||
city: 'london',
|
||||
promptText: 'Quieter London, good schools, lower crime',
|
||||
promptText: 'London under £700k, good schools, lower crime and lower noise',
|
||||
filters: {
|
||||
'Estimated current price': [0, 700000],
|
||||
'Outstanding primary schools within 2km': [1, 10],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 50],
|
||||
'Noise (dB)': [0, 58],
|
||||
},
|
||||
initialZoom: 10.4,
|
||||
posterTimeS: 3,
|
||||
cues: [
|
||||
{
|
||||
text: 'Seventeen spots left at nine ninety nine.',
|
||||
during: [showScene({
|
||||
mode: 'rank',
|
||||
accent: 'amber',
|
||||
kicker: 'Founder pricing',
|
||||
title: 'Cheap tier almost gone.',
|
||||
items: [
|
||||
{ label: '£0.99 / month', value: 'sold out', tone: 'bad' },
|
||||
{ label: '£9.99 / month', value: '17 left', tone: 'warn' },
|
||||
{ label: '£29.99 / month', value: 'next', tone: 'neutral' },
|
||||
],
|
||||
})],
|
||||
text: 'Nine ninety nine beats one wasted viewing.',
|
||||
during: [typeAct(
|
||||
'London under £700k, good schools, lower crime and lower noise',
|
||||
2700
|
||||
), submitAct(900)],
|
||||
tail: [wait(400)],
|
||||
},
|
||||
{
|
||||
text: 'Then the price triples.',
|
||||
text: 'Use the map before spending a Saturday in the wrong area.',
|
||||
during: [scrollFilters(300, 900)],
|
||||
tail: [wait(500)],
|
||||
},
|
||||
{
|
||||
text: 'Get in before the next jump.',
|
||||
during: [hideScene(360)],
|
||||
text: 'The cheapest mistake is the one you skip.',
|
||||
tail: [wait(600)],
|
||||
},
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue