diff --git a/apps/web/src/components/ad-placeholder.tsx b/apps/web/src/components/ad-placeholder.tsx
new file mode 100644
index 0000000..7fabde3
--- /dev/null
+++ b/apps/web/src/components/ad-placeholder.tsx
@@ -0,0 +1,25 @@
+import { cn } from "@/lib/utils";
+
+interface AdPlaceholderProps {
+ width?: string;
+ height?: string;
+ label?: string;
+ className?: string;
+}
+
+export function AdPlaceholder({ width, height, label = "Ad", className }: AdPlaceholderProps) {
+ return (
+
+
+ Advertisement
+
+ {label}
+
+ );
+}
diff --git a/apps/web/src/components/house-ad.tsx b/apps/web/src/components/house-ad.tsx
new file mode 100644
index 0000000..162bc4f
--- /dev/null
+++ b/apps/web/src/components/house-ad.tsx
@@ -0,0 +1,153 @@
+import { useAuth } from "@/context/auth-context";
+import { cn } from "@/lib/utils";
+import { Link } from "@tanstack/react-router";
+import { Gift, TrendingDown, Trophy } from "lucide-react";
+
+interface HouseAdProps {
+ variant: "banner" | "tower";
+ className?: string;
+}
+
+export function HouseAd({ variant, className }: HouseAdProps) {
+ const { user, isPending } = useAuth();
+
+ if (isPending) {
+ return (
+
+ );
+ }
+
+ if (!user) {
+ return ;
+ }
+
+ return ;
+}
+
+function SignUpAd({ variant, className }: { variant: "banner" | "tower"; className?: string }) {
+ if (variant === "banner") {
+ return (
+
+
+
+
+
+
Play risk-free
+
Start with 1,000 free NoCoins
+
+
+ Sign up
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
Play risk-free
+
+ No real money.
+
+ Just the thrill of the game.
+
+
+
+
1,000
+
NoCoins on sign up
+
+
+ Create free account
+
+
No deposits ยท No risk
+
+ );
+}
+
+function LoggedInAd({ variant, className }: { variant: "banner" | "tower"; className?: string }) {
+ if (variant === "banner") {
+ return (
+
+
+
+
+
+
Rewards shop
+
Redeem your NoCoins for real prizes
+
+
+ Browse โ
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+
Rewards Shop
+
+ Trade your NoCoins for real prizes and discounts
+
+
+
+ Browse rewards
+
+
+
+
+
+
+
+
+
Your Stats
+
+ See how much you've avoided losing by not betting for real
+
+
+
+ View dashboard
+
+
+
+ );
+}
diff --git a/apps/web/src/routes/__root.tsx b/apps/web/src/routes/__root.tsx
index aeba0c6..88b4096 100644
--- a/apps/web/src/routes/__root.tsx
+++ b/apps/web/src/routes/__root.tsx
@@ -5,11 +5,11 @@ import { BetSlip } from "../components/betting/bet-slip";
import { BottomNav } from "../components/betting/bottom-nav";
import { SportsSidebar } from "../components/betting/sports-sidebar";
import { ErrorBoundary } from "../components/error-boundary";
+import { HouseAd } from "../components/house-ad";
import { Footer, Header } from "../components/layout";
import { Sheet, SheetContent } from "../components/ui/sheet";
import { ActiveSportProvider, useActiveSport } from "../context/active-sport-context";
-import { useAuth } from "../context/auth-context";
-import { AuthProvider } from "../context/auth-context";
+import { AuthProvider, useAuth } from "../context/auth-context";
import { BetSlipProvider, useBetSlip } from "../context/bet-slip-context";
function AppLayout() {
@@ -49,6 +49,12 @@ function AppLayout() {
/>
+ {/* [AD TOWER LEFT] xl only โ stays visible while main scrolls */}
+
+
+ {/* Desktop sports sidebar */}
+
+ {/* [AD TOWER RIGHT] xl only โ stays visible while main scrolls */}
+