diff --git a/package-lock.json b/package-lock.json index 6eae3f4..47c4576 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" + } } } } diff --git a/package.json b/package.json index 52a6f4f..14c991e 100644 --- a/package.json +++ b/package.json @@ -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" } } diff --git a/src/lib/assets/landing/bouquet.svg b/src/lib/assets/landing/bouquet.svg new file mode 100644 index 0000000..2810128 --- /dev/null +++ b/src/lib/assets/landing/bouquet.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lib/assets/landing/flower.svg b/src/lib/assets/landing/flower.svg new file mode 100644 index 0000000..5178657 --- /dev/null +++ b/src/lib/assets/landing/flower.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/lib/assets/landing/seed.svg b/src/lib/assets/landing/seed.svg new file mode 100644 index 0000000..749941e --- /dev/null +++ b/src/lib/assets/landing/seed.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/lib/assets/landing/sprout.svg b/src/lib/assets/landing/sprout.svg new file mode 100644 index 0000000..d332eaf --- /dev/null +++ b/src/lib/assets/landing/sprout.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/lib/components/ui/landing/GrowthMetaphorIllustration.svelte b/src/lib/components/ui/landing/GrowthMetaphorIllustration.svelte new file mode 100644 index 0000000..11828ab --- /dev/null +++ b/src/lib/components/ui/landing/GrowthMetaphorIllustration.svelte @@ -0,0 +1,59 @@ + + + + + diff --git a/src/lib/components/ui/landing/LandingHero.svelte b/src/lib/components/ui/landing/LandingHero.svelte new file mode 100644 index 0000000..26995c2 --- /dev/null +++ b/src/lib/components/ui/landing/LandingHero.svelte @@ -0,0 +1,36 @@ + + +
+
+ + +

+ Every Bouquet Starts with a Muse +

+
+ +
+
+

AI Florist

+

+ DearYou +

+
+ +
+ +
+
+
diff --git a/src/lib/landing/landingGrowthStages.js b/src/lib/landing/landingGrowthStages.js new file mode 100644 index 0000000..24f56cf --- /dev/null +++ b/src/lib/landing/landingGrowthStages.js @@ -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; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 9ae6757..0321bbd 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,9 +1,5 @@ -
- -
+