You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(web,api): trace the mark from the official export instead of the brand board
The board was the wrong source and the method was wrong for this shape.
`Brand.png` is a picture of the logo: a dark panel, a glow around the mark, and
a resolution chosen for a contact sheet. Tracing it meant colour-thresholding
lime out of that and hoping the halo fell outside the threshold. `Logo SENT.png`
is the artwork — transparent background, no glow, 1254px. The mask is "alpha >
127", which has nothing to tune and no halo to exclude.
THE ROUNDING WAS DONE TWICE
The previous trace eroded the mask, kept a small set of vertices, and told the
consumer to stroke them with a round join. That is the right trick when a shape
has SHARP corners in the source and you want them rounded. This one's are
already rounded, so eroding and re-stroking rounded them again — and spent two
dozen vertices retracing curves that were already in the file, which is what
should have given it away.
Tracing the outline as it stands reproduces the artwork including corners that
differ from one another. Thirty vertices per form, simplification error near
0.05 viewBox units: a twentieth of a pixel at 32px, under one on a 512px icon.
No stroke, no radius constant, nothing to keep in step.
The script now prefers the official export and falls back to the board, and its
tolerance is a fraction of the artwork's extent so a larger export does not
produce proportionally more vertices.
Verified by rendering the emitted paths and comparing against the export, then
in the app and on the share card.
Copy file name to clipboardExpand all lines: apps/web/src/components/Logo.tsx
+26-33Lines changed: 26 additions & 33 deletions
Original file line number
Diff line number
Diff line change
@@ -3,27 +3,26 @@
3
3
*
4
4
* WHERE THIS GEOMETRY COMES FROM
5
5
* ------------------------------
6
-
* `Brand.png`, in the repository root, measured. The previous version of this
7
-
* file was drawn by eye from that board and said so; it was three flat slabs and
8
-
* the real mark is two stepped diagonal forms with 180° rotational symmetry, so
9
-
* it did not look like the brand on any page that used it — which is every page,
10
-
* plus the favicon.
6
+
* `Logo SENT.png`, the official export, measured. Not drawn by eye — an earlier
7
+
* version of this file was, and it was three flat slabs where the mark is two
8
+
* stepped diagonal forms, on every page and in the favicon.
11
9
*
12
-
* The board was there the whole time. The shape is a measurement rather than an
13
-
* opinion: the volt-lime pixels were masked, the two components traced with a
14
-
* Moore boundary walk, and each contour reduced to the handful of vertices it
15
-
* actually has. Re-derive with `scripts/trace-mark.py` if the board changes.
10
+
* `scripts/trace-mark.py` masks the artwork's alpha channel, walks each form's
11
+
* boundary and reduces it to the vertices it actually has. It prints exactly the
12
+
* constants below; run it when the artwork changes.
16
13
*
17
-
* WHY THE CORNERS ARE A STROKE AND NOT ARCS
18
-
* -----------------------------------------
19
-
* Every corner on the mark is rounded by the same radius. Writing that as arc
20
-
* segments would mean twelve hand-tuned curves per path and a shape nobody can
21
-
* safely edit afterwards.
14
+
* WHY THESE ARE PLAIN FILLED POLYGONS
15
+
* -----------------------------------
16
+
* A version before this traced an eroded mask and stroked it with a round join,
17
+
* which is how you round the corners of a shape whose corners are sharp in the
18
+
* source. This one's are not — the export already has its rounding — so that
19
+
* rounded everything twice and spent two dozen vertices retracing curves that
20
+
* were already there.
22
21
*
23
-
* Instead each path is the outline INSET by the corner radius, stroked with
24
-
* twice that radius and a round line join. The stroke grows the shape back to
25
-
* its true size with every corner rounded uniformly and exactly. It is why the
26
-
* polygons below are traced from an eroded mask rather than the raw one.
22
+
* Tracing the outline as it stands reproduces the artwork, including corners
23
+
* that differ from one another. Roughly thirty vertices per form, with a
24
+
* simplification error near 0.05 viewBox units: a twentieth of a pixel at 32px,
25
+
* under one pixel on a 512px app icon.
27
26
*
28
27
* The mark is never re-coloured beyond the LOCKED palette and never stretched:
29
28
* `preserveAspectRatio` is left at its default for exactly that reason.
@@ -32,17 +31,17 @@
32
31
importtype{JSX}from"react";
33
32
34
33
/**
35
-
* The two forms, inset by {@link CORNER}, in a 32×32 box.
34
+
* The two forms, in a 32×32 box, traced from the official export.
36
35
*
37
-
* Traced from `Brand.png`. The pair reads as an S at a glance and as two
38
-
* offset slabs up close, which is what the board's "clearspace and grid" panel
39
-
* is protecting — hence the margin baked into these coordinates.
36
+
* The pair reads as an S at a glance and as two offset slabs up close, which is
37
+
* what the board's clear-space panel is protecting — hence the margin baked
38
+
* into these coordinates.
40
39
*/
41
-
constUPPER="M 14.16 1.96 L 20.23 8.34 L 22.78 8.82 L 28.37 8.66 L 29.96 10.41 L 29.96 16.64 L 28.85 17.6 L 14.8 8.5 L 14.32 7.38 L 14.16 2.12 Z";
42
-
constLOWER="M 3.15 13.29 L 11.29 20.31 L 18.95 24.3 L 19.59 25.89 L 19.59 30.04 L 12.09 22.38 L 4.27 22.38 L 2.99 21.9 L 2.2 20.63 L 2.04 18.55 L 2.04 15.04 L 2.99 13.45 Z";
40
+
constUPPER=
41
+
"M 13.94 1.0 L 14.63 1.03 L 15.32 1.38 L 22.43 8.53 L 22.78 8.77 L 23.2 8.98 L 23.96 9.18 L 29.37 9.22 L 30.06 9.5 L 30.48 9.84 L 30.86 10.47 L 31.0 11.09 L 31.0 17.99 L 30.86 18.69 L 30.48 19.35 L 29.86 19.87 L 29.06 20.14 L 27.5 20.14 L 26.7 19.87 L 20.28 15.25 L 13.83 10.88 L 13.28 10.4 L 12.83 9.71 L 12.65 9.18 L 12.58 8.7 L 12.58 2.42 L 12.72 1.87 L 12.93 1.55 L 13.35 1.21 L 13.9 1.03 Z";
43
42
44
-
/** Corner radius in viewBox units, from the board. */
45
-
constCORNER=0.957;
43
+
constLOWER=
44
+
"M 3.08 11.92 L 4.68 11.96 L 5.13 12.1 L 5.61 12.38 L 11.96 18.24 L 18.72 22.29 L 19.38 22.85 L 19.8 23.47 L 20.04 24.41 L 20.04 29.72 L 19.94 30.17 L 19.76 30.48 L 19.31 30.86 L 18.86 31.0 L 18.27 30.93 L 17.96 30.76 L 17.27 30.03 L 11.58 23.4 L 11.09 22.95 L 10.36 22.54 L 9.53 22.33 L 2.8 22.33 L 1.97 22.05 L 1.49 21.64 L 1.14 21.05 L 1.0 20.42 L 1.03 13.8 L 1.31 13.03 L 1.66 12.58 L 2.21 12.17 L 2.7 11.99 L 3.05 11.96 Z";
Copy file name to clipboardExpand all lines: services/api/src/preview.ts
+9-12Lines changed: 9 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -74,20 +74,17 @@ const WARN = "#fbbf24";
74
74
* diagonal forms, so the artefact that travels furthest carried a glyph that is
75
75
* not the logo — on every link anyone ever posted.
76
76
*
77
-
* Measured from `Brand.png` by `scripts/trace-mark.py`, which prints exactly
78
-
* these constants; `apps/web/src/components/Logo.tsx` holds the same values for
79
-
* the same reason the colours are repeated here. An SVG served to a crawler has
80
-
* no stylesheet and no imports — it has to be self-contained, and the price of
81
-
* that is a copy. The script is the source; both copies are its output.
82
-
*
83
-
* The paths are the outline INSET by the corner radius, stroked with twice it
84
-
* and a round join, which rounds every corner uniformly without a dozen arcs.
77
+
* Measured from the official export by `scripts/trace-mark.py`, which prints
78
+
* exactly these constants; `apps/web/src/components/Logo.tsx` holds the same
79
+
* values for the same reason the colours are repeated here. An SVG served to a
80
+
* crawler has no stylesheet and no imports — it has to be self-contained, and
81
+
* the price of that is a copy. The script is the source; both copies are its
82
+
* output.
85
83
*/
86
84
constMARK_UPPER=
87
-
"M 14.16 1.96 L 20.23 8.34 L 22.78 8.82 L 28.37 8.66 L 29.96 10.41 L 29.96 16.64 L 28.85 17.60 L 14.80 8.50 L 14.32 7.38 L 14.16 2.12 Z";
85
+
"M 13.94 1.0 L 14.63 1.03 L 15.32 1.38 L 22.43 8.53 L 22.78 8.77 L 23.2 8.98 L 23.96 9.18 L 29.37 9.22 L 30.06 9.5 L 30.48 9.84 L 30.86 10.47 L 31.0 11.09 L 31.0 17.99 L 30.86 18.69 L 30.48 19.35 L 29.86 19.87 L 29.06 20.14 L 27.5 20.14 L 26.7 19.87 L 20.28 15.25 L 13.83 10.88 L 13.28 10.4 L 12.83 9.71 L 12.65 9.18 L 12.58 8.7 L 12.58 2.42 L 12.72 1.87 L 12.93 1.55 L 13.35 1.21 L 13.9 1.03 Z";
88
86
constMARK_LOWER=
89
-
"M 3.15 13.29 L 11.29 20.31 L 18.95 24.30 L 19.59 25.89 L 19.59 30.04 L 12.09 22.38 L 4.27 22.38 L 2.99 21.90 L 2.20 20.63 L 2.04 18.55 L 2.04 15.04 L 2.99 13.45 Z";
90
-
constMARK_CORNER=0.957;
87
+
"M 3.08 11.92 L 4.68 11.96 L 5.13 12.1 L 5.61 12.38 L 11.96 18.24 L 18.72 22.29 L 19.38 22.85 L 19.8 23.47 L 20.04 24.41 L 20.04 29.72 L 19.94 30.17 L 19.76 30.48 L 19.31 30.86 L 18.86 31.0 L 18.27 30.93 L 17.96 30.76 L 17.27 30.03 L 11.58 23.4 L 11.09 22.95 L 10.36 22.54 L 9.53 22.33 L 2.8 22.33 L 1.97 22.05 L 1.49 21.64 L 1.14 21.05 L 1.0 20.42 L 1.03 13.8 L 1.31 13.03 L 1.66 12.58 L 2.21 12.17 L 2.7 11.99 L 3.05 11.96 Z";
91
88
/** The mark is authored in a 32-unit box; the card wants it at 44. */
92
89
constMARK_SCALE=44/32;
93
90
@@ -216,7 +213,7 @@ export function renderPreview(m: PreviewMarket): string {
216
213
217
214
<!-- Brand mark. §231: the platform is named on anything that travels. -->
0 commit comments