diff --git a/public/icons/menu.svg b/public/icons/menu.svg
new file mode 100644
index 00000000..85e910be
--- /dev/null
+++ b/public/icons/menu.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/app/[ticker]/TickerInfo/TickerInfo.module.css b/src/app/[ticker]/TickerInfo/TickerInfo.module.css
index b7a1d3d7..b0694c3b 100644
--- a/src/app/[ticker]/TickerInfo/TickerInfo.module.css
+++ b/src/app/[ticker]/TickerInfo/TickerInfo.module.css
@@ -6,6 +6,7 @@
height: auto;
min-height: 100%;
}
+
.assetInfo {
display: flex;
justify-content: center;
@@ -146,3 +147,37 @@
font-weight: 600;
margin: 0;
}
+
+@media screen and (max-width: 600px) {
+ .container {
+ gap: 1rem;
+ }
+
+ .assetInfo {
+ gap: 10px;
+ }
+
+ .tickerTitle {
+ font-size: 20px;
+ }
+
+ .assetInfo img {
+ width: 34px;
+ height: 34px;
+ }
+
+ .actionButtons {
+ display: grid;
+ grid-template-columns: repeat(4, auto);
+ justify-content: stretch;
+ gap: 7px;
+ width: 100%;
+ }
+
+ .supplyButton,
+ .borrowButton,
+ .withdrawButton,
+ .repayButton {
+ min-width: unset;
+ }
+}
diff --git a/src/app/[ticker]/ticker.module.css b/src/app/[ticker]/ticker.module.css
index 0124273f..9b1ea0fc 100644
--- a/src/app/[ticker]/ticker.module.css
+++ b/src/app/[ticker]/ticker.module.css
@@ -91,6 +91,33 @@
width: 100%;
}
+@media screen and (max-width: 600px) {
+ .titleWrapper {
+ width: 90vw;
+ }
+
+ .title {
+ font-size: 20px;
+ }
+
+ .backIcon {
+ width: 20px;
+ height: 20px;
+ }
+
+ .topContainer {
+ width: 90vw;
+ flex-direction: column;
+ justify-content: unset;
+ gap: 1.6rem;
+ }
+
+ .grid {
+ grid-template-columns: auto;
+ width: 90vw;
+ }
+}
+
.modalOverlay {
position: fixed;
top: 0;
diff --git a/src/app/earn/earn.module.css b/src/app/earn/earn.module.css
index f77fd412..677fb8e3 100644
--- a/src/app/earn/earn.module.css
+++ b/src/app/earn/earn.module.css
@@ -88,6 +88,37 @@
gap: 25px;
}
+@media screen and (max-width: 600px) {
+ .bodyContainer {
+ width: 90vw;
+ padding: 2rem 0;
+ }
+
+ .topSection {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 1.25rem;
+ }
+
+ .titleContainer {
+ gap: 0;
+ }
+
+ .loBalanceContainer {
+ flex-direction: column-reverse;
+ }
+
+ .loTitle {
+ text-align: left;
+ }
+
+ .depositSection {
+ flex-direction: column;
+ justify-content: unset;
+ gap: 1rem;
+ }
+}
+
.assetSquareContainer {
position: relative;
display: flex;
diff --git a/src/app/home/ActionTab/ActionTab.tsx b/src/app/home/ActionTab/ActionTab.tsx
index 5b7b2829..10f487d6 100644
--- a/src/app/home/ActionTab/ActionTab.tsx
+++ b/src/app/home/ActionTab/ActionTab.tsx
@@ -34,17 +34,13 @@ const ActionTab: React.FC = ({ ticker, mode, onClose }) => {
const { data: walletBalance, isLoading: isLoadingBalance } =
useUserBalance(tokenAddress);
- const { data: aoBalance, isLoading: isLoadingAoBalance } = useUserBalance("0syT13r0s0tgPmIed95bJnuSqaD29HQNN8D3ElLSrsc");
- const hasAoForAction = useMemo(
- () => {
- if (isLoadingAoBalance) return true;
- return Quantity.lt(
- new Quantity(1n, 2n),
- new Quantity(aoBalance, 12n)
- );
- },
- [aoBalance, isLoadingAoBalance]
+ const { data: aoBalance, isLoading: isLoadingAoBalance } = useUserBalance(
+ "0syT13r0s0tgPmIed95bJnuSqaD29HQNN8D3ElLSrsc",
);
+ const hasAoForAction = useMemo(() => {
+ if (isLoadingAoBalance) return true;
+ return Quantity.lt(new Quantity(1n, 2n), new Quantity(aoBalance, 12n));
+ }, [aoBalance, isLoadingAoBalance]);
const { lend, isLending, lendError } = useLend({
onSuccess: onClose,
@@ -241,7 +237,8 @@ const ActionTab: React.FC = ({ ticker, mode, onClose }) => {
exit="hidden"
>
- You will need a minimal amount of AO for this message to be executed.
+ You will need a minimal amount of AO for this message to be
+ executed.
)}
diff --git a/src/app/home/AssetRow/AssetRow.module.css b/src/app/home/AssetRow/AssetRow.module.css
index 6d10a5eb..a8a5f41d 100644
--- a/src/app/home/AssetRow/AssetRow.module.css
+++ b/src/app/home/AssetRow/AssetRow.module.css
@@ -100,6 +100,20 @@
gap: 5px;
}
+@media screen and (max-width: 600px) {
+ .assetRow {
+ display: grid;
+ grid-template-columns: auto auto;
+ gap: 0.85rem 0;
+ }
+
+ .actionButtons {
+ grid-column: 1 / -1;
+ justify-content: flex-start;
+ padding-left: 52px;
+ }
+}
+
.supplyBorrowButton {
padding: 9px;
border-radius: 50px;
diff --git a/src/app/home/WithdrawRepay/WithdrawRepay.tsx b/src/app/home/WithdrawRepay/WithdrawRepay.tsx
index 3e888dce..f8ad56b1 100644
--- a/src/app/home/WithdrawRepay/WithdrawRepay.tsx
+++ b/src/app/home/WithdrawRepay/WithdrawRepay.tsx
@@ -14,7 +14,10 @@ import { tokenInput } from "liquidops";
import { useGetPosition } from "@/hooks/LiquidOpsData/useGetPosition";
import { useLoadingScreen } from "@/components/LoadingScreen/useLoadingScreen";
import { useValueLimit } from "@/hooks/data/useValueLimit";
-import { useInfo, useProtocolStats } from "@/hooks/LiquidOpsData/useProtocolStats";
+import {
+ useInfo,
+ useProtocolStats,
+} from "@/hooks/LiquidOpsData/useProtocolStats";
import { AnimatePresence, motion } from "framer-motion";
import { warningVariants } from "@/components/DropDown/FramerMotion";
import { useCooldown } from "@/hooks/data/useCooldown";
@@ -42,25 +45,21 @@ const WithdrawRepay: React.FC = ({
const { data: oTokenBalance, isLoading: isLoadingOTokenBalance } =
useUserBalance(oTokenAddress);
- const { data: aoBalance, isLoading: isLoadingAoBalance } = useUserBalance("0syT13r0s0tgPmIed95bJnuSqaD29HQNN8D3ElLSrsc");
- const hasAoForAction = useMemo(
- () => {
- if (isLoadingAoBalance) return true;
- return Quantity.lt(
- new Quantity(1n, 2n),
- new Quantity(aoBalance, 12n)
- );
- },
- [aoBalance, isLoadingAoBalance]
+ const { data: aoBalance, isLoading: isLoadingAoBalance } = useUserBalance(
+ "0syT13r0s0tgPmIed95bJnuSqaD29HQNN8D3ElLSrsc",
);
+ const hasAoForAction = useMemo(() => {
+ if (isLoadingAoBalance) return true;
+ return Quantity.lt(new Quantity(1n, 2n), new Quantity(aoBalance, 12n));
+ }, [aoBalance, isLoadingAoBalance]);
const currentBalance = useMemo(
- () => mode === "withdraw" ? lentBalance : positionBalance,
- [mode, lentBalance, positionBalance]
+ () => (mode === "withdraw" ? lentBalance : positionBalance),
+ [mode, lentBalance, positionBalance],
);
const isLoadingCurrentBalance = useMemo(
- () => mode === "withdraw" ? isLoadingBalance : isLoadingPosition,
- [mode, isLoadingBalance, isLoadingPosition]
+ () => (mode === "withdraw" ? isLoadingBalance : isLoadingPosition),
+ [mode, isLoadingBalance, isLoadingPosition],
);
const { unlend, isUnlending, unlendError } = useLend({
@@ -137,38 +136,40 @@ const WithdrawRepay: React.FC = ({
}
const amount = Quantity.__div(
- Quantity.__mul(currentBalance, new Quantity(0n, 12n).fromNumber(percentage)),
+ Quantity.__mul(
+ currentBalance,
+ new Quantity(0n, 12n).fromNumber(percentage),
+ ),
new Quantity(0n, 12n).fromNumber(100),
);
setInputValue(amount.toString());
};
- const currentPercentage = useMemo(
- () => {
- // no data
- if (
- !currentBalance ||
- !inputValue ||
- Quantity.eq(currentBalance, new Quantity(0n, 12n))
- ) {
- return 0;
- }
+ const currentPercentage = useMemo(() => {
+ // no data
+ if (
+ !currentBalance ||
+ !inputValue ||
+ Quantity.eq(currentBalance, new Quantity(0n, 12n))
+ ) {
+ return 0;
+ }
- if (isNaN(Number(inputValue.replace(/,/g, "")))) return 0;
+ if (isNaN(Number(inputValue.replace(/,/g, "")))) return 0;
- const percentage = Quantity.__div(
- Quantity.__mul(
- new Quantity(0n, currentBalance.denomination).fromString(inputValue),
- new Quantity(0n, currentBalance.denomination).fromNumber(100),
- ),
- currentBalance,
- );
- return Math.min(100, Math.max(0, percentage.toNumber()));
- },
- [currentBalance, inputValue]
- );
+ const percentage = Quantity.__div(
+ Quantity.__mul(
+ new Quantity(0n, currentBalance.denomination).fromString(inputValue),
+ new Quantity(0n, currentBalance.denomination).fromNumber(100),
+ ),
+ currentBalance,
+ );
+ return Math.min(100, Math.max(0, percentage.toNumber()));
+ }, [currentBalance, inputValue]);
- const { data: tokenInfo, isLoading: isLoadingTokenInfo } = useInfo(ticker.toUpperCase());
+ const { data: tokenInfo, isLoading: isLoadingTokenInfo } = useInfo(
+ ticker.toUpperCase(),
+ );
const handleSubmit = () => {
setHasUserInteracted(true);
@@ -191,13 +192,18 @@ const WithdrawRepay: React.FC = ({
// x _underlying_ = x * totalSupply / totalPooled _oToken_
const { collateralDenomination, denomination } = tokenInfo;
const totalPooled = new Quantity(
- BigInt(tokenInfo.cash) + BigInt(tokenInfo.totalBorrows) - BigInt(tokenInfo.totalReserves),
- BigInt(collateralDenomination)
+ BigInt(tokenInfo.cash) +
+ BigInt(tokenInfo.totalBorrows) -
+ BigInt(tokenInfo.totalReserves),
+ BigInt(collateralDenomination),
+ );
+ const totalSupply = new Quantity(
+ tokenInfo.totalSupply,
+ BigInt(denomination),
);
- const totalSupply = new Quantity(tokenInfo.totalSupply, BigInt(denomination));
quantity = Quantity.__convert(
Quantity.__div(Quantity.__mul(quantity, totalSupply), totalPooled),
- BigInt(denomination)
+ BigInt(denomination),
);
if (oTokenBalance) {
@@ -267,7 +273,8 @@ const WithdrawRepay: React.FC = ({
exit="hidden"
className={styles.aoNotice}
>
- You will need a minimal amount of AO for this message to be executed.
+ You will need a minimal amount of AO for this message to be
+ executed.
)}
diff --git a/src/app/home/home.module.css b/src/app/home/home.module.css
index 53b63b07..15bbbcc6 100644
--- a/src/app/home/home.module.css
+++ b/src/app/home/home.module.css
@@ -76,6 +76,17 @@
width: 100%;
}
+@media screen and (max-width: 600px) {
+ .grid {
+ width: 90vw;
+ grid-template-columns: 1fr;
+ }
+
+ .widgetContainer {
+ width: 90vw;
+ }
+}
+
.modalOverlay {
position: fixed;
top: 0;
diff --git a/src/app/markets/MarketRow/MarketRow.module.css b/src/app/markets/MarketRow/MarketRow.module.css
index fe39c932..f0678a54 100644
--- a/src/app/markets/MarketRow/MarketRow.module.css
+++ b/src/app/markets/MarketRow/MarketRow.module.css
@@ -29,6 +29,18 @@
flex-shrink: 0;
}
+@media screen and (max-width: 600px) {
+ .marketRow {
+ display: grid;
+ grid-template-columns: auto auto auto;
+ gap: 1rem;
+ }
+
+ .assetInfo {
+ grid-column: 1 / 4;
+ }
+}
+
.iconWrapper {
width: 40px;
height: 40px;
diff --git a/src/app/markets/MarketStats/MarketStats.module.css b/src/app/markets/MarketStats/MarketStats.module.css
index 8f7c84f9..dd9f8b42 100644
--- a/src/app/markets/MarketStats/MarketStats.module.css
+++ b/src/app/markets/MarketStats/MarketStats.module.css
@@ -15,6 +15,21 @@
border-radius: 24px;
}
+@media screen and (max-width: 600px) {
+ .marketStats {
+ flex-direction: column;
+ width: 90vw;
+ gap: 1rem;
+ }
+
+ .marketContainer {
+ width: 100%;
+ justify-content: flex-start;
+ gap: 30px;
+ padding: 24px 30px;
+ }
+}
+
.pieChart {
display: flex;
justify-content: center;
diff --git a/src/app/markets/markets.module.css b/src/app/markets/markets.module.css
index 25b2a08e..4fc28625 100644
--- a/src/app/markets/markets.module.css
+++ b/src/app/markets/markets.module.css
@@ -38,3 +38,11 @@
padding: 24px;
border-radius: 24px;
}
+
+@media screen and (max-width: 600px) {
+ .marketsList {
+ width: 90vw;
+ padding: 14px;
+ gap: 0.7rem;
+ }
+}
diff --git a/src/components/Connect/Connect.module.css b/src/components/Connect/Connect.module.css
index 8dc9f877..c2733331 100644
--- a/src/components/Connect/Connect.module.css
+++ b/src/components/Connect/Connect.module.css
@@ -41,6 +41,12 @@
color: var(--primary-palatinate-blue);
}
+@media screen and (max-width: 600px) {
+ .profileName {
+ display: none;
+ }
+}
+
.connectImage {
height: 32px;
width: 32px;
diff --git a/src/components/Footer/Footer.module.css b/src/components/Footer/Footer.module.css
index 9dd8608c..e95d62c8 100644
--- a/src/components/Footer/Footer.module.css
+++ b/src/components/Footer/Footer.module.css
@@ -15,6 +15,19 @@
gap: 10px;
}
+@media screen and (max-width: 600px) {
+ .footer {
+ padding: 20px 1.5rem;
+ align-items: flex-start;
+ }
+
+ .left {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 1rem;
+ }
+}
+
.right {
display: flex;
justify-content: center;
diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx
index d58aaf2c..a85be75c 100644
--- a/src/components/Footer/Footer.tsx
+++ b/src/components/Footer/Footer.tsx
@@ -66,20 +66,19 @@ const Footer = () => {
Analytics
-
+
+ Terms
+
+
+ Privacy
+
+
+ {gitHash}
+
diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css
index f8fbe04e..5cd04954 100644
--- a/src/components/Header/Header.module.css
+++ b/src/components/Header/Header.module.css
@@ -48,9 +48,9 @@
/* Existing header styles */
.header {
display: flex;
- justify-content: space-between;
align-items: flex-start;
- height: 150px;
+ flex-direction: column;
+ gap: 1.5rem;
padding: 2rem 3rem;
box-sizing: border-box;
width: 100%;
@@ -58,12 +58,23 @@
background-color: white;
}
-.leftSection {
+.topSection {
display: flex;
- height: 100%;
- flex-direction: column;
- align-items: flex-start;
+ align-items: center;
justify-content: space-between;
+ width: 100%;
+}
+
+.connectAndMobileMenu {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+.menuIcon {
+ display: none;
+ -webkit-tap-highlight-color: transparent;
+ cursor: pointer;
}
.titleAndDropdown {
@@ -93,6 +104,44 @@
gap: 1.5rem;
}
+@media screen and (max-width: 600px) {
+ .header {
+ padding: 1.6rem 1.8rem;
+ }
+
+ .menuIcon {
+ display: block;
+ }
+
+ .navLinks {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100vw;
+ height: 100vh;
+ z-index: 1000;
+ background-color: #fff;
+ flex-direction: column;
+ padding: 4rem;
+ }
+
+ .navLinks:not(.showNavMobile) {
+ display: none;
+ }
+
+ .navLinks a {
+ text-align: center;
+ }
+
+ .navLinks .menuIcon {
+ margin-left: auto;
+ width: 1.3rem;
+ height: 1.3rem;
+ }
+}
+
.navLinks a:hover {
background-color: var(--primary-ghost-white);
}
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
index 5ac4a2b8..af99f08a 100644
--- a/src/components/Header/Header.tsx
+++ b/src/components/Header/Header.tsx
@@ -69,6 +69,8 @@ const Header: React.FC
= ({
}
}, [triggerConnect]);
+ const [showNavMobile, setShowNavMobile] = useState(false);
+
return (
<>
{isClient && isBannerVisible && (
@@ -105,7 +107,7 @@ const Header: React.FC = ({