Initial commit after forking over from the starter project.

master
Zed A. Shaw 3 years ago
commit 557fdeaf38
  1. 279
      .eslintrc.js
  2. 114
      .gitignore
  3. 1
      LICENSE
  4. 10
      README.md
  5. 24
      lib/jasmine_examples/Player.js
  6. 9
      lib/jasmine_examples/Song.js
  7. 7569
      package-lock.json
  8. 57
      package.json
  9. 1
      public/build/bundle.css
  10. 9978
      public/build/bundle.js
  11. 1
      public/build/bundle.js.map
  12. BIN
      public/favicon.png
  13. 449
      public/global.css
  14. 1
      public/icons/feather-sprite.svg
  15. 18
      public/index.html
  16. 76
      rollup.config.js
  17. 117
      scripts/setupTypeScript.js
  18. 15
      spec/helpers/jasmine_examples/SpecHelper.js
  19. 60
      spec/jasmine_examples/PlayerSpec.js
  20. 11
      spec/support/jasmine.json
  21. 1
      src/About.svelte
  22. 59
      src/App.svelte
  23. 128
      src/Home.svelte
  24. 1
      src/NotFound.svelte
  25. 30
      src/Sidebar.svelte
  26. 42
      src/components/CodeBubble.svelte
  27. 31
      src/components/Darkmode.svelte
  28. 35
      src/components/Icon.svelte
  29. 102
      src/demos/Google.svelte
  30. 143
      src/demos/Instagram.svelte
  31. 24
      src/demos/Login.svelte
  32. 181
      src/demos/Pinterest.svelte
  33. 327
      src/demos/Twitter.svelte
  34. 155
      src/demos/XorAcademy.svelte
  35. 241
      src/demos/XorAcademyWatch.svelte
  36. 279
      src/demos/Youtube.svelte
  37. 81
      src/demos/index.svelte
  38. 10
      src/main.js
  39. 27
      src/routes.js
  40. 101
      src/thumbs/Google.svelte
  41. 114
      src/thumbs/Instagram.svelte
  42. 24
      src/thumbs/Login.svelte
  43. 126
      src/thumbs/Pinterest.svelte
  44. 130
      src/thumbs/Twitter.svelte
  45. 110
      src/thumbs/Youtube.svelte

@ -0,0 +1,279 @@
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true,
},
"plugins": ["jest"],
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"accessor-pairs": "error",
"array-bracket-newline": "off",
"array-bracket-spacing": [
"error",
"never"
],
"array-callback-return": "error",
"array-element-newline": "off",
"arrow-body-style": "off",
"arrow-parens": "off",
"arrow-spacing": [
"error",
{
"after": true,
"before": true
}
],
"block-scoped-var": "error",
"block-spacing": "error",
"brace-style": [
"error",
"1tbs"
],
"callback-return": "off",
"camelcase": "off",
"capitalized-comments": "off",
"class-methods-use-this": "error",
"comma-dangle": "off",
"comma-spacing": [
"error",
{
"after": true,
"before": false
}
],
"comma-style": [
"error",
"last"
],
"complexity": "error",
"computed-property-spacing": [
"error",
"never"
],
"consistent-return": "error",
"consistent-this": "error",
"curly": "off",
"default-case": "error",
"dot-location": "error",
"dot-notation": "off",
"eol-last": "error",
"eqeqeq": "off",
"func-call-spacing": "error",
"func-name-matching": "error",
"func-names": "error",
"func-style": [
"error",
"expression"
],
"function-paren-newline": "off",
"generator-star-spacing": "error",
"global-require": "off",
"guard-for-in": "error",
"handle-callback-err": "error",
"id-blacklist": "error",
"id-length": "off",
"id-match": "error",
"implicit-arrow-linebreak": [
"error",
"beside"
],
"indent": "off",
"indent-legacy": "off",
"init-declarations": "error",
"jsx-quotes": "error",
"key-spacing": "warn",
"keyword-spacing": "off",
"line-comment-position": "off",
"linebreak-style": [
"error",
"unix"
],
"lines-around-comment": "error",
"lines-around-directive": "error",
"lines-between-class-members": "error",
"max-classes-per-file": "off",
"max-depth": "error",
"max-len": "off",
"max-lines": "off",
"max-lines-per-function": "off",
"max-nested-callbacks": "error",
"max-params": "off",
"max-statements": "off",
"max-statements-per-line": "error",
"multiline-comment-style": "off",
"new-cap": "error",
"new-parens": "error",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"no-alert": "error",
"no-array-constructor": "error",
"no-async-promise-executor": "error",
"no-await-in-loop": "error",
"no-bitwise": "error",
"no-buffer-constructor": "error",
"no-caller": "error",
"no-catch-shadow": "error",
"no-confusing-arrow": "error",
"no-continue": "error",
"no-div-regex": "error",
"no-duplicate-imports": "error",
"no-else-return": "off",
"no-empty-function": "error",
"no-eq-null": "off",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
"no-extra-parens": "error",
"no-floating-decimal": "error",
"no-implicit-coercion": "error",
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-inline-comments": "off",
"no-invalid-this": "error",
"no-iterator": "error",
"no-label-var": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-loop-func": "error",
"no-magic-numbers": "off",
"no-misleading-character-class": "error",
"no-mixed-operators": "error",
"no-mixed-requires": "error",
"no-multi-assign": "error",
"no-multi-spaces": "off",
"no-multi-str": "error",
"no-multiple-empty-lines": "error",
"no-native-reassign": "error",
"no-negated-condition": "off",
"no-negated-in-lhs": "error",
"no-nested-ternary": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-new-require": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-param-reassign": "error",
"no-path-concat": "error",
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
"no-process-env": "off",
"no-process-exit": "off",
"no-proto": "error",
"no-prototype-builtins": "error",
"no-restricted-globals": "error",
"no-restricted-imports": "error",
"no-restricted-modules": "error",
"no-restricted-properties": "error",
"no-restricted-syntax": "error",
"no-return-assign": "error",
"no-return-await": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow": "off",
"no-shadow-restricted-names": "error",
"no-spaced-func": "error",
"no-sync": "warn",
"no-tabs": "off",
"no-template-curly-in-string": "error",
"no-ternary": "off",
"no-throw-literal": "error",
"no-trailing-spaces": "off",
"no-undef-init": "error",
"no-undefined": "off",
"no-underscore-dangle": "off",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": "error",
"no-unused-expressions": "error",
"no-use-before-define": ["error", {"functions": true, "classes": false}],
"no-useless-call": "error",
"no-useless-computed-key": "error",
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-useless-rename": "error",
"no-useless-return": "error",
"no-var": "error",
"no-void": "error",
"no-warning-comments": "off",
"no-whitespace-before-property": "error",
"no-with": "error",
"nonblock-statement-body-position": "error",
"object-curly-newline": "off",
"object-curly-spacing": "off",
"object-shorthand": "error",
"one-var": "off",
"one-var-declaration-per-line": "error",
"operator-assignment": "error",
"operator-linebreak": "error",
"padded-blocks": "off",
"padding-line-between-statements": "error",
"prefer-arrow-callback": "error",
"prefer-const": "off",
"prefer-destructuring": "off",
"prefer-numeric-literals": "error",
"prefer-object-spread": "error",
"prefer-promise-reject-errors": "error",
"prefer-reflect": "off",
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "error",
"quote-props": "off",
"quotes": "off",
"radix": "error",
"require-atomic-updates": "warn",
"require-await": "off",
"require-jsdoc": "error",
"require-unicode-regexp": "error",
"rest-spread-spacing": "error",
"semi": "off",
"semi-spacing": "error",
"semi-style": [
"error",
"last"
],
"sort-imports": "off",
"sort-keys": "off",
"sort-vars": "error",
"space-before-blocks": "error",
"space-before-function-paren": "off",
"space-in-parens": [
"error",
"never"
],
"space-infix-ops": "off",
"space-unary-ops": "error",
"spaced-comment": [
"error",
"always"
],
"strict": "error",
"switch-colon-spacing": "error",
"symbol-description": "error",
"template-curly-spacing": [
"error",
"never"
],
"template-tag-spacing": "error",
"unicode-bom": [
"error",
"never"
],
"valid-jsdoc": "error",
"vars-on-top": "error",
"wrap-iife": "error",
"wrap-regex": "error",
"yield-star-spacing": "error",
"yoda": [
"error",
"never"
]
}
};

114
.gitignore vendored

@ -0,0 +1,114 @@
# ---> Node
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# FuseBox cache
.fusebox/
# ---> Vim
# Swap
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
.DS_Store
/node_modules/
/src/node_modules/@sapper/
yarn-error.log
/cypress/screenshots/
.DS_Store
/node_modules/
/src/node_modules/@sapper/
yarn-error.log
/cypress/screenshots/
/__sapper__/
.sessions
dump.rdb
devices/
*.mp4
*.webm
*.jpg

@ -0,0 +1 @@
There is no license given at all for this code. It is fully copyright like any creative work you find online. Think of this as being like a photographer's photo or a painting in a museum. You can look at it and marvel at it's glorious beauty, but you can't take it home or use it without permission.

