We use cookies and visitor tracking to improve your experience. We identify your company from your IP address using IP2Location and Hunter.io. High-confidence identifications (≥60%) are synced to our Notion CRM.
Essential cookies and visitor tracking are always enabled. You can customize analytics and marketing preferences below.
Source of truth for the MarketingUpgrade.pro brand. Refrain, POV, ICP, voice, color, typography, components, and entity graph in one document. Edit this file when any brand decision changes; everything else in the codebase should derive from here.
Strategy is folklore. I ship operating systems.
Seven words, two clauses. The first clause names the problem (consultant industry sells folklore). The second clause names the alternative (a working system, not a deck). Repeat this on every hero, every CTA exit, every footer strap, every OG image alt, every email subject A/B variant, and every sales reply until it is the first thing every prospect can recall about the brand.
Most marketing engagements are folklore: someone reads a deck back to a board, a retainer renews, and growth does not move. The alternative is a working marketing operating system the team owns after the engagement ends.
€5M–€100M revenue businesses across six verticals (E-commerce, Financial Services, Indie Game Dev, B2B SaaS, Healthtech, Marketplaces). Stage: post-PMF, pre-Series C. Decision-maker: founder, CEO, or board chair.
€5,000–€25,000/month, 3–12 months. 30-day exit clause. Operational from day one. Sprint, interim placement, or fractional ongoing — never a retainer-for-vibes.
A marketing function that runs without us by month nine: stack consolidated, channel mix reset, agentic workflows live, hiring plan executed, board reporting cadence in place.
Six brand colors. Two operational accents (neon green for action, neon purple for brand). Black foundation, off-white text. Three greys for hierarchy. Danger red only on legal/regulatory pages. Click a swatch to copy the hex.
Primary action. CTAs, accents, success state, positive signal.
Brand primary. Borders, secondary accents, attention markers.
Page background, foundation.
Body text, primary readable content.
Muted secondary text, captions, metadata.
Body copy on dark cards.
Hard warning, destructive states, error borders.
Four typefaces. Display (Black Ops One) for every heading. Mono (Space Mono) for everything else. Hand (Permanent Marker) for one rotated accent per section. Sans (Space Grotesk) as the long-form fallback. Never use Google's default sans serifs.
All H1-H6. All hero text. ALL CAPS with 0.05em letter-spacing.
Weights: 400 (single weight)
Body text, paragraphs, navigation, tags, code, fine print.
Weights: 400, 700 (regular + bold)
Pull quotes, slight rotation accents (.rotate-slight class), human moments. Use sparingly — max one per section.
Weights: 400
Body fallback when Space Mono is too dense. Long-form articles.
Weights: 400, 500, 600, 700
Six rules. Apply to every surface — homepage hero, blog posts, CTA copy, email subject lines, social posts. Voice violations are the single most common brand drift; this section is the merge gate.
Strategy is folklore. I ship operating systems.
We deliver strategic, results-driven marketing transformation.
Why: Two short clauses are memorable. They survive translation, voice search, AEO snippet selection.
I rebuilt the marketing function at WeTransfer.
Our team rebuilt the marketing function at WeTransfer.
Why: Solo operator. 'We' fakes scale we don't have and is the #1 consultancy cliché.
B2C neobank CAC rose from €20-40 (2019) to €150-300 (2024).
Acquisition costs have become more challenging.
Why: GEO/AEO favour content with verifiable statistics. LLMs cite numbers, not vibes.
No 90-day onboarding. No PowerPoint. No retainer-for-vibes. Day-one impact.
We focus on quick wins and long-term value delivery.
Why: Three negatives sharpen the contrast. One positive lands the punch. Rhythm matters.
Compliant under AFM, DNB, MiCA, and DSA.
Compliant with relevant European regulations.
Why: Specifics signal expertise. Vague signals consultancy.
Use a comma, a colon, or split the sentence.
Em-dashes — they are inconsistent across keyboards.
Why: Phase 11.4 work-order policy. Em-dashes break GEO parsing in some pipelines.
Every above-fold hero uses these four lines, in this order. Eyebrow names the category. H1 is the refrain. Sub places the offer in context. Eyebrow2 sharpens with three negatives and one positive.
Enterprise interim CMO leadership for €5M-€100M businesses across e-commerce, fintech, SaaS, healthtech, marketplaces, and indie games. Embedded from week one.
NO 90-DAY ONBOARDING. NO POWERPOINT. NO RETAINER-FOR-VIBES. ONE OPERATOR, DAY-ONE IMPACT.
The visual vocabulary of the TFS (Tactical Field Scrapbook / Brutalist) language. Every page mixes these six elements in some combination. Adding a new element requires updating this section first.
border-2 border-[#00ff00] borderStyle:dashedPrimary container for any structured content (KPIs, stack lists, pricing tiers).
border-radius: 0 (TFS --radius: 0rem)All buttons, cards, inputs. Never round corners. Brutalist baseline.
textShadow: 0 0 10px <color> — usually 10-20px blurHero text, brand strap, critical accents. Reserve for ~1-2 surfaces per page.
repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,255,0,0.015) 2px, rgba(0,255,0,0.015) 4px)Overlaid on hero sections as low-opacity ambient texture. Never on text.
.rotate-slight (animation: wiggle 1s ease-in-out infinite)Apply to font-hand accents (Permanent Marker). One per section max.
text-xs tracking-widest uppercase — usually with font-black or font-displaySection eyebrows, category labels, badge/chip copy.

