feat: add root page design

* feat: add options/map flow, dev seed, and artwork fixes

Options page, Kakao map with florist order message, dev tooling, and
create/message dummy gating — without secrets in .env.example.

Co-authored-by: Cursor <cursoragent@cursor.com>

* with generating page + art work

* with flower images

* with route page

* route page loop

---------

Co-authored-by: 이지은 <ijieun@ijieun-ui-MacBookPro.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Chaewon Lee
2026-06-14 17:16:14 +09:00
committed by GitHub
parent 10881ded29
commit 4b27c82036
10 changed files with 348 additions and 11 deletions

165
package-lock.json generated
View File

@@ -10,7 +10,8 @@
"dependencies": {
"@google/generative-ai": "^0.24.1",
"@supabase/supabase-js": "^2.108.1",
"openai": "^6.42.0"
"openai": "^6.42.0",
"p5": "^2.3.0"
},
"devDependencies": {
"@eslint/compat": "^2.0.4",
@@ -32,6 +33,21 @@
"vite": "^8.0.7"
}
},
"node_modules/@babel/runtime": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
"integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@davepagurek/bezier-path": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/@davepagurek/bezier-path/-/bezier-path-0.0.7.tgz",
"integrity": "sha512-CVlnCOrV1iy4Z12T756i9l4G6kF7r8uhlnb+xqDemAMmWQB+8Q0b+8VEqIiUfywgZDSiDr18Rm7pZlnA69rE8Q==",
"license": "MIT"
},
"node_modules/@emnapi/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
@@ -290,6 +306,12 @@
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@japont/unicode-range": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@japont/unicode-range/-/unicode-range-1.0.0.tgz",
"integrity": "sha512-BckHvA2XdjRBVAWe2uceNuRf78lBeI28kyWEbfr/Q2pE17POkwuZ6WWY/UMv8FL9iBxhW4xfDoNLM9UVZaTeUQ==",
"license": "MIT"
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -1145,7 +1167,6 @@
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -1164,6 +1185,18 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/acorn-walk": {
"version": "8.3.5",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
"integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
"license": "MIT",
"dependencies": {
"acorn": "^8.11.0"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/ajv": {
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
@@ -1234,6 +1267,16 @@
"node": ">=6"
}
},
"node_modules/colorjs.io": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.6.1.tgz",
"integrity": "sha512-8lyR2wHzuIykCpqHKgluGsqQi5iDm3/a2IgP2GBZrasn2sBRkE4NOGsglZxWLs/jZQoNkmA/KM/8NV16rLUdBg==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/color"
}
},
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
@@ -1351,6 +1394,27 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/escodegen": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
"integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
"license": "BSD-2-Clause",
"dependencies": {
"esprima": "^4.0.1",
"estraverse": "^5.2.0",
"esutils": "^2.0.2"
},
"bin": {
"escodegen": "bin/escodegen.js",
"esgenerate": "bin/esgenerate.js"
},
"engines": {
"node": ">=6.0"
},
"optionalDependencies": {
"source-map": "~0.6.1"
}
},
"node_modules/eslint": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.1.tgz",
@@ -1527,6 +1591,19 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/esquery": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
@@ -1575,7 +1652,6 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -1585,7 +1661,6 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
@@ -1696,6 +1771,12 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/gifenc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/gifenc/-/gifenc-1.0.3.tgz",
"integrity": "sha512-xdr6AdrfGBcfzncONUOlXMBuc5wJDtOueE3c5rdG0oNgtINLD+f2iFZltrBRZYzACRbKr+mSVU/x98zv2u3jmw==",
"license": "MIT"
},
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -1729,6 +1810,24 @@
"dev": true,
"license": "ISC"
},
"node_modules/i18next": {
"version": "19.9.2",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-19.9.2.tgz",
"integrity": "sha512-0i6cuo6ER6usEOtKajUUDj92zlG+KArFia0857xxiEHAQcUwh/RtOQocui1LPJwunSYT574Pk64aNva1kwtxZg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.0"
}
},
"node_modules/i18next-browser-languagedetector": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-4.3.1.tgz",
"integrity": "sha512-KIToAzf8zwWvacgnRwJp63ase26o24AuNUlfNVJ5YZAFmdGhsJpmFClxXPuk9rv1FMI4lnc8zLSqgZPEZMrW4g==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.5.5"
}
},
"node_modules/iceberg-js": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz",
@@ -1870,6 +1969,12 @@
"node": ">= 0.8.0"
}
},
"node_modules/libtess": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/libtess/-/libtess-1.2.2.tgz",
"integrity": "sha512-Nps8HPeVVcsmJxUvFLKVJcCgcz+1ajPTXDVAVPs6+giOQP4AHV31uZFFkh+CKow/bkB7GbZWKmwmit7myaqDSw==",
"license": "SGI-B-2.0"
},
"node_modules/lightningcss": {
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
@@ -2244,6 +2349,12 @@
],
"license": "MIT"
},
"node_modules/omggif": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",
"integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==",
"license": "MIT"
},
"node_modules/openai": {
"version": "6.42.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-6.42.0.tgz",
@@ -2312,6 +2423,33 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p5": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p5/-/p5-2.3.0.tgz",
"integrity": "sha512-akBaN7KbLo5Y6fQ6xJ3w5KKVSfkHGLmqxkJZ7IwZkKw7QlEuVFlLuFTkx9/5o8AAyuJttzucXh7aWk2natRNMA==",
"license": "LGPL-2.1",
"dependencies": {
"@davepagurek/bezier-path": "^0.0.7",
"@japont/unicode-range": "^1.0.0",
"acorn": "^8.15.0",
"acorn-walk": "^8.3.4",
"colorjs.io": "^0.6.0",
"escodegen": "^2.1.0",
"gifenc": "^1.0.3",
"i18next": "^19.0.2",
"i18next-browser-languagedetector": "^4.0.1",
"libtess": "^1.2.2",
"omggif": "^1.0.10",
"pako": "^2.1.0",
"zod": "^4.2.1"
}
},
"node_modules/pako": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
"license": "(MIT AND Zlib)"
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -2707,6 +2845,16 @@
"node": ">=18"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -3076,6 +3224,15 @@
"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
"dev": true,
"license": "MIT"
},
"node_modules/zod": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}