@ -0,0 +1,10 @@
Notes for starter-project:
* Keep it simple and just an SPA with svelte-spa
* Include everything needed to get started with a full stack. Database, knex, sqlite3, etc.
* Logins, passwords, and payments included ready to go.
* Email templates and sending built-in and ready.
I installed most of the stuff so I think what I have to do is start building a first thing, then add
the components I pull out to it as I go.

@ -0,0 +1,24 @@
function Player() {
}
Player.prototype.play = function(song) {
this.currentlyPlayingSong = song;
this.isPlaying = true;
};
Player.prototype.pause = function() {
this.isPlaying = false;
};
Player.prototype.resume = function() {
if (this.isPlaying) {
throw new Error("song is already playing");
}
this.isPlaying = true;
};
Player.prototype.makeFavorite = function() {
this.currentlyPlayingSong.persistFavoriteStatus(true);
};
module.exports = Player;

@ -0,0 +1,9 @@
function Song() {
}
Song.prototype.persistFavoriteStatus = function(value) {
// something complicated
throw new Error("not yet implemented");
};
module.exports = Song;

7569
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,57 @@
{
"name": "svelte-app",
"version": "1.0.0",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public",
"test": "jasmine"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"axios": "^0.21.0",
"axios-cookiejar-support": "^1.0.1",
"chromedriver": "^87.0.0",
"faker": "^5.1.0",
"jasmine": "^3.6.3",
"maildev": "^1.1.0",
"node-notifier": "^8.0.0",
"pm2": "^4.5.0",
"pm2-logrotate": "^2.7.0",
"puppeteer": "^5.5.0",
"rollup": "^2.3.4",
"rollup-plugin-css-only": "^3.0.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
"svelte": "^3.0.0"
},
"dependencies": {
"Validator": "^1.1.2",
"bcrypt": "^5.0.0",
"body-parser": "^1.19.0",
"bull": "^3.20.0",
"compression": "^1.7.4",
"cookie-session": "^1.4.0",
"dayjs": "^1.9.6",
"email-deep-validator": "^3.3.0",
"eslint": "^7.14.0",
"express-session": "^1.17.1",
"knex": "^0.21.12",
"knex-paginate": "^1.2.3",
"morgan": "^1.10.0",
"node-fetch": "^2.6.1",
"nodemailer": "^6.4.16",
"passport": "^0.4.1",
"passport-local": "^1.0.0",
"pg": "^8.5.1",
"pino": "^6.7.0",
"pino-http": "^5.3.0",
"pino-pretty": "^4.3.0",
"polka": "^0.5.2",
"sirv-cli": "^1.0.0",
"sqlite3": "^5.0.0",
"svelte-spa-router": "^3.0.5"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -0,0 +1,449 @@
/* MVP.css v1.6.2 - https://github.com/andybrewer/mvp */
:root {
--border-radius: 5px;
--box-shadow: 2px 2px 10px;
--color: #000;
--color-accent: #111;
--color-inactive: #999;
--color-inactive-secondary: #fff;
--color-bg: #fff;
--color-bg-secondary: #eee;
--color-secondary: #666;
--color-secondary-accent: #888;
--color-shadow: #ddd;
--color-shadow-secondary: #fff;
--color-bg-inverted: #555;
--color-text: #000;
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
--hover-brightness: 1.2;
--justify-important: center;
--justify-normal: left;
--line-height: 1.5;
--width-card: 285px;
--width-card-medium: 460px;
--width-card-wide: 800px;
--width-content: 1090px;
}
[data-theme="dark"] {
--color: #bbb;
--color-accent: #fff;
--color-bg: #333;
--color-bg-secondary: #555;
--color-shadow-secondary: #333;
--color-secondary: #ddd;
--color-secondary-accent: #ddd;
--color-shadow: #bbb;
--color-text: #fff;
--color-text-secondary: #aaa;
--color-inactive: #666;
--color-bg-inverted: #fff;
}
/* Layout */
article aside {
background: var(--color-secondary-accent);
border-left: 4px solid var(--color-secondary);
padding: 0.01rem 0.8rem;
}
body {
background: var(--color-bg);
color: var(--color-text);
font-family: var(--font-family);
line-height: var(--line-height);
margin: 0;
overflow-x: hidden;
padding: 1rem 0;
}
footer,
header,
main {
margin: 0 auto;
max-width: var(--width-content);
}
hr {
background-color: var(--color-bg-secondary);
border: none;
height: 1px;
margin: 4rem 0;
}
section {
display: flex;
flex-wrap: wrap;
justify-content: var(--justify-important);
}
section aside {
border: 1px solid var(--color-bg-secondary);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow) var(--color-shadow);
margin: 1rem;
padding: 1.25rem;
width: var(--width-card);
}
section aside:hover {
box-shadow: var(--box-shadow) var(--color-bg-secondary);
}
section aside img {
max-width: 100%;
}
[hidden] {
display: none;
}
/* Headers */
article header,
div header,
main header {
padding-top: 0;
}
header {
text-align: var(--justify-important);
}
header a b,
header a em,
header a i,
header a strong {
margin-left: 0.5rem;
margin-right: 0.5rem;
}
header nav img {
margin: 1rem 0;
}
section header {
padding-top: 0;
width: 100%;
}
/* Nav */
nav {
align-items: center;
display: flex;
font-weight: bold;
justify-content: space-between;
}
nav ul {
list-style: none;
padding: 0;
}
nav ul li {
display: inline-block;
margin: 0 0.5rem;
position: relative;
text-align: left;
}
/* Nav Dropdown */
nav ul li:hover ul {
display: block;
}
nav ul li ul {
background: var(--color-bg);
border: 1px solid var(--color-bg-secondary);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow) var(--color-shadow);
display: none;
height: auto;
left: -2px;
padding: .5rem 1rem;
position: absolute;
top: 1.7rem;
white-space: nowrap;
width: auto;
}
nav ul li ul li,
nav ul li ul li a {
display: block;
}
/* Typography */
code,
samp {
background-color: var(--color-accent);
border-radius: var(--border-radius);
color: var(--color-text);
display: inline-block;
margin: 0 0.1rem;
padding: 0 0.5rem;
}
details {
margin: 1.3rem 0;
}
details summary {
font-weight: bold;
cursor: pointer;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: var(--line-height);
}
mark {
padding: 0.1rem;
}
ol li,
ul li {
padding: 0.2rem 0;
}
p {
padding: 0;
}
pre {
margin: 1rem 0;
max-width: var(--width-card-wide);
padding: 1rem 0;
}
pre code,
pre samp {
display: block;
max-width: var(--width-card-wide);
padding: 0.5rem 2rem;
white-space: pre-wrap;
}
small {
color: var(--color-text-secondary);
}
sup {
background-color: var(--color-secondary);
border-radius: var(--border-radius);
color: var(--color-bg);
font-size: xx-small;
font-weight: bold;
margin: 0.2rem;
padding: 0.2rem 0.3rem;
position: relative;
top: -2px;
}
/* Links */
a {
--text-decoration: none;
color: var(--color-secondary);
display: inline-block;
font-weight: bold;
text-decoration: var(--text-decoration);
}
a:hover {
filter: brightness(var(--hover-brightness));
text-decoration: underline;
}
a b,
a em,
a i,
a strong,
button {
border-radius: var(--border-radius);
display: inline-block;
font-size: medium;
font-weight: bold;
line-height: var(--line-height);
padding: 1rem 2rem;
}
button {
font-family: var(--font-family);
}
button:hover {
cursor: pointer;
filter: brightness(var(--hover-brightness));
}
a b,
a strong,
button {
background-color: var(--color);
border: 2px solid var(--color);
color: var(--color-bg);
}
a em,
a i {
border: 2px solid var(--color);
border-radius: var(--border-radius);
color: var(--color);
display: inline-block;
padding: 1rem 2rem;
}
/* Images */
figure {
margin: 0;
padding: 0;
}
figure img {
max-width: 100%;
}
figure figcaption {
color: var(--color-text-secondary);
}
/* Forms */
button:disabled,
input:disabled {
background: var(--color-bg-secondary);
border-color: var(--color-bg-secondary);
color: var(--color-text-secondary);
cursor: not-allowed;
}
button[disabled]:hover {
filter: none;
}
form {
border: 1px solid var(--color-bg-secondary);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow) var(--color-shadow);
display: block;
max-width: var(--width-card-wide);
min-width: var(--width-card);
padding: 1.5rem;
text-align: var(--justify-normal);
}
form header {
margin: 1.5rem 0;
padding: 1.5rem 0;
}
input,
label,
select,
textarea {
display: block;
font-size: inherit;
max-width: var(--width-card-wide);
}
input[type="checkbox"],
input[type="radio"] {
display: inline-block;
}
input[type="checkbox"]+label,
input[type="radio"]+label {
display: inline-block;
font-weight: normal;
position: relative;
top: 1px;
}
input,
select,
textarea {
border: 1px solid var(--color-bg-secondary);
border-radius: var(--border-radius);
margin-bottom: 1rem;
padding: 0.4rem 0.8rem;
}
input[readonly],
textarea[readonly] {
background-color: var(--color-bg-secondary);
}
label {
font-weight: bold;
margin-bottom: 0.2rem;
}
/* Tables */
table {
border: 1px solid var(--color-bg-secondary);
border-radius: var(--border-radius);
border-spacing: 0;
display: inline-block;
max-width: 100%;
overflow-x: auto;
padding: 0;
white-space: nowrap;
}
table td,
table th,
table tr {
padding: 0.4rem 0.8rem;
text-align: var(--justify-important);
}
table thead {
background-color: var(--color);
border-collapse: collapse;
border-radius: var(--border-radius);
color: var(--color-bg);
margin: 0;
padding: 0;
}
table thead th:first-child {
border-top-left-radius: var(--border-radius);
}
table thead th:last-child {
border-top-right-radius: var(--border-radius);
}
table thead th:first-child,
table tr td:first-child {
text-align: var(--justify-normal);
}
table tr:nth-child(even) {
background-color: var(--color-accent);
}
/* Quotes */
blockquote {
display: block;
font-size: x-large;
line-height: var(--line-height);
margin: 1rem auto;
max-width: var(--width-card-medium);
padding: 1.5rem 1rem;
text-align: var(--justify-important);
}
blockquote footer {
color: var(--color-text-secondary);
display: block;
font-size: small;
line-height: var(--line-height);
padding: 1.5rem 0;
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 58 KiB

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>fsck CSS</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/bundle.css'>
<script defer src='/build/bundle.js'></script>
</head>
<body>
</body>
</html>

@ -0,0 +1,76 @@
import svelte from 'rollup-plugin-svelte';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import css from 'rollup-plugin-css-only';
const production = !process.env.ROLLUP_WATCH;
function serve() {
let server;
function toExit() {
if (server) server.kill(0);
}
return {
writeBundle() {
if (server) return;
server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
process.on('SIGTERM', toExit);
process.on('exit', toExit);
}
};
}
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/bundle.js'
},
plugins: [
svelte({
compilerOptions: {
// enable run-time checks when not in production
dev: !production
}
}),
// we'll extract any component CSS out into
// a separate file - better for performance
css({ output: 'bundle.css' }),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};

