Source comments state design history and measurements as facts, without quoting or naming anyone
Comments in library/ and internal/ that quoted a person, attributed a decision to one, used first person, named fleet agents or carried private host names now state the same technical fact in neutral words: poster-render (including the comments it writes into generated posters), packet-render, the poster and research scripts, PosterWall, DataTable, the legends, the layouts and the gates. The network-policy note states the policy itself. Behaviour is unchanged: a few printed gate messages and reason labels drop an agent name, the poster-render integrity pin follows its comment-only edit, and series.json changes only in its _meta and _why notes. The historical poster design snapshots (library/scripts/posters/snapshots/), which nothing reads, are removed.
This commit is contained in:
parent
3f7d489409
commit
2c397d25ef
179 changed files with 753 additions and 17481 deletions
|
|
@ -423,7 +423,7 @@ func (e *engine) startWith(lang, device string, src *recorderProc, sink func(eve
|
|||
recMu.Unlock()
|
||||
writeMu.Lock()
|
||||
// The streaming model holds back the last fraction of a second (its right context) until more audio
|
||||
// or a pause arrives, and a commit alone does not flush it (rega: a Stop mid-sentence lost "what
|
||||
// or a pause arrives, and a commit alone does not flush it (measured: a Stop mid-sentence lost "what
|
||||
// your country…"). 1.2 s of silence first lets it finish the words already spoken.
|
||||
silence := make([]byte, 3200)
|
||||
for i := 0; i < 12; i++ {
|
||||
|
|
@ -750,7 +750,7 @@ func (e *engine) startWith(lang, device string, src *recorderProc, sink func(eve
|
|||
e.logs.add("speech server error: %s", string(msg))
|
||||
emit(event{"type": "error", "message": string(msg)})
|
||||
case t == "input_audio_buffer.committed":
|
||||
// The commit acknowledges Stop; the words for the audio before it can still follow (rega: a
|
||||
// The commit acknowledges Stop; the words for the audio before it can still follow (measured: a
|
||||
// Stop mid-word lost "what your country…"). Keep reading until the final text or 6 s of quiet (a loaded server can take seconds per backlog chunk).
|
||||
committed = true
|
||||
e.logs.add("speech server committed the stream; reading its last words")
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="512" width="840" height="1208" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="489" width="840" height="1231" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="627" width="840" height="1093" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -214,8 +214,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -286,15 +286,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="351" width="840" height="1333" fill="var(--sea)"
|
||||
|
|
@ -318,7 +316,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -342,8 +340,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1925" x2="1474" y2="1925" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="512" width="840" height="1208" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="443" width="840" height="1277" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@
|
|||
.hseries{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:14px;fill:#7E7562;letter-spacing:.01em}
|
||||
.hseries-em{font-weight:700;fill:#6B4A78}
|
||||
.hseries-dim{fill:#A79E8A}
|
||||
/* The site reference on its OWN line — Brief: "so that it is less wide". A
|
||||
/* The site reference on its OWN line, so the series block is less wide. A
|
||||
single long line was forcing the series block wider than the map. */
|
||||
.hseries-dim2{font-family:Lato,'Segoe UI',system-ui,sans-serif;font-size:12px;
|
||||
fill:#A79E8A;letter-spacing:.02em}
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
the map's width (~1100px); the band is now 1388px, so the type follows.
|
||||
15px measures ~1263px — fills the band while keeping headroom over the width
|
||||
estimator's error rather than sitting one glyph from overflow. */
|
||||
/* 13.5px bold. Brief: "this is too large, it should not span full width —
|
||||
there needs to be gaps." At 15px bold it measured 1396px of the 1448px band,
|
||||
/* 13.5px bold. At full width it was too large: the line needs gaps at both
|
||||
ends. At 15px bold it measured 1396px of the 1448px band,
|
||||
i.e. touching both rules; 13.5 measures ~1256px and leaves ~96px of paper at
|
||||
each end, so the line reads as SET INSIDE the band rather than filling it.
|
||||
Bold + dark ink still carry the weight. */
|
||||
|
|
@ -276,15 +276,13 @@
|
|||
<feDropShadow dx="0" dy="3" stdDeviation="5" flood-color="#2A2721" flood-opacity="0.34"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating."
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating.
|
||||
A soft drop shadow under a crisp 1.5px border lifts the map off the paper,
|
||||
so it reads as an object ON the sheet rather than a window cut INTO it —
|
||||
which is also what makes the surrounding text feel like a mount around it. -->
|
||||
<!-- THE MAP FLOATS. Brief: "a border around the map itself like a border line
|
||||
and a shadow around the outside of that line that makes the map itself look
|
||||
like it is floating." The white mat was tried and rejected — the shadow-only
|
||||
<!-- THE MAP FLOATS: a border line around the map itself, with a shadow outside
|
||||
that line, makes the map look like it is floating. The white mat was tried and rejected — the shadow-only
|
||||
border reads better, and the mat also cut every leader line with a band of
|
||||
white where the lines crossed it. -->
|
||||
<rect x="330" y="466" width="840" height="1254" fill="var(--sea)"
|
||||
|
|
@ -308,7 +306,7 @@
|
|||
down to where the region name stops being the loudest thing on the poster.
|
||||
Splitting it lets the CATEGORY sit quietly above and the REGION stay big:
|
||||
the region is what a passer-by uses to find their sheet on a wall of 30. -->
|
||||
<!-- TITLE, two-tone. Brief: the title reads "Unengaged of <Region>", with
|
||||
<!-- TITLE, two-tone. The title reads "Unengaged of <Region>", with
|
||||
"Unengaged of" in a DIFFERENT COLOUR from the region name — so a passer-by
|
||||
reads at a glance that it is these PEOPLE who are unengaged, while the
|
||||
region stays the loudest thing on the sheet. The overline above it is now
|
||||
|
|
@ -332,8 +330,8 @@
|
|||
shadow now define that edge far more clearly, so the rule just floated as a
|
||||
stray horizontal line above the map.) -->
|
||||
<line x1="26" y1="1936" x2="1474" y2="1936" class="rule"/>
|
||||
<!-- FOOTER SCRIPTURE — TIER 1. Brief: "should be larger text bold and not two
|
||||
lines but one line with scripture reference on the right." It is one of the
|
||||
<!-- FOOTER SCRIPTURE — TIER 1: larger, bold, on ONE line, with the scripture
|
||||
reference on the right. It is one of the
|
||||
three things that must read when a reader steps closer, alongside the title
|
||||
and the people-group names, so it carries display weight. The reference is
|
||||
right-aligned to the map's own edge, which is what keeps it on ONE line. -->
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ export function backendDevPlugin(root, env = process.env) {
|
|||
name: 'dx-backend-dev',
|
||||
apply: 'serve',
|
||||
configureServer(server) {
|
||||
// ENGINE NOT RUNNING, QUIETLY (dx-shepherd, R500): with no backend process the proxy answered
|
||||
// ENGINE NOT RUNNING, QUIETLY (R500): with no backend process the proxy answered
|
||||
// 500 ECONNREFUSED, which every page showed as console errors. While a backend is down its routes get
|
||||
// well-formed answers instead: /events streams ONE status event saying the engine is offline (the
|
||||
// plugin renders its own "engine not running" state from it), anything else returns an empty JSON
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ done
|
|||
|
||||
# Everything busy: keep POLLING EVERY SLOT until the deadline, and report a timeout as UNMEASURED
|
||||
# rather than as a verdict. This used to queue on slot 1 alone (flock -w on slot 1), so a slot that
|
||||
# freed up was never taken: measured 2026-09-25 (dx-shepherd), ten waiters were piled on slot 1 while
|
||||
# freed up was never taken: measured 2026-09-25, ten waiters were piled on slot 1 while
|
||||
# slot 2 sat free, and with slot 1 held 12 s and slot 2 freed at ~3 s a caller waited 11.5 s — the
|
||||
# two-slot semaphore had collapsed into ONE queue. Polling takes the first slot that frees (~4 s in
|
||||
# the same test). Trade-off, accepted: polling is not first-come-first-served, so under heavy
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ check('a GeoJSON feature is matched to rows on the same point', colocatedWith(id
|
|||
check('a lone point shares with nobody', colocatedWith(idx, rows[3]).length === 0, colocatedWith(idx, rows[3]))
|
||||
check('a row without a position is ignored', colocatedWith(idx, rows[4]).length === 0, colocatedWith(idx, rows[4]))
|
||||
// A click hands over the RENDERED feature: the engine rebuilt its geometry from tile coordinates, so it is
|
||||
// near the roster point but not equal to it: ~0.001 degree at low zoom (rega, row 46, a shared point that never matched).
|
||||
// near the roster point but not equal to it: ~0.001 degree at low zoom (a browser check, row 46: a shared point that never matched).
|
||||
const rendered = { type: 'Feature', properties: { name: 'Koraga' }, geometry: { type: 'Point', coordinates: [75.2486, 12.8431] } }
|
||||
check('a rendered (tile-rounded) feature still finds its co-located groups', colocatedWith(idx, rendered).sort().join() === 'Godda,Maila', colocatedWith(idx, rendered))
|
||||
// The same people in two countries: the nearest roster row wins, not the first.
|
||||
|
|
@ -39,7 +39,7 @@ const renderedFar = { type: 'Feature', properties: { name: 'Koraga' }, geometry:
|
|||
check('a repeated name resolves to the nearest roster point', colocatedWith(twin, renderedFar).join() === 'Other', colocatedWith(twin, renderedFar))
|
||||
// The rows a map DRAWS are normalized people groups (name + latitude/longitude, no geometry), and every
|
||||
// map built on useMapData must offer them to its legends: the prayer map did not, so its legends read the
|
||||
// raw API cache and neither the shared-point sentence nor the standing note appeared (rega, row 46 at 835ec1ac).
|
||||
// raw API cache and neither the shared-point sentence nor the standing note appeared (a browser check, row 46 at 835ec1ac).
|
||||
const drawn = [{ name: 'A', latitude: 12.85, longitude: 75.25 }, { name: 'B', latitude: '12.85', longitude: '75.25' }]
|
||||
const clickedA = { type: 'Feature', properties: { name: 'A' }, geometry: { type: 'Point', coordinates: [75.2504, 12.8497] } }
|
||||
check('normalized rows (no geometry) index and match a clicked pin', colocatedWith(buildColocationIndex(drawn), clickedA).join() === 'B', colocatedWith(buildColocationIndex(drawn), clickedA))
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ if (!targets.length) {
|
|||
// The token to hand the partner page is the one the tree already bakes into its own leaves: this
|
||||
// gate must not invent a key, and a token that is not this tree's would 401 and look like our bug.
|
||||
// The tree bakes no token since the auto engine (the repo ships none), so every tk case SKIPPED and every
|
||||
// provider case went UNMEASURED: a hollow PASS (rega, ded4b3c1). A seat that has a real public token passes
|
||||
// it as TEST_MAPBOX_TOKEN (as rega's checks do); otherwise a baked one is still used if a tree has it.
|
||||
// provider case went UNMEASURED: a hollow PASS (measured at ded4b3c1). A seat that has a real public token passes
|
||||
// it as TEST_MAPBOX_TOKEN (as the browser checks do); otherwise a baked one is still used if a tree has it.
|
||||
const bakedToken = process.env.TEST_MAPBOX_TOKEN || (() => {
|
||||
for (const b of manifest.bundles || []) {
|
||||
for (const p of b.profiles || []) {
|
||||
|
|
@ -170,10 +170,10 @@ try {
|
|||
lines.push(` · ${t.element} [${c.knob}] SKIPPED — no baked token in this tree to hand the host`)
|
||||
continue
|
||||
}
|
||||
// The composite's OWN profile rides with the knob under test (rega, 1a761741: gospel-resources,
|
||||
// The composite's OWN profile rides with the knob under test (measured at 1a761741: gospel-resources,
|
||||
// my-upg-100-list, regions-dashboard and two more drew no map under a knob-only config, because a
|
||||
// multi-profile element needs to be told which profile is the composite). A knob still wins.
|
||||
// A composite that opens on a non-map view must be told to show its map (exp-shepherd: country-posters-mfe
|
||||
// A composite that opens on a non-map view must be told to show its map (country-posters-mfe
|
||||
// reads profile-config `view`), or there is no canvas to measure.
|
||||
const VIEW = { 'country-posters-mfe': { view: 'map' } }
|
||||
const cfg = JSON.stringify({ profile: t.profile, ...(VIEW[t.element] || {}), ...c.config(bakedToken) }).replace(/'/g, ''')
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
* ★ WHY IT NOW REBUILDS AND COMPARES BYTES, NOT MTIMES (2026-09-25). The first version compared
|
||||
* the newest child SOURCE mtime with the parent BUNDLE mtime. File times are not build facts:
|
||||
* a git merge or checkout rewrites sources with checkout-time mtimes, so rega's publish of
|
||||
* a git merge or checkout rewrites sources with checkout-time mtimes, so a publish of
|
||||
* beb13da3 stopped on "doxa-maps-spa / plugin-studio / stack-demo STALE vs gospel-resources /
|
||||
* research-dashboard" although a rebuild reproduced the committed bytes exactly — and two of
|
||||
* those parents mount their children BY TAG at runtime, so they compile none of the child in
|
||||
|
|
@ -61,7 +61,7 @@ const TREE = join(ROOT, 'public', TREE_NAME)
|
|||
const argv = process.argv.slice(2)
|
||||
const oi = argv.indexOf('--only')
|
||||
const ONLY = oi >= 0 && argv[oi + 1] ? new Set(argv[oi + 1].split(',')) : null
|
||||
// NOT ONLY COMPOSITES (rega, 2026-09-25): a library change merged into main reached prayer-walk-planner,
|
||||
// NOT ONLY COMPOSITES (measured 2026-09-25): a library change merged into main reached prayer-walk-planner,
|
||||
// which composes nothing, so this gate could not see it was stale. --all checks EVERY bundle; --bundles a,b
|
||||
// checks those (the landing precondition passes the ones a landing can have changed).
|
||||
const ALL = argv.includes('--all')
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
*
|
||||
* NOT A SUBSTITUTE FOR A BROWSER. Both ends existing is necessary, not sufficient: UPG-100's
|
||||
* select-zone listener exists and still loses the first click, because the lazy Map pane attaches it
|
||||
* too late (rega, 2026-09-26). The runtime half is check:gallery-embed's `linked` phase.
|
||||
* too late (measured 2026-09-26). The runtime half is check:gallery-embed's `linked` phase.
|
||||
*
|
||||
* NEGATIVE-TESTED (2026-09-26, main 521f8b18, PASS with 17 links and the 3 LATE_KNOWN sites), each FAILS:
|
||||
* a receiver renamed in source ('map-filtered' -> 'map-filter' in research-map-plus-grid.vue);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* `tk` to a baked-in child, at production stage. See the comment at the scan below.
|
||||
*
|
||||
* Source-level and headless BY DESIGN: the behavioural twin (check:composite-embed-knobs) needs a
|
||||
* browser and only rega may run one. Exit 0 pass · 1 fail.
|
||||
* browser, and this gate runs without one. Exit 0 pass · 1 fail.
|
||||
*/
|
||||
import { readFileSync, existsSync } from 'node:fs'
|
||||
import { resolve, dirname, join } from 'node:path'
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
* and Simple Research, both in the Research Gallery). Every structural gate passed. This gate runs
|
||||
* the thing that failed: the composite's own setup, and its mounted hooks.
|
||||
*
|
||||
* HOW. No browser (fleet policy: only rega launches one). Vite loads each composite .vue through
|
||||
* HOW. No browser (by design: this gate runs headless). Vite loads each composite .vue through
|
||||
* ssrLoadModule with the repo's alias and the same vue({ customElement: true }) plugin, and
|
||||
* @vue/runtime-core mounts it on a no-op renderer. The SSR compile gives the component an
|
||||
* ssrRender rather than a render, so the renderer draws nothing and no CHILD is set up: this
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
*
|
||||
* Nothing throws, because the t() shim falls back to its key. So it reads as "a few strings not
|
||||
* translated yet" and it survived in country-posters, key-cities, gospel-resources, cities-internet and
|
||||
* my-upg-100-list simultaneously — confirmed independently by regions-plugin, who censused all 19 entry
|
||||
* my-upg-100-list simultaneously — confirmed independently by a census of all 19 entry
|
||||
* files and found the same five and no sixth.
|
||||
*
|
||||
* ★ AND A CENSUS THAT COUNTED FUNCTION BODIES SAW FOUR OF SIXTEEN. That is why this gate greps for the
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* THE DEFECT (2026-09-28, found testing live): the link copied from Simple Research was
|
||||
* `research-map-plus-grid/research-map-plus-grid/index.html` while the page was
|
||||
* `http://127.0.0.1:5192/#f=…` — "the perfect example of how embeddability is not working".
|
||||
* `http://127.0.0.1:5192/#f=…`, a clear case of an embed that could not work.
|
||||
*
|
||||
* WHY IT SURVIVED SO LONG, and it is the reason this is a gate rather than a fix: a relative share link
|
||||
* WORKS WHEN CLICKED. The browser resolves it against the page you copied it from, so the person testing
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ const run = async () => {
|
|||
const f = __srcFeatures(m, 'rd-bubbles'); return !!(f && f.length > 0);
|
||||
})()`, { timeout: 90000 })
|
||||
} catch (e) {
|
||||
// ★ DISTINGUISH "I CANNOT MEASURE THIS ENGINE" FROM "THE PRODUCT IS BROKEN".
|
||||
// ★ DISTINGUISH "THIS ENGINE CANNOT BE MEASURED HERE" FROM "THE PRODUCT IS BROKEN".
|
||||
// This gate reads the source's CURRENT GeoJSON off `_data`, a private Mapbox internal. MEASURED
|
||||
// on one dashboard, one build, only the engine differing, by calling the app's own setData() to
|
||||
// shrink 2107 features to 5:
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs'
|
|||
import { join, relative, resolve, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { TREE_NAME } from './_tree-name.mjs'
|
||||
// ★ SHARED WITH check:hardcoded-english (regions-plugin). Two gates must agree about WHICH files are
|
||||
// ★ SHARED WITH check:hardcoded-english (the same file list). Two gates must agree about WHICH files are
|
||||
// in scope even when they disagree about what they find in them; a second copy would drift on exactly
|
||||
// the pair-form / transitive / cycle details below, and the drift would be silent.
|
||||
import { effectiveStages, stageReason } from './lib/effective-stage.mjs'
|
||||
|
|
@ -73,7 +73,7 @@ function findFrozen(ast, aliases) {
|
|||
if (name && (TRANSLATORS.has(name) || aliases.has(name))) {
|
||||
// tStatic(path, EXPLICIT_LOCALE) — the caller pinned it deliberately.
|
||||
const pinned = name === 'tStatic' && node.arguments.length > 1
|
||||
// ★ tStatic IS NEVER LIVE, WHEREVER IT SITS (exp, 2026-09-28). It resolves the locale via
|
||||
// ★ tStatic IS NEVER LIVE, WHEREVER IT SITS (2026-09-28). It resolves the locale via
|
||||
// getRuntimeLocale(), which reads a PLAIN window property — not a Vue ref — so a computed()
|
||||
// wrapping it has NO reactive dependency and never invalidates. computed(() => tStatic(x))
|
||||
// is strictly WORSE than the naked call: it looks like the fix, so nobody looks again.
|
||||
|
|
@ -153,7 +153,7 @@ const DEAD_LOCALE_GETTER = /\b(getRuntimeLocale|detectLocale|localeFromUrl)\s*\(
|
|||
/**
|
||||
* Is offset `at` inside the parentheses of a computed()/watch()/watchEffect() that tracks the locale?
|
||||
*
|
||||
* ⚠ BRACE DEPTH, NOT A LOOKBACK WINDOW (gospel, GOS-FROZEN-SR). The first version of this asked
|
||||
* ⚠ BRACE DEPTH, NOT A LOOKBACK WINDOW (GOS-FROZEN-SR). The first version of this asked
|
||||
* whether a wrapper appeared in the preceding 260 characters. gospel hit exactly this in GiDrawer.vue
|
||||
* — the enclosing `computed(` opens at line 35 and the call sites are at 95-100 — and reported SIX
|
||||
* false positives on working code, nearly "fixing" it. Measured on the same shape here: 2,600
|
||||
|
|
@ -206,7 +206,7 @@ function findStoredTreeFreeze(code) {
|
|||
// function RETURNS A STRUCTURE whose values come from the translator — an options object or a
|
||||
// node list — which a caller then stores. So require the translator call to sit inside a
|
||||
// returned object/array literal, not merely somewhere in the body.
|
||||
// ★ THE MECHANISM IS "BUILT CORRECTLY, THEN PARKED", not "built once at setup" (gospel, on
|
||||
// ★ THE MECHANISM IS "BUILT CORRECTLY, THEN PARKED", not "built once at setup" (found on
|
||||
// upg100's legendOpts). That function re-reads t() correctly on EVERY call — its own comment
|
||||
// says the function shape is deliberate — and the freeze is one level out: the RESULT is
|
||||
// assigned into a ref and nothing re-fills it. A rule that only looked for a translator outside
|
||||
|
|
@ -282,7 +282,7 @@ function findDeadGetterComputed(code) {
|
|||
}
|
||||
|
||||
/**
|
||||
* SHAPE 3 — labels evaluated inside a provide() literal (gospel, GOS-FROZEN-SR; real in GiCombos.vue).
|
||||
* SHAPE 3 — labels evaluated inside a provide() literal (GOS-FROZEN-SR; real in GiCombos.vue).
|
||||
*
|
||||
* provide('dashboardConfig', { facets: { access_level: { label: T('…') } } })
|
||||
*
|
||||
|
|
@ -388,7 +388,7 @@ const CASES = [
|
|||
['GOOD inside an arrow', () => scanSource("const { t } = useI18n()\nconst f = () => t('a.b')").length, 0],
|
||||
['GOOD tStatic with explicit locale', () => scanSource("const x = tStatic('a.b', 'en')").length, 0],
|
||||
['GOOD watch(() => t())', () => scanSource("const { t } = useI18n()\nwatch(src, () => t('a.b'))").length, 0],
|
||||
// ★ exp's false negative: a computed cannot make tStatic live.
|
||||
// ★ A known false negative: a computed cannot make tStatic live.
|
||||
['BAD computed(() => tStatic()) is STILL frozen', () => scanSource("const X = computed(() => tStatic('a.b'))").length, 1],
|
||||
// A function BODY re-reads the global on every call (useOptionalT:74 returns such an arrow),
|
||||
// so it is NOT frozen. Only a reactive wrapper caches it. I had this case backwards at first.
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ try {
|
|||
the data was right and the feature was dead. */
|
||||
/* ⚠ THE NAME, CASE-FOLDED, ANYWHERE IN THE CARD. This asserted `text.includes(slug.split('-')[0])`
|
||||
— "abai" against a rendered "Abai Sungai" — and reported a false negative on a card that was
|
||||
rendering correctly, which cost rega a round. A slug fragment is not the name; the roster has
|
||||
rendering correctly, which cost a review round. A slug fragment is not the name; the roster has
|
||||
the name, so the roster is what it compares. */
|
||||
const anyRow = (JSON.parse(readFileSync(resolve(PUBLIC, TREE_NAME, 'assets/tables/doxa-people-groups.json'), 'utf8')).rows || [])
|
||||
.find((r) => r.slug && r.mapped)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* check-gospel-engine-contract.mjs — the map must use the engine it was ASKED for, or say nothing
|
||||
* at all. Never a different one.
|
||||
*
|
||||
* THE DEFECT THIS IS WRITTEN AGAINST (regions' C3 read + upg100's addendum, 2026-09-26).
|
||||
* THE DEFECT THIS IS WRITTEN AGAINST (the C3 review and its addendum, 2026-09-26).
|
||||
* resources-map resolved its engine as `engineGlobal(provider) || window.mapboxgl`. engineGlobal
|
||||
* already defaults to mapbox, so that fallback could only fire for provider 'maplibre' — and then
|
||||
* it returned MAPBOX. A page that chose the keyless engine silently got the one that needs a
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* check-gospel-english-leaks.mjs — a translated key must not render in English.
|
||||
*
|
||||
* THE METHOD, from rega by way of dx-shepherd. A string is a LEAK when the catalogue has a
|
||||
* THE METHOD, taken from the browser review. A string is a LEAK when the catalogue has a
|
||||
* DIFFERENT value for the locale and the page still shows the English one. That is a render
|
||||
* or wiring fault, and it is a different thing from an untranslated string, which is a
|
||||
* catalogue gap. Only the first is this check's business.
|
||||
|
|
@ -75,7 +75,7 @@ try {
|
|||
/* ═══ WHOLE LABELS, NOT SUBSTRINGS — the third correction, and the last ═══════════
|
||||
* Substring matching over the rendered blob reported keys that were never rendered at
|
||||
* all: "Language" matched inside the DATA — the people-group language "Sign Language" —
|
||||
* and "Region" inside a region name. Those are exactly the data strings rega's method
|
||||
* and "Region" inside a region name. Those are exactly the data strings the method
|
||||
* excludes, and no amount of length filtering separates a label from a word that
|
||||
* happens to sit inside one.
|
||||
* So the unit is an ELEMENT'S OWN LABEL: the trimmed text a leaf element renders. A
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import { fileURLToPath } from 'node:url'
|
|||
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const PORT = Number(process.env.RTL_SHAPE_PORT || 5393)
|
||||
const POISON = process.argv.includes('--poison')
|
||||
// ⚠ PARAMETERISED, not forked. dx-shepherd routed this gate to the other RAW-map owners
|
||||
// ⚠ PARAMETERISED, not forked. This gate was routed to the other RAW-map owners
|
||||
// (cities-internet, key-cities, upg-100-list, RegionCountryMap) — copying it would give each of
|
||||
// them their own drifting copy of the pan-first logic and the poison arm, which are the two parts
|
||||
// that took corrections to get right. The leaf is the only thing that differs.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* to zoom out past the point where ONE WORLD fills the canvas WIDTH. That puts a hard floor under the
|
||||
* zoom at log2(canvasWidth/512) — and on a WIDE, SHORT figure that floor is too close for the
|
||||
* drawing's own height, so the outermost groups fall outside the frame. minZoom does not help; the
|
||||
* width constraint wins. rega measured it at 1440: 54 groups outside in ar and 97 in en, which is
|
||||
* width constraint wins. A browser check measured it at 1440: 54 groups outside in ar and 97 in en, which is
|
||||
* what proved it was the WIDTH and never RTL.
|
||||
*
|
||||
* WHAT IT ASSERTS. For every layout the charts actually get, the drawing's vertical extent at the
|
||||
|
|
@ -45,11 +45,11 @@ export function neededHeightPx(extent, fraction, canvasWidth) {
|
|||
return worldFraction * 512 * Math.pow(2, floorZoom(canvasWidth))
|
||||
}
|
||||
|
||||
// The canvases the charts are actually given: rega's measured figures at 1440 and 1280, the embed
|
||||
// The canvases the charts are actually given: the measured figures at 1440 and 1280, the embed
|
||||
// card, and two narrow ones so a phone cannot regress unnoticed.
|
||||
const LAYOUTS = [
|
||||
{ name: '1440 board (rega measured)', w: 796, h: 249 },
|
||||
{ name: '1280 board (rega measured)', w: 636, h: 220 },
|
||||
{ name: '1440 board (measured)', w: 796, h: 249 },
|
||||
{ name: '1280 board (measured)', w: 636, h: 220 },
|
||||
{ name: 'embed card', w: 1198, h: 560 },
|
||||
{ name: 'tablet', w: 380, h: 300 },
|
||||
{ name: 'phone', w: 340, h: 240 },
|
||||
|
|
@ -77,13 +77,13 @@ for (const chart of CHARTS) {
|
|||
}
|
||||
|
||||
// ★ NEGATIVE CONTROL. The 0.17 default is the value that was measured FAILING on the page, so if
|
||||
// this arm does not fail the calculation is not measuring what rega measured and a pass means
|
||||
// this arm does not fail the calculation is not measuring what the browser measured and a pass means
|
||||
// nothing. Asserted on the tightest real layout.
|
||||
const poison = neededHeightPx(CENTERED_EXTENT, 0.17, 796)
|
||||
ok(
|
||||
'NEG CONTROL: the old 0.17 fraction still does NOT fit 796x249',
|
||||
poison > 249 - 2 * FIT_PADDING,
|
||||
`0.17 needs ${poison.toFixed(0)}px of ${249 - 2 * FIT_PADDING}px — the defect rega measured`,
|
||||
`0.17 needs ${poison.toFixed(0)}px of ${249 - 2 * FIT_PADDING}px — the measured defect`,
|
||||
)
|
||||
|
||||
// The two charts must share one footprint, or the same population reads as a different size when a
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
/**
|
||||
* check-grid-image-loading — the people-group cards must not fetch 24 photos during boot.
|
||||
*
|
||||
* THE MEASUREMENT (rega, SR-LOAD on 21ebb4f26): a cold load of Simple Research downloaded 24
|
||||
* THE MEASUREMENT (SR-LOAD on 21ebb4f26): a cold load of Simple Research downloaded 24
|
||||
* people-group photos, 5.3 MB, DURING BOOT — competing with the map engine and the API data on the
|
||||
* same connection. Nothing was wrong with any single image; there was simply no instruction about
|
||||
* WHEN to fetch them, so the browser fetched them all at once.
|
||||
*
|
||||
* ★ WHY A GATE AND NOT JUST THE FIX. This component is being MERGED with the regions list right now
|
||||
* (a settled decision, regions-plugin building it), and a merge rewrites markup. Four attributes on
|
||||
* (a settled decision, built by the regions plugin), and a merge rewrites markup. Four attributes on
|
||||
* one <img> are exactly the kind of thing that survives a review and not a rewrite — and losing them
|
||||
* is invisible: the page still works, it just costs 5.3 MB again on every cold load.
|
||||
*
|
||||
|
|
@ -36,7 +36,7 @@ if (!m) {
|
|||
const tag = m[0]
|
||||
if (!/:loading=/.test(tag)) {
|
||||
fails.push('the card image has no loading attribute, so every photo is fetched during boot — '
|
||||
+ 'rega measured 24 of them, 5.3 MB, competing with the map and the API data.')
|
||||
+ 'a cold load measured 24 of them, 5.3 MB, competing with the map and the API data.')
|
||||
}
|
||||
if (!/decoding="async"/.test(tag)) fails.push('the card image does not decode off the main thread (decoding="async").')
|
||||
if (!/\bwidth=/.test(tag) || !/\bheight=/.test(tag)) {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
* by whether the lookup it guards actually works. `msg !== 'messages.engineMissing' ? msg : 'English'`
|
||||
* is treated as a fallback — but if the key is looked up with the wrong prefix, the lookup ALWAYS
|
||||
* misses and the English arm becomes the NORMAL path, in every locale, while this gate stays quiet.
|
||||
* That is exactly what exp-shepherd found in cities-internet after I triaged the same line as "not a
|
||||
* leak". A hardcoded-English scan cannot see a misconfigured lookup; check:i18n-keys-exist and a
|
||||
* That is exactly what a later review found in cities-internet after the same line had been triaged as
|
||||
* "not a leak". A hardcoded-English scan cannot see a misconfigured lookup; check:i18n-keys-exist and a
|
||||
* locale render are what catch that. Treat a guarded fallback as "not a leak HERE", never as "this
|
||||
* string is not reaching users".
|
||||
*
|
||||
|
|
@ -59,7 +59,7 @@ const ALLOW = [
|
|||
{ why: 'HTML fragments: these plugins build popup markup in template literals, so a quasi is often '
|
||||
+ 'a tag, or the seam between two attributes ("\" alt=\"" / "\" loading=\"lazy\">")',
|
||||
test: (s) => /<\/?[a-zA-Z][^>]*>?/.test(s)
|
||||
// dir and lang join the list (exp, END-EXP-SR-DIRLANG): `'" dir="'` is the seam between two
|
||||
// dir and lang join the list (SR-DIRLANG): `'" dir="'` is the seam between two
|
||||
// attributes in a print page assembled by concatenation, and every RTL-aware page writes both.
|
||||
// They are the same class as class= and href= — attribute NAMES, not text a reader sees.
|
||||
|| /\b(class|href|src|alt|loading|width|height|style|id|target|rel|dir|lang)\s*=/.test(s)
|
||||
|
|
@ -91,7 +91,7 @@ const ALLOW = [
|
|||
test: (s) => /^[a-z-]+\($/.test(s)
|
||||
|| /^[,)\s]*[a-z-]+\([^)]*\)[,)\s]*$/.test(s)
|
||||
|| /^[,)\s]+$/.test(s) },
|
||||
// ★ DECLARATION SEAMS, the other half of the same split (exp, I18N-EXP-PLAN). Splitting
|
||||
// ★ DECLARATION SEAMS, the other half of the same split (I18N-EXP-PLAN). Splitting
|
||||
// `width:${w}px;height:${h}px` leaves the quasi "px;height:" — a seam BETWEEN two declarations,
|
||||
// carrying the tail of one value and the head of the next property. It has a colon but no value
|
||||
// and no brace, so every CSS shape above misses it. exp measured these as false leaks in
|
||||
|
|
@ -351,7 +351,7 @@ function isDataComparison(node, parent) {
|
|||
// resource not found means NOT FOUND in the pools checked" is a sentence that happens to be used as
|
||||
// a key, and that is a real leak — gospel found twelve defects hiding in exactly that kind of
|
||||
// already-classified bucket. Anything with sentence punctuation stays loud whatever its value is.
|
||||
// ★ REGION IDENTITIES, EXEMPT ONLY WHILE THEY ARE TRANSLATABLE (studio's judgement, R26).
|
||||
// ★ REGION IDENTITIES, EXEMPT ONLY WHILE THEY ARE TRANSLATABLE (R26).
|
||||
// legend-tree's REGION_OF maps a zone slug to a region NAME, and that name is an identity: node ids
|
||||
// derive from it, and every surface that shows one translates it at render through REGION_KEY —
|
||||
// upg-100-list.vue:440 `REGION_KEY[english] ? t(\`poster.${…}\`) : english`, poster-wall.vue:129 the
|
||||
|
|
@ -1009,7 +1009,7 @@ const RENDERED = { africa: 'A sentence the reader actually sees here', asia: 'An
|
|||
// names, values that are prose a reader sees: the keys must STILL count, because this is a
|
||||
// label table, not a join table. Without this case the allData guard can be removed and every
|
||||
// test still passes — measured by poisoning it.
|
||||
// ★ REGION IDENTITIES (studio, R26): exempt ONLY while REGION_KEY names them. A region added
|
||||
// ★ REGION IDENTITIES (R26): exempt ONLY while REGION_KEY names them. A region added
|
||||
// without a key falls through `|| english` and renders English in eleven locales — the defect
|
||||
// upg100 already shipped once with Americas and Europe. The conditional IS the rule.
|
||||
{
|
||||
|
|
@ -1068,7 +1068,7 @@ const a = greeting + 'Welcome to the prayer map'
|
|||
</script>`
|
||||
ok(scanSfc(CAT, 'concat.vue').some((f) => f.text === 'Welcome to the prayer map'),
|
||||
'COUNTS a sentence built by CONCATENATION — only an equality test means "compared against data"')
|
||||
// ★ exp's CSS DECLARATION SEAMS (I18N-EXP-PLAN), tested on the SHAPE rather than through a fixture.
|
||||
// ★ CSS DECLARATION SEAMS (I18N-EXP-PLAN), tested on the SHAPE rather than through a fixture.
|
||||
// A seam like "px;height:" only exists as a separate string if a quasi is judged alone, and this
|
||||
// gate deliberately judges a split template literal as ONE string — so a .vue fixture can never
|
||||
// produce one, and an assertion written that way passes whether or not the rule exists. I wrote
|
||||
|
|
@ -1081,7 +1081,7 @@ const a = greeting + 'Welcome to the prayer map'
|
|||
'prose ending in a colon is NOT — the seam shape needs a semicolon-separated declaration')
|
||||
ok(!allowedBy('Pools checked; nothing found:'),
|
||||
'prose with a semicolon AND a colon is NOT — the segments must be property:value pairs')
|
||||
// ★ exp's HTML ATTRIBUTE SEAM (END-EXP-SR-DIRLANG). `'<html lang="' + l + '" dir="' + d + '">'`
|
||||
// ★ HTML ATTRIBUTE SEAM (SR-DIRLANG). `'<html lang="' + l + '" dir="' + d + '">'`
|
||||
// leaves the quasi `" dir="`, an attribute seam rather than a declaration seam. dir and lang were
|
||||
// the only standard attributes missing from the HTML shape. Asserted on the shape for the same
|
||||
// reason as the CSS seam: the gate judges a split literal as ONE string, so no fixture reaches it.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* check-instance-config-keys.mjs — a preset's profile-config keys must be keys the profile READS.
|
||||
*
|
||||
* ★ THE DEFECT (rega RQ20): people-groups-grid's "driven" preset declares "show-search":"false" and
|
||||
* ★ THE DEFECT (RQ20): people-groups-grid's "driven" preset declares "show-search":"false" and
|
||||
* "show-filters":"false", and the page renders the search box and the filters bar anyway. Nothing
|
||||
* errored — 0 console errors — because nothing was wrong at runtime. The key simply never reached
|
||||
* the component:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* check-leaf-engine-per-provider — a leaf loads the engine its PROVIDER asks for, and no other.
|
||||
*
|
||||
* THE BUG (card BUG-LEAF-PAGES-PRELOAD-MAPBOX-EVEN-UNDER-MAPLIBRE; measured by exp-shepherd at
|
||||
* THE BUG (card BUG-LEAF-PAGES-PRELOAD-MAPBOX-EVEN-UNDER-MAPLIBRE; measured at
|
||||
* 577149af). generate-tree chose a leaf's engine peer at BUILD time, from the instance config, and
|
||||
* baked it into <head> as static tags: mapbox-gl.css, the geocoder css, mapbox-gl.js and the geocoder
|
||||
* js, all from api.mapbox.com. The provider is chosen at RUNTIME (resolveMapProvider:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* check-leaf-english-leaks — a translated key must not render in English, on ANY leaf.
|
||||
*
|
||||
* THE METHOD is rega's, by way of dx-shepherd, and is already proven in
|
||||
* THE METHOD comes from the browser review and is already proven in
|
||||
* check-gospel-english-leaks.mjs. A string is a LEAK when the catalogue has a DIFFERENT value
|
||||
* for the locale and the page still shows the English one. That is a render or wiring fault,
|
||||
* and it is a different thing from an untranslated string, which is a catalogue gap.
|
||||
|
|
@ -145,7 +145,7 @@ for (const t of TARGETS) {
|
|||
// {value:'unengaged', label:'Unengaged'}, 2 distinct values, 100% populated, and
|
||||
// dashboard.config.js:132 counts 2,081 Unengaged / 27 Engaged. They are API VALUES
|
||||
// that happen to equal a catalogue string.
|
||||
// That is the population rega's method excludes by name ("DATA, the people-group and
|
||||
// That is the population the method excludes by name ("DATA, the people-group and
|
||||
// place names that come from the publishers"). Whole-label matching stops a substring
|
||||
// impersonating a label; it cannot stop a DATA CELL rendering the same text. So the
|
||||
// table body is excluded by ROLE, the way prose already is.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
* fmtCount }. There is no `rows`. Two plugins independently read `legend.rows` anyway, and because
|
||||
* JavaScript answers `undefined` rather than complaining, each failure wore a different costume:
|
||||
*
|
||||
* - countries-map: Export poster THREW (exp-shepherd's NE-17, fixed in d6916e05e)
|
||||
* - countries-map: Export poster THREW (NE-17, fixed in d6916e05e)
|
||||
* - research-map: provide('legendRows', legend.rows) provided undefined; the poster fallback
|
||||
* `legend?.rows?.value || []` could only ever be []; and the packet's legend slot was
|
||||
* `rows: legend?.rows?.value || []` with no second source, so that poster printed NO legend at
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* WHY: the shared legend (.stl-panel, its reopen button, the detail buttons, the tree-guide hairlines) used
|
||||
* `left: 8px`. MapToolbar uses `inset-inline-end`, which mirrors under dir="rtl"; a physical `left` does not.
|
||||
* So in Arabic the controls moved left onto a legend that stayed left, on three production maps at once
|
||||
* (Simple Research, Prayer Progress, UPG-100; rega's survey at 52eeb0db). The fix is inset-inline-start /
|
||||
* (Simple Research, Prayer Progress, UPG-100; a browser survey at 52eeb0db). The fix is inset-inline-start /
|
||||
* inset-inline-end; this gate keeps a physical left/right from coming back.
|
||||
*
|
||||
* WHAT IT READS: every CSS declaration in library/components/legends/*.vue (comments stripped). A
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
*
|
||||
* ★ BUT showsFlyTools() DESCRIBES THE LEGEND TYPE, NOT WHETHER THE TOOLBAR EXISTS. Fly + Clusters are
|
||||
* leaf-only: the composite — which is what a reader calls "Simple Research" — passes legendTools:false,
|
||||
* so the toolbar is never drawn there and the 56px reserved a slot for nothing. rega measured it at
|
||||
* so the toolbar is never drawn there and the 56px reserved a slot for nothing. A browser check measured it at
|
||||
* 1440x900 on main e1d0bc20: the band from the map's top edge (y 44) to the legend card (y 100) is 56px
|
||||
* of empty map on both tabs, no toolbar anywhere in the strip.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@ const MISSING = [
|
|||
'asia-china-xinjiang-uyghur-autonomous-region',
|
||||
'asia-india-bihar',
|
||||
]
|
||||
// asia-india-madhya-pradesh WAS here and is now FILED. upg100 hit this arm while filing it, and
|
||||
// did the right thing with it: they reported the red instead of editing my expectation to make
|
||||
// their change green — "editing someone else's pinned expectation to make my own change green is
|
||||
// precisely the move that hollows out a guard". dx-shepherd then ruled that their data and this
|
||||
// fixture land TOGETHER, which is the only ordering where neither of us is red in between.
|
||||
// asia-india-madhya-pradesh WAS here and is now FILED. The filing change hit this arm, and the
|
||||
// red was reported instead of the pinned expectation being edited to turn the change green: editing
|
||||
// another owner's pinned expectation to make one's own change green is precisely the move that hollows
|
||||
// out a guard. The data and this fixture landed TOGETHER, the only ordering where neither side is red
|
||||
// in between.
|
||||
|
||||
|
||||
ok(leavesOf(TREE[0]).map((l) => l.id).join(',') === 'z1,z2,z3', 'leavesOf walks NESTED children, not one level')
|
||||
|
|
@ -85,7 +85,7 @@ const naive = TREE // what a region-grouped tree gives you, unaugmented
|
|||
ok(!zoneIdsIn(naive).has('asia-china-xinjiang-uyghur-autonomous-region'),
|
||||
'NEG CONTROL: the unaugmented tree really does omit xinjiang, so the bucket is not decoration')
|
||||
|
||||
// ── a region sweep is NOT a zone sweep (gospel, END-GOS-VLG2) ───────────────────────────────────
|
||||
// ── a region sweep is NOT a zone sweep (gospel-resources) ───────────────────────────────────
|
||||
// ★ The consequence of the bucket that neither of us should leave implicit: ticking every REGION
|
||||
// still does not select every ZONE, because the unfiled zones have no region BY DEFINITION.
|
||||
// Nothing on screen would say so — the reader just gets a smaller total, which is the exact
|
||||
|
|
@ -113,7 +113,7 @@ ok(selectedId(leavesOf(EMPTYZONE[0])[0]) === 'z9', 'and it still emits its own i
|
|||
ok(withUnassigned(EMPTYZONE, ['z9']).length === EMPTYZONE.length,
|
||||
'presence is by ID, not by member count, so an unresolvable zone is not ALSO dumped in the bucket')
|
||||
|
||||
// ── the gap is REAL TODAY, not just real in my fixture (gospel, END-GOS-VLG3) ───────────────────
|
||||
// ── the gap is REAL TODAY, not just real in a fixture (gospel-resources) ───────────────────
|
||||
// ★ EVERY ASSERTION ABOVE RUNS AGAINST A FIXTURE. That proves the MODULE behaves, and it proves the
|
||||
// fixture models a gap — it does not prove the gap still exists in the data we ship. So the negative
|
||||
// control above could stay green forever while the bucket quietly became dead code, or while a FIFTH
|
||||
|
|
@ -148,7 +148,7 @@ ok(realGap.join(',') === MISSING.join(','),
|
|||
realGap.join(',') === MISSING.join(',')
|
||||
? 'and it is exactly the four this check names, so the fixture above models the shipped data rather than a story about it'
|
||||
: `THE GAP MOVED — re-derive. shipped now: [${realGap.join(', ')}] but this check asserts: [${MISSING.join(', ')}]. A zone ADDED here is groups that just became unreachable; a zone REMOVED got filed and the fixture is stale. Either way the numbers in the commit body are no longer true.`)
|
||||
// ── the zones that got FILED stay filed (dx-shepherd RG12) ─────────────────────────────────────
|
||||
// ── the zones that got FILED stay filed (RG12) ─────────────────────────────────────
|
||||
// The gap arms watch the BAD direction. Filing is the good one, and it is exactly as revertible:
|
||||
// drop a key from zone-regions and those groups leave the region tree again, silently, with the
|
||||
// bucket the only thing still carrying them. Two of these three were never visible to the gap arms
|
||||
|
|
@ -163,7 +163,7 @@ for (const z of FILED) {
|
|||
ok(joinable.has('asia-china-xinjiang-uyghur-autonomous-region') && !filed.has('asia-china-xinjiang-uyghur-autonomous-region'),
|
||||
'xinjiang specifically: joinable in admin-to-list, absent from zone-regions — its 100 groups are reachable ONLY through the bucket')
|
||||
|
||||
// ── the id ambiguity that is masked by a data coincidence (gospel, END-GOS-VLGC) ────────────────
|
||||
// ── the id ambiguity that is masked by a data coincidence (gospel-resources) ────────────────
|
||||
// ★ REGION IDS AND ZONE IDS SHARE ONE NAMESPACE. selectedId emits one bare string with no kind, and
|
||||
// the two sets OVERLAP in the shipped data. gospel found it while wiring and I re-measured it here
|
||||
// rather than taking the report: 33 zone ids, 7 region ids, intersection exactly {europe}, whose
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* check-map-attribution — the credit line names the basemap of the engine that actually drew the map.
|
||||
*
|
||||
* WHY (licence credit, rega's row 28 at ccc2b1bb): addMapAttribution always credited "Mapbox ·
|
||||
* WHY (licence credit, row 28 at ccc2b1bb): addMapAttribution always credited "Mapbox ·
|
||||
* © OpenStreetMap". Under MapLibre the tiles are OpenFreeMap's (OpenMapTiles on OpenStreetMap), so
|
||||
* gospel-resources, key-cities and cities-internet credited Mapbox, which served nothing, and omitted
|
||||
* the OpenMapTiles credit. Headless: the real module against stand-in map classes and a minimal DOM.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* check-map-unmount-guard — the fast, browser-free half of the unmount-race proof (by gospel-plugin,
|
||||
/* check-map-unmount-guard — the fast, browser-free half of the unmount-race proof (by the gospel-resources owner,
|
||||
adopted into internal/ by the studio lane; the end-to-end half is check-map-unmount-mid-init.mjs).
|
||||
|
||||
Proves the guard by REPRODUCING the race against the real file: take the shipped source,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* (f) ProfileLoader stops mounting the notice, or the rule stops staying quiet inside the Gallery;
|
||||
* (g) a flagged profile's element is mounted by neither ProfileLoader nor its own useScreenGate —
|
||||
* dashboard-plus-grid defines its element without ProfileLoader, so its leaf carried
|
||||
* "desktop-only" and mounted the map on a phone anyway (rega, 390px).
|
||||
* "desktop-only" and mounted the map on a phone anyway (measured at 390px).
|
||||
* `--self-test` plants one bad case per rule and proves each can fail before a pass is trusted.
|
||||
*/
|
||||
import { readFileSync, existsSync, readdirSync } from 'node:fs'
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* check-no-credentials-omit.mjs — no data fetch in library/ or plugin-designs/ may use credentials:'omit'.
|
||||
*
|
||||
* WHY (dx-shepherd, 2026-09-27): behind any login gate (basic auth, a session cookie, OIDC) the Research
|
||||
* WHY (2026-09-27): behind any login gate (basic auth, a session cookie, OIDC) the Research
|
||||
* Gallery said "Could not load Big Picture", because doxa-maps-spa fetched its SAME-ORIGIN manifest with
|
||||
* credentials:'omit', so the gate's cookie never went and the request was refused. 'same-origin' (the fetch
|
||||
* default) sends credentials only to the page's own origin: a cross-origin CDN or token service still
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* check-no-silent-engine-substitution — a profile must never fall back to a DIFFERENT map engine than
|
||||
* the one its provider asked for.
|
||||
*
|
||||
* THE DEFECT, found by regions' C3 read and routed by dx-shepherd (END-SHEP-C3C, 2026-09-26):
|
||||
* THE DEFECT, found by the C3 review (2026-09-26):
|
||||
*
|
||||
* const gl = engineGlobal(provider) || window.mapboxgl
|
||||
*
|
||||
|
|
@ -72,7 +72,7 @@ function scan(text) {
|
|||
// documented what they removed in a /* */ block whose second line begins with a BACKTICK:
|
||||
// `engineGlobal(grProvider) || window.mapboxgl`. engineGlobal already defaults to mapbox, so
|
||||
// The prefix test saw no comment marker, matched the quoted pattern, and reported gospel as the last
|
||||
// remaining offender at main 9df086e5. I relayed that to dx-shepherd as fact and it was wrong: the
|
||||
// remaining offender at main 9df086e5. That was relayed as fact and it was wrong: the
|
||||
// line number had also moved three times (1490 -> 1505 -> 1509) purely because their file grew, which
|
||||
// is what made a stale card look like a live defect.
|
||||
// ★ A GATE THAT FAILS ON THE EXPLANATION OF A FIX IS WORSE THAN NO GATE. It tells the one person who
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
* (2) is the half that matters over time: a fixed shell plus a plugin that adds .foo{min-height:700px}
|
||||
* next month is the same bug again, and nobody would connect it to this.
|
||||
*
|
||||
* Source-level and headless BY DESIGN. Only rega runs a browser here, and the browser proof is rega's
|
||||
* Source-level and headless BY DESIGN. This gate runs no browser, and the browser proof is a separate
|
||||
* scroll-container count. This is the cheap guard that keeps the class from coming back between runs.
|
||||
* ★ THIS GATE IS RED ON PURPOSE AT LANDING, and is NOT wired into gates:pre yet. gospel-internet's
|
||||
* .gb still carries min-height:640px; that fix belongs to its owner, not to me, and wiring a red gate
|
||||
|
|
@ -103,7 +103,7 @@ for (const bundle of readdirSync(DESIGNS)) {
|
|||
//
|
||||
// ★ THIS IS GATED BECAUSE IT WAS ALREADY PORTED ONCE AND ARRIVED SHORT. doxa-maps-spa's .dms-pane was
|
||||
// copied from VerticalTabsLayout's .vtl-host -- its own comment says "porting the same proven shape" --
|
||||
// and took the first two lines. rega measured the result: 12 of 16 gallery tabs overflowing by exactly
|
||||
// and took the first two lines. A browser check measured the result: 12 of 16 gallery tabs overflowing by exactly
|
||||
// the DX-life header height, on plugins with no floor of their own. Two thirds of a fix reads as a
|
||||
// whole one in review, which is precisely why a reviewer cannot be the check.
|
||||
for (const [file, label] of [
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env node
|
||||
/* check-optional-t-equivalence.mjs — `bun run check:optional-t-equivalence`. Source-only, headless.
|
||||
EVERY LATER C4 WAVE EXTENDS THIS FILE (dx-shepherd, REGC4G): a wave that migrates a site without
|
||||
EVERY LATER C4 WAVE EXTENDS THIS FILE (REGC4G): a wave that migrates a site without
|
||||
adding its row here is a wave whose behaviour nobody re-checks. Sections 1-6 are the helper's own
|
||||
contract; section 7 is the per-site register. */
|
||||
// C4: does useOptionalT() behave like the twenty hand-written guarded translators it replaces?
|
||||
|
|
@ -122,11 +122,11 @@ const SITES = [
|
|||
['library/components/hints/PinHint.vue', 'useOptionalI18n', 'PINHINT_FALLBACK[key]'],
|
||||
['plugin-designs/pplr-data-maps/src/composables/usePplrT.js', 'useOptionalT', null],
|
||||
['plugin-designs/upg-neighbor/src/composables/useNeighborT.js', 'useOptionalT', null],
|
||||
// wave 3a — gospel-resources (owner: gospel-plugin). All four fell back to enLookup, i.e. the
|
||||
// wave 3a — gospel-resources. All four fell back to enLookup, i.e. the
|
||||
// SHIPPED ENGLISH, not the locale-aware catalogue; each passes that enLookup in, so a bare host
|
||||
// still renders English. Switching them to the catalogue default would make a bare host honour
|
||||
// ?lang=ar — a real improvement, and gospel-plugin's to make, not this migration's.
|
||||
// ★ gospel-plugin CHOSE the locale-honouring catalogue fallback (2026-09-26) rather than keeping
|
||||
// ?lang=ar — a real improvement, and its owner's to make, not this migration's.
|
||||
// ★ gospel-resources' owner CHOSE the locale-honouring catalogue fallback (2026-09-26) rather than keeping
|
||||
// enLookup's English: "most partners will drop a custom element or an iframe and never install
|
||||
// vue-i18n ... an Arabic ministry site embedding this map serves its readers English while the
|
||||
// bundle already carries all 11 catalogues. That is a bug, not a decision." So these four take NO
|
||||
|
|
@ -143,13 +143,13 @@ const SITES = [
|
|||
// wave 3b — cities-internet. All three were byte-identical in the guard block; each keeps its own
|
||||
// enLookup fallback, so a bare host renders the same English. Their local fill() used `k in params`,
|
||||
// so the shared fillParams also removes a way for them to print the literal "null".
|
||||
// ★ exp-shepherd, as cities-internet's owner, took the locale-honouring default (2026-09-26): "the
|
||||
// bundle already carries all 11 catalogues, so a bare host getting English would be a bug". So these
|
||||
// ★ cities-internet's owner took the locale-honouring default (2026-09-26): the bundle already
|
||||
// carries all 11 catalogues, so a bare host getting English would be a bug. So these
|
||||
// three pass NO fallback, and their English-only enLookup + per-area catalogue import are deleted.
|
||||
['plugin-designs/cities-internet/connectivity-list.vue', 'useOptionalT', null],
|
||||
['plugin-designs/cities-internet/connectivity-map.vue', 'useOptionalT', null],
|
||||
['plugin-designs/cities-internet/data-tables.vue', 'useOptionalT', null],
|
||||
// wave 3d — all-people-groups. Treated as UNOWNED (studio agreed), so the conservative reading wins:
|
||||
// wave 3d — all-people-groups. Treated as UNOWNED, so the conservative reading wins:
|
||||
// its inline EN map stays the fallback rather than switching to the catalogue, because nobody is
|
||||
// available to decide that this bundle should start honouring the locale on a bare host -- THEN
|
||||
// the locale-honouring fallback was RULED for everywhere (2026-09-27; the goal: a bare-host
|
||||
|
|
@ -162,11 +162,11 @@ const SITES = [
|
|||
// the inline EN map. Taking a SITES array wholesale from another branch re-asserts ITS view of every
|
||||
// file in it, including the ones you changed; the gate caught it, which is the only reason it is right.
|
||||
['plugin-designs/all-people-groups/all-people-groups.vue', 'useOptionalI18n', null],
|
||||
// wave 3c — my-upg-100-list (owner: upg100-plugin). No namespace, since callers pass full keys.
|
||||
// wave 3c — my-upg-100-list. No namespace, since callers pass full keys.
|
||||
// ⚠ THE THIRD COLUMN IS null, NOT 'humanizeKey(k)', and that is a DEPARTURE from 4c05e589, which
|
||||
// kept the fallback. Correct as regions-plugin wrote it; wrong the moment dx-shepherd took the
|
||||
// kept the fallback. Correct as first written; wrong the moment the owner took the
|
||||
// product call (UPGHK, 2026-09-27) to delete it. A row asserting a fallback the code no longer
|
||||
// passes fails by design — the same hole regions flagged to me in the opposite direction.
|
||||
// passes fails by design — the same hole flagged earlier in the opposite direction.
|
||||
// ★ WHY IT WAS DELETED. humanizeKey rendered a key's last segment title-cased, failing two ways: on
|
||||
// the messages keys it printed "Upg100 Wall Intro" where a whole sentence exists (wrong even in
|
||||
// English), and on the tabs keys it printed the RIGHT English by coincidence — those keys are named
|
||||
|
|
@ -175,7 +175,7 @@ const SITES = [
|
|||
// someone changes locale.
|
||||
// The premise for keeping it ("these keys are not fully catalogued") was MINE and was FALSE: seven
|
||||
// keys across both files, all string literals, every one present in all eleven locales, 0 gaps.
|
||||
// Same class of decision gospel-plugin took for its four sites above, and the OPPOSITE of the 3d
|
||||
// Same class of decision gospel-resources' owner took for its four sites above, and the OPPOSITE of the 3d
|
||||
// reading directly above — which is right, because that file is unowned and these two are not.
|
||||
['plugin-designs/my-upg-100-list/poster-wall.vue', 'useOptionalT', null],
|
||||
['plugin-designs/my-upg-100-list/upg-100-mfe.vue', 'useOptionalT', null],
|
||||
|
|
@ -188,11 +188,11 @@ const SITES = [
|
|||
// third bare call — a new unguarded translator — still fails this gate.
|
||||
// ★ DELIBERATELY NOT IN THIS REGISTER, so nobody "completes" C4 by converting it:
|
||||
// plugin-designs/pplr-data-maps/src/components/SemanticTreeLegend.vue
|
||||
// It still hand-rolls the guard, and exp-shepherd asked for it to stay that way: the file is carded for
|
||||
// It still hand-rolls the guard, and its owner asked for it to stay that way: the file is carded for
|
||||
// retirement (RETIRE-PPLR-SEMANTICTREELEGEND) in favour of the library component, so converting it is
|
||||
// work that gets thrown away. A migration whose value expires before it lands is not worth the diff.
|
||||
// Two more sites are their owners' to cut, not absent by oversight: country-posters-mfe.vue
|
||||
// (exp-shepherd, into its single posters landing) and key-cities/cities-map.vue (exp-shepherd, gated).
|
||||
// (into its single posters landing) and key-cities/cities-map.vue (gated).
|
||||
|
||||
const ALLOWED_BARE = { 'plugin-designs/gospel-resources/resources-map.vue': 2 }
|
||||
for (const [file, helper, fallbackFrag] of SITES) {
|
||||
|
|
@ -221,13 +221,13 @@ for (const [file, helper, fallbackFrag] of SITES) {
|
|||
// Which sites were MOVED to the catalogue by a decision, vs which always resolved there. Saying "as it
|
||||
// always did" about a moved file is a false statement inside a gate message, the one place a reader has
|
||||
// no reason to doubt. gospel-resources and cities-internet moved by their owners' decisions,
|
||||
// my-upg-100-list by dx-shepherd's product call (UPGHK) deleting humanizeKey, and all-people-groups by
|
||||
// my-upg-100-list by a product call (UPGHK) deleting humanizeKey, and all-people-groups by
|
||||
// the embed-contract ruling (locale-honouring everywhere, 2026-09-27).
|
||||
const MOVED_BY = {
|
||||
'gospel-resources': "gospel-plugin moved it here from enLookup's English",
|
||||
'cities-internet': "exp-shepherd moved it here from enLookup's English",
|
||||
'my-upg-100-list': 'upg100-plugin moved it here from humanizeKey, a title-cased key segment',
|
||||
'all-people-groups': "dx-shepherd's embed-contract ruling moved it here from its inline English map",
|
||||
'gospel-resources': "its owner moved it here from enLookup's English",
|
||||
'cities-internet': "its owner moved it here from enLookup's English",
|
||||
'my-upg-100-list': 'its owner moved it here from humanizeKey, a title-cased key segment',
|
||||
'all-people-groups': "the embed contract moved it here from its inline English map",
|
||||
}
|
||||
const mover = Object.keys(MOVED_BY).find((d) => file.includes(d))
|
||||
ok(!/fallback:/.test(code), mover
|
||||
|
|
@ -236,7 +236,7 @@ for (const [file, helper, fallbackFrag] of SITES) {
|
|||
}
|
||||
}
|
||||
|
||||
// ── 7b. gospel-plugin's ASKED-FOR ROW, against the REAL catalogue ───────────────────────────────
|
||||
// ── 7b. gospel-resources' ASKED-FOR ROW, against the REAL catalogue ───────────────────────────────
|
||||
// Their words: "a BARE host (no vue-i18n) with ?lang=ar must render pins.approximate in Arabic — not
|
||||
// the key, not gospel.pins.approximate, not English." It covers their conditions 1 and 2 together: a
|
||||
// namespace would corrupt the key, and an EN-only fallback would serve English to an Arabic reader.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* WHY: JSON.parse keeps the LAST of two equal keys and says nothing, so a duplicate silently kills the
|
||||
* first entry. "check:religion-label-not-value" sat twice in //scripts, one description dead, while
|
||||
* check:doc-scripts passed (it reads the parsed object, where only one survives). It was a merge artifact:
|
||||
* the landing tooling unions both sides' package.json additions. Found by regions-plugin; only Bun's parser
|
||||
* the landing tooling unions both sides' package.json additions. Found during a landing; only Bun's parser
|
||||
* warned, while running something unrelated.
|
||||
*
|
||||
* HOW: a small JSON scanner that tracks every object's keys by position, so it sees what JSON.parse
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ ok(Math.round(per / 100) * 100 === 40200,
|
|||
// it: 32 contiguous cells fill most of row 1 of 52, so the page printed as one solid bar across the
|
||||
// header — the ordinary chart the life grid exists to avoid — and the existing gate asserts only
|
||||
// that the shaded COUNT is between 0 and 5,200, which is equally true of a bar and of a scatter.
|
||||
// A count cannot distinguish a distribution. rega's eyes caught it; nothing else could have.
|
||||
// A count cannot distinguish a distribution. A visual review caught it; nothing else could have.
|
||||
const picked = scatterCells(5200, 32, 'upg-100')
|
||||
const spread = scatterSpread(picked, 52)
|
||||
ok(spread.cells === 32, '32 shaded cells are picked, distinct')
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import { pathToFileURL, fileURLToPath } from 'node:url'
|
|||
import { requirePathInThisCheckout } from './_serves-this-tree.mjs'
|
||||
|
||||
// ★ --expect-funnel TURNS AN OPTIONAL PAGE INTO A DECLARED REQUIREMENT, and it exists because of a
|
||||
// real near-miss (regions-plugin, 2026-09-26, reported unprompted). A merge resolved with
|
||||
// real near-miss (2026-09-26, reported unprompted). A merge resolved with
|
||||
// `git checkout --ours` silently deleted the printPacket call site that supplies the funnel data —
|
||||
// 60 lines — AND EVERY GATE STAYED GREEN. It had to: the funnel page is optional by design
|
||||
// (buildPacket omits it when the arg is null), so a packet with no page 2 is not malformed, just
|
||||
|
|
@ -274,8 +274,8 @@ const r = await page.evaluate(() => {
|
|||
})(),
|
||||
funnelEq: document.querySelectorAll('.funnel-eq').length,
|
||||
funnelSteps: document.querySelectorAll('.funnel-mine').length,
|
||||
// ★ MEASURED SO THE GATE CAN REPORT WHAT IT ASSERTED. rega: "the gate prints no funnel line, even
|
||||
// with --expect-funnel ... a reader cannot see WHAT it asserted about page 2." A silent pass is
|
||||
// ★ MEASURED SO THE GATE CAN REPORT WHAT IT ASSERTED. A review found the gate printed no funnel line, even
|
||||
// with --expect-funnel, so a reader could not see WHAT it asserted about page 2. A silent pass is
|
||||
// the mirror of a printed-but-unasserted number: the check is real and the evidence is invisible.
|
||||
// ⚠ ZERO POPULATION IS COUNTED ON PURPOSE. The reader's row printed "0 people" in every packet
|
||||
// (Number(null) is 0, so the finite-number guard admitted a deliberate no-data marker). Fixed in
|
||||
|
|
@ -302,10 +302,10 @@ const r = await page.evaluate(() => {
|
|||
.filter((d) => /^0(\.0+)?\s+\D/.test(d.textContent.trim())).length
|
||||
})(),
|
||||
funnelShare: (document.querySelector('.funnel-share')?.textContent || '').trim().slice(0, 80),
|
||||
// ★ LATIN RUNS ON A NON-LATIN SHEET, which is the one gap rega named and I left open: "the gate
|
||||
// passed: it counts rows, not the row's language." It asserted the funnel page's STRUCTURE and
|
||||
// nothing about whether its prose reached the reader's language — my own standing rule turned on
|
||||
// my own gate.
|
||||
// ★ LATIN RUNS ON A NON-LATIN SHEET, the one gap a review named and that was left open: the gate
|
||||
// passed because it counted rows, not the rows' language. It asserted the funnel page's STRUCTURE
|
||||
// and nothing about whether its prose reached the reader's language, the standing rule turned on
|
||||
// this gate itself.
|
||||
//
|
||||
// ⚠ IT ONLY WORKS IN A NON-LATIN-SCRIPT LOCALE, and that is why it is worth having rather than
|
||||
// aspiring to a general "is this translated?" test, which is not decidable. On a hi/ar/ru/zh sheet
|
||||
|
|
@ -749,7 +749,7 @@ if (r.lifeSheets) {
|
|||
}
|
||||
}
|
||||
// ⚠ AND THE SHADE MUST BE SCATTERED, NOT STACKED — the assertion that would have caught what three gates
|
||||
// and a passing suite did not. rega's contact sheet (2026-09-28) showed page 3 reading as ONE SOLID BAR:
|
||||
// and a passing suite did not. A contact sheet (2026-09-28) showed page 3 reading as ONE SOLID BAR:
|
||||
// 32 contiguous cells fill most of row 1 of 52, so the page said "a big green block" where the
|
||||
// intent is 32 boxes lost in 5,200. Every assertion passed, because they all measured the COUNT.
|
||||
// Half the grid height is a deliberately loose floor: a genuine scatter of even a few cells spans most of
|
||||
|
|
@ -793,7 +793,7 @@ if (r.funnel && !r.funnelSteps) {
|
|||
// ★ AND IF THE CALLER DECLARED IT, ITS ABSENCE IS A FAILURE. See the --expect-funnel note at the top:
|
||||
// a lost call site produces a packet that is CORRECT but missing page 2, which is why nothing caught
|
||||
// a merge deleting one.
|
||||
// ★ EVERY FUNNEL ROW MUST HAVE A BAR. rega measured the first version: the reader's step had no bar,
|
||||
// ★ EVERY FUNNEL ROW MUST HAVE A BAR. A browser check measured the first version: the reader's step had no bar,
|
||||
// so the funnel never visibly narrowed to "yours" — a funnel whose final term is not drawn as part of
|
||||
// the funnel fails at the one thing it is for. Rows and bars are counted separately so the next
|
||||
// regression is a mismatch rather than an invisible omission.
|
||||
|
|
@ -805,8 +805,8 @@ if (r.funnel && r.funnelRows !== r.funnelBars) {
|
|||
// because Number(null) is 0 and the renderer's guard tested finiteness rather than PRESENCE. A people
|
||||
// group with no people is not a fact; it is missing data wearing a number's clothes.
|
||||
// ★ AND ON A NON-LATIN SHEET, THE FUNNEL'S PROSE MUST BE IN THE READER'S SCRIPT. See funnelLatinRuns
|
||||
// above for why this is only meaningful in hi/ar/ru/zh. This is the gap rega named after the ?list=
|
||||
// render: "the gate passed: it counts rows, not the row's language", and it was right — the English
|
||||
// above for why this is only meaningful in hi/ar/ru/zh. This is the gap a review named after the ?list=
|
||||
// render (the gate passed because it counted rows, not the rows' language), and it was right — the English
|
||||
// list label sat among Devanagari and every assertion here was green.
|
||||
//
|
||||
// ⚠ THE ALLOWLIST IS TWO ENTRIES AND BOTH ARE DECISIONS, NOT BOOKMARKS:
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ ok(count(light, /sheet-sets-(bounded|centered)/g) === 0, 'lightweight still carr
|
|||
// "rows close on the bottom margin" one already deleted from check-profile-table. A printed sheet
|
||||
// is simply much taller than gospel's constrained pane, which is why their bug is not ours.
|
||||
// The real protection is the empty-ring filter asserted above (ten rows is the ceiling) plus
|
||||
// rega's rendered check; a headless budget with 790px of slack would be decoration.
|
||||
// the rendered browser check; a headless budget with 790px of slack would be decoration.
|
||||
}
|
||||
|
||||
// An unknown variant must print the FULL packet. A typo that printed a SHORTER packet would look
|
||||
|
|
@ -204,7 +204,7 @@ ok(/printPacketAs[\s\S]{0,600}prints\.printPacket\(/.test(WALL),
|
|||
'printPacketAs does not call prints.printPacket — the Prayer List caret would print the columnar LIST again, not the packet')
|
||||
ok(/variant/.test(PRINTS.match(/async function printPacket\([^)]*\)/)?.[0] || ''),
|
||||
'usePosterPrints.printPacket does not accept a variant — the caret\'s choice would be silently dropped')
|
||||
// printList itself STAYS (dx-shepherd: don't delete it, just stop the button calling it).
|
||||
// printList itself STAYS (by decision: keep it, just stop the button calling it).
|
||||
ok(/function printList\(/.test(PRINTS) && /printList,/.test(PRINTS),
|
||||
'printList was removed — it must remain exported for any surface that still wants the columnar list')
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ const gate = join(HERE, 'check-packet-render.mjs')
|
|||
|
||||
// ★ THE FUNNEL PAGE IS REQUIRED HERE, and this line is the half of the fix that was missing.
|
||||
// check-packet-render gained --expect-funnel after a merge deleted the call site supplying the funnel
|
||||
// data and every gate stayed green (regions-plugin, 2026-09-26). But a DECLARABLE expectation that
|
||||
// data and every gate stayed green (2026-09-26). But a DECLARABLE expectation that
|
||||
// nothing declares is not a closed hole — it is an invisible defect traded for a visible obligation.
|
||||
// I said as much to regions and then owed the second half.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* check-pane-config-reforward — a composite's panes keep following the outer config for the whole
|
||||
* session, and a locale change never rewrites a filter into a display name.
|
||||
*
|
||||
* ★ THE BUG THIS GUARDS, measured by rega on development 92ca8b6e6 across FOUR composites
|
||||
* ★ THE BUG THIS GUARDS, measured on development 92ca8b6e6 across FOUR composites
|
||||
* (regions-mfe, upg-100-mfe, country-posters-mfe, research-map-plus-grid). The outer element's
|
||||
* profile-config reached locale 'ar' by +1.5 s — attribute AND property, same node — while every
|
||||
* NESTED host carried NO locale key at boot and still none at +15 s. Text per composite at +15 s:
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* ★ IT RUNS THE SHIPPED HELPER WITH REAL VUE. usePaneConfig is imported, not re-typed, and driven
|
||||
* by real refs through a real watchEffect — the dependency-tracking hole this gate's case 3 covers
|
||||
* (a plain array leaves a LATER entry's getter untracked) is invisible to any test that fakes
|
||||
* reactivity, and it was found by studio only because their test used real Vue.
|
||||
* reactivity, and it was found only because a test used real Vue.
|
||||
*
|
||||
* ★ AND IT ASSERTS THE DOM, NOT THE RETURN VALUE. Every case reads the attribute back off the
|
||||
* element, because "the helper decided to write" and "the pane was told" are different claims and
|
||||
|
|
@ -76,7 +76,7 @@ const cfgOf = (el) => {
|
|||
paneConfig.dispose()
|
||||
}
|
||||
|
||||
// ── 1b. NO LOCALE KEY AT BOOT IS THE REAL BEFORE-STATE, not a stale one. rega measured the nested
|
||||
// ── 1b. NO LOCALE KEY AT BOOT IS THE REAL BEFORE-STATE, not a stale one. A browser check measured the nested
|
||||
// hosts carrying no locale key at all, so the first re-forward is absent -> 'ar'.
|
||||
{
|
||||
const outer = ref({ apiBaseUrl: '/api' })
|
||||
|
|
@ -225,7 +225,7 @@ const cfgOf = (el) => {
|
|||
// gridLanguage() falls back to `linked.language.value || linked.language.label`, and `label` is a
|
||||
// DISPLAY NAME. The grid's valueMatches() compares whole normalised values, so a name fetched in
|
||||
// one language matches no row in another — the failure that took the grid 2,107 -> 0 and read as
|
||||
// "no results" (rega, 2026-09-26). This asserts the CLASS, not today's instance.
|
||||
// "no results" (measured 2026-09-26). This asserts the CLASS, not today's instance.
|
||||
{
|
||||
const locale = ref('en')
|
||||
// A language whose display label follows the locale, as the API returns it, but whose code does not.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
* this._data = typeof options.data === 'string' ? { url: options.data } : { geojson: options.data }
|
||||
*
|
||||
* so `data.features` was undefined and the reader returned an EMPTY LIST on MapLibre — the keyless
|
||||
* engine the public builds use. Measured by rega on 2026-09-28: a language-family selection and a
|
||||
* engine the public builds use. Measured on 2026-09-28: a language-family selection and a
|
||||
* prayer selection both logged "0 pin(s) selected" with the pins plainly on screen.
|
||||
*
|
||||
* ★ THE FAILURE MODE IS WHY A TEST IS THE ONLY GUARD. Every caller is written to NO-OP when it finds no
|
||||
|
|
@ -79,7 +79,7 @@ for (const [label, src] of [['mapbox', { _data: COLLECTION }], ['maplibre', { _d
|
|||
eq('expressions are ANDed', matchesExpression(['all', ['==', ['get', 'uniqueId'], 'a'], ['==', ['get', 'languageFamily'], 'Indo-European']], FEATURES[0].properties), false)
|
||||
|
||||
// ── PACKETSEL: the prayer count is LIVE, so the packet must read feature-state ──────────────────
|
||||
// rega, RQ3(b): the packet's "Has Prayer" selection showed 50 of 997 where the legend row said 699.
|
||||
// RQ3(b): the packet's "Has Prayer" selection showed 50 of 997 where the legend row said 699.
|
||||
// The legend is right. Polling writes each pin's current count with setFeatureState() and
|
||||
// prayer-progress.js:94 colours from ['feature-state','peoplePraying']; the GeoJSON property is
|
||||
// whatever was true at page load. Reading the property selects the wrong people to pray for, which is
|
||||
|
|
|
|||
|
|
@ -108,9 +108,9 @@ async function measure(width, lang) {
|
|||
await page.waitForTimeout(10000)
|
||||
|
||||
// ★ HOVER IS INVISIBLE TO A STATIC PROBE, which is exactly how the blue outline stayed
|
||||
// unbuilt for so long. Repeated reports asked to "restore the blue outline around the poster";
|
||||
// unbuilt for so long. A blue outline around the hovered poster was reported missing more than once;
|
||||
// measuring the loaded page found `outline:none` on all 136 framed elements and concluded it had
|
||||
// never existed — true, and useless, because the affordance being asked for only exists WHILE
|
||||
// never existed — true, and useless, because the affordance in question only exists WHILE
|
||||
// THE POINTER IS OVER THE CARD. The pointer has to actually move.
|
||||
//
|
||||
// ⚠ AND IT MUST NOT MOVE ANYTHING. The whole rest of this gate asserts where the print row sits.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* check-poster-layout-optin — the composed poster layout is OPT-IN, and every caller that does not
|
||||
* ask for it gets byte-for-byte what it got before.
|
||||
*
|
||||
* WHY THE OPT-IN EXISTS (dx-shepherd's ruling, from upg100's check). The renderer used to raster the
|
||||
* WHY THE OPT-IN EXISTS (a decision that followed upg-100-list's check). The renderer used to raster the
|
||||
* map at FULL PAGE size and composite the title, legend and footer on top of it, so the legend lay
|
||||
* over the map it describes. usePosterLayout had always computed the correct geometry and nothing
|
||||
* consumed it. Fixing that unconditionally would have broken a different product: country-posters
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ ok(typeof html === 'string' && html.length > 10000 && /<svg\b/.test(html), `the
|
|||
|
||||
// THE CLASSIC-SCRIPT COPY (strict-CSP pages load it with <script integrity>): pinned, served as the tree
|
||||
// writes it, and — run as a real classic script — the SAME generator: its sheet is byte-identical to the
|
||||
// module's for the same inputs. (The <script> path itself needs a browser; that half is rega's.)
|
||||
// module's for the same inputs. (The <script> path itself needs a browser; that half is a browser check.)
|
||||
{
|
||||
const classic = globalVariant(source)
|
||||
const servedClassic = readFileSync(join(REPO, 'public/dx-maps/assets/lib/poster-render.global.js'), 'utf8')
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* check-preset-config-merge — a preset page keeps its profile's defaults. Headless.
|
||||
*
|
||||
* A preset (<bundle>/<profile>/<instance>/index.html) bakes a config made of the profile's
|
||||
* <profile>.meta.json `config` with the instance's `props` MERGED over it. It used to REPLACE it: go-int's
|
||||
* <profile>.meta.json `config` with the instance's `props` MERGED over it. It used to REPLACE it: the
|
||||
* upg-neighbor presets lost the profile's pinHint:false. For every built preset page this asserts each
|
||||
* meta `config` key is present, with the instance's own value where the instance sets one.
|
||||
* Rule stated in documentation/PRESET-PLUGIN-STANDARD.md.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
* It runs in Node with no layout engine, so it asserts the things that are TRUE OF THE MODEL: the
|
||||
* geometry closes, every group gets a row, the fit ladder picks the size it claims, the fallback
|
||||
* fires in all three states. It CANNOT assert that the rendered row is 73px tall in a browser —
|
||||
* that is rega's seat (internal/check-packet-render.mjs, which launches a browser and is exit-75
|
||||
* that is the browser gate (internal/check-packet-render.mjs, which launches a browser and is exit-75
|
||||
* NOT MEASURED anywhere else). A character-count budget is a MODEL of wrapping, not a measurement
|
||||
* of it, and the honest place to say so is here rather than in a commit message nobody re-reads.
|
||||
*
|
||||
|
|
@ -61,7 +61,7 @@ const CH = (H - 2 * M - HEAD - GUT * (PER_PAGE - 1)) / PER_PAGE
|
|||
// to fire: 20 rows (73px) and 21 rows (69px) pass because the content genuinely fits; 24 rows
|
||||
// (60px) and 28 fail. That is the boundary this is meant to guard.
|
||||
// ⚠ THE ROW IS A BORDER-BOX, so its padding and border come OUT of the declared height rather than
|
||||
// being added to it. rega measured 81px against a 73.25px model before `box-sizing:border-box` was
|
||||
// being added to it. A browser check measured 81px against a 73.25px model before `box-sizing:border-box` was
|
||||
// set — the rows were rendering 7.75px taller than the geometry that positions them, overlapping
|
||||
// their successors, while the stack still fitted the sheet (ending 8px INSIDE the bottom margin
|
||||
// rather than on it). Nothing clipped and nothing ran off the page, which is exactly why only a
|
||||
|
|
@ -156,7 +156,7 @@ ok(long.text.endsWith('…'), 'a clamped description is not marked with an ellip
|
|||
}
|
||||
|
||||
// ── 5. EVERY SHIPPED LOCALE FITS, MEASURED AGAINST THE REAL CATALOGUE ──────────────────────────
|
||||
// ★ This is the arm that would have caught a locale I cannot eyeball. The ladder is INSURANCE, not
|
||||
// ★ This is the arm that would have caught a locale no reviewer can read by eye. The ladder is INSURANCE, not
|
||||
// routine: if a real locale is routinely stepping down, the budget is wrong and the fix is the
|
||||
// budget, not the ladder. Longest today is German at 178 against a 234-char budget.
|
||||
{
|
||||
|
|
@ -177,4 +177,4 @@ if (fails.length) {
|
|||
for (const f of fails) console.error(` ✗ ${f}`)
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('PROFILE-TABLE: PASS — the row is tall enough for a name plus two description lines at the smallest ladder size, every group gets a row across page boundaries, the fit ladder steps 17→15→14 and cuts at a whole word only as a last resort, a missing or empty describer degrades to the metadata line, and every shipped locale fits at full size. NOT covered here: the RENDERED row height and whether the description actually wraps to two lines — those need a browser and are rega\'s seat.')
|
||||
console.log('PROFILE-TABLE: PASS — the row is tall enough for a name plus two description lines at the smallest ladder size, every group gets a row across page boundaries, the fit ladder steps 17→15→14 and cuts at a whole word only as a last resort, a missing or empty describer degrades to the metadata line, and every shipped locale fits at full size. NOT covered here: the RENDERED row height and whether the description actually wraps to two lines — those need a browser check.')
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env node
|
||||
/* check-provider-for.mjs — run as `bun run check:provider-for`. Source-only, headless, ~0.1s.
|
||||
Placed in internal/ with studio's explicit authorisation for this one gate (END-STU-C3AB): it spans
|
||||
Placed in internal/ by explicit decision for this one gate: it spans
|
||||
library/ plus three separate plugins, so no single plugin's scripts/ folder owns it. */
|
||||
// C3: do the library helpers behave like the raw-global code they replace, on BOTH engine shapes AND
|
||||
// on the ambiguous case that is neither?
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
* ★ NARROWED AFTER LANDING, and this is what the next reader needs: the ordering is not merely
|
||||
* "not the cause" — it is UNCONSTRUCTIBLE today. region-dashboards.vue:1091 gates the entire map
|
||||
* subtree behind v-if="loading", and loadRegions assigns points inside the try while loading=false
|
||||
* is in the finally, so the map CANNOT mount with empty points. rega measured 0 grey in 36 mounts,
|
||||
* is in the finally, so the map CANNOT mount with empty points. A browser check measured 0 grey in 36 mounts,
|
||||
* including a run with the prayer API held back 20s: the map was constructed AFTER the data, every
|
||||
* time. So this gate guards a FUTURE refactor that drops that v-if data gate — not a live path.
|
||||
*
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
*
|
||||
* ★ WHAT THIS ASSERTS, and it is a MODEL not a mock: the four arrival orders, against the real
|
||||
* repaint rule. It fails if any order can leave the fill flat-grey while points exist. A browser
|
||||
* cannot be run here (that is rega's seat), so the ordering is modelled and the SOURCE is asserted
|
||||
* cannot be run here (that is a browser check), so the ordering is modelled and the SOURCE is asserted
|
||||
* to carry the repaint that makes the model's good cases reachable.
|
||||
*/
|
||||
import { readFileSync } from 'node:fs'
|
||||
|
|
|
|||
|
|
@ -85,14 +85,14 @@ const LINKED_KNOWN = {
|
|||
// - both fixes are ancestors of main: 12a64702 (release the retained request on success — the FIRST
|
||||
// press was losing the zone) and 67e9ede5 (the wall clears its memory when its pane goes inert).
|
||||
// - the receiving side still registers its listener.
|
||||
// - rega proved it end to end on BOTH engines at 810ffa26.
|
||||
// - a browser check proved it end to end on BOTH engines at 810ffa26.
|
||||
}
|
||||
const MAPBOX_KNOWN = {
|
||||
// pplr-data-maps (new Experimental bundle, exp-shepherd) loads the Mapbox GEOCODER script even when
|
||||
// pplr-data-maps (new Experimental bundle) loads the Mapbox GEOCODER script even when
|
||||
// the host asked for maplibre: the only api.mapbox.com request in the whole keyless gallery, both
|
||||
// modes, measured 2026-09-25 while that tab was open. Routed via dx-shepherd; delete this entry in
|
||||
// modes, measured 2026-09-25 while that tab was open. Routed to its owner; delete this entry in
|
||||
// the owner's fix commit so the gate enforces zero again.
|
||||
'https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.min.js': 'exp-shepherd (pplr-data-maps loads the Mapbox geocoder under maplibre)',
|
||||
'https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.min.js': 'pplr-data-maps loads the Mapbox geocoder under maplibre',
|
||||
// EMPTY ON PURPOSE. The one entry here — my-upg-100-list/upg-100-list.vue:1464 pinning
|
||||
// mapbox-gl.css v3.3.0 regardless of engine — was fixed and the exemption deleted in the SAME
|
||||
// COMMIT as the fix, so main never had a window where the gate red-flagged its own known bug and
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* check-select-zone-race — "Show on map" works on the FIRST click, not the second.
|
||||
*
|
||||
* THE DEFECT (PRODUCTION-MATRIX:422, measured by rega): the composite's list pane dispatches
|
||||
* THE DEFECT (PRODUCTION-MATRIX:422, measured in a browser): the composite's list pane dispatches
|
||||
* 'doxa:select-zone' at the map pane, but the map pane attaches its listener in onMounted and the
|
||||
* pane mounts lazily. So the first click landed before any listener existed, did nothing, and only
|
||||
* a SECOND click selected the zone. A control you must press twice reads as broken.
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
* Delivery and arrival both succeeding still lost the selection without this.
|
||||
*
|
||||
* Source-level and headless: the race is a lifecycle ordering between two custom elements, which a
|
||||
* DOM-less runner cannot stage and which the browser seat measures end to end (rega owns that).
|
||||
* DOM-less runner cannot stage and which the browser seat measures end to end.
|
||||
* What this pins is that none of the three mechanisms quietly disappears.
|
||||
*
|
||||
* Exit 0 pass · 1 fail.
|
||||
|
|
@ -58,7 +58,7 @@ ok(/addEventListener\('doxa:select-zone'/.test(LIST),
|
|||
|
||||
// ── 3. EFFECT: retained while unready, drained at the readiness signal ─────────────────────────
|
||||
// ⚠ THE SUBTLEST LAYER. Delivery and arrival can both succeed and the selection still not hold,
|
||||
// because onLegendSelect returns early while the tapestry layer is down. rega read that state
|
||||
// because onLegendSelect returns early while the tapestry layer is down. A browser check read that state
|
||||
// twice, 13 ms apart, with the correct id.
|
||||
// ⚠ TWO DISTINCT RETAIN SITES, and a single /_pendingZoneId = zoneId/ match passes while ONE of
|
||||
// them is deleted — measured: removing the not-found retain left the gate green on the other.
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ const HAND_VOCAB = {
|
|||
* THE FAILURE: the hand list above held the phrases I had already FOUND. It could not see framing
|
||||
* I never enumerated, so when a SERIES=country poster still printed "Unengaged of West Africa",
|
||||
* "Series: List of 100 UPG's · map 11 of 28" and a side box calling it "one of a 30-map set", this
|
||||
* gate said PASS — and I reported that PASS to three agents AS PROOF the render was clean. rega
|
||||
* gate said PASS — and that PASS was reported AS PROOF the render was clean. A review
|
||||
* found it by reading the rendered page. A hand list makes a gate a LOWER BOUND on correctness
|
||||
* while it looks like a guarantee.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ function shadowCssOf(script, filename) {
|
|||
fold(node.arguments[0], acc)
|
||||
// The style ID (second argument). A plain identifier is the only correct shape: a CSS rule moved
|
||||
// past the first argument concatenates onto it ('@media(...){...}doxa-gospel-map'), which is valid
|
||||
// JS, keeps the build green and silently loses the rule (gospel-plugin's trap, COMMON.md).
|
||||
// JS, keeps the build green and silently loses the rule (a known trap, COMMON.md).
|
||||
const lab = { text: '', literal: true, present: !!node.arguments[1] }
|
||||
if (node.arguments[1]) { const la = { css: '', complete: true, endsLiteral: false }; fold(node.arguments[1], la); lab.text = la.css; lab.literal = la.complete }
|
||||
acc.label = lab
|
||||
|
|
@ -133,7 +133,7 @@ function scanCss(cssRaw) {
|
|||
if (depth === 0 && ch === ';' && /[A-Za-z-]+\s*:/.test(chunk)) { orphans.push(chunk.trim().slice(0, 90)); chunk = '' }
|
||||
i++
|
||||
}
|
||||
// ★ A SELECTOR THAT NEVER GETS A BLOCK (regions-plugin, 2026-09-29). Whatever is left in `chunk`
|
||||
// ★ A SELECTOR THAT NEVER GETS A BLOCK (2026-09-29). Whatever is left in `chunk`
|
||||
// once the scan ends sits at depth 0 after the last '}' — i.e. text that looks like a selector and
|
||||
// has no declarations. That is how regions-list.vue shipped
|
||||
// [lang="ru"] .rl-title, [lang="ru-RU"] .rl-title,regions-list
|
||||
|
|
@ -198,7 +198,7 @@ ok(!r.dangling.length, 'trailing whitespace is not a dangling selector')
|
|||
'an argument built partly from an imported constant is reported PARTIAL, not scanned as a whole sheet')
|
||||
}
|
||||
{
|
||||
// gospel-plugin's trap: a rule moved past the CSS argument concatenates onto the style id
|
||||
// The known trap: a rule moved past the CSS argument concatenates onto the style id
|
||||
const trap = "useShadowStyles('.a{ color:red; }', '@media (max-width:1px){ .b{ color:red; } }' + 'doxa-gospel-map')"
|
||||
const lab = shadowCssOf(trap, 'x.js')[0].label
|
||||
ok(lab.literal && !/^[a-z0-9-]+$/.test(lab.text), 'the style-id arm reads a rule concatenated onto the id as NOT a plain identifier')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* WHY: a page's own reduced-motion reset never crosses a shadow boundary, so a component rendered inside a
|
||||
* custom element's shadow root animates for a reader who asked for less motion unless the root carries its
|
||||
* own reset (regions-plugin, ProgressBar; ten legend and map-control components had none).
|
||||
* own reset (ProgressBar; ten legend and map-control components had none).
|
||||
*
|
||||
* WHAT: (1) library/composables/useShadowStyles.js injects REDUCED_MOTION_CSS, a prefers-reduced-motion:
|
||||
* reduce block, once per shadow root; (2) every library/components/**.vue that declares a transition or an
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ if (debt.length) {
|
|||
// Links that already exist must keep opening.
|
||||
eq('a legacy JSON hash still restores', parseView('#f=' + encodeURIComponent(JSON.stringify({ affinity_bloc: 'A008' }))).filters, { affinity_bloc: 'A008' })
|
||||
eq('an old link with no q restores no search', parseView('#f=religion_family:Hinduism').search, '')
|
||||
// QUERY MODE, requested by go-int: its board already shares as ?access=…&band=…, restored before
|
||||
// QUERY MODE, requested by the gospel-internet board: it already shares as ?access=…&band=…, restored before
|
||||
// first render, and writes only on its own leaves so a partner's address bar is never touched. A
|
||||
// hash-only composable would have given that board TWO URL states instead of replacing its glue.
|
||||
// The host-param case is the one that matters: writing must not eat a query the page already owns.
|
||||
|
|
@ -184,7 +184,7 @@ if (debt.length) {
|
|||
eq('query round-trips filters and search', parseQuery(serializeQuery({ access: 'low', band: ['2g', '3g'] }, 'bhutan'), ['access', 'band']), { filters: { access: 'low', band: ['2g', '3g'] }, search: 'bhutan' })
|
||||
eq('query reads only declared facet keys', parseQuery('?access=low&panel=map', ['access']).filters, { access: 'low' })
|
||||
eq('query keeps a comma inside a value', parseQuery(serializeQuery({ language: ['Arabic, Sudanese'] }, ''), ['language']).filters, { language: 'Arabic, Sudanese' })
|
||||
// ★ AN ALIAS MAP, because a param name already published cannot be renamed. go-int has shared
|
||||
// ★ AN ALIAS MAP, because a param name already published cannot be renamed. gospel-internet has shared
|
||||
// ?access= against a bus key of access_level; insisting the two match would have renamed every
|
||||
// param on adoption and broken every link already sitting on a partner page — the exact harm this
|
||||
// card exists to prevent, delivered by the thing meant to prevent it. Driven with its real names.
|
||||
|
|
@ -193,7 +193,7 @@ if (debt.length) {
|
|||
eq('alias reads an already-shared link', parseQuery('?access=low&app=sms', ALIAS), { filters: { access_level: 'low', messaging: 'sms' }, search: '' })
|
||||
eq('an undeclared bus key keeps its own name', serializeQuery({ country: 'BT' }, '', '', { facetKeys: ALIAS }), '?country=BT')
|
||||
eq('a host param survives under an alias map', serializeQuery({ access_level: 'low' }, '', '?utm=x', { facetKeys: ALIAS }), '?utm=x&access=low')
|
||||
// ★ BOTH SEPARATORS ON READ, ONE ON WRITE. go-int's board has always written band=yes|partial and
|
||||
// ★ BOTH SEPARATORS ON READ, ONE ON WRITE. The gospel-internet board has always written band=yes|partial and
|
||||
// those links are on partner pages; splitting only on ',' read that back as the single value
|
||||
// "yes|partial" and matched no row, so adopting this composable would have broken every multi-value
|
||||
// link they had already shared. Reserving `|` on write is what makes accepting it on read free.
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ const MARKERS = [
|
|||
id: 'legend-a11y-keys',
|
||||
component: 'library/components/legends/SemanticTreeLegend.vue',
|
||||
marker: 'legend.a11y',
|
||||
landed: 'regions, c4c60a4 and earlier',
|
||||
landed: 'c4c60a4 and earlier',
|
||||
why: 'accessible names + aria-expanded on the legend row caret and clear chip',
|
||||
},
|
||||
{
|
||||
|
|
@ -81,7 +81,7 @@ const MARKERS = [
|
|||
// if it still compiles ensureEngineCSS without the guard; with neither shape it is NOT AFFECTED.
|
||||
staleRe: /const ([\w$]+)=([\w$]+)\.getRootNode\(\);if\(!\(\1 instanceof ShadowRoot\)\)return/g,
|
||||
marker: 'if (!element) return (ensureEngineCSS)',
|
||||
landed: 'studio, 2026-09-25',
|
||||
landed: '2026-09-25',
|
||||
why: 'a map whose pane unmounts mid-initialise no longer throws "reading getRootNode" (check-map-unmount-mid-init)',
|
||||
},
|
||||
{
|
||||
|
|
@ -96,7 +96,7 @@ const MARKERS = [
|
|||
builtRe: /cdn\.jsdelivr\.net\/npm\/@mapbox\/mapbox-gl-rtl-text/,
|
||||
staleRe: /GL JS script to your page/g,
|
||||
marker: 'installRtlTextPlugin(gl) (MapLibre RTL shaping)',
|
||||
landed: 'rega, 2026-09-25',
|
||||
landed: '2026-09-25',
|
||||
why: 'Arabic, Hebrew and Persian map labels are shaped on MapLibre (keyless) maps, not drawn as disconnected glyphs',
|
||||
},
|
||||
{
|
||||
|
|
@ -110,7 +110,7 @@ const MARKERS = [
|
|||
builtRe: /\["coalesce",\["get","name:"/,
|
||||
staleRe: /GL JS script to your page/g,
|
||||
marker: 'localizeBasemapLabels(map.value, readerLang()) (basemap labels localized)',
|
||||
landed: 'rega, 2026-09-25',
|
||||
landed: '2026-09-25',
|
||||
why: 'country, city and street names on the basemap render in the reader\'s language (Mapbox setLanguage, MapLibre name:<lang>)',
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* check-snippets-draw — every PUBLISHED embed snippet draws, pasted verbatim on a partner page on another origin.
|
||||
* (card GATE-EVERY-PUBLISHED-SNIPPET-DRAWS-A-MAP; ported from rega's probes snipgate.mjs and mbxcheck.mjs)
|
||||
* (card GATE-EVERY-PUBLISHED-SNIPPET-DRAWS-A-MAP; ported from the browser probes snipgate.mjs and mbxcheck.mjs)
|
||||
*
|
||||
* WHY. The manifest's embed snippets are the one artefact a partner copies. check:snippet-engine proves what a
|
||||
* snippet SAYS (the engine it preloads, the provider it names); only a browser proves it DRAWS. The probe this is
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ ok(/:only-child[^{]*\{[^}]*border-radius:\s*4px/.test(TOOLBAR), 'and a lone cont
|
|||
// ── 2c. NO CHILD BRINGS ITS OWN OUTLINE ──────────────────────────────────────────
|
||||
// ShareButton is not a .mcb -- it wraps its button in .share-wrap with border-radius:50% and a
|
||||
// conic-gradient ring on ::before -- so the button rules missed it and it kept a round rainbow halo
|
||||
// inside the square panel. Found by rega at 390, not by me.
|
||||
// inside the square panel. Found by a browser check at 390, not by this gate.
|
||||
ok(/\.map-toolbar--square \.share-wrap \{[^}]*border-radius:\s*0/.test(TOOLBAR),
|
||||
'the square panel flattens .share-wrap, which is a div and not a .mcb')
|
||||
ok(/\.map-toolbar--square \.share-wrap::before \{[^}]*display:\s*none/.test(TOOLBAR),
|
||||
|
|
@ -157,7 +157,7 @@ for (const [name, path] of CONSUMERS) {
|
|||
}
|
||||
ok(optedIn === 0, `none of the ${CONSUMERS.length} MapToolbar consumers passes controls=, so every one renders exactly as before (${optedIn} opted in)`)
|
||||
|
||||
// ── 6. THE GEOMETRY, for rega to confirm with eyes ──────────────────────────────────────────────
|
||||
// ── 6. THE GEOMETRY, for a browser check to confirm ──────────────────────────────────────────────
|
||||
// A square toolbar is SHORTER, because the gaps become dividers. That is the one measurable knock-on:
|
||||
// MapControlMenu's matchToolbar limits a menu to the toolbar column's height.
|
||||
const BTN = 32, GAP_DESKTOP = 8, GAP_MOBILE = 6
|
||||
|
|
@ -169,7 +169,7 @@ for (const [name, , n] of CONSUMERS) {
|
|||
}
|
||||
const five = { round: 5 * BTN + 4 * GAP_DESKTOP, square: 5 * BTN + 4 }
|
||||
ok(five.square < five.round,
|
||||
`a 5-control toolbar goes ${five.round}px -> ${five.square}px, so a matchToolbar menu gets ${five.round - five.square}px shorter -- rega should confirm the menu still fits its content`)
|
||||
`a 5-control toolbar goes ${five.round}px -> ${five.square}px, so a matchToolbar menu gets ${five.round - five.square}px shorter -- a browser check should confirm the menu still fits its content`)
|
||||
console.log(` at mobile gap ${GAP_MOBILE}px a 5-control toolbar is ${5 * BTN + 4 * GAP_MOBILE}px round vs ${five.square}px square`)
|
||||
|
||||
// ── 7. NEG CONTROLS ─────────────────────────────────────────────────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ function undeclaredLabels(manifest) {
|
|||
// b.stage drags every experimental sibling in with it. Measured: cities-internet is a
|
||||
// production bundle whose connectivity-list and data-tables are EXPERIMENTAL, and
|
||||
// gospel-resources likewise for charts / data-tables / resources-list. That was 5 false
|
||||
// violations out of 7 (regions-plugin caught it, 2026-09-28).
|
||||
// violations out of 7 (caught 2026-09-28).
|
||||
// I had already moved off stageOf (bundle-keyed) once; moving to b.stage was the SAME
|
||||
// mistake wearing a different field name. The profile's own stage is the only one that
|
||||
// answers "is this row production".
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* check-window-globals-released — a component that puts something on `window` must take it back.
|
||||
*
|
||||
* rega's heap snapshots (_qa-cycle/rega/leak-722ac7789) measured Simple Research and All People
|
||||
* Heap snapshots at 722ac7789 measured Simple Research and All People
|
||||
* Groups mounted twice: 54.2 MB -> 65.1 MB, live Vue apps 6 -> 8. EVERY unmounted app stayed in
|
||||
* memory, one copy per mount, and the retainers were all the same shape — a window key set during
|
||||
* setup and never cleared:
|
||||
|
|
@ -82,7 +82,7 @@ for (const file of files) {
|
|||
// - a PAGE-WIDE CACHE keyed off itself: `window.__x = window.__x || {}` is shared on purpose
|
||||
// across every component on the page, so no single component may clear it.
|
||||
// What does retain is a closure (it captures the component) or a bare reference to one of its
|
||||
// objects — which is every case rega's snapshots actually found.
|
||||
// objects — which is every case the snapshots actually found.
|
||||
if (/^(true|false|-?\d|['"`])/.test(after)) continue
|
||||
if (new RegExp(`window\\s*\\.\\s*${name}\\b`).test(after)) continue
|
||||
if (!set.has(name)) set.set(name, [])
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ function fixTree(root) {
|
|||
}
|
||||
// The Research Gallery reads a BYTE-IDENTICAL copy of the manifest first when it runs on a foreign
|
||||
// origin (generate-tree writes it; see doxa-maps-spa.vue). Repairing the root manifest alone left the
|
||||
// copy with the OLD integrity, so an embedded gallery refused the rebuilt bundle (rega, 2026-09-25).
|
||||
// copy with the OLD integrity, so an embedded gallery refused the rebuilt bundle (measured 2026-09-25).
|
||||
for (const rel of ['doxa-maps-spa/manifest.json']) {
|
||||
const copy = join(root, rel)
|
||||
if (existsSync(copy) && readFileSync(copy, 'utf8') !== after) {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
"check:hardcoded-english": "report-only while its findings are triaged (97 user-visible English strings on 2026-09-29); chaining it now would hold every gate red. Its :self-test IS chained, so the matcher stays proven",
|
||||
"check:shot-fonts": "checks that the MACHINE taking README screenshots can render emoji (fc-list): a property of that box, not of the product, so it runs before a screenshot session, not in the gates",
|
||||
"check:coverage-consistent": "the full run includes clause L, the age of the oldest link verification (45 days), which depends on the CALENDAR: chained, it would turn gates red on a date (first 2026-11-08) with no code change. Run it with the link re-verification; every other clause runs in gates:pre as check:coverage-consistent:chained",
|
||||
"check:snippets-draw": "AWAITING ITS FIRST BROWSER RUN (rega): the browser suite lists a gate only after it has run. Moves into verify-browser-all's GATES, and out of this list, once that run is recorded.",
|
||||
"check:snippets-draw": "AWAITING ITS FIRST BROWSER RUN: the browser suite lists a gate only after it has run. Moves into verify-browser-all's GATES, and out of this list, once that run is recorded.",
|
||||
"check:grid-merge-defaults": "WAITS FOR ITS CODE: it asserts the defaults of three grid props (filtersToggle, backdrop, backdropFloor) that are not on development, because the grid merge (b1e839a33) has not landed. Chain it in gates:pre in the same landing as that merge.",
|
||||
"check:snippets-draw:mapbox": "AWAITING ITS FIRST BROWSER RUN (rega): the browser suite lists a gate only after it has run. Moves into verify-browser-all's GATES, and out of this list, once that run is recorded. Needs MAP_TOKEN."
|
||||
"check:snippets-draw:mapbox": "AWAITING ITS FIRST BROWSER RUN: the browser suite lists a gate only after it has run. Moves into verify-browser-all's GATES, and out of this list, once that run is recorded. Needs MAP_TOKEN."
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
/**
|
||||
* generate-wagf-region-names.mjs — the WAGF region names, in the reader's language, from vendored CLDR.
|
||||
*
|
||||
* ★ THE DEFECT (rega KA3, 3d64bcad, ?lang=ar). Big Picture's region chart labels its bars with the
|
||||
* ★ THE DEFECT (KA3, 3d64bcad, ?lang=ar). Big Picture's region chart labels its bars with the
|
||||
* prayer API's ENGLISH region names — "Africa", "Asia", "Latin America & Caribbean" — on an Arabic page.
|
||||
* They are not chrome and no catalogue held them: they are DATA labels, so every i18n gate was green
|
||||
* while the chart read English to every reader. The regions are a closed set of seven
|
||||
* (library/colors/wagf-region.js WAGF_REGIONS), which is what makes cataloguing them possible at all.
|
||||
*
|
||||
* ★ WHY GENERATED AND NOT HAND-AUTHORED. Ten locales x seven names is seventy strings I cannot write.
|
||||
* ★ WHY GENERATED AND NOT HAND-AUTHORED. Ten locales x seven names is seventy strings that cannot be hand-written reliably.
|
||||
* Five of the seven ARE standard UN M49 macro-regions, so CLDR already names them in every locale we
|
||||
* ship, and Node's own ICU is the same data library/utils/countryName.js already trusts for countries.
|
||||
* Generating is what keeps a translation out of my hands: the strings are copied from CLDR, committed,
|
||||
|
|
|
|||
|
|
@ -167,8 +167,8 @@ async function shot(name, path, {
|
|||
// ★ WAIT ON THE MAP ITSELF, NOT A CLOCK (2026-09-26). Every map a page (or any frame in it) creates is
|
||||
// recorded, so the capture can wait until each visible one has its style and tiles loaded AND has
|
||||
// drawn features on OUR layers (sources that are not the basemap's). A fixed 7 s wait shot the
|
||||
// upg-100-list counter over a bare basemap: that leaf paints 9.5-16.5 s in (rega, 3 cold loads at
|
||||
// fc2fa2e4). Same predicate rega measures with (_qa-cycle/rega/upglist-fc2fa2e4/upglist.mjs).
|
||||
// upg-100-list counter over a bare basemap: that leaf paints 9.5-16.5 s in (3 cold loads at
|
||||
// fc2fa2e4). The same predicate the browser check measures with.
|
||||
await ctx.addInitScript(() => {
|
||||
window.__SHOT_MAPS = []
|
||||
const patch = (x) => {
|
||||
|
|
@ -300,7 +300,7 @@ await shot('cap3-monolithic-research', `/${TREE_NAME}/doxa-research-map/research
|
|||
// upg-100-mfe (the cap-4 composite) · upg-100-list (the list) · poster-wall.
|
||||
// There are no "list pages" — see the note below the second shot. ----
|
||||
await shot('cap4-upg100-mfe', `/${TREE_NAME}/my-upg-100-list/upg-100-mfe/index.html`, { wait: 8000 })
|
||||
// wait 20000: this leaf PAINTS 9.5-16.5 s after load under swiftshader (rega, 3 cold loads at fc2fa2e4,
|
||||
// wait 20000: this leaf PAINTS 9.5-16.5 s after load under swiftshader (3 cold loads at fc2fa2e4,
|
||||
// judged by rendered features on its own layers), and its "195 polys · 27/27 zones · 2107 pins" counter
|
||||
// appears BEFORE the paint, so a 7 s wait shot the counter over a bare basemap. The shot now waits on the
|
||||
// map itself (style + tiles + features drawn on our layers, see shot()); `wait` is only a fallback.
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ if (!profileModules) {
|
|||
throw new Error('[ProfileLoader] No profileModules provided. Bundle entry must `app.provide("profileModules", import.meta.glob("./*.vue"))`')
|
||||
}
|
||||
|
||||
// ★ A ONE-PROFILE BUNDLE ANSWERS A BARE TAG (rega, DX Life drop-in, 2026-09-29). Every country page
|
||||
// ★ A ONE-PROFILE BUNDLE ANSWERS A BARE TAG (DX Life drop-in, 2026-09-29). Every country page
|
||||
// rendered `⚠️ Profile "" not found.` where its map should be: the host wrote <doxa-country-map>
|
||||
// with no profile-config, profileName resolved to null, and the loader had nothing to load — while
|
||||
// the element sat in the DOM at full size with 0 console errors and 0 failed requests, which is why
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ useShadowStyles(`
|
|||
.rm-side-backdrop.open { opacity:1;pointer-events:auto; }
|
||||
/* box-shadow lives on .open ONLY: when closed the drawer is translateX(100%) off
|
||||
the right edge, but a left-pointing shadow (-4px) bled back onto the map's right
|
||||
edge — the mystery "shadow on the right side" (coder staging QA 2026-06-25). */
|
||||
edge — the mystery "shadow on the right side". */
|
||||
.rm-side-drawer { position:absolute;top:0;right:0;bottom:0;width:340px;max-width:100vw;background:#171c23;color:#e7ebf0;border-left:1px solid #232a33;z-index:1600;transform:translateX(100%);transition:transform .22s ease;display:flex;flex-direction:column;font:13px -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; }
|
||||
.rm-side-drawer.open { transform:translateX(0); box-shadow:-4px 0 16px rgba(0,0,0,0.4); }
|
||||
.rm-side-header { display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #232a33;flex:0 0 auto; }
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ const labelW = computed(() => {
|
|||
return Math.max(96, Math.min(260, Math.round((width.value || 640) * 0.34)))
|
||||
})
|
||||
// Room on the right for the printed value when a bar runs long.
|
||||
// The value column fits the LONGEST value label (rega, row 82: a fixed 74px clipped "10,160,000" at the edge
|
||||
// The value column fits the LONGEST value label (row 82: a fixed 74px clipped "10,160,000" at the edge
|
||||
// of a 335px card). ~7px per character at the value font, plus the 8px gap and a margin; never under 74.
|
||||
const VALUE_GUTTER = computed(() => {
|
||||
const longest = Math.max(0, ...rows.value.filter((r) => !r.unknown).map((r) => String(props.format(total(r))).length))
|
||||
|
|
@ -199,7 +199,7 @@ useShadowStyles(
|
|||
|
||||
<!-- direction:ltr on the SVG: its geometry is left-to-right by construction (labels at x=0, values after
|
||||
the bar end). Under an inherited rtl, text-anchor start flips, so labels ran off the left edge and
|
||||
values back over their bars (rega, row 82, ar). Each label's own text still shapes as Arabic. -->
|
||||
values back over their bars (row 82, ar). Each label's own text still shapes as Arabic. -->
|
||||
<svg v-else :width="width || 640" :height="svgH" role="img" :aria-label="ariaLabel" direction="ltr" style="direction:ltr">
|
||||
<defs>
|
||||
<!-- Hatching means NOT MEASURED. It must not look like a small bar. -->
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ function addTrunks(rows) {
|
|||
// the research palette remains free to change its own neutral without reaching in here.
|
||||
const KIT_NEUTRAL_SWATCH = '#c4c8c0'
|
||||
// A dashboard that supplies no `legend` gets an honest degraded rail — uncoloured swatches and raw
|
||||
// values — rather than a crash. That is the state go-int sees before it wires its own palette, and
|
||||
// values — rather than a crash. That is the state a new dashboard sees before it wires its own palette, and
|
||||
// a half-configured dashboard should look plain, not broken.
|
||||
const legend = computed(() => (cfg && cfg.legend) || null)
|
||||
const colorFor = (...a) => (legend.value?.colorFor ? legend.value.colorFor(...a) : KIT_NEUTRAL_SWATCH)
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@ onBeforeUnmount(() => {
|
|||
})
|
||||
|
||||
useShadowStyles(`
|
||||
/* ★ NOT ON PAPER (rega, RQ-RGPRINT on fc93c97e4). "Tap a coloured dot — someone still needs
|
||||
/* ★ NOT ON PAPER (measured on a print of fc93c97e4). "Tap a coloured dot — someone still needs
|
||||
prayer" printed across the bottom of the map. It is an instruction for a finger, addressed to
|
||||
a reader who is now holding a sheet of paper; on the page it reads as part of the map's own
|
||||
caption and is simply untrue there. */
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ useShadowStyles(`
|
|||
left:8px, width:380px) so the LegendDesktop card and the SemanticTreeLegend
|
||||
sit at exactly the same position+size — no visible jump when the user
|
||||
clicks a pin and the detail panel swaps in over the language-family legend
|
||||
(qa: 2026-05-02). */
|
||||
*/
|
||||
.legend-container{position:absolute;top:60px;inset-inline-start:8px;width:var(--map-legend-width,380px);max-height:calc(100vh - 80px);background:#fff;border-radius:var(--map-radius,16px);box-shadow:0 2px 8px rgba(0,0,0,0.12),0 1px 3px rgba(0,0,0,0.08);z-index:1000;overflow:hidden;display:flex;flex-direction:column;transition:width 200ms cubic-bezier(0.2,0,0,1),max-height 200ms cubic-bezier(0.2,0,0,1),min-width 200ms cubic-bezier(0.2,0,0,1),border-radius 200ms linear,box-shadow 200ms linear;will-change:width,max-height;}
|
||||
/* ── DESKTOP TYPE SCALE for the LegendRows-based card (2026-09-16: larger, more
|
||||
readable desktop legends). The semantic-tree panel's scale lives in SemanticTreeLegend.vue
|
||||
|
|
@ -124,7 +124,7 @@ useShadowStyles(`
|
|||
|
||||
/* Desktop slim rows — scoped to .legend-container so mobile (.legend-mobile-sheet)
|
||||
keeps its 44px tap targets. Original desktop rows were 36px tall with 6px
|
||||
pill padding — too clunky per user feedback 2026-04-27. */
|
||||
pill padding — too clunky in QA review (2026-04-27). */
|
||||
.legend-container .lrg-row,
|
||||
.legend-container .lft-row{min-height:24px;}
|
||||
.legend-container .lrg-item-inner,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ useShadowStyles(`
|
|||
single tight row, slightly reduced and translucent. The corners sit just above the sheet's
|
||||
collapsed strip (48px), so the watermark is always visible when the legend is closed; an
|
||||
opened sheet covers it. */
|
||||
/* ★ THE FAB SITS ON THE ATTRIBUTION TOO, not just the sheet (rega at 390x844, dx-life
|
||||
/* ★ THE FAB SITS ON THE ATTRIBUTION TOO, not just the sheet (measured at 390x844 on DX Life's
|
||||
/research: the gallery's 44px vtl-fab at (12,788) is topmost over Cities' bottom-left
|
||||
attribution line "…oundaries · OpenFreeMap"). This rule already lifted the engine's bottom
|
||||
corners clear of the legend SHEET; it never knew about the circle, which lives in the LAYOUT
|
||||
|
|
@ -146,7 +146,7 @@ useShadowStyles(`
|
|||
row's column-1 caret slot (LegendRows .lrg-title-caret-slot or
|
||||
SemanticTreeLegend .stl-tb-caret-slot). Vertical alignment with the
|
||||
title text comes from the slot's align-items:center, so no absolute
|
||||
positioning or padding offsets are needed (qa: 2026-05-02 iter-9). */
|
||||
positioning or padding offsets are needed. */
|
||||
/* Collapse caret — matches STL's .stl-collapse-btn exactly (22x20px,
|
||||
same bg/border/radius/hover as the desktop SemanticTreeLegend caret). */
|
||||
.mobile-collapse-caret{width:22px;height:20px;display:flex;align-items:center;justify-content:center;background:rgba(208,215,222,0.4);border:1px solid #d0d7de;border-radius:5px;cursor:pointer;color:#57606a;padding:0;transition:transform 0.3s ease-out,color 0.1s,background 0.1s,border-color 0.1s;transform-origin:center;outline:none;-webkit-tap-highlight-color:transparent;flex-shrink:0;}
|
||||
|
|
@ -193,7 +193,7 @@ useShadowStyles(`
|
|||
a DEFINITE height via flex:1 — height:100% on a non-flex parent with only
|
||||
flex:1 (no explicit height) falls back to auto, which made the inner
|
||||
scrollable shorter than the sheet on tier-3 fullyOpen and left a white
|
||||
gap at the bottom (qa: 2026-05-02 iter-10).
|
||||
gap at the bottom.
|
||||
IMPORTANT: NO backticks anywhere in this comment block — it lives
|
||||
inside a JS template literal (useShadowStyles) and a stray backtick
|
||||
silently closes the string and blanks the entire mobile stylesheet. */
|
||||
|
|
@ -217,7 +217,7 @@ useShadowStyles(`
|
|||
breathing room on each side — caret doesn't hug the sheet edge. The
|
||||
title row's subgrid offsets the title text so it begins right after
|
||||
the caret without overlap. Same widening on column 5 (right gutter)
|
||||
keeps the table visually balanced. qa: 2026-05-02 iter-9. */
|
||||
keeps the table visually balanced. */
|
||||
.legend-mobile-sheet .legend-row-group{--lrg-caret-col:24px;}
|
||||
.legend-content::-webkit-scrollbar{width:4px;}
|
||||
.legend-content::-webkit-scrollbar-track{background:transparent;}
|
||||
|
|
@ -238,7 +238,7 @@ useShadowStyles(`
|
|||
/* Fully-collapsed sheet (showing only "Legend" + caret) drops the
|
||||
16px top-corner radius — square edges look cleaner when the sheet
|
||||
is acting as a thin bottom footer. Rounded corners return when
|
||||
expanded (user feedback 2026-04-27). */
|
||||
expanded. */
|
||||
.legend-mobile-sheet.collapsed{box-shadow:0 -2px 8px rgba(0,0,0,0.15);height:48px !important;min-height:48px;border-top-left-radius:0;border-top-right-radius:0;padding-inline-start:var(--map-fab-beside,0px);}
|
||||
/* The detail footer is placed absolutely, so the sheet's padding does not reach it: the same inset, directly. */
|
||||
.legend-mobile-sheet.collapsed .collapsed-detail-footer{inset-inline-start:var(--map-fab-beside,0px);}
|
||||
|
|
@ -263,7 +263,7 @@ useShadowStyles(`
|
|||
.legend-mobile-sheet.collapsed .lft-title-row,
|
||||
.legend-mobile-sheet.collapsed .stl-titlebar{padding:0 16px!important;display:flex;align-items:center;justify-content:center;gap:8px;height:48px;min-height:0!important;border-bottom:none!important;}
|
||||
/* line-height:1.4 (not 1) so the descender of 'g' in "Legend" / "Engagement
|
||||
Progress" isn't clipped at the bottom — qa: 2026-05-02. */
|
||||
Progress" isn't clipped at the bottom. */
|
||||
.legend-mobile-sheet.collapsed .stl-tb-title,
|
||||
.legend-mobile-sheet.collapsed .lrg-title,
|
||||
.legend-mobile-sheet.collapsed .lrg-title-row .lrg-title,
|
||||
|
|
@ -294,8 +294,8 @@ useShadowStyles(`
|
|||
.legend-mobile-sheet .stl-panel.closed{transform:none!important;opacity:1!important;pointer-events:auto!important;}
|
||||
.legend-mobile-sheet .stl-inner{border:none!important;border-radius:0!important;box-shadow:none!important;background:transparent!important;}
|
||||
/* Slim row height on mobile prayer/engagement/adoption tabs so they read
|
||||
as thin/dense like desktop, not chunky touch-targets (qa: 2026-05-03 user
|
||||
feedback — "desktop legend rows are thinner, can you make mobile match").
|
||||
as thin/dense like desktop, not chunky touch-targets (the mobile
|
||||
rows match the thinner desktop rows).
|
||||
Drops .lrg-item-inner min-height 36→28, vertical padding 6→2, and tightens
|
||||
the .lrg-items row-gap 6→3 for the same compact-table feel. */
|
||||
.legend-mobile-sheet .lrg-item-inner{min-height:28px!important;padding:2px 0!important;}
|
||||
|
|
@ -306,7 +306,7 @@ useShadowStyles(`
|
|||
only sets flex:1 — without min-height:0, the flex item's default
|
||||
min-height:auto = content height, so a long list grows past the parent
|
||||
instead of scrolling, leaving white space below the panel on tier-3
|
||||
fullyOpen (qa: 2026-05-02 iter-11). LegendRows' .lrg-items already has
|
||||
fullyOpen. LegendRows' .lrg-items already has
|
||||
min-height:0 in its base CSS, which is why iter-10 fixed Prayer/Engagement/
|
||||
Adoption but missed Language Families. */
|
||||
.legend-mobile-sheet .stl-rows{min-height:0;}
|
||||
|
|
@ -315,7 +315,7 @@ useShadowStyles(`
|
|||
/* (Removed iter-1 rule that was setting padding-left:0 here — it was
|
||||
overriding the iter-5 padding-left:36px rule above, causing the caret
|
||||
to overlap the title text "Lan-guage Families" → "guage Families"
|
||||
visible. qa: 2026-05-02.) Border-bottom color preserved. */
|
||||
visible.) Border-bottom color preserved. */
|
||||
.legend-mobile-sheet .stl-titlebar{border-bottom-color:rgba(0,0,0,0.08)!important;}
|
||||
|
||||
/* ── Mobile language-family tree overrides ──
|
||||
|
|
@ -323,8 +323,7 @@ useShadowStyles(`
|
|||
The desktop CSS makes the title-row a SUBGRID of .lft-items so the
|
||||
UPGS / POPULATION column headers line up with the data rows' badges.
|
||||
An explicit grid-template-columns on the title-row breaks subgrid
|
||||
inheritance and causes the misaligned headers we saw in user feedback
|
||||
(2026-04-27).
|
||||
inheritance and causes misaligned headers.
|
||||
Tap-area: rows are 44px tall (Apple HIG) so the row is comfortably
|
||||
tappable; the in-row caret stays slim like desktop. The colored pill
|
||||
keeps its desktop look.
|
||||
|
|
@ -448,7 +447,7 @@ const dataStore = inject('dataStore')
|
|||
|
||||
// Provided by research-map app profile so the mobile SemanticTreeLegend
|
||||
// row-clicks fire the same dim/clear pipeline as the desktop instance
|
||||
// (qa: 2026-05-03 iter-18 — without this, deselecting a language-family
|
||||
// (without this, deselecting a language-family
|
||||
// row didn't restore the dimmed pins because mapStore.selectFamily was
|
||||
// never updated by the mobile flow).
|
||||
const onSemanticTreeSelect = inject('onSemanticTreeSelect', () => {})
|
||||
|
|
@ -984,7 +983,7 @@ onBeforeUnmount(() => { if (_creditTimer) { clearTimeout(_creditTimer); _creditT
|
|||
detail mode. PeopleGroupDetail isn't designed to render at 48px, so
|
||||
we render a footer-style title bar inline (caret + people-group
|
||||
name) that mimics the LegendRows / SemanticTreeLegend collapsed
|
||||
footer pattern. (qa: 2026-05-03 user feedback iter-16) -->
|
||||
footer pattern. -->
|
||||
<div
|
||||
v-if="legendState === 'collapsed' && legendMode === 'detail' && selectedPeopleGroup"
|
||||
class="collapsed-detail-footer"
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ useShadowStyles(`
|
|||
part of the legend chrome. Dark is the STL default; .lpb-light mirrors the
|
||||
.stl-panel[data-theme="light"] palette. ── */
|
||||
.lpb{position:relative;display:flex;align-items:center;gap:8px;min-width:0;width:100%;box-sizing:border-box;}
|
||||
/* Hit area vs paint (WCAG 2.5.8, rega at 390: every segment was a 10px-tall button). The track is 24px
|
||||
/* Hit area vs paint (WCAG 2.5.8, measured at 390: every segment was a 10px-tall button). The track is 24px
|
||||
tall so each segment button is a 24px target, but it paints only a 10px band: the track's background is
|
||||
a centred 10px strip and each segment clips its colour to its content box inside 7px of padding. The
|
||||
-7px margins keep the legend's layout exactly 10px tall, as before. */
|
||||
|
|
@ -199,7 +199,7 @@ function hide() { activeKey.value = null }
|
|||
fills the span from the left and the has-prayer colour completes it. -->
|
||||
<span class="lpb-span" :style="{ width: coveredPct + '%' }" :data-span-pct="coveredPct.toFixed(2)">
|
||||
<!-- An empty segment is not drawn: a zero-width button is an invisible tab stop, and it took the
|
||||
bar's rounded left end (rega). -->
|
||||
bar's rounded left end. -->
|
||||
<button
|
||||
v-for="seg in spanSegs.filter(s => segPctOfSpan(s) > 0)" :key="seg.key"
|
||||
type="button"
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ useShadowStyles(`
|
|||
Background darkens the row color by 28% (mix with #000) so white badge text
|
||||
stays readable on bright rows like the engagement-tab "Engaged" green. The
|
||||
previous mix used currentColor (which is white in light mode), so on bright
|
||||
rows it LIGHTENED the badge — wrong direction. qa: 2026-05-02. */
|
||||
rows it LIGHTENED the badge — wrong direction. */
|
||||
.lrg-badge{display:flex;align-items:center;justify-content:center;}
|
||||
.lrg-badge-inner{display:inline-block;background:color-mix(in srgb, var(--lrg-item-color, #888), #000 28%);border-radius:8px;padding:2px 10px;font-size:11px;font-weight:600;font-family:'Courier New',monospace;white-space:nowrap;min-width:32px;text-align:center;}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue