├── .gitignore ├── .husky └── pre-commit ├── .npmrc ├── .prettierignore ├── .vscode └── settings.json ├── README.md ├── eslint.config.js ├── jsconfig.json ├── netlify.toml ├── package-lock.json ├── package.json ├── postcss.config.js ├── prettier.config.cjs ├── src ├── app.css ├── app.html ├── lib │ ├── components │ │ ├── input-box.svelte │ │ ├── key-value-button.svelte │ │ ├── spinner-input-button.svelte │ │ └── spinner-input.svelte │ └── utils │ │ └── add-wait-to-keyframes.js └── routes │ ├── +layout.js │ ├── +layout.svelte │ └── +page.svelte ├── static ├── favicon.ico └── images │ ├── android-chrome-36x36.png │ ├── android-chrome-48x48.png │ ├── android-chrome-72x72.png │ ├── android-chrome-96x96.png │ ├── apple-touch-icon-57x57.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-72x72.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── manifest.json │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-70x70.png │ ├── safari-pinned-tab.svg │ ├── wa-avatar.png │ ├── wa-avatar.pxm │ ├── wa-favicon.png │ ├── wa-favicon.pxm │ └── worn-dots.png ├── svelte.config.js ├── tailwind.config.js └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | vite.config.js.timestamp-* 10 | vite.config.ts.timestamp-* 11 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | lint-staged 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | 10 | # Ignore files for PNPM, NPM and YARN 11 | pnpm-lock.yaml 12 | package-lock.json 13 | yarn.lock 14 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": { 3 | "sash.hoverBorder": "#c63632", 4 | "titleBar.activeForeground": "#9d2b28", 5 | "titleBar.inactiveForeground": "#9d2b2899" 6 | }, 7 | "eslint.enable": true, 8 | "eslint.validate": ["javascript", "javascriptreact", "svelte"], 9 | "cSpell.words": ["bindable", "sindresorhus", "waitanimate"] 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # create-svelte 2 | 3 | Everything you need to build a Svelte project, powered by 4 | [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). 5 | 6 | ## Creating a project 7 | 8 | If you're seeing this, you've probably already done this step. Congrats! 9 | 10 | ```bash 11 | # create a new project in the current directory 12 | npm create svelte@latest 13 | 14 | # create a new project in my-app 15 | npm create svelte@latest my-app 16 | ``` 17 | 18 | ## Developing 19 | 20 | Once you've created a project and installed dependencies with `npm install` (or 21 | `pnpm install` or `yarn`), start a development server: 22 | 23 | ```bash 24 | npm run dev 25 | 26 | # or start the server and open the app in a new browser tab 27 | npm run dev -- --open 28 | ``` 29 | 30 | ## Building 31 | 32 | To create a production version of your app: 33 | 34 | ```bash 35 | npm run build 36 | ``` 37 | 38 | You can preview the production build with `npm run preview`. 39 | 40 | > To deploy your app, you may need to install an 41 | > [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. 42 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from '@will-stone/eslint-config' 2 | import pluginSvelte from 'eslint-plugin-svelte' 3 | 4 | export default [ 5 | ...config(), 6 | { 7 | ignores: ['.svelte-kit/**/*'], 8 | }, 9 | ...pluginSvelte.configs['flat/recommended'], 10 | ...pluginSvelte.configs['flat/prettier'], 11 | { 12 | rules: { 13 | 'prefer-const': 'off', 14 | }, 15 | }, 16 | ] 17 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | } 13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files 14 | // 15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 16 | // from the referenced tsconfig.json - TypeScript does not merge them in 17 | } 18 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "npm run build" 3 | publish = "build" 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wait-animate", 3 | "version": "2.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build", 8 | "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", 9 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch", 10 | "dev": "vite dev", 11 | "format": "prettier --write .", 12 | "lint": "eslint .", 13 | "prepare": "husky", 14 | "preview": "vite preview" 15 | }, 16 | "lint-staged": { 17 | "*.{js,jsx,ts,tsx,svelte}": [ 18 | "eslint --fix" 19 | ], 20 | "*.{css,json,md}": [ 21 | "prettier --write" 22 | ] 23 | }, 24 | "dependencies": { 25 | "@sindresorhus/string-hash": "^2.0.0", 26 | "copy-text-to-clipboard": "^3.2.0" 27 | }, 28 | "devDependencies": { 29 | "@sveltejs/adapter-auto": "^3.3.1", 30 | "@sveltejs/adapter-static": "^3.0.6", 31 | "@sveltejs/kit": "^2.7.3", 32 | "@sveltejs/vite-plugin-svelte": "^4.0.0", 33 | "@will-stone/eslint-config": "^12.0.0", 34 | "@will-stone/prettier-config": "^8.0.1", 35 | "autoprefixer": "^10.4.20", 36 | "eslint": "^9.13.0", 37 | "eslint-plugin-svelte": "^2.46.0", 38 | "husky": "^9.1.6", 39 | "lint-staged": "^15.2.10", 40 | "postcss": "^8.4.47", 41 | "prettier": "^3.3.3", 42 | "prettier-plugin-svelte": "^3.2.7", 43 | "svelte": "^5.1.6", 44 | "svelte-check": "^4.0.5", 45 | "tailwindcss": "^3.4.14", 46 | "typescript": "^5.6.3", 47 | "vite": "^5.4.10" 48 | }, 49 | "overrides": { 50 | "eslint": "^9.13.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | 5 | autoprefixer: {}, 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /prettier.config.cjs: -------------------------------------------------------------------------------- 1 | const myConfig = require('@will-stone/prettier-config') 2 | 3 | module.exports = { 4 | ...myConfig, 5 | overrides: [{ files: '*.svelte', options: { parser: 'svelte' } }], 6 | plugins: [...myConfig.plugins, 'prettier-plugin-svelte'], 7 | } 8 | -------------------------------------------------------------------------------- /src/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | WAIT! Animate 8 | 9 | 15 | 16 | 21 | 22 | 23 | 28 | 33 | 38 | 43 | 49 | 55 | 61 | 65 | 70 | 74 | 75 | 79 | 80 | 81 | 87 | 88 | 94 | 95 | %sveltekit.head% 96 | 97 | 98 | 103 |
104 |
105 |

