feat: update branding, genesis hash, and fix UI issues

- Update PEZKUWI_GENESIS to correct hash (0x1fc56b6a5fcd50358707f69b2b0bb0c8ab1fea2bcfc5eba7279efbcafef642af)
- Change highlight color from pink/orange to Kurdistan green (#86e62a)
- Add critical CSS in index.html to fix initial theme load issue
- Fix metadata badge showing incorrectly on every page load
- Fix block time text rendering vertically in explorer
- Update SVG logos with correct branding colors
This commit is contained in:
github-actions[bot]
2026-01-30 11:10:18 +03:00
parent 7e3a96ef5a
commit b2e2798d8c
15 changed files with 208 additions and 44 deletions
+2 -2
View File
@@ -19,8 +19,8 @@ export const KULUPU_GENESIS = getGenesis('kulupu');
// Dicle - Pezkuwi canary relay chain (placeholder until mainnet launch) // Dicle - Pezkuwi canary relay chain (placeholder until mainnet launch)
export const DICLE_GENESIS = '0xd9d3cd7c1e5d890d969b957f4c5b71a111bbeeabc968f1d0d4538c2663f080a7'; export const DICLE_GENESIS = '0xd9d3cd7c1e5d890d969b957f4c5b71a111bbeeabc968f1d0d4538c2663f080a7';
// Pezkuwi - Pezkuwi main relay chain (placeholder until mainnet launch) // Pezkuwi - Pezkuwi main relay chain
export const PEZKUWI_GENESIS = '0x41693961995d879073269a008d0a52832caa3e0ae73869f02127f3d5daa4934c'; export const PEZKUWI_GENESIS = '0x1fc56b6a5fcd50358707f69b2b0bb0c8ab1fea2bcfc5eba7279efbcafef642af';
export const PEZKUWI_DENOM_BLOCK = new BN(1248328); export const PEZKUWI_DENOM_BLOCK = new BN(1248328);
export const PASEO_GENESIS = '0x77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f'; export const PASEO_GENESIS = '0x77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f';
@@ -59,7 +59,7 @@ export const prodRelayPezkuwi: EndpointOption = {
teleport: [1000], teleport: [1000],
text: 'Pezkuwi', text: 'Pezkuwi',
ui: { ui: {
color: '#e6007a', color: '#86e62a',
identityIcon: 'jdenticon', identityIcon: 'jdenticon',
logo: chainsPezkuwiSVG logo: chainsPezkuwiSVG
} }
@@ -1,14 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs> <defs>
<linearGradient id="pezkuwiGrad" x1="0%" y1="0%" x2="100%" y2="100%"> <linearGradient id="pezkuwiGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#e6007a;stop-opacity:1" /> <stop offset="0%" style="stop-color:#86e62a;stop-opacity:1" />
<stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" /> <stop offset="100%" style="stop-color:#5cb800;stop-opacity:1" />
</linearGradient> </linearGradient>
</defs> </defs>
<!-- Kurdistan Sun inspired design with 21 rays --> <!-- Kurdistan Sun inspired design -->
<circle cx="50" cy="50" r="48" fill="url(#pezkuwiGrad)"/> <circle cx="50" cy="50" r="48" fill="url(#pezkuwiGrad)"/>
<circle cx="50" cy="50" r="35" fill="#ffffff"/> <circle cx="50" cy="50" r="35" fill="#ffffff"/>
<circle cx="50" cy="50" r="20" fill="#e6007a"/> <circle cx="50" cy="50" r="20" fill="#86e62a"/>
<!-- P letter for Pezkuwi --> <!-- P letter for Pezkuwi -->
<text x="50" y="58" text-anchor="middle" font-family="Arial, sans-serif" font-weight="bold" font-size="24" fill="#ffffff">P</text> <text x="50" y="58" text-anchor="middle" font-family="Arial, sans-serif" font-weight="bold" font-size="24" fill="#ffffff">P</text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 691 B

@@ -1,7 +1,7 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs> <defs>
<linearGradient id="pezkuwiassemblyGrad" x1="0%" y1="0%" x2="100%" y2="100%"> <linearGradient id="pezkuwiassemblyGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#e6007a;stop-opacity:1" /> <stop offset="0%" style="stop-color:#86e62a;stop-opacity:1" />
<stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" /> <stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" />
</linearGradient> </linearGradient>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,7 +1,7 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs> <defs>
<linearGradient id="pezkuwiholicGrad" x1="0%" y1="0%" x2="100%" y2="100%"> <linearGradient id="pezkuwiholicGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#e6007a;stop-opacity:1" /> <stop offset="0%" style="stop-color:#86e62a;stop-opacity:1" />
<stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" /> <stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" />
</linearGradient> </linearGradient>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 680 B

After

Width:  |  Height:  |  Size: 680 B

+1 -1
View File
@@ -1,7 +1,7 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs> <defs>
<linearGradient id="pezkuwiscanGrad" x1="0%" y1="0%" x2="100%" y2="100%"> <linearGradient id="pezkuwiscanGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#e6007a;stop-opacity:1" /> <stop offset="0%" style="stop-color:#86e62a;stop-opacity:1" />
<stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" /> <stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" />
</linearGradient> </linearGradient>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 873 B

After

Width:  |  Height:  |  Size: 873 B

@@ -1,7 +1,7 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs> <defs>
<linearGradient id="pezkuwistatsGrad" x1="0%" y1="0%" x2="100%" y2="100%"> <linearGradient id="pezkuwistatsGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#e6007a;stop-opacity:1" /> <stop offset="0%" style="stop-color:#86e62a;stop-opacity:1" />
<stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" /> <stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" />
</linearGradient> </linearGradient>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 809 B

After

Width:  |  Height:  |  Size: 809 B

@@ -1,7 +1,7 @@
<svg viewBox="0 0 1976.45 2282.21" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 1976.45 2282.21" xmlns="http://www.w3.org/2000/svg">
<defs> <defs>
<linearGradient id="bizinikiwiGrad" x1="0%" y1="0%" x2="100%" y2="100%"> <linearGradient id="bizinikiwiGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#e6007a;stop-opacity:1" /> <stop offset="0%" style="stop-color:#86e62a;stop-opacity:1" />
<stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" /> <stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" />
</linearGradient> </linearGradient>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1,7 +1,7 @@
<svg width="121" height="121" viewBox="0 0 121 121" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="121" height="121" viewBox="0 0 121 121" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs> <defs>
<linearGradient id="soraBizinikiwiGrad" x1="0%" y1="0%" x2="100%" y2="100%"> <linearGradient id="soraBizinikiwiGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#e6007a;stop-opacity:1" /> <stop offset="0%" style="stop-color:#86e62a;stop-opacity:1" />
<stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" /> <stop offset="100%" style="stop-color:#86e62a;stop-opacity:1" />
</linearGradient> </linearGradient>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 976 B

After

Width:  |  Height:  |  Size: 976 B

+134 -7
View File
@@ -3,21 +3,148 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#211b25"> <meta name="theme-color" content="#86e62a">
<meta name="description" content="PezkuwiChain Explorer">
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="favicon.ico">
<title><%= htmlWebpackPlugin.options.PAGE_TITLE %></title> <title><%= htmlWebpackPlugin.options.PAGE_TITLE %></title>
<script type="text/javascript" src="env-config.js"></script> <script type="text/javascript" src="env-config.js"></script>
<script>
(function() {
// Read theme from localStorage
var themeName = 'light';
try {
var settings = localStorage.getItem('settings');
if (settings) {
var parsed = JSON.parse(settings);
if (parsed && parsed.uiTheme === 'dark') {
themeName = 'dark';
}
}
} catch (e) {}
// Apply theme attribute immediately
document.documentElement.setAttribute('data-theme', themeName);
document.documentElement.className = 'theme--' + themeName;
})();
</script>
<style> <style>
.--absolute { position: absolute; } :root {
.--digits { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; } --highlight-color: #86e62a;
.--hidden { display: none; } --highlight-contrast: #1a1b20;
.--relative { position: relative; } }
.--tmp { background: grey; filter: blur(2px); opacity: 0.15; }
/* Dark theme variables */
html[data-theme="dark"],
.theme--dark {
--bg-page: #1a1b20;
--bg-table: #26272c;
--bg-input: #38393f;
--bg-menu: #26272c;
--bg-tabs: #38393f;
--bg-sidebar: #1a1b20;
--color-text: rgba(244, 242, 240, 0.8);
--color-label: rgba(244, 242, 240, 0.6);
--border-table: #343536;
}
/* Light theme variables */
html[data-theme="light"],
.theme--light {
--bg-page: #f5f3f1;
--bg-table: #ffffff;
--bg-input: #ffffff;
--bg-menu: #ffffff;
--bg-tabs: #ffffff;
--bg-sidebar: #fafafa;
--color-text: rgba(78, 78, 78, 0.8);
--color-label: rgba(78, 78, 78, 0.6);
--border-table: #efedeb;
}
html, body {
margin: 0;
padding: 0;
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
body {
background: var(--bg-page) !important;
color: var(--color-text) !important;
}
#root {
min-height: 100vh;
background: var(--bg-page) !important;
color: var(--color-text) !important;
}
/* Override semantic-ui defaults */
.ui.segment,
.ui.segments,
.ui.form,
.ui.menu,
.ui.table,
.ui.card,
.ui.cards > .card {
background: var(--bg-table) !important;
color: var(--color-text) !important;
}
.ui.table thead th {
background: var(--bg-tabs) !important;
color: var(--color-text) !important;
}
.ui.input > input,
.ui.form input,
.ui.form textarea,
.ui.selection.dropdown {
background: var(--bg-input) !important;
color: var(--color-text) !important;
}
/* Critical: Menu highlight background */
.highlight--bg {
background: var(--highlight-color) !important;
}
/* Critical: Toggle switches */
.ui--Toggle.isChecked:not(.isRadio) .ui--Toggle-Slider {
background: var(--highlight-color) !important;
}
.ui--Toggle.isChecked:not(.isRadio) .ui--Toggle-Slider::before {
border-color: var(--highlight-color) !important;
}
/* Critical: Buttons */
.ui--Button:hover:not(.isDisabled):not(.isReadOnly),
.ui--Button.isSelected {
background: var(--highlight-color) !important;
color: var(--highlight-contrast) !important;
}
/* Critical: Tabs active indicator */
.ui--Tabs .active .tabLinkText::after {
background: var(--highlight-color) !important;
}
/* Critical: Primary buttons */
.ui.primary.button,
.ui.buttons .primary.button {
background: var(--highlight-color) !important;
color: var(--highlight-contrast) !important;
}
/* Critical: Badge on menu */
.ui--MenuItem.isActive .ui--Badge {
background: var(--highlight-color);
}
</style> </style>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>JavaScript is required to run this application.</noscript>
<div id="root"></div> <div id="root"></div>
<div id="tooltips"></div> <div id="tooltips"></div>
<script> <script>
+3 -1
View File
@@ -54,7 +54,7 @@ function BlockHeader ({ headers }: Props): React.ReactElement<Props> | null {
)} )}
</td> </td>
<td <td
className='all --digits blockTime' className='--digits blockTime'
key={Date.now()} key={Date.now()}
> >
{getDisplayValue((Date.now() - value.timestamp.toNumber()) / 1000)} {getDisplayValue((Date.now() - value.timestamp.toNumber()) / 1000)}
@@ -74,6 +74,8 @@ const StyledTr = styled.tr<{isFirstItem: boolean; isLastItem: boolean}>`
.blockTime { .blockTime {
text-align: right; text-align: right;
font-style: italic; font-style: italic;
white-space: nowrap;
min-width: 6rem;
} }
td { td {
+15 -2
View File
@@ -81,8 +81,21 @@ function filterAll (api: ApiPromise, all: ExtensionKnown[]): Extensions {
.map((info): ExtensionInfo | null => { .map((info): ExtensionInfo | null => {
const current = info.known.find(({ genesisHash }) => api.genesisHash.eq(genesisHash)) || null; const current = info.known.find(({ genesisHash }) => api.genesisHash.eq(genesisHash)) || null;
// if we cannot find it as known, or either the specVersion or properties mismatches, mark it as upgradable // Only mark as upgradable if:
return !current || api.runtimeVersion.specVersion.gtn(current.specVersion) || !hasCurrentProperties(api, info) // 1. Extension HAS metadata for this chain but specVersion is outdated, OR
// 2. Extension HAS metadata but properties (decimals, symbol, ss58) have changed
// Do NOT mark as upgradable if extension simply doesn't have metadata for this chain yet
// (that's a fresh install scenario, not an "update needed" scenario)
if (!current) {
// No metadata for this chain - don't mark as needing update
// The extension will get metadata when user explicitly provides it
return null;
}
// Check if specVersion is outdated or properties have changed
const needsUpdate = api.runtimeVersion.specVersion.gtn(current.specVersion) || !hasCurrentProperties(api, info);
return needsUpdate
? { ...info, current } ? { ...info, current }
: null; : null;
}) })
+2 -2
View File
@@ -88,7 +88,7 @@ function tattooSpiro (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
ctx.translate(0, -radius); ctx.translate(0, -radius);
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, (bits[i] ? dot : dot / 2), 0, 2 * Math.PI); ctx.arc(0, 0, (bits[i] ? dot : dot / 2), 0, 2 * Math.PI);
ctx.fillStyle = bits[i] ? 'black' : '#e6007a'; ctx.fillStyle = bits[i] ? 'black' : '#86e62a';
ctx.fill(); ctx.fill();
ctx.restore(); ctx.restore();
} }
@@ -105,7 +105,7 @@ function tattooPink (ctx: CanvasRenderingContext2D, bits: boolean[]): void {
ring(ctx, 0.5 - (31 / 500) * (i + 0.5), rows[i], (ctx, on) => { ring(ctx, 0.5 - (31 / 500) * (i + 0.5), rows[i], (ctx, on) => {
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, (on ? 8 : 4) / 500, 0, 2 * Math.PI); ctx.arc(0, 0, (on ? 8 : 4) / 500, 0, 2 * Math.PI);
ctx.fillStyle = on ? 'black' : '#e6007a'; ctx.fillStyle = on ? 'black' : '#86e62a';
ctx.fill(); ctx.fill();
}); });
} }
+39 -17
View File
@@ -18,7 +18,7 @@ const FACTORS = [0.2126, 0.7152, 0.0722];
const PARTS = [0, 2, 4]; const PARTS = [0, 2, 4];
const VERY_DARK = 16; const VERY_DARK = 16;
export const defaultHighlight = '#f19135'; export const defaultHighlight = '#86e62a';
function getHighlight (uiHighlight: string | undefined): string { function getHighlight (uiHighlight: string | undefined): string {
return (uiHighlight || defaultHighlight); return (uiHighlight || defaultHighlight);
@@ -64,27 +64,47 @@ export default createGlobalStyle<Props>(({ uiHighlight }: Props) => `
/* Dark theme CSS variables */ /* Dark theme CSS variables */
html[data-theme="dark"], html[data-theme="dark"],
[data-theme="dark"] { [data-theme="dark"] {
--bg-page: #26272c !important; --bg-page: #26272c;
--bg-table: #3b3d3f !important; --bg-table: #3b3d3f;
--bg-input: #38393f !important; --bg-input: #38393f;
--bg-menu: #26272c !important; --bg-input-error: #48393f;
--bg-tabs: #38393f !important; --bg-menu: #26272c;
--bg-sidebar: #1a1b20 !important; --bg-tabs: #38393f;
--color-text: rgba(244, 242, 240, 0.8) !important; --bg-sidebar: #1a1b20;
--border-table: #343536 !important; --bg-toggle: #58595f;
--bg-inverse: rgba(78, 78, 78, 0.66);
--bg-identicon-circle: #282829;
--color-text: rgba(244, 242, 240, 0.8);
--color-header: rgba(244, 242, 240, 0.9);
--color-label: rgba(244, 242, 240, 0.6);
--color-error: rgba(255, 83, 83, 0.8);
--border-table: #343536;
--border-tabs: #343536;
--border-input: rgba(234, 236, 238, .15);
--border-identicon: transparent;
} }
/* Light theme CSS variables */ /* Light theme CSS variables */
html[data-theme="light"], html[data-theme="light"],
[data-theme="light"] { [data-theme="light"] {
--bg-page: #f5f3f1 !important; --bg-page: #f5f3f1;
--bg-table: #ffffff !important; --bg-table: #ffffff;
--bg-input: #ffffff !important; --bg-input: #ffffff;
--bg-menu: #ffffff !important; --bg-input-error: #fff6f6;
--bg-tabs: #ffffff !important; --bg-menu: #ffffff;
--bg-sidebar: #fafafa !important; --bg-tabs: #ffffff;
--color-text: rgba(78, 78, 78, 0.8) !important; --bg-sidebar: #fafafa;
--border-table: #efedeb !important; --bg-toggle: #e4e5e6;
--bg-inverse: rgba(244, 242, 240, 0.91);
--bg-identicon-circle: #eee;
--color-text: rgba(78, 78, 78, 0.8);
--color-header: rgba(78, 78, 78, 0.9);
--color-label: rgba(78, 78, 78, 0.6);
--color-error: rgba(139, 0, 0);
--border-table: #efedeb;
--border-tabs: #f1efed;
--border-input: rgba(34, 36, 38, .15);
--border-identicon: #ddd;
} }
.highlight--all { .highlight--all {
@@ -331,6 +351,8 @@ export default createGlobalStyle<Props>(({ uiHighlight }: Props) => `
} }
} }
html.theme--dark,
html.theme--light,
.theme--dark, .theme--dark,
.theme--light { .theme--light {
.ui--Tabs .active .tabLinkText::after { .ui--Tabs .active .tabLinkText::after {
@@ -6,8 +6,8 @@ export const colorBtnDefault = '#767778';
export const colorBtnShadow = '#98999a'; export const colorBtnShadow = '#98999a';
/* highlighted buttons, orange */ /* highlighted buttons, Kurdistan green */
export const colorBtnHighlight = '#f19135'; export const colorBtnHighlight = '#86e62a';
/* primary buttons, blue */ /* primary buttons, blue */
export const colorBtnPrimary = colorBtnDefault; // '#2e86ab'; export const colorBtnPrimary = colorBtnDefault; // '#2e86ab';