diff --git a/NOTICE b/NOTICE index dc699f6..b3de303 100644 --- a/NOTICE +++ b/NOTICE @@ -20,4 +20,9 @@ repository are nominative and descriptive only, for two purposes: scenarios against real WireMock as a reference oracle. The oracle code lives in the test/harness projects and is not part of the distributed product. +The "Mockifyr" name and the logo files under brand/ are trademarks of this project. Apache-2.0 +grants a copyright and patent licence but no trademark licence (see LICENSE, section 6): you may +fork and redistribute the code, but not use the name or the logo in a way that suggests the result +is Mockifyr or is endorsed by it. + All other product names, logos, and brands are property of their respective owners. diff --git a/README.md b/README.md index 9509d0b..392fcdf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ + + + + + # Mockifyr [![CI](https://github.com/omercelikdev/mockifyr/actions/workflows/ci.yml/badge.svg)](https://github.com/omercelikdev/mockifyr/actions/workflows/ci.yml) diff --git a/brand/README.md b/brand/README.md new file mode 100644 index 0000000..3e9afe6 --- /dev/null +++ b/brand/README.md @@ -0,0 +1,80 @@ +# Mockifyr brand assets + +Source artwork for the Mockifyr mark, lockup, app icon and favicon. Everything here is SVG, so it +stays sharp at any size. + +## The mark + +Two chevrons facing each other — a request going in, a response coming back — joined by a wing, with +the eye as the single accent. Read as a whole it is a bird in flight; read as a diagram it is the +engine: something goes out, a stand-in comes back. + +## Colours + +| Role | Hex | Notes | +| --- | --- | --- | +| Ink | `#111111` | The mark on light backgrounds. | +| Brand blue | `#0a4ecf` | Eye + accent on light backgrounds. 7.0:1 against white. | +| Light blue | `#5a8dff` | Eye on dark backgrounds. 6.3:1 against `#0a0a0c`. | +| Icon blue | `#bcd0ff` | Eye on the brand-blue app-icon tile, where `#5a8dff` has too little separation. | + +The eye always switches with the surface behind it — that is deliberate, not an inconsistency. + +## Geometry + +The mark is drawn on a tight `0 0 125 63` viewBox: the artwork's ink, including the round stroke +caps, touches all four edges exactly. Consumers add their own padding, and the mark centres +correctly in any container without eyeballing. + +Stroke width is `10` with round caps and joins throughout. That ratio is load-bearing, and it is +set by the shortest segment, not the longest: the body notch is a ~25-unit stroke, so anything much +heavier stops reading as a line and turns into a lump that welds the three shapes into one mass at +small sizes. Keep the counters open and the silhouette survives down to 16px. + +## Files + +``` +mark/ mark only — black (light bg) · white (dark bg) · duo (two-tone) +lockup/ horizontal logo, mark + wordmark — light / dark +app-icon/ 512px rounded-square app icon — blue / black / white tile +favicon/ 64px browser tab icon — transparent, theme-aware +``` + +The favicon is the one file that deliberately breaks the geometry above, and it has to. Scaling a +line drawing down past roughly 24px does not preserve it: at tab size the master stroke lands under +one pixel and renders as grey haze next to neighbours that are bold shapes filling their whole box. +So the favicon is redrawn at its own optical size — same skeleton, stroke `14` instead of `10`, and +94% fill instead of 64%. Stroke still stays under 60% of the body notch's length, which is what keeps +the three shapes from welding together. + +It carries no tile. A tab strip already has a background, and a white square reads as a white square +on every tab that is not the active one. With nothing behind it the ink has to carry itself, so the +file switches colour on `prefers-color-scheme` rather than assuming a light browser. + +## Which file to use + +- Dashboard, light theme — `mark/mockifyr-mark-black.svg` +- Dashboard, dark theme — `mark/mockifyr-mark-white.svg` +- Browser tab — `favicon/mockifyr-favicon.svg` +- App / store icon — `app-icon/mockifyr-appicon-blue.svg` + +Inside the dashboard the mark is not loaded from these files. It ships as an inline React component +(`ui/src/components/ui/brand-mark.tsx`) whose stroke is `currentColor`, so a single element follows +the theme instead of two files being swapped on every theme change. + +## A note on the lockups + +The wordmark in `lockup/*.svg` is live SVG `` set in **Sora**. On a machine without Sora +installed it silently falls back to another font — the logo then renders as something that is not +the logo. Treat these files as editable sources, not as artwork to embed. + +Wherever a lockup is needed in the product or in documentation, compose it from the mark plus real +text (HTML, markdown heading, slide title). That keeps the text selectable, translatable and +theme-aware, and removes the font dependency entirely. To ship a lockup as a single image, convert +the text to outlines first on a machine that has Sora. + +## Trademark + +The Mockifyr name and these logo files are trademarks of the project. The Apache-2.0 licence that +covers the source code does not grant trademark rights (see LICENSE §6 and NOTICE). Do not use them +to brand a fork or to imply endorsement. diff --git a/brand/app-icon/mockifyr-appicon-black.svg b/brand/app-icon/mockifyr-appicon-black.svg new file mode 100644 index 0000000..11dd877 --- /dev/null +++ b/brand/app-icon/mockifyr-appicon-black.svg @@ -0,0 +1,12 @@ + + Mockifyr + + + + + + + + + + diff --git a/brand/app-icon/mockifyr-appicon-blue.svg b/brand/app-icon/mockifyr-appicon-blue.svg new file mode 100644 index 0000000..2fdcaac --- /dev/null +++ b/brand/app-icon/mockifyr-appicon-blue.svg @@ -0,0 +1,12 @@ + + Mockifyr + + + + + + + + + + diff --git a/brand/app-icon/mockifyr-appicon-white.svg b/brand/app-icon/mockifyr-appicon-white.svg new file mode 100644 index 0000000..7a75307 --- /dev/null +++ b/brand/app-icon/mockifyr-appicon-white.svg @@ -0,0 +1,12 @@ + + Mockifyr + + + + + + + + + + diff --git a/brand/favicon/mockifyr-favicon.svg b/brand/favicon/mockifyr-favicon.svg new file mode 100644 index 0000000..3a52659 --- /dev/null +++ b/brand/favicon/mockifyr-favicon.svg @@ -0,0 +1,25 @@ + + Mockifyr + + + + + + + + + + + diff --git a/brand/lockup/mockifyr-lockup-dark.svg b/brand/lockup/mockifyr-lockup-dark.svg new file mode 100644 index 0000000..5ac92d4 --- /dev/null +++ b/brand/lockup/mockifyr-lockup-dark.svg @@ -0,0 +1,13 @@ + + Mockifyr — mock & prototype, faster. + + + + + + + + + Mockifyr + mock & prototype, faster. + diff --git a/brand/lockup/mockifyr-lockup-light.svg b/brand/lockup/mockifyr-lockup-light.svg new file mode 100644 index 0000000..2503828 --- /dev/null +++ b/brand/lockup/mockifyr-lockup-light.svg @@ -0,0 +1,13 @@ + + Mockifyr — mock & prototype, faster. + + + + + + + + + Mockifyr + mock & prototype, faster. + diff --git a/brand/mark/mockifyr-mark-black.svg b/brand/mark/mockifyr-mark-black.svg new file mode 100644 index 0000000..d88bfba --- /dev/null +++ b/brand/mark/mockifyr-mark-black.svg @@ -0,0 +1,9 @@ + + Mockifyr + + + + + + + diff --git a/brand/mark/mockifyr-mark-duo.svg b/brand/mark/mockifyr-mark-duo.svg new file mode 100644 index 0000000..29992e0 --- /dev/null +++ b/brand/mark/mockifyr-mark-duo.svg @@ -0,0 +1,9 @@ + + Mockifyr + + + + + + + diff --git a/brand/mark/mockifyr-mark-white.svg b/brand/mark/mockifyr-mark-white.svg new file mode 100644 index 0000000..5f4b9c6 --- /dev/null +++ b/brand/mark/mockifyr-mark-white.svg @@ -0,0 +1,9 @@ + + Mockifyr + + + + + + + diff --git a/ui/index.html b/ui/index.html index c622886..77f28c6 100644 --- a/ui/index.html +++ b/ui/index.html @@ -4,6 +4,10 @@ + + + Mockifyr — Mock Platform diff --git a/ui/public/favicon.svg b/ui/public/favicon.svg index 6893eb1..3a52659 100644 --- a/ui/public/favicon.svg +++ b/ui/public/favicon.svg @@ -1 +1,25 @@ - \ No newline at end of file + + Mockifyr + + + + + + + + + + + diff --git a/ui/src/components/layout/app-sidebar.tsx b/ui/src/components/layout/app-sidebar.tsx index e60ea5c..cea8c05 100644 --- a/ui/src/components/layout/app-sidebar.tsx +++ b/ui/src/components/layout/app-sidebar.tsx @@ -9,6 +9,7 @@ import { cn } from '@/lib/utils' import { useUi } from '@/components/providers' import { clearAdminAuth, fetchJournal, fetchScenarios, fetchStubs, hasAdminAuth } from '@/lib/api' import { LOCALES } from '@/lib/i18n' +import { BrandMark } from '@/components/ui/brand-mark' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' import { TenantSwitcher } from './tenant-switcher' import { @@ -68,14 +69,14 @@ export function AppSidebar() {
- M +
) : (
- M + {t('brand.name')} {t('brand.sub')} diff --git a/ui/src/components/ui/brand-mark.tsx b/ui/src/components/ui/brand-mark.tsx new file mode 100644 index 0000000..a03e16e --- /dev/null +++ b/ui/src/components/ui/brand-mark.tsx @@ -0,0 +1,27 @@ +// The Mockifyr mark: two chevrons facing each other — a request going out, a response coming back — +// joined by a wing, with the eye as the single accent. Drawn on the brand's tight 125x63 viewBox, where +// the ink (round stroke caps included) touches all four edges, so it centres in any box without nudging. +// +// It sits directly on the surface rather than inside a filled tile: on a light background the mark is +// near-black, on a dark one near-white. That is what the stroke being currentColor buys — one element +// follows the theme, with no flash and no second request from swapping a black and a white file. The +// filled tile is the favicon's job, where an icon has to hold its own against a browser chrome it does +// not control; in the app the mark can simply be the mark. +// +// Every stroke here is diagonal, so its edges antialias at any size — that softness is inherent, not a +// resolution problem, and the only real remedy is more pixels. Hence 50px in the header rather than the +// 40px that first looked "enough": at 50px the 10-unit stroke lands on exactly 4 device-independent +// pixels, and the counters have room to stay open. + +export function BrandMark({ className }: { className?: string }) { + return ( + + + + + + + + + ) +} diff --git a/ui/src/index.css b/ui/src/index.css index 0e83d93..5bc5754 100644 --- a/ui/src/index.css +++ b/ui/src/index.css @@ -25,6 +25,11 @@ --primary: #18181b; /* accent — actions · active · CTA (swap to re-skin) */ --primary-foreground: #ffffff; + + /* Brand blue — the logo's eye, and the only place brand colour appears. Deliberately kept out of the + UI ramp: the palette stays zinc-monochrome, and this blue never competes with --info, which is a + near-identical informational state colour. */ + --brand: #0a4ecf; --accent: #f1f1f3; /* soft fill: nav hover/active, secondary */ --accent-foreground: #18181b; @@ -59,6 +64,8 @@ --primary: #fafafa; --primary-foreground: #18181b; + + --brand: #5a8dff; /* lifted so it holds against the dark page */ --accent: #202026; --accent-foreground: #fafafa;