106 | WAIT! 107 | Animate 108 |

109 | 110 |

111 | CSS doesn't provide a property to pause an animation before it loops 112 | around again. Yes, there's 113 | animation-delay 116 | but this simply denotes a delay at the very start of the animation, 117 | when the element is first shown. 118 | WAIT! Animate 119 | calculates updated keyframe percentages given a 120 | wait 121 | time meaning you can insert a delay between each animation iteration 122 | using pure CSS, without JavaScript. 123 |

124 | 125 |
%sveltekit.body%
126 | 127 |
128 | 129 |

SCSS Mixin

130 | 131 |
132 | @mixin waitAnimate($options: ()) {
133 |   $options: map-merge((
134 |     animationName: waitAnimate,
135 |     duration: 1,
136 |     waitTime: 0,
137 |     timingFunction: linear,
138 |     iterationCount: infinite
139 |   ), $options);
140 | 
141 |   $name: map-get($options, animationName);
142 |   $kf: map-get($options, keyframes);
143 |   $kfLength: length($kf);
144 |   $duration: map-get($options, duration);
145 |   $waitTime: map-get($options, waitTime);
146 |   $timingFunction: map-get($options, timingFunction);
147 |   $iterationCount: map-get($options, iterationCount);
148 |   $counter: 1; // index of 'each'
149 | 
150 |   @keyframes #{$name} {
151 |     @each $frame, $prop in $kf {
152 |       #{$frame * $duration / ($duration + $waitTime)}% {
153 |         @each $k, $v in $prop {
154 |           #{$k}: #{$v}
155 |         }
156 |       }
157 |       // if last in loop and waitTime is not 0, add the last frame as 100% (this is what creates the pause)
158 |       @if $counter == $kfLength and $waitTime > 0 {
159 |         100% {
160 |           @each $k, $v in $prop {
161 |             #{$k}: #{$v}
162 |           }
163 |         }
164 |       }
165 |       $counter: $counter+1;
166 |     }
167 |   }
168 | 
169 |   .#{$name} {
170 |     animation: #{$name} #{$duration + $waitTime}s #{$timingFunction} #{$iterationCount};
171 |   }
172 | }
173 |         
174 | 175 |
176 |
177 |

Include:

178 | 179 |
180 | @include waitAnimate(
181 |   (
182 |     animationName: animName,
183 |     keyframes: (
184 |       0: (
185 |         transform: scale(1),
186 |         background-color: blue
187 |       ),
188 |       50: (
189 |         transform: scale(2),
190 |         background-color: green
191 |       ),
192 |       100: (
193 |         transform: scale(3),
194 |         background-color: red
195 |       )
196 |     ),
197 |     duration: 2,
198 |     waitTime: 1,
199 |     timingFunction: ease,
200 |     iterationCount: infinite
201 |   )
202 | );
203 |             
204 |
205 | 206 |
207 |

Output:

