From f3adb29bee2ad28ba7d826b97978d55ed6cfef00 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Wed, 9 Oct 2024 17:30:33 +0100
Subject: [PATCH 01/15] feat: refactor cowamm banner

---
 .../src/common/pure/CoWAMMBanner/index.tsx    | 289 ++++++++++--------
 1 file changed, 158 insertions(+), 131 deletions(-)

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index 265c32cc46..dcd66afc04 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -1,30 +1,36 @@
-import { Media } from '@cowprotocol/ui'
+import { useState } from 'react'
+
+import { Media, ProductLogo, ProductVariant } from '@cowprotocol/ui'
 import { ClosableBanner } from '@cowprotocol/ui'
 
 import { X } from 'react-feather'
+import { Textfit } from 'react-textfit'
 import styled from 'styled-components/macro'
 
 import { cowAnalytics } from 'modules/analytics'
 
 const BannerWrapper = styled.div`
   --darkGreen: #194d05;
+  --green: #2b6f0b;
   --lightGreen: #bcec79;
+  --lighterGreen: #dcf8a7;
+  --blue: #3fc4ff;
 
   position: fixed;
   top: 76px;
   right: 10px;
   z-index: 3;
-  width: 400px;
-  height: 345px;
+  width: 485px;
+  height: auto;
   border-radius: 24px;
   background-color: var(--darkGreen);
-  color: var(--lightGreen);
-  padding: 24px;
+  color: var(--darkGreen);
+  padding: 20px;
+  gap: 20px;
   display: flex;
   flex-flow: column wrap;
   align-items: center;
   justify-content: center;
-  gap: 24px;
   overflow: hidden;
 
   ${Media.upToSmall()} {
@@ -40,160 +46,141 @@ const BannerWrapper = styled.div`
     box-shadow: 0 0 0 100vh rgb(0 0 0 / 40%);
     z-index: 10;
   }
+`
 
-  > i {
-    position: absolute;
-    top: -30px;
-    left: -30px;
-    width: 166px;
-    height: 42px;
-    border: 1px solid var(--lightGreen);
-    border-radius: 16px;
-    border-left: 0;
-    animation: bounceLeftRight 7s infinite;
-    animation-delay: 2s;
-  }
-
-  &::before {
-    content: '';
-    position: absolute;
-    top: 100px;
-    left: -23px;
-    width: 56px;
-    height: 190px;
-    border: 1px solid var(--lightGreen);
-    border-radius: 16px;
-    border-left: 0;
-    animation: bounceUpDown 7s infinite;
-  }
-
-  &::after {
-    content: '';
-    position: absolute;
-    bottom: -21px;
-    right: 32px;
-    width: 76px;
-    height: 36px;
-    border: 1px solid var(--lightGreen);
-    border-radius: 16px;
-    border-bottom: 0;
-    animation: bounceLeftRight 7s infinite;
-    animation-delay: 1s;
-  }
-
-  > div {
-    display: flex;
-    flex-flow: column wrap;
-    gap: 24px;
-    width: 100%;
-    max-width: 75%;
-    margin: 0 auto;
-  }
-
-  @keyframes bounceUpDown {
-    0%,
-    100% {
-      transform: translateY(0);
-    }
-    50% {
-      transform: translateY(-7px);
-    }
-  }
+const CloseButton = styled(X)`
+  position: absolute;
+  top: 16px;
+  right: 16px;
+  cursor: pointer;
+  color: var(--lightGreen);
+  opacity: 0.6;
+  transition: opacity 0.2s ease-in-out;
 