@ -0,0 +1,117 @@
// @ts-check
/** This script modifies the project to support TS code in .svelte files like:
<script lang="ts">
export let name: string;
</script>
As well as validating the code for CI.
*/
/** To work on this script:
rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template
*/
const fs = require("fs")
const path = require("path")
const { argv } = require("process")
const projectRoot = argv[2] || path.join(__dirname, "..")
// Add deps to pkg.json
const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf8"))
packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
"svelte-check": "^1.0.0",
"svelte-preprocess": "^4.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"typescript": "^3.9.3",
"tslib": "^2.0.0",
"@tsconfig/svelte": "^1.0.0"
})
// Add script for checking
packageJSON.scripts = Object.assign(packageJSON.scripts, {
"validate": "svelte-check"
})
// Write the package JSON
fs.writeFileSync(path.join(projectRoot, "package.json"), JSON.stringify(packageJSON, null, " "))
// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too
const beforeMainJSPath = path.join(projectRoot, "src", "main.js")
const afterMainTSPath = path.join(projectRoot, "src", "main.ts")
fs.renameSync(beforeMainJSPath, afterMainTSPath)
// Switch the app.svelte file to use TS
const appSveltePath = path.join(projectRoot, "src", "App.svelte")
let appFile = fs.readFileSync(appSveltePath, "utf8")
appFile = appFile.replace("<script>", '<script lang="ts">')
appFile = appFile.replace("export let name;", 'export let name: string;')
fs.writeFileSync(appSveltePath, appFile)
// Edit rollup config
const rollupConfigPath = path.join(projectRoot, "rollup.config.js")
let rollupConfig = fs.readFileSync(rollupConfigPath, "utf8")
// Edit imports
rollupConfig = rollupConfig.replace(`'rollup-plugin-terser';`, `'rollup-plugin-terser';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';`)
// Replace name of entry point
rollupConfig = rollupConfig.replace(`'src/main.js'`, `'src/main.ts'`)
// Add preprocessor
rollupConfig = rollupConfig.replace(
'compilerOptions:',
'preprocess: sveltePreprocess(),\n\t\t\tcompilerOptions:'
);
// Add TypeScript
rollupConfig = rollupConfig.replace(
'commonjs(),',
'commonjs(),\n\t\ttypescript({\n\t\t\tsourceMap: !production,\n\t\t\tinlineSources: !production\n\t\t}),'
);
fs.writeFileSync(rollupConfigPath, rollupConfig)
// Add TSConfig
const tsconfig = `{
"extends": "@tsconfig/svelte/tsconfig.json",
"include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"]
}`
const tsconfigPath = path.join(projectRoot, "tsconfig.json")
fs.writeFileSync(tsconfigPath, tsconfig)
// Delete this script, but not during testing
if (!argv[2]) {
// Remove the script
fs.unlinkSync(path.join(__filename))
// Check for Mac's DS_store file, and if it's the only one left remove it
const remainingFiles = fs.readdirSync(path.join(__dirname))
if (remainingFiles.length === 1 && remainingFiles[0] === '.DS_store') {
fs.unlinkSync(path.join(__dirname, '.DS_store'))
}
// Check if the scripts folder is empty
if (fs.readdirSync(path.join(__dirname)).length === 0) {
// Remove the scripts folder
fs.rmdirSync(path.join(__dirname))
}
}
// Adds the extension recommendation
fs.mkdirSync(path.join(projectRoot, ".vscode"))
fs.writeFileSync(path.join(projectRoot, ".vscode", "extensions.json"), `{
"recommendations": ["svelte.svelte-vscode"]
}
`)
console.log("Converted to TypeScript.")
if (fs.existsSync(path.join(projectRoot, "node_modules"))) {
console.log("\nYou will need to re-run your dependency manager to get started.")
}

@ -0,0 +1,15 @@
beforeEach(function () {
jasmine.addMatchers({
toBePlaying: function () {
return {
compare: function (actual, expected) {
var player = actual;
return {
pass: player.currentlyPlayingSong === expected && player.isPlaying
}
}
};
}
});
});

@ -0,0 +1,60 @@
describe("Player", () => {
var Player = require('../../lib/jasmine_examples/Player');
var Song = require('../../lib/jasmine_examples/Song');
var player;
var song;
beforeEach(() => {
player = new Player();
song = new Song();
});
it("should be able to play a Song", () => {
player.play(song);
expect(player.currentlyPlayingSong).toEqual(song);
//demonstrates use of custom matcher
expect(player).toBePlaying(song);
});
describe("when song has been paused", () => {
beforeEach(() => {
player.play(song);
player.pause();
});
it("should indicate that the song is currently paused", () => {
expect(player.isPlaying).toBeFalsy();
// demonstrates use of 'not' with a custom matcher
expect(player).not.toBePlaying(song);
});
it("should be possible to resume", () => {
player.resume();
expect(player.isPlaying).toBeTruthy();
expect(player.currentlyPlayingSong).toEqual(song);
});
});
// demonstrates use of spies to intercept and test method calls
it("tells the current song if the user has made it a favorite", () => {
spyOn(song, 'persistFavoriteStatus');
player.play(song);
player.makeFavorite();
expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
});
//demonstrates use of expected exceptions
describe("#resume", () => {
it("should throw an exception if song is already playing", () => {
player.play(song);
expect(() => {
player.resume();
}).toThrowError("song is already playing");
});
});
});

@ -0,0 +1,11 @@
{
"spec_dir": "spec",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"helpers/**/*.js"
],
"stopSpecOnExpectationFailure": false,
"random": true
}

@ -0,0 +1 @@
<h1>About Page</h1>

@ -0,0 +1,59 @@
<script>
import Router from 'svelte-spa-router';
import routes from './routes';
import { link } from 'svelte-spa-router';
import Icon from './components/Icon.svelte';
import Darkmode from './components/Darkmode.svelte';
</script>
<svelte:head>
<title>LJSTHW Starter Template</title>
</svelte:head>
<style>
header {
}
main {
}
footer {
display: flex;
flex: flex-grow;
flex-direction: row;
}
footer nav {
flex: 1;
}
</style>
<header>
<nav>
<a href="/" use:link>
<Icon name="trash-2" size="64" />
</a>
<ul>
<li><a href="/demos" use:link>Demos</a></li>
<li><a href="/about" use:link>About</a></li>
</ul>
</nav>
</header>
<main>
<Router {routes } restoreScrollState={true} />
</main>
<hr>
<footer>
<nav>
<a href="/" use:link>
<p>Copyright (C) Big Corp.</p>
</a>
<ul>
<li><Icon name="twitter" size="32" /></li>
<li><Icon name="instagram" size="32" /></li>
<li><Darkmode /></li>
</ul>
</nav>
</footer>

