diff --git a/src/app/_components/Footer/StacksSmiley.tsx b/src/app/_components/Footer/StacksSmiley.tsx
new file mode 100644
index 000000000..4bd65166e
--- /dev/null
+++ b/src/app/_components/Footer/StacksSmiley.tsx
@@ -0,0 +1,34 @@
+import { useColorMode } from '@/components/ui/color-mode';
+import { StacksSmileyDarkIcon } from '@/ui/icons/StacksSmileyDarkIcon';
+import { StacksSmileyLaserEyesDarkIcon } from '@/ui/icons/StacksSmileyLaserEyesDarkIcon';
+import { StacksSmileyLaserEyesLightIcon } from '@/ui/icons/StacksSmileyLaserEyesLightIcon';
+import { StacksSmileyLightIcon } from '@/ui/icons/StacksSmileyLightIcon';
+import { Box, BoxProps, ClientOnly } from '@chakra-ui/react';
+import { useState } from 'react';
+
+export const StacksSmiley = (boxProps: BoxProps) => {
+ const { colorMode } = useColorMode();
+ const [isHovered, setIsHovered] = useState(false);
+ return (
+
+ setIsHovered(true)}
+ onMouseLeave={() => setIsHovered(false)}
+ {...boxProps}
+ >
+ {colorMode === 'light' ? (
+ isHovered ? (
+
+ ) : (
+
+ )
+ ) : isHovered ? (
+
+ ) : (
+
+ )}
+
+
+ );
+};
diff --git a/src/app/_components/NewFooter.tsx b/src/app/_components/NewFooter.tsx
new file mode 100644
index 000000000..601f69849
--- /dev/null
+++ b/src/app/_components/NewFooter.tsx
@@ -0,0 +1,211 @@
+'use client';
+
+import { ExplorerLink } from '@/common/components/ExplorerLinks';
+import { HiroIcon } from '@/ui/icons/HiroIcon';
+import { StacksNameAndLogo } from '@/ui/icons/StacksNameAndLogo';
+import { Box, Flex, Grid, Stack, Text } from '@chakra-ui/react';
+
+import { PAGE_MAX_WIDTH } from '../../common/constants/constants';
+import { Link } from '../../ui/Link';
+import { StacksSmiley } from './Footer/StacksSmiley';
+
+interface Link {
+ label: string;
+ href: string;
+}
+
+const rightSideLinks: Link[] = [
+ {
+ label: 'Home',
+ href: '/',
+ },
+ {
+ label: 'Blocks',
+ href: '/blocks',
+ },
+ {
+ label: 'Transactions',
+ href: '/transactions',
+ },
+ {
+ label: 'sBTC',
+ href: '/token/SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token',
+ },
+ {
+ // This page is not implemented yet
+ label: 'Stacking',
+ href: '/stacking',
+ },
+ {
+ // This page is not implemented yet
+ label: 'Mempool',
+ href: '/mempool',
+ },
+ {
+ label: 'Signers',
+ href: '/signers',
+ },
+ {
+ label: 'Tokens',
+ href: '/tokens',
+ },
+ {
+ // This page is not implemented yet
+ label: 'NFTs',
+ href: '/nfts',
+ },
+ {
+ // This page is not implemented yet
+ label: 'Analytics',
+ href: '/analytics',
+ },
+ {
+ label: 'Search',
+ href: '/search',
+ },
+];
+
+const leftSideLinks: Link[] = [
+ {
+ label: 'Sandbox',
+ href: '/sandbox/deploy',
+ },
+ {
+ label: 'Status Center',
+ href: 'https://status.hiro.so/',
+ },
+ {
+ label: 'Support',
+ href: '/support',
+ },
+];
+
+const xPadding = 8;
+
+export const NewFooter = () => {
+ return (
+
+
+
+
+
+
+
+
+ {rightSideLinks.map(link => (
+
+ {link.label}
+
+ ))}
+
+
+
+ {leftSideLinks.map(link => (
+
+ {link.label}
+
+ ))}
+
+
+
+
+
+ {rightSideLinks.concat(leftSideLinks).map(link => (
+
+ {link.label}
+
+ ))}
+
+
+
+
+
+
+
+ This Stacks Explorer is built and maintained by{' '}
+
+ Hiro
+
+
+
+
+ Terms of Use
+
+
+ Privacy Policy
+
+
+ Market data provided by{' '}
+
+ LunarCrush
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/app/_components/PageWrapper.tsx b/src/app/_components/PageWrapper.tsx
index af27895f1..d12e7db48 100644
--- a/src/app/_components/PageWrapper.tsx
+++ b/src/app/_components/PageWrapper.tsx
@@ -1,5 +1,6 @@
'use client';
+import { isRedesignUrl } from '@/common/utils/url-utils';
import { Stack } from '@chakra-ui/react';
import styled from '@emotion/styled';
import { ReactNode } from 'react';
@@ -11,6 +12,7 @@ import { TokenPrice } from '../../common/types/tokenPrice';
import { Footer } from './Footer';
import { NavBar } from './NavBar';
import { NetworkModeToast } from './NetworkModeToast';
+import { NewFooter } from './NewFooter';
import { CMSStatusBars } from './StatusBar/CMSStatusBars';
import { IncidentsStatusBarWithErrorBoundary } from './StatusBar/IncidentsStatusBar';
import { NonHiroNetworkWarningBar } from './StatusBar/NonHiroNetworkWarningBar';
@@ -82,6 +84,7 @@ export function PageWrapper({
statusBarContent: IncidentContent | null;
serverThemeCookie: string;
}) {
+ const redesignUrl = isRedesignUrl();
return (
<>
@@ -99,7 +102,7 @@ export function PageWrapper({
>
{children}
-
+ {redesignUrl ? : }
diff --git a/src/common/utils/url-utils.ts b/src/common/utils/url-utils.ts
index f6084d229..11dbc372e 100644
--- a/src/common/utils/url-utils.ts
+++ b/src/common/utils/url-utils.ts
@@ -9,3 +9,9 @@ const isImage = (url: string): boolean => {
const extension = urlWithoutParams.split('.').pop();
return !!extension && ['png', 'jpg', 'jpeg', 'gif', 'svg'].includes(extension);
};
+
+export const isRedesignUrl = (): boolean => {
+ const queryParams = new URLSearchParams(window.location.search);
+ const redesignParam = queryParams.get('redesign');
+ return !!redesignParam;
+};
diff --git a/src/ui/icons/HiroIcon.tsx b/src/ui/icons/HiroIcon.tsx
new file mode 100644
index 000000000..061057daa
--- /dev/null
+++ b/src/ui/icons/HiroIcon.tsx
@@ -0,0 +1,32 @@
+import { Icon, IconProps } from '@chakra-ui/react';
+
+export const HiroIcon = ({ color, ...rest }: IconProps) => {
+ return (
+
+
+
+ );
+};
diff --git a/src/ui/icons/StacksNameAndLogo.tsx b/src/ui/icons/StacksNameAndLogo.tsx
new file mode 100644
index 000000000..13978ed8e
--- /dev/null
+++ b/src/ui/icons/StacksNameAndLogo.tsx
@@ -0,0 +1,50 @@
+import { Icon, IconProps } from '@chakra-ui/react';
+
+export const StacksNameAndLogo = ({ color, ...rest }: { color: string } & IconProps) => {
+ return (
+
+
+
+ );
+};
diff --git a/src/ui/icons/StacksSmileyDarkIcon.tsx b/src/ui/icons/StacksSmileyDarkIcon.tsx
new file mode 100644
index 000000000..c26af4e3c
--- /dev/null
+++ b/src/ui/icons/StacksSmileyDarkIcon.tsx
@@ -0,0 +1,193 @@
+import { Icon, IconProps } from '@chakra-ui/react';
+
+export const StacksSmileyDarkIcon = (iconProps: IconProps) => {
+ return (
+
+
+
+ );
+};
diff --git a/src/ui/icons/StacksSmileyLaserEyesDarkIcon.tsx b/src/ui/icons/StacksSmileyLaserEyesDarkIcon.tsx
new file mode 100644
index 000000000..c292b85ce
--- /dev/null
+++ b/src/ui/icons/StacksSmileyLaserEyesDarkIcon.tsx
@@ -0,0 +1,271 @@
+import { Icon, IconProps } from '@chakra-ui/react';
+
+export const StacksSmileyLaserEyesDarkIcon = (iconProps: IconProps) => {
+ return (
+
+
+
+ );
+};
diff --git a/src/ui/icons/StacksSmileyLaserEyesLightIcon.tsx b/src/ui/icons/StacksSmileyLaserEyesLightIcon.tsx
new file mode 100644
index 000000000..ed864c7c7
--- /dev/null
+++ b/src/ui/icons/StacksSmileyLaserEyesLightIcon.tsx
@@ -0,0 +1,271 @@
+import { Icon, IconProps } from '@chakra-ui/react';
+
+export const StacksSmileyLaserEyesLightIcon = (iconProps: IconProps) => {
+ return (
+
+
+
+ );
+};
diff --git a/src/ui/icons/StacksSmileyLightIcon.tsx b/src/ui/icons/StacksSmileyLightIcon.tsx
new file mode 100644
index 000000000..5db779357
--- /dev/null
+++ b/src/ui/icons/StacksSmileyLightIcon.tsx
@@ -0,0 +1,193 @@
+import { Icon, IconProps } from '@chakra-ui/react';
+
+export const StacksSmileyLightIcon = (iconProps: IconProps) => {
+ return (
+
+
+
+ );
+};
diff --git a/src/ui/theme/recipes/LinkRecipe.ts b/src/ui/theme/recipes/LinkRecipe.ts
index 94a101a2b..ced9d9354 100644
--- a/src/ui/theme/recipes/LinkRecipe.ts
+++ b/src/ui/theme/recipes/LinkRecipe.ts
@@ -1,5 +1,3 @@
-'use client';
-
import { defineRecipe } from '@chakra-ui/react';
export const linkRecipe = defineRecipe({
diff --git a/src/ui/theme/semanticTokens.ts b/src/ui/theme/semanticTokens.ts
index 6cda11aa6..5f15d47cf 100644
--- a/src/ui/theme/semanticTokens.ts
+++ b/src/ui/theme/semanticTokens.ts
@@ -237,6 +237,9 @@ export const CURRENT_SEMANTIC_TOKENS = {
},
},
},
+ stacksNameAndLogo: {
+ value: { base: '{colors.neutral.sand-1000}', _dark: '{colors.neutral.sand-50}' },
+ },
},
};
@@ -248,6 +251,18 @@ export const NEW_SEMANTIC_TOKENS = {
iconPrimary: {
value: { base: '{colors.black}', _dark: '{colors.neutral.sand-100}' },
},
+ iconTertiary: {
+ value: { base: '{colors.neutral.sand-400}', _dark: '{colors.neutral.sand-500}' },
+ },
+ textInteractiveHover: {
+ value: { base: '{colors.accent.stacks-600}', _dark: '{colors.accent.stacks-400}' },
+ },
+ textSecondary: {
+ value: { base: '{colors.neutral.sand-600}', _dark: '{colors.neutral.sand-400}' },
+ },
+ textPrimary: {
+ value: { base: '{colors.neutral.sand-1000}', _dark: '{colors.neutral.sand-100}' },
+ },
},
};
diff --git a/src/ui/theme/sizes.ts b/src/ui/theme/sizes.ts
index f9b9f9975..137670420 100644
--- a/src/ui/theme/sizes.ts
+++ b/src/ui/theme/sizes.ts
@@ -19,9 +19,11 @@ import { SPACE } from './space';
// };
export const CURRENT_SIZES = {
- 4.5: { value: '1.125rem' },
- 60: { value: '3.75rem' },
- 150: { value: '9.375rem' },
+ 3.5: { value: '0.875rem' }, // 14px
+ 4.5: { value: '1.125rem' }, // 18px
+ 18: { value: '4.5rem' }, // 72px
+ 60: { value: '3.75rem' }, // 60px
+ 150: { value: '9.375rem' }, // 150px
};
export const NEW_SIZES = {
diff --git a/src/ui/theme/space.ts b/src/ui/theme/space.ts
index ad5f6ab46..6b6dd041f 100644
--- a/src/ui/theme/space.ts
+++ b/src/ui/theme/space.ts
@@ -43,6 +43,7 @@ export const NEW_SPACE = {
1: { value: '0.25rem' }, // 4px
2: { value: '0.5rem' }, // 8px
3: { value: '0.75rem' }, // 12px
+ 3.5: { value: '0.875rem' }, // 14px
4: { value: '1rem' }, // 16px
4.5: { value: '1.125rem' },
5: { value: '1.25rem' }, // 20px