-  @keyframes bounceLeftRight {
-    0%,
-    100% {
-      transform: translateX(0);
-    }
-    50% {
-      transform: translateX(7px);
-    }
+  &:hover {
+    opacity: 1;
   }
 `
 
 const Title = styled.h2`
-  font-size: 34px;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 18px;
   font-weight: bold;
-  margin: 0;
+  margin: 0 auto 0 0;
+  color: var(--lightGreen);
 
   ${Media.upToSmall()} {
     font-size: 26px;
   }
 `
 
-const Description = styled.p`
-  font-size: 17px;
-  line-height: 1.5;
+const Card = styled.div<{ bgColor?: string; color?: string }>`
+  display: grid;
+  grid-template-columns: 1.1fr 0.9fr;
+  gap: 24px;
+  align-items: center;
+  justify-content: center;
+  font-size: 30px;
+  line-height: 1.2;
+  font-weight: 500;
   margin: 0;
+  width: 100%;
+  max-width: 100%;
+  min-height: 150px;
+  border-radius: 16px;
+  padding: 24px;
+  background: ${({ bgColor }) => bgColor || 'transparent'};
+  color: ${({ color }) => color || 'inherit'};
 
-  ${Media.upToSmall()} {
-    font-size: 15px;
+  > h3,
+  > p {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin: 0;
+    width: 100%;
+    height: 100%;
+
+    > div {
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+
+  > h3 {
+    font-weight: bold;
+    letter-spacing: -2px;
+  }
+
+  > p {
+    font-weight: inherit;
   }
 `
 
 const CTAButton = styled.button`
-  background-color: var(--lightGreen);
+  --size: 58px;
+  background: var(--lightGreen);
   color: var(--darkGreen);
   border: none;
-  border-radius: 56px;
+  border-radius: var(--size);
+  min-height: var(--size);
   padding: 12px 24px;
-  font-size: 18px;
+  font-size: 24px;
   font-weight: bold;
   cursor: pointer;
   width: 100%;
-  max-width: 75%;
+  max-width: 100%;
   display: flex;
   align-items: center;
   justify-content: center;
   gap: 8px;
-  transition: border-radius 0.2s ease-in-out;
+  transition: background 0.2s ease-in-out;
 
   &:hover {
-    border-radius: 16px;
-
-    > i {
-      transform: rotate(45deg);
-    }
-  }
-
-  > i {
-    font-size: 22px;
-    font-weight: bold;
-    font-style: normal;
-    line-height: 1;
-    margin: 3px 0 0;
-    transition: transform 0.2s ease-in-out;
-    animation: spin 6s infinite;
-  }
-
-  @keyframes spin {
-    0% {
-      transform: rotate(0deg);
-    }
-    20% {
-      transform: rotate(360deg);
-    }
-    100% {
-      transform: rotate(360deg);
-    }
+    background: var(--lighterGreen);
   }
 `
 
-const CloseButton = styled(X)`
-  position: absolute;
-  top: 16px;
-  right: 16px;
-  cursor: pointer;
+const SecondaryLink = styled.a`
   color: var(--lightGreen);
-  opacity: 0.6;
-  transition: opacity 0.2s ease-in-out;
+  font-size: 14px;
+  font-weight: 500;
+  text-decoration: none;
 
   &:hover {
-    opacity: 1;
+    text-decoration: underline;
   }
 `
 
+const DEMO_DROPDOWN = styled.select`
+  position: fixed;
+  bottom: 150px;
+  right: 10px;
+  z-index: 999999999;
+  padding: 5px;
+  font-size: 16px;
+`
+
+// Dummy data for different states
+const dummyData = {
+  noLp: { apr: 1.5, comparison: 'UNI-V2' },
+  uniV2: { apr: 2.1, comparison: 'UNI-V2' },
+  sushi: { apr: 1.8, comparison: 'SushiSwap' },
+  curve: { apr: 1.3, comparison: 'Curve' },
+  pancake: { apr: 2.5, comparison: 'PancakeSwap' },
+  multiple: { apr: 2.0, comparison: 'UNI-V2, SushiSwap' },
+} as const
+
+type StateKey = keyof typeof dummyData
+
 export function CoWAmmBanner() {
+  const [selectedState, setSelectedState] = useState<StateKey>('noLp')
+
   const handleCTAClick = () => {
     cowAnalytics.sendEvent({
       category: 'CoW Swap',
@@ -202,7 +189,7 @@ export function CoWAmmBanner() {
 
     window.open(
       'https://balancer.fi/pools/cow?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner',
-      '_blank'
+      '_blank',
     )
   }
 
@@ -213,9 +200,21 @@ export function CoWAmmBanner() {
     })
   }
 
-  return ClosableBanner('cow_amm_banner', (close) => (
+  const getAprMessage = () => {
+    const { apr } = dummyData[selectedState]
+    return `+${apr.toFixed(1)}%`
+  }
+
+  const getComparisonMessage = () => {
+    const { comparison } = dummyData[selectedState]
+    if (selectedState === 'multiple') {
+      return `Get higher APR than average ${comparison}`
+    }
+    return `Get higher APR than ${comparison}`
+  }
+
+  return ClosableBanner('cow_amm_banner_2024_va', (close) => (
     <BannerWrapper>
-      <i></i>
       <CloseButton
         size={24}
         onClick={() => {
@@ -223,15 +222,43 @@ export function CoWAmmBanner() {
           close()
         }}
       />
-      <div>
-        <Title>Now live: the first MEV-capturing AMM</Title>
-        <Description>
-          CoW AMM shields you from LVR, so you can provide liquidity with less risk and more rewards.
-        </Description>
-      </div>
-      <CTAButton onClick={handleCTAClick}>
-        LP on CoW AMM <i>↗</i>
-      </CTAButton>
+
+      <DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
+        <option value="noLp">No LP tokens</option>
+        <option value="uniV2">UNI-V2 LP</option>
+        <option value="sushi">SushiSwap LP</option>
+        <option value="curve">Curve LP</option>
+        <option value="pancake">PancakeSwap LP</option>
+        <option value="multiple">Multiple LP tokens</option>
+      </DEMO_DROPDOWN>
+
+      <Title>
+        <ProductLogo height={20} overrideColor={'var(--lightGreen)'} variant={ProductVariant.CowAmm} logoIconOnly />
+        <span>CoW AMM</span>
+      </Title>
+      <Card bgColor={'var(--blue)'}>
+        <h3>
+          <Textfit mode="single" forceSingleModeWidth={false} min={21} max={76}>
+            {getAprMessage()}
+          </Textfit>
+        </h3>
+        <p>
+          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28}>
+            {getComparisonMessage()}
+          </Textfit>
+        </p>
+      </Card>
+
+      <Card bgColor={'var(--green)'} color={'var(--lighterGreen)'}>
+        <p>
+          <Textfit mode="single" forceSingleModeWidth={false} min={10} max={28}>
+            One-click convert, boost yield
+          </Textfit>
+        </p>
+      </Card>
+
+      <CTAButton onClick={handleCTAClick}>Booooost APR gas-free!</CTAButton>
+      <SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</SecondaryLink>
     </BannerWrapper>
   ))
 }

From 8054f7fc97f8baa386f1de1ff5d52afd3def5aa5 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Thu, 10 Oct 2024 17:53:35 +0100
Subject: [PATCH 02/15] feat: refactor cowamm banner

---
 .../src/common/pure/CoWAMMBanner/index.tsx    | 279 ++++++++++++++++--
 libs/assets/src/cow-swap/icon-curve.svg       |   1 +
 libs/assets/src/cow-swap/icon-pancakeswap.svg |   1 +
 libs/assets/src/cow-swap/icon-sushi.svg       |   1 +
 libs/assets/src/cow-swap/icon-uni.svg         |   1 +
 5 files changed, 252 insertions(+), 31 deletions(-)
 create mode 100644 libs/assets/src/cow-swap/icon-curve.svg
 create mode 100644 libs/assets/src/cow-swap/icon-pancakeswap.svg
 create mode 100644 libs/assets/src/cow-swap/icon-sushi.svg
 create mode 100644 libs/assets/src/cow-swap/icon-uni.svg

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index dcd66afc04..59dcebe5ed 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -1,21 +1,40 @@
 import { useState } from 'react'
 
+import ICON_ARROW from '@cowprotocol/assets/cow-swap/arrow.svg'
+import ICON_CURVE from '@cowprotocol/assets/cow-swap/icon-curve.svg'
+import ICON_PANCAKESWAP from '@cowprotocol/assets/cow-swap/icon-pancakeswap.svg'
+import ICON_SUSHISWAP from '@cowprotocol/assets/cow-swap/icon-sushi.svg'
+import ICON_UNISWAP from '@cowprotocol/assets/cow-swap/icon-uni.svg'
+import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
 import { Media, ProductLogo, ProductVariant } from '@cowprotocol/ui'
 import { ClosableBanner } from '@cowprotocol/ui'
 
 import { X } from 'react-feather'
+import SVG from 'react-inlinesvg'
 import { Textfit } from 'react-textfit'
 import styled from 'styled-components/macro'
 
 import { cowAnalytics } from 'modules/analytics'
 
-const BannerWrapper = styled.div`
-  --darkGreen: #194d05;
-  --green: #2b6f0b;
-  --lightGreen: #bcec79;
-  --lighterGreen: #dcf8a7;
-  --blue: #3fc4ff;
+// Add this enum at the top of the file, after imports
+enum CoWAMMColors {
+  DarkGreen = '#194d05',
+  Green = '#2b6f0b',
+  LightGreen = '#bcec79',
+  LighterGreen = '#dcf8a7',
+  Blue = '#3fc4ff',
+  LightBlue = '#ccf8ff',
+}
+
+// Add this enum after the CoWAMMColors enum
+enum LpToken {
+  UniswapV2 = 'UniswapV2',
+  Sushiswap = 'Sushiswap',
+  PancakeSwap = 'PancakeSwap',
+  Curve = 'Curve',
+}
 
+const BannerWrapper = styled.div`
   position: fixed;
   top: 76px;
   right: 10px;
@@ -23,8 +42,8 @@ const BannerWrapper = styled.div`
   width: 485px;
   height: auto;
   border-radius: 24px;
-  background-color: var(--darkGreen);
-  color: var(--darkGreen);
+  background-color: ${CoWAMMColors.DarkGreen};
+  color: ${CoWAMMColors.DarkGreen};
   padding: 20px;
   gap: 20px;
   display: flex;
@@ -53,7 +72,7 @@ const CloseButton = styled(X)`
   top: 16px;
   right: 16px;
   cursor: pointer;
-  color: var(--lightGreen);
+  color: ${CoWAMMColors.LightGreen};
   opacity: 0.6;
   transition: opacity 0.2s ease-in-out;
 
@@ -69,16 +88,17 @@ const Title = styled.h2`
   font-size: 18px;
   font-weight: bold;
   margin: 0 auto 0 0;
-  color: var(--lightGreen);
+  color: ${CoWAMMColors.LightGreen};
 
   ${Media.upToSmall()} {
     font-size: 26px;
   }
 `
 
-const Card = styled.div<{ bgColor?: string; color?: string }>`
-  display: grid;
-  grid-template-columns: 1.1fr 0.9fr;
+const Card = styled.div<{ bgColor?: string; color?: string; height?: string }>`
+  --default-height: 150px;
+  display: flex;
+  flex-flow: row nowrap;
   gap: 24px;
   align-items: center;
   justify-content: center;
@@ -88,12 +108,13 @@ const Card = styled.div<{ bgColor?: string; color?: string }>`
   margin: 0;
   width: 100%;
   max-width: 100%;
-  min-height: 150px;
+  height: ${({ height }) => height || 'var(--default-height)'};
+  max-height: ${({ height }) => height || 'var(--default-height)'};
   border-radius: 16px;
   padding: 24px;
   background: ${({ bgColor }) => bgColor || 'transparent'};
   color: ${({ color }) => color || 'inherit'};
-
+  position: relative;
   > h3,
   > p {
     display: flex;
@@ -102,6 +123,7 @@ const Card = styled.div<{ bgColor?: string; color?: string }>`
     margin: 0;
     width: 100%;
     height: 100%;
+    max-height: 100%;
 
     > div {
       width: 100%;
@@ -120,12 +142,17 @@ const Card = styled.div<{ bgColor?: string; color?: string }>`
   > p {
     font-weight: inherit;
   }
+
+  > p b {
+    font-weight: 900;
+    color: ${CoWAMMColors.LighterGreen};
+  }
 `
 
 const CTAButton = styled.button`
   --size: 58px;
-  background: var(--lightGreen);
-  color: var(--darkGreen);
+  background: ${CoWAMMColors.LightGreen};
+  color: ${CoWAMMColors.DarkGreen};
   border: none;
   border-radius: var(--size);
   min-height: var(--size);
@@ -142,12 +169,12 @@ const CTAButton = styled.button`
   transition: background 0.2s ease-in-out;
 
   &:hover {
-    background: var(--lighterGreen);
+    background: ${CoWAMMColors.LighterGreen};
   }
 `
 
 const SecondaryLink = styled.a`
-  color: var(--lightGreen);
+  color: ${CoWAMMColors.LightGreen};
   font-size: 14px;
   font-weight: 500;
   text-decoration: none;
@@ -166,18 +193,164 @@ const DEMO_DROPDOWN = styled.select`
   font-size: 16px;
 `
 
-// Dummy data for different states
+const StarIcon = styled.div<{ size?: number; top?: number; left?: number; right?: number; bottom?: number }>`
+  width: ${({ size }) => size || 16}px;
+  height: ${({ size }) => size || 16}px;
+  position: absolute;
+  top: ${({ top }) => top ?? 'initial'}px;
+  left: ${({ left }) => left ?? 'initial'}px;
+  right: ${({ right }) => right ?? 'initial'}px;
+  bottom: ${({ bottom }) => bottom ?? 'initial'}px;
+`
+
+const LpEmblems = styled.div<{ totalItems: number }>`
+  display: flex;
+  gap: 8px;
+  width: 100%;
+  justify-content: center;
+  align-items: center;
+`
+
+const LpEmblemItemsWrapper = styled.div<{ totalItems: number }>`
+  display: ${({ totalItems }) => (totalItems > 2 ? 'grid' : 'flex')};
+  gap: ${({ totalItems }) => (totalItems > 2 ? '0' : '8px')};
+  width: 100%;
+  justify-content: center;
+  align-items: center;
+
+  ${({ totalItems }) =>
+    totalItems === 3 &&
+    `
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: 1fr 1fr;
+    justify-items: center;
+
+    > :first-child {
+      grid-column: 1 / -1;
+    }
+  `}
+
+  ${({ totalItems }) =>
+    totalItems === 4 &&
+    `
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: 1fr 1fr;
+  `}
+`
+
+const LpEmblemItem = styled.div<{
+  totalItems: number
+  index: number
+}>`
+  --size: ${({ totalItems }) =>
+    totalItems === 4 ? '50px' : totalItems === 3 ? '65px' : totalItems === 2 ? '80px' : '104px'};
+  width: var(--size);
+  height: var(--size);
+  padding: ${({ totalItems }) => (totalItems === 4 ? '10px' : totalItems >= 2 ? '15px' : '20px')};
+  border-radius: 50%;
+  background: ${CoWAMMColors.DarkGreen};
+  color: ${CoWAMMColors.LightGreen};
+  border: ${({ totalItems }) =>
+    totalItems > 2 ? `2px solid ${CoWAMMColors.Green}` : `4px solid ${CoWAMMColors.Green}`};
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+
+  > svg {
+    width: 100%;
+    height: 100%;
+  }
+
+  ${({ totalItems, index }) => {
+    const styleMap: Record<number, Record<number, string>> = {
+      2: {
+        0: 'margin-right: -42px;',
+      },
+      3: {
+        0: 'margin-bottom: -20px; z-index: 10;',
+        1: 'margin-top: -20px;',
+        2: 'margin-top: -20px;',
+      },
+      4: {
+        0: 'margin-bottom: -5px; z-index: 10; margin-right: -10px;',
+        1: 'margin-bottom: -5px; z-index: 10;',
+        2: 'margin-top: -5px; margin-right: -10px;',
+        3: 'margin-top: -5px;',
+      },
+    }
+
+    return styleMap[totalItems]?.[index] || ''
+  }}
+`
+
+const CoWAMMEmblemItem = styled.div`
+  --size: 104px;
+  width: var(--size);
+  height: var(--size);
+  border-radius: var(--size);
+  padding: 30px 30px 23px 30px;
+  background: ${CoWAMMColors.LightGreen};
+  color: ${CoWAMMColors.DarkGreen};
+  border: 4px solid ${CoWAMMColors.Green};
+  display: flex;
+  align-items: center;
+  justify-content: center;
+`
+
+const EmblemArrow = styled.div`
+  --size: 32px;
+  width: var(--size);
+  height: var(--size);
+  min-width: var(--size);
+  border-radius: var(--size);
+  background: ${CoWAMMColors.DarkGreen};
+  border: 3px solid ${CoWAMMColors.Green};
+  margin: 0 -24px;
+  padding: 6px;
+  z-index: 10;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: ${CoWAMMColors.LightGreen};
+
+  > svg > path {
+    fill: ${CoWAMMColors.LightGreen};
+  }
+`
+// Update the dummyData object to include all possible states
 const dummyData = {
   noLp: { apr: 1.5, comparison: 'UNI-V2' },
   uniV2: { apr: 2.1, comparison: 'UNI-V2' },
   sushi: { apr: 1.8, comparison: 'SushiSwap' },
   curve: { apr: 1.3, comparison: 'Curve' },
   pancake: { apr: 2.5, comparison: 'PancakeSwap' },
-  multiple: { apr: 2.0, comparison: 'UNI-V2, SushiSwap' },
+  twoLps: { apr: 2.0, comparison: 'UNI-V2 and SushiSwap' },
+  threeLps: { apr: 2.2, comparison: 'UNI-V2, SushiSwap, and Curve' },
+  fourLps: { apr: 2.4, comparison: 'UNI-V2, Sushiswap, Curve, and Balancer' },
 } as const
 
 type StateKey = keyof typeof dummyData
 
+// Update the lpTokenConfig mapping to match dummyData keys
+const lpTokenConfig: Record<StateKey, LpToken[]> = {
+  noLp: [LpToken.UniswapV2],
+  uniV2: [LpToken.UniswapV2],
+  sushi: [LpToken.Sushiswap],
+  curve: [LpToken.Curve],
+  pancake: [LpToken.PancakeSwap],
+  twoLps: [LpToken.UniswapV2, LpToken.Sushiswap],
+  threeLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve],
+  fourLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve, LpToken.Curve],
+}
+
+const lpTokenIcons: Record<LpToken, string> = {
+  [LpToken.UniswapV2]: ICON_UNISWAP,
+  [LpToken.Sushiswap]: ICON_SUSHISWAP,
+  [LpToken.PancakeSwap]: ICON_PANCAKESWAP,
+  [LpToken.Curve]: ICON_CURVE,
+}
+
 export function CoWAmmBanner() {
   const [selectedState, setSelectedState] = useState<StateKey>('noLp')
 
@@ -207,12 +380,47 @@ export function CoWAmmBanner() {
 
   const getComparisonMessage = () => {
     const { comparison } = dummyData[selectedState]
-    if (selectedState === 'multiple') {
-      return `Get higher APR than average ${comparison}`
+    if (selectedState === 'noLp') {
+      return `yield over the average UNI-V2 pool`
+    }
+    if (selectedState === 'twoLps' || selectedState === 'threeLps') {
+      return `Get higher average APR than ${comparison}`
     }
     return `Get higher APR than ${comparison}`
   }
 
+  const renderLpEmblems = () => {
+    const tokens = lpTokenConfig[selectedState]
+    const totalItems = tokens.length
+
+    if (totalItems === 0) {
+      return null
+    }
+
+    return (
+      <LpEmblems totalItems={totalItems}>
+        <LpEmblemItemsWrapper totalItems={totalItems}>
+          {tokens.map((token, index) => (
+            <LpEmblemItem key={token} totalItems={totalItems} index={index}>
+              <SVG src={lpTokenIcons[token]} />
+            </LpEmblemItem>
+          ))}
+        </LpEmblemItemsWrapper>
+        <EmblemArrow>
+          <SVG src={ICON_ARROW} />
+        </EmblemArrow>
+        <CoWAMMEmblemItem>
+          <ProductLogo
+            height={'100%'}
+            overrideColor={CoWAMMColors.DarkGreen}
+            variant={ProductVariant.CowAmm}
+            logoIconOnly
+          />
+        </CoWAMMEmblemItem>
+      </LpEmblems>
+    )
+  }
+
   return ClosableBanner('cow_amm_banner_2024_va', (close) => (
     <BannerWrapper>
       <CloseButton
@@ -229,32 +437,41 @@ export function CoWAmmBanner() {
         <option value="sushi">SushiSwap LP</option>
         <option value="curve">Curve LP</option>
         <option value="pancake">PancakeSwap LP</option>
-        <option value="multiple">Multiple LP tokens</option>
+        <option value="twoLps">2 LP tokens</option>
+        <option value="threeLps">3 LP tokens</option>
+        <option value="fourLps">4 LP tokens</option>
       </DEMO_DROPDOWN>
 
       <Title>
-        <ProductLogo height={20} overrideColor={'var(--lightGreen)'} variant={ProductVariant.CowAmm} logoIconOnly />
+        <ProductLogo height={20} overrideColor={CoWAMMColors.DarkGreen} variant={ProductVariant.CowAmm} logoIconOnly />
         <span>CoW AMM</span>
       </Title>
-      <Card bgColor={'var(--blue)'}>
+      <Card bgColor={CoWAMMColors.Blue}>
+        <StarIcon size={36} top={-17} right={80}>
+          <SVG src={ICON_STAR} />
+        </StarIcon>
         <h3>
-          <Textfit mode="single" forceSingleModeWidth={false} min={21} max={76}>
+          <Textfit mode="single" forceSingleModeWidth={false} min={21} max={80} key={getAprMessage()}>
             {getAprMessage()}
           </Textfit>
         </h3>
         <p>
-          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28}>
+          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28} key={getComparisonMessage()}>
             {getComparisonMessage()}
           </Textfit>
         </p>
+        <StarIcon size={26} bottom={-10} right={20}>
+          <SVG src={ICON_STAR} />
+        </StarIcon>
       </Card>
 
-      <Card bgColor={'var(--green)'} color={'var(--lighterGreen)'}>
+      <Card bgColor={CoWAMMColors.Green} color={CoWAMMColors.LightGreen}>
         <p>
-          <Textfit mode="single" forceSingleModeWidth={false} min={10} max={28}>
-            One-click convert, boost yield
+          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={30}>
+            One-click convert, <b>boost yield</b>
           </Textfit>
         </p>
+        {renderLpEmblems()}
       </Card>
 
       <CTAButton onClick={handleCTAClick}>Booooost APR gas-free!</CTAButton>
diff --git a/libs/assets/src/cow-swap/icon-curve.svg b/libs/assets/src/cow-swap/icon-curve.svg
new file mode 100644
index 0000000000..07688bbd5c
--- /dev/null
+++ b/libs/assets/src/cow-swap/icon-curve.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 33 34"><path fill="#BCEC79" d="M26.194 13.864c-.264-2.34-4.42-5.15-11.121-7.516a3.02 3.02 0 0 0-.464-.04c-.28 0-.563.053-.708.237-.216.274-.16.816-.071 1.017 1.01 2.277 2.354 5.621 2.69 9.024 1.526-.064 4.128-.18 6.523-.485 3.348-.45 3.2-1.795 3.151-2.238v.002Z"/><path fill="#BCEC79" d="M30.805 11.095c-.957-1.367-4.086-3.777-5.415-4.564-1.123-.664-6.382-3.48-11.59-5.12-.761-.236-2.164-.593-3.708-.593-1.262 0-2.619.238-3.796.973C3.59 3.481 1.238 8.142.574 13.129c-.74 5.511-.901 15.784 3.188 19.323 1.426 1.235 3.233 1.519 5.523.867 1.907-.545 4.161-2.822 4.894-6.678l.085-.442.037-.013c.698-2.77.913-5.342.735-8.754v-.006c-.177-3.404-1.579-6.904-2.617-9.24-.256-.58-.395-1.748.268-2.593.388-.494 1.174-1.027 2.714-.757l.062.012.06.021c9.649 3.395 11.962 6.671 12.206 8.825.164 1.502-.48 3.402-4.485 3.939-2.45.313-5.076.432-6.631.496.098 2.785-.083 5.12-.587 7.466.564-.197 1.102-.387 1.629-.577 3.234-1.15 5.787-2.059 9.767-2.79l.075-.014c1.162-.193 4.246-.704 5.048-3.803.894-3.36.159-4.597-1.738-7.316h-.002ZM9.588 26.147c-.64 1.282-1.405 1.529-1.802 1.564h-.033l-.033.001c-.4 0-1.18-.189-1.905-1.449-.61-1.03-.968-2.445-1.009-3.973-.04-1.521.236-2.953.776-4.032.64-1.281 1.405-1.528 1.804-1.563h.064c.4-.002 1.181.185 1.905 1.445.592 1.043.95 2.45 1.009 3.964v.01c.04 1.52-.235 2.953-.776 4.031v.002Z"/><path fill="#BCEC79" d="M8.013 18.91c-.233-.406-.432-.584-.536-.647-.106.069-.301.262-.516.687-.422.845-.646 2.047-.613 3.302.033 1.25.324 2.431.8 3.236.238.415.439.594.543.658.106-.07.301-.263.515-.687.423-.843.645-2.046.614-3.296-.05-1.253-.344-2.438-.807-3.252v-.002Zm23.979 10.21a.343.343 0 0 1-.346-.347c0-.194.152-.347.346-.347.2 0 .356.153.356.347a.351.351 0 0 1-.356.346Zm.236 2.72h-.48v-2.384h.48v2.384Zm-.926-2.383v.42h-.614v1.964h-.48v-1.964h-.384v-.42h.383v-.208c0-.462.292-.763.726-.763.152 0 .263.023.351.051v.44a.945.945 0 0 0-.259-.042c-.185 0-.337.074-.337.3v.222h.614Zm-2.198 2.413a.363.363 0 0 1-.365-.366c0-.203.157-.36.365-.36.213 0 .36.162.36.36a.359.359 0 0 1-.36.365Zm-2.56-1.073c.041.356.263.638.67.638a.563.563 0 0 0 .55-.356h.494c-.037.226-.31.79-1.044.79-.689 0-1.165-.527-1.165-1.22 0-.679.485-1.22 1.141-1.22.638 0 1.11.541 1.11 1.193 0 .064-.005.124-.01.175h-1.746Zm.646-.933c-.355 0-.573.25-.633.573h1.253c-.051-.319-.264-.573-.62-.573Zm-1.858-.409h.513l-.947 2.384h-.494l-.952-2.384h.513l.42 1.077c.083.217.185.48.263.72h.005c.083-.24.18-.503.263-.72l.416-1.077Zm-2.327-.025c.111 0 .176.009.231.014v.48a1.48 1.48 0 0 0-.25-.023c-.36 0-.614.203-.614.66v1.28h-.48v-2.384h.48v.314a.706.706 0 0 1 .633-.341Zm-2.959 2.437c-.527 0-.878-.356-.878-.984v-1.428h.48v1.405c0 .314.236.531.536.531a.539.539 0 0 0 .545-.55v-1.386h.48v2.384h-.47v-.332a.817.817 0 0 1-.693.36Zm-2.833.001a1.672 1.672 0 0 1-1.668-1.69c0-.934.735-1.692 1.668-1.692a1.5 1.5 0 0 1 1.465 1.137h-.508c-.125-.384-.555-.656-.957-.656-.67 0-1.187.54-1.187 1.21 0 .67.517 1.21 1.187 1.21.44 0 .823-.249.97-.66h.509c-.153.642-.703 1.141-1.479 1.141Z"/></svg>
\ No newline at end of file
diff --git a/libs/assets/src/cow-swap/icon-pancakeswap.svg b/libs/assets/src/cow-swap/icon-pancakeswap.svg
new file mode 100644
index 0000000000..3367035850
--- /dev/null
+++ b/libs/assets/src/cow-swap/icon-pancakeswap.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 192 199"><path fill="currentColor" fill-rule="evenodd" d="M25.708 178.998c16.598 12.582 40.353 19.587 69.844 19.609h.148c29.49-.022 53.245-7.027 69.844-19.609 16.797-12.733 25.708-30.803 25.708-51.25 0-19.701-8.892-33.907-18.952-43.51-7.884-7.525-16.585-12.344-22.643-15.117 1.37-4.162 3.079-9.61 4.608-15.238 2.047-7.53 4.054-16.366 4.054-22.84 0-7.663-1.688-15.36-6.239-21.34C147.272 3.385 140.033 0 131.325 0c-6.806 0-12.584 2.499-17.107 6.81-4.324 4.12-7.202 9.593-9.189 15.298-3.492 10.024-4.851 22.618-5.233 35.187h-8.34c-.382-12.569-1.742-25.163-5.233-35.187-1.987-5.705-4.865-11.177-9.19-15.298C72.51 2.5 66.734 0 59.927 0 51.218 0 43.98 3.385 39.171 9.703c-4.55 5.98-6.239 13.677-6.239 21.34 0 6.474 2.008 15.31 4.054 22.84 1.53 5.628 3.239 11.076 4.608 15.238-6.058 2.773-14.758 7.592-22.642 15.118C8.892 93.84 0 108.047 0 127.748c0 20.447 8.91 38.517 25.708 51.25Zm36.647-46.323c5.666 0 10.258-5.061 10.258-14.779s-4.592-14.779-10.258-14.779c-5.665 0-10.257 5.061-10.257 14.779s4.592 14.779 10.257 14.779Zm66.676 0c5.665 0 10.257-5.061 10.257-14.779s-4.592-14.779-10.257-14.779c-5.666 0-10.258 5.061-10.258 14.779s4.592 14.779 10.258 14.779Z" clip-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/libs/assets/src/cow-swap/icon-sushi.svg b/libs/assets/src/cow-swap/icon-sushi.svg
new file mode 100644
index 0000000000..5e214be336
--- /dev/null
+++ b/libs/assets/src/cow-swap/icon-sushi.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 22"><path fill="currentColor" d="M12.94 9.462c2.4 1.6 4.8 2.1 5.5 1.1.7-1-.7-3.1-3-4.7-2.4-1.6-4.8-2.1-5.5-1.1-.7 1 .7 3.1 3 4.7Z"/><path fill="currentColor" fill-rule="evenodd" d="M17.04 3.464c5.2 3.4 8 8.2 6.5 10.5l-4.6 6.8-.048-.033c-1.658 2.215-7.002 1.297-12.051-2.267C1.823 14.922-1.065 10.413.366 7.982L.34 7.964l4.6-6.7c1.6-2.3 7-1.4 12.1 2.2Zm-5.2 7.798c4.7 3.3 9.6 4.3 11 2.3 1.3-2-1.5-6.2-6.2-9.5s-9.6-4.3-11-2.3c-1.4 2 1.4 6.2 6.2 9.5Zm-7.3-7.699c0-.1-.1-.2-.2-.1a.559.559 0 0 1-.11.082c-.052.033-.09.056-.09.118.026.08.053.154.078.222.068.185.122.332.122.478 0 .1.1.2.2.1.1 0 .2-.1.1-.2 0-.2 0-.4-.1-.7Zm.501 1.6c0-.1-.1-.2-.2-.1s-.1.1-.1.2c1.1 2.5 3.4 5.2 6.4 7.2.067.067.134.044.2.022.034-.011.067-.022.1-.022.067-.067.045-.133.023-.2a.322.322 0 0 1-.023-.1c-3.1-2-5.3-4.6-6.4-7Zm11.9 9.9c0-.1.1-.1.2-.1.15.05.324.1.5.15.174.05.35.1.5.15.1 0 .1.1.1.2s-.1.1-.2.1c-.15-.05-.325-.1-.5-.15-.175-.05-.35-.1-.5-.15-.1 0-.1-.1-.1-.2Zm1.8.5c0-.1.1-.2.2-.2.8.1 1.6.2 2.4.1.1 0 .2.1.2.2s-.1.2-.2.2c-.7.1-1.6 0-2.4-.1-.1 0-.2-.1-.2-.2Z" clip-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/libs/assets/src/cow-swap/icon-uni.svg b/libs/assets/src/cow-swap/icon-uni.svg
new file mode 100644
index 0000000000..a88a09ae2e
--- /dev/null
+++ b/libs/assets/src/cow-swap/icon-uni.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 38 41"><path fill="currentColor" d="M14.702 9.722c-.46-.067-.479-.075-.263-.106.414-.06 1.392.022 2.066.173 1.574.354 3.005 1.26 4.533 2.87l.406.427.581-.088c2.447-.372 4.936-.076 7.018.833.573.25 1.476.749 1.588.877.036.04.102.303.147.584.155.97.077 1.713-.236 2.268-.17.302-.18.398-.066.656.092.206.347.359.6.359.517 0 1.074-.792 1.332-1.893l.103-.437.203.217c1.113 1.194 1.988 2.822 2.138 3.98l.04.302-.188-.274c-.322-.473-.645-.794-1.06-1.054-.747-.468-1.537-.627-3.63-.731-1.89-.094-2.959-.247-4.02-.574-1.804-.557-2.713-1.298-4.857-3.958-.952-1.181-1.54-1.835-2.126-2.362-1.33-1.196-2.636-1.823-4.31-2.069Z"/><path fill="currentColor" d="M31.058 12.36c.047-.791.16-1.313.389-1.79.09-.19.175-.344.188-.344.013 0-.026.14-.087.31-.166.463-.193 1.096-.08 1.832.146.935.228 1.07 1.273 2.08.49.473 1.059 1.07 1.266 1.326l.375.467-.375-.333c-.46-.408-1.516-1.202-1.75-1.316-.155-.076-.179-.075-.275.016-.09.084-.108.21-.12.804-.02.927-.153 1.522-.475 2.116-.174.322-.202.253-.044-.11.118-.27.13-.39.129-1.287-.002-1.803-.228-2.236-1.555-2.979-.336-.188-.89-.459-1.23-.602-.341-.144-.612-.269-.602-.278.037-.035 1.331.322 1.852.511.774.282.902.319.996.285.064-.023.094-.197.125-.707Zm-15.464 3.084c-.933-1.214-1.51-3.076-1.385-4.467l.04-.431.211.037c.399.068 1.086.31 1.408.495.883.507 1.265 1.175 1.654 2.89.114.503.263 1.071.332 1.264.11.31.53 1.033.87 1.503.244.338.082.499-.46.453-.827-.071-1.947-.802-2.67-1.744Zm14.333 9.037c-4.357-1.66-5.892-3.1-5.892-5.53 0-.358.013-.65.029-.65s.184.117.375.262c.883.67 1.873.956 4.612 1.334 1.611.223 2.518.402 3.355.665 2.66.834 4.305 2.527 4.697 4.833.114.67.047 1.927-.138 2.59-.146.523-.59 1.466-.709 1.502-.033.01-.065-.109-.073-.27-.045-.866-.508-1.71-1.284-2.341-.884-.718-2.07-1.29-4.972-2.395Zm-3.059.689c-.055-.307-.15-.7-.21-.872l-.112-.313.207.22c.286.303.512.69.703 1.208.146.395.162.512.161 1.153 0 .63-.02.762-.154 1.117a3.51 3.51 0 0 1-.92 1.384c-.796.766-1.819 1.19-3.295 1.367a34.81 34.81 0 0 1-1.663.114c-1.657.082-2.748.25-3.729.576-.14.047-.266.075-.28.063-.039-.038.629-.414 1.18-.665.777-.354 1.55-.547 3.285-.82.856-.136 1.74-.3 1.965-.364 2.12-.616 3.21-2.203 2.862-4.168Z"/><path fill="currentColor" d="M28.865 28.526c-.579-1.177-.711-2.314-.394-3.374.034-.113.088-.206.12-.206.034 0 .17.07.304.155.267.17.802.457 2.228 1.192 1.778.917 2.792 1.627 3.482 2.439.604.71.978 1.52 1.158 2.507.102.56.042 1.905-.11 2.468-.478 1.775-1.59 3.17-3.175 3.983-.232.12-.44.217-.463.218-.023 0 .062-.203.188-.453.533-1.054.594-2.08.19-3.222-.246-.699-.75-1.552-1.766-2.993-1.181-1.677-1.471-2.123-1.762-2.714ZM12.5 34.878c1.616-1.292 3.628-2.21 5.46-2.49.79-.122 2.106-.074 2.837.103 1.173.284 2.221.92 2.767 1.677.533.74.762 1.385 1 2.82.093.566.196 1.135.227 1.263.178.744.526 1.339.957 1.637.685.474 1.864.504 3.024.076.197-.073.368-.123.38-.112.042.04-.542.41-.954.604-.555.262-.995.364-1.581.364-1.063 0-1.945-.512-2.68-1.554-.145-.205-.471-.82-.724-1.366-.777-1.676-1.16-2.187-2.063-2.746-.785-.486-1.798-.573-2.56-.22-1 .464-1.28 1.674-.563 2.44.285.305.816.568 1.25.619.813.096 1.511-.49 1.511-1.265 0-.504-.204-.792-.72-1.012-.704-.3-1.46.05-1.457.676.002.267.125.435.407.556.182.077.186.084.038.054-.646-.126-.797-.863-.278-1.352.624-.587 1.913-.328 2.356.474.186.336.207 1.006.045 1.411-.363.906-1.421 1.383-2.495 1.123-.73-.176-1.028-.367-1.91-1.226-1.53-1.492-2.125-1.781-4.333-2.107l-.423-.063.481-.384Z"/><path fill="currentColor" fill-rule="evenodd" d="M.952 1.452c5.114 5.871 12.998 15.013 13.39 15.525.323.422.201.802-.352 1.1-.308.165-.941.333-1.258.333-.358 0-.762-.163-1.056-.427-.208-.186-1.047-1.372-2.984-4.214-1.482-2.175-2.722-3.98-2.755-4.01-.079-.07-.077-.067 2.604 4.472 1.684 2.85 2.252 3.857 2.252 3.992 0 .274-.079.418-.436.795-.596.629-.862 1.335-1.055 2.797-.215 1.64-.821 2.797-2.5 4.779-.984 1.16-1.145 1.372-1.393 1.84-.313.589-.399.919-.433 1.662-.037.786.035 1.294.288 2.045.223.658.455 1.093 1.048 1.962.512.75.806 1.307.806 1.525 0 .173.035.173.828.004 1.898-.405 3.44-1.118 4.306-1.992.537-.541.663-.84.667-1.581.002-.485-.016-.586-.154-.865-.226-.454-.636-.832-1.541-1.417-1.186-.767-1.692-1.384-1.832-2.233-.115-.696.018-1.188.674-2.488.68-1.346.848-1.92.961-3.276.074-.877.176-1.223.442-1.5.277-.29.527-.387 1.215-.476 1.12-.145 1.833-.42 2.42-.93.508-.444.721-.87.754-1.514l.025-.488-.285-.313C14.57 15.423.263.559.2.559c-.014 0 .325.402.752.893Zm6.744 29.533a.834.834 0 0 0-.28-1.136c-.368-.231-.94-.122-.94.18 0 .091.054.158.176.218.204.099.219.21.058.439-.163.231-.15.434.037.573.3.222.726.1.95-.274ZM16.59 20.06c-.526.152-1.037.68-1.196 1.233-.096.337-.042.928.103 1.111.234.295.46.373 1.071.369 1.198-.008 2.24-.494 2.36-1.101.1-.498-.358-1.188-.988-1.491-.325-.157-1.016-.219-1.35-.122Zm1.4 1.035c.184-.248.104-.516-.21-.698-.599-.345-1.503-.06-1.503.475 0 .266.471.557.904.557.288 0 .682-.163.809-.334Z" clip-rule="evenodd"/></svg>
\ No newline at end of file

From b6f7c69372b7d8a4f67a39b6b0d4df3a53dae8bd Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Fri, 11 Oct 2024 15:34:31 +0100
Subject: [PATCH 03/15] feat: add token selector cow amm banner

---
 .../src/common/pure/CoWAMMBanner/dummyData.ts |  30 ++
 .../src/common/pure/CoWAMMBanner/index.tsx    | 498 ++++--------------
 .../src/common/pure/CoWAMMBanner/styled.ts    | 354 +++++++++++++
 .../pure/CoWAMMBanner/tokenSelectorBanner.tsx | 143 +++++
 .../pure/SelectTokenModal/index.tsx           |   2 +
 .../pure/TokensVirtualList/index.tsx          |   4 +
 libs/ui/src/enum.ts                           |   9 +
 libs/ui/src/theme/ThemeColorVars.tsx          |  13 +-
 8 files changed, 647 insertions(+), 406 deletions(-)
 create mode 100644 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
 create mode 100644 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
 create mode 100644 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
new file mode 100644
index 0000000000..0cfb4da319
--- /dev/null
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
@@ -0,0 +1,30 @@
+export enum LpToken {
+  UniswapV2 = 'UniswapV2',
+  Sushiswap = 'Sushiswap',
+  PancakeSwap = 'PancakeSwap',
+  Curve = 'Curve',
+}
+
+export const dummyData = {
+  noLp: { apr: 1.5, comparison: 'UNI-V2' },
+  uniV2: { apr: 2.1, comparison: 'UNI-V2' },
+  sushi: { apr: 1.8, comparison: 'SushiSwap' },
+  curve: { apr: 1.3, comparison: 'Curve' },
+  pancake: { apr: 2.5, comparison: 'PancakeSwap' },
+  twoLps: { apr: 2.0, comparison: 'UNI-V2 and SushiSwap' },
+  threeLps: { apr: 2.2, comparison: 'UNI-V2, SushiSwap, and Curve' },
+  fourLps: { apr: 2.4, comparison: 'UNI-V2, Sushiswap, Curve, and Balancer' },
+} as const
+
+export type StateKey = keyof typeof dummyData
+
+export const lpTokenConfig: Record<StateKey, LpToken[]> = {
+  noLp: [LpToken.UniswapV2],
+  uniV2: [LpToken.UniswapV2],
+  sushi: [LpToken.Sushiswap],
+  curve: [LpToken.Curve],
+  pancake: [LpToken.PancakeSwap],
+  twoLps: [LpToken.UniswapV2, LpToken.Sushiswap],
+  threeLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve],
+  fourLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve, LpToken.Curve],
+}
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index 59dcebe5ed..d0164987f6 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react'
+import { useState, useCallback, useMemo } from 'react'
 
 import ICON_ARROW from '@cowprotocol/assets/cow-swap/arrow.svg'
 import ICON_CURVE from '@cowprotocol/assets/cow-swap/icon-curve.svg'
@@ -6,343 +6,32 @@ import ICON_PANCAKESWAP from '@cowprotocol/assets/cow-swap/icon-pancakeswap.svg'
 import ICON_SUSHISWAP from '@cowprotocol/assets/cow-swap/icon-sushi.svg'
 import ICON_UNISWAP from '@cowprotocol/assets/cow-swap/icon-uni.svg'
 import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
-import { Media, ProductLogo, ProductVariant } from '@cowprotocol/ui'
+import { ProductLogo, ProductVariant, UI } from '@cowprotocol/ui'
 import { ClosableBanner } from '@cowprotocol/ui'
 
-import { X } from 'react-feather'
 import SVG from 'react-inlinesvg'
 import { Textfit } from 'react-textfit'
-import styled from 'styled-components/macro'
 
-import { cowAnalytics } from 'modules/analytics'
-
-// Add this enum at the top of the file, after imports
-enum CoWAMMColors {
-  DarkGreen = '#194d05',
-  Green = '#2b6f0b',
-  LightGreen = '#bcec79',
-  LighterGreen = '#dcf8a7',
-  Blue = '#3fc4ff',
-  LightBlue = '#ccf8ff',
-}
-
-// Add this enum after the CoWAMMColors enum
-enum LpToken {
-  UniswapV2 = 'UniswapV2',
-  Sushiswap = 'Sushiswap',
-  PancakeSwap = 'PancakeSwap',
-  Curve = 'Curve',
-}
-
-const BannerWrapper = styled.div`
-  position: fixed;
-  top: 76px;
-  right: 10px;
-  z-index: 3;
-  width: 485px;
-  height: auto;
-  border-radius: 24px;
-  background-color: ${CoWAMMColors.DarkGreen};
-  color: ${CoWAMMColors.DarkGreen};
-  padding: 20px;
-  gap: 20px;
-  display: flex;
-  flex-flow: column wrap;
-  align-items: center;
-  justify-content: center;
-  overflow: hidden;
-
-  ${Media.upToSmall()} {
-    width: 100%;
-    height: auto;
-    left: 0;
-    right: 0;
-    margin: 0 auto;
-    bottom: 57px;
-    top: initial;
-    border-bottom-left-radius: 0;
-    border-bottom-right-radius: 0;
-    box-shadow: 0 0 0 100vh rgb(0 0 0 / 40%);
-    z-index: 10;
-  }
-`
-
-const CloseButton = styled(X)`
-  position: absolute;
-  top: 16px;
-  right: 16px;
-  cursor: pointer;
-  color: ${CoWAMMColors.LightGreen};
-  opacity: 0.6;
-  transition: opacity 0.2s ease-in-out;
-
-  &:hover {
-    opacity: 1;
-  }
-`
-
-const Title = styled.h2`
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  font-size: 18px;
-  font-weight: bold;
-  margin: 0 auto 0 0;
-  color: ${CoWAMMColors.LightGreen};
-
-  ${Media.upToSmall()} {
-    font-size: 26px;
-  }
-`
-
-const Card = styled.div<{ bgColor?: string; color?: string; height?: string }>`
-  --default-height: 150px;
-  display: flex;
-  flex-flow: row nowrap;
-  gap: 24px;
-  align-items: center;
-  justify-content: center;
-  font-size: 30px;
-  line-height: 1.2;
-  font-weight: 500;
-  margin: 0;
-  width: 100%;
-  max-width: 100%;
-  height: ${({ height }) => height || 'var(--default-height)'};
-  max-height: ${({ height }) => height || 'var(--default-height)'};
-  border-radius: 16px;
-  padding: 24px;
-  background: ${({ bgColor }) => bgColor || 'transparent'};
-  color: ${({ color }) => color || 'inherit'};
-  position: relative;
-  > h3,
-  > p {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    margin: 0;
-    width: 100%;
-    height: 100%;
-    max-height: 100%;
-
-    > div {
-      width: 100%;
-      height: 100%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-  }
-
-  > h3 {
-    font-weight: bold;
-    letter-spacing: -2px;
-  }
-
-  > p {
-    font-weight: inherit;
-  }
-
-  > p b {
-    font-weight: 900;
-    color: ${CoWAMMColors.LighterGreen};
-  }
-`
-
-const CTAButton = styled.button`
-  --size: 58px;
-  background: ${CoWAMMColors.LightGreen};
-  color: ${CoWAMMColors.DarkGreen};
-  border: none;
-  border-radius: var(--size);
-  min-height: var(--size);
-  padding: 12px 24px;
-  font-size: 24px;
-  font-weight: bold;
-  cursor: pointer;
-  width: 100%;
-  max-width: 100%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  gap: 8px;
-  transition: background 0.2s ease-in-out;
-
-  &:hover {
-    background: ${CoWAMMColors.LighterGreen};
-  }
-`
-
-const SecondaryLink = styled.a`
-  color: ${CoWAMMColors.LightGreen};
-  font-size: 14px;
-  font-weight: 500;
-  text-decoration: none;
-
-  &:hover {
-    text-decoration: underline;
-  }
-`
-
-const DEMO_DROPDOWN = styled.select`
-  position: fixed;
-  bottom: 150px;
-  right: 10px;
-  z-index: 999999999;
-  padding: 5px;
-  font-size: 16px;
-`
+import { upToSmall, useMediaQuery } from 'legacy/hooks/useMediaQuery'
 
-const StarIcon = styled.div<{ size?: number; top?: number; left?: number; right?: number; bottom?: number }>`
-  width: ${({ size }) => size || 16}px;
-  height: ${({ size }) => size || 16}px;
-  position: absolute;
-  top: ${({ top }) => top ?? 'initial'}px;
-  left: ${({ left }) => left ?? 'initial'}px;
-  right: ${({ right }) => right ?? 'initial'}px;
-  bottom: ${({ bottom }) => bottom ?? 'initial'}px;
-`
-
-const LpEmblems = styled.div<{ totalItems: number }>`
-  display: flex;
-  gap: 8px;
-  width: 100%;
-  justify-content: center;
-  align-items: center;
-`
-
-const LpEmblemItemsWrapper = styled.div<{ totalItems: number }>`
-  display: ${({ totalItems }) => (totalItems > 2 ? 'grid' : 'flex')};
-  gap: ${({ totalItems }) => (totalItems > 2 ? '0' : '8px')};
-  width: 100%;
-  justify-content: center;
-  align-items: center;
-
-  ${({ totalItems }) =>
-    totalItems === 3 &&
-    `
-    grid-template-columns: 1fr 1fr;
-    grid-template-rows: 1fr 1fr;
-    justify-items: center;
-
-    > :first-child {
-      grid-column: 1 / -1;
-    }
-  `}
-
-  ${({ totalItems }) =>
-    totalItems === 4 &&
-    `
-    grid-template-columns: 1fr 1fr;
-    grid-template-rows: 1fr 1fr;
-  `}
-`
-
-const LpEmblemItem = styled.div<{
-  totalItems: number
-  index: number
-}>`
-  --size: ${({ totalItems }) =>
-    totalItems === 4 ? '50px' : totalItems === 3 ? '65px' : totalItems === 2 ? '80px' : '104px'};
-  width: var(--size);
-  height: var(--size);
-  padding: ${({ totalItems }) => (totalItems === 4 ? '10px' : totalItems >= 2 ? '15px' : '20px')};
-  border-radius: 50%;
-  background: ${CoWAMMColors.DarkGreen};
-  color: ${CoWAMMColors.LightGreen};
-  border: ${({ totalItems }) =>
-    totalItems > 2 ? `2px solid ${CoWAMMColors.Green}` : `4px solid ${CoWAMMColors.Green}`};
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  position: relative;
-
-  > svg {
-    width: 100%;
-    height: 100%;
-  }
-
-  ${({ totalItems, index }) => {
-    const styleMap: Record<number, Record<number, string>> = {
-      2: {
-        0: 'margin-right: -42px;',
-      },
-      3: {
-        0: 'margin-bottom: -20px; z-index: 10;',
-        1: 'margin-top: -20px;',
-        2: 'margin-top: -20px;',
-      },
-      4: {
-        0: 'margin-bottom: -5px; z-index: 10; margin-right: -10px;',
-        1: 'margin-bottom: -5px; z-index: 10;',
-        2: 'margin-top: -5px; margin-right: -10px;',
-        3: 'margin-top: -5px;',
-      },
-    }
-
-    return styleMap[totalItems]?.[index] || ''
-  }}
-`
-
-const CoWAMMEmblemItem = styled.div`
-  --size: 104px;
-  width: var(--size);
-  height: var(--size);
-  border-radius: var(--size);
-  padding: 30px 30px 23px 30px;
-  background: ${CoWAMMColors.LightGreen};
-  color: ${CoWAMMColors.DarkGreen};
-  border: 4px solid ${CoWAMMColors.Green};
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`
+import { cowAnalytics } from 'modules/analytics'
 
-const EmblemArrow = styled.div`
-  --size: 32px;
-  width: var(--size);
-  height: var(--size);
-  min-width: var(--size);
-  border-radius: var(--size);
-  background: ${CoWAMMColors.DarkGreen};
-  border: 3px solid ${CoWAMMColors.Green};
-  margin: 0 -24px;
-  padding: 6px;
-  z-index: 10;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  color: ${CoWAMMColors.LightGreen};
+import { LpToken, dummyData, lpTokenConfig, StateKey } from './dummyData'
+import * as styledEl from './styled'
 
-  > svg > path {
-    fill: ${CoWAMMColors.LightGreen};
-  }
-`
-// Update the dummyData object to include all possible states
-const dummyData = {
-  noLp: { apr: 1.5, comparison: 'UNI-V2' },
-  uniV2: { apr: 2.1, comparison: 'UNI-V2' },
-  sushi: { apr: 1.8, comparison: 'SushiSwap' },
-  curve: { apr: 1.3, comparison: 'Curve' },
-  pancake: { apr: 2.5, comparison: 'PancakeSwap' },
-  twoLps: { apr: 2.0, comparison: 'UNI-V2 and SushiSwap' },
-  threeLps: { apr: 2.2, comparison: 'UNI-V2, SushiSwap, and Curve' },
-  fourLps: { apr: 2.4, comparison: 'UNI-V2, Sushiswap, Curve, and Balancer' },
-} as const
+const ANALYTICS_URL = 'https://cow.fi/pools?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner'
+const BANNER_ID = 'cow_amm_banner_2024_va'
 
-type StateKey = keyof typeof dummyData
-
-// Update the lpTokenConfig mapping to match dummyData keys
-const lpTokenConfig: Record<StateKey, LpToken[]> = {
-  noLp: [LpToken.UniswapV2],
-  uniV2: [LpToken.UniswapV2],
-  sushi: [LpToken.Sushiswap],
-  curve: [LpToken.Curve],
-  pancake: [LpToken.PancakeSwap],
-  twoLps: [LpToken.UniswapV2, LpToken.Sushiswap],
-  threeLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve],
-  fourLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve, LpToken.Curve],
-}
+const DEMO_DROPDOWN_OPTIONS = [
+  { value: 'noLp', label: 'No LP tokens' },
+  { value: 'uniV2', label: 'UNI-V2 LP' },
+  { value: 'sushi', label: 'SushiSwap LP' },
+  { value: 'curve', label: 'Curve LP' },
+  { value: 'pancake', label: 'PancakeSwap LP' },
+  { value: 'twoLps', label: '2 LP tokens' },
+  { value: 'threeLps', label: '3 LP tokens' },
+  { value: 'fourLps', label: '4 LP tokens' },
+]
 
 const lpTokenIcons: Record<LpToken, string> = {
   [LpToken.UniswapV2]: ICON_UNISWAP,
@@ -353,32 +42,30 @@ const lpTokenIcons: Record<LpToken, string> = {
 
 export function CoWAmmBanner() {
   const [selectedState, setSelectedState] = useState<StateKey>('noLp')
+  const isMobile = useMediaQuery(upToSmall)
 
-  const handleCTAClick = () => {
+  const handleCTAClick = useCallback(() => {
     cowAnalytics.sendEvent({
       category: 'CoW Swap',
-      action: 'CoW AMM Banner CTA Clicked',
+      action: 'CoW AMM Banner [Global] CTA Clicked',
     })
 
-    window.open(
-      'https://balancer.fi/pools/cow?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner',
-      '_blank',
-    )
-  }
+    window.open(ANALYTICS_URL, '_blank')
+  }, [])
 
-  const handleClose = () => {
+  const handleClose = useCallback(() => {
     cowAnalytics.sendEvent({
       category: 'CoW Swap',
-      action: 'CoW AMM Banner Closed',
+      action: 'CoW AMM Banner [Global] Closed',
     })
-  }
+  }, [])
 
-  const getAprMessage = () => {
+  const aprMessage = useMemo(() => {
     const { apr } = dummyData[selectedState]
     return `+${apr.toFixed(1)}%`
-  }
+  }, [selectedState])
 
-  const getComparisonMessage = () => {
+  const comparisonMessage = useMemo(() => {
     const { comparison } = dummyData[selectedState]
     if (selectedState === 'noLp') {
       return `yield over the average UNI-V2 pool`
@@ -387,9 +74,9 @@ export function CoWAmmBanner() {
       return `Get higher average APR than ${comparison}`
     }
     return `Get higher APR than ${comparison}`
-  }
+  }, [selectedState, dummyData])
 
-  const renderLpEmblems = () => {
+  const lpEmblems = useMemo(() => {
     const tokens = lpTokenConfig[selectedState]
     const totalItems = tokens.length
 
@@ -398,84 +85,87 @@ export function CoWAmmBanner() {
     }
 
     return (
-      <LpEmblems totalItems={totalItems}>
-        <LpEmblemItemsWrapper totalItems={totalItems}>
+      <styledEl.LpEmblems>
+        <styledEl.LpEmblemItemsWrapper totalItems={totalItems}>
           {tokens.map((token, index) => (
-            <LpEmblemItem key={token} totalItems={totalItems} index={index}>
+            <styledEl.LpEmblemItem key={token} totalItems={totalItems} index={index}>
               <SVG src={lpTokenIcons[token]} />
-            </LpEmblemItem>
+            </styledEl.LpEmblemItem>
           ))}
-        </LpEmblemItemsWrapper>
-        <EmblemArrow>
+        </styledEl.LpEmblemItemsWrapper>
+        <styledEl.EmblemArrow>
           <SVG src={ICON_ARROW} />
-        </EmblemArrow>
-        <CoWAMMEmblemItem>
+        </styledEl.EmblemArrow>
+        <styledEl.CoWAMMEmblemItem>
           <ProductLogo
             height={'100%'}
-            overrideColor={CoWAMMColors.DarkGreen}
+            overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
             variant={ProductVariant.CowAmm}
             logoIconOnly
           />
-        </CoWAMMEmblemItem>
-      </LpEmblems>
+        </styledEl.CoWAMMEmblemItem>
+      </styledEl.LpEmblems>
     )
-  }
-
-  return ClosableBanner('cow_amm_banner_2024_va', (close) => (
-    <BannerWrapper>
-      <CloseButton
-        size={24}
-        onClick={() => {
-          handleClose()
-          close()
-        }}
-      />
-
-      <DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
-        <option value="noLp">No LP tokens</option>
-        <option value="uniV2">UNI-V2 LP</option>
-        <option value="sushi">SushiSwap LP</option>
-        <option value="curve">Curve LP</option>
-        <option value="pancake">PancakeSwap LP</option>
-        <option value="twoLps">2 LP tokens</option>
-        <option value="threeLps">3 LP tokens</option>
-        <option value="fourLps">4 LP tokens</option>
-      </DEMO_DROPDOWN>
-
-      <Title>
-        <ProductLogo height={20} overrideColor={CoWAMMColors.DarkGreen} variant={ProductVariant.CowAmm} logoIconOnly />
+  }, [selectedState])
+
+  const handleBannerClose = (close: () => void) => () => {
+    handleClose()
+    close()
+  }
+
+  return ClosableBanner(BANNER_ID, (close) => (
+    <styledEl.BannerWrapper>
+      <styledEl.CloseButton size={24} onClick={handleBannerClose(close)} />
+
+      <styledEl.DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
+        {DEMO_DROPDOWN_OPTIONS.map((option) => (
+          <option key={option.value} value={option.value}>
+            {option.label}
+          </option>
+        ))}
+      </styledEl.DEMO_DROPDOWN>
+
+      <styledEl.Title>
+        <ProductLogo
+          height={20}
+          overrideColor={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}
+          variant={ProductVariant.CowAmm}
+          logoIconOnly
+        />
         <span>CoW AMM</span>
-      </Title>
-      <Card bgColor={CoWAMMColors.Blue}>
-        <StarIcon size={36} top={-17} right={80}>
+      </styledEl.Title>
+      <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_BLUE})`}>
+        <styledEl.StarIcon size={36} top={-17} right={80}>
           <SVG src={ICON_STAR} />
-        </StarIcon>
+        </styledEl.StarIcon>
         <h3>
-          <Textfit mode="single" forceSingleModeWidth={false} min={21} max={80} key={getAprMessage()}>
-            {getAprMessage()}
+          <Textfit mode="single" forceSingleModeWidth={false} min={80} max={80} key={aprMessage}>
+            {aprMessage}
           </Textfit>
         </h3>
         <p>
-          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28} key={getComparisonMessage()}>
-            {getComparisonMessage()}
+          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28} key={comparisonMessage}>
+            {comparisonMessage}
           </Textfit>
         </p>