View File

@@ -34,6 +34,7 @@
"dependencies": {
"@google/generative-ai": "^0.24.1",
"@supabase/supabase-js": "^2.108.1",
"openai": "^6.42.0"
"openai": "^6.42.0",
"p5": "^2.3.0"
}
}

View File

@@ -0,0 +1,34 @@
<svg width="200" height="250" viewBox="0 0 200 250" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M150 72.0007C144.216 64.4808 145.933 54.7827 154.012 48.1699C159.236 56.5188 157.52 66.2169 150 72.0007Z" fill="#38322F"/>
<path d="M58 99.9998C50.0105 104.17 41.2205 100.965 36.3665 92.3152C45.0394 88.8046 53.8294 92.0104 58 99.9998Z" fill="#38322F"/>
<path d="M150 127.999C148.876 119.535 154.578 112.749 163.851 111.23C164.166 120.089 158.464 126.875 150 127.999Z" fill="#38322F"/>
<path d="M82 88C86 122 100 150 105 170" stroke="#38322F" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M124 98C123 130 110 156 105 170" stroke="#38322F" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M100 122C101 142 104 158 105 170" stroke="#38322F" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M104 184C100 202 95 216 90 232" stroke="#38322F" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M105 184L104 234" stroke="#38322F" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M106 184C110 202 115 214 120 230" stroke="#38322F" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M103 184C100 200 99 212 99 226" stroke="#38322F" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M82 70.8475C86.5774 70.8475 90.288 67.1368 90.288 62.5595C90.288 57.9821 86.5774 54.2715 82 54.2715C77.4227 54.2715 73.712 57.9821 73.712 62.5595C73.712 67.1368 77.4227 70.8475 82 70.8475Z" fill="#38322F"/>
<path d="M93.6368 77.5682C98.2141 77.5682 101.925 73.8575 101.925 69.2802C101.925 64.7029 98.2141 60.9922 93.6368 60.9922C89.0594 60.9922 85.3488 64.7029 85.3488 69.2802C85.3488 73.8575 89.0594 77.5682 93.6368 77.5682Z" fill="#38322F"/>
<path d="M93.6368 91.0076C98.2141 91.0076 101.925 87.297 101.925 82.7196C101.925 78.1423 98.2141 74.4316 93.6368 74.4316C89.0594 74.4316 85.3488 78.1423 85.3488 82.7196C85.3488 87.297 89.0594 91.0076 93.6368 91.0076Z" fill="#38322F"/>
<path d="M82 97.7283C86.5774 97.7283 90.288 94.0177 90.288 89.4403C90.288 84.863 86.5774 81.1523 82 81.1523C77.4227 81.1523 73.712 84.863 73.712 89.4403C73.712 94.0177 77.4227 97.7283 82 97.7283Z" fill="#38322F"/>
<path d="M70.3632 91.0076C74.9405 91.0076 78.6512 87.297 78.6512 82.7196C78.6512 78.1423 74.9405 74.4316 70.3632 74.4316C65.7859 74.4316 62.0752 78.1423 62.0752 82.7196C62.0752 87.297 65.7859 91.0076 70.3632 91.0076Z" fill="#38322F"/>
<path d="M70.3632 77.5682C74.9405 77.5682 78.6512 73.8575 78.6512 69.2802C78.6512 64.7029 74.9405 60.9922 70.3632 60.9922C65.7859 60.9922 62.0752 64.7029 62.0752 69.2802C62.0752 73.8575 65.7859 77.5682 70.3632 77.5682Z" fill="#38322F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M74.608 75.9994C74.608 77.9599 75.3868 79.8401 76.7731 81.2264C78.1594 82.6126 80.0396 83.3914 82 83.3914C83.9605 83.3914 85.8407 82.6126 87.227 81.2264C88.6132 79.8401 89.392 77.9599 89.392 75.9994C89.392 74.0389 88.6132 72.1588 87.227 70.7725C85.8407 69.3862 83.9605 68.6074 82 68.6074C80.0396 68.6074 78.1594 69.3862 76.7731 70.7725C75.3868 72.1588 74.608 74.0389 74.608 75.9994ZM77.296 75.9994C77.296 77.247 77.7916 78.4435 78.6738 79.3257C79.556 80.2078 80.7525 80.7034 82 80.7034C83.2476 80.7034 84.4441 80.2078 85.3263 79.3257C86.2084 78.4435 86.704 77.247 86.704 75.9994C86.704 74.7518 86.2084 73.5554 85.3263 72.6732C84.4441 71.791 83.2476 71.2954 82 71.2954C80.7525 71.2954 79.556 71.791 78.6738 72.6732C77.7916 73.5554 77.296 74.7518 77.296 75.9994ZM79.872 75.9994C79.872 76.2789 79.9271 76.5556 80.034 76.8138C80.141 77.072 80.2977 77.3065 80.4953 77.5041C80.6929 77.7017 80.9275 77.8585 81.1857 77.9654C81.4439 78.0724 81.7206 78.1274 82 78.1274C82.2795 78.1274 82.5562 78.0724 82.8144 77.9654C83.0726 77.8585 83.3072 77.7017 83.5048 77.5041C83.7024 77.3065 83.8591 77.072 83.966 76.8138C84.073 76.5556 84.128 76.2789 84.128 75.9994C84.128 75.72 84.073 75.4433 83.966 75.1851C83.8591 74.9269 83.7024 74.6923 83.5048 74.4947C83.3072 74.2971 83.0726 74.1403 82.8144 74.0334C82.5562 73.9265 82.2795 73.8714 82 73.8714C81.7206 73.8714 81.4439 73.9265 81.1857 74.0334C80.9275 74.1403 80.6929 74.2971 80.4953 74.4947C80.2977 74.6923 80.141 74.9269 80.034 75.1851C79.9271 75.4433 79.872 75.72 79.872 75.9994Z" fill="#38322F"/>
<path d="M124 83.3996C128.087 83.3996 131.4 80.0865 131.4 75.9996C131.4 71.9127 128.087 68.5996 124 68.5996C119.913 68.5996 116.6 71.9127 116.6 75.9996C116.6 80.0865 119.913 83.3996 124 83.3996Z" fill="#38322F"/>
<path d="M134.39 89.3996C138.477 89.3996 141.79 86.0865 141.79 81.9996C141.79 77.9127 138.477 74.5996 134.39 74.5996C130.303 74.5996 126.99 77.9127 126.99 81.9996C126.99 86.0865 130.303 89.3996 134.39 89.3996Z" fill="#38322F"/>
<path d="M134.39 101.4C138.477 101.4 141.79 98.0865 141.79 93.9996C141.79 89.9127 138.477 86.5996 134.39 86.5996C130.303 86.5996 126.99 89.9127 126.99 93.9996C126.99 98.0865 130.303 101.4 134.39 101.4Z" fill="#38322F"/>
<path d="M124 107.4C128.087 107.4 131.4 104.087 131.4 99.9996C131.4 95.9127 128.087 92.5996 124 92.5996C119.913 92.5996 116.6 95.9127 116.6 99.9996C116.6 104.087 119.913 107.4 124 107.4Z" fill="#38322F"/>
<path d="M113.61 101.4C117.697 101.4 121.01 98.0865 121.01 93.9996C121.01 89.9127 117.697 86.5996 113.61 86.5996C109.523 86.5996 106.21 89.9127 106.21 93.9996C106.21 98.0865 109.523 101.4 113.61 101.4Z" fill="#38322F"/>
<path d="M113.61 89.3996C117.697 89.3996 121.01 86.0865 121.01 81.9996C121.01 77.9127 117.697 74.5996 113.61 74.5996C109.523 74.5996 106.21 77.9127 106.21 81.9996C106.21 86.0865 109.523 89.3996 113.61 89.3996Z" fill="#38322F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M117.4 88.0004C117.4 89.7508 118.095 91.4296 119.333 92.6673C120.571 93.905 122.249 94.6004 124 94.6004C125.75 94.6004 127.429 93.905 128.667 92.6673C129.905 91.4296 130.6 89.7508 130.6 88.0004C130.6 86.25 129.905 84.5712 128.667 83.3335C127.429 82.0957 125.75 81.4004 124 81.4004C122.249 81.4004 120.571 82.0957 119.333 83.3335C118.095 84.5712 117.4 86.25 117.4 88.0004ZM119.8 88.0004C119.8 89.1143 120.242 90.1826 121.03 90.9702C121.818 91.7579 122.886 92.2004 124 92.2004C125.114 92.2004 126.182 91.7579 126.97 90.9702C127.757 90.1826 128.2 89.1143 128.2 88.0004C128.2 86.8865 127.757 85.8182 126.97 85.0305C126.182 84.2429 125.114 83.8004 124 83.8004C122.886 83.8004 121.818 84.2429 121.03 85.0305C120.242 85.8182 119.8 86.8865 119.8 88.0004ZM122.1 88.0004C122.1 88.2499 122.149 88.497 122.245 88.7275C122.34 88.958 122.48 89.1675 122.656 89.3439C122.833 89.5203 123.042 89.6603 123.273 89.7558C123.503 89.8512 123.75 89.9004 124 89.9004C124.249 89.9004 124.496 89.8512 124.727 89.7558C124.958 89.6603 125.167 89.5203 125.343 89.3439C125.52 89.1675 125.66 88.958 125.755 88.7275C125.851 88.497 125.9 88.2499 125.9 88.0004C125.9 87.7509 125.851 87.5038 125.755 87.2733C125.66 87.0428 125.52 86.8333 125.343 86.6569C125.167 86.4805 124.958 86.3405 124.727 86.245C124.496 86.1495 124.249 86.1004 124 86.1004C123.75 86.1004 123.503 86.1495 123.273 86.245C123.042 86.3405 122.833 86.4805 122.656 86.6569C122.48 86.8333 122.34 87.0428 122.245 87.2733C122.149 87.5038 122.1 87.7509 122.1 88.0004Z" fill="#38322F"/>
<path d="M99.9999 107.033C104.414 107.033 107.992 103.455 107.992 99.0408C107.992 94.627 104.414 91.0488 99.9999 91.0488C95.5861 91.0488 92.0079 94.627 92.0079 99.0408C92.0079 103.455 95.5861 107.033 99.9999 107.033Z" fill="#38322F"/>
<path d="M111.221 113.513C115.635 113.513 119.213 109.935 119.213 105.521C119.213 101.107 115.635 97.5293 111.221 97.5293C106.807 97.5293 103.229 101.107 103.229 105.521C103.229 109.935 106.807 113.513 111.221 113.513Z" fill="#38322F"/>
<path d="M111.221 126.472C115.635 126.472 119.213 122.894 119.213 118.48C119.213 114.066 115.635 110.488 111.221 110.488C106.807 110.488 103.229 114.066 103.229 118.48C103.229 122.894 106.807 126.472 111.221 126.472Z" fill="#38322F"/>
<path d="M99.9999 132.953C104.414 132.953 107.992 129.375 107.992 124.961C107.992 120.547 104.414 116.969 99.9999 116.969C95.5861 116.969 92.0079 120.547 92.0079 124.961C92.0079 129.375 95.5861 132.953 99.9999 132.953Z" fill="#38322F"/>
<path d="M88.7787 126.472C93.1926 126.472 96.7707 122.894 96.7707 118.48C96.7707 114.066 93.1926 110.488 88.7787 110.488C84.3649 110.488 80.7867 114.066 80.7867 118.48C80.7867 122.894 84.3649 126.472 88.7787 126.472Z" fill="#38322F"/>
<path d="M88.7787 113.513C93.1926 113.513 96.7707 109.935 96.7707 105.521C96.7707 101.107 93.1926 97.5293 88.7787 97.5293C84.3649 97.5293 80.7867 101.107 80.7867 105.521C80.7867 109.935 84.3649 113.513 88.7787 113.513Z" fill="#38322F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M92.8719 112.001C92.8719 113.892 93.6229 115.705 94.9597 117.041C96.2964 118.378 98.1095 119.129 99.9999 119.129C101.89 119.129 103.703 118.378 105.04 117.041C106.377 115.705 107.128 113.892 107.128 112.001C107.128 110.111 106.377 108.298 105.04 106.961C103.703 105.624 101.89 104.873 99.9999 104.873C98.1095 104.873 96.2964 105.624 94.9597 106.961C93.6229 108.298 92.8719 110.111 92.8719 112.001ZM95.4639 112.001C95.4639 113.204 95.9418 114.358 96.7925 115.208C97.6432 116.059 98.7969 116.537 99.9999 116.537C101.203 116.537 102.357 116.059 103.207 115.208C104.058 114.358 104.536 113.204 104.536 112.001C104.536 110.798 104.058 109.644 103.207 108.794C102.357 107.943 101.203 107.465 99.9999 107.465C98.7969 107.465 97.6432 107.943 96.7925 108.794C95.9418 109.644 95.4639 110.798 95.4639 112.001ZM97.9479 112.001C97.9479 112.271 98.001 112.537 98.1041 112.786C98.2073 113.035 98.3584 113.261 98.549 113.452C98.7395 113.643 98.9657 113.794 99.2147 113.897C99.4636 114 99.7305 114.053 99.9999 114.053C100.269 114.053 100.536 114 100.785 113.897C101.034 113.794 101.26 113.643 101.451 113.452C101.641 113.261 101.793 113.035 101.896 112.786C101.999 112.537 102.052 112.271 102.052 112.001C102.052 111.732 101.999 111.465 101.896 111.216C101.793 110.967 101.641 110.741 101.451 110.55C101.26 110.36 101.034 110.208 100.785 110.105C100.536 110.002 100.269 109.949 99.9999 109.949C99.7305 109.949 99.4636 110.002 99.2147 110.105C98.9657 110.208 98.7395 110.36 98.549 110.55C98.3584 110.741 98.2073 110.967 98.1041 111.216C98.001 111.465 97.9479 111.732 97.9479 112.001Z" fill="#38322F"/>
<path d="M112 165H98C94.134 165 91 168.134 91 172C91 175.866 94.134 179 98 179H112C115.866 179 119 175.866 119 172C119 168.134 115.866 165 112 165Z" fill="#38322F"/>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,18 @@
<svg width="64" height="104" viewBox="0 0 64 104" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2215_68)">
<path d="M32 104V50" stroke="#38322F" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M32.0001 67.9998C26.1003 70.0966 20.3629 67.0412 17.8598 60.6213C24.1659 59.0446 29.9033 62.1 32.0001 67.9998Z" fill="#38322F"/>
<path d="M32 24.8475C36.5774 24.8475 40.288 21.1368 40.288 16.5595C40.288 11.9821 36.5774 8.27148 32 8.27148C27.4227 8.27148 23.712 11.9821 23.712 16.5595C23.712 21.1368 27.4227 24.8475 32 24.8475Z" fill="#38322F"/>
<path d="M43.6368 31.5682C48.2141 31.5682 51.9248 27.8575 51.9248 23.2802C51.9248 18.7029 48.2141 14.9922 43.6368 14.9922C39.0594 14.9922 35.3488 18.7029 35.3488 23.2802C35.3488 27.8575 39.0594 31.5682 43.6368 31.5682Z" fill="#38322F"/>
<path d="M43.6368 45.0076C48.2141 45.0076 51.9248 41.297 51.9248 36.7196C51.9248 32.1423 48.2141 28.4316 43.6368 28.4316C39.0594 28.4316 35.3488 32.1423 35.3488 36.7196C35.3488 41.297 39.0594 45.0076 43.6368 45.0076Z" fill="#38322F"/>
<path d="M32 51.7283C36.5774 51.7283 40.288 48.0177 40.288 43.4403C40.288 38.863 36.5774 35.1523 32 35.1523C27.4227 35.1523 23.712 38.863 23.712 43.4403C23.712 48.0177 27.4227 51.7283 32 51.7283Z" fill="#38322F"/>
<path d="M20.3632 45.0076C24.9405 45.0076 28.6512 41.297 28.6512 36.7196C28.6512 32.1423 24.9405 28.4316 20.3632 28.4316C15.7859 28.4316 12.0752 32.1423 12.0752 36.7196C12.0752 41.297 15.7859 45.0076 20.3632 45.0076Z" fill="#38322F"/>
<path d="M20.3632 31.5682C24.9405 31.5682 28.6512 27.8575 28.6512 23.2802C28.6512 18.7029 24.9405 14.9922 20.3632 14.9922C15.7859 14.9922 12.0752 18.7029 12.0752 23.2802C12.0752 27.8575 15.7859 31.5682 20.3632 31.5682Z" fill="#38322F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.608 29.9994C24.608 31.9599 25.3868 33.8401 26.7731 35.2264C28.1594 36.6126 30.0396 37.3914 32 37.3914C33.9605 37.3914 35.8407 36.6126 37.227 35.2264C38.6132 33.8401 39.392 31.9599 39.392 29.9994C39.392 28.0389 38.6132 26.1588 37.227 24.7725C35.8407 23.3862 33.9605 22.6074 32 22.6074C30.0396 22.6074 28.1594 23.3862 26.7731 24.7725C25.3868 26.1588 24.608 28.0389 24.608 29.9994ZM27.296 29.9994C27.296 31.247 27.7916 32.4435 28.6738 33.3257C29.556 34.2078 30.7525 34.7034 32 34.7034C33.2476 34.7034 34.4441 34.2078 35.3263 33.3257C36.2084 32.4435 36.704 31.247 36.704 29.9994C36.704 28.7518 36.2084 27.5554 35.3263 26.6732C34.4441 25.791 33.2476 25.2954 32 25.2954C30.7525 25.2954 29.556 25.791 28.6738 26.6732C27.7916 27.5554 27.296 28.7518 27.296 29.9994ZM29.872 29.9994C29.872 30.2789 29.9271 30.5556 30.034 30.8138C30.141 31.072 30.2977 31.3065 30.4953 31.5041C30.6929 31.7017 30.9275 31.8585 31.1857 31.9654C31.4439 32.0724 31.7206 32.1274 32 32.1274C32.2795 32.1274 32.5562 32.0724 32.8144 31.9654C33.0726 31.8585 33.3072 31.7017 33.5048 31.5041C33.7024 31.3065 33.8591 31.072 33.966 30.8138C34.073 30.5556 34.128 30.2789 34.128 29.9994C34.128 29.72 34.073 29.4433 33.966 29.1851C33.8591 28.9269 33.7024 28.6923 33.5048 28.4947C33.3072 28.2971 33.0726 28.1403 32.8144 28.0334C32.5562 27.9265 32.2795 27.8714 32 27.8714C31.7206 27.8714 31.4439 27.9265 31.1857 28.0334C30.9275 28.1403 30.6929 28.2971 30.4953 28.4947C30.2977 28.6923 30.141 28.9269 30.034 29.1851C29.9271 29.4433 29.872 29.72 29.872 29.9994Z" fill="#38322F"/>
</g>
<defs>
<clipPath id="clip0_2215_68">
<rect width="64" height="104" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="34" viewBox="0 0 24 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 28.5C15.3137 28.5 18 24.2467 18 19C18 13.7533 15.3137 9.5 12 9.5C8.68629 9.5 6 13.7533 6 19C6 24.2467 8.68629 28.5 12 28.5Z" fill="#38322F"/>
</svg>