@ -0,0 +1,128 @@
<script>
import {link} from 'svelte-spa-router';
import Icon from './components/Icon.svelte';
</script>
<style>
hero {
display: block;
padding: 3rem;
background-color: var(--color-bg-secondary);
}
hero h1 {
font-size: 3rem;
}
aside a {
--text-decoration: underline;
}
rationale {
display: flex;
flex-direction: column;
font-size: 1.5em;
padding-left: 4rem;
padding-right: 4rem;
}
</style>
<hero>
<h1>fsck CSS</h1>
<p>An experiment in cleaning up CSS and HTML with modern tools like <b>flexbox</b> and <b>grids</b>.</p>
</hero>
<hr>
<section>
<aside>
<h3>Remove Classes</h3>
<Icon name="code" size="64" />
<p>Using a classless style like <a href="https://andybrewer.github.io/mvp/">MVP.css</a>, you
bring back CSS specificity to its original intent.</p>
</aside>
<aside>
<h3>Add Flexbox</h3>
<Icon name="box" size="64" />
<p>Using <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">flexbox</a> you can layout anything you want without tons of divs.</p>
</aside>
<aside>
<h3>Modify with Variables</h3>
<Icon name="sliders" size="64" />
<p>Using CSS variables you can replace many uses of classes and ids, avoiding most specificity
issues. Try the dark mode button below.
</p>
</aside>
</section>
<rationale>
<section>
<h1>Cleaner CSS</h1>
</section>
<p>This website is nothing more than a set of small demos for the idea of
using flexbox and grids to clean up and simplify CSS. Most everything else
about CSS stays. Filters, transforms, attributes, and everything that
applies to the visual display of the components of a design. What gets
removed is <b>div</b> heavy, class heavy, not-semantic-at-all layout
systems cluttering the real information available through simple HTML
tags.</p>
<p>In short, if you're writing this:</p>
<section>
<aside>
<pre>
&lt;div class="grid col-1">
&lt;div class="card">
...
&lt;/div>
&lt;/div>
</pre>
</aside>
</section>
<p>You could write this if you use flexbox, grids, and variables:</p>
<section>
<aside>
<pre>
&lt;card>
...
&lt;/card>
</pre>
</aside>
</section>
<hr>
<section>
<p>I demonstrate the idea with a series of copies of existing websites and other layout problems
people frequently encounter. If you have a suggested layout challenge for me, then tell me on Twitter <a href="https://twitter.com/lzsthw">@lzsthw</a> and I'll give it a shot.
</p>
<a href="/demos" use:link><button>View The Demos</button></a>
</section>
<hr>
<h1>What's wrong with classes?</h1>
<p>There's nothing wrong with classes in CSS. How they're used in recent CSS subverts the normal specificity rules making CSS unecessarily difficult. The original specificity rules put the base design of a component at the tag level, then a <b>class</b> can be used to modify and extend the design, and an <b>id</b> can make this even more specific. In today's use of <b>div.class</b> heavy markup you lose this ability to alter the design as needed where its used, and instead you have to resort to <b>!important</b> and specificity hacking to change how something looks, or add more <b>div</b> with more <b>class</b>.</p>
<p>The other problem with <b>div.class</b> is it's more difficult to debug problems with the layout. Because you're relying on specificity that can come from anywhere in the cascade it's much more difficult to find exactly <b>what</b> bit of CSS is overriding your local decisions. If you've ever had to open the inspector in your browser to troll through CSS locations looking for the culprit then that's why. If the base design decisions are at the tag level, then your local <b>class</b> and <b>id</b> specifics will work as expected. You can also replace many uses of class as design modifiers with scoped CSS variables and reduce the use of <b>div.class</b> even further.</p>
<p>Finally, using <b>div.class</b> heavy layout systems polutes your markup with structure that's difficult to maintain and change over time. When you focus on using <b>truly</b> semantic named tags and follow specificity as intended then your HTML is lighter and easier to understand because it isn't full of <b>div.grid.col-1.col-mx-auto</b> class rules that really have nothing to do with the actual meaning of that particular visual element. With <b>flexbox</b> and <b>CSS grids</b> you don't need any layout divs, and can keep the HTML clean and semantic. This also ends up being more flexible with less or the same effort as using a pre-made grid system full of divs.</p>
<h1>Should we ban div.class?</h1>
<p>Hell no. The current problem of <b>too much</b> class based CSS is because of trends in recent years calling for everyone to irrationally ban some practice. Remember when everyone decided tables were evil? So then we banned tables and <b>grids</b> completely? Then nobody could do a layout without crazy tricks and JavaScript? Nobody wants a repeat of the anti-tables "semantic markup" war, so please don't ban div.class.</p>
<p>All this website does is demonstrate that you don't need <b>so much div.class</b>. You can scrap a lot of what you're using now to do layout and go with clean easy to read HTML that has a nicer flat structure and is easy to maintain, then judiciously add in any extra things you find you need like <b>div.class</b>. Treat <b>div.class</b> like salt. Right now you're pouring a whole box of it on your HTML when a little bit makes it taste better.</p>
<h1>How did it get like this?</h1>
<p>Before flexbox and CSS grids there really was no choice but to use <b>div.class</b> to make grids for layout. Since everyone in the CSS design world irrationally banned tables as a layout mechanism your only choice was to invent another table but call it <b>div.grid.col-1</b>.</p>
<p>Today we don't have to use divs for layout anymore. It's entirely possible to use flexbox and CSS grids to solve many layout problems, and to do it without too many irrelevant alterations to the meaningful HTML. You no longer have to wrap an <b>img</b> with 5 <b>div</b> tags just to overlay it on a background. You can write the <b>img</b>, maybe a <b>figure</b> and then use CSS to do anything you want to it.</p>
</rationale>

@ -0,0 +1 @@
<h1>Not found</h1>

@ -0,0 +1,30 @@
<style>
side {
background-color: var(--color-bg-secondary);
padding: 1em;
}
sidebar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
height: 60vh;
}
content {
padding: 1em;
display: flex;
flex-direction: column;
flex: grow;
}
</style>
<sidebar>
<side>
<slot name="side"></slot>
</side>
<content>
<slot name="content"></slot>
</content>
</sidebar>