-        <StarIcon size={26} bottom={-10} right={20}>
+        <styledEl.StarIcon size={26} bottom={-10} right={20}>
           <SVG src={ICON_STAR} />
-        </StarIcon>
-      </Card>
-
-      <Card bgColor={CoWAMMColors.Green} color={CoWAMMColors.LightGreen}>
-        <p>
-          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={30}>
-            One-click convert, <b>boost yield</b>
-          </Textfit>
-        </p>
-        {renderLpEmblems()}
-      </Card>
-
-      <CTAButton onClick={handleCTAClick}>Booooost APR gas-free!</CTAButton>
-      <SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</SecondaryLink>
-    </BannerWrapper>
+        </styledEl.StarIcon>
+      </styledEl.Card>
+
+      {!isMobile && (
+        <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_GREEN})`} color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}>
+          <p>
+            <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={30}>
+              One-click convert, <b>boost yield</b>
+            </Textfit>
+          </p>
+          {lpEmblems}
+        </styledEl.Card>
+      )}
+
+      <styledEl.CTAButton onClick={handleCTAClick}>Booooost APR gas-free!</styledEl.CTAButton>
+      <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
+    </styledEl.BannerWrapper>
   ))
 }
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
new file mode 100644
index 0000000000..44c54083fd
--- /dev/null
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
@@ -0,0 +1,354 @@
+import { UI, Media } from '@cowprotocol/ui'
+
+import { X } from 'react-feather'
+import styled from 'styled-components/macro'
+
+export const BannerWrapper = styled.div`
+  position: fixed;
+  top: 76px;
+  right: 10px;
+  z-index: 3;
+  width: 485px;
+  height: auto;
+  border-radius: 24px;
+  background-color: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  color: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  padding: 20px;
+  display: flex;
+  flex-flow: column wrap;
+  align-items: center;
+  justify-content: center;
+  gap: 20px;
+  overflow: hidden;
+
+  ${Media.upToSmall()} {
+    width: 100%;
+    height: auto;
+    left: 0;
+    right: 0;
+    margin: 0 auto;
+    bottom: 57px;
+    top: initial;
+    border-radius: 24px 24px 0 0;
+    box-shadow: 0 0 0 100vh rgb(0 0 0 / 40%);
+    z-index: 10;
+  }
+`
+
+export const CloseButton = styled(X)<{ color?: string; top?: number }>`
+  position: absolute;
+  top: ${({ top = 16 }) => top}px;
+  right: 16px;
+  cursor: pointer;
+  color: ${({ color }) => color || `var(${UI.COLOR_COWAMM_LIGHT_GREEN})`};
+  opacity: 0.6;
+  transition: opacity 0.2s ease-in-out;
+
+  &:hover {
+    opacity: 1;
+  }
+`
+
+export const Title = styled.h2<{ color?: string }>`
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-size: 18px;
+  font-weight: bold;
+  margin: 0 auto 0 0;
+  color: ${({ color }) => color || `var(${UI.COLOR_COWAMM_LIGHT_GREEN})`};
+
+  ${Media.upToSmall()} {
+    font-size: 26px;
+  }
+`
+
+export const Card = styled.div<{
+  bgColor?: string
+  color?: string
+  height?: string
+  borderColor?: string
+  borderWidth?: number
+  padding?: string
+  gap?: string
+}>`
+  --default-height: 150px;
+  display: flex;
+  flex-flow: row nowrap;
+  align-items: center;
+  justify-content: center;
+  gap: ${({ gap }) => gap || '24px'};
+  font-size: 30px;
+  line-height: 1.2;
+  font-weight: 500;
+  margin: 0;
+  width: 100%;
+  max-width: 100%;
+  height: ${({ height }) => height || 'var(--default-height)'};
+  max-height: ${({ height }) => height || 'var(--default-height)'};
+  border-radius: 16px;
+  padding: ${({ padding }) => padding || '24px'};
+  background: ${({ bgColor }) => bgColor || 'transparent'};
+  color: ${({ color }) => color || 'inherit'};
+  border: ${({ borderWidth, borderColor }) => borderWidth && borderColor && `${borderWidth}px solid ${borderColor}`};
+  position: relative;
+
+  > h3,
+  > p {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin: 0;
+    width: max-content;
+    height: 100%;
+    max-height: 100%;
+
+    > div {
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+
+  > h3 {
+    font-weight: bold;
+    letter-spacing: -2px;
+  }
+
+  > p {
+    font-weight: inherit;
+  }
+
+  > p b {
+    font-weight: 900;
+    color: var(${UI.COLOR_COWAMM_LIGHTER_GREEN});
+  }
+`
+
+export const CTAButton = styled.button<{
+  bgColor?: string
+  bgHoverColor?: string
+  color?: string
+  size?: number
+  fontSize?: number
+}>`
+  --size: ${({ size = 58 }) => size}px;
+  background: ${({ bgColor }) => bgColor || `var(${UI.COLOR_COWAMM_LIGHT_GREEN})`};
+  color: ${({ color }) => color || `var(${UI.COLOR_COWAMM_DARK_GREEN})`};
+  border: none;
+  border-radius: var(--size);
+  min-height: var(--size);
+  padding: 12px 24px;
+  font-size: ${({ fontSize = 24 }) => fontSize}px;
+  font-weight: bold;
+  cursor: pointer;
+  width: 100%;
+  max-width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 8px;
+  transition: background 0.2s ease-in-out;
+
+  @keyframes shake {
+    0% {
+      transform: translate(1px, 1px) rotate(0deg);
+    }
+    10% {
+      transform: translate(-1px, -2px) rotate(-1deg);
+    }
+    20% {
+      transform: translate(-3px, 0px) rotate(1deg);
+    }
+    30% {
+      transform: translate(3px, 2px) rotate(0deg);
+    }
+    40% {
+      transform: translate(1px, -1px) rotate(1deg);
+    }
+    50% {
+      transform: translate(-1px, 2px) rotate(-1deg);
+    }
+    60% {
+      transform: translate(-3px, 1px) rotate(0deg);
+    }
+    70% {
+      transform: translate(3px, 1px) rotate(-1deg);
+    }
+    80% {
+      transform: translate(-1px, -1px) rotate(1deg);
+    }
+    90% {
+      transform: translate(1px, 2px) rotate(0deg);
+    }
+    100% {
+      transform: translate(1px, -2px) rotate(-1deg);
+    }
+  }
+
+  &:hover {
+    background: ${({ bgHoverColor }) => bgHoverColor || `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`};
+    animation: shake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
+    transform: translate3d(0, 0, 0);
+    backface-visibility: hidden;
+    perspective: 1000px;
+  }
+`
+
+export const SecondaryLink = styled.a`
+  color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
+  font-size: 14px;
+  font-weight: 500;
+  text-decoration: none;
+
+  &:hover {
+    text-decoration: underline;
+  }
+`
+
+export const DEMO_DROPDOWN = styled.select`
+  position: fixed;
+  bottom: 150px;
+  right: 10px;
+  z-index: 999999999;
+  padding: 5px;
+  font-size: 16px;
+`
+
+export const StarIcon = styled.div<{
+  color?: string
+  size?: number
+  top?: number | 'initial'
+  left?: number | 'initial'
+  right?: number | 'initial'
+  bottom?: number | 'initial'
+}>`
+  width: ${({ size = 16 }) => size}px;
+  height: ${({ size = 16 }) => size}px;
+  position: absolute;
+  top: ${({ top }) => (top === 'initial' ? 'initial' : top != null ? `${top}px` : 'initial')};
+  left: ${({ left }) => (left === 'initial' ? 'initial' : left != null ? `${left}px` : 'initial')};
+  right: ${({ right }) => (right === 'initial' ? 'initial' : right != null ? `${right}px` : 'initial')};
+  bottom: ${({ bottom }) => (bottom === 'initial' ? 'initial' : bottom != null ? `${bottom}px` : 'initial')};
+  color: ${({ color }) => color ?? `var(${UI.COLOR_WHITE})`};
+
+  > svg > path {
+    fill: ${({ color }) => color ?? 'currentColor'};
+  }
+`
+
+export const LpEmblems = styled.div`
+  display: flex;
+  gap: 8px;
+  width: 100%;
+  justify-content: center;
+  align-items: center;
+`
+
+export const LpEmblemItemsWrapper = styled.div<{ totalItems: number }>`
+  display: ${({ totalItems }) => (totalItems > 2 ? 'grid' : 'flex')};
+  gap: ${({ totalItems }) => (totalItems > 2 ? '0' : '8px')};
+  width: 100%;
+  justify-content: center;
+  align-items: center;
+
+  ${({ totalItems }) =>
+    totalItems === 3 &&
+    `
+    grid-template: 1fr 1fr / 1fr 1fr;
+    justify-items: center;
+
+    > :first-child {
+      grid-column: 1 / -1;
+    }
+  `}
+
+  ${({ totalItems }) =>
+    totalItems === 4 &&
+    `
+    grid-template: 1fr 1fr / 1fr 1fr;
+  `}
+`
+
+export const LpEmblemItem = styled.div<{
+  totalItems: number
+  index: number
+}>`
+  --size: ${({ totalItems }) =>
+    totalItems === 4 ? '50px' : totalItems === 3 ? '65px' : totalItems === 2 ? '80px' : '104px'};
+  width: var(--size);
+  height: var(--size);
+  padding: ${({ totalItems }) => (totalItems === 4 ? '10px' : totalItems >= 2 ? '15px' : '20px')};
+  border-radius: 50%;
+  background: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
+  border: ${({ totalItems }) =>
+    totalItems > 2 ? `2px solid var(${UI.COLOR_COWAMM_GREEN})` : `4px solid var(${UI.COLOR_COWAMM_GREEN})`};
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+
+  > svg {
+    width: 100%;
+    height: 100%;
+  }
+
+  ${({ totalItems, index }) => {
+    const styleMap: Record<number, Record<number, string>> = {
+      2: {
+        0: 'margin-right: -42px;',
+      },
+      3: {
+        0: 'margin-bottom: -20px; z-index: 10;',
+        1: 'margin-top: -20px;',
+        2: 'margin-top: -20px;',
+      },
+      4: {
+        0: 'margin: -5px -10px -5px 0; z-index: 10;',
+        1: 'margin-bottom: -5px; z-index: 10;',
+        2: 'margin: -5px -10px 0 0;',
+        3: 'margin-top: -5px;',
+      },
+    }
+
+    return styleMap[totalItems]?.[index] || ''
+  }}
+`
+
+export const CoWAMMEmblemItem = styled.div`
+  --size: 104px;
+  width: var(--size);
+  height: var(--size);
+  border-radius: var(--size);
+  padding: 30px 30px 23px;
+  background: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
+  color: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  border: 4px solid var(${UI.COLOR_COWAMM_GREEN});
+  display: flex;
+  align-items: center;
+  justify-content: center;
+`
+
+export const EmblemArrow = styled.div`
+  --size: 32px;
+  width: var(--size);
+  height: var(--size);
+  min-width: var(--size);
+  border-radius: var(--size);
+  background: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  border: 3px solid var(${UI.COLOR_COWAMM_GREEN});
+  margin: 0 -24px;
+  padding: 6px;
+  z-index: 10;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
+
+  > svg > path {
+    fill: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
+  }
+`
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
new file mode 100644
index 0000000000..1002ee845c
--- /dev/null
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
@@ -0,0 +1,143 @@
+import { useState, useCallback, useMemo } from 'react'
+
+import styled from 'styled-components/macro'
+import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
+import { ProductLogo, ProductVariant, UI } from '@cowprotocol/ui'
+import { ClosableBanner } from '@cowprotocol/ui'
+
+import SVG from 'react-inlinesvg'
+import { Textfit } from 'react-textfit'
+
+import { upToSmall, useMediaQuery } from 'legacy/hooks/useMediaQuery'
+
+import { cowAnalytics } from 'modules/analytics'
+
+import { dummyData, StateKey } from './dummyData'
+import * as styledEl from './styled'
+
+export const Wrapper = styled.div`
+  z-index: 3;
+  width: 100%;
+  padding: 20px;
+  position: relative;
+`
+
+const WrapperInner = styled.div`
+  position: relative;
+  width: 100%;
+  height: auto;
+  border-radius: 24px;
+  background-color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
+  color: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  padding: 14px;
+  margin: 0 auto;
+  display: flex;
+  flex-flow: column wrap;
+  align-items: center;
+  justify-content: center;
+  gap: 14px;
+  overflow: hidden;
+`
+
+const ANALYTICS_URL = 'https://cow.fi/pools?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner'
+const BANNER_ID = 'cow_amm_banner_tokenselector_2024_va'
+
+export function CoWAmmTokenSelectorBanner() {
+  const [selectedState, setSelectedState] = useState<StateKey>('noLp')
+
+  const handleCTAClick = useCallback(() => {
+    cowAnalytics.sendEvent({
+      category: 'CoW Swap',
+      action: 'CoW AMM Banner [Token selector] CTA Clicked',
+    })
+
+    window.open(ANALYTICS_URL, '_blank')
+  }, [])
+
+  const handleClose = useCallback(() => {
+    cowAnalytics.sendEvent({
+      category: 'CoW Swap',
+      action: 'CoW AMM Banner [Token selector] Closed',
+    })
+  }, [])
+
+  const aprMessage = useMemo(() => {
+    const { apr } = dummyData[selectedState]
+    return `+${apr.toFixed(1)}%`
+  }, [selectedState])
+
+  const comparisonMessage = useMemo(() => {
+    const { comparison } = dummyData[selectedState]
+    if (selectedState === 'noLp') {
+      return `yield over the average UNI-V2 pool`
+    }
+    if (selectedState === 'twoLps' || selectedState === 'threeLps') {
+      return `Get higher average APR than ${comparison}`
+    }
+    return `Get higher APR than ${comparison}`
+  }, [selectedState, dummyData])
+
+  const handleBannerClose = (close: () => void) => () => {
+    handleClose()
+    close()
+  }
+
+  return ClosableBanner(BANNER_ID, (close) => (
+    <Wrapper>
+      <WrapperInner>
+        <styledEl.CloseButton
+          top={14}
+          size={24}
+          onClick={handleBannerClose(close)}
+          color={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+        />
+
+        <styledEl.Title color={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}>
+          <ProductLogo
+            height={20}
+            overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+            variant={ProductVariant.CowAmm}
+            logoIconOnly
+          />
+          <span>CoW AMM</span>
+        </styledEl.Title>
+        <styledEl.Card
+          bgColor={'transparent'}
+          borderColor={`var(${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30})`}
+          borderWidth={2}
+          padding={'14px'}
+          gap={'14px'}
+          height={'78px'}
+        >
+          <styledEl.StarIcon size={26} top={-16} right={80} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
+            <SVG src={ICON_STAR} />
+          </styledEl.StarIcon>
+          <h3>
+            <Textfit mode="single" forceSingleModeWidth={false} min={45} max={48} key={aprMessage}>
+              {aprMessage}
+            </Textfit>
+          </h3>
+          <p>
+            <Textfit mode="multi" forceSingleModeWidth={false} min={12} max={21} key={comparisonMessage}>
+              {comparisonMessage}
+            </Textfit>
+          </p>
+          <styledEl.StarIcon size={16} bottom={3} right={20} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
+            <SVG src={ICON_STAR} />
+          </styledEl.StarIcon>
+        </styledEl.Card>
+
+        <styledEl.CTAButton
+          onClick={handleCTAClick}
+          size={38}
+          fontSize={18}
+          bgColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+          bgHoverColor={`var(${UI.COLOR_COWAMM_GREEN})`}
+          color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}
+        >
+          Boooooost APR gas-free!
+        </styledEl.CTAButton>
+      </WrapperInner>
+    </Wrapper>
+  ))
+}
diff --git a/apps/cowswap-frontend/src/modules/tokensList/pure/SelectTokenModal/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/pure/SelectTokenModal/index.tsx
index 1dba5f772b..36b6ba37b2 100644
--- a/apps/cowswap-frontend/src/modules/tokensList/pure/SelectTokenModal/index.tsx
+++ b/apps/cowswap-frontend/src/modules/tokensList/pure/SelectTokenModal/index.tsx
@@ -88,7 +88,9 @@ export function SelectTokenModal(props: SelectTokenModalProps) {
           hideTooltip={hideFavoriteTokensTooltip}
         />
       </styledEl.Row>
+
       <styledEl.Separator />
+
       {inputValue.trim() ? (
         <TokenSearchResults searchInput={inputValue.trim()} {...selectTokenContext} />
       ) : (
diff --git a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
index 16e91c70a8..186d8545ed 100644
--- a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
+++ b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
@@ -5,6 +5,8 @@ import { TokenWithLogo } from '@cowprotocol/common-const'
 import { useVirtualizer } from '@tanstack/react-virtual'
 import ms from 'ms.macro'
 
+import { CoWAmmTokenSelectorBanner } from 'common/pure/CoWAMMBanner/tokenSelectorBanner'
+
 import * as styledEl from './styled'
 
 import { SelectTokenContext } from '../../types'
@@ -65,6 +67,8 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
 
   return (
     <CommonListContainer id="tokens-list" ref={parentRef} onScroll={onScroll}>
+      <CoWAmmTokenSelectorBanner />
+
       <styledEl.TokensInner ref={wrapperRef} style={{ height: virtualizer.getTotalSize() }}>
         <styledEl.TokensScroller style={{ transform: `translateY(${items[0]?.start ?? 0}px)` }}>
           {items.map((virtualRow) => {
diff --git a/libs/ui/src/enum.ts b/libs/ui/src/enum.ts
index 8a2986e83b..608ce17b35 100644
--- a/libs/ui/src/enum.ts
+++ b/libs/ui/src/enum.ts
@@ -60,6 +60,15 @@ export enum UI {
   COLOR_DANGER_BG = '--cow-color-danger-bg',
   COLOR_DANGER_TEXT = '--cow-color-danger-text',
 
+  // CoW AMM Colors
+  COLOR_COWAMM_DARK_GREEN = '--cow-color-cowamm-dark-green',
+  COLOR_COWAMM_DARK_GREEN_OPACITY_30 = '--cow-color-cowamm-dark-green-opacity-30',
+  COLOR_COWAMM_GREEN = '--cow-color-cowamm-green',
+  COLOR_COWAMM_LIGHT_GREEN = '--cow-color-cowamm-light-green',
+  COLOR_COWAMM_LIGHTER_GREEN = '--cow-color-cowamm-lighter-green',
+  COLOR_COWAMM_BLUE = '--cow-color-cowamm-blue',
+  COLOR_COWAMM_LIGHT_BLUE = '--cow-color-cowamm-light-blue',
+
   // ================================================================================
 
   // Badge
diff --git a/libs/ui/src/theme/ThemeColorVars.tsx b/libs/ui/src/theme/ThemeColorVars.tsx
index 6f2860c49a..55efc51732 100644
--- a/libs/ui/src/theme/ThemeColorVars.tsx
+++ b/libs/ui/src/theme/ThemeColorVars.tsx
@@ -97,8 +97,17 @@ export const ThemeColorVars = css`
     ${UI.COLOR_GREEN}: ${({ theme }) => theme.success};
     ${UI.COLOR_RED}: ${({ theme }) => theme.danger};
 
+    // CoW AMM Colors
+    ${UI.COLOR_COWAMM_DARK_GREEN}: #194d05;
+    ${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30}: ${() => transparentize('#194d05', 0.7)};
+    ${UI.COLOR_COWAMM_GREEN}: #2b6f0b;
+    ${UI.COLOR_COWAMM_LIGHT_GREEN}: #bcec79;
+    ${UI.COLOR_COWAMM_LIGHTER_GREEN}: #dcf8a7;
+    ${UI.COLOR_COWAMM_BLUE}: #3fc4ff;
+    ${UI.COLOR_COWAMM_LIGHT_BLUE}: #ccf8ff;
+
     // Base
-    ${UI.COLOR_CONTAINER_BG_02}: ${UI.COLOR_PAPER};
+    ${UI.COLOR_CONTAINER_BG_02}: var(${UI.COLOR_PAPER});
     ${UI.MODAL_BACKDROP}: var(${UI.COLOR_TEXT});
     ${UI.BORDER_RADIUS_NORMAL}: 24px;
     ${UI.PADDING_NORMAL}: 24px;
@@ -115,7 +124,7 @@ export const ThemeColorVars = css`
     ${UI.COLOR_TEXT_OPACITY_25}: ${({ theme }) => transparentize(theme.text, 0.75)};
     ${UI.COLOR_TEXT_OPACITY_10}: ${({ theme }) => transparentize(theme.text, 0.9)};
     ${UI.COLOR_TEXT2}: ${({ theme }) => transparentize(theme.text, 0.3)};
-    ${UI.COLOR_LINK}: ${`var(${UI.COLOR_PRIMARY})`};
+    ${UI.COLOR_LINK}: var(${UI.COLOR_PRIMARY});
     ${UI.COLOR_LINK_OPACITY_10}: ${({ theme }) => transparentize(theme.info, 0.9)};
 
     // Font Weights & Sizes

From 7f10daaf29059b7ef688d0622481c77c9f0f1291 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Fri, 11 Oct 2024 15:42:27 +0100
Subject: [PATCH 04/15] feat: add shared atom state

---
 .../src/common/pure/CoWAMMBanner/cowAmmBannerState.ts      | 5 +++++
 .../src/common/pure/CoWAMMBanner/index.tsx                 | 7 +++++--
 .../src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx   | 7 +++++--
 3 files changed, 15 insertions(+), 4 deletions(-)
 create mode 100644 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/cowAmmBannerState.ts

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/cowAmmBannerState.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/cowAmmBannerState.ts
new file mode 100644
index 0000000000..bc0c9b3054
--- /dev/null
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/cowAmmBannerState.ts
@@ -0,0 +1,5 @@
+import { atom } from 'jotai'
+
+import { StateKey } from './dummyData'
+
+export const cowAmmBannerStateAtom = atom<StateKey>('noLp')
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index d0164987f6..1fce3ee502 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -1,4 +1,7 @@
-import { useState, useCallback, useMemo } from 'react'
+import { useAtom } from 'jotai'
+import { cowAmmBannerStateAtom } from './cowAmmBannerState'
+
+import { useCallback, useMemo } from 'react'
 
 import ICON_ARROW from '@cowprotocol/assets/cow-swap/arrow.svg'
 import ICON_CURVE from '@cowprotocol/assets/cow-swap/icon-curve.svg'
@@ -41,7 +44,7 @@ const lpTokenIcons: Record<LpToken, string> = {
 }
 
 export function CoWAmmBanner() {
-  const [selectedState, setSelectedState] = useState<StateKey>('noLp')
+  const [selectedState, setSelectedState] = useAtom(cowAmmBannerStateAtom)
   const isMobile = useMediaQuery(upToSmall)
 
   const handleCTAClick = useCallback(() => {
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
index 1002ee845c..243e1eaa4e 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
@@ -1,4 +1,7 @@
-import { useState, useCallback, useMemo } from 'react'
+import { useAtomValue } from 'jotai'
+import { cowAmmBannerStateAtom } from './cowAmmBannerState'
+
+import { useCallback, useMemo } from 'react'
 
 import styled from 'styled-components/macro'
 import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
@@ -43,7 +46,7 @@ const ANALYTICS_URL = 'https://cow.fi/pools?utm_source=swap.cow.fi&utm_medium=we
 const BANNER_ID = 'cow_amm_banner_tokenselector_2024_va'
 
 export function CoWAmmTokenSelectorBanner() {
-  const [selectedState, setSelectedState] = useState<StateKey>('noLp')
+  const selectedState = useAtomValue(cowAmmBannerStateAtom)
 
   const handleCTAClick = useCallback(() => {
     cowAnalytics.sendEvent({

From f765bdd415c1789e35d4b01628103338b5854ea4 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Fri, 11 Oct 2024 18:05:09 +0100
Subject: [PATCH 05/15] feat: add animation and refactoring

---
 .../pure/CoWAMMBanner/arrowBackground.tsx     |  88 +++++++++++++++
 .../src/common/pure/CoWAMMBanner/index.tsx    |  30 ++++-
 .../src/common/pure/CoWAMMBanner/styled.ts    | 104 +++++++++++-------
 .../pure/CoWAMMBanner/tokenSelectorBanner.tsx |  25 ++++-
 4 files changed, 200 insertions(+), 47 deletions(-)
 create mode 100644 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx
new file mode 100644
index 0000000000..184afe0e7d
--- /dev/null
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx
@@ -0,0 +1,88 @@
+import React, { forwardRef, useMemo } from 'react'
+import { memo } from 'react'
+
+import { UI } from '@cowprotocol/ui'
+
+import styled from 'styled-components/macro'
+
+const ArrowBackgroundWrapper = styled.div`
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  pointer-events: none;
+  visibility: hidden;
+  opacity: 0;
+  transition: opacity 0.3s ease-in-out;
+`
+
+const MIN_FONT_SIZE = 18
+const MAX_FONT_SIZE = 42
+
+const Arrow = styled.div<{ delay: number; color: string; fontSize: number }>`
+  position: absolute;
+  font-size: ${({ fontSize }) => fontSize}px;
+  color: ${({ color }) => color};
+  animation: float 2s infinite linear;
+  animation-delay: ${({ delay }) => delay}s;
+
+  @keyframes float {
+    0% {
+      transform: translateY(100%);
+      opacity: 0;
+    }
+    10% {
+      opacity: 0.3;
+    }
+    50% {
+      opacity: 0.3;
+    }
+    90% {
+      opacity: 0.2;
+    }
+    100% {
+      transform: translateY(-100%);
+      opacity: 0;
+    }
+  }
+`
+
+export interface ArrowBackgroundProps {
+  count?: number
+  color?: string
+}
+
+export const ArrowBackground = memo(
+  forwardRef<HTMLDivElement, ArrowBackgroundProps>(
+    ({ count = 36, color = `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` }, ref) => {
+      const arrows = useMemo(() => {
+        return Array.from({ length: count }, (_, index) => ({
+          delay: (index / count) * 4,
+          left: `${Math.random() * 100}%`,
+          top: `${Math.random() * 100}%`,
+          fontSize: Math.floor(Math.random() * (MAX_FONT_SIZE - MIN_FONT_SIZE + 1)) + MIN_FONT_SIZE,
+        }))
+      }, [count])
+
+      return (
+        <ArrowBackgroundWrapper ref={ref}>
+          {arrows.map((arrow, index) => (
+            <Arrow
+              key={index}
+              delay={arrow.delay}
+              color={color}
+              fontSize={arrow.fontSize}
+              style={{
+                left: arrow.left,
+                top: arrow.top,
+              }}
+            >
+              ↑
+            </Arrow>
+          ))}
+        </ArrowBackgroundWrapper>
+      )
+    },
+  ),
+)
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index 1fce3ee502..f2e7853715 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -1,7 +1,7 @@
 import { useAtom } from 'jotai'
 import { cowAmmBannerStateAtom } from './cowAmmBannerState'
 
-import { useCallback, useMemo } from 'react'
+import { useCallback, useMemo, useRef } from 'react'
 
 import ICON_ARROW from '@cowprotocol/assets/cow-swap/arrow.svg'
 import ICON_CURVE from '@cowprotocol/assets/cow-swap/icon-curve.svg'
@@ -12,6 +12,8 @@ import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
 import { ProductLogo, ProductVariant, UI } from '@cowprotocol/ui'
 import { ClosableBanner } from '@cowprotocol/ui'
 
+import { ArrowBackground } from './arrowBackground'
+
 import SVG from 'react-inlinesvg'
 import { Textfit } from 'react-textfit'
 
@@ -46,6 +48,7 @@ const lpTokenIcons: Record<LpToken, string> = {
 export function CoWAmmBanner() {
   const [selectedState, setSelectedState] = useAtom(cowAmmBannerStateAtom)
   const isMobile = useMediaQuery(upToSmall)
+  const arrowBackgroundRef = useRef<HTMLDivElement>(null)
 
   const handleCTAClick = useCallback(() => {
     cowAnalytics.sendEvent({
@@ -63,6 +66,20 @@ export function CoWAmmBanner() {
     })
   }, [])
 
+  const handleCTAMouseEnter = useCallback(() => {
+    if (arrowBackgroundRef.current) {
+      arrowBackgroundRef.current.style.visibility = 'visible'
+      arrowBackgroundRef.current.style.opacity = '1'
+    }
+  }, [])
+
+  const handleCTAMouseLeave = useCallback(() => {
+    if (arrowBackgroundRef.current) {
+      arrowBackgroundRef.current.style.visibility = 'hidden'
+      arrowBackgroundRef.current.style.opacity = '0'
+    }
+  }, [])
+
   const aprMessage = useMemo(() => {
     const { apr } = dummyData[selectedState]
     return `+${apr.toFixed(1)}%`
@@ -167,7 +184,16 @@ export function CoWAmmBanner() {
         </styledEl.Card>
       )}
 
-      <styledEl.CTAButton onClick={handleCTAClick}>Booooost APR gas-free!</styledEl.CTAButton>
+      <styledEl.CTAButton
+        onClick={handleCTAClick}
+        onMouseEnter={handleCTAMouseEnter}
+        onMouseLeave={handleCTAMouseLeave}
+      >
+        Booooost APR gas-free!
+      </styledEl.CTAButton>
+
+      <ArrowBackground ref={arrowBackgroundRef} />
+
       <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
     </styledEl.BannerWrapper>
   ))
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
index 44c54083fd..be0d1f8be3 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
@@ -1,7 +1,21 @@
 import { UI, Media } from '@cowprotocol/ui'
 
 import { X } from 'react-feather'
-import styled from 'styled-components/macro'
+import styled, { keyframes } from 'styled-components/macro'
+
+const arrowUpAnimation = keyframes`
+  0% {
+    transform: translateY(100%);
+    opacity: 0;
+  }
+  50% {
+    opacity: 1;
+  }
+  100% {
+    transform: translateY(-100%);
+    opacity: 0;
+  }
+`
 
 export const BannerWrapper = styled.div`
   position: fixed;
@@ -20,6 +34,8 @@ export const BannerWrapper = styled.div`
   justify-content: center;
   gap: 20px;
   overflow: hidden;
+  overflow: hidden;
+  transition: transform 0.2s ease;
 
   ${Media.upToSmall()} {
     width: 100%;
@@ -150,50 +166,30 @@ export const CTAButton = styled.button<{
   align-items: center;
   justify-content: center;
   gap: 8px;
-  transition: background 0.2s ease-in-out;
+  position: relative;
+  overflow: hidden;
+  z-index: 1;
 
-  @keyframes shake {
-    0% {
-      transform: translate(1px, 1px) rotate(0deg);
-    }
-    10% {
-      transform: translate(-1px, -2px) rotate(-1deg);
-    }
-    20% {
-      transform: translate(-3px, 0px) rotate(1deg);
-    }
-    30% {
-      transform: translate(3px, 2px) rotate(0deg);
-    }
-    40% {
-      transform: translate(1px, -1px) rotate(1deg);
-    }
-    50% {
-      transform: translate(-1px, 2px) rotate(-1deg);
-    }
-    60% {
-      transform: translate(-3px, 1px) rotate(0deg);
-    }
-    70% {
-      transform: translate(3px, 1px) rotate(-1deg);
-    }
-    80% {
-      transform: translate(-1px, -1px) rotate(1deg);
-    }
-    90% {
-      transform: translate(1px, 2px) rotate(0deg);
-    }
-    100% {
-      transform: translate(1px, -2px) rotate(-1deg);
-    }
+  &::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: ${({ bgHoverColor }) => bgHoverColor || `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`};
+    z-index: -1;
+    transform: scaleX(0);
+    transform-origin: left;
+    transition: transform 2s ease-out;
   }
 
-  &:hover {
-    background: ${({ bgHoverColor }) => bgHoverColor || `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`};
-    animation: shake 0.5s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
-    transform: translate3d(0, 0, 0);
-    backface-visibility: hidden;
-    perspective: 1000px;
+  &:hover::before {
+    transform: scaleX(1);
+  }
+
+  > * {
+    z-index: 2;
   }
 `
 
@@ -352,3 +348,27 @@ export const EmblemArrow = styled.div`
     fill: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
   }
 `
+
+export const ArrowBackground = styled.div`
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  pointer-events: none;
+  height: 100%;
+  width: 100%;
+  visibility: hidden;
+  opacity: 0;
+  transition: opacity 0.2s ease-in-out;
+`
+
+export const Arrow = styled.span<{ delay: number }>`
+  position: absolute;
+  font-size: 28px;
+  color: rgba(255, 255, 255, 0.3);
+  animation: ${arrowUpAnimation} 1s linear infinite;
+  animation-delay: ${({ delay }) => delay}s;
+  left: ${() => Math.random() * 100}%;
+  font-weight: 500;
+`
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
index 243e1eaa4e..3cf6a04c27 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
@@ -1,7 +1,7 @@
 import { useAtomValue } from 'jotai'
 import { cowAmmBannerStateAtom } from './cowAmmBannerState'
 
-import { useCallback, useMemo } from 'react'
+import { useCallback, useMemo, useRef } from 'react'
 
 import styled from 'styled-components/macro'
 import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
@@ -11,13 +11,13 @@ import { ClosableBanner } from '@cowprotocol/ui'
 import SVG from 'react-inlinesvg'
 import { Textfit } from 'react-textfit'
 
-import { upToSmall, useMediaQuery } from 'legacy/hooks/useMediaQuery'
-
 import { cowAnalytics } from 'modules/analytics'
 
 import { dummyData, StateKey } from './dummyData'
 import * as styledEl from './styled'
 
+import { ArrowBackground } from './arrowBackground'
+
 export const Wrapper = styled.div`
   z-index: 3;
   width: 100%;
@@ -47,6 +47,7 @@ const BANNER_ID = 'cow_amm_banner_tokenselector_2024_va'
 
 export function CoWAmmTokenSelectorBanner() {
   const selectedState = useAtomValue(cowAmmBannerStateAtom)
+  const arrowBackgroundRef = useRef<HTMLDivElement>(null)
 
   const handleCTAClick = useCallback(() => {
     cowAnalytics.sendEvent({
@@ -64,6 +65,20 @@ export function CoWAmmTokenSelectorBanner() {
     })
   }, [])
 
+  const handleCTAMouseEnter = useCallback(() => {
+    if (arrowBackgroundRef.current) {
+      arrowBackgroundRef.current.style.visibility = 'visible'
+      arrowBackgroundRef.current.style.opacity = '1'
+    }
+  }, [])
+
+  const handleCTAMouseLeave = useCallback(() => {
+    if (arrowBackgroundRef.current) {
+      arrowBackgroundRef.current.style.visibility = 'hidden'
+      arrowBackgroundRef.current.style.opacity = '0'
+    }
+  }, [])
+
   const aprMessage = useMemo(() => {
     const { apr } = dummyData[selectedState]
     return `+${apr.toFixed(1)}%`
@@ -132,6 +147,8 @@ export function CoWAmmTokenSelectorBanner() {
 
         <styledEl.CTAButton
           onClick={handleCTAClick}
+          onMouseEnter={handleCTAMouseEnter}
+          onMouseLeave={handleCTAMouseLeave}
           size={38}
           fontSize={18}
           bgColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
@@ -140,6 +157,8 @@ export function CoWAmmTokenSelectorBanner() {
         >
           Boooooost APR gas-free!
         </styledEl.CTAButton>
+
+        <ArrowBackground ref={arrowBackgroundRef} count={14} color={`var(${UI.COLOR_COWAMM_GREEN})`} />
       </WrapperInner>
     </Wrapper>
   ))

From bdbcb238d348f83b25d1bce9c57a84abc7ec0ad4 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Mon, 14 Oct 2024 09:49:27 +0100
Subject: [PATCH 06/15] feat: consolidate banners into single component

---
 .../pure/CoWAMMBanner/CoWAmmBannerContent.tsx | 241 ++++++++++++++++++
 .../pure/CoWAMMBanner/arrowBackground.tsx     |   2 +-
 .../src/common/pure/CoWAMMBanner/index.tsx    | 184 ++-----------
 .../src/common/pure/CoWAMMBanner/styled.ts    |  24 ++
 .../pure/CoWAMMBanner/tokenSelectorBanner.tsx | 165 ------------
 .../pure/TokensVirtualList/index.tsx          |   4 +-
 6 files changed, 294 insertions(+), 326 deletions(-)
 create mode 100644 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
 delete mode 100644 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
new file mode 100644
index 0000000000..c2ce0fc717
--- /dev/null
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
@@ -0,0 +1,241 @@
+import { useCallback, useMemo, useRef } from 'react'
+
+import ICON_ARROW from '@cowprotocol/assets/cow-swap/arrow.svg'
+import ICON_CURVE from '@cowprotocol/assets/cow-swap/icon-curve.svg'
+import ICON_PANCAKESWAP from '@cowprotocol/assets/cow-swap/icon-pancakeswap.svg'
+import ICON_SUSHISWAP from '@cowprotocol/assets/cow-swap/icon-sushi.svg'
+import ICON_UNISWAP from '@cowprotocol/assets/cow-swap/icon-uni.svg'
+import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
+import { ProductLogo, ProductVariant, UI } from '@cowprotocol/ui'
+
+import SVG from 'react-inlinesvg'
+import { Textfit } from 'react-textfit'
+
+import { upToSmall, useMediaQuery } from 'legacy/hooks/useMediaQuery'
+
+import { ArrowBackground } from './arrowBackground'
+import { LpToken, StateKey } from './dummyData'
+import * as styledEl from './styled'
+
+import { DEMO_DROPDOWN_OPTIONS } from './index'
+
+const lpTokenIcons: Record<LpToken, string> = {
+  [LpToken.UniswapV2]: ICON_UNISWAP,
+  [LpToken.Sushiswap]: ICON_SUSHISWAP,
+  [LpToken.PancakeSwap]: ICON_PANCAKESWAP,
+  [LpToken.Curve]: ICON_CURVE,
+}
+
+interface CoWAmmBannerContentProps {
+  location: 'global' | 'tokenSelector'
+  selectedState: StateKey
+  setSelectedState: (state: StateKey) => void
+  dummyData: Record<StateKey, { apr: number; comparison: string }>
+  lpTokenConfig: Record<StateKey, LpToken[]>
+  handleCTAClick: () => void
+  handleBannerClose: () => void
+}
+
+export function CoWAmmBannerContent({
+  location,
+  selectedState,
+  setSelectedState,
+  dummyData,
+  lpTokenConfig,
+  handleCTAClick,
+  handleBannerClose,
+}: CoWAmmBannerContentProps) {
+  const isMobile = useMediaQuery(upToSmall)
+  const arrowBackgroundRef = useRef<HTMLDivElement>(null)
+
+  const handleCTAMouseEnter = useCallback(() => {
+    if (arrowBackgroundRef.current) {
+      arrowBackgroundRef.current.style.visibility = 'visible'
+      arrowBackgroundRef.current.style.opacity = '1'
+    }
+  }, [])
+
+  const handleCTAMouseLeave = useCallback(() => {
+    if (arrowBackgroundRef.current) {
+      arrowBackgroundRef.current.style.visibility = 'hidden'
+      arrowBackgroundRef.current.style.opacity = '0'
+    }
+  }, [])
+
+  const aprMessage = useMemo(() => {
+    const { apr } = dummyData[selectedState]
+    return `+${apr.toFixed(1)}%`
+  }, [selectedState, dummyData])
+
+  const comparisonMessage = useMemo(() => {
+    const { comparison } = dummyData[selectedState]
+    if (selectedState === 'noLp') {
+      return `yield over the average UNI-V2 pool`
+    }
+    if (selectedState === 'twoLps' || selectedState === 'threeLps') {
+      return `Get higher average APR than ${comparison}`
+    }
+    return `Get higher APR than ${comparison}`
+  }, [selectedState, dummyData])
+
+  const lpEmblems = useMemo(() => {
+    const tokens = lpTokenConfig[selectedState]
+    const totalItems = tokens.length
+
+    if (totalItems === 0) {
+      return null
+    }
+
+    return (
+      <styledEl.LpEmblems>
+        <styledEl.LpEmblemItemsWrapper totalItems={totalItems}>
+          {tokens.map((token, index) => (
+            <styledEl.LpEmblemItem key={token} totalItems={totalItems} index={index}>
+              <SVG src={lpTokenIcons[token]} />
+            </styledEl.LpEmblemItem>
+          ))}
+        </styledEl.LpEmblemItemsWrapper>
+        <styledEl.EmblemArrow>
+          <SVG src={ICON_ARROW} />
+        </styledEl.EmblemArrow>
+        <styledEl.CoWAMMEmblemItem>
+          <ProductLogo
+            height={'100%'}
+            overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+            variant={ProductVariant.CowAmm}
+            logoIconOnly
+          />
+        </styledEl.CoWAMMEmblemItem>
+      </styledEl.LpEmblems>
+    )
+  }, [selectedState, lpTokenConfig])
+
+  const isTokenSelector = (loc: typeof location): loc is 'tokenSelector' => loc === 'tokenSelector'
+
+  const renderBannerContent = () => {
+    if (isTokenSelector(location)) {
+      return (
+        <styledEl.TokenSelectorWrapper>
+          <styledEl.TokenSelectorWrapperInner>
+            <styledEl.Title>
+              <ProductLogo
+                height={20}
+                overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+                variant={ProductVariant.CowAmm}
+                logoIconOnly
+              />
+              <span>CoW AMM</span>
+            </styledEl.Title>
+            <styledEl.Card
+              bgColor={'transparent'}
+              borderColor={`var(${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30})`}
+              borderWidth={2}
+              padding={'14px'}
+              gap={'14px'}
+              height={'78px'}
+            >
+              <styledEl.StarIcon size={26} top={-16} right={80} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
+                <SVG src={ICON_STAR} />
+              </styledEl.StarIcon>
+              <h3>
+                <Textfit mode="single" forceSingleModeWidth={false} min={45} max={48} key={aprMessage}>
+                  {aprMessage}
+                </Textfit>
+              </h3>
+              <p>
+                <Textfit mode="multi" forceSingleModeWidth={false} min={12} max={21} key={comparisonMessage}>
+                  {comparisonMessage}
+                </Textfit>
+              </p>
+              <styledEl.StarIcon size={16} bottom={3} right={20} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
+                <SVG src={ICON_STAR} />
+              </styledEl.StarIcon>
+            </styledEl.Card>
+          </styledEl.TokenSelectorWrapperInner>
+        </styledEl.TokenSelectorWrapper>
+      )
+    }
+
+    return (
+      <>
+        <styledEl.Title>
+          <ProductLogo
+            height={20}
+            overrideColor={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}
+            variant={ProductVariant.CowAmm}
+            logoIconOnly
+          />
+          <span>CoW AMM</span>
+        </styledEl.Title>
+        <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_BLUE})`}>
+          <styledEl.StarIcon size={36} top={-17} right={80}>
+            <SVG src={ICON_STAR} />
+          </styledEl.StarIcon>
+          <h3>
+            <Textfit mode="single" forceSingleModeWidth={false} min={80} max={80} key={aprMessage}>
+              {aprMessage}
+            </Textfit>
+          </h3>
+          <p>
+            <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28} key={comparisonMessage}>
+              {comparisonMessage}
+            </Textfit>
+          </p>
+          <styledEl.StarIcon size={26} bottom={-10} right={20}>
+            <SVG src={ICON_STAR} />
+          </styledEl.StarIcon>
+        </styledEl.Card>
+
+        {!isMobile && (
+          <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_GREEN})`} color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}>
+            <p>
+              <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={30}>
+                One-click convert, <b>boost yield</b>
+              </Textfit>
+            </p>
+            {lpEmblems}
+          </styledEl.Card>
+        )}
+      </>
+    )
+  }
+
+  return (
+    <>
+      {isTokenSelector(location) ? (
+        renderBannerContent()
+      ) : (
+        <styledEl.BannerWrapper>
+          <styledEl.CloseButton size={24} onClick={handleBannerClose} />
+
+          <styledEl.DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
+            {DEMO_DROPDOWN_OPTIONS.map((option) => (
+              <option key={option.value} value={option.value}>
+                {option.label}
+              </option>
+            ))}
+          </styledEl.DEMO_DROPDOWN>
+
+          {renderBannerContent()}
+
+          <styledEl.CTAButton
+            onClick={handleCTAClick}
+            onMouseEnter={handleCTAMouseEnter}
+            onMouseLeave={handleCTAMouseLeave}
+            size={isTokenSelector(location) ? 38 : undefined}
+            fontSize={isTokenSelector(location) ? 18 : undefined}
+            bgColor={isTokenSelector(location) ? `var(${UI.COLOR_COWAMM_DARK_GREEN})` : undefined}
+            bgHoverColor={isTokenSelector(location) ? `var(${UI.COLOR_COWAMM_GREEN})` : undefined}
+            color={isTokenSelector(location) ? `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` : undefined}
+          >
+            Booooost APR gas-free!
+          </styledEl.CTAButton>
+
+          <ArrowBackground ref={arrowBackgroundRef} />
+
+          <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
+        </styledEl.BannerWrapper>
+      )}
+    </>
+  )
+}
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx
index 184afe0e7d..a4677c4674 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/arrowBackground.tsx
@@ -1,4 +1,4 @@
-import React, { forwardRef, useMemo } from 'react'
+import { forwardRef, useMemo } from 'react'
 import { memo } from 'react'
 
 import { UI } from '@cowprotocol/ui'
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index f2e7853715..40f0ad3edf 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -1,33 +1,17 @@
 import { useAtom } from 'jotai'
-import { cowAmmBannerStateAtom } from './cowAmmBannerState'
-
-import { useCallback, useMemo, useRef } from 'react'
+import { useCallback } from 'react'
 
-import ICON_ARROW from '@cowprotocol/assets/cow-swap/arrow.svg'
-import ICON_CURVE from '@cowprotocol/assets/cow-swap/icon-curve.svg'
-import ICON_PANCAKESWAP from '@cowprotocol/assets/cow-swap/icon-pancakeswap.svg'
-import ICON_SUSHISWAP from '@cowprotocol/assets/cow-swap/icon-sushi.svg'
-import ICON_UNISWAP from '@cowprotocol/assets/cow-swap/icon-uni.svg'
-import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
-import { ProductLogo, ProductVariant, UI } from '@cowprotocol/ui'
 import { ClosableBanner } from '@cowprotocol/ui'
 
-import { ArrowBackground } from './arrowBackground'
-
-import SVG from 'react-inlinesvg'
-import { Textfit } from 'react-textfit'
-
-import { upToSmall, useMediaQuery } from 'legacy/hooks/useMediaQuery'
-
 import { cowAnalytics } from 'modules/analytics'
 
-import { LpToken, dummyData, lpTokenConfig, StateKey } from './dummyData'
-import * as styledEl from './styled'
+import { CoWAmmBannerContent } from './CoWAmmBannerContent'
+import { cowAmmBannerStateAtom } from './cowAmmBannerState'
+import { dummyData, lpTokenConfig } from './dummyData'
 
 const ANALYTICS_URL = 'https://cow.fi/pools?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner'
-const BANNER_ID = 'cow_amm_banner_2024_va'
 
-const DEMO_DROPDOWN_OPTIONS = [
+export const DEMO_DROPDOWN_OPTIONS = [
   { value: 'noLp', label: 'No LP tokens' },
   { value: 'uniV2', label: 'UNI-V2 LP' },
   { value: 'sushi', label: 'SushiSwap LP' },
@@ -38,163 +22,47 @@ const DEMO_DROPDOWN_OPTIONS = [
   { value: 'fourLps', label: '4 LP tokens' },
 ]
 
-const lpTokenIcons: Record<LpToken, string> = {
-  [LpToken.UniswapV2]: ICON_UNISWAP,
-  [LpToken.Sushiswap]: ICON_SUSHISWAP,
-  [LpToken.PancakeSwap]: ICON_PANCAKESWAP,
-  [LpToken.Curve]: ICON_CURVE,
+type BannerLocation = 'global' | 'tokenSelector'
+
+interface BannerProps {
+  location: BannerLocation
 }
 
-export function CoWAmmBanner() {
+export function CoWAmmBanner({ location }: BannerProps) {
   const [selectedState, setSelectedState] = useAtom(cowAmmBannerStateAtom)
-  const isMobile = useMediaQuery(upToSmall)
-  const arrowBackgroundRef = useRef<HTMLDivElement>(null)
 
   const handleCTAClick = useCallback(() => {
     cowAnalytics.sendEvent({
       category: 'CoW Swap',
-      action: 'CoW AMM Banner [Global] CTA Clicked',
+      action: `CoW AMM Banner [${location}] CTA Clicked`,
     })
 
     window.open(ANALYTICS_URL, '_blank')
-  }, [])
+  }, [location])
 
   const handleClose = useCallback(() => {
     cowAnalytics.sendEvent({
       category: 'CoW Swap',
-      action: 'CoW AMM Banner [Global] Closed',
+      action: `CoW AMM Banner [${location}] Closed`,
     })
-  }, [])
-
-  const handleCTAMouseEnter = useCallback(() => {
-    if (arrowBackgroundRef.current) {
-      arrowBackgroundRef.current.style.visibility = 'visible'
-      arrowBackgroundRef.current.style.opacity = '1'
-    }
-  }, [])
-
-  const handleCTAMouseLeave = useCallback(() => {
-    if (arrowBackgroundRef.current) {
-      arrowBackgroundRef.current.style.visibility = 'hidden'
-      arrowBackgroundRef.current.style.opacity = '0'
-    }
-  }, [])
-
-  const aprMessage = useMemo(() => {
-    const { apr } = dummyData[selectedState]
-    return `+${apr.toFixed(1)}%`
-  }, [selectedState])
-
-  const comparisonMessage = useMemo(() => {
-    const { comparison } = dummyData[selectedState]
-    if (selectedState === 'noLp') {
-      return `yield over the average UNI-V2 pool`
-    }
-    if (selectedState === 'twoLps' || selectedState === 'threeLps') {
-      return `Get higher average APR than ${comparison}`
-    }
-    return `Get higher APR than ${comparison}`
-  }, [selectedState, dummyData])
-
-  const lpEmblems = useMemo(() => {
-    const tokens = lpTokenConfig[selectedState]
-    const totalItems = tokens.length
-
-    if (totalItems === 0) {
-      return null
-    }
-
-    return (
-      <styledEl.LpEmblems>
-        <styledEl.LpEmblemItemsWrapper totalItems={totalItems}>
-          {tokens.map((token, index) => (
-            <styledEl.LpEmblemItem key={token} totalItems={totalItems} index={index}>
-              <SVG src={lpTokenIcons[token]} />
-            </styledEl.LpEmblemItem>
-          ))}
-        </styledEl.LpEmblemItemsWrapper>
-        <styledEl.EmblemArrow>
-          <SVG src={ICON_ARROW} />
-        </styledEl.EmblemArrow>
-        <styledEl.CoWAMMEmblemItem>
-          <ProductLogo
-            height={'100%'}
-            overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
-            variant={ProductVariant.CowAmm}
-            logoIconOnly
-          />
-        </styledEl.CoWAMMEmblemItem>
-      </styledEl.LpEmblems>
-    )
-  }, [selectedState])
+  }, [location])
 
   const handleBannerClose = (close: () => void) => () => {
     handleClose()
     close()
   }
 
-  return ClosableBanner(BANNER_ID, (close) => (
-    <styledEl.BannerWrapper>
-      <styledEl.CloseButton size={24} onClick={handleBannerClose(close)} />
-
-      <styledEl.DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
-        {DEMO_DROPDOWN_OPTIONS.map((option) => (
-          <option key={option.value} value={option.value}>
-            {option.label}
-          </option>
-        ))}
-      </styledEl.DEMO_DROPDOWN>
-
-      <styledEl.Title>
-        <ProductLogo
-          height={20}
-          overrideColor={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}
-          variant={ProductVariant.CowAmm}
-          logoIconOnly
-        />
-        <span>CoW AMM</span>
-      </styledEl.Title>
-      <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_BLUE})`}>
-        <styledEl.StarIcon size={36} top={-17} right={80}>
-          <SVG src={ICON_STAR} />
-        </styledEl.StarIcon>
-        <h3>
-          <Textfit mode="single" forceSingleModeWidth={false} min={80} max={80} key={aprMessage}>
-            {aprMessage}
-          </Textfit>
-        </h3>
-        <p>
-          <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28} key={comparisonMessage}>
-            {comparisonMessage}
-          </Textfit>
-        </p>
-        <styledEl.StarIcon size={26} bottom={-10} right={20}>
-          <SVG src={ICON_STAR} />
-        </styledEl.StarIcon>
-      </styledEl.Card>
-
-      {!isMobile && (
-        <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_GREEN})`} color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}>
-          <p>
-            <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={30}>
-              One-click convert, <b>boost yield</b>
-            </Textfit>
-          </p>
-          {lpEmblems}
-        </styledEl.Card>
-      )}
-
-      <styledEl.CTAButton
-        onClick={handleCTAClick}
-        onMouseEnter={handleCTAMouseEnter}
-        onMouseLeave={handleCTAMouseLeave}
-      >
-        Booooost APR gas-free!
-      </styledEl.CTAButton>
-
-      <ArrowBackground ref={arrowBackgroundRef} />
-
-      <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
-    </styledEl.BannerWrapper>
+  const bannerId = `cow_amm_banner_2024_va_${location}`
+
+  return ClosableBanner(bannerId, (close) => (
+    <CoWAmmBannerContent
+      location={location}
+      selectedState={selectedState}
+      setSelectedState={setSelectedState}
+      dummyData={dummyData}
+      lpTokenConfig={lpTokenConfig}
+      handleCTAClick={handleCTAClick}
+      handleBannerClose={handleBannerClose(close)}
+    />
   ))
 }
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
index be0d1f8be3..2485823659 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
@@ -372,3 +372,27 @@ export const Arrow = styled.span<{ delay: number }>`
   left: ${() => Math.random() * 100}%;
   font-weight: 500;
 `
+
+export const TokenSelectorWrapper = styled.div`
+  z-index: 3;
+  width: 100%;
+  padding: 20px;
+  position: relative;
+`
+
+export const TokenSelectorWrapperInner = styled.div`
+  position: relative;
+  width: 100%;
+  height: auto;
+  border-radius: 24px;
+  background-color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
+  color: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  padding: 14px;
+  margin: 0 auto;
+  display: flex;
+  flex-flow: column wrap;
+  align-items: center;
+  justify-content: center;
+  gap: 14px;
+  overflow: hidden;
+`
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
deleted file mode 100644
index 3cf6a04c27..0000000000
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/tokenSelectorBanner.tsx
+++ /dev/null
@@ -1,165 +0,0 @@
-import { useAtomValue } from 'jotai'
-import { cowAmmBannerStateAtom } from './cowAmmBannerState'
-
-import { useCallback, useMemo, useRef } from 'react'
-
-import styled from 'styled-components/macro'
-import ICON_STAR from '@cowprotocol/assets/cow-swap/star-shine.svg'
-import { ProductLogo, ProductVariant, UI } from '@cowprotocol/ui'
-import { ClosableBanner } from '@cowprotocol/ui'
-
-import SVG from 'react-inlinesvg'
-import { Textfit } from 'react-textfit'
-
-import { cowAnalytics } from 'modules/analytics'
-
-import { dummyData, StateKey } from './dummyData'
-import * as styledEl from './styled'
-
-import { ArrowBackground } from './arrowBackground'
-
-export const Wrapper = styled.div`
-  z-index: 3;
-  width: 100%;
-  padding: 20px;
-  position: relative;
-`
-
-const WrapperInner = styled.div`
-  position: relative;
-  width: 100%;
-  height: auto;
-  border-radius: 24px;
-  background-color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
-  color: var(${UI.COLOR_COWAMM_DARK_GREEN});
-  padding: 14px;
-  margin: 0 auto;
-  display: flex;
-  flex-flow: column wrap;
-  align-items: center;
-  justify-content: center;
-  gap: 14px;
-  overflow: hidden;
-`
-
-const ANALYTICS_URL = 'https://cow.fi/pools?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner'
-const BANNER_ID = 'cow_amm_banner_tokenselector_2024_va'
-
-export function CoWAmmTokenSelectorBanner() {
-  const selectedState = useAtomValue(cowAmmBannerStateAtom)
-  const arrowBackgroundRef = useRef<HTMLDivElement>(null)
-
-  const handleCTAClick = useCallback(() => {
-    cowAnalytics.sendEvent({
-      category: 'CoW Swap',
-      action: 'CoW AMM Banner [Token selector] CTA Clicked',
-    })
-
-    window.open(ANALYTICS_URL, '_blank')
-  }, [])
-
-  const handleClose = useCallback(() => {
-    cowAnalytics.sendEvent({
-      category: 'CoW Swap',
-      action: 'CoW AMM Banner [Token selector] Closed',
-    })
-  }, [])
-
-  const handleCTAMouseEnter = useCallback(() => {
-    if (arrowBackgroundRef.current) {
-      arrowBackgroundRef.current.style.visibility = 'visible'
-      arrowBackgroundRef.current.style.opacity = '1'
-    }
-  }, [])
-
-  const handleCTAMouseLeave = useCallback(() => {
-    if (arrowBackgroundRef.current) {
-      arrowBackgroundRef.current.style.visibility = 'hidden'
-      arrowBackgroundRef.current.style.opacity = '0'
-    }
-  }, [])
-
-  const aprMessage = useMemo(() => {
-    const { apr } = dummyData[selectedState]
-    return `+${apr.toFixed(1)}%`
-  }, [selectedState])
-
-  const comparisonMessage = useMemo(() => {
-    const { comparison } = dummyData[selectedState]
-    if (selectedState === 'noLp') {
-      return `yield over the average UNI-V2 pool`
-    }
-    if (selectedState === 'twoLps' || selectedState === 'threeLps') {
-      return `Get higher average APR than ${comparison}`
-    }
-    return `Get higher APR than ${comparison}`
-  }, [selectedState, dummyData])
-
-  const handleBannerClose = (close: () => void) => () => {
-    handleClose()
-    close()
-  }
-
-  return ClosableBanner(BANNER_ID, (close) => (
-    <Wrapper>
-      <WrapperInner>
-        <styledEl.CloseButton
-          top={14}
-          size={24}
-          onClick={handleBannerClose(close)}
-          color={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
-        />
-
-        <styledEl.Title color={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}>
-          <ProductLogo
-            height={20}
-            overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
-            variant={ProductVariant.CowAmm}
-            logoIconOnly
-          />
-          <span>CoW AMM</span>
-        </styledEl.Title>
-        <styledEl.Card
-          bgColor={'transparent'}
-          borderColor={`var(${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30})`}
-          borderWidth={2}
-          padding={'14px'}
-          gap={'14px'}
-          height={'78px'}
-        >
-          <styledEl.StarIcon size={26} top={-16} right={80} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
-            <SVG src={ICON_STAR} />
-          </styledEl.StarIcon>
-          <h3>
-            <Textfit mode="single" forceSingleModeWidth={false} min={45} max={48} key={aprMessage}>
-              {aprMessage}
-            </Textfit>
-          </h3>
-          <p>
-            <Textfit mode="multi" forceSingleModeWidth={false} min={12} max={21} key={comparisonMessage}>
-              {comparisonMessage}
-            </Textfit>
-          </p>
-          <styledEl.StarIcon size={16} bottom={3} right={20} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
-            <SVG src={ICON_STAR} />
-          </styledEl.StarIcon>
-        </styledEl.Card>
-
-        <styledEl.CTAButton
-          onClick={handleCTAClick}
-          onMouseEnter={handleCTAMouseEnter}
-          onMouseLeave={handleCTAMouseLeave}
-          size={38}
-          fontSize={18}
-          bgColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
-          bgHoverColor={`var(${UI.COLOR_COWAMM_GREEN})`}
-          color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}
-        >
-          Boooooost APR gas-free!
-        </styledEl.CTAButton>
-
-        <ArrowBackground ref={arrowBackgroundRef} count={14} color={`var(${UI.COLOR_COWAMM_GREEN})`} />
-      </WrapperInner>
-    </Wrapper>
-  ))
-}
diff --git a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
index 186d8545ed..93f4623b30 100644
--- a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
+++ b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
@@ -5,7 +5,7 @@ import { TokenWithLogo } from '@cowprotocol/common-const'
 import { useVirtualizer } from '@tanstack/react-virtual'
 import ms from 'ms.macro'
 
-import { CoWAmmTokenSelectorBanner } from 'common/pure/CoWAMMBanner/tokenSelectorBanner'
+import { CoWAmmBanner } from 'common/pure/CoWAMMBanner'
 
 import * as styledEl from './styled'
 
@@ -67,7 +67,7 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
 
   return (
     <CommonListContainer id="tokens-list" ref={parentRef} onScroll={onScroll}>
-      <CoWAmmTokenSelectorBanner />
+      <CoWAmmBanner location="tokenSelector" />
 
       <styledEl.TokensInner ref={wrapperRef} style={{ height: virtualizer.getTotalSize() }}>
         <styledEl.TokensScroller style={{ transform: `translateY(${items[0]?.start ?? 0}px)` }}>

From 33918c48be344b04fe5e6bef5596101d2a5cd928 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Mon, 14 Oct 2024 13:46:58 +0100
Subject: [PATCH 07/15] feat: add darkmode styling for cow amm banners

---
 .../pure/CoWAMMBanner/CoWAmmBannerContent.tsx | 289 +++++++++---------
 .../src/common/pure/CoWAMMBanner/index.tsx    |  22 +-
 .../src/common/pure/CoWAMMBanner/styled.ts    |  12 +-
 .../application/containers/App/index.tsx      |   6 +-
 .../pure/TokensVirtualList/index.tsx          |   5 +-
 libs/ui/src/enum.ts                           |   1 +
 libs/ui/src/theme/ThemeColorVars.tsx          |   1 +
 7 files changed, 182 insertions(+), 154 deletions(-)

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
index c2ce0fc717..75b615b287 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
@@ -12,12 +12,13 @@ import SVG from 'react-inlinesvg'
 import { Textfit } from 'react-textfit'
 
 import { upToSmall, useMediaQuery } from 'legacy/hooks/useMediaQuery'
+import { useIsDarkMode } from 'legacy/state/user/hooks'
 
 import { ArrowBackground } from './arrowBackground'
 import { LpToken, StateKey } from './dummyData'
 import * as styledEl from './styled'
 
-import { DEMO_DROPDOWN_OPTIONS } from './index'
+import { BannerLocation, DEMO_DROPDOWN_OPTIONS } from './index'
 
 const lpTokenIcons: Record<LpToken, string> = {
   [LpToken.UniswapV2]: ICON_UNISWAP,
@@ -27,25 +28,34 @@ const lpTokenIcons: Record<LpToken, string> = {
 }
 
 interface CoWAmmBannerContentProps {
-  location: 'global' | 'tokenSelector'
+  id: string
+  title: string
+  ctaText: string
+  location: BannerLocation
+  isDemo: boolean
   selectedState: StateKey
   setSelectedState: (state: StateKey) => void
   dummyData: Record<StateKey, { apr: number; comparison: string }>
   lpTokenConfig: Record<StateKey, LpToken[]>
-  handleCTAClick: () => void
-  handleBannerClose: () => void
+  onCtaClick: () => void
+  onClose: () => void
 }
 
 export function CoWAmmBannerContent({
+  id,
+  title,
+  ctaText,
   location,
+  isDemo,
   selectedState,
   setSelectedState,
   dummyData,
   lpTokenConfig,
-  handleCTAClick,
-  handleBannerClose,
+  onCtaClick,
+  onClose,
 }: CoWAmmBannerContentProps) {
   const isMobile = useMediaQuery(upToSmall)
+  const isDarkMode = useIsDarkMode()
   const arrowBackgroundRef = useRef<HTMLDivElement>(null)
 
   const handleCTAMouseEnter = useCallback(() => {
@@ -62,21 +72,19 @@ export function CoWAmmBannerContent({
     }
   }, [])
 
-  const aprMessage = useMemo(() => {
-    const { apr } = dummyData[selectedState]
-    return `+${apr.toFixed(1)}%`
-  }, [selectedState, dummyData])
+  const { apr, comparison } = dummyData[selectedState]
+
+  const aprMessage = useMemo(() => `+${apr.toFixed(1)}%`, [apr])
 
   const comparisonMessage = useMemo(() => {
-    const { comparison } = dummyData[selectedState]
     if (selectedState === 'noLp') {
       return `yield over the average UNI-V2 pool`
     }
-    if (selectedState === 'twoLps' || selectedState === 'threeLps') {
-      return `Get higher average APR than ${comparison}`
-    }
-    return `Get higher APR than ${comparison}`
-  }, [selectedState, dummyData])
+    const prefix = ['twoLps', 'threeLps'].includes(selectedState)
+      ? 'Get higher average APR than'
+      : 'Get higher APR than'
+    return `${prefix} ${comparison}`
+  }, [selectedState, comparison])
 
   const lpEmblems = useMemo(() => {
     const tokens = lpTokenConfig[selectedState]
@@ -110,132 +118,141 @@ export function CoWAmmBannerContent({
     )
   }, [selectedState, lpTokenConfig])
 
-  const isTokenSelector = (loc: typeof location): loc is 'tokenSelector' => loc === 'tokenSelector'
-
-  const renderBannerContent = () => {
-    if (isTokenSelector(location)) {
-      return (
-        <styledEl.TokenSelectorWrapper>
-          <styledEl.TokenSelectorWrapperInner>
-            <styledEl.Title>
-              <ProductLogo
-                height={20}
-                overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
-                variant={ProductVariant.CowAmm}
-                logoIconOnly
-              />
-              <span>CoW AMM</span>
-            </styledEl.Title>
-            <styledEl.Card
-              bgColor={'transparent'}
-              borderColor={`var(${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30})`}
-              borderWidth={2}
-              padding={'14px'}
-              gap={'14px'}
-              height={'78px'}
-            >
-              <styledEl.StarIcon size={26} top={-16} right={80} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
-                <SVG src={ICON_STAR} />
-              </styledEl.StarIcon>
-              <h3>
-                <Textfit mode="single" forceSingleModeWidth={false} min={45} max={48} key={aprMessage}>
-                  {aprMessage}
-                </Textfit>
-              </h3>
-              <p>
-                <Textfit mode="multi" forceSingleModeWidth={false} min={12} max={21} key={comparisonMessage}>
-                  {comparisonMessage}
-                </Textfit>
-              </p>
-              <styledEl.StarIcon size={16} bottom={3} right={20} color={`var(${UI.COLOR_COWAMM_LIGHTER_GREEN})`}>
-                <SVG src={ICON_STAR} />
-              </styledEl.StarIcon>
-            </styledEl.Card>
-          </styledEl.TokenSelectorWrapperInner>
-        </styledEl.TokenSelectorWrapper>
-      )
-    }
+  const renderProductLogo = (color: string) => (
+    <ProductLogo height={20} overrideColor={`var(${color})`} variant={ProductVariant.CowAmm} logoIconOnly />
+  )
 
-    return (
-      <>
-        <styledEl.Title>
-          <ProductLogo
-            height={20}
-            overrideColor={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}
-            variant={ProductVariant.CowAmm}
-            logoIconOnly
-          />
-          <span>CoW AMM</span>
+  const renderStarIcon = (props: any) => (
+    <styledEl.StarIcon {...props}>
+      <SVG src={ICON_STAR} />
+    </styledEl.StarIcon>
+  )
+
+  const renderTextfit = (
+    content: React.ReactNode,
+    mode: 'single' | 'multi',
+    minFontSize: number,
+    maxFontSize: number,
+  ) => (
+    <Textfit mode={mode} forceSingleModeWidth={false} min={minFontSize} max={maxFontSize}>
+      {content}
+    </Textfit>
+  )
+
+  const renderTokenSelectorContent = () => (
+    <styledEl.TokenSelectorWrapper>
+      <styledEl.TokenSelectorWrapperInner
+        bgColor={isDarkMode ? `var(${UI.COLOR_COWAMM_DARK_GREEN})` : undefined}
+        color={isDarkMode ? `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` : undefined}
+      >
+        <styledEl.CloseButton
+          size={24}
+          top={14}
+          onClick={onClose}
+          color={`var(${isDarkMode ? UI.COLOR_COWAMM_LIGHT_GREEN : UI.COLOR_COWAMM_DARK_GREEN})`}
+        />
+        <styledEl.Title color={`var(${isDarkMode ? UI.COLOR_COWAMM_LIGHT_GREEN : UI.COLOR_COWAMM_DARK_GREEN})`}>
+          {renderProductLogo(isDarkMode ? UI.COLOR_COWAMM_LIGHT_GREEN : UI.COLOR_COWAMM_DARK_GREEN)}
+          <span>{title}</span>
         </styledEl.Title>
-        <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_BLUE})`}>
-          <styledEl.StarIcon size={36} top={-17} right={80}>
-            <SVG src={ICON_STAR} />
-          </styledEl.StarIcon>
-          <h3>
-            <Textfit mode="single" forceSingleModeWidth={false} min={80} max={80} key={aprMessage}>
-              {aprMessage}
-            </Textfit>
-          </h3>
-          <p>
-            <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={28} key={comparisonMessage}>
-              {comparisonMessage}
-            </Textfit>
-          </p>
-          <styledEl.StarIcon size={26} bottom={-10} right={20}>
-            <SVG src={ICON_STAR} />
-          </styledEl.StarIcon>
+        <styledEl.Card
+          bgColor={'transparent'}
+          borderColor={`var(${isDarkMode ? UI.COLOR_COWAMM_LIGHT_GREEN_OPACITY_30 : UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30})`}
+          borderWidth={2}
+          padding={'14px'}
+          gap={'14px'}
+          height={'78px'}
+        >
+          {renderStarIcon({ size: 26, top: -16, right: 80, color: `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` })}
+          <h3>{renderTextfit(aprMessage, 'single', 45, 48)}</h3>
+          <span>{renderTextfit(comparisonMessage, 'multi', 12, 21)}</span>
+          {renderStarIcon({ size: 16, bottom: 3, right: 20, color: `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` })}
+        </styledEl.Card>
+        <styledEl.CTAButton
+          onClick={onCtaClick}
+          onMouseEnter={handleCTAMouseEnter}
+          onMouseLeave={handleCTAMouseLeave}
+          size={38}
+          fontSize={18}
+          bgColor={isDarkMode ? `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` : `var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+          bgHoverColor={isDarkMode ? `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` : `var(${UI.COLOR_COWAMM_GREEN})`}
+          color={isDarkMode ? `var(${UI.COLOR_COWAMM_DARK_GREEN})` : `var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}
+        >
+          {ctaText}
+        </styledEl.CTAButton>
+      </styledEl.TokenSelectorWrapperInner>
+    </styledEl.TokenSelectorWrapper>
+  )
+
+  const renderGlobalContent = () => (
+    <styledEl.BannerWrapper>
+      <styledEl.CloseButton size={24} onClick={onClose} />
+      <styledEl.Title>
+        {renderProductLogo(UI.COLOR_COWAMM_LIGHT_GREEN)}
+        <span>{title}</span>
+      </styledEl.Title>
+      <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_BLUE})`}>
+        {renderStarIcon({ size: 36, top: -17, right: 80 })}
+        <h3>{renderTextfit(aprMessage, 'single', 80, 80)}</h3>
+        <span>{renderTextfit(comparisonMessage, 'multi', 10, 28)}</span>
+        {renderStarIcon({ size: 26, bottom: -10, right: 20 })}
+      </styledEl.Card>
+
+      {!isMobile && (
+        <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_GREEN})`} color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}>
+          <span>
+            {renderTextfit(
+              <>
+                One-click convert, <strong>boost yield</strong>
+              </>,
+              'multi',
+              10,
+              30,
+            )}
+          </span>
+          {lpEmblems}
         </styledEl.Card>
