Carry the region colours onto the landmasses, in the chooser only
The pins already paint by region; the polygons underneath were flat brand grey. They now take the same seven hues, so the chooser reads as seven regions at a glance instead of one grey world with coloured dots. The shared expression could not be reused as-is: it matches on a region property that belongs to our own geojson, while the boundary tileset's features carry iso_3166_1_alpha_3 and know nothing about WAGF regions. So this bridges country code to region to the same palette — no second palette, which is what the one-palette gate exists to prevent. Their fill is 0.12, near-invisible, which is right for a single highlighted country; the chooser is ours and carries 0.42 so the colours read. Cloned pages keep 0.12 and the flat fill exactly, asserted both ways.
This commit is contained in:
parent
ee4b7ed4e9
commit
be33bac508
10 changed files with 207 additions and 69 deletions
|
|
@ -33,7 +33,7 @@ import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
|||
// The region palette comes from the shared strategy, never from a table in here:
|
||||
// check:one-palette exists because a private palette in a consumer is what once made two
|
||||
// surfaces disagree about what a colour meant.
|
||||
import { applyColor as regionColorExpression } from '@map/colors/wagf-region.js'
|
||||
import { applyColor as regionColorExpression, PALETTE as REGION_PALETTE, getColor as regionColorFor } from '@map/colors/wagf-region.js'
|
||||
|
||||
|
||||
const emit = defineEmits(['pick-country'])
|
||||
|
|
@ -129,6 +129,34 @@ const { map, isMapReady, initializeMap, destroy } = useMapInstance({
|
|||
showEdgeBorders: true,
|
||||
})
|
||||
|
||||
// THE REGION COLOURS, CARRIED ONTO THE LANDMASSES (Driver card, 2026-09-24).
|
||||
// The pins already paint by region via the shared expression (regionColorExpression, below at the
|
||||
// pin layer). The polygons cannot use that expression directly: it matches on ['get','region'],
|
||||
// which is a property of OUR geojson, while the boundary tileset's features carry
|
||||
// `iso_3166_1_alpha_3` and know nothing about WAGF regions. So this builds the bridge — country
|
||||
// code -> that country's region -> THE SAME PALETTE. No second palette, which is exactly what
|
||||
// check:one-palette exists to prevent.
|
||||
// The library's fallback, taken from the library itself: getColor({}) resolves an unknown region
|
||||
// to DEFAULT_COLOR. That constant is not exported, and adding an export to a file every bundle
|
||||
// imports is not worth one colour (RULE 2).
|
||||
const REGION_DEFAULT = regionColorFor({})
|
||||
const regionFillExpression = computed(() => {
|
||||
const byCode = new Map()
|
||||
for (const p of props.points) {
|
||||
if (!p || !p.code || !p.region) continue
|
||||
if (!byCode.has(p.code)) byCode.set(p.code, p.region)
|
||||
}
|
||||
if (!byCode.size) return REGION_DEFAULT
|
||||
const match = ['match', ['get', 'iso_3166_1_alpha_3']]
|
||||
for (const [code, region] of byCode) match.push(code, REGION_PALETTE[region] || REGION_DEFAULT)
|
||||
match.push(REGION_DEFAULT)
|
||||
return match
|
||||
})
|
||||
// Their fill is 0.12 — near-invisible, which is right for a single highlighted country on a
|
||||
// CLONED page. The chooser is ours and its whole job is to read AS seven regions at a glance, so
|
||||
// it carries more. The cloned pages keep 0.12 exactly.
|
||||
const FILL_OPACITY_REGION = 0.42
|
||||
|
||||
const SRC_PINS = 'rcm-people-groups'
|
||||
const SRC_COUNTRIES = 'rcm-country-boundaries'
|
||||
|
||||
|
|
@ -225,7 +253,10 @@ function addLayers() {
|
|||
m.addLayer({
|
||||
id: 'rcm-focus-fill', type: 'fill', source: SRC_COUNTRIES,
|
||||
...srcLayer, filter: countryFilter(),
|
||||
paint: { 'fill-color': C.brand, 'fill-opacity': 0.12 },
|
||||
paint: {
|
||||
'fill-color': props.colorMode === 'region' ? regionFillExpression.value : C.brand,
|
||||
'fill-opacity': props.colorMode === 'region' ? FILL_OPACITY_REGION : 0.12,
|
||||
},
|
||||
})
|
||||
m.addLayer({
|
||||
id: 'rcm-focus-outline', type: 'line', source: SRC_COUNTRIES,
|
||||
|
|
@ -321,6 +352,13 @@ function applySubject() {
|
|||
for (const id of ['rcm-focus-fill', 'rcm-focus-outline']) {
|
||||
if (m.getLayer(id)) m.setFilter(id, countryFilter())
|
||||
}
|
||||
// The fill follows the mode too, not just the filter: switching between the chooser and a
|
||||
// cloned page must repaint the landmasses, or the region colours would leak onto their pages.
|
||||
if (m.getLayer('rcm-focus-fill')) {
|
||||
const byRegion = props.colorMode === 'region'
|
||||
m.setPaintProperty('rcm-focus-fill', 'fill-color', byRegion ? regionFillExpression.value : C.brand)
|
||||
m.setPaintProperty('rcm-focus-fill', 'fill-opacity', byRegion ? FILL_OPACITY_REGION : 0.12)
|
||||
}
|
||||
// PROJECTION follows the mode, and only the chooser changes it.
|
||||
// Mapbox v3 defaults to the GLOBE below about zoom 6, so a world-view chooser rendered as a
|
||||
// small sphere floating in a 1200x780 frame — most of the surface empty, the regions tiny.
|
||||
|
|
|
|||
100
public/doxa-maps/assets/fonts/figtree/LICENSE
generated
Normal file
100
public/doxa-maps/assets/fonts/figtree/LICENSE
generated
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
Figtree — SIL Open Font License, Version 1.1
|
||||
Designer: Erik D. Kennedy. Distributed via Google Fonts.
|
||||
Vendored as the free stand-in for Brandon Grotesque (commercial), by Driver decision
|
||||
2026-09-24. Chosen by MEASUREMENT, not by name: at 500/19.5312px Figtree renders
|
||||
'FULL PROFILE' at 126px against Brandon's 128px on live doxa.life — the closest of 19
|
||||
libre grotesques tested. See _probe-glyph-width.mjs.
|
||||
|
||||
Copyright 2022 The Figtree Project Authors (https://github.com/erikdkennedy/figtree)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
public/doxa-maps/assets/fonts/figtree/figtree-500-latin-ext.woff2
generated
Normal file
BIN
public/doxa-maps/assets/fonts/figtree/figtree-500-latin-ext.woff2
generated
Normal file
Binary file not shown.
BIN
public/doxa-maps/assets/fonts/figtree/figtree-500-latin.woff2
generated
Normal file
BIN
public/doxa-maps/assets/fonts/figtree/figtree-500-latin.woff2
generated
Normal file
Binary file not shown.
2
public/doxa-maps/index.html
generated
2
public/doxa-maps/index.html
generated
File diff suppressed because one or more lines are too long
8
public/doxa-maps/manifest.json
generated
8
public/doxa-maps/manifest.json
generated
|
|
@ -874,7 +874,7 @@
|
|||
"bundle": "regions-dashboard",
|
||||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"output": "doxa-maps/regions-dashboard/regions-dashboard.js",
|
||||
"integrity": "sha384-V6UcPxx9/C30jhjP3qxO1v/Ib4nMhu+uPJL0dd0geMrA236NuP9HZchD58RT3DL3",
|
||||
"integrity": "sha384-jj4JBxH2lbWxtqsuDMdk7yN2IiLQfLFmwLVj8nPk33JRqqSaaz3XOjz3dDxAG+3c",
|
||||
"elements": [
|
||||
"regions-dashboard"
|
||||
],
|
||||
|
|
@ -894,7 +894,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-V6UcPxx9/C30jhjP3qxO1v/Ib4nMhu+uPJL0dd0geMrA236NuP9HZchD58RT3DL3\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jj4JBxH2lbWxtqsuDMdk7yN2IiLQfLFmwLVj8nPk33JRqqSaaz3XOjz3dDxAG+3c\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -908,7 +908,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-V6UcPxx9/C30jhjP3qxO1v/Ib4nMhu+uPJL0dd0geMrA236NuP9HZchD58RT3DL3\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jj4JBxH2lbWxtqsuDMdk7yN2IiLQfLFmwLVj8nPk33JRqqSaaz3XOjz3dDxAG+3c\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -922,7 +922,7 @@
|
|||
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-V6UcPxx9/C30jhjP3qxO1v/Ib4nMhu+uPJL0dd0geMrA236NuP9HZchD58RT3DL3\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jj4JBxH2lbWxtqsuDMdk7yN2IiLQfLFmwLVj8nPk33JRqqSaaz3XOjz3dDxAG+3c\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-V6UcPxx9/C30jhjP3qxO1v/Ib4nMhu+uPJL0dd0geMrA236NuP9HZchD58RT3DL3" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-jj4JBxH2lbWxtqsuDMdk7yN2IiLQfLFmwLVj8nPk33JRqqSaaz3XOjz3dDxAG+3c" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
118
public/doxa-maps/regions-dashboard/regions-dashboard.js
generated
118
public/doxa-maps/regions-dashboard/regions-dashboard.js
generated
File diff suppressed because one or more lines are too long
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-V6UcPxx9/C30jhjP3qxO1v/Ib4nMhu+uPJL0dd0geMrA236NuP9HZchD58RT3DL3" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-jj4JBxH2lbWxtqsuDMdk7yN2IiLQfLFmwLVj8nPk33JRqqSaaz3XOjz3dDxAG+3c" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
|
||||
<script src="../regions-dashboard.js" integrity="sha384-V6UcPxx9/C30jhjP3qxO1v/Ib4nMhu+uPJL0dd0geMrA236NuP9HZchD58RT3DL3" crossorigin="anonymous"></script>
|
||||
<script src="../regions-dashboard.js" integrity="sha384-jj4JBxH2lbWxtqsuDMdk7yN2IiLQfLFmwLVj8nPk33JRqqSaaz3XOjz3dDxAG+3c" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue