Skip to content

Commit 5effe5d

Browse files
sktbrdclaude
andauthored
fix(ui): bare chest trigger, and un-crop the embedded swap widget (#247)
Chest — the trigger was a rendered object sitting inside a bordered, gradient-filled rounded rectangle, which read as chrome around an icon rather than as the object itself. The plate, border and box-shadow are gone; the chest carries a drop shadow so it stays legible over light page content, and the "rewards ready" pulse became a soft radial behind it rather than a glowing rounded-rectangle outline, which would have drawn back the very box it was lighting. Swap — the widget's responsive layout was keyed to the viewport, so at 1440px it forced its three-column FROM | arrow | TO strip on even though the homepage embeds it in a 440px column. The strip needed 397px of a 368px box and the widget's own overflow-hidden sliced off the difference. It is `@container`-relative now: the columns come in at 42rem of container width, which /swap's 768px box clears and the homepage's does not. /swap renders identically at every width; the homepage stacks. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 9289a37 commit 5effe5d

2 files changed

Lines changed: 39 additions & 33 deletions

File tree

src/app/[locale]/swap/SwapWidget.tsx

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -715,12 +715,17 @@ export function SwapWidget() {
715715
: t("captions.enterAmount");
716716

717717
return (
718-
<div className="overflow-hidden bg-transparent">
719-
<div className="space-y-7 p-6 md:px-9 md:py-8">
718+
// `@container` makes the breakpoints below relative to this box rather
719+
// than the viewport. The widget is embedded in a 440px column on the
720+
// homepage, where a viewport-keyed `md:` still forced the three-column
721+
// strip on and overflowed it by 29px — which the overflow-hidden then
722+
// sliced off.
723+
<div className="@container overflow-hidden bg-transparent">
724+
<div className="space-y-7 p-6 @2xl:px-9 @2xl:py-8">
720725
{/* Editorial strip: FROM | arrow | TO */}
721-
<div className="grid grid-cols-1 items-end gap-y-7 md:grid-cols-[1fr_auto_1fr] md:gap-y-0">
726+
<div className="grid grid-cols-1 items-end gap-y-7 @2xl:grid-cols-[1fr_auto_1fr] @2xl:gap-y-0">
722727
{/* FROM */}
723-
<div className="md:border-r md:border-border md:pr-7">
728+
<div className="@2xl:border-r @2xl:border-border @2xl:pr-7">
724729
<div className="mb-2.5 flex items-center justify-between gap-2">
725730
<TokenPicker
726731
value={sellToken}
@@ -768,9 +773,9 @@ export function SwapWidget() {
768773
value={sellAmount}
769774
onChange={(e) => setSellAmount(e.target.value)}
770775
aria-label={t("from.sellAmount")}
771-
className="h-auto flex-1 border-0 bg-transparent p-0 text-[44px] font-thin leading-none tracking-[-2px] text-foreground shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0 placeholder:text-muted-foreground/30 md:text-[56px] md:tracking-[-3px] dark:bg-transparent [appearance:textfield] [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none"
776+
className="h-auto flex-1 border-0 bg-transparent p-0 text-[44px] font-thin leading-none tracking-[-2px] text-foreground shadow-none outline-none focus-visible:ring-0 focus-visible:ring-offset-0 placeholder:text-muted-foreground/30 @2xl:text-[56px] @2xl:tracking-[-3px] dark:bg-transparent [appearance:textfield] [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none"
772777
/>
773-
<span className="shrink-0 text-xl font-light tracking-tight text-muted-foreground/60 md:text-2xl">
778+
<span className="shrink-0 text-xl font-light tracking-tight text-muted-foreground/60 @2xl:text-2xl">
774779
{sellToken.symbol}
775780
</span>
776781
</div>
@@ -786,20 +791,20 @@ export function SwapWidget() {
786791
</div>
787792

788793
{/* CENTER — flip arrow with springy easing */}
789-
<div className="flex justify-center px-0 py-2 md:px-7 md:py-0">
794+
<div className="flex justify-center px-0 py-2 @2xl:px-7 @2xl:py-0">
790795
<button
791796
type="button"
792797
onClick={flip}
793798
aria-label={t("flipTokens")}
794799
className="group rounded-full p-2 text-muted-foreground transition-all duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] hover:rotate-180 hover:scale-110 hover:text-foreground motion-reduce:transition-none motion-reduce:hover:rotate-0 motion-reduce:hover:scale-100"
795800
>
796-
<ArrowRight className="hidden h-5 w-5 md:block" />
797-
<ArrowRight className="h-5 w-5 rotate-90 md:hidden" />
801+
<ArrowRight className="hidden h-5 w-5 @2xl:block" />
802+
<ArrowRight className="h-5 w-5 rotate-90 @2xl:hidden" />
798803
</button>
799804
</div>
800805

801806
{/* TO */}
802-
<div className="md:pl-7">
807+
<div className="@2xl:pl-7">
803808
<div className="mb-2.5 flex items-center justify-between gap-2">
804809
<TokenPicker
805810
value={buyToken}
@@ -829,7 +834,7 @@ export function SwapWidget() {
829834
)}
830835
</div>
831836
<div className="flex items-baseline gap-3 border-b border-border pb-2.5">
832-
<span className="flex-1 truncate text-[44px] font-thin leading-none tracking-[-2px] text-foreground/90 md:text-[56px] md:tracking-[-3px]">
837+
<span className="flex-1 truncate text-[44px] font-thin leading-none tracking-[-2px] text-foreground/90 @2xl:text-[56px] @2xl:tracking-[-3px]">
833838
{isFetching ? (
834839
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground/40" />
835840
) : (
@@ -842,7 +847,7 @@ export function SwapWidget() {
842847
</span>
843848
)}
844849
</span>
845-
<span className="shrink-0 text-xl font-light tracking-tight text-muted-foreground/60 md:text-2xl">
850+
<span className="shrink-0 text-xl font-light tracking-tight text-muted-foreground/60 @2xl:text-2xl">
846851
{buyToken.symbol}
847852
</span>
848853
</div>
@@ -858,14 +863,14 @@ export function SwapWidget() {
858863
<div className="h-px bg-border" />
859864

860865
{/* CTA + footer */}
861-
<div className="flex flex-col items-stretch gap-4 md:flex-row md:items-center">
862-
<div className="md:flex-shrink-0">
866+
<div className="flex flex-col items-stretch gap-4 @2xl:flex-row @2xl:items-center">
867+
<div className="@2xl:flex-shrink-0">
863868
{!isConnected ? (
864869
<Button
865870
variant="outline"
866871
size="lg"
867872
disabled
868-
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide md:w-auto"
873+
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide @2xl:w-auto"
869874
>
870875
{t("buttons.connectToSwap")}
871876
</Button>
@@ -874,7 +879,7 @@ export function SwapWidget() {
874879
size="lg"
875880
onClick={handleSwitchChain}
876881
disabled={isSwitchingChain}
877-
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide md:w-auto"
882+
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide @2xl:w-auto"
878883
>
879884
{isSwitchingChain
880885
? t("chain.switching")
@@ -885,7 +890,7 @@ export function SwapWidget() {
885890
size="lg"
886891
onClick={handleApprove}
887892
disabled={isApproving}
888-
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide md:w-auto"
893+
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide @2xl:w-auto"
889894
>
890895
{isApproving ? (
891896
<>
@@ -901,7 +906,7 @@ export function SwapWidget() {
901906
size="lg"
902907
onClick={handleSwap}
903908
disabled={!canSwap}
904-
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide md:w-auto"
909+
className="w-full rounded-full px-7 text-[13px] font-medium tracking-wide @2xl:w-auto"
905910
>
906911
{isSwapping ? (
907912
<>
@@ -917,7 +922,7 @@ export function SwapWidget() {
917922
)}
918923
</div>
919924

920-
<div className="hidden h-px flex-1 bg-border md:block" />
925+
<div className="hidden h-px flex-1 bg-border @2xl:block" />
921926

922927
{/* Fee opt-in */}
923928
<div className="flex items-center gap-2">

src/components/stake/MorLootbox.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -286,16 +286,16 @@ export function MorLootbox({
286286
<div className="fixed bottom-5 right-5 z-50">
287287
<Tooltip>
288288
<TooltipTrigger asChild>
289+
{/* No plate behind the chest — it is a rendered object with its own
290+
silhouette, and boxing it in a bordered rounded rectangle read as
291+
chrome around an icon rather than as the object itself. A drop
292+
shadow keeps it legible over light page content. */}
289293
<Link
290294
href="/stake"
291295
aria-label={t("lootbox.enableRewards")}
292-
className="relative flex h-14 w-14 cursor-pointer items-center justify-center rounded-2xl opacity-70 shadow-xl transition-opacity hover:opacity-100"
293-
style={{
294-
background: "linear-gradient(160deg,#123, #04140d)",
295-
border: `1px solid ${MOR_GREEN}33`,
296-
}}
296+
className="relative block cursor-pointer opacity-70 drop-shadow-[0_6px_14px_rgba(0,0,0,.55)] transition-opacity hover:opacity-100"
297297
>
298-
<ChestIcon size={44} />
298+
<ChestIcon size={60} />
299299
</Link>
300300
</TooltipTrigger>
301301
<TooltipContent side="left">{t("lootbox.enableRewards")}</TooltipContent>
@@ -341,25 +341,26 @@ export function MorLootbox({
341341
type="button"
342342
onClick={() => setOpen(true)}
343343
aria-label={t("lootbox.title")}
344-
className="relative flex h-16 w-16 cursor-pointer items-center justify-center rounded-2xl shadow-xl"
345-
style={{
346-
background: "linear-gradient(160deg,#123, #04140d)",
347-
border: `1px solid ${MOR_GREEN}55`,
348-
}}
344+
className="relative flex cursor-pointer items-center justify-center drop-shadow-[0_6px_14px_rgba(0,0,0,.55)]"
349345
animate={{ y: [0, -6, 0] }}
350346
transition={{ duration: 2.4, repeat: Infinity, ease: "easeInOut" }}
351347
whileHover={{ scale: 1.06 }}
352348
whileTap={{ scale: 0.94 }}
353349
>
350+
{/* The pulse is a soft radial behind the chest rather than a glowing
351+
rounded-rectangle outline — with the plate gone, a box-shadow on a
352+
rounded box would have drawn back the very rectangle it lit. */}
354353
<motion.span
355354
aria-hidden
356-
className="absolute inset-0 rounded-2xl"
357-
style={{ boxShadow: `0 0 24px 2px ${MOR_GREEN}` }}
355+
className="pointer-events-none absolute left-1/2 top-1/2 size-[112%] -translate-x-1/2 -translate-y-1/2 rounded-full"
356+
style={{
357+
background: `radial-gradient(circle, ${MOR_GREEN}55 0%, ${MOR_GREEN}00 68%)`,
358+
}}
358359
animate={{ opacity: [0.35, 0.8, 0.35] }}
359360
transition={{ duration: 2, repeat: Infinity, ease: "easeInOut" }}
360361
/>
361362
<span className="relative">
362-
<ChestIcon size={52} />
363+
<ChestIcon size={68} />
363364
</span>
364365
<span
365366
className="absolute -right-1.5 -top-1.5 flex min-w-5 items-center justify-center rounded-full px-1.5 text-[10px] font-black"

0 commit comments

Comments
 (0)