+      )}
 
-        {!isMobile && (
-          <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_GREEN})`} color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}>
-            <p>
-              <Textfit mode="multi" forceSingleModeWidth={false} min={10} max={30}>
-                One-click convert, <b>boost yield</b>
-              </Textfit>
-            </p>
-            {lpEmblems}
-          </styledEl.Card>
-        )}
-      </>
-    )
+      <styledEl.CTAButton onClick={onCtaClick} onMouseEnter={handleCTAMouseEnter} onMouseLeave={handleCTAMouseLeave}>
+        {ctaText}
+      </styledEl.CTAButton>
+
+      <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
+
+      <ArrowBackground ref={arrowBackgroundRef} />
+    </styledEl.BannerWrapper>
+  )
+
+  const renderDemoDropdown = () => (
+    <styledEl.DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
+      {DEMO_DROPDOWN_OPTIONS.map((option) => (
+        <option key={option.value} value={option.value}>
+          {option.label}
+        </option>
+      ))}
+    </styledEl.DEMO_DROPDOWN>
+  )
+
+  const content = (() => {
+    switch (location) {
+      case BannerLocation.TokenSelector:
+        return renderTokenSelectorContent()
+      case BannerLocation.Global:
+        return renderGlobalContent()
+      default:
+        return null
+    }
+  })()
+
+  if (!content) {
+    return null
   }
 
   return (
-    <>
-      {isTokenSelector(location) ? (
-        renderBannerContent()
-      ) : (
-        <styledEl.BannerWrapper>
-          <styledEl.CloseButton size={24} onClick={handleBannerClose} />
-
-          <styledEl.DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
-            {DEMO_DROPDOWN_OPTIONS.map((option) => (
-              <option key={option.value} value={option.value}>
-                {option.label}
-              </option>
-            ))}
-          </styledEl.DEMO_DROPDOWN>
-
-          {renderBannerContent()}
-
-          <styledEl.CTAButton
-            onClick={handleCTAClick}
-            onMouseEnter={handleCTAMouseEnter}
-            onMouseLeave={handleCTAMouseLeave}
-            size={isTokenSelector(location) ? 38 : undefined}
-            fontSize={isTokenSelector(location) ? 18 : undefined}
-            bgColor={isTokenSelector(location) ? `var(${UI.COLOR_COWAMM_DARK_GREEN})` : undefined}
-            bgHoverColor={isTokenSelector(location) ? `var(${UI.COLOR_COWAMM_GREEN})` : undefined}
-            color={isTokenSelector(location) ? `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` : undefined}
-          >
-            Booooost APR gas-free!
-          </styledEl.CTAButton>
-
-          <ArrowBackground ref={arrowBackgroundRef} />
-
-          <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
-        </styledEl.BannerWrapper>
-      )}
-    </>
+    <div data-banner-id={id}>
+      {content}
+      {isDemo && renderDemoDropdown()}
+    </div>
   )
 }
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index 40f0ad3edf..987d3e35d8 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -9,6 +9,7 @@ import { CoWAmmBannerContent } from './CoWAmmBannerContent'
 import { cowAmmBannerStateAtom } from './cowAmmBannerState'
 import { dummyData, lpTokenConfig } from './dummyData'
 
+const IS_DEMO_MODE = true
 const ANALYTICS_URL = 'https://cow.fi/pools?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner'
 
 export const DEMO_DROPDOWN_OPTIONS = [
@@ -22,7 +23,10 @@ export const DEMO_DROPDOWN_OPTIONS = [
   { value: 'fourLps', label: '4 LP tokens' },
 ]
 
-type BannerLocation = 'global' | 'tokenSelector'
+export enum BannerLocation {
+  Global = 'global',
+  TokenSelector = 'tokenSelector',
+}
 
 interface BannerProps {
   location: BannerLocation
@@ -47,22 +51,28 @@ export function CoWAmmBanner({ location }: BannerProps) {
     })
   }, [location])
 
-  const handleBannerClose = (close: () => void) => () => {
+  const handleBannerClose = useCallback(() => {
     handleClose()
-    close()
-  }
+  }, [handleClose])
 
   const bannerId = `cow_amm_banner_2024_va_${location}`
 
   return ClosableBanner(bannerId, (close) => (
     <CoWAmmBannerContent
+      id={bannerId}
+      title="CoW AMM"
+      ctaText="Explore CoW AMM"
       location={location}
+      isDemo={IS_DEMO_MODE}
       selectedState={selectedState}
       setSelectedState={setSelectedState}
       dummyData={dummyData}
       lpTokenConfig={lpTokenConfig}
-      handleCTAClick={handleCTAClick}
-      handleBannerClose={handleBannerClose(close)}
+      onCtaClick={handleCTAClick}
+      onClose={() => {
+        handleBannerClose()
+        close()
+      }}
     />
   ))
 }
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
index 2485823659..18769e6472 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
@@ -110,7 +110,7 @@ export const Card = styled.div<{
   position: relative;
 
   > h3,
-  > p {
+  > span {
     display: flex;
     align-items: center;
     justify-content: center;
@@ -133,11 +133,11 @@ export const Card = styled.div<{
     letter-spacing: -2px;
   }
 
-  > p {
+  > span {
     font-weight: inherit;
   }
 
-  > p b {
+  > span b {
     font-weight: 900;
     color: var(${UI.COLOR_COWAMM_LIGHTER_GREEN});
   }
@@ -380,13 +380,13 @@ export const TokenSelectorWrapper = styled.div`
   position: relative;
 `
 
-export const TokenSelectorWrapperInner = styled.div`
+export const TokenSelectorWrapperInner = styled.div<{ bgColor?: string; color?: string }>`
   position: relative;
   width: 100%;
   height: auto;
   border-radius: 24px;
-  background-color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
-  color: var(${UI.COLOR_COWAMM_DARK_GREEN});
+  background: ${({ bgColor }) => bgColor || `var(${UI.COLOR_COWAMM_LIGHT_GREEN})`};
+  color: ${({ color }) => color || `var(${UI.COLOR_COWAMM_DARK_GREEN})`};
   padding: 14px;
   margin: 0 auto;
   display: flex;
diff --git a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
index c08a02680e..8cdbbbbc57 100644
--- a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
+++ b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
@@ -24,7 +24,7 @@ import { useInitializeUtm } from 'modules/utm'
 import { InvalidLocalTimeWarning } from 'common/containers/InvalidLocalTimeWarning'
 import { useCategorizeRecentActivity } from 'common/hooks/useCategorizeRecentActivity'
 import { useMenuItems } from 'common/hooks/useMenuItems'
-import { CoWAmmBanner } from 'common/pure/CoWAMMBanner'
+import { BannerLocation, CoWAmmBanner } from 'common/pure/CoWAMMBanner'
 import { LoadingApp } from 'common/pure/LoadingApp'
 import { CoWDAOFonts } from 'common/styles/CoWDAOFonts'
 import RedirectAnySwapAffectedUsers from 'pages/error/AnySwapAffectedUsers/RedirectAnySwapAffectedUsers'
@@ -62,7 +62,7 @@ export function App() {
         onClick: toggleDarkMode,
       },
     ],
-    [darkMode, toggleDarkMode]
+    [darkMode, toggleDarkMode],
   )
 
   const tradeContext = useTradeRouteContext()
@@ -129,7 +129,7 @@ export function App() {
           )}
 
           {/* CoW AMM banner */}
-          {!isInjectedWidgetMode && <CoWAmmBanner />}
+          {!isInjectedWidgetMode && <CoWAmmBanner location={BannerLocation.Global} />}
 
           <styledEl.BodyWrapper>
             <TopLevelModals />
diff --git a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
index 93f4623b30..33377421db 100644
--- a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
+++ b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
@@ -5,7 +5,7 @@ import { TokenWithLogo } from '@cowprotocol/common-const'
 import { useVirtualizer } from '@tanstack/react-virtual'
 import ms from 'ms.macro'
 
-import { CoWAmmBanner } from 'common/pure/CoWAMMBanner'
+import { CoWAmmBanner, BannerLocation } from 'common/pure/CoWAMMBanner'
 
 import * as styledEl from './styled'
 
@@ -67,8 +67,7 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
 
   return (
     <CommonListContainer id="tokens-list" ref={parentRef} onScroll={onScroll}>
-      <CoWAmmBanner location="tokenSelector" />
-
+      <CoWAmmBanner location={BannerLocation.TokenSelector} />
       <styledEl.TokensInner ref={wrapperRef} style={{ height: virtualizer.getTotalSize() }}>
         <styledEl.TokensScroller style={{ transform: `translateY(${items[0]?.start ?? 0}px)` }}>
           {items.map((virtualRow) => {
diff --git a/libs/ui/src/enum.ts b/libs/ui/src/enum.ts
index 608ce17b35..fda3e8dbc5 100644
--- a/libs/ui/src/enum.ts
+++ b/libs/ui/src/enum.ts
@@ -65,6 +65,7 @@ export enum UI {
   COLOR_COWAMM_DARK_GREEN_OPACITY_30 = '--cow-color-cowamm-dark-green-opacity-30',
   COLOR_COWAMM_GREEN = '--cow-color-cowamm-green',
   COLOR_COWAMM_LIGHT_GREEN = '--cow-color-cowamm-light-green',
+  COLOR_COWAMM_LIGHT_GREEN_OPACITY_30 = '--cow-color-cowamm-light-green-opacity-30',
   COLOR_COWAMM_LIGHTER_GREEN = '--cow-color-cowamm-lighter-green',
   COLOR_COWAMM_BLUE = '--cow-color-cowamm-blue',
   COLOR_COWAMM_LIGHT_BLUE = '--cow-color-cowamm-light-blue',
diff --git a/libs/ui/src/theme/ThemeColorVars.tsx b/libs/ui/src/theme/ThemeColorVars.tsx
index 55efc51732..81a27134de 100644
--- a/libs/ui/src/theme/ThemeColorVars.tsx
+++ b/libs/ui/src/theme/ThemeColorVars.tsx
@@ -102,6 +102,7 @@ export const ThemeColorVars = css`
     ${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30}: ${() => transparentize('#194d05', 0.7)};
     ${UI.COLOR_COWAMM_GREEN}: #2b6f0b;
     ${UI.COLOR_COWAMM_LIGHT_GREEN}: #bcec79;
