Skip to content

Commit fd508b9

Browse files
logo
1 parent 249a6b3 commit fd508b9

12 files changed

Lines changed: 163 additions & 209 deletions

File tree

engi-demo/public/favicon.svg

Lines changed: 4 additions & 9 deletions
Loading

uapi/app/(root)/components/MarketingLandingPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ export default function MarketingLandingPage() {
562562
>
563563
<div className="flex flex-wrap items-center gap-3">
564564
<div className="flex h-11 w-11 items-center justify-center rounded-2xl border border-emerald-300/20 bg-emerald-400/10 shadow-[0_0_28px_rgba(103,254,183,0.14)]">
565-
<Logo height="h-5" width="w-5" />
565+
<Logo height="h-7" width="w-7" />
566566
</div>
567567
</div>
568568

@@ -825,7 +825,7 @@ export default function MarketingLandingPage() {
825825
</div>
826826
<div className="absolute right-0 top-0">
827827
<EngiSoftwareSvgLogo
828-
width="60px"
828+
width="44px"
829829
softwareClassName="hidden"
830830
className="opacity-90"
831831
/>

uapi/app/favicon.ico

-15 KB
Binary file not shown.

uapi/app/layout.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export const metadata: Metadata = {
4040
title: metadataTitle,
4141
description: metadataDescription,
4242
applicationName: 'Bitcode',
43+
icons: {
44+
icon: '/bitcode.svg',
45+
shortcut: '/bitcode.svg',
46+
apple: '/bitcode.svg',
47+
},
4348
alternates: {
4449
canonical: '/',
4550
},

uapi/components/base/engi/branding/engi-software-svg-logo.tsx

Lines changed: 75 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -3,191 +3,106 @@ import React from 'react';
33
type EngiSoftwareSvgLogoProps = {
44
width?: string;
55
height?: string;
6-
/** Extra classes applied to the outer container */
76
className?: string;
8-
/** Extra classes applied to the ".software" text */
97
softwareClassName?: string;
10-
/** Fill color for the base logo */
118
fill?: string;
12-
13-
/**
14-
* Optional per-instance vertical translation for the “.software” span
15-
* (e.g. "-1px"). If omitted, the component uses a sensible default.
16-
*/
179
softwareOffsetY?: string;
18-
19-
/**
20-
* Whether to render the neon-green glow on the first letter. The glow is
21-
* implemented by overlaying a second, clipped SVG that is filled with the
22-
* green colour and blurred via drop-shadows. In very small renderings – for
23-
* example inside the footer where the full “engi.software” wordmark is
24-
* displayed – that clipped overlay looks like a hard-cut green gradient on
25-
* the left edge of the logo. Allow turning it off so we can show a clean
26-
* monochrome logo when desired.
27-
*/
2810
glow?: boolean;
2911
};
3012

31-
/*
32-
We want the first letter (the lower-case "e") to retain the neon-green glow
33-
that existed before we switched the logo to an inline SVG. To achieve this
34-
without re-drawing the path we simply render the same SVG twice:
13+
function normalizeLogoColor(fill: string) {
14+
if (fill === 'theme(colors.brand.emerald)') return '#65FEB7';
15+
if (fill === 'theme(colors.brand.red)') return '#EF4444';
16+
return fill;
17+
}
3518

36-
1. The base layer is the normal white (or provided `fill`) logo.
37-
2. A second layer is absolutely positioned on top, clipped so that only the
38-
first ~22 % of the width (i.e. the "e") is visible and a drop-shadow is
39-
applied to produce the glow.
19+
function computeGlyphHeight(width: string) {
20+
const numericWidth = Number.parseFloat(width);
21+
if (Number.isNaN(numericWidth)) return 'auto';
22+
return `${(numericWidth * 49) / 36}px`;
23+
}
4024

41-
This keeps the markup simple, avoids having to split the path, and still
42-
isolates the glow to the "e" only.
43-
*/
25+
function computeWordmarkMetrics(width: string) {
26+
const numericWidth = Number.parseFloat(width);
27+
if (Number.isNaN(numericWidth)) {
28+
return {
29+
glyphWidth: '28px',
30+
fontSize: undefined as string | undefined,
31+
};
32+
}
33+
34+
return {
35+
glyphWidth: `${Math.max(16, Math.round(numericWidth * 0.26))}px`,
36+
fontSize: `${Math.max(12, Math.round(numericWidth * 0.24))}px`,
37+
};
38+
}
4439

4540
export default function EngiSoftwareSvgLogo({
46-
width = "115px",
47-
height = "auto",
48-
className = "",
49-
/*
50-
Tailwind utility classes for the “.software” text. You can override the
51-
default vertical offset via the `softwareOffsetY` prop instead of inline
52-
styles.
53-
*/
41+
width = '115px',
42+
height = 'auto',
43+
className = '',
5444
softwareClassName =
55-
"ml-1 inline-block font-medium text-sm tracking-wide align-baseline bg-gradient-to-r from-[#65FEB7] via-white to-[#65FEB7] text-transparent bg-clip-text",
56-
fill = "white",
57-
// Keep the green first letter but *without* the neon drop-shadow. Overlay
58-
// therefore remains enabled by default.
45+
'ml-1 inline-block font-semibold tracking-wide align-baseline bg-gradient-to-r from-[#65FEB7] via-white to-[#65FEB7] text-transparent bg-clip-text',
46+
fill = 'white',
5947
glow = true,
6048
softwareOffsetY,
6149
}: EngiSoftwareSvgLogoProps) {
62-
// Percentage of the logo's width that roughly covers the first letter.
63-
// We keep this as a constant (in %) so the clipping scales with `width`.
64-
// Covers the width of the first letter ("e") including a tiny bit of margin
65-
// so the glow soft-edges are not clipped.
66-
/*
67-
Clip only the first letter ("e") for the colour overlay. The original
68-
20 % width worked well at smaller render sizes but left a visible white
69-
strip on the right edge of the “e” once the word-mark scaled up – most
70-
noticeably inside the marketing competitors table where the logo is
71-
rendered at ~92 px.
72-
73-
Based on the vector path the first glyph occupies ~30 % of the total
74-
view-box width, so we expand the clipping region accordingly. This fully
75-
covers the character across all current logo sizes whilst still stopping
76-
short of the neighbouring “n”.
77-
*/
78-
const LETTER_CLIP_PERCENT = 30;
79-
80-
/*
81-
Horizontal nudge so the green overlay sits exactly on top of the underlying
82-
letter. Positive moves it right, negative left. The value is empirical
83-
but expressed as a constant in % so it scales with the logo width.
84-
*/
85-
const LETTER_OFFSET_PERCENT = -1.1;
86-
87-
/*
88-
Static vertical tweak for the “.software” text ---------------------------
89-
90-
Adjust this pixel value up/down until the bodies of both words sit on the
91-
same visual baseline at your most common render sizes.
92-
*/
93-
const SOFTWARE_Y_TRANSLATE = softwareOffsetY ?? '-2px';
94-
95-
const ORIGINAL_VIEWBOX_WIDTH = 404;
96-
const ORIGINAL_VIEWBOX_HEIGHT = 175;
97-
98-
const numericWidth = parseFloat(width.toString());
99-
100-
// Exact rendered height of the SVG for the given width so we can give the
101-
// overlay wrapper an explicit, identical height. This avoids subtle 5–6 px
102-
// mismatches that occur when the base <svg> sizes itself via intrinsic
103-
// aspect-ratio while the absolutely positioned overlay relies on `height:
104-
// 100 %` without a resolved containing block height.
105-
const computedHeight = isNaN(numericWidth)
106-
? 'auto'
107-
: `${(numericWidth * ORIGINAL_VIEWBOX_HEIGHT) / ORIGINAL_VIEWBOX_WIDTH}px`;
108-
109-
/*
110-
Glow fade -----------------------------------------------------------------
111-
112-
A soft fade avoids the visible rectangular clipping of the green overlay.
113-
We fade over ~12 % of the logo’s rendered width.
114-
*/
115-
/*
116-
Fade the overlay before the hard rectangular clip becomes visible. A
117-
gentler 7 % looks closer to a natural neon fall-off.
118-
*/
119-
const GLOW_FADE_PX = isNaN(numericWidth) ? 8 : Math.ceil(numericWidth * 0.07);
120-
121-
// We inline the SVG path once so it can be re-used by the two <svg> tags
122-
const LogoPath = (
123-
<path
124-
fillRule="evenodd"
125-
clipRule="evenodd"
126-
d="M372.26 15C367.433 15 363.521 18.9128 363.521 23.7395C363.521 28.5662 367.433 32.479 372.26 32.479C377.087 32.479 381 28.5662 381 23.7395C381 18.9128 377.087 15 372.26 15ZM120.258 101.051C114.79 113.707 102.196 122.563 87.5328 122.563C72.8698 122.563 60.2754 113.707 54.808 101.051H41.9228C47.9426 120.52 66.0858 134.664 87.5328 134.664C108.98 134.664 127.123 120.52 133.143 101.051H120.258ZM54.808 72.8156C60.2754 60.1599 72.8698 51.303 87.5328 51.303C102.196 51.303 114.79 60.1599 120.258 72.8156H120.26C121.819 76.1769 122.597 80.5352 122.597 80.5352H109.532H83.3859H31.412L22 92.3182H134.968C134.968 92.3182 135.265 89.8431 135.265 86.261C135.265 84.0149 134.968 79.1289 133.148 72.8156H133.143C127.123 53.3465 108.98 39.2021 87.5328 39.2021C66.0858 39.2021 47.9426 53.3465 41.9228 72.8156H54.808ZM227.72 118.53V84.9164C227.72 66.3522 212.67 51.303 194.105 51.303C175.541 51.303 160.491 66.3522 160.491 84.9164V118.53V122.563V134.664H148.39V84.9164C148.39 59.6691 168.857 39.2021 194.105 39.2021C219.353 39.2021 239.821 59.6691 239.821 84.9164V134.664H227.72V122.563V118.53ZM300.998 122.563C320.677 122.563 336.63 106.611 336.63 86.9332C336.63 67.2555 320.677 51.303 300.998 51.303C281.319 51.303 265.367 67.2555 265.367 86.9332C265.367 106.611 281.319 122.563 300.998 122.563ZM336.63 118.694C327.888 128.494 315.164 134.664 300.998 134.664C274.636 134.664 253.266 113.294 253.266 86.9332C253.266 60.5721 274.636 39.2021 300.998 39.2021C315.164 39.2021 327.888 45.3728 336.63 55.1727V43.2354H348.731V127.269C348.731 153.63 327.361 175 300.999 175C279.552 175 261.409 160.856 255.389 141.387H268.274C273.741 154.042 286.336 162.899 300.999 162.899C320.677 162.899 336.63 146.947 336.63 127.269V118.694ZM366.21 43.2354H378.311V134.664H366.21V43.2354Z"
127-
fill={fill}
50+
const resolvedFill = normalizeLogoColor(fill);
51+
const hideWordmark = /\bhidden\b/.test(softwareClassName);
52+
const glyphWidth = hideWordmark ? width : computeWordmarkMetrics(width).glyphWidth;
53+
const glyphHeight = height === 'auto' ? computeGlyphHeight(glyphWidth) : height;
54+
const wordmarkFontSize = hideWordmark
55+
? undefined
56+
: computeWordmarkMetrics(width).fontSize;
57+
const wordmarkOffset = softwareOffsetY ?? '-2px';
58+
59+
const glyph = (
60+
<span
61+
className="relative z-10"
62+
aria-hidden="true"
63+
style={{
64+
display: 'inline-block',
65+
width: glyphWidth,
66+
height: glyphHeight,
67+
backgroundColor: resolvedFill,
68+
WebkitMaskImage: 'url("/bitcode.svg")',
69+
maskImage: 'url("/bitcode.svg")',
70+
WebkitMaskRepeat: 'no-repeat',
71+
maskRepeat: 'no-repeat',
72+
WebkitMaskPosition: 'center',
73+
maskPosition: 'center',
74+
WebkitMaskSize: 'contain',
75+
maskSize: 'contain',
76+
}}
12877
/>
12978
);
13079

13180
return (
132-
<div className={`relative flex items-baseline ${className}`}>
133-
{/* Base logo (white) */}
134-
{/*
135-
The original SVG viewBox included ~15 px of empty space below the actual
136-
glyphs (0–190 px). Because flexbox baseline alignment uses the bottom
137-
box edge for replaced elements like <svg>, that extra space pushed the
138-
word-mark up and created the visual gap the design review called out.
139-
140-
Cropping the viewBox to the exact path bounds (0–175 px) removes the
141-
stray whitespace so the baseline sits flush with the bottom of the
142-
letters. This change keeps the logo proportions intact (the width
143-
remains 404 px) while fixing the vertical mis-alignment between
144-
“engi” and “.software”.
145-
*/}
146-
<svg
147-
width={width}
148-
height={computedHeight}
149-
viewBox="0 0 404 175"
150-
fill="none"
151-
xmlns="http://www.w3.org/2000/svg"
152-
className="relative z-10"
153-
>
154-
{LogoPath}
155-
</svg>
156-
157-
{/* Optional glow overlay – can be disabled via the `glow` prop */}
158-
{glow && (
81+
<div className={`relative inline-flex items-center gap-[0.18em] align-middle leading-none ${className}`}>
82+
{glow ? (
15983
<div
160-
className="absolute top-0 left-0 pointer-events-none z-20"
84+
className="relative"
16185
style={{
162-
overflow: 'visible',
163-
width: `calc(${LETTER_CLIP_PERCENT}% + ${GLOW_FADE_PX}px)`,
164-
height: computedHeight,
165-
//transform: `translateX(${LETTER_OFFSET_PERCENT}%)`,
166-
WebkitMaskImage: `linear-gradient(90deg,#000 calc(100% - ${GLOW_FADE_PX}px),transparent)` as any,
167-
maskImage: `linear-gradient(90deg,#000 calc(100% - ${GLOW_FADE_PX}px),transparent)`,
86+
filter:
87+
'drop-shadow(0 0 8px rgba(101,254,183,0.55)) drop-shadow(0 0 18px rgba(101,254,183,0.25))',
16888
}}
16989
>
170-
<svg
171-
width={width}
172-
height={computedHeight}
173-
viewBox="0 0 404 175"
174-
fill="none"
175-
xmlns="http://www.w3.org/2000/svg"
176-
style={{ filter: 'none' }}
177-
>
178-
{/* The overlay is filled with the neon colour itself so the drop-shadow stands out */}
179-
{React.cloneElement(LogoPath, { fill: '#65FEB7' })}
180-
</svg>
90+
{glyph}
18191
</div>
92+
) : (
93+
glyph
18294
)}
183-
184-
{/* .software text */}
185-
<span
186-
className={softwareClassName}
187-
style={{ transform: `translateY(${SOFTWARE_Y_TRANSLATE})` }}
188-
>
189-
.software
190-
</span>
95+
{!hideWordmark ? (
96+
<span
97+
className={`${softwareClassName} leading-none`}
98+
style={{
99+
transform: `translateY(${wordmarkOffset})`,
100+
fontSize: wordmarkFontSize,
101+
}}
102+
>
103+
Bitcode
104+
</span>
105+
) : null}
191106
</div>
192107
);
193108
}

uapi/components/base/engi/branding/logo.tsx

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,38 @@ type LogoProps = {
88
fill?: string;
99
};
1010

11+
function normalizeLogoColor(fill: string) {
12+
if (fill === 'theme(colors.brand.emerald)') return '#65FEB7';
13+
if (fill === 'theme(colors.brand.red)') return '#EF4444';
14+
return fill;
15+
}
16+
1117
export default function Logo({
1218
beta = false,
1319
className = "",
1420
height = 'h-10',
1521
width = 'h-10',
1622
fill = '#65FEB7'
1723
}: LogoProps) {
24+
const resolvedFill = normalizeLogoColor(fill);
25+
1826
return (
1927
<div className={"relative " + className} >
20-
<svg viewBox="0 0 31 26" className={`${height} ${width} z-20`}>
21-
<path fillRule="evenodd" clipRule="evenodd" d="M17.936 22.704a9.756 9.756 0 0 0 8.956-5.859h3.527A13.062 13.062 0 0 1 17.936 26a13.062 13.062 0 0 1-12.483-9.155h3.526a9.756 9.756 0 0 0 8.957 5.86Zm0-19.408a9.756 9.756 0 0 0-8.957 5.859H5.453A13.062 13.062 0 0 1 17.936 0c5.87 0 10.836 3.852 12.483 9.155h.002c.498 1.72.579 3.05.579 3.662 0 .976-.081 1.65-.081 1.65H0l2.576-3.21h24.957s-.213-1.187-.64-2.102a9.756 9.756 0 0 0-8.957-5.86Z" fill={fill}>
22-
</path>
23-
</svg>
28+
<span
29+
aria-label="Bitcode logo"
30+
className={`block ${height} ${width} z-20`}
31+
style={{
32+
backgroundColor: resolvedFill,
33+
WebkitMaskImage: 'url("/bitcode.svg")',
34+
maskImage: 'url("/bitcode.svg")',
35+
WebkitMaskRepeat: 'no-repeat',
36+
maskRepeat: 'no-repeat',
37+
WebkitMaskPosition: 'center',
38+
maskPosition: 'center',
39+
WebkitMaskSize: 'contain',
40+
maskSize: 'contain',
41+
}}
42+
/>
2443
{beta && (
2544
<div className="absolute z-30 bottom-0 right-[-10px] translate-x-[65%] translate-y-[65%] text-xs font-medium text-nowrap">
2645
<span className="text-[#65FEB7] [text-shadow:0_0_8px_rgba(101,254,183,0.8),0_0_16px_rgba(101,254,183,0.4)]">GA-1</span><sup className="text-[0.75em] ml-[1px] text-[#FF9547] [text-shadow:0_0_8px_rgba(255,149,71,0.8),0_0_16px_rgba(255,149,71,0.4)]">PRC</sup>

0 commit comments

Comments
 (0)