@ -0,0 +1,42 @@
<script>
import Icon from '../components/Icon.svelte';
import { fade } from 'svelte/transition';
export let visible = false;
export let url = "";
const hide_code_button = () => {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
visible = false;
} else {
visible = true;
}
}
</script>
<svelte:window on:scroll={hide_code_button} />
<style>
code-bubble {
position: fixed;
bottom: 1em;
right: 1em;
}
code-bubble button {
background-color: var(--color-bg-secondary);
padding: 0.5em;
border-radius: 30%;
box-shadow: 4px 4px 4px var(--color-shadow);
}
</style>
{#if visible}
<code-bubble>
<a transition:fade href={ url }>
<button>
<Icon name="code" size="32" />
</button>
</a>
</code-bubble>
{/if}

@ -0,0 +1,31 @@
<script>
import Icon from './Icon.svelte';
import {onMount} from 'svelte';
export let theme = localStorage.getItem('theme') ? localStorage.getItem('theme') : 'light';
const set_theme = () => {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
}
const toggle = () => {
theme = theme == 'light' ? 'dark' : 'light';
set_theme();
}
onMount(() => {
set_theme()
});
</script>
{#if theme == 'dark'}
<span on:click={ () => toggle() }>
<Icon name="sunrise" size="32" />
</span>
{:else}
<span on:click={ () => toggle() }>
<Icon name="sunset" size="32"/>
</span>
{/if}

@ -0,0 +1,35 @@
<script>
export let size="24";
export let fill="none";
export let color="var(--color)";
export let light=false;
export let width="2";
export let linecap="round";
export let linejoin="round";
export let name;
export let inactive=false;
export let light_color = 'var(--color)';
</script>
<style lang="scss">
@import 'sass/_variables';
.inactive {
stroke: var(--color-inactive);
fill: var(--color-bg);
}
</style>
<span>
<svg class="icon-{name}" class:inactive="{inactive}"
width="{size}"
height="{size}"
fill="{fill}"
stroke="{light ? light_color : color}"
stroke-width="{width}"
stroke-linecap="{linecap}"
stroke-linejoin="{linejoin}"
>
<use xlink:href="/icons/feather-sprite.svg#{name}"/>
</svg>
</span>

@ -0,0 +1,102 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
</script>
<style>
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
}
header {
display: flex;
flex: flex-grow;
width: 100%;
flex-direction: row;
padding: unset;
}
nav {
flex: 1;
}
figure {
display: flex;
justify-content: center;
margin-top: 4rem;
}
search {
display: flex;
justify-content: center;
flex-direction: column;
margin-top: 2rem;
}
search input {
align-self: center;
width: 50ch;
}
search buttons {
display: flex;
justify-content: space-evenly;
}
button {
padding: 0.5rem;
background-color: #ddd;
border: unset;
color: #000;
font-weight: unset;
}
nav {
font-weight: normal;
}
a {
color: unset;
font-weight: normal;
}
</style>
<content>
<header>
<nav>
<nav-left>
<a>About</a>
<a>Store</a>
</nav-left>
<ul>
<li>Gmail</li>
<li>Image</li>
<li><Icon name="grid" color="#000" /></li>
<li><button>Sign In</button></li>
</ul>
</nav>
</header>
<figure>
<a href="/demos/google" use:link>
<img src="https://via.placeholder.com/500x200?text=Google+Doodle">
</a>
</figure>
<search>
<input type="text">
<buttons>
<button>Google Search</button>
<button>I'm Feeling Lucky</button>
</buttons>
</search>
</content>

@ -0,0 +1,143 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
let posts = [1,2,3,4,5,6,7,8,9,10];
let pins = [1,2,3,4];
</script>
<style>
a {
color: var(--color);
}
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
nav {
flex: 1;
}
button {
padding: 0.5rem;
}
profile {
display: flex;
flow-direction: row;
}
profile figure {
padding-right: 3rem;
padding-left: 3rem;
}
profile info {
display: flex;
flex-direction: column;
width: 100%;
}
profile info p {
padding: 0.5rem;
}
tabs nav {
justify-content: center;
border-top: 1px black solid;
border-color: var(--color-inactive);
}
posts {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
posts figure {
}
pins {
display: flex;
flex-direction: row;
justify-content: space-evenly;
margin-top: 1rem;
margin-bottom: 1rem;
}
</style>
<content>
<header>
<nav>
<b><Icon name="instagram" color="var(--color-text)" /> Instagram</b>
<input placeholder="Search">
<ul>
<li><button>Log In</button></li>
<li><a>Sign Up</a></li>
</ul>
</nav>
</header>
<profile>
<figure>
<img alt="Zed's Face" src="https://via.placeholder.com/256x256?text=Zed's Face">
</figure>
<info>
<p>
<b>zedshaw</b> <button>follow</button>
</p>
<p>
<b>280</b> posts <b>4,695 followers</b> <b>1,778 following</b>
</p>
<p><b>Zed A. Shaw</b></p>
<p>Painter in oil, watercolor, and pastel. I’m doing live streams of little paintings on Twitch:<br>
<a href="www.twitch.tv/zedashaw">www.twitch.tv/zedashaw</a>
</p>
</info>
</profile>
<pins>
{#each pins as pin}
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Story">
</figure>
{/each}
</pins>
<tabs>
<nav>
<ul>
<li><Icon name="grid" color="var(--color-text)" /> POSTS</li>
<li><Icon name="movie" color="var(--color-text)" /> REELS</li>
<li><Icon name="tv" color="var(--color-text)" /> TV</li>
<li><Icon name="user" color="var(--color-text)" /> TAGGED</li>
</ul>
</nav>
</tabs>
<posts>
{#each posts as post}
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/300x300?text=Post Image">
</figure>
{/each}
</posts>
</content>

@ -0,0 +1,24 @@
<style>
content {
display: flex;
flex: flex-shrink;
flex-grow: 1;
justify-content: center;
}
</style>
<content>
<spacer></spacer>
<form>
<header>Login</header>
<label for="username">Username</label>
<input type="text" id="username" name="username" size="32" placeholder="Username">
<label for="password">Password</label>
<input type="password" id="password" name="password" size="32" placeholder="Password">
<br>
<button type="submit">Login</button>
</form>
<spacer></spacer>
</content>

@ -0,0 +1,181 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
let samples = [1,2,3];
let lanes = [1,2,3,4,5];
let pin_sizes = [240, 180, 250, 580];
export let thumbnail = false;
const random_select = (from_array) => {
let min = Math.ceil(0);
let max = Math.floor(from_array.length);
let index = Math.floor(Math.random() * (max - min) + min);
return from_array[index];
}
const random_sample = (from_array, count) => {
let result = [];
for(let i = 0; i < count; i++) {
result.push(random_select(from_array));
}
return result;
}
</script>
<style>
:root {
--pin-red: #e60023;
}
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
header nav {
display: flex;
flex: 1;
}
header nav input {
width: 100%;
}
header nav button {
border-radius: 30px;
background-color: var(--color-bg-secondary);
border: unset;
color: var(--color-text);
padding-left: 1rem;
padding-right: 1rem;
}
header nav button#signup {
background-color: var(--pin-red);
color: var(--color-bg);
}
header nav a {
color: var(--text-color);
}
header logo {
color: var(--pin-red);
display: flex;
font-size: 1.2em;
}
header left {
display: flex;
justify-content: space-evenly;
padding: 1em;
flex: 2;
}
header input {
border-radius: 30px;
flex: 3;
padding: 1rem;
}
profile {
display: flex;
flex-direction: row;
width: 100%;
justify-content: center;
}
profile info {
margin-right: 2em;
}
profile h1 {
margin-bottom: unset;
font-size: 3em;
}
profile p {
margin-bottom: 0.5rem;
margin-top: 0.5rem;
}
pins {
display: flex;
flex-direction: row;
}
pins lane figure {
margin: 0.5rem;
}
pins lane figure img {
border-radius: 15px;
}
pins lane {
display: flex;
flex-direction: column;
}
</style>
<content>
<header>
<nav>
<left>
<logo><Icon name="pinterest" color="var(--color)" /> Pinterest</logo>
<a>Today</a>
<a>Explore</a>
</left>
<input placeholder="Search">
<ul>
<li><button>Log In</button></li>
<li><button id="signup">Sign Up</button></li>
</ul>
</nav>
</header>
{#if !thumbnail}
<profile>
<info>
<h1>Vincent van Gogh</h1>
<p>Collection by A Person</p>
<p><b>420</b> Pins • <b>3.59k</b> Followers</p>
<p>"I dream my painting and I paint my dream." ~ Vincent van Gogh
</info>
<figure>
<img alt="Zed's Face" src="https://via.placeholder.com/128x128?text=Zed's Face">
</figure>
</profile>
<pins>
{#each lanes as lane}
<lane>
{#each random_sample(pin_sizes, 10) as height}
<figure>
<img alt="Zed's Face" src="https://via.placeholder.com/240x{height}?text=Art240x{height}">
<figcaption>Something about Van Gogh {height} high.</figcaption>
</figure>
{/each}
</lane>
{/each}
</pins>
{/if}
</content>

@ -0,0 +1,327 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
import CodeBubble from '../components/CodeBubble.svelte';
let tweets = [1,2,3,4,5];
export let thumbnail = false;
</script>
<style>
content {
border: 1px solid #ddd;
display: flex;
flex-direction: row;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 0rem;
}
left {
display: flex;
flex-basis: 200px;
flex-direction: column;
border-right: 1px solid var(--color-bg-secondary);
padding: 1em;
font-size: 1.2em;
}
middle {
display: flex;
flex: 2;
flex-direction: column;
}
right {
display: flex;
flex-basis: 300px;
flex-direction: column;
border-left: 1px solid var(--color-bg-secondary);
}
header {
width: 100%;
text-align: unset;
}
header nav {
justify-content: left;
}
header nav h4 {
}
header nav back {
padding-left: 1rem;
padding-right: 1rem;
}
header nav name h4 {
margin: unset;
padding: unset;
}
header nav name span {
font-size: 0.8em;
font-weight: normal;
}
middle images {
display: grid;
grid-template-columns: 1fr min-content;
}
middle images figure#background {
z-index: -1;
grid-column: 1/2;
grid-row: 1/ span 2;
}
figure#background img {
height: 200px;
min-width: 500px;
}
middle images figure#avatar {
z-index: 5;
grid-column: 1/1;
grid-row: 2/2;
}
middle images figure#avatar img {
z-index: 5;
position: relative;
top: 90px;
left: 10px;
width: 128px;
}
figure#avatar img {
border-radius: 50%;
border: 5px white solid;
}
button#follow {
padding: 0.8rem;
border-radius: 30px;
border: 1px var(--color) solid;
background: var(--color-bg);
color: var(--color);
position: relative;
top: 60px;
left: 220px;
}
button#signup {
border-radius: 30px;
padding: 0.5rem;
width: 100%;
font-size: 0.9em;
}
aside#newperson p {
font-size: 0.8em;
color: var(--color-inactive);
}
recent-media {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1px;
}
profile {
margin-top: 6rem;
margin-left: 1rem;
margin-right: 1rem;
}
tweet {
display: flex;
flex-direction: row;
}
tweet post {
padding-left: 1em;
flex-grow: 2;
margin-bottom: 1rem;
}
tweet figure#avatar img {
min-width: 64px;
height: 64px;
}
tweet post h4 {
margin: unset;
}
tweet post p {
margin-bottom: 0.5rem;
}
tweet post actions {
display: flex;
justify-content: space-evenly;
}
hr {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
aside#trending {
background-color: var(--color-bg-secondary);
padding: 0px;
}
aside#trending h3 {
margin-left: 1em;
}
aside#trending a {
margin-left: 1em;
color: var(--color);
}
aside#trending li {
border-top: 1px var(--color-bg) solid;
list-style-type: none;
list-style-position: outside;
padding: 0.3rem;
}
aside#trending ul {
padding-left: 0px;
}
</style>
<content>
{#if !thumbnail}
<left>
<Icon name="twitter" color="var(--color)" />
<h4># Explore</h4>
<h4><Icon name="settings" color="var(--color-text)" /> Settings</h4>
</left>
{/if}
<middle>
<header>
<nav>
<back><Icon name="arrow-left" /></back>
<name>
<h4>Zed A. Shaw, Writer</h4>
<span>7,754 Tweets</span>
</name>
</nav>
</header>
<images>
<figure id="background">
<img src="/header_pic.jpg">
</figure>
<figure id="avatar">
<img src="/profile_pic.jpg">
<button id="follow">Follow</button>
</figure>
</images>
<profile>
<h3>Zed A. Shaw, Writer</h3>
<p>@lzsthw</p>
<p>The author of The Hard Way Series published by Addison/Wesley including Learn Python The Hard Way and many more. Follow me here for coding tips and book news.</p>
<p><Icon name="map" size="24" color="var(--color-bg-secondary)" /> Some Place, KY <Icon name="link" size="24" color="var(--color-bg-secondary)" /> <a>learnjsthehardway.org</a> <Icon name="calendar" size="24" color="var(--color-bg-secondary)" /> Joined Jan, 1999. </p>
<p><b>167</b> Following <b>10.4k</b> Followers</p>
</profile>
{#if !thumbnail}
<hr>
<tweets>
{#each tweets as tweet}
<tweet>
<figure id="avatar">
<img alt="Stock photo" src="/profile_pic.jpg">
</figure>
<post>
<h4>Zed A. Shaw, Writer</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam: <br>
<a>quis nostrud exercitation</a> ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<actions>
<Icon size="16" name="message-circle" color="var(--color-inactive)" /> 2
<Icon size="16" name="repeat" color="var(--color-inactive)" /> 1
<Icon size="16" name="heart" color="var(--color-inactive)" /> 12
<Icon size="16" name="upload" color="var(--color-inactive)" />
</actions>
</post>
<Icon name="more-horizontal" />
</tweet>
{/each}
</tweets>
{/if}
</middle>
{#if !thumbnail}
<right>
<input placeholder="Search Twitter" />
<section>
<aside id="newperson">
<h3>New to Twitter?</h3>
<p>Sign up now to get your own personalized hate stream!</p>
<button id="signup">Sign Up</button>
</aside>
<aside>
<recent-media>
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Media">
</figure>
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Media">
</figure>
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Media">
</figure>
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Media">
</figure>
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Media">
</figure>
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Media">
</figure>
</recent-media>
</aside>
<aside id="trending">
<h3>You Might Like</h3>
<ul>
<li>Card Person</li>
<li>Card Person</li>
<li>Card Person</li>
</ul>
<a>Show More</a>
</aside>
<aside id="trending">
<h3>What's Happening</h3>
<ul>
<li>News news news.</li>
<li>News news news.</li>
<li>News news news.</li>
<li>News news news.</li>
<li>News news news.</li>
</ul>
</aside>
</section>
</right>
{/if}
</content>
<CodeBubble url="https://git.learnjsthehardway.com/" />

@ -0,0 +1,155 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
let posts = [1,2,3,4,5,6,7,8,9];
let related = [1,2,3,4];
</script>
<style>
a {
color: var(--color);
}
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
padding-top: 0px;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
header nav {
flex: 1;
}
header nav input {
display: flex;
flex-grow: 2;
margin: 1rem;
}
header nav logo {
font-weight: bold;
font-size: 1rem;
color: black;
}
header nav button {
background-color: var(--color-bg);
color: var(--color);
padding: 0.5rem;
}
profile {
display: flex;
flow-direction: row;
}
profile figure {
padding-right: 3rem;
padding-left: 3rem;
}
profile info {
display: flex;
flex-direction: column;
width: 100%;
}
profile info p {
padding: 0.5rem;
}
tabs nav {
justify-content: center;
border-top: 1px black solid;
border-color: var(--color-inactive);
}
posts {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
posts figure {
}
related {
display: flex;
flex-direction: row;
justify-content: space-evenly;
margin-top: 1rem;
margin-bottom: 1rem;
}
nav a,a:visited,a:active {
text-decoration: none;
color: var(--color-text);
}
</style>
<content>
<header>
<nav>
<b><a id="logo-link" href="/demos/xoracademy" use:link><Icon name="edit-3" color="var(--color-text)" /> Xor.Academy</a></b>
<input placeholder="Search">
<ul>
<li><a href="/demos/login" use:link><button>Log In</button></a></li>
<li><a>Sign Up</a></li>
</ul>
</nav>
</header>
<profile>
<figure>
<img alt="Module Thumb" src="https://via.placeholder.com/256x256?text=Module+Thumb">
</figure>
<info>
<p>
<button>Follow</button>
</p>
<p>
<b>10</b> videos <b>4,695 followers</b>
</p>
<h3>Drawing Level 1</h3>
<p>The first module you should take. It covers the basics of drawing and how to get started
making drawing a habit.
</p>
</info>
</profile>
<related>
{#each related as pin}
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Related">
</figure>
{/each}
</related>
<posts>
{#each posts as post}
<figure>
<a href="/demos/xoracademy/watch" use:link>
<img alt="Placeholder" src="https://via.placeholder.com/300x300?text=Video Thumb">
</a>
</figure>
{/each}
</posts>
</content>

@ -0,0 +1,241 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
let cards = [1,2,3,4];
</script>
<style>
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
--sub-color: #999;
--title-color: #000;
}
main {
display: flex;
flex-direction: column;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
header nav {
flex: 1;
margin-left: 1rem;
margin-right: 1rem;
}
header nav input {
display: flex;
flex-grow: 2;
margin: 1rem;
}
header nav logo {
font-weight: bold;
font-size: 1rem;
color: black;
}
header nav button {
background-color: var(--color-bg);
color: var(--color);
padding: 0.5rem;
}
hr {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
figcaption {
padding: 1rem;
}
figcaption a {
color: var(--color-secondary);
font-size: 0.8em;
}
figcaption p {
font-weight: bold;
margin-top: unset;
}
figcaption video-actions {
color: var(--sub-color);
font-weight: unset;
display: flex;
flex-grow: 1;
justify-content: space-between;
}
card {
display: flex;
margin-top: 0.2rem;
margin-bottom: 0.2rem;
--img-width: 120px;
--img-height: 80px;
--font-size: 0.8em;
}
card img {
width: var(--img-width);
height: var(--img-height);
}
card info {
display: flex;
flex-direction: column;
padding: 0.2rem;
color: var(--sub-color);
font-size: var(--font-size);
}
card info h4 {
font-weight: bold;
color: var(--title-color);
margin: 0px;
}
card.small {
--img-width: 100px;
--img-height: 70px;
--font-size: 0.6em;
}
promotion {
display: flex;
flex-direction: column;
}
promotion card {
--img-width:4rem;
--img-height:4rem;
}
promotion content {
border: unset;
padding-left: 4rem;
}
comments nav {
justify-content: left;
font-weight: unset;
}
comments nav sort {
color: var(--sub-color);
}
comments card {
color: black;
--img-width:4rem;
--img-height:4rem;
--font-size: 1em;
}
comments card p {
color: black;
}
comments card reply {
color: var(--color);
}
lower {
padding: 1rem;
}
nav#vote-nav {
justify-content: flex-end;
}
nav a,a:visited,a:active {
text-decoration: none;
color: var(--color-text);
}
</style>
<content>
<header>
<nav>
<b><a href="/demos/xoracademy" use:link><Icon name="edit-3" color="var(--color-text)" /> Xor.Academy</a></b>
<input placeholder="Search">
<ul>
<li><a href="/demos/login" use:link><button>Log In</button></a></li>
<li><a>Sign Up</a></li>
</ul>
</nav>
</header>
<main>
<figure>
<img src="https://via.placeholder.com/1280x720?text=Video">
<figcaption>
<a>#tag</a> <a>#anothertag</a>
<p>Title And Stuff</p>
<video-actions>
<likes>Likes Other Stats</likes>
<video-buttons>
<Icon name="thumbs-up" color="#999" /> 1.1K
<Icon name="thumbs-down" color="#999" /> 22
<Icon name="corner-up-right" color="#999" /> SHARE
<Icon name="menu" color="#999" /> SAVE
<Icon name="vertical-more" />
</video-buttons>
</video-actions>
</figcaption>
</figure>
<lower>
<promotion>
<nav>
<card>
<img src="https://via.placeholder.com/64x64?text=ME">
<info>
<h4>Zed A. Shaw</h4>
<subs>1 subscriber</subs>
</card>
<button id="subscribe">SUBSCRIBE</button>
</nav>
<content>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur
</content>
</promotion>
<hr>
<comments>
<nav>
<span>125 Comments</span> <sort><Icon name="bar-chart" color="var(--sub-color)" /> SORT BY</sort>
</nav>
{#each cards as card}
<card>
<img src="https://via.placeholder.com/64x64?text=Person">
<info>
<h4>Guys</h4>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque</p>
<nav id="vote-nav">
<Icon name="thumbs-up" color="var(--sub-color)" /> 233
</nav>
<reply><Icon name="chevron-down" /> View replies</reply>
</info>
</card>
{/each}
</comments>
</lower>
</main>
</content>

@ -0,0 +1,279 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
let cards = [1,2,3,4];
// this is used for display in the main grid
export let thumbnail = false;
</script>
<style>
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
--sub-color: #999;
--title-color: #000;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
nav {
flex: 1;
}
nav input {
display: flex;
flex-grow: 2;
margin: 1rem;
}
logo {
font-weight: bold;
font-size: 1rem;
color: black;
}
button {
background-color: var(--color-bg);
color: var(--color);
padding: 0.5rem;
border-radius: 2px;
}
hr {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
main {
display: flex;
flex-direction: row;
}
right {
margin-left: 0.5rem;
}
left {
margin-right: 0.5rem;
}
figcaption a {
color: var(--color-secondary);
font-size: 0.8em;
}
figcaption p {
font-weight: bold;
margin-top: unset;
}
figcaption video-actions {
color: var(--sub-color);
font-weight: unset;
display: flex;
flex-grow: 1;
justify-content: space-between;
}
card {
display: flex;
margin-top: 0.2rem;
margin-bottom: 0.2rem;
--img-width: 120px;
--img-height: 80px;
--font-size: 0.8em;
}
card img {
width: var(--img-width);
height: var(--img-height);
}
card info {
display: flex;
flex-direction: column;
padding: 0.2rem;
color: var(--sub-color);
font-size: var(--font-size);
}
card info h4 {
font-weight: bold;
color: var(--title-color);
margin: 0px;
}
card.small {
--img-width: 100px;
--img-height: 70px;
--font-size: 0.6em;
}
promotion {
display: flex;
flex-direction: column;
}
promotion nav button#subscribe {
background-color: red;
color: #fff;
border: unset;
}
promotion card {
--img-width:4rem;
--img-height:4rem;
}
promotion content {
border: unset;
padding-left: 4rem;
}
comments nav {
justify-content: left;
font-weight: unset;
}
comments nav sort {
color: var(--sub-color);
}
comments card {
color: black;
--img-width:4rem;
--img-height:4rem;
--font-size: 1em;
}
comments card p {
color: black;
}
comments card reply {
color: var(--color);
}
</style>
<content>
<header>
<nav>
<nav-left>
<a><Icon name="menu" /> <Icon name="youtube" /> <logo>Youtube</logo></a>
</nav-left>
<input id="search" placeholder="Search" name="search">
<ul>
<li><Icon name="camera" color="#000" /></li>
<li><Icon name="more-vertical" color="#000" /></li>
<li><Icon name="grid" color="#000" /></li>
<li><button><Icon name="user" /> Sign In</button></li>
</ul>
</nav>
</header>
<main>
<left>
<figure>
<a href="/demos/google" use:link>
<img src="https://via.placeholder.com/800x450?text=Video">
</a>
<figcaption>
<a>#tag</a> <a>#anothertag</a>
<p>Title And Stuff</p>
<video-actions>
<likes>Stats Stats</likes>
<video-buttons>
<Icon name="thumbs-up" color="#999" /> 1.1K
<Icon name="thumbs-down" color="#999" /> 22
<Icon name="corner-up-right" color="#999" /> SHARE
<Icon name="menu" color="#999" /> SAVE
<Icon name="vertical-more" />
</video-buttons>
</video-actions>
</figcaption>
</figure>
<hr>
<promotion>
<nav>
<card>
<img src="https://via.placeholder.com/64x64?text=ME">
<info>
<h4>Zed A. Shaw</h4>
<subs>1 subscriber</subs>
</card>
<button id="subscribe">SUBSCRIBE</button>
</nav>
<content>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur
</content>
</promotion>
<hr>
<comments>
<nav>
<span>125 Comments</span> <sort><Icon name="bar-chart" color="var(--sub-color)" /> SORT BY</sort>
</nav>
{#each cards as card}
<card>
<img src="https://via.placeholder.com/64x64?text=Person">
<info>
<h4>Guys</h4>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque</p>
<nav>
<Icon name="thumbs-up" color="var(--sub-color)" /> 233
<Icon name="thumbs-down" color="var(--sub-color)" /> 1
</nav>
<reply><Icon name="chevron-down" /> View replies</reply>
</info>
</card>
{/each}
</comments>
</left>
<right>
{#each cards as card}
<card class="small">
<img src="https://via.placeholder.com/120x80?text=Thumb">
<info>
<h4>Video Thumb Title</h4>
<author>Zed</author>
<views>1.1M views</views>
<date>2 years ago</date>
</info>
</card>
{/each}
<figure>
<a href="/demos/google" use:link>
<img src="https://via.placeholder.com/300x150?text=Advert">
</a>
</figure>
{#each cards as card}
<card>
<img src="https://via.placeholder.com/120x80?text=Thumb">
<info>
<h4>Video Thumb Title</h4>
<author>Zed</author>
<views>1.1M views</views>
<date>2 years ago</date>
</info>
</card>
{/each}
</right>
</main>
</content>

@ -0,0 +1,81 @@
<script>
import Google from '../thumbs/Google.svelte';
import Twitter from '../thumbs/Twitter.svelte';
import Youtube from '../thumbs/Youtube.svelte';
import Instagram from '../thumbs/Instagram.svelte';
import Pinterest from '../thumbs/Pinterest.svelte';
import Login from '../thumbs/Login.svelte';
import {push} from 'svelte-spa-router';
</script>
<style>
images {
display: grid;
grid-template-columns: 1fr 1fr;
}
:global(figure:hover content) {
filter: grayscale(1) blur(6px);
background-color: var(--color-bg-secondary);
cursor: pointer;
}
figure {
padding: 0.5em;
position: sticky;
}
figure figcaption {
display: none;
color: var(--color-text);
font-size: 6em;
filter: drop-shadow(10px 5px 5px var(--color-shadow-secondary));
font-weight: bold;
}
figure:hover figcaption {
display: flex;
padding-top: 2em;
width: 100%;
justify-content: center;
position: absolute;
top: 0;
left: 0;
}
</style>
<h1>A Compendium of Layout Demos</h1>
<images>
<figure on:click={ () => push('/demos/google') }>
<Google />
<figcaption>Google</figcaption>
</figure>
<figure on:click={ () => push('/demos/twitter') }>
<Twitter />
<figcaption>Twitter</figcaption>
</figure>
<figure id="main" on:click={ () => push('/demos/login') }>
<Login />
<figcaption>Basic Login</figcaption>
</figure>
<figure on:click={ () => push('/demos/youtube') }>
<Youtube />
<figcaption>Youtube</figcaption>
</figure>
<figure on:click={ () => push('/demos/instagram') }>
<Instagram />
<figcaption>Instagram</figcaption>
</figure>
<figure on:click={ () => push('/demos/pinterest') }>
<Pinterest />
<figcaption>Pinterest</figcaption>
</figure>
</images>

@ -0,0 +1,10 @@
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;

@ -0,0 +1,27 @@
import Home from "./Home.svelte";
import Demos from "./demos/index.svelte";
import About from "./About.svelte";
import NotFound from "./NotFound.svelte";
import Google from "./demos/Google.svelte";
import Twitter from "./demos/Twitter.svelte";
import Youtube from "./demos/Youtube.svelte";
import Instagram from "./demos/Instagram.svelte";
import Pinterest from "./demos/Pinterest.svelte";
import XorAcademy from "./demos/XorAcademy.svelte";
import XorAcademyWatch from "./demos/XorAcademyWatch.svelte";
import Login from "./demos/Login.svelte";
export default {
"/": Home,
"/about": About,
"/demos": Demos,
"/demos/login": Login,
"/demos/google": Google,
"/demos/twitter": Twitter,
"/demos/youtube": Youtube,
"/demos/instagram": Instagram,
"/demos/pinterest": Pinterest,
"/demos/xoracademy": XorAcademy,
"/demos/xoracademy/watch": XorAcademyWatch,
"*": NotFound,
}

@ -0,0 +1,101 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
</script>
<style>
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
}
header {
display: flex;
flex: flex-grow;
width: 100%;
flex-direction: row;
padding: unset;
}
nav {
flex: 1;
}
figure {
display: flex;
justify-content: center;
margin-top: 4rem;
}
search {
display: flex;
justify-content: center;
flex-direction: column;
margin-top: 2rem;
}
search input {
align-self: center;
width: 50ch;
}
search buttons {
display: flex;
justify-content: space-evenly;
}
button {
padding: 0.5rem;
background-color: #ddd;
border: unset;
color: #000;
font-weight: unset;
}
nav {
font-weight: normal;
}
a {
color: unset;
font-weight: normal;
}
</style>
<content>
<header>
<nav>
<nav-left>
<a>About</a>
<a>Store</a>
</nav-left>
<ul>
<li>Gmail</li>
<li>Image</li>
<li><Icon name="grid" color="#000" /></li>
<li><button>Sign In</button></li>
</ul>
</nav>
</header>
<figure>
<a href="/demos/google" use:link>
<img src="https://via.placeholder.com/500x200?text=Google+Doodle">
</a>
</figure>
<search>
<input type="text">
<buttons>
<button>Google Search</button>
<button>I'm Feeling Lucky</button>
</buttons>
</search>
</content>

@ -0,0 +1,114 @@
<script>
import { link } from 'svelte-spa-router';
import Icon from '../components/Icon.svelte';
let pins = [1,2,3,4];
</script>
<style>
a {
color: var(--color);
}
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
nav {
flex: 1;
}
button {
padding: 0.5rem;
}
profile {
display: flex;
flow-direction: row;
}
profile figure {
padding-right: 3rem;
padding-left: 3rem;
}
profile info {
display: flex;
flex-direction: column;
width: 100%;
}
profile info p {
padding: 0.5rem;
}
tabs nav {
justify-content: center;
border-top: 1px black solid;
border-color: var(--color-inactive);
}
pins {
display: flex;
flex-direction: row;
justify-content: space-evenly;
margin-top: 1rem;
margin-bottom: 1rem;
}
</style>
<content>
<header>
<nav>
<b><Icon name="instagram" color="var(--color-text)" /> Instagram</b>
<input placeholder="Search">
<ul>
<li><button>Log In</button></li>
<li><a>Sign Up</a></li>
</ul>
</nav>
</header>
<profile>
<figure>
<img alt="Zed's Face" src="https://via.placeholder.com/256x256?text=Zed's Face">
</figure>
<info>
<p>
<b>zedshaw</b> <button>follow</button>
</p>
<p>
<b>280</b> posts <b>4,695 followers</b> <b>1,778 following</b>
</p>
<p><b>Zed A. Shaw</b></p>
<p>Painter in oil, watercolor, and pastel. I’m doing live streams of little paintings on Twitch:<br>
<a href="www.twitch.tv/zedashaw">www.twitch.tv/zedashaw</a>
</p>
</info>
</profile>
<pins>
{#each pins as pin}
<figure>
<img alt="Stock photo" src="https://via.placeholder.com/82x82?text=Story">
</figure>
{/each}
</pins>
</content>

@ -0,0 +1,24 @@
<style>
content {
display: flex;
flex: flex-shrink;
flex-grow: 1;
justify-content: center;
}
</style>
<content>
<spacer></spacer>
<form>
<header>Login</header>
<label for="username">Username</label>
<input type="text" id="username" name="username" size="32" placeholder="Username">
<label for="password">Password</label>
<input type="password" id="password" name="password" size="32" placeholder="Password">
<br>
<button type="submit">Login</button>
</form>
<spacer></spacer>
</content>

@ -0,0 +1,126 @@
<script>
import Icon from '../components/Icon.svelte';
</script>
<style>
:root {
--pin-red: #e60023;
}
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
header nav {
display: flex;
flex: 1;
}
header nav input {
width: 100%;
}
header nav button {
border-radius: 30px;
background-color: var(--color-bg-secondary);
border: unset;
color: var(--color-text);
padding-left: 1rem;
padding-right: 1rem;
}
header nav button#signup {
background-color: var(--pin-red);
color: var(--color-bg);
}
header nav a {
color: var(--text-color);
}
header logo {
color: var(--pin-red);
display: flex;
font-size: 1.2em;
}
header left {
display: flex;
justify-content: space-evenly;
padding: 1em;
flex: 2;
}
header input {
border-radius: 30px;
flex: 3;
padding: 1rem;
}
profile {
display: flex;
flex-direction: row;
width: 100%;
justify-content: center;
}
profile info {
margin-right: 2em;
}
profile h1 {
margin-bottom: unset;
font-size: 3em;
}
profile p {
margin-bottom: 0.5rem;
margin-top: 0.5rem;
}
</style>
<content>
<header>
<nav>
<left>
<logo><Icon name="pinterest" color="var(--color)" /> Pinterest</logo>
<a>Today</a>
<a>Explore</a>
</left>
<input placeholder="Search">
<ul>
<li><button>Log In</button></li>
<li><button id="signup">Sign Up</button></li>
</ul>
</nav>
</header>
<profile>
<info>
<h1>Vincent van Gogh</h1>
<p>Collection by A Person</p>
<p><b>420</b> Pins • <b>3.59k</b> Followers</p>
<p>"I dream my painting and I paint my dream." ~ Vincent van Gogh
</info>
<figure>
<img alt="Zed's Face" src="https://via.placeholder.com/128x128?text=Zed's Face">
</figure>
</profile>
</content>

@ -0,0 +1,130 @@
<script>
import Icon from '../components/Icon.svelte';
</script>
<style>
content {
border: 1px solid #ddd;
display: flex;
flex-direction: row;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 0rem;
}
middle {
display: flex;
flex: 2;
flex-direction: column;
}
header {
width: 100%;
text-align: unset;
}
header nav {
justify-content: left;
}
header nav back {
padding-left: 1rem;
padding-right: 1rem;
}
header nav name h4 {
margin: unset;
padding: unset;
}
header nav name span {
font-size: 0.8em;
font-weight: normal;
}
middle images {
display: grid;
grid-template-columns: 1fr min-content;
}
middle images figure#background {
z-index: -1;
grid-column: 1/2;
grid-row: 1/ span 2;
}
figure#background img {
height: 200px;
min-width: 500px;
}
middle images figure#avatar {
z-index: 5;
grid-column: 1/1;
grid-row: 2/2;
}
middle images figure#avatar img {
z-index: 5;
position: relative;
top: 90px;
left: 10px;
width: 128px;
}
figure#avatar img {
border-radius: 50%;
border: 5px white solid;
}
button#follow {
padding: 0.8rem;
border-radius: 30px;
border: 1px var(--color) solid;
background: var(--color-bg);
color: var(--color);
position: relative;
top: 60px;
left: 220px;
}
profile {
margin-top: 6rem;
margin-left: 1rem;
margin-right: 1rem;
}
</style>
<content>
<middle>
<header>
<nav>
<back><Icon name="arrow-left" /></back>
<name>
<h4>Zed A. Shaw, Writer</h4>
<span>7,754 Tweets</span>
</name>
</nav>
</header>
<images>
<figure id="background">
<img alt="Profile background" src="/header_pic.jpg">
</figure>
<figure id="avatar">
<img alt="Profile picture" src="/profile_pic.jpg">
<button id="follow">Follow</button>
</figure>
</images>
<profile>
<h3>Zed A. Shaw, Writer</h3>
<p>@lzsthw</p>
<p>The author of The Hard Way Series published by Addison/Wesley including Learn Python The Hard Way and many more. Follow me here for coding tips and book news.</p>
<p><Icon name="map" size="24" color="var(--color-bg-secondary)" /> Some Place, KY <Icon name="link" size="24" color="var(--color-bg-secondary)" /> <a>learnjsthehardway.org</a> <Icon name="calendar" size="24" color="var(--color-bg-secondary)" /> Joined Jan, 1999. </p>
<p><b>167</b> Following <b>10.4k</b> Followers</p>
</profile>
</content>

@ -0,0 +1,110 @@
<script>
import Icon from '../components/Icon.svelte';
let cards = [1,2,3,4];
</script>
<style>
content {
border: 1px solid #ddd;
display: flex;
flex-direction: column;
flex: flex-grow;
flex-basis: 100%;
grid-column: 1/3;
padding: 1rem;
--sub-color: #999;
--title-color: #000;
}
header {
display: flex;
width: 100%;
flex-direction: row;
}
nav {
flex: 1;
}
nav input {
display: flex;
flex-grow: 2;
margin: 1rem;
}
logo {
font-weight: bold;
font-size: 1rem;
color: black;
}
button {
background-color: var(--color-bg);
color: var(--color);
padding: 0.5rem;
border-radius: 2px;
}
main {
display: flex;
flex-direction: row;
}
figcaption a {
color: var(--color-secondary);
font-size: 0.8em;
}
figcaption p {
font-weight: bold;
margin-top: unset;
}
figcaption video-actions {
color: var(--sub-color);
font-weight: unset;
display: flex;
flex-grow: 1;
justify-content: space-between;
}
</style>
<content>
<header>
<nav>
<nav-left>
<a><Icon name="menu" /> <Icon name="youtube" /> <logo>Youtube</logo></a>
</nav-left>
<input id="search" placeholder="Search" name="search">
<ul>
<li><Icon name="camera" color="#000" /></li>
<li><Icon name="more-vertical" color="#000" /></li>
<li><Icon name="grid" color="#000" /></li>
<li><button><Icon name="user" /> Sign In</button></li>
</ul>
</nav>
</header>
<main>
<left>
<figure>
<img src="https://via.placeholder.com/800x450?text=Video">
<figcaption>
<a>#tag</a> <a>#anothertag</a>
<p>Title And Stuff</p>
<video-actions>
<likes>Stats Stats</likes>
<video-buttons>
<Icon name="thumbs-up" color="#999" /> 1.1K
<Icon name="thumbs-down" color="#999" /> 22
<Icon name="corner-up-right" color="#999" /> SHARE
<Icon name="menu" color="#999" /> SAVE
<Icon name="vertical-more" />
</video-buttons>
</video-actions>
</figcaption>
</figure>
</main>
</content>
Loading…
Cancel
Save