Commit ·
e3df0d9
1
Parent(s): 56617fd
Polish classic matcha landing art
Browse files
src/app/c/[slug]/LandingClient.tsx
CHANGED
|
@@ -31,7 +31,7 @@ export function LandingClient({ slug, tableId, campaign }: Props) {
|
|
| 31 |
|
| 32 |
return (
|
| 33 |
<MobileShell>
|
| 34 |
-
<main className="relative flex
|
| 35 |
<div
|
| 36 |
className="pointer-events-none absolute inset-0"
|
| 37 |
style={{
|
|
@@ -40,8 +40,8 @@ export function LandingClient({ slug, tableId, campaign }: Props) {
|
|
| 40 |
}}
|
| 41 |
/>
|
| 42 |
|
| 43 |
-
<section className="relative flex flex-1 flex-col items-center px-7 pt-
|
| 44 |
-
<div className="mb-
|
| 45 |
<span className="h-px w-6 bg-[#5A523F]/55" aria-hidden />
|
| 46 |
{campaign.restaurantName}
|
| 47 |
<span className="h-px w-6 bg-[#5A523F]/55" aria-hidden />
|
|
@@ -49,17 +49,17 @@ export function LandingClient({ slug, tableId, campaign }: Props) {
|
|
| 49 |
|
| 50 |
<MatchaCircle />
|
| 51 |
|
| 52 |
-
<h1 className="text-display mt-
|
| 53 |
Free matcha,
|
| 54 |
<br />
|
| 55 |
<em className="text-[#4A5C32]">on the house</em>
|
| 56 |
</h1>
|
| 57 |
|
| 58 |
-
<p className="mx-auto mt-
|
| 59 |
Give us a quick guided video food review, get a free matcha.
|
| 60 |
</p>
|
| 61 |
|
| 62 |
-
<label className="mx-auto mt-
|
| 63 |
<input
|
| 64 |
type="checkbox"
|
| 65 |
checked={consentAccepted}
|
|
@@ -72,7 +72,7 @@ export function LandingClient({ slug, tableId, campaign }: Props) {
|
|
| 72 |
</label>
|
| 73 |
</section>
|
| 74 |
|
| 75 |
-
<footer className="relative px-7 pb-
|
| 76 |
<Button
|
| 77 |
onClick={handleStart}
|
| 78 |
disabled={!consentAccepted}
|
|
|
|
| 31 |
|
| 32 |
return (
|
| 33 |
<MobileShell>
|
| 34 |
+
<main className="relative flex h-dvh max-h-dvh flex-col overflow-hidden bg-[#EDE5D2] text-[#1B1A14]">
|
| 35 |
<div
|
| 36 |
className="pointer-events-none absolute inset-0"
|
| 37 |
style={{
|
|
|
|
| 40 |
}}
|
| 41 |
/>
|
| 42 |
|
| 43 |
+
<section className="relative flex min-h-0 flex-1 flex-col items-center px-7 pt-10 text-center [@media(max-height:720px)]:pt-6">
|
| 44 |
+
<div className="mb-5 flex items-center justify-center gap-3 font-serif text-[15px] italic text-[#5A523F] [@media(max-height:720px)]:mb-3">
|
| 45 |
<span className="h-px w-6 bg-[#5A523F]/55" aria-hidden />
|
| 46 |
{campaign.restaurantName}
|
| 47 |
<span className="h-px w-6 bg-[#5A523F]/55" aria-hidden />
|
|
|
|
| 49 |
|
| 50 |
<MatchaCircle />
|
| 51 |
|
| 52 |
+
<h1 className="text-display mt-5 text-[36px] text-[#1B1A14] [@media(max-height:720px)]:mt-3 [@media(max-height:720px)]:text-[32px]">
|
| 53 |
Free matcha,
|
| 54 |
<br />
|
| 55 |
<em className="text-[#4A5C32]">on the house</em>
|
| 56 |
</h1>
|
| 57 |
|
| 58 |
+
<p className="mx-auto mt-3 max-w-[294px] font-serif text-[14.5px] leading-[1.55] text-[#5A6E3F] [@media(max-height:720px)]:mt-2">
|
| 59 |
Give us a quick guided video food review, get a free matcha.
|
| 60 |
</p>
|
| 61 |
|
| 62 |
+
<label className="mx-auto mt-4 flex w-full max-w-[324px] cursor-pointer items-start gap-3 rounded-[14px] border border-[#78694B]/20 bg-[#F5EDD9] px-4 py-3.5 text-left shadow-[inset_0_1px_0_rgba(255,255,255,0.6)] [@media(max-height:720px)]:mt-3 [@media(max-height:720px)]:py-3">
|
| 63 |
<input
|
| 64 |
type="checkbox"
|
| 65 |
checked={consentAccepted}
|
|
|
|
| 72 |
</label>
|
| 73 |
</section>
|
| 74 |
|
| 75 |
+
<footer className="relative px-7 pb-5 pt-2 [@media(max-height:720px)]:pb-4">
|
| 76 |
<Button
|
| 77 |
onClick={handleStart}
|
| 78 |
disabled={!consentAccepted}
|
src/components/MatchaCircle.tsx
CHANGED
|
@@ -24,115 +24,213 @@ export function MatchaCircle() {
|
|
| 24 |
return (
|
| 25 |
<div
|
| 26 |
aria-hidden
|
| 27 |
-
className="mx-auto my-
|
| 28 |
style={{
|
| 29 |
width: 210,
|
| 30 |
-
height:
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
| 32 |
}}
|
| 33 |
>
|
| 34 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
<defs>
|
| 36 |
-
<linearGradient id="
|
| 37 |
-
<stop offset="0%" stopColor="
|
| 38 |
-
<stop offset="
|
| 39 |
-
<stop offset="100%" stopColor="
|
| 40 |
-
</linearGradient>
|
| 41 |
-
<radialGradient id="surfaceGlow" cx="42%" cy="35%" r="65%">
|
| 42 |
-
<stop offset="0%" stopColor="rgba(190,215,130,0.55)" />
|
| 43 |
-
<stop offset="100%" stopColor="rgba(190,215,130,0)" />
|
| 44 |
-
</radialGradient>
|
| 45 |
-
<linearGradient id="ceramicBody" x1="0%" y1="0%" x2="100%" y2="0%">
|
| 46 |
-
<stop offset="0%" stopColor="#F0E5C8" />
|
| 47 |
-
<stop offset="20%" stopColor="#EADDB8" />
|
| 48 |
-
<stop offset="55%" stopColor="#D9C89C" />
|
| 49 |
-
<stop offset="85%" stopColor="#B89F75" />
|
| 50 |
-
<stop offset="100%" stopColor="#9C8559" />
|
| 51 |
</linearGradient>
|
| 52 |
-
<filter id="
|
| 53 |
-
<
|
| 54 |
-
<feColorMatrix
|
| 55 |
-
values="0 0 0 0 0.45
|
| 56 |
-
0 0 0 0 0.55
|
| 57 |
-
0 0 0 0 0.25
|
| 58 |
-
0 0 0 0.18 0"
|
| 59 |
-
/>
|
| 60 |
-
<feComposite in2="SourceGraphic" operator="in" />
|
| 61 |
</filter>
|
| 62 |
-
<clipPath id="liquidClip">
|
| 63 |
-
<ellipse cx="100" cy="62" rx="64" ry="14" />
|
| 64 |
-
</clipPath>
|
| 65 |
</defs>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
-
|
| 78 |
-
d="M 36 60 C 30 90, 38 130, 70 158 L 130 158 C 162 130, 170 90, 164 60 A 64 14 0 0 1 36 60 Z"
|
| 79 |
-
fill="url(#ceramicBody)"
|
| 80 |
-
/>
|
| 81 |
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
|
|
|
| 88 |
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
stroke="rgba(80,55,30,0.5)"
|
| 101 |
-
strokeWidth="0.9"
|
| 102 |
-
/>
|
| 103 |
-
<ellipse cx="100" cy="61" rx="60" ry="12" fill="#3F5226" />
|
| 104 |
-
<ellipse cx="100" cy="62" rx="60" ry="12" fill="url(#matchaSurface)" />
|
| 105 |
-
<ellipse
|
| 106 |
-
cx="100"
|
| 107 |
-
cy="62"
|
| 108 |
-
rx="60"
|
| 109 |
-
ry="12"
|
| 110 |
-
fill="url(#matchaSurface)"
|
| 111 |
-
filter="url(#grain)"
|
| 112 |
-
opacity="0.55"
|
| 113 |
-
clipPath="url(#liquidClip)"
|
| 114 |
-
/>
|
| 115 |
-
<ellipse cx="100" cy="62" rx="60" ry="12" fill="url(#surfaceGlow)" />
|
| 116 |
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
</div>
|
| 137 |
);
|
| 138 |
}
|
|
|
|
| 24 |
return (
|
| 25 |
<div
|
| 26 |
aria-hidden
|
| 27 |
+
className="mx-auto my-2"
|
| 28 |
style={{
|
| 29 |
width: 210,
|
| 30 |
+
height: 283.5,
|
| 31 |
+
position: 'relative',
|
| 32 |
+
display: 'flex',
|
| 33 |
+
alignItems: 'flex-end',
|
| 34 |
+
justifyContent: 'center',
|
| 35 |
}}
|
| 36 |
>
|
| 37 |
+
<div
|
| 38 |
+
style={{
|
| 39 |
+
position: 'absolute',
|
| 40 |
+
left: '50%',
|
| 41 |
+
top: '40%',
|
| 42 |
+
width: 231,
|
| 43 |
+
height: 189,
|
| 44 |
+
transform: 'translate(-50%, -50%)',
|
| 45 |
+
background:
|
| 46 |
+
'radial-gradient(ellipse at center, rgba(232,180,110,0.32) 0%, rgba(232,180,110,0.12) 35%, rgba(232,180,110,0) 70%)',
|
| 47 |
+
filter: 'blur(2px)',
|
| 48 |
+
pointerEvents: 'none',
|
| 49 |
+
animation: 'warmthPulse 6s ease-in-out infinite',
|
| 50 |
+
}}
|
| 51 |
+
/>
|
| 52 |
+
|
| 53 |
+
<svg
|
| 54 |
+
width="147"
|
| 55 |
+
height="136.5"
|
| 56 |
+
viewBox="0 0 120 110"
|
| 57 |
+
style={{
|
| 58 |
+
position: 'absolute',
|
| 59 |
+
left: '50%',
|
| 60 |
+
top: -10,
|
| 61 |
+
transform: 'translateX(-50%)',
|
| 62 |
+
pointerEvents: 'none',
|
| 63 |
+
opacity: 1,
|
| 64 |
+
}}
|
| 65 |
+
>
|
| 66 |
<defs>
|
| 67 |
+
<linearGradient id="steamFade" x1="0%" y1="0%" x2="0%" y2="100%">
|
| 68 |
+
<stop offset="0%" stopColor="rgba(120,100,70,0)" />
|
| 69 |
+
<stop offset="35%" stopColor="rgba(120,100,70,0.85)" />
|
| 70 |
+
<stop offset="100%" stopColor="rgba(120,100,70,0.0)" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
</linearGradient>
|
| 72 |
+
<filter id="steamBlur">
|
| 73 |
+
<feGaussianBlur stdDeviation="0.8" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
</filter>
|
|
|
|
|
|
|
|
|
|
| 75 |
</defs>
|
| 76 |
+
<g filter="url(#steamBlur)">
|
| 77 |
+
<path
|
| 78 |
+
className="steam-wisp s1"
|
| 79 |
+
d="M 50 105 C 44 88, 56 76, 50 60 C 44 44, 56 30, 52 14"
|
| 80 |
+
fill="none"
|
| 81 |
+
stroke="url(#steamFade)"
|
| 82 |
+
strokeLinecap="round"
|
| 83 |
+
strokeWidth="4"
|
| 84 |
+
/>
|
| 85 |
+
<path
|
| 86 |
+
className="steam-wisp s2"
|
| 87 |
+
d="M 64 105 C 70 86, 58 72, 66 56 C 74 40, 62 24, 70 8"
|
| 88 |
+
fill="none"
|
| 89 |
+
stroke="url(#steamFade)"
|
| 90 |
+
strokeLinecap="round"
|
| 91 |
+
strokeWidth="3.4"
|
| 92 |
+
/>
|
| 93 |
+
<path
|
| 94 |
+
className="steam-wisp s3"
|
| 95 |
+
d="M 76 105 C 80 90, 70 78, 78 62 C 84 50, 76 36, 82 22"
|
| 96 |
+
fill="none"
|
| 97 |
+
stroke="url(#steamFade)"
|
| 98 |
+
strokeLinecap="round"
|
| 99 |
+
strokeWidth="3"
|
| 100 |
+
/>
|
| 101 |
+
</g>
|
| 102 |
+
</svg>
|
| 103 |
|
| 104 |
+
<style>{`
|
| 105 |
+
@keyframes warmthPulse {
|
| 106 |
+
0%, 100% { opacity: 0.7; transform: translate(-50%, -50%) scale(1); }
|
| 107 |
+
50% { opacity: 1; transform: translate(-50%, -50%) scale(1.06); }
|
| 108 |
+
}
|
| 109 |
+
@keyframes steamRise {
|
| 110 |
+
0% { transform: translateY(8px) translateX(0px); opacity: 0; }
|
| 111 |
+
15% { opacity: 0.9; }
|
| 112 |
+
70% { opacity: 0.6; }
|
| 113 |
+
100% { transform: translateY(-14px) translateX(2px); opacity: 0; }
|
| 114 |
+
}
|
| 115 |
+
.steam-wisp {
|
| 116 |
+
transform-origin: 50% 100%;
|
| 117 |
+
animation: steamRise 4.2s ease-in-out infinite;
|
| 118 |
+
}
|
| 119 |
+
.steam-wisp.s1 { animation-delay: 0s; }
|
| 120 |
+
.steam-wisp.s2 { animation-delay: 1.2s; animation-duration: 4.6s; }
|
| 121 |
+
.steam-wisp.s3 { animation-delay: 2.3s; animation-duration: 3.8s; }
|
| 122 |
+
`}</style>
|
| 123 |
|
| 124 |
+
<div
|
| 125 |
+
style={{
|
| 126 |
+
width: 210,
|
| 127 |
+
height: 199.5,
|
| 128 |
+
filter: 'drop-shadow(0 8px 14px rgba(50,60,25,0.18))',
|
| 129 |
+
}}
|
| 130 |
+
>
|
| 131 |
+
<svg width="210" height="199.5" viewBox="0 0 200 190" className="block">
|
| 132 |
+
<defs>
|
| 133 |
+
<linearGradient id="matchaSurface" x1="0%" y1="0%" x2="0%" y2="100%">
|
| 134 |
+
<stop offset="0%" stopColor="#7A9242" />
|
| 135 |
+
<stop offset="40%" stopColor="#9BB75A" />
|
| 136 |
+
<stop offset="100%" stopColor="#82A047" />
|
| 137 |
+
</linearGradient>
|
| 138 |
+
<radialGradient id="surfaceGlow" cx="42%" cy="35%" r="65%">
|
| 139 |
+
<stop offset="0%" stopColor="rgba(190,215,130,0.55)" />
|
| 140 |
+
<stop offset="100%" stopColor="rgba(190,215,130,0)" />
|
| 141 |
+
</radialGradient>
|
| 142 |
+
<linearGradient id="ceramicBody" x1="0%" y1="0%" x2="100%" y2="0%">
|
| 143 |
+
<stop offset="0%" stopColor="#F0E5C8" />
|
| 144 |
+
<stop offset="20%" stopColor="#EADDB8" />
|
| 145 |
+
<stop offset="55%" stopColor="#D9C89C" />
|
| 146 |
+
<stop offset="85%" stopColor="#B89F75" />
|
| 147 |
+
<stop offset="100%" stopColor="#9C8559" />
|
| 148 |
+
</linearGradient>
|
| 149 |
+
<filter id="grain">
|
| 150 |
+
<feTurbulence type="fractalNoise" baseFrequency="2.4" numOctaves="2" seed="7" />
|
| 151 |
+
<feColorMatrix
|
| 152 |
+
values="0 0 0 0 0.45
|
| 153 |
+
0 0 0 0 0.55
|
| 154 |
+
0 0 0 0 0.25
|
| 155 |
+
0 0 0 0.18 0"
|
| 156 |
+
/>
|
| 157 |
+
<feComposite in2="SourceGraphic" operator="in" />
|
| 158 |
+
</filter>
|
| 159 |
+
<clipPath id="liquidClip">
|
| 160 |
+
<ellipse cx="100" cy="62" rx="64" ry="14" />
|
| 161 |
+
</clipPath>
|
| 162 |
+
</defs>
|
| 163 |
|
| 164 |
+
<ellipse cx="100" cy="178" rx="62" ry="4" fill="rgba(50,55,25,0.18)" />
|
|
|
|
|
|
|
|
|
|
| 165 |
|
| 166 |
+
<path
|
| 167 |
+
d="M 158 72 C 196 76, 198 132, 148 132 L 148 124 C 184 124, 184 84, 158 80 Z"
|
| 168 |
+
fill="url(#ceramicBody)"
|
| 169 |
+
stroke="rgba(80,55,30,0.45)"
|
| 170 |
+
strokeLinejoin="round"
|
| 171 |
+
strokeWidth="0.8"
|
| 172 |
+
/>
|
| 173 |
|
| 174 |
+
<path
|
| 175 |
+
d="M 36 60 C 30 90, 38 130, 70 158 L 130 158 C 162 130, 170 90, 164 60 A 64 14 0 0 1 36 60 Z"
|
| 176 |
+
fill="url(#ceramicBody)"
|
| 177 |
+
/>
|
| 178 |
|
| 179 |
+
<g opacity="0.18" stroke="rgba(80,55,30,1)" strokeWidth="0.6" fill="none">
|
| 180 |
+
<path d="M 50 70 Q 46 110, 64 152" />
|
| 181 |
+
<path d="M 70 64 Q 66 110, 78 156" />
|
| 182 |
+
<path d="M 130 64 Q 134 110, 122 156" />
|
| 183 |
+
<path d="M 150 70 Q 154 110, 136 152" />
|
| 184 |
+
</g>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
|
| 186 |
+
<path
|
| 187 |
+
d="M 38 64 C 32 92, 39 130, 66 156 L 76 156 C 54 130, 47 95, 50 66 Z"
|
| 188 |
+
fill="rgba(255,250,225,0.35)"
|
| 189 |
+
/>
|
| 190 |
|
| 191 |
+
<ellipse
|
| 192 |
+
cx="100"
|
| 193 |
+
cy="60"
|
| 194 |
+
rx="64"
|
| 195 |
+
ry="14"
|
| 196 |
+
fill="#E8DBB6"
|
| 197 |
+
stroke="rgba(80,55,30,0.5)"
|
| 198 |
+
strokeWidth="0.9"
|
| 199 |
+
/>
|
| 200 |
+
<ellipse cx="100" cy="61" rx="60" ry="12" fill="#3F5226" />
|
| 201 |
+
<ellipse cx="100" cy="62" rx="60" ry="12" fill="url(#matchaSurface)" />
|
| 202 |
+
<ellipse
|
| 203 |
+
cx="100"
|
| 204 |
+
cy="62"
|
| 205 |
+
rx="60"
|
| 206 |
+
ry="12"
|
| 207 |
+
fill="url(#matchaSurface)"
|
| 208 |
+
filter="url(#grain)"
|
| 209 |
+
opacity="0.55"
|
| 210 |
+
clipPath="url(#liquidClip)"
|
| 211 |
+
/>
|
| 212 |
+
<ellipse cx="100" cy="62" rx="60" ry="12" fill="url(#surfaceGlow)" />
|
| 213 |
|
| 214 |
+
<path
|
| 215 |
+
d="M 40 60 A 60 12 0 0 1 160 60 L 160 64 A 60 9 0 0 0 40 64 Z"
|
| 216 |
+
fill="rgba(40,55,20,0.35)"
|
| 217 |
+
/>
|
| 218 |
+
|
| 219 |
+
<g clipPath="url(#liquidClip)">
|
| 220 |
+
{foamBubbles.map(([x, y, r], index) => (
|
| 221 |
+
<circle key={index} cx={x} cy={y} r={r} fill="rgba(240,245,210,0.9)" />
|
| 222 |
+
))}
|
| 223 |
+
</g>
|
| 224 |
+
|
| 225 |
+
<path
|
| 226 |
+
d="M 78 62 Q 88 56 100 62 T 122 62"
|
| 227 |
+
fill="none"
|
| 228 |
+
stroke="rgba(245,250,215,0.95)"
|
| 229 |
+
strokeLinecap="round"
|
| 230 |
+
strokeWidth="2.4"
|
| 231 |
+
/>
|
| 232 |
+
</svg>
|
| 233 |
+
</div>
|
| 234 |
</div>
|
| 235 |
);
|
| 236 |
}
|