|
1 | 1 | <script lang="ts"> |
2 | | -import { cubicOut } from "svelte/easing"; |
3 | | -import { fade, scale } from "svelte/transition"; |
| 2 | + import { ButtonAction } from "$lib/ui"; |
| 3 | + import { cubicOut } from "svelte/easing"; |
| 4 | + import { fade, fly } from "svelte/transition"; |
| 5 | +
|
| 6 | + interface ISplashScreenProps { |
| 7 | + /** false = state A (logo "closed"). true = state B (tagline revealed). */ |
| 8 | + open?: boolean; |
| 9 | + /** true = state C (bottom drawer with CTAs revealed). */ |
| 10 | + showDrawer?: boolean; |
| 11 | + /** Fired when "Create Digital Self" is tapped. */ |
| 12 | + oncreate?: () => void; |
| 13 | + /** Fired when "Restore Digital Self" is tapped. */ |
| 14 | + onrestore?: () => void; |
| 15 | + } |
| 16 | +
|
| 17 | + const { |
| 18 | + open = false, |
| 19 | + showDrawer = false, |
| 20 | + oncreate, |
| 21 | + onrestore, |
| 22 | + }: ISplashScreenProps = $props(); |
4 | 23 | </script> |
5 | 24 |
|
6 | 25 | <div |
7 | | - out:fade={{ duration: 150 }} |
8 | | - class="z-50 absolute w-screen h-screen overflow-hidden" |
| 26 | + out:fade={{ duration: 200 }} |
| 27 | + class="z-50 fixed inset-0 bg-primary overflow-hidden flex flex-col" |
9 | 28 | > |
10 | | - <div class="relative w-screen h-screen bg-primary overflow-hidden"> |
11 | | - <img |
12 | | - in:scale={{ |
13 | | - start: 0.8, |
14 | | - duration: 500, |
15 | | - easing: cubicOut, |
16 | | - opacity: 1, |
17 | | - }} |
18 | | - class="absolute w-full bottom-[-80px] start-0" |
19 | | - src="/images/Shape1.svg" |
20 | | - alt="illustration" |
21 | | - /> |
22 | | - <img |
23 | | - in:scale={{ |
24 | | - start: 0.8, |
25 | | - duration: 500, |
26 | | - easing: cubicOut, |
27 | | - opacity: 1, |
28 | | - }} |
29 | | - class="absolute w-full top-[50px] end-[100px]" |
30 | | - src="/images/Shape2.svg" |
31 | | - alt="illustration" |
32 | | - /> |
| 29 | + <!-- Logo group: vertically biased toward top-third, mirroring the Figma spec. |
| 30 | + CSS animation (not svelte in:fade) because Svelte 5 skips intros for |
| 31 | + elements already present at first render. Bg stays solid (no flash). --> |
| 32 | + <div |
| 33 | + class="splash-content flex-1 flex flex-col items-center justify-start pt-[22svh]" |
| 34 | + > |
| 35 | + <div class="flex flex-col items-center"> |
| 36 | + <span |
| 37 | + class="text-white font-medium text-[110px] leading-[88%] tracking-[-0.02em] -my-1" |
| 38 | + style="font-family: 'Roboto Condensed Variable', sans-serif;" |
| 39 | + > |
| 40 | + eID |
| 41 | + </span> |
| 42 | + <!-- Tagline: height-animated so opening pushes the W3DS pill down |
| 43 | + (gives the "logo unfolds, tagline emerges" feel). --> |
| 44 | + <div |
| 45 | + class="overflow-hidden transition-all duration-500 ease-out" |
| 46 | + style:max-height={open ? "2.5rem" : "0"} |
| 47 | + style:opacity={open ? 0.5 : 0} |
| 48 | + aria-hidden={!open} |
| 49 | + > |
| 50 | + <p class="text-white text-2xl font-medium leading-[120%]"> |
| 51 | + Your Digital Self |
| 52 | + </p> |
| 53 | + </div> |
| 54 | + <img |
| 55 | + src="/images/w3ds-logo-main.svg" |
| 56 | + alt="W3DS" |
| 57 | + width="90" |
| 58 | + height="44" |
| 59 | + class="mt-4 transition-all duration-1000 ease-out" |
| 60 | + /> |
| 61 | + </div> |
| 62 | + </div> |
| 63 | + |
| 64 | + {#if showDrawer} |
33 | 65 | <div |
34 | | - in:scale={{ |
35 | | - start: 0.9, |
| 66 | + transition:fly={{ |
| 67 | + y: 400, |
36 | 68 | duration: 500, |
37 | 69 | easing: cubicOut, |
38 | 70 | opacity: 1, |
39 | 71 | }} |
40 | | - class="absolute w-full top-[42%] start-[50%] translate-x-[-50%] translate-y-[-42%]" |
| 72 | + class="absolute inset-x-0 bottom-0 bg-white rounded-t-3xl px-5 pt-5 flex flex-col gap-3" |
| 73 | + style="padding-bottom: max(20px, env(safe-area-inset-bottom));" |
41 | 74 | > |
42 | | - <h1 |
43 | | - in:fade={{ duration: 500 }} |
44 | | - class="text-center text-white text-[44px]" |
| 75 | + <ButtonAction |
| 76 | + variant="solid" |
| 77 | + callback={oncreate} |
| 78 | + class="w-full uppercase tracking-wide active:bg-primary-400" |
45 | 79 | > |
46 | | - eID Wallet |
47 | | - </h1> |
48 | | - <p in:fade={{ duration: 500 }} class="text-center text-white"> |
49 | | - for Web 3.0 Data Space |
| 80 | + Create Digital Self |
| 81 | + </ButtonAction> |
| 82 | + <ButtonAction |
| 83 | + variant="soft" |
| 84 | + callback={onrestore} |
| 85 | + class="w-full uppercase tracking-wide text-black active:bg-primary-200" |
| 86 | + > |
| 87 | + Restore Digital Self |
| 88 | + </ButtonAction> |
| 89 | + <p |
| 90 | + class="text-center font-medium text-md text-black-700/50 leading-normal" |
| 91 | + > |
| 92 | + By continuing you agree to our |
| 93 | + <a |
| 94 | + href="https://metastate.foundation/" |
| 95 | + target="_blank" |
| 96 | + rel="noopener noreferrer" |
| 97 | + class="text-primary" |
| 98 | + > |
| 99 | + Terms & Conditions |
| 100 | + </a> |
| 101 | + and |
| 102 | + <a |
| 103 | + href="https://metastate.foundation/" |
| 104 | + target="_blank" |
| 105 | + rel="noopener noreferrer" |
| 106 | + class="text-primary" |
| 107 | + > |
| 108 | + Privacy Policy |
| 109 | + </a> |
50 | 110 | </p> |
51 | 111 | </div> |
52 | | - <img |
53 | | - in:fade={{ duration: 500 }} |
54 | | - class="absolute bottom-[116px] start-[50%] translate-x-[-50%]" |
55 | | - src="/images/W3DSLogoWhite.svg" |
56 | | - alt="logo" |
57 | | - /> |
58 | | - </div> |
| 112 | + {/if} |
59 | 113 | </div> |
60 | 114 |
|
61 | 115 | <style> |
| 116 | + @keyframes splash-content-in { |
| 117 | + from { |
| 118 | + opacity: 0; |
| 119 | + } |
| 120 | + to { |
| 121 | + opacity: 1; |
| 122 | + } |
| 123 | + } |
| 124 | +
|
| 125 | + .splash-content { |
| 126 | + animation: splash-content-in 500ms ease-out both; |
| 127 | + } |
62 | 128 | </style> |
0 commit comments