After

Width:  |  Height:  |  Size: 258 B

View File

@@ -0,0 +1,11 @@
<svg width="46" height="80" viewBox="0 0 46 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2215_65)">
<path d="M23 80V28" stroke="#38322F" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M23 52C13 52 8 45 8 36C18 37 23 43 23 52Z" fill="#38322F"/>
</g>
<defs>
<clipPath id="clip0_2215_65">
<rect width="46" height="80" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 419 B

View File

@@ -0,0 +1,59 @@
<script>
import { onMount } from 'svelte';
import {
LANDING_CYCLE_MS,
LANDING_GROWTH_STAGES,
LANDING_STAGE_REVEAL_MS
} from '$lib/landing/landingGrowthStages.js';
let cycle = $state(0);
let reducedMotion = $state(false);
onMount(() => {
reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reducedMotion) return;
const timer = window.setInterval(() => {
cycle += 1;
}, LANDING_CYCLE_MS);
return () => {
window.clearInterval(timer);
};
});
</script>
<div class="growth-metaphor w-full" aria-hidden="true">
<div class="flex w-full items-end justify-between gap-2 sm:gap-4">
{#each LANDING_GROWTH_STAGES as stage (`${cycle}-${stage.id}`)}
<img
src={stage.src}
alt=""
class={[
'w-auto shrink-0 object-contain object-bottom',
stage.heightClass,
reducedMotion ? 'opacity-100' : 'stage-reveal'
]}
style={`--stage-delay: ${stage.delayMs}ms; --stage-duration: ${LANDING_STAGE_REVEAL_MS}ms;`}
/>
{/each}
</div>
<div class="h-px w-full bg-ink" aria-hidden="true"></div>
</div>
<style>
.stage-reveal {
opacity: 0;
transform: translateY(0.5rem);
animation: stage-reveal var(--stage-duration, 680ms) ease-out forwards;
animation-delay: var(--stage-delay, 0ms);
}
@keyframes stage-reveal {
to {
opacity: 1;
transform: translateY(0);
}
}
</style>

View File

@@ -0,0 +1,36 @@
<script>
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import Button from '$lib/components/ui/Button.svelte';
import GrowthMetaphorIllustration from '$lib/components/ui/landing/GrowthMetaphorIllustration.svelte';
function handleStart() {
goto(resolve('/create'));
}
</script>
<section
class="relative flex min-h-dvh flex-col bg-surface px-6 py-8 font-sans text-ink sm:px-10 sm:py-10 lg:px-14"
aria-label="Every bouquet starts with a muse — seed to bouquet growth metaphor"
>
<div class="mx-auto flex w-full max-w-6xl min-h-0 flex-1 flex-col justify-center">
<GrowthMetaphorIllustration />
<p class="mt-3 text-left text-sm tracking-[0.18em] text-muted sm:mt-4 sm:text-base">
Every Bouquet Starts with a Muse
</p>
</div>
<div class="mx-auto flex w-full max-w-6xl items-end justify-between gap-6 pb-2 pt-10">
<div class="min-w-0 text-left">
<p class="text-lg leading-none tracking-wide text-ink">AI Florist</p>
<h1 class="mt-2 text-4xl leading-none font-bold tracking-wide sm:text-5xl lg:text-6xl">
DearYou
</h1>
</div>
<div class="shrink-0 pb-1">
<Button onclick={handleStart}>start creating</Button>
</div>
</div>
</section>

View File

@@ -0,0 +1,22 @@
import seedSrc from '$lib/assets/landing/seed.svg';
import sproutSrc from '$lib/assets/landing/sprout.svg';
import flowerSrc from '$lib/assets/landing/flower.svg';
import bouquetSrc from '$lib/assets/landing/bouquet.svg';
/** 랜딩 growth metaphor — ref/route illustration SVG 4단계 */
export const LANDING_GROWTH_STAGES = [
{ id: 'seed', src: seedSrc, heightClass: 'h-[2.125rem] sm:h-9', delayMs: 0 },
{ id: 'sprout', src: sproutSrc, heightClass: 'h-16 sm:h-20', delayMs: 520 },
{ id: 'flower', src: flowerSrc, heightClass: 'h-24 sm:h-28', delayMs: 1040 },
{ id: 'bouquet', src: bouquetSrc, heightClass: 'h-36 sm:h-44 lg:h-52', delayMs: 1560 }
];
export const LANDING_STAGE_GAP_MS = 520;
export const LANDING_STAGE_REVEAL_MS = 680;
export const LANDING_CYCLE_HOLD_MS = 3000;
const lastStage = LANDING_GROWTH_STAGES[LANDING_GROWTH_STAGES.length - 1];
/** 4단계 reveal 완료 + hold 후 다음 사이클까지 */
export const LANDING_CYCLE_MS =
lastStage.delayMs + LANDING_STAGE_REVEAL_MS + LANDING_CYCLE_HOLD_MS;

View File

@@ -1,9 +1,5 @@
<script>
import { goto } from '$app/navigation';
import { resolve } from '$app/paths';
import Button from '$lib/components/ui/Button.svelte';
import LandingHero from '$lib/components/ui/landing/LandingHero.svelte';
</script>
<main class="flex min-h-dvh items-center justify-center bg-surface px-6">
<Button onclick={() => goto(resolve('/create'))}>start creating</Button>
</main>
<LandingHero />