@humanforest/nuxt-layer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +67 -0
- package/README.md +208 -0
- package/app.config.ts +10 -0
- package/assets/icons/forest/bike-asterisk.svg +21 -0
- package/assets/icons/forest/bike-down.svg +19 -0
- package/assets/icons/forest/bike-off.svg +20 -0
- package/assets/icons/forest/bike-up.svg +19 -0
- package/assets/icons/forest/bike-x.svg +19 -0
- package/assets/icons/forest/bike.svg +18 -0
- package/assets/icons/forest/mark-fill.svg +6 -0
- package/assets/icons/forest/mark.svg +6 -0
- package/assets/icons/forest/parking.svg +3 -0
- package/assets/icons/forest/star-fill.svg +4 -0
- package/assets/icons/forest/star.svg +4 -0
- package/assets/icons/forest/traffic-light-caution.svg +8 -0
- package/assets/icons/forest/traffic-light-go.svg +8 -0
- package/assets/icons/forest/traffic-light-lit.svg +8 -0
- package/assets/icons/forest/traffic-light-stop.svg +8 -0
- package/assets/icons/forest/traffic-light.svg +8 -0
- package/nuxt.config.ts +81 -0
- package/package.json +35 -0
- package/packages/charts/src/FBoroughShape.vue +52 -0
- package/packages/charts/src/FCalendarGrid.vue +332 -0
- package/packages/charts/src/FCellLegend.vue +54 -0
- package/packages/charts/src/FChartFrame.vue +201 -0
- package/packages/charts/src/FChartFrameSingle.vue +91 -0
- package/packages/charts/src/FChartLegend.vue +26 -0
- package/packages/charts/src/FDistributionBar.vue +224 -0
- package/packages/charts/src/FDottedMap.vue +335 -0
- package/packages/charts/src/FLondonMap.vue +399 -0
- package/packages/charts/src/FSparkline.vue +198 -0
- package/packages/charts/src/FStatusTrack.vue +151 -0
- package/packages/charts/src/cellSize.ts +46 -0
- package/packages/charts/src/distribution.ts +99 -0
- package/packages/charts/src/engine.ts +15 -0
- package/packages/charts/src/forestTooltip.ts +110 -0
- package/packages/charts/src/fromCategories.ts +43 -0
- package/packages/charts/src/index.ts +87 -0
- package/packages/charts/src/londonAreas.ts +75 -0
- package/packages/charts/src/londonGrid.ts +67 -0
- package/packages/charts/src/motionDuration.ts +49 -0
- package/packages/charts/src/presets.ts +143 -0
- package/packages/charts/src/resolveVar.ts +21 -0
- package/packages/charts/src/snapTooltip.ts +154 -0
- package/packages/charts/src/tooltipStandIn.ts +58 -0
- package/packages/charts/src/useCellScale.ts +155 -0
- package/packages/charts/src/useChartPalette.ts +61 -0
- package/packages/charts/src/useChartRepaintKey.ts +22 -0
- package/packages/charts/src/useThemeVersion.ts +17 -0
- package/packages/frames/src/FBrowserFrame.vue +53 -0
- package/packages/frames/src/FDeviceFrame.vue +242 -0
- package/packages/frames/src/FFitFrame.vue +83 -0
- package/packages/frames/src/art/iphone-11.svg +124 -0
- package/packages/frames/src/art/iphone-12.svg +601 -0
- package/packages/frames/src/art/iphone-13-pro.svg +820 -0
- package/packages/frames/src/art/iphone-13.svg +849 -0
- package/packages/frames/src/art/iphone-14.svg +681 -0
- package/packages/frames/src/art/iphone-15-pro.svg +633 -0
- package/packages/frames/src/art/iphone-15.svg +713 -0
- package/packages/frames/src/art/iphone-16-plus.svg +685 -0
- package/packages/frames/src/art/iphone-16-pro-max.svg +611 -0
- package/packages/frames/src/art/iphone-16-pro.svg +631 -0
- package/packages/frames/src/art/iphone-16.svg +713 -0
- package/packages/frames/src/art/iphone-17-pro-max.svg +355 -0
- package/packages/frames/src/art/iphone-17.svg +305 -0
- package/packages/frames/src/art/iphone-air.svg +389 -0
- package/packages/frames/src/art/iphone-se-3.svg +473 -0
- package/packages/frames/src/art/iphone-x.svg +652 -0
- package/packages/frames/src/art/pixel-10-pro-xl.svg +32 -0
- package/packages/frames/src/art/pixel-10-pro.svg +32 -0
- package/packages/frames/src/art/pixel-10.svg +32 -0
- package/packages/frames/src/art/pixel-8-pro.svg +208 -0
- package/packages/frames/src/art/pixel-8.svg +208 -0
- package/packages/frames/src/art/pixel-8a.svg +8 -0
- package/packages/frames/src/art/pixel-9-pro-xl.svg +32 -0
- package/packages/frames/src/art/pixel-9-pro.svg +34 -0
- package/packages/frames/src/art/pixel-9a.svg +25 -0
- package/packages/frames/src/art.ts +29 -0
- package/packages/frames/src/devices.ts +337 -0
- package/packages/frames/src/index.ts +15 -0
- package/packages/tokens/geo/london-boroughs.json +1 -0
- package/packages/tokens/geo/london-dots-coarse.json +1 -0
- package/packages/tokens/geo/london-dots-fine.json +1 -0
- package/packages/tokens/geo/london-dots-medium.json +1 -0
- package/packages/tokens/geo/london-dots-ultra.json +1 -0
- package/packages/tokens/geo/london-wards.json +1 -0
- package/packages/tokens/glyphs/glyphs.json +1 -0
- package/packages/tokens/logos/f-rot.svg +4 -0
- package/packages/tokens/logos/f.svg +4 -0
- package/packages/tokens/logos/favicon-c2w.svg +9 -0
- package/packages/tokens/logos/favicon-console.svg +9 -0
- package/packages/tokens/logos/favicon-ds.svg +9 -0
- package/packages/tokens/logos/favicon-fleet.svg +9 -0
- package/packages/tokens/logos/favicon-flex.svg +9 -0
- package/packages/tokens/logos/favicon-plus.svg +9 -0
- package/packages/tokens/logos/favicon-radar.svg +9 -0
- package/packages/tokens/logos/favicon-tower.svg +9 -0
- package/packages/tokens/logos/lockup-horizontal.svg +17 -0
- package/packages/tokens/logos/lockup-vertical.svg +17 -0
- package/packages/tokens/logos/mark-mono.svg +4 -0
- package/packages/tokens/logos/mark.svg +7 -0
- package/packages/tokens/logos/wordmark.svg +9 -0
- package/packages/tokens/src/colourEngine.ts +604 -0
- package/packages/tokens/src/glyphs.ts +127 -0
- package/packages/tokens/src/logo.ts +50 -0
- package/packages/tokens/src/subbrands.ts +44 -0
- package/packages/tokens/src/sublogo.ts +80 -0
- package/packages/ui/icons/forest/map/forest-place-count.svg +21 -0
- package/packages/ui/icons/forest/map/forest-place-marker.svg +17 -0
- package/packages/ui/icons/forest/map/forest-vehicle-marker.svg +73 -0
- package/packages/ui/icons/forest/map/manifest.json +373 -0
- package/packages/ui/icons/forest/map/place-count-manifest.json +83 -0
- package/packages/ui/icons/forest/map/place-manifest.json +74 -0
- package/packages/ui/src/address/address.ts +125 -0
- package/packages/ui/src/address/autofill.ts +78 -0
- package/packages/ui/src/address/geocode.ts +55 -0
- package/packages/ui/src/address/index.ts +31 -0
- package/packages/ui/src/address/validate.ts +91 -0
- package/packages/ui/src/canvas/FCanvasCard.vue +97 -0
- package/packages/ui/src/canvas/FCanvasControl.vue +121 -0
- package/packages/ui/src/canvas/FCanvasControlGroup.vue +100 -0
- package/packages/ui/src/canvas/FCanvasFlyout.vue +216 -0
- package/packages/ui/src/canvas/FCanvasHud.vue +402 -0
- package/packages/ui/src/canvas/canvasSurface.ts +39 -0
- package/packages/ui/src/canvas/index.ts +17 -0
- package/packages/ui/src/contexts/ForestContext.vue +53 -0
- package/packages/ui/src/contexts/contexts.ts +153 -0
- package/packages/ui/src/contexts/index.ts +23 -0
- package/packages/ui/src/contexts/marketing-theme.ts +214 -0
- package/packages/ui/src/contexts/mobile-theme.ts +402 -0
- package/packages/ui/src/filter/FFilterBar.vue +72 -0
- package/packages/ui/src/filter/FFilterChip.vue +362 -0
- package/packages/ui/src/filter/FFilterClauses.vue +104 -0
- package/packages/ui/src/filter/FFilterTrigger.vue +183 -0
- package/packages/ui/src/filter/filter.theme.ts +27 -0
- package/packages/ui/src/filter/filterClause.ts +265 -0
- package/packages/ui/src/filter/filterPredicate.ts +134 -0
- package/packages/ui/src/filter/filterSchema.ts +82 -0
- package/packages/ui/src/filter/index.ts +36 -0
- package/packages/ui/src/forest-preset.ts +68 -0
- package/packages/ui/src/icons.ts +79 -0
- package/packages/ui/src/index.ts +17 -0
- package/packages/ui/src/kpi/FKpi.vue +253 -0
- package/packages/ui/src/kpi/FKpiGroup.vue +161 -0
- package/packages/ui/src/kpi/index.ts +20 -0
- package/packages/ui/src/kpi/kpi.theme.ts +168 -0
- package/packages/ui/src/kpi/kpiDelta.ts +82 -0
- package/packages/ui/src/kpi/kpiFormat.ts +72 -0
- package/packages/ui/src/kpi/kpiGroupState.ts +63 -0
- package/packages/ui/src/logo/FLogo.vue +52 -0
- package/packages/ui/src/logo/FSubLogo.vue +214 -0
- package/packages/ui/src/logo/index.ts +8 -0
- package/packages/ui/src/map/FMap.vue +355 -0
- package/packages/ui/src/map/FMapCompass.vue +154 -0
- package/packages/ui/src/map/FMapCoordinates.vue +134 -0
- package/packages/ui/src/map/FMapDrawTools.vue +116 -0
- package/packages/ui/src/map/FMapFullscreen.vue +92 -0
- package/packages/ui/src/map/FMapGeolocate.vue +208 -0
- package/packages/ui/src/map/FMapLayers.vue +75 -0
- package/packages/ui/src/map/FMapLegend.vue +45 -0
- package/packages/ui/src/map/FMapPopup.vue +129 -0
- package/packages/ui/src/map/FMapRamp.vue +69 -0
- package/packages/ui/src/map/FMapRegion.vue +77 -0
- package/packages/ui/src/map/FMapScale.vue +107 -0
- package/packages/ui/src/map/FMapSearch.vue +362 -0
- package/packages/ui/src/map/FMapTilt.vue +87 -0
- package/packages/ui/src/map/FMapTools.vue +61 -0
- package/packages/ui/src/map/FMapZoom.vue +81 -0
- package/packages/ui/src/map/FMarker.vue +218 -0
- package/packages/ui/src/map/FTrackScrubber.vue +94 -0
- package/packages/ui/src/map/FVehicleLegend.vue +72 -0
- package/packages/ui/src/map/FVehicleMark.vue +166 -0
- package/packages/ui/src/map/bin.ts +196 -0
- package/packages/ui/src/map/coordinates.ts +83 -0
- package/packages/ui/src/map/density.ts +401 -0
- package/packages/ui/src/map/draw.ts +356 -0
- package/packages/ui/src/map/ease.ts +67 -0
- package/packages/ui/src/map/fullscreen.ts +59 -0
- package/packages/ui/src/map/heat.ts +160 -0
- package/packages/ui/src/map/index.ts +351 -0
- package/packages/ui/src/map/liveMarkers.ts +60 -0
- package/packages/ui/src/map/map.css +116 -0
- package/packages/ui/src/map/mapColor.ts +31 -0
- package/packages/ui/src/map/mapContext.ts +12 -0
- package/packages/ui/src/map/mapLayers.ts +55 -0
- package/packages/ui/src/map/mapLegend.ts +70 -0
- package/packages/ui/src/map/mapSearch.theme.ts +79 -0
- package/packages/ui/src/map/mapSearch.ts +279 -0
- package/packages/ui/src/map/mapUrl.ts +117 -0
- package/packages/ui/src/map/markerAsset.ts +3 -0
- package/packages/ui/src/map/padding.ts +39 -0
- package/packages/ui/src/map/place.ts +192 -0
- package/packages/ui/src/map/ramp.ts +95 -0
- package/packages/ui/src/map/regionSelect.ts +163 -0
- package/packages/ui/src/map/route.ts +167 -0
- package/packages/ui/src/map/scale.ts +329 -0
- package/packages/ui/src/map/scaleBar.ts +67 -0
- package/packages/ui/src/map/selectionModel.ts +50 -0
- package/packages/ui/src/map/sources/coordinates.ts +58 -0
- package/packages/ui/src/map/sources/mapboxPlaces.ts +71 -0
- package/packages/ui/src/map/style.ts +14 -0
- package/packages/ui/src/map/track.ts +279 -0
- package/packages/ui/src/map/useFeatureSelect.ts +230 -0
- package/packages/ui/src/map/useLiveMarkers.ts +84 -0
- package/packages/ui/src/map/useMap.ts +150 -0
- package/packages/ui/src/map/useMapDraw.ts +776 -0
- package/packages/ui/src/map/useMapOverlay.ts +421 -0
- package/packages/ui/src/map/useMapTableSelection.ts +101 -0
- package/packages/ui/src/map/useMapUrlState.ts +155 -0
- package/packages/ui/src/map/useMarkerSource.ts +163 -0
- package/packages/ui/src/map/useRegionSelect.ts +309 -0
- package/packages/ui/src/map/useTokenMode.ts +61 -0
- package/packages/ui/src/map/useTrackPlayback.ts +131 -0
- package/packages/ui/src/map/useVehicleFilter.ts +51 -0
- package/packages/ui/src/map/useVisibleFeatures.ts +124 -0
- package/packages/ui/src/map/vehicle.ts +807 -0
- package/packages/ui/src/map/vehicleFilter.ts +284 -0
- package/packages/ui/src/map/vehicleLegend.ts +155 -0
- package/packages/ui/src/map/visibleFeatures.ts +192 -0
- package/packages/ui/src/map/zone.ts +291 -0
- package/packages/ui/src/shell/FAppNavbar.vue +68 -0
- package/packages/ui/src/shell/FAppShell.vue +163 -0
- package/packages/ui/src/shell/FAppSidebar.vue +215 -0
- package/packages/ui/src/shell/FPageToolbar.vue +126 -0
- package/packages/ui/src/shell/FScrollShadow.vue +43 -0
- package/packages/ui/src/shell/FSidePanel.vue +258 -0
- package/packages/ui/src/shell/FToolbarActions.vue +32 -0
- package/packages/ui/src/shell/index.ts +33 -0
- package/packages/ui/src/shell/nav.ts +37 -0
- package/packages/ui/src/shell/pageToolbar.ts +69 -0
- package/packages/ui/src/shell/shell.ts +74 -0
- package/packages/ui/src/shell/sidePanel.ts +115 -0
- package/packages/ui/src/themes/accordion.ts +36 -0
- package/packages/ui/src/themes/alert.ts +16 -0
- package/packages/ui/src/themes/auth-form.ts +19 -0
- package/packages/ui/src/themes/avatar-group.ts +9 -0
- package/packages/ui/src/themes/avatar.ts +18 -0
- package/packages/ui/src/themes/badge.ts +51 -0
- package/packages/ui/src/themes/banner.ts +21 -0
- package/packages/ui/src/themes/breadcrumb.ts +10 -0
- package/packages/ui/src/themes/button.mechanics.ts +191 -0
- package/packages/ui/src/themes/button.ts +136 -0
- package/packages/ui/src/themes/calendar.ts +29 -0
- package/packages/ui/src/themes/card.ts +67 -0
- package/packages/ui/src/themes/carousel.ts +41 -0
- package/packages/ui/src/themes/checkbox-group.ts +20 -0
- package/packages/ui/src/themes/checkbox.ts +47 -0
- package/packages/ui/src/themes/chip.ts +50 -0
- package/packages/ui/src/themes/collapsible.ts +26 -0
- package/packages/ui/src/themes/color-picker.ts +13 -0
- package/packages/ui/src/themes/command-palette.ts +37 -0
- package/packages/ui/src/themes/container.ts +14 -0
- package/packages/ui/src/themes/context-menu.ts +38 -0
- package/packages/ui/src/themes/dashboard-group.ts +11 -0
- package/packages/ui/src/themes/dashboard-navbar.ts +10 -0
- package/packages/ui/src/themes/dashboard-panel.ts +18 -0
- package/packages/ui/src/themes/dashboard-resize-handle.ts +35 -0
- package/packages/ui/src/themes/dashboard-sidebar-collapse.ts +7 -0
- package/packages/ui/src/themes/dashboard-sidebar-toggle.ts +7 -0
- package/packages/ui/src/themes/dashboard-sidebar.ts +58 -0
- package/packages/ui/src/themes/dashboard-toolbar.ts +15 -0
- package/packages/ui/src/themes/drawer.ts +45 -0
- package/packages/ui/src/themes/dropdown-menu.ts +38 -0
- package/packages/ui/src/themes/empty.ts +43 -0
- package/packages/ui/src/themes/field-group.ts +52 -0
- package/packages/ui/src/themes/file-upload.ts +38 -0
- package/packages/ui/src/themes/footer-columns.ts +13 -0
- package/packages/ui/src/themes/footer.ts +9 -0
- package/packages/ui/src/themes/form-field.ts +25 -0
- package/packages/ui/src/themes/form.ts +22 -0
- package/packages/ui/src/themes/header.ts +12 -0
- package/packages/ui/src/themes/icon.ts +61 -0
- package/packages/ui/src/themes/index.ts +99 -0
- package/packages/ui/src/themes/input-date.ts +73 -0
- package/packages/ui/src/themes/input-menu.ts +66 -0
- package/packages/ui/src/themes/input-number.ts +58 -0
- package/packages/ui/src/themes/input-rating.ts +25 -0
- package/packages/ui/src/themes/input-tags.ts +63 -0
- package/packages/ui/src/themes/input-time.ts +70 -0
- package/packages/ui/src/themes/input.ts +148 -0
- package/packages/ui/src/themes/kbd.ts +27 -0
- package/packages/ui/src/themes/link.ts +27 -0
- package/packages/ui/src/themes/listbox.ts +48 -0
- package/packages/ui/src/themes/main.ts +6 -0
- package/packages/ui/src/themes/marquee.ts +45 -0
- package/packages/ui/src/themes/modal.ts +46 -0
- package/packages/ui/src/themes/navigation-menu.ts +80 -0
- package/packages/ui/src/themes/page-anchors.ts +7 -0
- package/packages/ui/src/themes/page-aside.ts +7 -0
- package/packages/ui/src/themes/page-card.ts +22 -0
- package/packages/ui/src/themes/page-cta.ts +18 -0
- package/packages/ui/src/themes/page-feature.ts +13 -0
- package/packages/ui/src/themes/page-header.ts +16 -0
- package/packages/ui/src/themes/page-hero.ts +15 -0
- package/packages/ui/src/themes/page-links.ts +12 -0
- package/packages/ui/src/themes/page-section.ts +14 -0
- package/packages/ui/src/themes/page.ts +7 -0
- package/packages/ui/src/themes/pagination.ts +17 -0
- package/packages/ui/src/themes/pin-input.ts +73 -0
- package/packages/ui/src/themes/popover.ts +30 -0
- package/packages/ui/src/themes/progress.ts +29 -0
- package/packages/ui/src/themes/prose.ts +45 -0
- package/packages/ui/src/themes/radio-group.ts +39 -0
- package/packages/ui/src/themes/scroll-area.ts +23 -0
- package/packages/ui/src/themes/select-menu.ts +71 -0
- package/packages/ui/src/themes/select.ts +72 -0
- package/packages/ui/src/themes/separator.ts +28 -0
- package/packages/ui/src/themes/sidebar.ts +127 -0
- package/packages/ui/src/themes/skeleton.ts +15 -0
- package/packages/ui/src/themes/slideover.ts +87 -0
- package/packages/ui/src/themes/slider.ts +48 -0
- package/packages/ui/src/themes/stepper.ts +41 -0
- package/packages/ui/src/themes/switch.ts +63 -0
- package/packages/ui/src/themes/table.ts +34 -0
- package/packages/ui/src/themes/tabs.ts +74 -0
- package/packages/ui/src/themes/textarea.ts +77 -0
- package/packages/ui/src/themes/timeline.ts +25 -0
- package/packages/ui/src/themes/toast.ts +29 -0
- package/packages/ui/src/themes/toaster.ts +66 -0
- package/packages/ui/src/themes/tooltip.ts +31 -0
- package/packages/ui/src/themes/tree.ts +41 -0
- package/packages/ui/src/themes/user.ts +28 -0
- package/styles.cdn.gen.css +2047 -0
- package/theme.gen.json +1 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Word setting from the glyph atlas — turns a string into positioned OUTLINES. No font needs to be
|
|
2
|
+
// loaded and no font parser ships: scripts/glyphs.ts baked the brand fonts to path data at em 1000,
|
|
3
|
+
// and this walks them. Every consumer (the live <FSubLogo>, the SVG exporter) composes here, so a mark
|
|
4
|
+
// on screen and the same mark in a downloaded file are the same shapes.
|
|
5
|
+
//
|
|
6
|
+
// Two brand rules are enforced while setting, not left to the caller:
|
|
7
|
+
//
|
|
8
|
+
// 1. THE F IS ALWAYS THE DRAWN F. The wordmark's f is a custom letterform, not GT Haptik's, so every
|
|
9
|
+
// f in a lead or sub-brand is swapped for the artwork. It carries its own metrics (below).
|
|
10
|
+
// 2. FLAT ASCENDERS ARE CUT TO THE t. GT's b d h k l rise ~20 units above the t; the drawn f stops
|
|
11
|
+
// level with it. Left alone, a set word beside the drawn f has a ragged ascender line, so the flat
|
|
12
|
+
// stems are trimmed to the t's ink top.
|
|
13
|
+
import glyphAtlas from '../glyphs/glyphs.json';
|
|
14
|
+
import { WORDMARK_PATHS, F } from './logo';
|
|
15
|
+
|
|
16
|
+
type Glyph = { d?: string; advance: number; x1?: number; y1?: number; x2?: number; y2?: number };
|
|
17
|
+
type Atlas = Record<string, { upm: number; glyphs: Record<string, Glyph> }>;
|
|
18
|
+
const ATLAS = glyphAtlas as unknown as Atlas;
|
|
19
|
+
|
|
20
|
+
export type FontKey = 'gt' | 'mohr';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Which letters may be trimmed to the t. ONLY flat-topped ascenders: their extra height is a plain
|
|
24
|
+
* vertical stem, so it comes off invisibly. Deliberately excluded —
|
|
25
|
+
* · i j — the height is a DOT, and cutting decapitates the letter
|
|
26
|
+
* · 0-9 — digits reach the same line but with ROUND tops, which a flat cut would deform
|
|
27
|
+
* · f — never set from the font; it's the drawn artwork, already at the right height
|
|
28
|
+
*/
|
|
29
|
+
const FLAT_ASCENDERS = new Set(['b', 'd', 'h', 'k', 'l']);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Ink gap between the drawn f and the letter after it, measured off the wordmark itself: its f ends at
|
|
33
|
+
* x 106.85 and its o starts at 122.77. The drawn f is ~12 units narrower than GT's f, so GT's advance
|
|
34
|
+
* would strand that difference as a hole after every f — `fleet` setting as `f leet`. The f carries
|
|
35
|
+
* GT's own left sidebearing, so what precedes it spaces normally, and a right sidebearing that
|
|
36
|
+
* reproduces this gap.
|
|
37
|
+
*/
|
|
38
|
+
const WORDMARK_F_GAP = 15.92;
|
|
39
|
+
|
|
40
|
+
/** A glyph placed in the run, as a path plus the transform that puts it there. */
|
|
41
|
+
export type PlacedGlyph = {
|
|
42
|
+
d: string;
|
|
43
|
+
transform: string;
|
|
44
|
+
/** Needs the ascender trim — the renderer clips it at `cutY`. */
|
|
45
|
+
cut: boolean;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type SetRun = {
|
|
49
|
+
glyphs: PlacedGlyph[];
|
|
50
|
+
/** Pen position after the run — where a following word would start. */
|
|
51
|
+
advance: number;
|
|
52
|
+
/** True ink extents. The advance overruns the ink, and trusting it clips the last letter. */
|
|
53
|
+
inkLeft: number;
|
|
54
|
+
inkRight: number;
|
|
55
|
+
inkTop: number;
|
|
56
|
+
inkBottom: number;
|
|
57
|
+
/** Absolute y of the ascender cut line, for the renderer's clip. */
|
|
58
|
+
cutY: number;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Set `text` as outlines. `size` is the em size in the target's units, `x`/`baseline` where the run
|
|
63
|
+
* starts. `brandF` swaps the drawn f in (leads and joined sub-brands; the keycap word is Mohr, which
|
|
64
|
+
* has no f treatment). Advances are summed PER GLYPH, unkerned — the wordmark's own spacing is
|
|
65
|
+
* hand-tuned per pair and is artwork, not something a kern table should second-guess.
|
|
66
|
+
*/
|
|
67
|
+
export function setWord(
|
|
68
|
+
text: string,
|
|
69
|
+
{ font, size, x = 0, baseline = 0, brandF = false }:
|
|
70
|
+
{ font: FontKey; size: number; x?: number; baseline?: number; brandF?: boolean },
|
|
71
|
+
): SetRun {
|
|
72
|
+
const { upm, glyphs: table } = ATLAS[font];
|
|
73
|
+
const s = size / upm;
|
|
74
|
+
const cutY = baseline + (table['t']?.y1 ?? 0) * s;
|
|
75
|
+
|
|
76
|
+
// The drawn f's metrics: GT's left sidebearing, and a right sidebearing set so the next letter's ink
|
|
77
|
+
// lands WORDMARK_F_GAP away — calibrated on the f→o pair the wordmark itself defines.
|
|
78
|
+
const gtF = ATLAS.gt.glyphs['f'];
|
|
79
|
+
const gtO = ATLAS.gt.glyphs['o'];
|
|
80
|
+
const fLsb = (gtF.x1 ?? 0) * (size / ATLAS.gt.upm);
|
|
81
|
+
const fAdvance = fLsb + F.w + (WORDMARK_F_GAP - (gtO.x1 ?? 0) * (size / ATLAS.gt.upm));
|
|
82
|
+
|
|
83
|
+
const out: PlacedGlyph[] = [];
|
|
84
|
+
let pen = x;
|
|
85
|
+
let inkLeft = Infinity, inkRight = -Infinity, inkTop = Infinity, inkBottom = -Infinity;
|
|
86
|
+
const extend = (x1: number, y1: number, x2: number, y2: number) => {
|
|
87
|
+
inkLeft = Math.min(inkLeft, x1); inkRight = Math.max(inkRight, x2);
|
|
88
|
+
inkTop = Math.min(inkTop, y1); inkBottom = Math.max(inkBottom, y2);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
for (const ch of text) {
|
|
92
|
+
if (brandF && ch === 'f') {
|
|
93
|
+
// the artwork, authored in wordmark units with its baseline at F.h — no scaling, it IS the size
|
|
94
|
+
out.push({ d: WORDMARK_PATHS[0], transform: `translate(${round(pen + fLsb)} ${round(baseline - F.h)})`, cut: false });
|
|
95
|
+
extend(pen + fLsb, baseline - F.h, pen + fLsb + F.w, baseline);
|
|
96
|
+
pen += fAdvance;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const g = table[ch];
|
|
100
|
+
if (!g) { pen += (table[' ']?.advance ?? 0) * s; continue; } // unknown char — hold a space rather than drop the word
|
|
101
|
+
if (g.d) {
|
|
102
|
+
out.push({
|
|
103
|
+
d: g.d,
|
|
104
|
+
transform: `translate(${round(pen)} ${round(baseline)}) scale(${round(s, 6)})`,
|
|
105
|
+
cut: FLAT_ASCENDERS.has(ch),
|
|
106
|
+
});
|
|
107
|
+
// a cut glyph's ink stops at the trim line, so its extent has to be reported trimmed too
|
|
108
|
+
const top = Math.max(baseline + g.y1! * s, FLAT_ASCENDERS.has(ch) ? cutY : -Infinity);
|
|
109
|
+
extend(pen + g.x1! * s, top, pen + g.x2! * s, baseline + g.y2! * s);
|
|
110
|
+
}
|
|
111
|
+
pen += g.advance * s;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
glyphs: out, advance: pen,
|
|
116
|
+
inkLeft: inkLeft === Infinity ? x : inkLeft,
|
|
117
|
+
inkRight: inkRight === -Infinity ? x : inkRight,
|
|
118
|
+
inkTop: inkTop === Infinity ? baseline : inkTop,
|
|
119
|
+
inkBottom: inkBottom === -Infinity ? baseline : inkBottom,
|
|
120
|
+
cutY,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const round = (n: number, p = 3) => +n.toFixed(p);
|
|
125
|
+
|
|
126
|
+
/** The run's ink box, in the shape keycapGeometry() expects. */
|
|
127
|
+
export const runInk = (r: SetRun) => ({ x1: r.inkLeft, y1: r.inkTop, x2: r.inkRight, y2: r.inkBottom });
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Forest logo — the single source of truth. The primitives (mark paths + wordmark paths) plus the
|
|
2
|
+
// f-spacing geometry and the lockup offsets; everything else (the live <Logo> component AND the
|
|
3
|
+
// generated SVG files via scripts/logo.ts) is composed from this. Path `d` strings are colour-blind;
|
|
4
|
+
// colour roles are applied by the consumer (tokens in the component, baked hex in the generator).
|
|
5
|
+
|
|
6
|
+
// ── Mark (the tree in a rounded square) — viewBox 0 0 434.82 434.82 ──
|
|
7
|
+
export const MARK_SIZE = 434.82;
|
|
8
|
+
/*
|
|
9
|
+
The rounded square's corner radius and the ring's thickness, in viewBox units — both read off the
|
|
10
|
+
two paths below, which are the only place they existed.
|
|
11
|
+
|
|
12
|
+
★★ EXPORTED BECAUSE THE MARK IS A CARD SHAPE, not only a logo. The deck's mosaic cover sets nine
|
|
13
|
+
tiles beside each other and one of them IS the mark, so the other eight have to be the same
|
|
14
|
+
object: same corner, same ring, at whatever size the grid gives them. Every one of those is a
|
|
15
|
+
RATIO of MARK_SIZE, and a ratio copied into a stylesheet by hand is a number that cannot follow
|
|
16
|
+
the artwork. `square`'s first curve turns at 95.0854; `ring`'s inner edge sits at 19.
|
|
17
|
+
*/
|
|
18
|
+
export const MARK_CORNER = 95.0854;
|
|
19
|
+
export const MARK_RING = 19;
|
|
20
|
+
export const MARK = {
|
|
21
|
+
// rounded-square face
|
|
22
|
+
square: 'M2.1153e-08 95.0946C-0.00109574 42.5792 42.5701 0.00620037 95.0854 0.0051046L339.725 2.11533e-08C392.241 -0.00109575 434.814 42.5701 434.815 95.0854L434.82 339.725C434.821 392.241 392.25 434.814 339.734 434.815L95.0946 434.82C42.5792 434.821 0.00620035 392.25 0.00510458 339.734L2.1153e-08 95.0946Z',
|
|
23
|
+
// outer ring (the ink outline — reverses with the theme in the component)
|
|
24
|
+
ring: 'M434.812 340.954C434.155 392.903 391.839 434.813 339.734 434.815L95.0946 434.82L95.0938 415.819L339.733 415.814C381.755 415.814 415.82 381.748 415.819 339.726L415.814 95.0859C415.814 53.064 381.748 18.9991 339.726 19L95.0859 19.0049C53.0642 19.0058 18.9993 53.072 19 95.0938L19.0049 339.733C19.0058 381.755 53.072 415.82 95.0938 415.819L95.0946 434.82L93.8652 434.812C42.3254 434.16 0.666417 392.503 0.0126953 340.963L0.00510458 339.734L2.1153e-08 95.0946C-0.00108718 42.9895 41.9075 0.671801 93.8564 0.0126953L95.0854 0.0051046L339.725 2.11533e-08L340.954 0.0078125C392.903 0.664719 434.814 42.9804 434.815 95.0854L434.82 339.725L434.812 340.954Z',
|
|
25
|
+
// white tree
|
|
26
|
+
tree: 'M299.156 219.311H271.441L299.156 274.739H248.118V355.715C251.636 356.607 255.112 358.601 257.895 361.37C261.472 364.93 264.076 369.943 264.076 375.898V378.994H224.327V274.74H210.541V378.994H170.792V375.898C170.792 369.943 173.395 364.93 176.972 361.37C179.756 358.601 183.231 356.607 186.75 355.715V274.741L135.682 274.742L163.398 219.314H135.682L217.421 55.8441L299.156 219.311Z',
|
|
27
|
+
// inner tree detail (ink)
|
|
28
|
+
inner: 'M171.866 196.947L217.422 105.85L262.957 196.966H235.267L262.978 252.383H171.873L199.584 196.947H171.866Z',
|
|
29
|
+
};
|
|
30
|
+
// Mark as one knockout path (square minus tree, even-odd) for the one-colour treatment.
|
|
31
|
+
export const MARK_MONO = `${MARK.square}${MARK.tree}${MARK.inner}`;
|
|
32
|
+
|
|
33
|
+
// ── Wordmark ("forest") — viewBox 0 0 842 201, all paths are ink. First path is the "f". ──
|
|
34
|
+
export const WORDMARK_W = 842;
|
|
35
|
+
export const WORDMARK_H = 201;
|
|
36
|
+
export const WORDMARK_PATHS = [
|
|
37
|
+
'M73.8669 0C83.2312 0 94.2241 1.52679 106.846 4.58037V42.7501C97.0742 41.1216 89.6437 40.3073 84.5544 40.3073C79.2615 40.3073 75.3937 41.3251 72.9508 43.3609C70.508 45.6002 69.2865 49.1627 69.2865 54.0484V68.4602H106.846V102.344H69.2865V197.308H28.9793V102.344H0V68.4602H28.9793V48.2466C28.9793 31.3501 32.7453 19.034 40.2775 11.2982C48.0133 3.76608 59.2097 0 73.8669 0Z',
|
|
38
|
+
'M122.774 120.97C122.774 105.295 126.337 91.4525 133.462 79.4417C140.587 67.2274 150.358 57.7613 162.776 51.0434C175.398 44.3255 189.444 40.9666 204.916 40.9666C220.387 40.9666 234.332 44.3255 246.75 51.0434C259.371 57.7613 269.245 67.2274 276.37 79.4417C283.495 91.4525 287.057 105.295 287.057 120.97C287.057 136.646 283.495 150.59 276.37 162.805C269.245 174.815 259.371 184.18 246.75 190.898C234.332 197.615 220.387 200.974 204.916 200.974C189.444 200.974 175.398 197.615 162.776 190.898C150.358 184.18 140.587 174.815 133.462 162.805C126.337 150.59 122.774 136.646 122.774 120.97ZM245.528 120.97C245.528 108.96 241.661 99.1882 233.925 91.6561C226.189 84.1239 216.519 80.3578 204.916 80.3578C193.312 80.3578 183.642 84.1239 175.907 91.6561C168.171 99.1882 164.303 108.96 164.303 120.97C164.303 132.981 168.171 142.753 175.907 150.285C183.642 157.817 193.312 161.583 204.916 161.583C216.519 161.583 226.189 157.817 233.925 150.285C241.661 142.753 245.528 132.981 245.528 120.97Z',
|
|
39
|
+
'M346.76 69.6703C355.717 50.5345 370.171 40.9666 390.121 40.9666C394.396 40.9666 399.384 41.6791 405.084 43.1041V86.465C400.198 84.8364 394.091 84.0221 386.762 84.0221C373.53 84.0221 363.759 87.6864 357.448 95.015C351.341 102.344 348.287 113.438 348.287 128.299V197.31H307.98V44.6309H346.76V69.6703Z',
|
|
40
|
+
'M418.814 120.97C418.814 105.906 421.969 92.3686 428.28 80.3578C434.794 68.1435 443.955 58.5756 455.762 51.6541C467.569 44.5291 481.311 40.9666 496.986 40.9666C512.457 40.9666 525.791 44.3255 536.988 51.0434C548.388 57.7613 557.141 67.2274 563.248 79.4417C569.356 91.6561 572.409 105.906 572.409 122.192V133.185H460.037L460.343 133.796C462.582 143.363 467.569 150.692 475.305 155.781C483.041 160.667 491.693 163.11 501.261 163.11C518.157 163.11 532.611 157.919 544.622 147.537L561.416 180.821C545.131 194.256 524.875 200.974 500.65 200.974C483.957 200.974 469.402 197.514 456.984 190.592C444.566 183.671 435.1 174.205 428.585 162.194C422.071 149.979 418.814 136.238 418.814 120.97ZM528.438 103.87C527.42 95.3204 524.061 88.3989 518.361 83.106C512.864 77.8132 505.332 75.1667 495.764 75.1667C486.196 75.1667 478.257 77.6096 471.946 82.4953C465.839 87.381 461.768 94.5061 459.732 103.87H528.438Z',
|
|
41
|
+
'M594.817 89.5186C594.817 74.0471 600.517 62.1381 611.917 53.7916C623.317 45.2416 639.094 40.9666 659.247 40.9666C685.305 40.9666 705.56 48.4988 720.014 63.5631L697.417 92.8775C692.939 87.9918 686.933 84.2257 679.401 81.5793C671.869 78.7292 664.031 77.3042 655.888 77.3042C649.781 77.3042 644.997 78.2203 641.537 80.0525C638.28 81.8846 636.651 84.531 636.651 87.9918C636.651 90.4346 637.567 92.3686 639.399 93.7936C641.435 95.2186 644.59 96.5418 648.865 97.7632C653.14 98.7811 660.876 100.613 672.073 103.26C688.155 106.924 700.267 112.319 708.41 119.444C716.757 126.365 720.93 136.951 720.93 151.201C720.93 167.69 715.23 180.108 703.83 188.455C692.633 196.801 676.348 200.974 654.972 200.974C639.704 200.974 626.167 198.837 614.36 194.562C602.756 190.083 593.697 183.772 587.183 175.63L610.695 145.094C615.988 151.201 622.706 156.087 630.849 159.751C638.992 163.212 648.458 164.942 659.247 164.942C665.355 164.942 670.24 164.026 673.905 162.194C677.569 160.362 679.401 157.41 679.401 153.338C679.401 150.692 678.383 148.656 676.347 147.231C674.515 145.603 671.462 144.178 667.187 142.956C662.912 141.735 655.685 140.004 645.506 137.765C630.442 134.508 618.227 129.317 608.863 122.192C599.499 115.067 594.817 104.176 594.817 89.5186Z',
|
|
42
|
+
'M840.49 194.256C827.868 197.31 816.875 198.837 807.511 198.837C792.853 198.837 781.657 195.071 773.921 187.539C766.389 179.803 762.623 167.487 762.623 150.59V78.5257H734.835V44.6309H762.623V3.71289H802.93V44.6309H841.711V78.5257H802.93V144.788C802.93 149.674 804.152 153.237 806.595 155.476C809.037 157.512 812.905 158.53 818.198 158.53C823.287 158.53 830.718 157.715 840.49 156.087V194.256Z',
|
|
43
|
+
];
|
|
44
|
+
// The "f" glyph (first wordmark path) — the spacing module. Its tight bbox:
|
|
45
|
+
export const F = { x: 0, y: 0, w: 106.846, h: 197.308 };
|
|
46
|
+
|
|
47
|
+
// ── Lockup compositions — mark + wordmark at the brand's offsets ──
|
|
48
|
+
// gap (horizontal) ≈ one f-width; the wordmark sits at its natural size next to the full-height mark.
|
|
49
|
+
export const LOCKUP_H = { vb: [1381, 435] as const, mark: [0, 0] as const, word: [538.846, 116.95] as const };
|
|
50
|
+
export const LOCKUP_V = { vb: [842, 698] as const, mark: [203.387, 0] as const, word: [0, 496.141] as const };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// The sub-brand register — the canonical set of "<lead> [WORD]" lockups.
|
|
2
|
+
//
|
|
3
|
+
// This is DATA, not a build input: <FSubLogo> composes any entry (or any word that isn't here at all)
|
|
4
|
+
// straight from the glyph atlas, and the SVG exporter reads the same list. Adding a sub-brand means
|
|
5
|
+
// adding a line here. Nothing to run.
|
|
6
|
+
//
|
|
7
|
+
// `tier` groups the register on the docs page: internal = ops and staff tooling, external =
|
|
8
|
+
// rider-facing. DS carries none — it's the system's own mark, not a product, so it sits outside both.
|
|
9
|
+
//
|
|
10
|
+
// Each tier is its own colour namespace. Internal tooling and rider-facing products have no shared
|
|
11
|
+
// audience, so a hue can serve once in each tier: FLEET and PLUS both take forest, FLEX takes river.
|
|
12
|
+
// Uniqueness is enforced within a tier, not across it.
|
|
13
|
+
export type SubBrand = {
|
|
14
|
+
/** Set in the keycap, upper-case. */
|
|
15
|
+
word: string;
|
|
16
|
+
/** Colour ramp the keycap lives on. */
|
|
17
|
+
family: string;
|
|
18
|
+
tier?: 'internal' | 'external';
|
|
19
|
+
/** The word ahead of the keycap. Omit for the drawn forest wordmark. */
|
|
20
|
+
lead?: string;
|
|
21
|
+
/** Keycap fill level; defaults to 500. */
|
|
22
|
+
face?: number;
|
|
23
|
+
/** Keycap word level — set when the face is too light to hold white. */
|
|
24
|
+
ink?: number;
|
|
25
|
+
/** Border level — omit to sit on 950 and lighten to 300 in dark. */
|
|
26
|
+
line?: number;
|
|
27
|
+
/** Border level in dark, when a pinned `line` should shift rather than hold. */
|
|
28
|
+
lineDark?: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const SUB_BRANDS: SubBrand[] = [
|
|
32
|
+
{ word: 'DS', family: 'forest' }, // the design system's own sub-brand: forest DS, primary green keycap
|
|
33
|
+
{ word: 'FLEET', family: 'forest', tier: 'internal' },
|
|
34
|
+
{ word: 'CONSOLE', family: 'river', tier: 'internal', lead: 'fleet' }, // leads with fleet: fleet[CONSOLE]
|
|
35
|
+
{ word: 'TOWER', family: 'warm', tier: 'internal' },
|
|
36
|
+
{ word: 'RADAR', family: 'maple', tier: 'internal' },
|
|
37
|
+
{ word: 'PLUS', family: 'forest', tier: 'external' },
|
|
38
|
+
{ word: 'FLEX', family: 'river', tier: 'external' },
|
|
39
|
+
// peach face, bark-brown ink + border; the border brightens a touch in dark
|
|
40
|
+
{ word: 'C2W', family: 'warm', face: 200, ink: 950, line: 950, lineDark: 700, tier: 'external' },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
export const subBrand = (word: string) =>
|
|
44
|
+
SUB_BRANDS.find((b) => b.word.toLowerCase() === word.toLowerCase());
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Sub-brand lockup geometry — "<lead> [WORD]": a lead word plus a skewed keycap holding the sub-brand,
|
|
2
|
+
// set in Mohr Black Italic. The maths lives here, colour-blind and font-blind: every function takes an
|
|
3
|
+
// ink box (from setWord() in ./glyphs) and returns coordinates in wordmark user space (height 201).
|
|
4
|
+
// <FSubLogo> and the SVG exporter both compose through it, so neither owns the geometry.
|
|
5
|
+
//
|
|
6
|
+
// The sizes below are locked to the wordmark and derived from font metrics, so they're constants rather
|
|
7
|
+
// than inputs — scripts/glyphs.ts asserts them against the font files when it rebuilds the atlas.
|
|
8
|
+
import { WORDMARK_W, F } from './logo';
|
|
9
|
+
|
|
10
|
+
// Mohr Black Italic size for the keycap word — the wordmark's own size scaled by the brand's 136:305
|
|
11
|
+
// display ratio, so a keycap letter sits to "forest" exactly as it does in the mobile display type.
|
|
12
|
+
export const SUBLOGO_MOHR_SIZE = 138.0714529199992;
|
|
13
|
+
// GT Haptik Bold size matching the wordmark's letters — measured so a GT "t" equals the wordmark's own
|
|
14
|
+
// "t" (ink height 195.124). Matching the custom f instead runs ~1.4% large, the full word ~1.3% large:
|
|
15
|
+
// the tracking and the wider drawn f both inflate it. Used by any word set beside or joined to the mark.
|
|
16
|
+
export const SUBLOGO_GT_SIZE = 305.51525382263;
|
|
17
|
+
// Baseline — the GT t-top lands on the wordmark t-top here.
|
|
18
|
+
export const SUBLOGO_BASELINE = F.h;
|
|
19
|
+
|
|
20
|
+
export const SUBLOGO = {
|
|
21
|
+
gap: 70, // lead → keycap
|
|
22
|
+
radius: 42,
|
|
23
|
+
border: 18,
|
|
24
|
+
skew: -6, // the font's own italic angle (the L's stem slant) — the box runs parallel to the letters
|
|
25
|
+
faceLevel: 500, // default keycap fill
|
|
26
|
+
lineLevel: 950, // default keycap border; the component lightens it in dark
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
/** Ink box of a set word, in wordmark user space. */
|
|
30
|
+
export type InkBox = { x1: number; y1: number; x2: number; y2: number };
|
|
31
|
+
|
|
32
|
+
const TAN = Math.abs(Math.tan((SUBLOGO.skew * Math.PI) / 180));
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Keycap + lockup geometry. `leadW` is the ink right edge of the word ahead of the keycap (WORDMARK_W
|
|
36
|
+
* for the drawn wordmark); `word` is the measured ink box of the keycap word at SUBLOGO_MOHR_SIZE.
|
|
37
|
+
* The word is padded equally on all four sides — the vertical padding sets the horizontal, so the
|
|
38
|
+
* keycap keeps the same optical margin whatever the word's width.
|
|
39
|
+
*/
|
|
40
|
+
export function keycapGeometry(leadW: number, word: InkBox) {
|
|
41
|
+
const bleed = SUBLOGO.border / 2;
|
|
42
|
+
const boxH = F.h - SUBLOGO.border;
|
|
43
|
+
const boxY = bleed;
|
|
44
|
+
const cap = word.y2 - word.y1;
|
|
45
|
+
const pad = (boxH - cap) / 2;
|
|
46
|
+
const boxW = word.x2 - word.x1 + pad * 2;
|
|
47
|
+
const boxX = leadW + SUBLOGO.gap;
|
|
48
|
+
// where the word's origin goes so its ink lands inside the padding
|
|
49
|
+
const wordAt = { x: boxX + pad - word.x1, y: boxY + pad - word.y1 };
|
|
50
|
+
const cx = boxX + boxW / 2;
|
|
51
|
+
const cy = boxY + boxH / 2;
|
|
52
|
+
// the skew throws the box corners sideways — the lockup has to make room for the overhang
|
|
53
|
+
const skewBleed = TAN * (boxH / 2);
|
|
54
|
+
const fullW = Math.ceil(boxX + boxW + TAN * (F.h / 2) + bleed + 3);
|
|
55
|
+
return {
|
|
56
|
+
boxX, boxY, boxW, boxH, cx, cy, wordAt, fullW,
|
|
57
|
+
// the keycap on its own, in a tight viewBox: [x, width]
|
|
58
|
+
badgeVB: [boxX - bleed - skewBleed, boxW + 2 * (bleed + skewBleed)] as [number, number],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* App icon — a SQUARE keycap holding just the first letter. The skew throws the corners sideways, so
|
|
64
|
+
* the square is shrunk until its skewed outline fits the viewBox width: a touch shorter than tall,
|
|
65
|
+
* centred both ways. The letter is sized to the rect (~62% cap height), not to the wordmark-locked size.
|
|
66
|
+
*/
|
|
67
|
+
export function iconGeometry() {
|
|
68
|
+
const side = F.h;
|
|
69
|
+
const bleed = SUBLOGO.border / 2;
|
|
70
|
+
const outer = side / (1 + TAN); // skewed outer square == viewBox width
|
|
71
|
+
const sq = outer - SUBLOGO.border;
|
|
72
|
+
return { side, sq, off: (side - outer) / 2 + bleed, letterCap: sq * 0.62, cx: side / 2, cy: side / 2 };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** The skew transform for a keycap centred on (cx, cy). */
|
|
76
|
+
export const skewTransform = (cx: number, cy: number) =>
|
|
77
|
+
`translate(${cx} ${cy}) skewX(${SUBLOGO.skew}) translate(${-cx} ${-cy})`;
|
|
78
|
+
|
|
79
|
+
/** Default lead width — the drawn wordmark's. */
|
|
80
|
+
export const DEFAULT_LEAD_W = WORDMARK_W;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg width="42" height="28" viewBox="0 0 42 28" fill="none"
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
xmlns:m="https://www.mapbox.com">
|
|
4
|
+
<m:metadata>
|
|
5
|
+
<m:parameters>
|
|
6
|
+
<m:parameter m:type="color" m:name="body" m:value="#FF00FF" />
|
|
7
|
+
<m:parameter m:type="color" m:name="ring" m:value="#FF01FF" />
|
|
8
|
+
<m:parameter m:type="color" m:name="warehouse" m:value="#FF02FF" />
|
|
9
|
+
<m:parameter m:type="color" m:name="parking" m:value="#FF03FF" />
|
|
10
|
+
<m:parameter m:type="color" m:name="bike" m:value="#FF04FF" />
|
|
11
|
+
</m:parameters>
|
|
12
|
+
<m:stretch-x-areas>
|
|
13
|
+
<m:stretch-x-area m:left="25" m:width="2" />
|
|
14
|
+
</m:stretch-x-areas>
|
|
15
|
+
<m:content m:left="25" m:top="0" m:width="9" m:height="28" />
|
|
16
|
+
</m:metadata>
|
|
17
|
+
<rect x="1.4" y="1.4" width="39.2" height="25.2" rx="12.6" fill="#FF00FF" stroke="#FF01FF" stroke-width="2.8" />
|
|
18
|
+
<g transform="translate(8 8) scale(0.5)" fill="none" stroke="#FF02FF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2.52"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></g></g>
|
|
19
|
+
<g transform="translate(8 8) scale(0.5)" fill="#FF03FF" stroke="none"><path d="M4.68 20.5 6.48 3.5H12.99Q16.15 3.5 17.78 5.02Q19.41 6.53 19.32 9.35Q19.24 12.66 17.19 14.43Q15.14 16.2 11.62 16.2H10.22L9.78 20.5ZM10.7 11.79H11.95Q13 11.79 13.57 11.26Q14.14 10.73 14.2 9.74Q14.23 8.88 13.77 8.4Q13.3 7.91 12.38 7.91H11.1Z" /></g>
|
|
20
|
+
<g transform="translate(8 8) scale(0.5)" fill="none" stroke="#FF04FF" stroke-linecap="round" stroke-linejoin="round"><path d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z" stroke-width="2.52" stroke-linecap="round" stroke-linejoin="round" /><path d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z" stroke-width="2.52" stroke-linecap="round" stroke-linejoin="round" /><path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="2.52" stroke-linecap="round" /><path d="M8 9H10" stroke-width="2.52" stroke-linecap="round" /><path d="M9 9L12 15" stroke-width="2.52" stroke-linecap="round" /><path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="2.52" stroke-linecap="round" /><path d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16" stroke-width="2.52" stroke-linecap="round" /><path d="M5.5 12H3" stroke-width="2.52" stroke-linecap="round" /></g>
|
|
21
|
+
</svg>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svg width="40" height="40" viewBox="0 0 40 40" fill="none"
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
xmlns:m="https://www.mapbox.com">
|
|
4
|
+
<m:metadata>
|
|
5
|
+
<m:parameters>
|
|
6
|
+
<m:parameter m:type="color" m:name="body" m:value="#FF00FF" />
|
|
7
|
+
<m:parameter m:type="color" m:name="ring" m:value="#FF01FF" />
|
|
8
|
+
<m:parameter m:type="color" m:name="warehouse" m:value="#FF02FF" />
|
|
9
|
+
<m:parameter m:type="color" m:name="parking" m:value="#FF03FF" />
|
|
10
|
+
<m:parameter m:type="color" m:name="bike" m:value="#FF04FF" />
|
|
11
|
+
</m:parameters>
|
|
12
|
+
</m:metadata>
|
|
13
|
+
<rect x="1.665" y="1.665" width="36.67" height="36.67" rx="9.17" fill="#FF00FF" stroke="#FF01FF" stroke-width="3.33" />
|
|
14
|
+
<g transform="translate(8.5 8.5) scale(0.9585)" fill="none" stroke="#FF02FF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></g></g>
|
|
15
|
+
<g transform="translate(8.5 8.5) scale(0.9585)" fill="#FF03FF" stroke="none"><path d="M4.68 20.5 6.48 3.5H12.99Q16.15 3.5 17.78 5.02Q19.41 6.53 19.32 9.35Q19.24 12.66 17.19 14.43Q15.14 16.2 11.62 16.2H10.22L9.78 20.5ZM10.7 11.79H11.95Q13 11.79 13.57 11.26Q14.14 10.73 14.2 9.74Q14.23 8.88 13.77 8.4Q13.3 7.91 12.38 7.91H11.1Z" /></g>
|
|
16
|
+
<g transform="translate(8.5 8.5) scale(0.9585)" fill="none" stroke="#FF04FF" stroke-linecap="round" stroke-linejoin="round"><path d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z" stroke-width="1.74" stroke-linecap="round" stroke-linejoin="round" /><path d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z" stroke-width="1.74" stroke-linecap="round" stroke-linejoin="round" /><path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="1.74" stroke-linecap="round" /><path d="M8 9H10" stroke-width="1.74" stroke-linecap="round" /><path d="M9 9L12 15" stroke-width="1.74" stroke-linecap="round" /><path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="1.74" stroke-linecap="round" /><path d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16" stroke-width="1.74" stroke-linecap="round" /><path d="M5.5 12H3" stroke-width="1.74" stroke-linecap="round" /></g>
|
|
17
|
+
</svg>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<svg width="40" height="40" viewBox="0 0 40 40" fill="none"
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
xmlns:m="https://www.mapbox.com">
|
|
4
|
+
<m:metadata>
|
|
5
|
+
<m:parameters>
|
|
6
|
+
<m:parameter m:type="color" m:name="body" m:value="#FF00FF" />
|
|
7
|
+
<m:parameter m:type="color" m:name="edge" m:value="#FF01FF" />
|
|
8
|
+
<m:parameter m:type="color" m:name="battery" m:value="#FF02FF" />
|
|
9
|
+
<m:parameter m:type="color" m:name="batteryEdge" m:value="#FF03FF" />
|
|
10
|
+
<m:parameter m:type="color" m:name="dot" m:value="#FF04FF" />
|
|
11
|
+
<m:parameter m:type="color" m:name="dotEdge" m:value="#FF05FF" />
|
|
12
|
+
<m:parameter m:type="color" m:name="badgeSquare" m:value="#FF06FF" />
|
|
13
|
+
<m:parameter m:type="color" m:name="badgeSquareEdge" m:value="#FF07FF" />
|
|
14
|
+
<m:parameter m:type="color" m:name="badgeTriangle" m:value="#FF08FF" />
|
|
15
|
+
<m:parameter m:type="color" m:name="badgeTriangleEdge" m:value="#FF09FF" />
|
|
16
|
+
<m:parameter m:type="color" m:name="badgeCircle" m:value="#FF0AFF" />
|
|
17
|
+
<m:parameter m:type="color" m:name="badgeCircleEdge" m:value="#FF0BFF" />
|
|
18
|
+
<m:parameter m:type="color" m:name="badgeStar" m:value="#FF0CFF" />
|
|
19
|
+
<m:parameter m:type="color" m:name="badgeStarEdge" m:value="#FF0DFF" />
|
|
20
|
+
<m:parameter m:type="color" m:name="inUseFrom" m:value="#FF0EFF" />
|
|
21
|
+
<m:parameter m:type="color" m:name="inUseTo" m:value="#FF0FFF" />
|
|
22
|
+
<m:parameter m:type="color" m:name="locked" m:value="#FF10FF" />
|
|
23
|
+
<m:parameter m:type="color" m:name="lockedEdge" m:value="#FF11FF" />
|
|
24
|
+
<m:parameter m:type="color" m:name="bike" m:value="#FF12FF" />
|
|
25
|
+
<m:parameter m:type="color" m:name="pine" m:value="#FF13FF" />
|
|
26
|
+
<m:parameter m:type="color" m:name="eye" m:value="#FF14FF" />
|
|
27
|
+
<m:parameter m:type="color" m:name="relocate" m:value="#FF15FF" />
|
|
28
|
+
<m:parameter m:type="color" m:name="wrench" m:value="#FF16FF" />
|
|
29
|
+
<m:parameter m:type="color" m:name="warehouse" m:value="#FF17FF" />
|
|
30
|
+
<m:parameter m:type="color" m:name="truck" m:value="#FF18FF" />
|
|
31
|
+
<m:parameter m:type="color" m:name="bandage" m:value="#FF19FF" />
|
|
32
|
+
<m:parameter m:type="color" m:name="question" m:value="#FF1AFF" />
|
|
33
|
+
<m:parameter m:type="color" m:name="hand" m:value="#FF1BFF" />
|
|
34
|
+
<m:parameter m:type="color" m:name="flag" m:value="#FF1CFF" />
|
|
35
|
+
<m:parameter m:type="color" m:name="ready" m:value="#FF1DFF" />
|
|
36
|
+
<m:parameter m:type="color" m:name="skull" m:value="#FF1EFF" />
|
|
37
|
+
<m:parameter m:type="color" m:name="container" m:value="#FF1FFF" />
|
|
38
|
+
<m:parameter m:type="color" m:name="staff" m:value="#FF20FF" />
|
|
39
|
+
</m:parameters>
|
|
40
|
+
</m:metadata>
|
|
41
|
+
<defs>
|
|
42
|
+
<radialGradient id="inUse" cx="0.35" cy="0.3" r="0.85">
|
|
43
|
+
<stop offset="0" stop-color="#FF0EFF" />
|
|
44
|
+
<stop offset="1" stop-color="#FF0FFF" />
|
|
45
|
+
</radialGradient>
|
|
46
|
+
</defs>
|
|
47
|
+
<circle cx="20" cy="20" r="19.2" fill="#FF02FF" stroke="#FF03FF" stroke-width="1.6" />
|
|
48
|
+
<circle cx="20" cy="20" r="15.2" fill="#FF00FF" stroke="#FF01FF" stroke-width="1.6" />
|
|
49
|
+
<circle cx="20" cy="20" r="14.4" fill="url(#inUse)" />
|
|
50
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF12FF" stroke-linecap="round" stroke-linejoin="round"><path d="M18.5 19C20.433 19 22 17.433 22 15.5C22 13.567 20.433 12 18.5 12C16.567 12 15 13.567 15 15.5C15 17.433 16.567 19 18.5 19Z" stroke-width="1.74" stroke-linecap="round" stroke-linejoin="round" /><path d="M5.5 19C7.433 19 9 17.433 9 15.5C9 13.567 7.433 12 5.5 12C3.567 12 2 13.567 2 15.5C2 17.433 3.567 19 5.5 19Z" stroke-width="1.74" stroke-linecap="round" stroke-linejoin="round" /><path d="M6 15.5H11.3602C11.7502 15.5 12.1047 15.2732 12.2681 14.9191L15 9" stroke-width="1.74" stroke-linecap="round" /><path d="M8 9H10" stroke-width="1.74" stroke-linecap="round" /><path d="M9 9L12 15" stroke-width="1.74" stroke-linecap="round" /><path d="M12 5H12.8686C13.2543 5 13.6056 5.22183 13.7715 5.57007L18.5 15.5" stroke-width="1.74" stroke-linecap="round" /><path d="M15 6H18.6126C19.2951 6 19.7771 6.6687 19.5613 7.31623L19.2279 8.31623C19.0918 8.72457 18.7097 9 18.2792 9H16" stroke-width="1.74" stroke-linecap="round" /><path d="M5.5 12H3" stroke-width="1.74" stroke-linecap="round" /></g>
|
|
51
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF13FF" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L17.2 12.4H15.4L17.2 16H6.8L8.6 12.4H6.8L12 2Z" stroke-width="1.74" stroke-linecap="round" stroke-linejoin="round" /><path d="M10.2 16V22H8.6" stroke-width="1.74" stroke-linecap="round" stroke-linejoin="round" /><path d="M13.8 16V22H15.4" stroke-width="1.74" stroke-linecap="round" stroke-linejoin="round" /></g>
|
|
52
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF14FF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></g></g>
|
|
53
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF15FF" stroke-linecap="round" stroke-linejoin="round"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74" d="m16 3l4 4l-4 4m4-4H4m4 14l-4-4l4-4m-4 4h16"/></g>
|
|
54
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF16FF" stroke-linecap="round" stroke-linejoin="round"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74" d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/></g>
|
|
55
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF17FF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M18 21V10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1v11"/><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 1.132-1.803l7.95-3.974a2 2 0 0 1 1.837 0l7.948 3.974A2 2 0 0 1 22 8zM6 13h12M6 17h12"/></g></g>
|
|
56
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF18FF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2m10 0H9m10 0h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14"/><circle cx="17" cy="18" r="2"/><circle cx="7" cy="18" r="2"/></g></g>
|
|
57
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF19FF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M10 10.01h.01m-.01 4h.01m3.99-4h.01m-.01 4h.01M18 6v12M6 6v12"/><rect width="20" height="12" x="2" y="6" rx="2"/></g></g>
|
|
58
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF1AFF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3m.08 4h.01"/></g></g>
|
|
59
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF1BFF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2m0 4V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2m0 4.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8"/><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"/></g></g>
|
|
60
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF1CFF" stroke-linecap="round" stroke-linejoin="round"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74" d="M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528"/></g>
|
|
61
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF1DFF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M12 22V12m4 5l2 2l4-4"/><path d="M21 11.127V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l1.32-.753"/><path d="M3.29 7L12 12l8.71-5M7.5 4.27l8.997 5.148"/></g></g>
|
|
62
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF1EFF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="m12.5 17l-.5-1l-.5 1z"/><path d="M15 22a1 1 0 0 0 1-1v-1a2 2 0 0 0 1.56-3.25a8 8 0 1 0-11.12 0A2 2 0 0 0 8 20v1a1 1 0 0 0 1 1z"/><circle cx="15" cy="12" r="1"/><circle cx="9" cy="12" r="1"/></g></g>
|
|
63
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF1FFF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M22 7.7c0-.6-.4-1.2-.8-1.5l-6.3-3.9a1.72 1.72 0 0 0-1.7 0l-10.3 6c-.5.2-.9.8-.9 1.4v6.6c0 .5.4 1.2.8 1.5l6.3 3.9a1.72 1.72 0 0 0 1.7 0l10.3-6c.5-.3.9-1 .9-1.5Z"/><path d="M10 21.9V14L2.1 9.1M10 14l11.9-6.9M14 19.8v-8.1m4 5.8V9.4"/></g></g>
|
|
64
|
+
<g transform="translate(10.06 10.06) scale(0.828)" fill="none" stroke="#FF20FF" stroke-linecap="round" stroke-linejoin="round"><g stroke-linecap="round" stroke-linejoin="round" stroke-width="1.74"><path d="M12 12h.01M16 6V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2m14 7a18.15 18.15 0 0 1-20 0"/><rect width="20" height="14" x="2" y="6" rx="2"/></g></g>
|
|
65
|
+
<circle cx="32.16" cy="7.84" r="5.44" fill="#FF04FF" stroke="#FF05FF" stroke-width="1.6" />
|
|
66
|
+
<rect x="3.71" y="28.03" width="8.26" height="8.26" rx="1.4" fill="#FF06FF" stroke="#FF07FF" stroke-width="1.6" />
|
|
67
|
+
<path d="M 7.84,26.82 L 13.18,36 L 2.5,36 Z" fill="#FF08FF" stroke="#FF09FF" stroke-width="1.6" stroke-linejoin="round" />
|
|
68
|
+
<circle cx="7.84" cy="32.16" r="4.64" fill="#FF0AFF" stroke="#FF0BFF" stroke-width="1.6" />
|
|
69
|
+
<path d="M 7.84,26.68 L 9.77,29.5 L 13.05,30.47 L 10.96,33.18 L 11.06,36.59 L 7.84,35.45 L 4.62,36.59 L 4.72,33.18 L 2.63,30.47 L 5.91,29.5 Z" fill="#FF0CFF" stroke="#FF0DFF" stroke-width="1.6" stroke-linejoin="round" stroke-linecap="round" />
|
|
70
|
+
<circle cx="32.16" cy="32.16" r="5.44" fill="#FF10FF" stroke="#FF11FF" stroke-width="1.6" />
|
|
71
|
+
<rect x="29.92" y="29.49" width="1.95" height="5.34" rx="0.58" fill="#FF11FF" />
|
|
72
|
+
<rect x="32.45" y="29.49" width="1.95" height="5.34" rx="0.58" fill="#FF11FF" />
|
|
73
|
+
</svg>
|