+    ${UI.COLOR_COWAMM_LIGHT_GREEN_OPACITY_30}: ${() => transparentize('#bcec79', 0.7)};
     ${UI.COLOR_COWAMM_LIGHTER_GREEN}: #dcf8a7;
     ${UI.COLOR_COWAMM_BLUE}: #3fc4ff;
     ${UI.COLOR_COWAMM_LIGHT_BLUE}: #ccf8ff;

From b0bb42650116805c98ae8129706cc41371a7cc8b Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Tue, 15 Oct 2024 13:07:15 +0100
Subject: [PATCH 08/15] feat: add poolinfo element

---
 .../pure/CoWAMMBanner/CoWAmmBannerContent.tsx | 236 +++++++++++++-----
 .../src/common/pure/CoWAMMBanner/dummyData.ts |  85 ++++++-
 .../src/common/pure/CoWAMMBanner/index.tsx    |  20 +-
 .../src/common/pure/CoWAMMBanner/styled.ts    |  87 ++++++-
 libs/ui/src/enum.ts                           |   2 +
 libs/ui/src/theme/ThemeColorVars.tsx          |   2 +
 6 files changed, 336 insertions(+), 96 deletions(-)

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
index 75b615b287..8103c4baa8 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
@@ -1,3 +1,4 @@
+import React from 'react'
 import { useCallback, useMemo, useRef } from 'react'
 
 import ICON_ARROW from '@cowprotocol/assets/cow-swap/arrow.svg'
@@ -15,10 +16,14 @@ import { upToSmall, useMediaQuery } from 'legacy/hooks/useMediaQuery'
 import { useIsDarkMode } from 'legacy/state/user/hooks'
 
 import { ArrowBackground } from './arrowBackground'
-import { LpToken, StateKey } from './dummyData'
+import { LpToken, StateKey, dummyData, lpTokenConfig } from './dummyData'
 import * as styledEl from './styled'
 
 import { BannerLocation, DEMO_DROPDOWN_OPTIONS } from './index'
+import { TokenLogo } from '../../../../../../libs/tokens/src/pure/TokenLogo'
+import { USDC, WBTC } from '@cowprotocol/common-const'
+import { SupportedChainId } from '@cowprotocol/cow-sdk'
+import { DummyDataType, TwoLpScenario } from './dummyData'
 
 const lpTokenIcons: Record<LpToken, string> = {
   [LpToken.UniswapV2]: ICON_UNISWAP,
@@ -35,12 +40,28 @@ interface CoWAmmBannerContentProps {
   isDemo: boolean
   selectedState: StateKey
   setSelectedState: (state: StateKey) => void
-  dummyData: Record<StateKey, { apr: number; comparison: string }>
-  lpTokenConfig: Record<StateKey, LpToken[]>
+  dummyData: typeof dummyData
+  lpTokenConfig: typeof lpTokenConfig
   onCtaClick: () => void
   onClose: () => void
 }
 
+function isTwoLpScenario(scenario: DummyDataType[keyof DummyDataType]): scenario is TwoLpScenario {
+  return 'uniV2Apr' in scenario && 'sushiApr' in scenario
+}
+
+const renderTextfit = (
+  content: React.ReactNode,
+  mode: 'single' | 'multi',
+  minFontSize: number,
+  maxFontSize: number,
+  key: string,
+) => (
+  <Textfit key={key} mode={mode} forceSingleModeWidth={false} min={minFontSize} max={maxFontSize}>
+    {content}
+  </Textfit>
+)
+
 export function CoWAmmBannerContent({
   id,
   title,
@@ -72,26 +93,104 @@ export function CoWAmmBannerContent({
     }
   }, [])
 
-  const { apr, comparison } = dummyData[selectedState]
+  const { apr } = dummyData[selectedState]
 
   const aprMessage = useMemo(() => `+${apr.toFixed(1)}%`, [apr])
 
   const comparisonMessage = useMemo(() => {
-    if (selectedState === 'noLp') {
-      return `yield over the average UNI-V2 pool`
+    const currentData = dummyData[selectedState]
+
+    if (!currentData) {
+      return 'Invalid state selected'
     }
-    const prefix = ['twoLps', 'threeLps'].includes(selectedState)
-      ? 'Get higher average APR than'
-      : 'Get higher APR than'
-    return `${prefix} ${comparison}`
-  }, [selectedState, comparison])
+
+    const renderPoolInfo = (poolName: string) => (
+      <styledEl.PoolInfo
+        flow={location === BannerLocation.TokenSelector ? 'row' : 'column'}
+        align={location === BannerLocation.TokenSelector ? 'center' : 'flex-start'}
+        bgColor={
+          location === BannerLocation.TokenSelector ? `var(${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_15})` : undefined
+        }
+        color={location === BannerLocation.TokenSelector ? `var(${UI.COLOR_COWAMM_DARK_GREEN})` : undefined}
+        tokenBorderColor={location === BannerLocation.TokenSelector ? `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` : undefined}
+      >
+        higher APR available for your {poolName} pool:
+        <i>
+          <div>
+            <TokenLogo token={WBTC} /> <TokenLogo token={USDC[SupportedChainId.MAINNET]} />
+          </div>
+          <span>WBTC-USDC</span>
+        </i>
+      </styledEl.PoolInfo>
+    )
+
+    if (isTwoLpScenario(currentData)) {
+      if (selectedState === 'twoLpsMixed') {
+        return renderPoolInfo('UNI-V2')
+      } else if (selectedState === 'twoLpsBothSuperior') {
+        const { uniV2Apr, sushiApr } = currentData
+        const higherAprPool = uniV2Apr > sushiApr ? 'UNI-V2' : 'SushiSwap'
+        return renderPoolInfo(higherAprPool)
+      }
+    }
+
+    if (selectedState === 'uniV2Superior') {
+      return renderPoolInfo('UNI-V2')
+    }
+
+    if (currentData.hasCoWAmmPool) {
+      return `yield over average ${currentData.comparison} pool`
+    } else {
+      const tokens = lpTokenConfig[selectedState]
+      if (tokens.length > 1) {
+        const tokenNames = tokens
+          .map((token) => {
+            switch (token) {
+              case LpToken.UniswapV2:
+                return 'UNI-V2'
+              case LpToken.Sushiswap:
+                return 'Sushi'
+              case LpToken.PancakeSwap:
+                return 'PancakeSwap'
+              case LpToken.Curve:
+                return 'Curve'
+              default:
+                return ''
+            }
+          })
+          .filter(Boolean)
+
+        return `yield over average ${tokenNames.join(', ')} pool${tokenNames.length > 1 ? 's' : ''}`
+      } else {
+        return `yield over average UNI-V2 pool`
+      }
+    }
+  }, [selectedState, lpTokenConfig])
 
   const lpEmblems = useMemo(() => {
     const tokens = lpTokenConfig[selectedState]
     const totalItems = tokens.length
 
     if (totalItems === 0) {
-      return null
+      // Fallback to UniswapV2 emblem if no LP tokens
+      return (
+        <styledEl.LpEmblems>
+          <styledEl.LpEmblemItem key={LpToken.UniswapV2} totalItems={1} index={0}>
+            <SVG src={lpTokenIcons[LpToken.UniswapV2]} />
+          </styledEl.LpEmblemItem>
+          <styledEl.EmblemArrow>
+            <SVG src={ICON_ARROW} />
+          </styledEl.EmblemArrow>
+          <styledEl.CoWAMMEmblemItem>
+            <ProductLogo
+              height={'100%'}
+              overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+              variant={ProductVariant.CowAmm}
+              logoIconOnly
+            />
+          </styledEl.CoWAMMEmblemItem>
+        </styledEl.LpEmblems>
+      )
     }
 
     return (
@@ -116,27 +215,22 @@ export function CoWAmmBannerContent({
         </styledEl.CoWAMMEmblemItem>
       </styledEl.LpEmblems>
     )
-  }, [selectedState, lpTokenConfig])
-
-  const renderProductLogo = (color: string) => (
-    <ProductLogo height={20} overrideColor={`var(${color})`} variant={ProductVariant.CowAmm} logoIconOnly />
-  )
+  }, [selectedState, lpTokenConfig, lpTokenIcons])
 
-  const renderStarIcon = (props: any) => (
-    <styledEl.StarIcon {...props}>
-      <SVG src={ICON_STAR} />
-    </styledEl.StarIcon>
+  const renderProductLogo = useCallback(
+    (color: string) => (
+      <ProductLogo height={20} overrideColor={`var(${color})`} variant={ProductVariant.CowAmm} logoIconOnly />
+    ),
+    [],
   )
 
-  const renderTextfit = (
-    content: React.ReactNode,
-    mode: 'single' | 'multi',
-    minFontSize: number,
-    maxFontSize: number,
-  ) => (
-    <Textfit mode={mode} forceSingleModeWidth={false} min={minFontSize} max={maxFontSize}>
-      {content}
-    </Textfit>
+  const renderStarIcon = useCallback(
+    (props: any) => (
+      <styledEl.StarIcon {...props}>
+        <SVG src={ICON_STAR} />
+      </styledEl.StarIcon>
+    ),
+    [],
   )
 
   const renderTokenSelectorContent = () => (
@@ -159,13 +253,15 @@ export function CoWAmmBannerContent({
           bgColor={'transparent'}
           borderColor={`var(${isDarkMode ? UI.COLOR_COWAMM_LIGHT_GREEN_OPACITY_30 : UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30})`}
           borderWidth={2}
-          padding={'14px'}
+          padding={'10px'}
           gap={'14px'}
-          height={'78px'}
+          height={'max-content'}
         >
           {renderStarIcon({ size: 26, top: -16, right: 80, color: `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` })}
-          <h3>{renderTextfit(aprMessage, 'single', 45, 48)}</h3>
-          <span>{renderTextfit(comparisonMessage, 'multi', 12, 21)}</span>
+          <h3>{renderTextfit(aprMessage, 'single', 24, 48, `apr-${selectedState}`)}</h3>
+          <span>
+            {renderTextfit(comparisonMessage, 'multi', 12, isMobile ? 18 : 21, `comparison-${selectedState}`)}
+          </span>
           {renderStarIcon({ size: 16, bottom: 3, right: 20, color: `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` })}
         </styledEl.Card>
         <styledEl.CTAButton
@@ -173,6 +269,7 @@ export function CoWAmmBannerContent({
           onMouseEnter={handleCTAMouseEnter}
           onMouseLeave={handleCTAMouseLeave}
           size={38}
+          fontSizeMobile={18}
           fontSize={18}
           bgColor={isDarkMode ? `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` : `var(${UI.COLOR_COWAMM_DARK_GREEN})`}
           bgHoverColor={isDarkMode ? `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` : `var(${UI.COLOR_COWAMM_GREEN})`}
@@ -184,45 +281,50 @@ export function CoWAmmBannerContent({
     </styledEl.TokenSelectorWrapper>
   )
 
-  const renderGlobalContent = () => (
-    <styledEl.BannerWrapper>
-      <styledEl.CloseButton size={24} onClick={onClose} />
-      <styledEl.Title>
-        {renderProductLogo(UI.COLOR_COWAMM_LIGHT_GREEN)}
-        <span>{title}</span>
-      </styledEl.Title>
-      <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_BLUE})`}>
-        {renderStarIcon({ size: 36, top: -17, right: 80 })}
-        <h3>{renderTextfit(aprMessage, 'single', 80, 80)}</h3>
-        <span>{renderTextfit(comparisonMessage, 'multi', 10, 28)}</span>
-        {renderStarIcon({ size: 26, bottom: -10, right: 20 })}
-      </styledEl.Card>
-
-      {!isMobile && (
-        <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_GREEN})`} color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}>
+  const renderGlobalContent = () => {
+    return (
+      <styledEl.BannerWrapper>
+        <styledEl.CloseButton size={24} onClick={onClose} />
+        <styledEl.Title>
+          {renderProductLogo(UI.COLOR_COWAMM_LIGHT_GREEN)}
+          <span>{title}</span>
+        </styledEl.Title>
+        <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_BLUE})`} color={`var(${UI.COLOR_COWAMM_DARK_BLUE})`}>
+          {renderStarIcon({ size: 36, top: -17, right: 80 })}
+          <h3>{renderTextfit(aprMessage, 'single', isMobile ? 40 : 80, isMobile ? 50 : 80, `apr-${selectedState}`)}</h3>
           <span>
-            {renderTextfit(
-              <>
-                One-click convert, <strong>boost yield</strong>
-              </>,
-              'multi',
-              10,
-              30,
-            )}
+            {renderTextfit(comparisonMessage, 'multi', 10, isMobile ? 21 : 28, `comparison-${selectedState}`)}
           </span>
-          {lpEmblems}
+          {renderStarIcon({ size: 26, bottom: -10, right: 20 })}
         </styledEl.Card>
-      )}
 
-      <styledEl.CTAButton onClick={onCtaClick} onMouseEnter={handleCTAMouseEnter} onMouseLeave={handleCTAMouseLeave}>
-        {ctaText}
-      </styledEl.CTAButton>
+        {!isMobile && (
+          <styledEl.Card bgColor={`var(${UI.COLOR_COWAMM_GREEN})`} color={`var(${UI.COLOR_COWAMM_LIGHT_GREEN})`}>
+            <span>
+              {renderTextfit(
+                <>
+                  One-click convert, <strong>boost yield</strong>
+                </>,
+                'multi',
+                10,
+                30,
+                `boost-yield-${selectedState}`,
+              )}
+            </span>
+            {lpEmblems}
+          </styledEl.Card>
+        )}
 
-      <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
+        <styledEl.CTAButton onClick={onCtaClick} onMouseEnter={handleCTAMouseEnter} onMouseLeave={handleCTAMouseLeave}>
+          {ctaText}
+        </styledEl.CTAButton>
 
-      <ArrowBackground ref={arrowBackgroundRef} />
-    </styledEl.BannerWrapper>
-  )
+        <styledEl.SecondaryLink href={'https://cow.fi/'}>Pool analytics ↗</styledEl.SecondaryLink>
+
+        <ArrowBackground ref={arrowBackgroundRef} />
+      </styledEl.BannerWrapper>
+    )
+  }
 
   const renderDemoDropdown = () => (
     <styledEl.DEMO_DROPDOWN value={selectedState} onChange={(e) => setSelectedState(e.target.value as StateKey)}>
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
index 0cfb4da319..1a40e2de18 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
@@ -5,26 +5,87 @@ export enum LpToken {
   Curve = 'Curve',
 }
 
+type BaseScenario = {
+  readonly apr: number
+  readonly comparison: string
+  readonly hasCoWAmmPool: boolean
+}
+
+export type TwoLpScenario = BaseScenario & {
+  readonly uniV2Apr: number
+  readonly sushiApr: number
+}
+
 export const dummyData = {
-  noLp: { apr: 1.5, comparison: 'UNI-V2' },
-  uniV2: { apr: 2.1, comparison: 'UNI-V2' },
-  sushi: { apr: 1.8, comparison: 'SushiSwap' },
-  curve: { apr: 1.3, comparison: 'Curve' },
-  pancake: { apr: 2.5, comparison: 'PancakeSwap' },
-  twoLps: { apr: 2.0, comparison: 'UNI-V2 and SushiSwap' },
-  threeLps: { apr: 2.2, comparison: 'UNI-V2, SushiSwap, and Curve' },
-  fourLps: { apr: 2.4, comparison: 'UNI-V2, Sushiswap, Curve, and Balancer' },
+  noLp: {
+    apr: 1.5,
+    comparison: 'average UNI-V2 pool',
+    hasCoWAmmPool: false,
+  },
+  uniV2Superior: {
+    apr: 2.1,
+    comparison: 'UNI-V2',
+    hasCoWAmmPool: true,
+  },
+  uniV2Inferior: {
+    apr: 1.2,
+    comparison: 'UNI-V2',
+    hasCoWAmmPool: true,
+  },
+  sushi: {
+    apr: 1.8,
+    comparison: 'SushiSwap',
+    hasCoWAmmPool: true,
+  },
+  curve: {
+    apr: 1.3,
+    comparison: 'Curve',
+    hasCoWAmmPool: true,
+  },
+  pancake: {
+    apr: 2.5,
+    comparison: 'PancakeSwap',
+    hasCoWAmmPool: true,
+    isYieldSuperior: true,
+  },
+  twoLpsMixed: {
+    apr: 2.5,
+    comparison: 'UNI-V2 and SushiSwap',
+    hasCoWAmmPool: true,
+    uniV2Apr: 3.0,
+    sushiApr: 1.8,
+  } as TwoLpScenario,
+  twoLpsBothSuperior: {
+    apr: 3.2,
+    comparison: 'UNI-V2 and SushiSwap',
+    hasCoWAmmPool: true,
+    uniV2Apr: 3.5,
+    sushiApr: 2.9,
+  } as TwoLpScenario,
+  threeLps: {
+    apr: 2.2,
+    comparison: 'UNI-V2, SushiSwap, and Curve',
+    hasCoWAmmPool: false,
+  },
+  fourLps: {
+    apr: 2.4,
+    comparison: 'UNI-V2, SushiSwap, Curve, and PancakeSwap',
+    hasCoWAmmPool: false,
+  },
 } as const
 
 export type StateKey = keyof typeof dummyData
+export type DummyDataType = typeof dummyData
 
 export const lpTokenConfig: Record<StateKey, LpToken[]> = {
-  noLp: [LpToken.UniswapV2],
-  uniV2: [LpToken.UniswapV2],
+  noLp: [],
+  uniV2Superior: [LpToken.UniswapV2],
+  uniV2Inferior: [LpToken.UniswapV2],
   sushi: [LpToken.Sushiswap],
   curve: [LpToken.Curve],
   pancake: [LpToken.PancakeSwap],
-  twoLps: [LpToken.UniswapV2, LpToken.Sushiswap],
+  twoLpsMixed: [LpToken.UniswapV2, LpToken.Sushiswap],
+  twoLpsBothSuperior: [LpToken.UniswapV2, LpToken.Sushiswap],
   threeLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve],
-  fourLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve, LpToken.Curve],
+  fourLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve, LpToken.PancakeSwap],
 }
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index 987d3e35d8..fb65b7df8e 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -13,14 +13,16 @@ const IS_DEMO_MODE = true
 const ANALYTICS_URL = 'https://cow.fi/pools?utm_source=swap.cow.fi&utm_medium=web&utm_content=cow_amm_banner'
 
 export const DEMO_DROPDOWN_OPTIONS = [
-  { value: 'noLp', label: 'No LP tokens' },
-  { value: 'uniV2', label: 'UNI-V2 LP' },
-  { value: 'sushi', label: 'SushiSwap LP' },
-  { value: 'curve', label: 'Curve LP' },
-  { value: 'pancake', label: 'PancakeSwap LP' },
-  { value: 'twoLps', label: '2 LP tokens' },
-  { value: 'threeLps', label: '3 LP tokens' },
-  { value: 'fourLps', label: '4 LP tokens' },
+  { value: 'noLp', label: '🚫 No LP Tokens' },
+  { value: 'uniV2Superior', label: '⬆️ 🐴 UNI-V2 LP (Superior Yield)' },
+  { value: 'uniV2Inferior', label: '⬇️ 🐴 UNI-V2 LP (Inferior Yield)' },
+  { value: 'sushi', label: '⬇️ 🍣 SushiSwap LP (Inferior Yield)' },
+  { value: 'curve', label: '⬇️ 🌈 Curve LP (Inferior Yield)' },
+  { value: 'pancake', label: '⬇️ 🥞 PancakeSwap LP (Inferior Yield)' },
+  { value: 'twoLpsMixed', label: '⬆️ 🐴 UNI-V2 (Superior) & ⬇️ 🍣 SushiSwap (Inferior) LPs' },
+  { value: 'twoLpsBothSuperior', label: '⬆️ 🐴 UNI-V2 & ⬆️ 🍣 SushiSwap LPs (Both Superior, but UNI-V2 is higher)' },
+  { value: 'threeLps', label: '⬇️ 🐴 UNI-V2, 🍣 SushiSwap & 🌈 Curve LPs (Inferior Yield)' },
+  { value: 'fourLps', label: '⬇️ 🐴 UNI-V2, 🍣 SushiSwap, 🌈 Curve & 🥞 PancakeSwap LPs (Inferior Yield)' },
 ]
 
 export enum BannerLocation {
@@ -61,7 +63,7 @@ export function CoWAmmBanner({ location }: BannerProps) {
     <CoWAmmBannerContent
       id={bannerId}
       title="CoW AMM"
-      ctaText="Explore CoW AMM"
+      ctaText="Booooost APR gas-free!"
       location={location}
       isDemo={IS_DEMO_MODE}
       selectedState={selectedState}
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
index 18769e6472..d8896bfe2b 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
@@ -2,6 +2,7 @@ import { UI, Media } from '@cowprotocol/ui'
 
 import { X } from 'react-feather'
 import styled, { keyframes } from 'styled-components/macro'
+import { TokenLogoWrapper } from '../../../../../../libs/tokens/src/pure/TokenLogo'
 
 const arrowUpAnimation = keyframes`
   0% {
@@ -82,7 +83,7 @@ export const Title = styled.h2<{ color?: string }>`
 export const Card = styled.div<{
   bgColor?: string
   color?: string
-  height?: string
+  height?: number | 'max-content'
   borderColor?: string
   borderWidth?: number
   padding?: string
@@ -100,8 +101,10 @@ export const Card = styled.div<{
   margin: 0;
   width: 100%;
   max-width: 100%;
-  height: ${({ height }) => height || 'var(--default-height)'};
-  max-height: ${({ height }) => height || 'var(--default-height)'};
+  height: ${({ height }) =>
+    height === 'max-content' ? 'max-content' : height ? `${height}px` : 'var(--default-height)'};
+  max-height: ${({ height }) =>
+    height === 'max-content' ? 'max-content' : height ? `${height}px` : 'var(--default-height)'};
   border-radius: 16px;
   padding: ${({ padding }) => padding || '24px'};
   background: ${({ bgColor }) => bgColor || 'transparent'};
@@ -109,6 +112,13 @@ export const Card = styled.div<{
   border: ${({ borderWidth, borderColor }) => borderWidth && borderColor && `${borderWidth}px solid ${borderColor}`};
   position: relative;
 
+  ${Media.upToSmall()} {
+    flex-flow: column wrap;
+    height: auto;
+    max-height: initial;
+    gap: 8px;
+  }
+
   > h3,
   > span {
     display: flex;
@@ -118,6 +128,12 @@ export const Card = styled.div<{
     width: max-content;
     height: 100%;
     max-height: 100%;
+    color: inherit;
+
+    ${Media.upToSmall()} {
+      width: 100%;
+      text-align: center;
+    }
 
     > div {
       width: 100%;
@@ -143,21 +159,63 @@ export const Card = styled.div<{
   }
 `
 
+export const PoolInfo = styled.div<{
+  flow?: 'column' | 'row'
+  align?: 'flex-start' | 'center'
+  color?: string
+  bgColor?: string
+  tokenBorderColor?: string
+}>`
+  display: flex;
+  align-items: ${({ align = 'flex-start' }) => align};
+  flex-flow: ${({ flow = 'column' }) => flow};
+  font-size: 16px;
+  gap: 10px;
+
+  > i {
+    font-style: normal;
+    background: ${({ bgColor }) => bgColor || `var(${UI.COLOR_COWAMM_LIGHT_BLUE})`};
+    color: ${({ color }) => color || `var(${UI.COLOR_COWAMM_DARK_BLUE})`};
+    display: flex;
+    flex-flow: row;
+    gap: 6px;
+    padding: 6px 12px 6px 6px;
+    height: min-content;
+    border-radius: 62px;
+    width: min-content;
+    box-shadow: var(${UI.BOX_SHADOW_2});
+  }
+
+  > i > div {
+    display: flex;
+  }
+
+  ${TokenLogoWrapper} {
+    border: 2px solid ${({ tokenBorderColor }) => tokenBorderColor || `var(${UI.COLOR_COWAMM_LIGHT_BLUE})`};
+
+    :last-child {
+      margin-left: -18px;
+    }
+  }
+`
+
 export const CTAButton = styled.button<{
   bgColor?: string
   bgHoverColor?: string
   color?: string
   size?: number
   fontSize?: number
+  fontSizeMobile?: number
 }>`
   --size: ${({ size = 58 }) => size}px;
+  --font-size: ${({ fontSize = 24 }) => fontSize}px;
   background: ${({ bgColor }) => bgColor || `var(${UI.COLOR_COWAMM_LIGHT_GREEN})`};
   color: ${({ color }) => color || `var(${UI.COLOR_COWAMM_DARK_GREEN})`};
   border: none;
   border-radius: var(--size);
   min-height: var(--size);
   padding: 12px 24px;
-  font-size: ${({ fontSize = 24 }) => fontSize}px;
+  font-size: var(--font-size);
   font-weight: bold;
   cursor: pointer;
   width: 100%;
@@ -170,6 +228,11 @@ export const CTAButton = styled.button<{
   overflow: hidden;
   z-index: 1;
 
+  ${Media.upToSmall()} {
+    --font-size: ${({ fontSizeMobile = 21 }) => fontSizeMobile}px;
+    min-height: initial;
+  }
+
   &::before {
     content: '';
     position: absolute;
@@ -206,11 +269,19 @@ export const SecondaryLink = styled.a`
 
 export const DEMO_DROPDOWN = styled.select`
   position: fixed;
-  bottom: 150px;
-  right: 10px;
+  bottom: 20px;
+  right: 20px;
   z-index: 999999999;
   padding: 5px;
-  font-size: 16px;
+  font-size: 14px;
+
+  ${Media.upToSmall()} {
+    bottom: initial;
+    top: 0;
+    width: 100%;
+    right: 0;
+    left: 0;
+  }
 `
 
 export const StarIcon = styled.div<{
@@ -228,7 +299,7 @@ export const StarIcon = styled.div<{
   left: ${({ left }) => (left === 'initial' ? 'initial' : left != null ? `${left}px` : 'initial')};
   right: ${({ right }) => (right === 'initial' ? 'initial' : right != null ? `${right}px` : 'initial')};
   bottom: ${({ bottom }) => (bottom === 'initial' ? 'initial' : bottom != null ? `${bottom}px` : 'initial')};
-  color: ${({ color }) => color ?? `var(${UI.COLOR_WHITE})`};
+  color: ${({ color }) => color ?? `var(${UI.COLOR_COWAMM_LIGHT_BLUE})`};
 
   > svg > path {
     fill: ${({ color }) => color ?? 'currentColor'};
diff --git a/libs/ui/src/enum.ts b/libs/ui/src/enum.ts
index fda3e8dbc5..7b083a0990 100644
--- a/libs/ui/src/enum.ts
+++ b/libs/ui/src/enum.ts
@@ -63,11 +63,13 @@ export enum UI {
   // CoW AMM Colors
   COLOR_COWAMM_DARK_GREEN = '--cow-color-cowamm-dark-green',
   COLOR_COWAMM_DARK_GREEN_OPACITY_30 = '--cow-color-cowamm-dark-green-opacity-30',
+  COLOR_COWAMM_DARK_GREEN_OPACITY_15 = '--cow-color-cowamm-dark-green-opacity-15',
   COLOR_COWAMM_GREEN = '--cow-color-cowamm-green',
   COLOR_COWAMM_LIGHT_GREEN = '--cow-color-cowamm-light-green',
   COLOR_COWAMM_LIGHT_GREEN_OPACITY_30 = '--cow-color-cowamm-light-green-opacity-30',
   COLOR_COWAMM_LIGHTER_GREEN = '--cow-color-cowamm-lighter-green',
   COLOR_COWAMM_BLUE = '--cow-color-cowamm-blue',
+  COLOR_COWAMM_DARK_BLUE = '--cow-color-cowamm-dark-blue',
   COLOR_COWAMM_LIGHT_BLUE = '--cow-color-cowamm-light-blue',
 
   // ================================================================================
diff --git a/libs/ui/src/theme/ThemeColorVars.tsx b/libs/ui/src/theme/ThemeColorVars.tsx
index 81a27134de..03acc39dcf 100644
--- a/libs/ui/src/theme/ThemeColorVars.tsx
+++ b/libs/ui/src/theme/ThemeColorVars.tsx
@@ -100,11 +100,13 @@ export const ThemeColorVars = css`
     // CoW AMM Colors
     ${UI.COLOR_COWAMM_DARK_GREEN}: #194d05;
     ${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_30}: ${() => transparentize('#194d05', 0.7)};
+    ${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_15}: ${() => transparentize('#194d05', 0.85)};
     ${UI.COLOR_COWAMM_GREEN}: #2b6f0b;
     ${UI.COLOR_COWAMM_LIGHT_GREEN}: #bcec79;
     ${UI.COLOR_COWAMM_LIGHT_GREEN_OPACITY_30}: ${() => transparentize('#bcec79', 0.7)};
     ${UI.COLOR_COWAMM_LIGHTER_GREEN}: #dcf8a7;
     ${UI.COLOR_COWAMM_BLUE}: #3fc4ff;
+    ${UI.COLOR_COWAMM_DARK_BLUE}: #012F7A;
     ${UI.COLOR_COWAMM_LIGHT_BLUE}: #ccf8ff;
 
     // Base

From 8b2dde26e0b87296e71f86712e55503d87f6d5f6 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Tue, 15 Oct 2024 16:43:58 +0100
Subject: [PATCH 09/15] feat: text fit optimisation

---
 .../common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx   |  6 +++---
 .../src/common/pure/CoWAMMBanner/styled.ts             | 10 +++++++++-
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
index 8103c4baa8..018ceb9b31 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
@@ -255,12 +255,12 @@ export function CoWAmmBannerContent({
           borderWidth={2}
           padding={'10px'}
           gap={'14px'}
-          height={'max-content'}
+          height={90}
         >
           {renderStarIcon({ size: 26, top: -16, right: 80, color: `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` })}
-          <h3>{renderTextfit(aprMessage, 'single', 24, 48, `apr-${selectedState}`)}</h3>
+          <h3>{renderTextfit(aprMessage, 'single', 35, 65, `apr-${selectedState}`)}</h3>
           <span>
-            {renderTextfit(comparisonMessage, 'multi', 12, isMobile ? 18 : 21, `comparison-${selectedState}`)}
+            {renderTextfit(comparisonMessage, 'multi', 15, isMobile ? 15 : 21, `comparison-${selectedState}`)}
           </span>
           {renderStarIcon({ size: 16, bottom: 3, right: 20, color: `var(${UI.COLOR_COWAMM_LIGHTER_GREEN})` })}
         </styledEl.Card>
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
index d8896bfe2b..165e249b33 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
@@ -169,9 +169,13 @@ export const PoolInfo = styled.div<{
   display: flex;
   align-items: ${({ align = 'flex-start' }) => align};
   flex-flow: ${({ flow = 'column' }) => flow};
-  font-size: 16px;
+  font-size: inherit;
   gap: 10px;
 
+  ${Media.upToSmall()} {
+    flex-flow: column wrap;
+  }
+
   > i {
     font-style: normal;
     background: ${({ bgColor }) => bgColor || `var(${UI.COLOR_COWAMM_LIGHT_BLUE})`};
@@ -184,6 +188,10 @@ export const PoolInfo = styled.div<{
     border-radius: 62px;
     width: min-content;
     box-shadow: var(${UI.BOX_SHADOW_2});
+
+    ${Media.upToSmall()} {
+      margin: 0 auto;
+    }
   }
 
   > i > div {

From ea742c87d916e5719c02213b04743965534170f4 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Wed, 16 Oct 2024 11:37:34 +0100
Subject: [PATCH 10/15] feat: do not show banners without connect wallet

---
 .../src/modules/application/containers/App/index.tsx         | 5 ++++-
 .../src/modules/tokensList/pure/TokensVirtualList/index.tsx  | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
index 8cdbbbbc57..83a1a3810a 100644
--- a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
+++ b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
@@ -3,6 +3,7 @@ import { lazy, PropsWithChildren, Suspense, useMemo } from 'react'
 import { useMediaQuery } from '@cowprotocol/common-hooks'
 import { isInjectedWidget } from '@cowprotocol/common-utils'
 import { Color, Footer, GlobalCoWDAOStyles, Media, MenuBar } from '@cowprotocol/ui'
+import { useWalletInfo } from '@cowprotocol/wallet'
 
 import { NavLink } from 'react-router-dom'
 import { ThemeProvider } from 'theme'
@@ -94,6 +95,8 @@ export function App() {
     </HeaderControls>
   )
 
+  const { account } = useWalletInfo()
+
   return (
     <ErrorBoundary>
       <Suspense fallback={<LoadingApp />}>
@@ -129,7 +132,7 @@ export function App() {
           )}
 
           {/* CoW AMM banner */}
-          {!isInjectedWidgetMode && <CoWAmmBanner location={BannerLocation.Global} />}
+          {!isInjectedWidgetMode && account && <CoWAmmBanner location={BannerLocation.Global} />}
 
           <styledEl.BodyWrapper>
             <TopLevelModals />
diff --git a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
index 33377421db..c1313c0e5d 100644
--- a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
+++ b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
@@ -1,6 +1,7 @@
 import { useCallback, useMemo, useRef } from 'react'
 
 import { TokenWithLogo } from '@cowprotocol/common-const'
+import { useWalletInfo } from '@cowprotocol/wallet'
 
 import { useVirtualizer } from '@tanstack/react-virtual'
 import ms from 'ms.macro'
@@ -35,6 +36,8 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
     props
   const { values: balances, isLoading: balancesLoading } = balancesState
 
+  const { account: connectedAccount } = useWalletInfo()
+
   const isWalletConnected = !!account
 
   const scrollTimeoutRef = useRef<NodeJS.Timeout>()
@@ -67,7 +70,7 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
 
   return (
     <CommonListContainer id="tokens-list" ref={parentRef} onScroll={onScroll}>
-      <CoWAmmBanner location={BannerLocation.TokenSelector} />
+      {connectedAccount && <CoWAmmBanner location={BannerLocation.TokenSelector} />}
       <styledEl.TokensInner ref={wrapperRef} style={{ height: virtualizer.getTotalSize() }}>
         <styledEl.TokensScroller style={{ transform: `translateY(${items[0]?.start ?? 0}px)` }}>
           {items.map((virtualRow) => {

From 608f3c0fb6a65451e2500369eb99e6345af391f3 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Wed, 16 Oct 2024 12:05:00 +0100
Subject: [PATCH 11/15] feat: add usdc scenario

---
 .../pure/CoWAMMBanner/CoWAmmBannerContent.tsx | 78 ++++++++++++-------
 .../src/common/pure/CoWAMMBanner/dummyData.ts | 30 ++++++-
 .../src/common/pure/CoWAMMBanner/index.tsx    |  1 +
 .../src/common/pure/CoWAMMBanner/styled.ts    |  9 ++-
 4 files changed, 85 insertions(+), 33 deletions(-)

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
index 018ceb9b31..0e23150f2d 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
@@ -23,7 +23,7 @@ import { BannerLocation, DEMO_DROPDOWN_OPTIONS } from './index'
 import { TokenLogo } from '../../../../../../libs/tokens/src/pure/TokenLogo'
 import { USDC, WBTC } from '@cowprotocol/common-const'
 import { SupportedChainId } from '@cowprotocol/cow-sdk'
-import { DummyDataType, TwoLpScenario } from './dummyData'
+import { DummyDataType, TwoLpScenario, InferiorYieldScenario } from './dummyData'
 
 const lpTokenIcons: Record<LpToken, string> = {
   [LpToken.UniswapV2]: ICON_UNISWAP,
@@ -50,6 +50,10 @@ function isTwoLpScenario(scenario: DummyDataType[keyof DummyDataType]): scenario
   return 'uniV2Apr' in scenario && 'sushiApr' in scenario
 }
 
+function isInferiorYieldScenario(scenario: DummyDataType[keyof DummyDataType]): scenario is InferiorYieldScenario {
+  return 'poolsCount' in scenario
+}
+
 const renderTextfit = (
   content: React.ReactNode,
   mode: 'single' | 'multi',
@@ -95,7 +99,15 @@ export function CoWAmmBannerContent({
 
   const { apr } = dummyData[selectedState]
 
-  const aprMessage = useMemo(() => `+${apr.toFixed(1)}%`, [apr])
+  const aprMessage = useMemo(() => {
+    if (selectedState === 'uniV2InferiorWithLowAverageYield') {
+      const currentData = dummyData[selectedState]
+      if (isInferiorYieldScenario(currentData)) {
+        return `${currentData.poolsCount}+`
+      }
+    }
+    return `+${apr.toFixed(1)}%`
+  }, [selectedState, apr, dummyData])
 
   const comparisonMessage = useMemo(() => {
     const currentData = dummyData[selectedState]
@@ -138,6 +150,10 @@ export function CoWAmmBannerContent({
       return renderPoolInfo('UNI-V2')
     }
 
+    if (selectedState === 'uniV2InferiorWithLowAverageYield' && isInferiorYieldScenario(currentData)) {
+      return 'pools available to get yield on your assets!'
+    }
+
     if (currentData.hasCoWAmmPool) {
       return `yield over average ${currentData.comparison} pool`
     } else {
@@ -165,30 +181,44 @@ export function CoWAmmBannerContent({
         return `yield over average UNI-V2 pool`
       }
     }
-  }, [selectedState, lpTokenConfig])
+  }, [selectedState, location, lpTokenConfig])
 
   const lpEmblems = useMemo(() => {
     const tokens = lpTokenConfig[selectedState]
     const totalItems = tokens.length
 
-    if (totalItems === 0) {
-      // Fallback to UniswapV2 emblem if no LP tokens
+    const renderEmblemContent = () => (
+      <>
+        <styledEl.EmblemArrow>
+          <SVG src={ICON_ARROW} />
+        </styledEl.EmblemArrow>
+        <styledEl.CoWAMMEmblemItem>
+          <ProductLogo
+            height={'100%'}
+            overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
+            variant={ProductVariant.CowAmm}
+            logoIconOnly
+          />
+        </styledEl.CoWAMMEmblemItem>
+      </>
+    )
+
+    if (totalItems === 0 || selectedState === 'uniV2InferiorWithLowAverageYield') {
       return (
         <styledEl.LpEmblems>
-          <styledEl.LpEmblemItem key={LpToken.UniswapV2} totalItems={1} index={0}>
-            <SVG src={lpTokenIcons[LpToken.UniswapV2]} />
+          <styledEl.LpEmblemItem
+            key="USDC"
+            totalItems={1}
+            index={0}
+            isUSDC={selectedState === 'uniV2InferiorWithLowAverageYield'}
+          >
+            {selectedState === 'uniV2InferiorWithLowAverageYield' ? (
+              <TokenLogo token={USDC[SupportedChainId.MAINNET]} size={40} />
+            ) : (
+              <SVG src={lpTokenIcons[LpToken.UniswapV2]} />
+            )}
           </styledEl.LpEmblemItem>
-          <styledEl.EmblemArrow>
-            <SVG src={ICON_ARROW} />
-          </styledEl.EmblemArrow>
-          <styledEl.CoWAMMEmblemItem>
-            <ProductLogo
-              height={'100%'}
-              overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
-              variant={ProductVariant.CowAmm}
-              logoIconOnly
-            />
-          </styledEl.CoWAMMEmblemItem>
+          {renderEmblemContent()}
         </styledEl.LpEmblems>
       )
     }
@@ -202,17 +232,7 @@ export function CoWAmmBannerContent({
             </styledEl.LpEmblemItem>
           ))}
         </styledEl.LpEmblemItemsWrapper>
-        <styledEl.EmblemArrow>
-          <SVG src={ICON_ARROW} />
-        </styledEl.EmblemArrow>
-        <styledEl.CoWAMMEmblemItem>
-          <ProductLogo
-            height={'100%'}
-            overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`}
-            variant={ProductVariant.CowAmm}
-            logoIconOnly
-          />
-        </styledEl.CoWAMMEmblemItem>
+        {renderEmblemContent()}
       </styledEl.LpEmblems>
     )
   }, [selectedState, lpTokenConfig, lpTokenIcons])
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
index 1a40e2de18..26492684f6 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/dummyData.ts
@@ -16,7 +16,25 @@ export type TwoLpScenario = BaseScenario & {
   readonly sushiApr: number
 }
 
-export const dummyData = {
+export type InferiorYieldScenario = BaseScenario & {
+  readonly poolsCount: number
+}
+
+export type DummyDataType = {
+  noLp: BaseScenario
+  uniV2Superior: BaseScenario
+  uniV2Inferior: BaseScenario
+  sushi: BaseScenario
+  curve: BaseScenario
+  pancake: BaseScenario & { readonly isYieldSuperior: boolean }
+  twoLpsMixed: TwoLpScenario
+  twoLpsBothSuperior: TwoLpScenario
+  threeLps: BaseScenario
+  fourLps: BaseScenario
+  uniV2InferiorWithLowAverageYield: InferiorYieldScenario
+}
+
+export const dummyData: DummyDataType = {
   noLp: {
     apr: 1.5,
     comparison: 'average UNI-V2 pool',
@@ -72,10 +90,15 @@ export const dummyData = {
     comparison: 'UNI-V2, SushiSwap, Curve, and PancakeSwap',
     hasCoWAmmPool: false,
   },
-} as const
+  uniV2InferiorWithLowAverageYield: {
+    apr: 1.2,
+    comparison: 'UNI-V2',
+    hasCoWAmmPool: true,
+    poolsCount: 195,
+  },
+}
 
 export type StateKey = keyof typeof dummyData
-export type DummyDataType = typeof dummyData
 
 export const lpTokenConfig: Record<StateKey, LpToken[]> = {
   noLp: [],
@@ -88,4 +111,5 @@ export const lpTokenConfig: Record<StateKey, LpToken[]> = {
   twoLpsBothSuperior: [LpToken.UniswapV2, LpToken.Sushiswap],
   threeLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve],
   fourLps: [LpToken.UniswapV2, LpToken.Sushiswap, LpToken.Curve, LpToken.PancakeSwap],
+  uniV2InferiorWithLowAverageYield: [LpToken.UniswapV2],
 }
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index fb65b7df8e..f100a2baf3 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -16,6 +16,7 @@ export const DEMO_DROPDOWN_OPTIONS = [
   { value: 'noLp', label: '🚫 No LP Tokens' },
   { value: 'uniV2Superior', label: '⬆️ 🐴 UNI-V2 LP (Superior Yield)' },
   { value: 'uniV2Inferior', label: '⬇️ 🐴 UNI-V2 LP (Inferior Yield)' },
+  { value: 'uniV2InferiorWithLowAverageYield', label: '⬇️ 🐴 UNI-V2 LP (Inferior Yield, Lower Average)' },
   { value: 'sushi', label: '⬇️ 🍣 SushiSwap LP (Inferior Yield)' },
   { value: 'curve', label: '⬇️ 🌈 Curve LP (Inferior Yield)' },
   { value: 'pancake', label: '⬇️ 🥞 PancakeSwap LP (Inferior Yield)' },
diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
index 165e249b33..ba9093db41 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/styled.ts
@@ -350,12 +350,14 @@ export const LpEmblemItemsWrapper = styled.div<{ totalItems: number }>`
 export const LpEmblemItem = styled.div<{
   totalItems: number
   index: number
+  isUSDC?: boolean
 }>`
   --size: ${({ totalItems }) =>
     totalItems === 4 ? '50px' : totalItems === 3 ? '65px' : totalItems === 2 ? '80px' : '104px'};
   width: var(--size);
   height: var(--size);
-  padding: ${({ totalItems }) => (totalItems === 4 ? '10px' : totalItems >= 2 ? '15px' : '20px')};
+  padding: ${({ totalItems, isUSDC }) =>
+    isUSDC ? '9px' : totalItems === 4 ? '10px' : totalItems >= 2 ? '15px' : '20px'};
   border-radius: 50%;
   background: var(${UI.COLOR_COWAMM_DARK_GREEN});
   color: var(${UI.COLOR_COWAMM_LIGHT_GREEN});
@@ -391,6 +393,11 @@ export const LpEmblemItem = styled.div<{
 
     return styleMap[totalItems]?.[index] || ''
   }}
+
+  ${TokenLogoWrapper} {
+    width: 100%;
+    height: 100%;
+  }
 `
 
 export const CoWAMMEmblemItem = styled.div`

From 9087316b0d3da0713a58df877e69d82ea38b00a5 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Fri, 18 Oct 2024 12:36:00 +0100
Subject: [PATCH 12/15] feat: modify CTA button text for SC wallets

---
 apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
index f100a2baf3..5f831b0ece 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/index.tsx
@@ -2,6 +2,7 @@ import { useAtom } from 'jotai'
 import { useCallback } from 'react'
 
 import { ClosableBanner } from '@cowprotocol/ui'
+import { useIsSmartContractWallet } from '@cowprotocol/wallet'
 
 import { cowAnalytics } from 'modules/analytics'
 
@@ -60,11 +61,13 @@ export function CoWAmmBanner({ location }: BannerProps) {
 
   const bannerId = `cow_amm_banner_2024_va_${location}`
 
+  const isSmartContractWallet = useIsSmartContractWallet()
+
   return ClosableBanner(bannerId, (close) => (
     <CoWAmmBannerContent
       id={bannerId}
       title="CoW AMM"
-      ctaText="Booooost APR gas-free!"
+      ctaText={isSmartContractWallet ? 'Booooost APR!' : 'Booooost APR gas-free!'}
       location={location}
       isDemo={IS_DEMO_MODE}
       selectedState={selectedState}

From cb108ccbf674509a3ef4471af537db8cd9639021 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Fri, 18 Oct 2024 14:02:55 +0100
Subject: [PATCH 13/15] feat: add dark mode styles for token selector banner

---
 .../pure/CoWAMMBanner/CoWAmmBannerContent.tsx | 24 +++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
index 0e23150f2d..2a2fd6d5dd 100644
--- a/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
+++ b/apps/cowswap-frontend/src/common/pure/CoWAMMBanner/CoWAmmBannerContent.tsx
@@ -121,10 +121,26 @@ export function CoWAmmBannerContent({
         flow={location === BannerLocation.TokenSelector ? 'row' : 'column'}
         align={location === BannerLocation.TokenSelector ? 'center' : 'flex-start'}
         bgColor={
-          location === BannerLocation.TokenSelector ? `var(${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_15})` : undefined
+          location === BannerLocation.TokenSelector
+            ? isDarkMode
+              ? `var(${UI.COLOR_COWAMM_LIGHT_BLUE})`
+              : `var(${UI.COLOR_COWAMM_DARK_GREEN_OPACITY_15})`
+            : undefined
+        }
+        color={
+          location === BannerLocation.TokenSelector
+            ? isDarkMode
+              ? `var(${UI.COLOR_COWAMM_DARK_BLUE})`
+              : `var(${UI.COLOR_COWAMM_DARK_GREEN})`
+            : undefined
+        }
+        tokenBorderColor={
+          location === BannerLocation.TokenSelector
+            ? isDarkMode
+              ? `var(${UI.COLOR_COWAMM_LIGHT_BLUE})`
+              : `var(${UI.COLOR_COWAMM_DARK_GREEN})`
+            : undefined
         }
-        color={location === BannerLocation.TokenSelector ? `var(${UI.COLOR_COWAMM_DARK_GREEN})` : undefined}
-        tokenBorderColor={location === BannerLocation.TokenSelector ? `var(${UI.COLOR_COWAMM_LIGHT_GREEN})` : undefined}
       >
         higher APR available for your {poolName} pool:
         <i>
@@ -181,7 +197,7 @@ export function CoWAmmBannerContent({
         return `yield over average UNI-V2 pool`
       }
     }
-  }, [selectedState, location, lpTokenConfig])
+  }, [selectedState, location, lpTokenConfig, isDarkMode])
 
   const lpEmblems = useMemo(() => {
     const tokens = lpTokenConfig[selectedState]

From 077667a04f946d84330e5ec68a9bf0a7a5cb8be7 Mon Sep 17 00:00:00 2001
From: fairlighteth <31534717+fairlighteth@users.noreply.github.com>
Date: Fri, 18 Oct 2024 14:20:40 +0100
Subject: [PATCH 14/15] feat: only show banners on supported networks

---
 .../src/modules/application/containers/App/index.tsx      | 6 +++++-
 .../modules/tokensList/pure/TokensVirtualList/index.tsx   | 8 +++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
index 83a1a3810a..3f157a846f 100644
--- a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
+++ b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
@@ -24,6 +24,7 @@ import { useInitializeUtm } from 'modules/utm'
 
 import { InvalidLocalTimeWarning } from 'common/containers/InvalidLocalTimeWarning'
 import { useCategorizeRecentActivity } from 'common/hooks/useCategorizeRecentActivity'
+import { useIsProviderNetworkUnsupported } from 'common/hooks/useIsProviderNetworkUnsupported'
 import { useMenuItems } from 'common/hooks/useMenuItems'
 import { BannerLocation, CoWAmmBanner } from 'common/pure/CoWAMMBanner'
 import { LoadingApp } from 'common/pure/LoadingApp'
@@ -96,6 +97,7 @@ export function App() {
   )
 
   const { account } = useWalletInfo()
+  const isChainIdUnsupported = useIsProviderNetworkUnsupported()
 
   return (
     <ErrorBoundary>
@@ -132,7 +134,9 @@ export function App() {
           )}
 
           {/* CoW AMM banner */}
-          {!isInjectedWidgetMode && account && <CoWAmmBanner location={BannerLocation.Global} />}
+          {!isInjectedWidgetMode && account && !isChainIdUnsupported && (
+            <CoWAmmBanner location={BannerLocation.Global} />
+          )}
 
           <styledEl.BodyWrapper>
             <TopLevelModals />
diff --git a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
index c1313c0e5d..1cb591f269 100644
--- a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
+++ b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
@@ -1,11 +1,13 @@
 import { useCallback, useMemo, useRef } from 'react'
 
 import { TokenWithLogo } from '@cowprotocol/common-const'
+import { isInjectedWidget } from '@cowprotocol/common-utils'
 import { useWalletInfo } from '@cowprotocol/wallet'
 
 import { useVirtualizer } from '@tanstack/react-virtual'
 import ms from 'ms.macro'
 
+import { useIsProviderNetworkUnsupported } from 'common/hooks/useIsProviderNetworkUnsupported'
 import { CoWAmmBanner, BannerLocation } from 'common/pure/CoWAMMBanner'
 
 import * as styledEl from './styled'
@@ -38,7 +40,9 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
 
   const { account: connectedAccount } = useWalletInfo()
 
+  const isInjectedWidgetMode = isInjectedWidget()
   const isWalletConnected = !!account
+  const isChainIdUnsupported = useIsProviderNetworkUnsupported()
 
   const scrollTimeoutRef = useRef<NodeJS.Timeout>()
   const parentRef = useRef<HTMLDivElement>(null)
@@ -70,7 +74,9 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
 
   return (
     <CommonListContainer id="tokens-list" ref={parentRef} onScroll={onScroll}>
-      {connectedAccount && <CoWAmmBanner location={BannerLocation.TokenSelector} />}
+      {!isInjectedWidgetMode && connectedAccount && !isChainIdUnsupported && (
+        <CoWAmmBanner location={BannerLocation.TokenSelector} />
+      )}
       <styledEl.TokensInner ref={wrapperRef} style={{ height: virtualizer.getTotalSize() }}>
         <styledEl.TokensScroller style={{ transform: `translateY(${items[0]?.start ?? 0}px)` }}>
           {items.map((virtualRow) => {

From ec81c0651dabbd7290998804487bb323673f4fe7 Mon Sep 17 00:00:00 2001
From: Alexandr Kazachenko <shoom3301@gmail.com>
Date: Wed, 23 Oct 2024 12:26:22 +0500
Subject: [PATCH 15/15] chore: temporarily hide cow amm banner

---
 .../application/containers/App/index.tsx        | 13 +++++--------
 .../tokensList/pure/TokensVirtualList/index.tsx | 17 +++++------------
 2 files changed, 10 insertions(+), 20 deletions(-)

diff --git a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
index a68e699e33..b8f9b4db77 100644
--- a/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
+++ b/apps/cowswap-frontend/src/modules/application/containers/App/index.tsx
@@ -3,7 +3,6 @@ import { lazy, PropsWithChildren, Suspense, useMemo } from 'react'
 import { useMediaQuery } from '@cowprotocol/common-hooks'
 import { isInjectedWidget } from '@cowprotocol/common-utils'
 import { Color, Footer, GlobalCoWDAOStyles, Media, MenuBar } from '@cowprotocol/ui'
-import { useWalletInfo } from '@cowprotocol/wallet'
 
 import { NavLink } from 'react-router-dom'
 import { ThemeProvider } from 'theme'
@@ -24,9 +23,7 @@ import { useInitializeUtm } from 'modules/utm'
 
 import { InvalidLocalTimeWarning } from 'common/containers/InvalidLocalTimeWarning'
 import { useCategorizeRecentActivity } from 'common/hooks/useCategorizeRecentActivity'
-import { useIsProviderNetworkUnsupported } from 'common/hooks/useIsProviderNetworkUnsupported'
 import { useMenuItems } from 'common/hooks/useMenuItems'
-import { BannerLocation, CoWAmmBanner } from 'common/pure/CoWAMMBanner'
 import { LoadingApp } from 'common/pure/LoadingApp'
 import { CoWDAOFonts } from 'common/styles/CoWDAOFonts'
 import RedirectAnySwapAffectedUsers from 'pages/error/AnySwapAffectedUsers/RedirectAnySwapAffectedUsers'
@@ -96,8 +93,8 @@ export function App() {
     </HeaderControls>
   )
 
-  const { account } = useWalletInfo()
-  const isChainIdUnsupported = useIsProviderNetworkUnsupported()
+  // const { account } = useWalletInfo()
+  // const isChainIdUnsupported = useIsProviderNetworkUnsupported()
 
   return (
     <ErrorBoundary>
@@ -134,9 +131,9 @@ export function App() {
           )}
 
           {/* CoW AMM banner */}
-          {!isInjectedWidgetMode && account && !isChainIdUnsupported && (
-            <CoWAmmBanner location={BannerLocation.Global} />
-          )}
+          {/*{!isInjectedWidgetMode && account && !isChainIdUnsupported && (*/}
+          {/*  <CoWAmmBanner location={BannerLocation.Global} />*/}
+          {/*)}*/}
 
           <styledEl.BodyWrapper>
             <TopLevelModals />
diff --git a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
index 1cb591f269..3637167df1 100644
--- a/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
+++ b/apps/cowswap-frontend/src/modules/tokensList/pure/TokensVirtualList/index.tsx
@@ -1,15 +1,10 @@
 import { useCallback, useMemo, useRef } from 'react'
 
 import { TokenWithLogo } from '@cowprotocol/common-const'
-import { isInjectedWidget } from '@cowprotocol/common-utils'
-import { useWalletInfo } from '@cowprotocol/wallet'
 
 import { useVirtualizer } from '@tanstack/react-virtual'
 import ms from 'ms.macro'
 
-import { useIsProviderNetworkUnsupported } from 'common/hooks/useIsProviderNetworkUnsupported'
-import { CoWAmmBanner, BannerLocation } from 'common/pure/CoWAMMBanner'
-
 import * as styledEl from './styled'
 
 import { SelectTokenContext } from '../../types'
@@ -38,11 +33,9 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
     props
   const { values: balances, isLoading: balancesLoading } = balancesState
 
-  const { account: connectedAccount } = useWalletInfo()
-
-  const isInjectedWidgetMode = isInjectedWidget()
   const isWalletConnected = !!account
-  const isChainIdUnsupported = useIsProviderNetworkUnsupported()
+  // const isInjectedWidgetMode = isInjectedWidget()
+  // const isChainIdUnsupported = useIsProviderNetworkUnsupported()
 
   const scrollTimeoutRef = useRef<NodeJS.Timeout>()
   const parentRef = useRef<HTMLDivElement>(null)
@@ -74,9 +67,9 @@ export function TokensVirtualList(props: TokensVirtualListProps) {
 
   return (
     <CommonListContainer id="tokens-list" ref={parentRef} onScroll={onScroll}>
-      {!isInjectedWidgetMode && connectedAccount && !isChainIdUnsupported && (
-        <CoWAmmBanner location={BannerLocation.TokenSelector} />
-      )}
+      {/*{!isInjectedWidgetMode && account && !isChainIdUnsupported && (*/}
+      {/*  <CoWAmmBanner location={BannerLocation.TokenSelector} />*/}
+      {/*)}*/}
       <styledEl.TokensInner ref={wrapperRef} style={{ height: virtualizer.getTotalSize() }}>
         <styledEl.TokensScroller style={{ transform: `translateY(${items[0]?.start ?? 0}px)` }}>
           {items.map((virtualRow) => {