diff --git a/src/lib/assets/cursor.svg b/src/lib/assets/cursor.svg new file mode 100644 index 0000000..ab3858d --- /dev/null +++ b/src/lib/assets/cursor.svg @@ -0,0 +1,106 @@ + + + + + diff --git a/src/lib/assets/favicon.svg b/src/lib/assets/favicon.svg index cc5dc66..a63789a 100644 --- a/src/lib/assets/favicon.svg +++ b/src/lib/assets/favicon.svg @@ -1 +1,23 @@ -svelte-logo \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/lib/assets/flower.svg b/src/lib/assets/flower.svg index 101ed26..df751c6 100644 --- a/src/lib/assets/flower.svg +++ b/src/lib/assets/flower.svg @@ -1,5 +1,5 @@ - + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lib/components/ui/Artwork/DescriptionCard.svelte b/src/lib/components/ui/Artwork/DescriptionCard.svelte index e45878a..a3a9729 100644 --- a/src/lib/components/ui/Artwork/DescriptionCard.svelte +++ b/src/lib/components/ui/Artwork/DescriptionCard.svelte @@ -2,7 +2,7 @@ let { title = 'Title', description = 'Description Description Description' } = $props(); -
-

{title}

+
+

{title}

{description}

diff --git a/src/lib/components/ui/FlowerCursor.svelte b/src/lib/components/ui/FlowerCursor.svelte new file mode 100644 index 0000000..6ff5dd7 --- /dev/null +++ b/src/lib/components/ui/FlowerCursor.svelte @@ -0,0 +1,68 @@ + + +{#if visible} +
+ +
+{/if} + + diff --git a/src/lib/components/ui/Header.svelte b/src/lib/components/ui/Header.svelte index f614129..b85d323 100644 --- a/src/lib/components/ui/Header.svelte +++ b/src/lib/components/ui/Header.svelte @@ -1,4 +1,6 @@
- - - - +
+ (01) + (02) + (03) + (04) + {caption} + + + + + +
diff --git a/src/lib/components/ui/upload/SnsFeedUpload.svelte b/src/lib/components/ui/upload/SnsFeedUpload.svelte index e501dec..586e164 100644 --- a/src/lib/components/ui/upload/SnsFeedUpload.svelte +++ b/src/lib/components/ui/upload/SnsFeedUpload.svelte @@ -4,13 +4,13 @@ import { hydrateDevUpload } from '$lib/dev/hydrateUpload.js'; import { getFlowObject, isDevSeeded } from '$lib/flowerFlow/session.js'; - let { primaryFile = $bindable(null) } = $props(); + let { primaryFile = $bindable(null), caption = 'upload their feed!' } = $props(); let firstFile = $state(null); - let secondFile = $state(null); $effect(() => { - primaryFile = firstFile ?? secondFile ?? null; + const next = firstFile ?? null; + if (primaryFile !== next) primaryFile = next; }); onMount(async () => { @@ -23,7 +23,6 @@ try { const files = await hydrateDevUpload(/** @type {Record} */ (tiles)); if (files.first) firstFile = files.first; - if (files.second) secondFile = files.second; } catch { // dev seed 실패 시 빈 타일 유지 } @@ -31,45 +30,89 @@
- - +
+ (01) + {caption} + + +
diff --git a/src/lib/components/ui/upload/UploadTile.svelte b/src/lib/components/ui/upload/UploadTile.svelte index 8c93c55..8b566ee 100644 --- a/src/lib/components/ui/upload/UploadTile.svelte +++ b/src/lib/components/ui/upload/UploadTile.svelte @@ -3,7 +3,13 @@ // the chosen image (cover) when filled. Layout (size / grid placement) is // supplied by the parent via `class` and `style` so the same tile works in // both the moodboard and the SNS feed. - let { label = null, class: klass = '', style = '', file = $bindable(null) } = $props(); + let { + label = null, + showLabel = true, + class: klass = '', + style = '', + file = $bindable(null) + } = $props(); let preview = $state(null); @@ -44,14 +50,14 @@ {#if preview} {label -
- {#if label} +
+ {#if label && showLabel} {label} {/if} Change @@ -63,7 +69,7 @@ class="flex size-10 items-center justify-center rounded-full border border-current text-xl leading-none" aria-hidden="true">+ - {#if label} + {#if label && showLabel} {label} {/if}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 0c1bdb9..52b7b35 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -2,15 +2,19 @@ import './layout.css'; import favicon from '$lib/assets/favicon.svg'; import DevSeedButton from '$lib/components/dev/DevSeedButton.svelte'; + import FlowerCursor from '$lib/components/ui/FlowerCursor.svelte'; let { children } = $props(); + + {@render children()} + diff --git a/src/routes/edit/+page.svelte b/src/routes/edit/+page.svelte index 1a456ad..ec519ef 100644 --- a/src/routes/edit/+page.svelte +++ b/src/routes/edit/+page.svelte @@ -2,6 +2,7 @@ import { onMount } from 'svelte'; import { goto } from '$app/navigation'; import { resolve } from '$app/paths'; + import DescriptionCard from '$lib/components/ui/Artwork/DescriptionCard.svelte'; import Header from '$lib/components/ui/Header.svelte'; import { editImages, fetchJob, finalizeJob, toDataUrl } from '$lib/flowerFlow/api.js'; import { getFlowString, saveFlow } from '$lib/flowerFlow/session.js'; @@ -182,7 +183,7 @@
-
+
{#if loading}
@@ -193,10 +194,7 @@ {/if}
-
-

{title}

-

{description}

-
+
diff --git a/src/routes/layout.css b/src/routes/layout.css index 9e18c0f..897c142 100644 --- a/src/routes/layout.css +++ b/src/routes/layout.css @@ -7,7 +7,7 @@ /* Color tokens */ --color-surface: #eeeeee; /* page background, text on dark */ --color-ink: #38322f; /* primary text */ - --color-pill: #1a1a1a; /* active toggle pill */ + --color-pill: #38322f; /* active toggle pill — logo color */ --color-track: #f4f4f4; /* toggle track */ --color-muted: #9e9e9e; /* inactive / secondary text */ --color-subtle: #7d7d7d; /* accent gray (active step dot, illustration) */ @@ -15,3 +15,20 @@ --color-line: #e5e7eb; /* dividers / light borders */ --color-line-strong: #d1d5db; /* card border */ } + +@layer base { + html, + body { + background-color: var(--color-surface); + } +} + +@layer utilities { + .bg-surface { + background-color: var(--color-surface); + background-image: url('/paper_texture.png'); + background-position: center; + background-repeat: no-repeat; + background-size: cover; + } +} diff --git a/src/routes/upload/+page.svelte b/src/routes/upload/+page.svelte index bbfd9ad..82387fb 100644 --- a/src/routes/upload/+page.svelte +++ b/src/routes/upload/+page.svelte @@ -27,6 +27,13 @@ let loading = $state(false); let error = $state(''); + const recipientPronoun = $derived.by(() => { + const style = typeof userInput.style === 'string' ? userInput.style.toLowerCase() : ''; + if (style === 'masculine') return 'his'; + if (style === 'feminine') return 'her'; + return 'their'; + }); + async function continueToMessage() { error = ''; @@ -77,18 +84,20 @@ >
-
+
-
+
{#if mode === 'moodboard'} - + {:else} - + {/if}
{#if error}

@@ -100,20 +109,26 @@ type="button" disabled={loading} onclick={continueToMessage} - class="w-full bg-pill px-4 py-3 text-sm text-surface disabled:opacity-50" + class="w-full px-2 py-3 text-sm whitespace-nowrap text-ink underline-offset-4 hover:underline disabled:opacity-50 lg:order-2 lg:w-auto" > - {loading ? 'Analyzing mood...' : 'Continue to message'} + {loading ? 'Analyzing mood...' : 'Continue to message ->'}

+ +