208 | 209 |
210 | @keyframes animName {
211 |   0% {
212 |     transform: scale(1);
213 |     background-color: blue;
214 |   }
215 |   33.33333333% {
216 |     transform: scale(2);
217 |     background-color: green;
218 |   }
219 |   66.66666667% {
220 |     transform: scale(3);
221 |     background-color: red;
222 |   }
223 |   100% {
224 |     transform: scale(3);
225 |     background-color: red;
226 |   }
227 | }
228 | 
229 | .animName {
230 |   animation: animName 2s ease infinite;
231 | }
232 |             
233 |
234 |
235 | 236 |

237 | You'll notice that you need to change your keyframes rule to a SASS 238 | map object. I was unable to find a solution that could manipulate a 239 | standard keyframes rule. If you know of a way to do this, please let 240 | me know. 241 |

242 | 243 |

244 | @include waitAnimate((options)); 247 |

248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 274 | 275 | 276 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 305 | 306 | 307 | 308 | 309 | 310 |
OptionDescriptionTypeRequired?Default
animationNameThe class name of your animation.StringNowaitAnimate
keyframesThe 0% to 100% animation rule.SASS map objectYes 273 |
duration 277 | The length of the animation in seconds (wait time will be added 278 | to this). 279 | NumberNo1
waitTime 287 | The amount of pause time in seconds at the end of the animation. 288 | NumberNo0
timingFunctionThe speed curve of the animation.StringNolinear
iterationCount 303 | The number of times the animation should be played. 304 | StringNoinfinite
311 |
312 | 313 |
314 | 315 | 356 |
357 | 358 | 359 | -------------------------------------------------------------------------------- /src/lib/components/input-box.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 | 20 | -------------------------------------------------------------------------------- /src/lib/components/key-value-button.svelte: -------------------------------------------------------------------------------- 1 | 15 | 16 | 30 | -------------------------------------------------------------------------------- /src/lib/components/spinner-input-button.svelte: -------------------------------------------------------------------------------- 1 | 25 | 26 | 42 | -------------------------------------------------------------------------------- /src/lib/components/spinner-input.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 | 17 | 18 | 19 |
20 | -------------------------------------------------------------------------------- /src/lib/utils/add-wait-to-keyframes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} number 3 | * @returns number 4 | */ 5 | function roundToThreeDecimals(number) { 6 | return Number(`${Math.round(Number(`${number}e+3`))}e-3`) 7 | } 8 | 9 | /** 10 | * @param {string} keyframes 11 | * @param {string} duration 12 | * @param {string} waitTime 13 | * @returns 14 | */ 15 | export function addWaitToKeyframes(keyframes, duration, waitTime) { 16 | try { 17 | const asArray = keyframes 18 | // Remove whitespace from start and end 19 | .trim() 20 | // Split by frame 21 | .split('}') 22 | // Remove empty array items 23 | .filter(Boolean) 24 | // Remove all whitespace from frame, including line breaks 25 | .map((s) => s.replaceAll(/\s/gu, '')) 26 | // Put closing frame bracket back 27 | .map((s) => `${s}}`) 28 | // Split frame percentage and properties 29 | .map((s) => { 30 | // Get number before opening frame and strip percentage 31 | const frameValue = s.split('{')[0].trim().replace('%', '') 32 | // Parse to numeric 33 | let frame = Number(frameValue) 34 | 35 | if (frameValue === 'from') { 36 | frame = 0 37 | } else if (frameValue === 'to') { 38 | frame = 100 39 | } 40 | 41 | return { 42 | frame, 43 | properties: s.match(/\{(.*)\}/u)?.[1], 44 | } 45 | }) 46 | 47 | return ( 48 | [ 49 | ...asArray.map((f) => ({ 50 | // Reduce frame percentages to accommodate wait and duration 51 | frame: roundToThreeDecimals( 52 | (f.frame * Number(duration)) / 53 | (Number(duration) + Number(waitTime)), 54 | ), 55 | properties: f.properties, 56 | })), 57 | // Extend last frame to end to simulate the wait time 58 | { 59 | frame: 100, 60 | properties: asArray.at(-1)?.properties, 61 | }, 62 | ] 63 | // Turn back into string 64 | .map((f) => { 65 | const parsedProperties = f.properties 66 | // Separate properties 67 | ?.split(';') 68 | // Add lines breaks between properties and indent 69 | .join(';\n ') 70 | // Add space between property name and value 71 | .replaceAll(':', ': ') 72 | // Remove line break added from the join 73 | .trim() 74 | 75 | return ` ${f.frame}% {\n ${parsedProperties}\n }` 76 | }) 77 | // Add line break between frames 78 | .join('\n') 79 | ) 80 | } catch { 81 | return ' ERROR: Unable to parse keyframes, please try again.' 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/routes/+layout.js: -------------------------------------------------------------------------------- 1 | export const prerender = true 2 | -------------------------------------------------------------------------------- /src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 | {@render children?.()} 13 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 55 | 56 |
57 |
58 |
59 |

Class Name

60 | 61 | 62 |
63 | 64 |
65 |
66 |

Wait Time

67 | 68 | 69 | 70 |
Seconds
71 |
72 | 73 |
74 |

Animation Duration

75 | 76 | 77 | 78 |
Seconds
79 |
80 |
81 | 82 |

Timing Function

83 | 84 |
85 | 86 | 87 | 88 | 89 | 90 |
91 | 92 |
93 |
94 |

Transform Origin X

95 | 96 | 97 | 98 |
%
99 |
100 | 101 |
102 |

Transform Origin Y

103 | 104 | 105 | 106 |
%
107 |
108 |
109 | 110 |

Keyframes

111 | 112 | 118 |
119 | 120 |
121 |
122 |
123 | ! 124 |
125 |
126 | 127 |

Calculated Keyframes

128 | 129 |
133 | 134 | {@html `<${'style'} class="block whitespace-pre">${output}`} 135 |
136 | 137 | 145 |
146 |
147 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/favicon.ico -------------------------------------------------------------------------------- /static/images/android-chrome-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/android-chrome-36x36.png -------------------------------------------------------------------------------- /static/images/android-chrome-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/android-chrome-48x48.png -------------------------------------------------------------------------------- /static/images/android-chrome-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/android-chrome-72x72.png -------------------------------------------------------------------------------- /static/images/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/android-chrome-96x96.png -------------------------------------------------------------------------------- /static/images/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /static/images/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /static/images/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /static/images/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /static/images/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /static/images/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/apple-touch-icon.png -------------------------------------------------------------------------------- /static/images/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | #df3e39 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /static/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/favicon-16x16.png -------------------------------------------------------------------------------- /static/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/favicon-32x32.png -------------------------------------------------------------------------------- /static/images/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/favicon-96x96.png -------------------------------------------------------------------------------- /static/images/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WAIT! Animate", 3 | "icons": [ 4 | { 5 | "src": "images/android-chrome-36x36.png?v=GvvwO0J8Lj", 6 | "sizes": "36x36", 7 | "type": "image/png", 8 | "density": 0.75 9 | }, 10 | { 11 | "src": "images/android-chrome-48x48.png?v=GvvwO0J8Lj", 12 | "sizes": "48x48", 13 | "type": "image/png", 14 | "density": 1 15 | }, 16 | { 17 | "src": "images/android-chrome-72x72.png?v=GvvwO0J8Lj", 18 | "sizes": "72x72", 19 | "type": "image/png", 20 | "density": 1.5 21 | }, 22 | { 23 | "src": "images/android-chrome-96x96.png?v=GvvwO0J8Lj", 24 | "sizes": "96x96", 25 | "type": "image/png", 26 | "density": 2 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /static/images/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/mstile-150x150.png -------------------------------------------------------------------------------- /static/images/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/mstile-310x150.png -------------------------------------------------------------------------------- /static/images/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/mstile-70x70.png -------------------------------------------------------------------------------- /static/images/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /static/images/wa-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/wa-avatar.png -------------------------------------------------------------------------------- /static/images/wa-avatar.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/wa-avatar.pxm -------------------------------------------------------------------------------- /static/images/wa-favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/wa-favicon.png -------------------------------------------------------------------------------- /static/images/wa-favicon.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/wa-favicon.pxm -------------------------------------------------------------------------------- /static/images/worn-dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-stone/waitanimate/0b7a42b8356bbddf1544ad025f0c5324913d5ae5/static/images/worn-dots.png -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-static' 2 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | kit: { 7 | // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. 8 | // If your environment is not supported or you settled on a specific environment, switch out the adapter. 9 | // See https://kit.svelte.dev/docs/adapters for more information about adapters. 10 | adapter: adapter(), 11 | }, 12 | preprocess: vitePreprocess(), 13 | } 14 | 15 | export default config 16 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ['./src/**/*.{html,js,svelte,ts}'], 4 | plugins: [], 5 | theme: { 6 | container: { 7 | center: true, 8 | padding: { 9 | DEFAULT: '1rem', 10 | sm: '2rem', 11 | }, 12 | }, 13 | extend: { 14 | fontFamily: { 15 | title: ['Bowlby One SC', 'sans-serif'], 16 | }, 17 | }, 18 | screens: { 19 | lg: '1024px', 20 | md: '768px', 21 | sm: '640px', 22 | }, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite' 2 | import { defineConfig } from 'vite' 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()], 6 | }) 7 | --------------------------------------------------------------------------------