For the primary conversion action on every page. One per surface. Always “Start an intake” or a refrain-flavoured variant. Never “Get in touch”, “Learn more”, or any passive CTA.
For the not-ready-yet visitor. Always leads to a content surface (verticals, blog, whitepaper, glossary). Never leads to a calendar or form.
The brand operates as two linked schema.org entities: a Person (the operator) and an Organization (the brand). Both share a cross-referenced sameAs graph. Any new platform presence must be added to both arrays and shipped on the same commit.
When adding a new platform (e.g., Substack, Mastodon, Wikidata Q-number, YouTube channel), update: client/index.html Person.sameAs, client/index.html Organization.sameAs, client/index.html LocalBusiness.sameAs, /client/public/.well-known/agent.json, /client/public/humans.txt, /client/public/llms.txt, /client/public/llms-full.txt, AND this brandbook. All in one PR.
Every indexable page MUST satisfy this checklist. The seo:lint script enforces it in CI. Pages that fail are blocked from merge.
Nine monthly tiers from €5,000 to €25,000. Each tier adds scope on top of the one below. The brandbook codifies them so quotations, contracts, blog CTAs, and vertical pages stay in sync.
Every brand color exposes a 50-950 step scale for nuanced UI usage (hover states, alert backgrounds, gradient stops, data visualization). The 500 step is the canonical hex. Lower numbers are lighter; higher numbers are darker. Generated programmatically; OKLCH-tuned source of truth lives in client/src/index.css.
Every brand-color foreground × background pairing measured against WCAG 2.2. AA threshold: 4.5:1 for normal text, 3:1 for large text (18pt regular or 14pt bold). AAA: 7:1 normal / 4.5:1 large. Pairings marked “Fail” must not be used for text. Use them for decorative-only surfaces (borders, dividers, icons with adjacent labels).
| FG / BG | Black | Off-white | Card #0a0a0a | Card #1a1a1a |
|---|---|---|---|---|
| White | 21.00:1 N:AAA · L:AAA | 1.12:1 N:Fail · L:Fail | 19.80:1 N:AAA · L:AAA | 17.40:1 N:AAA · L:AAA |
| Off-white | 18.76:1 N:AAA · L:AAA | 1.00:1 N:Fail · L:Fail | 17.68:1 N:AAA · L:AAA | 15.55:1 N:AAA · L:AAA |
| Grey 80 | 13.08:1 N:AAA · L:AAA | 1.43:1 N:Fail · L:Fail | 12.33:1 N:AAA · L:AAA | 10.84:1 N:AAA · L:AAA |
| Grey 60 | 7.37:1 N:AAA · L:AAA | 2.54:1 N:Fail · L:Fail | 6.95:1 N:AA · L:AAA | 6.11:1 N:AA · L:AAA |
| Neon Green | 15.30:1 N:AAA · L:AAA | 1.23:1 N:Fail · L:Fail | 14.43:1 N:AAA · L:AAA | 12.68:1 N:AAA · L:AAA |
| Neon Purple | 8.85:1 N:AAA · L:AAA | 2.12:1 N:Fail · L:Fail | 8.35:1 N:AAA · L:AAA | 7.34:1 N:AAA · L:AAA |
| Danger Red | 5.25:1 N:AA · L:AAA | 3.57:1 N:Fail · L:AA | 4.95:1 N:AA · L:AAA | 4.35:1 N:Fail · L:AA |
N = normal text grade · L = large text grade. AAA = ideal, AA = minimum, Fail = decorative only.
The full responsive type ramp, mobile-first. All sizes use rem so they respect user font-size preferences. Line heights are tuned per step; display sizes are tight (0.9-1.1) while body sits at 1.6 for long-form readability.
| Token | Size (rem) | Size (px) | Line-height | Use |
|---|---|---|---|---|
| display-xl | 5.625 | 90 | 0.9 | Hero H1 desktop |
| display-lg | 4.5 | 72 | 0.95 | Hero H1 tablet |
| display | 3.5 | 56 | 1.0 | Hero H1 mobile / Section H2 desktop |
| h1 | 3.0 | 48 | 1.05 | Section H2 mobile |
| h2 | 2.25 | 36 | 1.1 | Subsection H3 |
| h3 | 1.875 | 30 | 1.15 | Card title |
| h4 | 1.5 | 24 | 1.2 | Inline emphasis |
| lead | 1.25 | 20 | 1.5 | Sub-hero / lede paragraph |
| body-lg | 1.125 | 18 | 1.6 | Long-form blog body |
| body | 1.0 | 16 | 1.6 | Default paragraph |
| body-sm | 0.875 | 14 | 1.55 | Card body, FAQ |
| caption | 0.75 | 12 | 1.5 | Meta, byline, fine print |
| mono-sm | 0.6875 | 11 | 1.4 | Code, hex, technical refs |
| eyebrow | 0.625 | 10 | 1.3 | All-caps tracking-widest |
Everything in the layout uses 4px increments. Tailwind's default scale maps cleanly: spacing-1 = 4px, spacing-2 = 8px, spacing-4 = 16px. Component padding, gap, and margin must come from this scale. Adding a one-off value (e.g., 13px) requires a design-token RFC.
Lucide React. Stroke-based, single weight (1.5px at 24px size). Always pair with a text label for accessibility. Never use an icon alone as a button without an aria-label.
Motion serves communication, not decoration. Hero text uses staggered letter reveal with a cinematic ease curve. Scroll-driven parallax for hero sections only. Always respect prefers-reduced-motion.
cubic-bezier(0.25, 0.46, 0.45, 0.94)Hero text reveal, section entrances, anything narrative
cubic-bezier(0.16, 1, 0.3, 1)Button hover, popover entry, anything reactive
linearProgress bars, scanline overlays, infinite loops only
rotate(-3deg) → rotate(3deg), 1s loopPermanent Marker accents, .rotate-slight class
Choreographed motion — entrances, count-ups, staggers, loops — is built with GSAP 3.15+ (free for commercial use since 3.13, all plugins included). Gesture-bound motion that tracks a pointer or spring-physics UI state (card tilt, flip, drag) stays on framer-motion. One engine per job; never both on the same property of the same element.
Every page wraps its tweens in gsap.context(() => {...}, rootRef) and returns ctx.revert() on unmount. No global selectors, no leaked tweens.
Markup renders the FINAL state (SEO- and no-JS-safe); gsap.from() animates toward it. prefers-reduced-motion? Skip the whole context — the DOM is already correct.
back.out(1.4) for hero/card entrances · power2.out for reveals & counters · power3.out for bars/meters · power2.inOut for loops (sheens, sweeps).
Number count-ups: gsap.from with innerText: 0 + snap. Grid staggers 0.08–0.12s. Loops repeat with repeatDelay ≥ 6s — ambience, not noise.
useLayoutEffect(() => {
if (matchMedia("(prefers-reduced-motion: reduce)").matches) return;
const ctx = gsap.context(() => {
gsap.from(".hero-card", { autoAlpha: 0, y: 48, scale: 0.92, duration: 1, ease: "back.out(1.4)" });
gsap.from(".stat-num", { innerText: 0, snap: { innerText: 1 }, duration: 1.5, ease: "power2.out", stagger: 0.09 });
gsap.from(".stat-bar", { scaleX: 0, transformOrigin: "0% 50%", duration: 1.1, ease: "power3.out", stagger: 0.09 });
}, pageRef);
return () => ctx.revert();
}, []);Reference implementation: fifacv.marketingupgrade.pro — entrance swing, stat count-ups, bar fills, below-fold reveals, and an 8-second sheen loop, all in one reverted context.
Every shipped page must meet WCAG 2.2 Level AA. We do not target AAA at color, because the brand palette is built on saturated neon — but we hit AAA on text-on-card pairings (white on #0a0a0a) which is where the long-form content lives.
Canonical token export. CSS variables (drop into any project), Tailwind config snippet, and a JSON payload for Figma / Style Dictionary. Source of truth: client/src/index.css. When tokens change, update there first, then this brandbook.
:root {
/* color */
--green-500: #00ff00;
--purple-500: #e386e9;
--red-500: #ff0000;
--white: #ffffff;
--off-white: #f2f2f2;
--grey-50: #f0f0f0;
--grey-60: #999999;
--grey-80: #cccccc;
--bg-base: #000000;
--bg-card: #0a0a0a;
/* fonts */
--font-display: "Black Ops One", system-ui;
--font-mono: "Space Mono", monospace;
--font-hand: "Permanent Marker", cursive;
--font-sans: "Space Grotesk", system-ui, sans-serif;
/* radius */
--radius: 0;
/* motion */
--ease-cinematic: cubic-bezier(.25,.46,.45,.94);
--ease-snap: cubic-bezier(.16,1,.3,1);
--duration-fast: 150ms;
--duration-base: 300ms;
--duration-slow: 600ms;
}{
"color": {
"green": { "500": "#00ff00" },
"purple": { "500": "#e386e9" },
"red": { "500": "#ff0000" },
"neutral": {
"0": "#000000",
"10": "#0a0a0a",
"60": "#999999",
"80": "#cccccc",
"95": "#f2f2f2",
"100": "#ffffff"
}
},
"font": {
"display": "Black Ops One",
"mono": "Space Mono",
"hand": "Permanent Marker",
"sans": "Space Grotesk"
},
"radius": { "default": 0 },
"motion": {
"ease": {
"cinematic": "cubic-bezier(.25,.46,.45,.94)",
"snap": "cubic-bezier(.16,1,.3,1)"
},
"duration": {
"fast": "150ms",
"base": "300ms",
"slow": "600ms"
}
}
}Canonical hosted assets. Use the absolute URL; never duplicate or re-host. Adding a new asset requires landing the file in client/public/images and registering it here.
The brandbook is the source of truth. Changes to colors, typography, voice, or component vocabulary require a documented RFC. Quick fixes (typos, formatting) can ship freely.
Examples: Fixing a typo, updating an asset URL, adding a new entry to an existing list.
Process: Open PR, merge after self-review. No external sign-off.
Examples: Adding a new shade step to an existing color scale. Adding a new icon to the library. Adding a new spacing token.
Process: Open PR with rationale + 2 example use cases. Merge after 1 reviewer approves.
Examples: Adding a new brand color. Adding a new typeface. Adding a new component pattern. Adding a new voice rule.
Process: Open RFC issue first. 7-day comment window. Implement only if no veto. Update brandbook + every reference in the codebase in the same PR.
Examples: Changing the refrain. Changing the ICP. Changing the POV.
Process: Synchronous workshop with the operator + a trusted external advisor. Cannot be done in a PR alone.
Initial publication. Refrain locked: 'Strategy is folklore. I ship operating systems.' ICP: stay broad across six verticals. Brand graph (Person + Organization + LocalBusiness) cross-references LinkedIn, Reddit, and Interactive CV subdomain.