├── .gitignore ├── README.md ├── app ├── assets │ ├── ink.mov │ ├── ink.mp4 │ ├── ink.ogv │ └── ink.webm ├── components │ ├── _vars.css │ ├── body.css │ ├── button.css │ ├── colors.css │ ├── depth.css │ ├── dividers.css │ ├── layouts.css │ ├── lists.css │ ├── picture.css │ ├── prism.css │ ├── quotes.css │ ├── slyd-arrows.css │ ├── slyd-group.css │ ├── slyd.css │ ├── slyds.css │ ├── typography.css │ └── video.css ├── images │ ├── aliens.png │ └── starwars.png ├── index.html ├── index.js ├── manifest.json ├── service-worker.js └── slyd │ ├── index.css │ ├── index.js │ ├── slyd-manager.js │ └── slyd-observer.js ├── dist ├── slyd.css └── slyd.js ├── package-lock.json ├── package.json ├── postcss.config.js └── rollup.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | app/slyd.css 3 | app/slyd.js 4 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Netlify Status](https://api.netlify.com/api/v1/badges/634baf91-9509-4983-8e3b-c7093c29603d/deploy-status)](https://app.netlify.com/sites/slyd/deploys) 2 | 3 | ## Getting Started 4 | Load bundles from a url or use modules from NPM. 5 | 6 | > Note: there aren't any docs yet, just a demo site. The demo site is the best docs you have for the time being as it's sorta documentation by example. I'll improve this! 7 | 8 |
9 | 10 | ##### CDN 11 | 1. `import 'https://slyd.netlify.com/slyd.js';` 12 | 1. `@import 'https://slyd.netlify.com/slyd.css';` 13 | 14 | ##### NPM 15 | 16 | 1. `npm i slyd` 17 | 1. `import 'slyd';` // use es module 18 | 1. `@import 'slyd';` // use postcss module 19 | 20 | ##### Starter Kit 21 | 22 | 1. Clone and go with this [Slyd starter](https://github.com/argyleink/slyd-starter) 23 | 24 | ##### Pika 25 | 1. coming soon 26 | 27 |
28 |
29 | 30 | Start making ``'s by adding HTML to your page. 31 | 32 | ```html 33 | 34 | 35 |

Slide 1

36 |

subtitle

37 |
38 | 39 | 40 | 41 | 42 |

Slide 2

43 |

is in a vertical slide list

44 |
45 | 46 | ... 47 | 48 |
49 | 50 | ... 51 |
52 | ``` 53 | -------------------------------------------------------------------------------- /app/assets/ink.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/argyleink/slyd/1264ce5fa90b10d514e58e6c4d27f48ca7ae0752/app/assets/ink.mov -------------------------------------------------------------------------------- /app/assets/ink.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/argyleink/slyd/1264ce5fa90b10d514e58e6c4d27f48ca7ae0752/app/assets/ink.mp4 -------------------------------------------------------------------------------- /app/assets/ink.ogv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/argyleink/slyd/1264ce5fa90b10d514e58e6c4d27f48ca7ae0752/app/assets/ink.ogv -------------------------------------------------------------------------------- /app/assets/ink.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/argyleink/slyd/1264ce5fa90b10d514e58e6c4d27f48ca7ae0752/app/assets/ink.webm -------------------------------------------------------------------------------- /app/components/_vars.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --sans-serif: system-ui; 3 | --serif: serif; 4 | --ampersand: 'Goudy Old Style', Palatino, 'Book Antiqua', serif; 5 | 6 | --hue: 210; 7 | --saturation: 2%; 8 | --lightness: 7%; 9 | 10 | --surface-1: hsl(var(--hue) var(--saturation) var(--lightness)); 11 | --surface-2: hsl(var(--hue) var(--saturation) calc(var(--lightness) * 1.1)); 12 | 13 | --text-color-1: hsl(var(--hue) var(--saturation) 87%); 14 | --text-color-2: hsl(var(--hue) 5% 60%); 15 | --text-color-3: hsl(var(--hue) 10% 40%); 16 | 17 | --brand-color-1: hsl(var(--hue) 50% 75%); 18 | --brand-color-2: hsl(calc(var(--hue) * 1.5) 65% 75%); 19 | --brand-color-3: hsl(calc(var(--hue) * 1.2) 75% 80%); 20 | 21 | --spacing-1: 1.5vmax; 22 | --spacing-2: 3vmax; 23 | --spacing-3: 5vmax; 24 | --spacing-4: 10vmax; 25 | 26 | /* https://easings.net */ 27 | --easing: ease-out-expo; 28 | 29 | --max-linelength: 30ch; 30 | --bg-blur: .5rem; 31 | } -------------------------------------------------------------------------------- /app/components/body.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | overflow: hidden; 4 | } 5 | 6 | ::selection { 7 | background: var(--brand-color-1); 8 | color: white; 9 | } 10 | -------------------------------------------------------------------------------- /app/components/button.css: -------------------------------------------------------------------------------- 1 | button { 2 | --button-theme: var(--hue); 3 | 4 | --bg: hsla(var(--button-theme), 50%, 75%, 80%); 5 | --bg-hover: hsl(var(--button-theme) 50% 80%); 6 | --text: hsl(var(--button-theme) 60% 15%); 7 | 8 | block-size: 2.5em; 9 | cursor: pointer; 10 | display: inline-grid; 11 | align-items: center; 12 | position: relative; 13 | gap: .5em; 14 | grid-auto-flow: columns; 15 | padding: 0 1.25em; 16 | margin: 0; 17 | border: none; 18 | border-radius: 3rem; 19 | background: var(--bg); 20 | color: var(--text); 21 | border: 2px solid transparent; 22 | line-height: 1.4; 23 | white-space: nowrap; 24 | 25 | backdrop-filter: blur(var(--bg-blur)); 26 | transition: background-color .3s ease; 27 | 28 | --fluid-type-min-size: .75; 29 | --fluid-type-max-size: 1.5; 30 | --fluid-type-min-screen: 20; 31 | --fluid-type-max-screen: 88; 32 | 33 | font-size: calc( 34 | (var(--fluid-type-min-size) * 1rem) + (var(--fluid-type-max-size) - var(--fluid-type-min-size)) * (100vw - (var(--fluid-type-min-screen) * 1rem)) / 35 | (var(--fluid-type-max-screen) - var(--fluid-type-min-screen)) 36 | ); 37 | 38 | &:hover { 39 | background: var(--bg-hover); 40 | } 41 | 42 | &:active { 43 | top: 2px; 44 | } 45 | 46 | &:focus-visible { 47 | outline: none; 48 | } 49 | 50 | &[secondary] { 51 | --button-theme: calc(var(--hue) * 1.5); 52 | } 53 | 54 | &[ghost] { 55 | background: none; 56 | --bg-hover: hsla(var(--hue), 80%, 40%, 10%); 57 | --text: var(--brand-color-1); 58 | border: 2px solid var(--bg); 59 | color: var(--bg); 60 | } 61 | 62 | &[link] { 63 | background: none; 64 | --bg-hover: transparent; 65 | --text: var(--brand-color-1); 66 | 67 | &:hover { 68 | text-decoration: underline; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /app/components/colors.css: -------------------------------------------------------------------------------- 1 | [color="text-1"] { color: var(--text-color-1); } 2 | [color="text-2"] { color: var(--text-color-2); } 3 | [color="text-3"] { color: var(--text-color-3); } 4 | 5 | [color="brand-1"] { color: var(--brand-color-1); } 6 | [color="brand-2"] { color: var(--brand-color-2); } 7 | [color="brand-3"] { color: var(--brand-color-3); } 8 | 9 | [bg="surface-1"] { background-color: var(--surface-1); } 10 | [bg="surface-2"] { background-color: var(--surface-2); } 11 | -------------------------------------------------------------------------------- /app/components/depth.css: -------------------------------------------------------------------------------- 1 | slyd-group { perspective: 30px; } 2 | 3 | [depth-7] 4 | pre { transform: translateZ(10px); } 5 | 6 | [depth-6], 7 | h1 { transform: translateZ(8px); } 8 | 9 | [depth-5], 10 | h2, blockquote, [ampersand] { transform: translateZ(6px); } 11 | 12 | [depth-4], 13 | h3, picture { transform: translateZ(4px); } 14 | 15 | [depth-3], 16 | button,h4 { transform: translateZ(3px); } 17 | 18 | [depth-2], 19 | a,h5,h6 { transform: translateZ(2px); } 20 | 21 | [depth-1], 22 | small { transform: translateZ(1px); } 23 | 24 | [no-depth] { transform: translateZ(0); } -------------------------------------------------------------------------------- /app/components/dividers.css: -------------------------------------------------------------------------------- 1 | hr { 2 | margin: 3rem -20% 3rem !important; 3 | inline-size: 140%; 4 | position: relative; 5 | padding: 0; 6 | border-block-end: none; 7 | border-block-start: 1px solid var(--brand-color-2); 8 | } 9 | 10 | [push-top="0"] { margin-block-start: 0; } 11 | [push-top="1"] { margin-block-start: 2vmax; } 12 | [push-top="2"] { margin-block-start: 5vmax; } 13 | [push-top="3"] { margin-block-start: 10vmax; } 14 | 15 | [push-bottom="0"] { margin-block-end: 0; } 16 | [push-bottom="1"] { margin-block-end: 2vmax; } 17 | [push-bottom="2"] { margin-block-end: 5vmax; } 18 | [push-bottom="3"] { margin-block-end: 10vmax; } -------------------------------------------------------------------------------- /app/components/layouts.css: -------------------------------------------------------------------------------- 1 | [stack], slyd { 2 | display: grid; 3 | justify-items: center; 4 | align-content: center; 5 | gap: var(--spacing-1); 6 | } 7 | 8 | [shelf] { 9 | display: grid; 10 | grid-auto-flow: column; 11 | justify-items: center; 12 | align-content: center; 13 | gap: var(--spacing-3); 14 | 15 | @media (orientation: portrait) { 16 | grid-auto-flow: row; 17 | } 18 | } 19 | 20 | [split] { 21 | display: grid; 22 | grid-template-columns: 1fr 1fr; 23 | grid-auto-flow: column; 24 | } 25 | -------------------------------------------------------------------------------- /app/components/lists.css: -------------------------------------------------------------------------------- 1 | ul, ol { 2 | display: grid; 3 | gap: .5rem; 4 | padding: 0; 5 | margin: 0 10vw; 6 | text-align: left; 7 | 8 | --fluid-type-min-size: 1.25; 9 | --fluid-type-max-size: 2.5; 10 | --fluid-type-min-screen: 20; 11 | --fluid-type-max-screen: 88; 12 | 13 | font-size: calc( 14 | (var(--fluid-type-min-size) * 1rem) + (var(--fluid-type-max-size) - var(--fluid-type-min-size)) * (100vw - (var(--fluid-type-min-screen) * 1rem)) / 15 | (var(--fluid-type-max-screen) - var(--fluid-type-min-screen)) 16 | ); 17 | 18 | &[tight] { 19 | margin: 0; 20 | } 21 | } 22 | 23 | ul { 24 | & > li:before { 25 | position: relative; 26 | top: -0.075em; 27 | margin-inline-end: 1rem; 28 | } 29 | } 30 | 31 | ol { 32 | list-style: none; 33 | counter-reset: slyd-list-counter; 34 | 35 | & > li { 36 | counter-increment: slyd-list-counter; 37 | 38 | &:before { 39 | content: "0" counter(slyd-list-counter); 40 | top: 0.1em; 41 | position: relative; 42 | } 43 | } 44 | } 45 | 46 | li { 47 | display: inline-flex; 48 | align-items: flex-start; 49 | font-weight: 300; 50 | max-width: var(--max-linelength); 51 | 52 | &:before { 53 | content: "»"; 54 | color: var(--text-color-3); 55 | font-weight: bold; 56 | font-size: 1.5em; 57 | margin-right: 2rem; 58 | font-family: var(--serif); 59 | line-height: 1; 60 | } 61 | } -------------------------------------------------------------------------------- /app/components/picture.css: -------------------------------------------------------------------------------- 1 | picture { 2 | display: inline-block; 3 | 4 | & > img { 5 | inline-size: 100%; 6 | block-size: 100%; 7 | object-fit: contain; 8 | 9 | &[cover] { 10 | object-fit: cover; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /app/components/prism.css: -------------------------------------------------------------------------------- 1 | code[class*="language-"], pre[class*="language-"] { 2 | color: var(--text-color-1); 3 | font-family: 'Dank Mono', 'Operator Mono', 'Inconsolata', 'Fira Mono', 'SF Mono', 'Monaco', 'Droid Sans Mono', 'Source Code Pro', monospace; 4 | display: inline-block; 5 | 6 | --fluid-type-min-size: .5; 7 | --fluid-type-max-size: 1; 8 | --fluid-type-min-screen: 20; 9 | --fluid-type-max-screen: 88; 10 | 11 | font-size: calc( 12 | (var(--fluid-type-min-size) * 1rem) + (var(--fluid-type-max-size) - var(--fluid-type-min-size)) * (100vw - (var(--fluid-type-min-screen) * 1rem)) / 13 | (var(--fluid-type-max-screen) - var(--fluid-type-min-screen)) 14 | ); 15 | } 16 | 17 | .line-numbers .line-numbers-rows { 18 | border-right: 1px solid hsl(0, 0%, 20%); 19 | width: 2.5em; 20 | } 21 | 22 | .token { 23 | &:is(.property, .keyword, .tag, .function) { 24 | color: var(--brand-color-1); 25 | } 26 | 27 | &:is(.selector, .attr-name, .string, .operator, .char, .builtin, .inserted) { 28 | color: var(--brand-color-2); 29 | } 30 | 31 | &:is(.parameter, .punctuation) { 32 | color: var(--brand-color-3); 33 | } 34 | 35 | &:is(.attr-value) { 36 | color: var(--text-color-1); 37 | } 38 | 39 | /* &:is(.property, .tag, .function, .comment) { 40 | font-style: italic; 41 | } */ 42 | } 43 | 44 | .line-numbers-rows > span:before { 45 | color: var(--text-color-3); 46 | } -------------------------------------------------------------------------------- /app/components/quotes.css: -------------------------------------------------------------------------------- 1 | blockquote { 2 | text-align: center; 3 | position: relative; 4 | margin-inline: 10%; 5 | font-family: var(--serif); 6 | 7 | --fluid-type-min-size: 2; 8 | --fluid-type-max-size: 3; 9 | --fluid-type-min-screen: 20; 10 | --fluid-type-max-screen: 88; 11 | 12 | font-size: calc( 13 | (var(--fluid-type-min-size) * 1rem) + (var(--fluid-type-max-size) - var(--fluid-type-min-size)) * (100vw - (var(--fluid-type-min-screen) * 1rem)) / 14 | (var(--fluid-type-max-screen) - var(--fluid-type-min-screen)) 15 | ); 16 | 17 | &:before { 18 | content: "“"; 19 | position: absolute; 20 | top: -14vmax; 21 | left: 0; 22 | 23 | color: var(--text-color-3); 24 | font-size: 20vmax; 25 | } 26 | 27 | & > p { 28 | letter-spacing: -2px; 29 | } 30 | 31 | & > footer { 32 | font-family: var(--sans-serif); 33 | font-weight: 200; 34 | color: var(--brand-color-3); 35 | font-size: .5em; 36 | 37 | &:before { 38 | display: block; 39 | margin: 0 auto 1em; 40 | content: ""; 41 | inline-size: 1em; 42 | block-size: 1px; 43 | background-color: var(--brand-color-2); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /app/components/slyd-arrows.css: -------------------------------------------------------------------------------- 1 | slyds { 2 | & > slyd-group > slyd:first-child:after { 3 | content: "↓"; 4 | position: absolute; 5 | bottom: 2vh; 6 | left: calc(50vw - .5em); 7 | color: var(--text-color-2); 8 | font-size: 1.5rem; 9 | 10 | animation: bounce-down 2s ease-in-out infinite; 11 | } 12 | 13 | & > slyd:after, 14 | & > slyd-group:not(:last-child) > slyd:last-child:after { 15 | content: "→"; 16 | position: absolute; 17 | bottom: calc(50vh - .5em); 18 | right: 2vw; 19 | color: var(--text-color-2); 20 | font-size: 1.5rem; 21 | 22 | animation: bounce-right 2s ease-in-out infinite; 23 | } 24 | 25 | & > slyd-group:last-child > slyd:last-child:after { 26 | content: "✓"; 27 | position: absolute; 28 | bottom: 1vh; 29 | left: calc(50vw - .5em); 30 | color: white; 31 | font-size: 2rem; 32 | } 33 | } 34 | 35 | @keyframes bounce-down { 36 | 50% { 37 | transform: translateY(1vmax); 38 | } 39 | } 40 | 41 | @keyframes bounce-right { 42 | 50% { 43 | transform: translateX(1vmax); 44 | } 45 | } -------------------------------------------------------------------------------- /app/components/slyd-group.css: -------------------------------------------------------------------------------- 1 | slyd-group { 2 | display: grid; 3 | grid-auto-flow: row; 4 | grid-auto-rows: 100vh; 5 | grid-template-columns: 100vw; 6 | position: relative; 7 | 8 | scroll-snap-type: y mandatory; 9 | 10 | & > * { 11 | scroll-snap-align: center; 12 | scroll-snap-stop: always; 13 | transform-style: preserve-3d; 14 | } 15 | 16 | overflow-y: scroll; 17 | overflow-x: hidden; 18 | overscroll-behavior-y: contain; 19 | -webkit-overflow-scrolling: touch; 20 | /* scrollbar-color: light; 21 | -webkit-scrollbar-color: light; */ 22 | 23 | /* &::-webkit-scrollbar { 24 | width: 1px; 25 | background-color: var(--surface-1); 26 | } 27 | 28 | &::-webkit-scrollbar-thumb { 29 | background-color: var(--brand-color-1); 30 | } */ 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/components/slyd.css: -------------------------------------------------------------------------------- 1 | slyd { 2 | width: 100vw; 3 | height: 100vh; 4 | position: relative; 5 | text-align: center; 6 | 7 | &:focus-visible { 8 | outline: none; 9 | } 10 | 11 | --darkness: 50%; 12 | 13 | background-image: 14 | radial-gradient(circle, hsla(0,0%,0%,var(--darkness)) 0%, hsla(0,0%,0%,var(--darkness)) 100%), 15 | var(--image); 16 | background-position: center center; 17 | background-size: cover; 18 | 19 | &[slow-zoom] { 20 | &[slyd-active="true"] { 21 | transition: transform 20s cubic-bezier(0.51, 0.01, 0.68, 0.99); 22 | transform: translateZ(2px); 23 | transform-style: preserve-3d; 24 | } 25 | } 26 | 27 | & > h1:first-child, 28 | & > h2:first-child, 29 | & > h3:first-child { 30 | color: var(--text-color-1); 31 | } 32 | 33 | & > picture:only-child { padding: 0 10vw; } 34 | } -------------------------------------------------------------------------------- /app/components/slyds.css: -------------------------------------------------------------------------------- 1 | slyds { 2 | width: 100vw; 3 | height: 100vh; 4 | 5 | background: var(--surface-1); 6 | color: var(--text-color-1); 7 | font-family: var(--sans-serif); 8 | 9 | /* snapping grid layout */ 10 | display: grid; 11 | grid-auto-flow: column; 12 | grid-auto-columns: 100vw; 13 | grid-template-rows: 100vh; 14 | 15 | scroll-snap-type: x mandatory; 16 | 17 | & > * { 18 | scroll-snap-align: center; 19 | scroll-snap-stop: always; 20 | } 21 | 22 | overflow-x: scroll; 23 | overflow-y: hidden; 24 | -webkit-overflow-scrolling: touch; 25 | overscroll-behavior-x: contain; 26 | /* scrollbar-color: light; 27 | -webkit-scrollbar-color: light; */ 28 | 29 | &::-webkit-scrollbar { 30 | height: 1px; 31 | background-color: var(--surface-1); 32 | } 33 | 34 | &::-webkit-scrollbar-thumb { 35 | background-color: var(--brand-color-1); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/components/typography.css: -------------------------------------------------------------------------------- 1 | [text-left] { text-align: left; } 2 | [text-center] { text-align: center; } 3 | [text-right] { text-align: right; } 4 | [justify] { text-align: justify; text-justify: inter-word; } 5 | [uppercase] { text-transform: uppercase; } 6 | [capitalize] { text-transform: capitalize; } 7 | [italic] { font-style: italic; } 8 | [bold] { font-weight: bolder; } 9 | [book] { font-weight: normal; } 10 | [light] { font-weight: 200; } 11 | [thin] { font-weight: lightest; } 12 | [serif] { font-family: var(--serif); } 13 | 14 | [highlight] { 15 | position: relative; 16 | color: var(--text-color-1); 17 | 18 | &:before { 19 | content: " "; 20 | position: absolute; 21 | top: 1px; 22 | left: -.15em; 23 | width: 100%; 24 | height: 100%; 25 | padding: 0 .1em; 26 | background: hsla(calc(var(--hue) * 1.2), 50%, 75%, 20%); 27 | border-left: 2px solid var(--brand-color-3); 28 | border-right: 2px solid var(--brand-color-3); 29 | } 30 | } 31 | 32 | em { 33 | font-style: normal; 34 | font-size: 2.5em; 35 | font-weight: lighter; 36 | position: relative; 37 | top: .2em; 38 | } 39 | 40 | a { 41 | display: inline-block; 42 | color: var(--brand-color-2); 43 | font-size: 1em; 44 | } 45 | 46 | slyd { 47 | line-height: 1.5; 48 | font-weight: 200; 49 | --fluid-type-min-size: 1.25; 50 | --fluid-type-max-size: 2.5; 51 | --fluid-type-min-screen: 20; 52 | --fluid-type-max-screen: 88; 53 | 54 | font-size: calc( 55 | (var(--fluid-type-min-size) * 1rem) + (var(--fluid-type-max-size) - var(--fluid-type-min-size)) * (100vw - (var(--fluid-type-min-screen) * 1rem)) / 56 | (var(--fluid-type-max-screen) - var(--fluid-type-min-screen)) 57 | ); 58 | 59 | @media (orientation: landscape) { 60 | --fluid-type-min-size: 1; 61 | --fluid-type-max-size: 2.25; 62 | } 63 | } 64 | 65 | p { 66 | margin: 0; 67 | max-width: var(--max-linelength); 68 | font-weight: 300; 69 | 70 | --fluid-type-min-size: 1.25; 71 | --fluid-type-max-size: 2.5; 72 | --fluid-type-min-screen: 20; 73 | --fluid-type-max-screen: 88; 74 | 75 | font-size: calc( 76 | (var(--fluid-type-min-size) * 1rem) + (var(--fluid-type-max-size) - var(--fluid-type-min-size)) * (100vw - (var(--fluid-type-min-screen) * 1rem)) / 77 | (var(--fluid-type-max-screen) - var(--fluid-type-min-screen)) 78 | ); 79 | 80 | &[lead] { 81 | line-height: 1.5; 82 | font-weight: 200; 83 | } 84 | 85 | @media (orientation: landscape) { 86 | --max-linelength: 40vw; 87 | --fluid-type-min-size: 1; 88 | --fluid-type-max-size: 2.25; 89 | } 90 | 91 | @media (orientation: portrait) { 92 | margin: 0 var(--spacing-3); 93 | } 94 | } 95 | 96 | small { 97 | display: inline-block; 98 | color: var(--text-color-2); 99 | font-weight: 300; 100 | font-size: 1.25em; 101 | letter-spacing: 1px; 102 | } 103 | 104 | h1, h2, h3, h4, h5, h6 { 105 | line-height: 1.3; 106 | margin: 0; 107 | padding: 0; 108 | 109 | --fluid-type-min-size: 1; 110 | --fluid-type-max-size: 2; 111 | --fluid-type-min-screen: 20; 112 | --fluid-type-max-screen: 88; 113 | 114 | font-size: calc( 115 | (var(--fluid-type-min-size) * 1rem) + (var(--fluid-type-max-size) - var(--fluid-type-min-size)) * (100vw - (var(--fluid-type-min-screen) * 1rem)) / 116 | (var(--fluid-type-max-screen) - var(--fluid-type-min-screen)) 117 | ); 118 | 119 | @media (orientation: portrait) { 120 | margin: 0 7.5vmax; 121 | } 122 | } 123 | 124 | /* https://andy-bell.design/wrote/custom-property-controlled-fluid-type-sizing/ */ 125 | h1 { 126 | --fluid-type-min-size: 2; 127 | --fluid-type-max-size: 5; 128 | 129 | font-weight: lighter; 130 | letter-spacing: 0.2em; 131 | color: var(--text-color-1); 132 | 133 | @media (orientation: portrait) { 134 | --fluid-type-min-size: 1.5; 135 | --fluid-type-max-size: 4.5; 136 | } 137 | } 138 | 139 | h2 { 140 | --fluid-type-min-size: 1.5; 141 | --fluid-type-max-size: 3.5; 142 | 143 | font-weight: 200; 144 | letter-spacing: 3px; 145 | color: var(--text-color-2); 146 | } 147 | 148 | h3, h4, h5, h6 { 149 | --fluid-type-min-size: 1.25; 150 | --fluid-type-max-size: 2.5; 151 | 152 | font-weight: 300; 153 | letter-spacing: 2px; 154 | color: var(--text-color-3); 155 | } 156 | 157 | h4 { 158 | --fluid-type-min-size: 1.25; 159 | --fluid-type-max-size: 2; 160 | font-weight: 400; 161 | } 162 | 163 | h5 { 164 | --fluid-type-min-size: .75; 165 | --fluid-type-max-size: 1.5; 166 | font-weight: 500; 167 | } 168 | 169 | h6 { 170 | --fluid-type-min-size: .5; 171 | --fluid-type-max-size: 1; 172 | font-weight: 600; 173 | } 174 | -------------------------------------------------------------------------------- /app/components/video.css: -------------------------------------------------------------------------------- 1 | video { 2 | object-fit: contain; 3 | 4 | &[full-width] { 5 | inline-size: 100%; 6 | } 7 | 8 | &[full-height] { 9 | block-size: 100%; 10 | } 11 | 12 | &[cover] { 13 | inline-size: 100%; 14 | block-size: 100%; 15 | object-fit: cover; 16 | } 17 | 18 | &[background-video] { 19 | position: absolute; 20 | inset: 0; 21 | } 22 | } -------------------------------------------------------------------------------- /app/images/aliens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/argyleink/slyd/1264ce5fa90b10d514e58e6c4d27f48ca7ae0752/app/images/aliens.png -------------------------------------------------------------------------------- /app/images/starwars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/argyleink/slyd/1264ce5fa90b10d514e58e6c4d27f48ca7ae0752/app/images/starwars.png -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Slyd 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |

slyd

23 |

a minimalist's slide deck

24 |
25 | 26 | 27 | 28 | 29 |

2 Way

30 |

bi-directional CSS parallax

31 |
32 | 33 | 34 |

Natural

35 |

content naturally enters and exits the stage

36 |
37 | 38 | 39 |

Deep Links

40 |

(share a link directly to a slide)

41 |
42 | 43 | 44 |

touch & keyboard support

45 |
46 | 47 | 48 |

Themeable

49 |

via CSS custom properties

50 |
51 | 52 |
53 | 54 | 55 |

Minimal Markup

56 |

 57 |           <slyd>
 58 |             <h2>Minimal Markup</h2>
 59 |             <pre class="language-html line-numbers show-language"><code>
 60 |               ...
 61 |             </code></pre>
 62 |           </slyd>
 63 |         
64 |

^ code for this slide

65 |
66 | 67 | 68 | 69 | 70 |
comes with
71 |

components

72 |
73 | 74 | 75 |
76 |

What's the object-oriented way to become wealthy?

77 |

Inheritance.

78 |
Claudio
79 |
80 |
81 | 82 | 83 |

Syntax Highlighting

84 |

 85 |             document.querySelectorAll('.🤓')
 86 |               .forEach(({style}) => 
 87 |                 Object.assign(style, {
 88 |                   backgroundColor: 'hsl(200 100% 90%)',
 89 |                   color: 'hsl(200 82% 15%)',
 90 |                 }))
 91 |           
92 |
93 | 94 | 95 |

Heading 1

96 |

Heading 2

97 |

Heading 3

98 |

Heading 4

99 |
Heading 5
100 |
Heading 6
101 |
102 | 103 | 104 |

Regular & Leaded

105 |
106 |

Milk, qui, french press half and half turkish kopi-luwak cortado half and half café au lait extraction chicory. Id est, aftertaste cultivar french press chicory siphon.

107 |

Climb a tree, wait for a fireman jump to fireman then scratch his face leave fur on owners clothes stare at imaginary bug i'm bored inside, let me out i'm lonely.

108 |
109 |
110 | 111 | 112 |

Justified

113 |

Climb a tree, wait for a fireman jump to fireman then scratch his face leave fur on owners clothes stare at imaginary bug i'm bored inside, let me out i'm lonely.

114 |
115 | 116 | 117 |
    118 |
  1. Plain
  2. 119 |
  3. HTML
  4. 120 |
  5. Lists
  6. 121 |
  7. That can handle really long lengths of text and still look alright because otherwise why would I want it?
  8. 122 |
123 |
124 | 125 | 126 |
    127 |
  • Normal
  • 128 |
  • Fine
  • 129 |
  • Bullets
  • 130 |
131 |
132 | 133 | 134 |

Links

135 |
136 | lowercase link 137 | Super Long Link With Fancy Underlines 138 |
139 |
140 | 141 | 142 |

Buttons

143 |
144 | 145 | 146 | 147 | 148 | 149 |
150 |
151 | 152 | 153 |

Decorators

154 |
155 |
156 |

serif

157 |

uppercase

158 |

capitalize

159 |
160 | & 161 |
162 |

brand colors

163 |

on

164 |

anything

165 |
166 |
167 |
168 | 169 |
170 | 171 | 172 | 173 | 174 |

Embed Media

175 |

Using all your favorite tags

176 |
177 | 178 | 179 |

180 |             <picture cover>
181 |               <img loading="lazy" src="...">
182 |             </picture>
183 |           
184 |
185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 |

Background Images

194 | 195 |
196 | 197 | 198 |
199 |

What's the object-oriented way to become wealthy?

200 |

Inheritance.

201 |
Claudio
202 |
203 |
204 | 205 | 206 | 212 |

Overlay Video

213 |
214 | 215 |
216 | 217 | 218 | 219 | 220 |

Start Here

221 | Slyd Starter Kit → 222 |
223 | 224 | 225 |

Grab The Source

226 | Here, On Github → 227 |
228 | 229 |
230 | 231 |
232 | 233 | 234 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | import './slyd/' 2 | 3 | // restores #hash location if not first page load.. 4 | if (window.location.hash) 5 | window.onload = () => 6 | window.location = window.location -------------------------------------------------------------------------------- /app/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Slyd", 3 | "name": "Slyd", 4 | "start_url": "index.html", 5 | "background_color": "#111212", 6 | "display": "fullscreen" 7 | } -------------------------------------------------------------------------------- /app/service-worker.js: -------------------------------------------------------------------------------- 1 | // HTML files: try the network first, then the cache. 2 | // Other files: try the cache first, then the network. 3 | // Both: cache a fresh version if possible. 4 | // (beware: the cache will grow and grow; there's no cleanup) 5 | 6 | const cacheName = 'files'; 7 | 8 | addEventListener('fetch', fetchEvent => { 9 | const request = fetchEvent.request; 10 | if (request.method !== 'GET') { 11 | return; 12 | } 13 | fetchEvent.respondWith(async function() { 14 | const responseFromFetch = fetch(request); 15 | fetchEvent.waitUntil(async function() { 16 | const responseCopy = (await responseFromFetch).clone(); 17 | const myCache = await caches.open(cacheName); 18 | await myCache.put(request, responseCopy); 19 | }()); 20 | if (request.headers.get('Accept').includes('text/html')) { 21 | try { 22 | return await responseFromFetch; 23 | } 24 | catch(error) { 25 | return caches.match(request); 26 | } 27 | } else { 28 | const responseFromCache = await caches.match(request); 29 | return responseFromCache || responseFromFetch; 30 | } 31 | }()); 32 | }); -------------------------------------------------------------------------------- /app/slyd/index.css: -------------------------------------------------------------------------------- 1 | @import '../components/_vars.css'; 2 | 3 | @import '../components/body.css'; 4 | @import '../components/typography.css'; 5 | @import '../components/colors.css'; 6 | @import '../components/layouts.css'; 7 | @import '../components/depth.css'; 8 | 9 | @import '../components/slyds.css'; 10 | @import '../components/slyd.css'; 11 | @import '../components/slyd-group.css'; 12 | @import '../components/slyd-arrows.css'; 13 | 14 | @import '../components/button.css'; 15 | @import '../components/lists.css'; 16 | @import '../components/quotes.css'; 17 | @import '../components/dividers.css'; 18 | @import '../components/picture.css'; 19 | @import '../components/video.css'; 20 | @import '../components/prism.css'; 21 | -------------------------------------------------------------------------------- /app/slyd/index.js: -------------------------------------------------------------------------------- 1 | import 'https://unpkg.com/prismjs' 2 | import 'https://unpkg.com/prismjs@1.26.0/plugins/line-numbers/prism-line-numbers.min.js' 3 | import 'https://unpkg.com/prismjs@1.26.0/plugins/normalize-whitespace/prism-normalize-whitespace.min.js' 4 | import 'https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver%2CSet' 5 | 6 | import './slyd-manager.js' -------------------------------------------------------------------------------- /app/slyd/slyd-manager.js: -------------------------------------------------------------------------------- 1 | import { onSlydChanged } from './slyd-observer.js' 2 | 3 | document.querySelectorAll('slyd') 4 | .forEach(slyd => 5 | slyd.setAttribute('aria-role', 'article')) // authoring convenience 6 | 7 | const state = { 8 | slyds: { 9 | active: undefined, 10 | } 11 | } 12 | 13 | const setActive = ({target:in_view_slide}) => { 14 | state.slyds.active = in_view_slide 15 | state.slyds.active.setAttribute('slyd-active', true) 16 | in_view_slide.setAttribute('tabIndex', -1) 17 | setSrcs(in_view_slide) 18 | playVideo(in_view_slide) 19 | } 20 | 21 | const removeActive = () => { 22 | const {active} = state.slyds 23 | 24 | if (active) { 25 | active.removeAttribute('slyd-active') 26 | active.removeAttribute('tabIndex') 27 | pauseVideo(active) 28 | } 29 | } 30 | 31 | const setSrcs = slyd => 32 | slyd.querySelectorAll('[lazy-src]') 33 | .forEach(lazysrc => { 34 | lazysrc.setAttribute('src', lazysrc.getAttribute('lazy-src')) 35 | lazysrc.removeAttribute('lazy-src') 36 | }) 37 | 38 | const playVideo = slyd => 39 | Array.from(slyd.querySelectorAll('video')) 40 | .filter(video => 41 | video.hasAttribute('src') && 42 | video.paused) 43 | .forEach(video => 44 | video.play()) 45 | 46 | const pauseVideo = slyd => 47 | slyd.querySelectorAll('video') 48 | .forEach(video => 49 | video.pause()) 50 | 51 | const setURL = hash => 52 | window.location.hash = hash 53 | 54 | onSlydChanged(slyd => { 55 | removeActive() 56 | setActive(slyd) 57 | 58 | setURL(state.slyds.active.id) 59 | }) -------------------------------------------------------------------------------- /app/slyd/slyd-observer.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | callbacks: new Set(), 3 | } 4 | 5 | export const onSlydChanged = cb => 6 | state.callbacks.add(cb) 7 | 8 | if (window.hasOwnProperty('IntersectionObserver')) { 9 | const slyd_observer = new IntersectionObserver(slides => { 10 | const [slyd] = slides.filter(slide => slide.isIntersecting) 11 | 12 | if (slyd) 13 | state.callbacks.forEach(cb => 14 | cb(slyd)) 15 | }, { 16 | root: document.querySelector('slyds'), 17 | rootMargin: '0px 0px 1px 0px', 18 | threshold: 1, 19 | }) 20 | 21 | document.querySelectorAll('slyd') 22 | .forEach(slyd => 23 | slyd_observer.observe(slyd)) 24 | } 25 | -------------------------------------------------------------------------------- /dist/slyd.css: -------------------------------------------------------------------------------- 1 | :root{--sans-serif:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif;--serif:serif;--ampersand:"Goudy Old Style",Palatino,"Book Antiqua",serif;--hue:210;--saturation:2%;--lightness:7%;--surface-1:hsl(var(--hue) var(--saturation) var(--lightness));--surface-2:hsl(var(--hue) var(--saturation) calc(var(--lightness)*1.1));--text-color-1:hsl(var(--hue) var(--saturation) 87%);--text-color-2:hsl(var(--hue) 5% 60%);--text-color-3:hsl(var(--hue) 10% 40%);--brand-color-1:hsl(var(--hue) 50% 75%);--brand-color-2:hsl(calc(var(--hue)*1.5) 65% 75%);--brand-color-3:hsl(calc(var(--hue)*1.2) 75% 80%);--spacing-1:1.5vmax;--spacing-2:3vmax;--spacing-3:5vmax;--spacing-4:10vmax;--easing:cubic-bezier(0.19,1,0.22,1);--max-linelength:30ch;--bg-blur:.5rem}body{margin:0;overflow:hidden}::-moz-selection{background:var(--brand-color-1);color:#fff}::selection{background:var(--brand-color-1);color:#fff}[text-left]{text-align:left}[text-center]{text-align:center}[text-right]{text-align:right}[justify]{text-align:justify;text-justify:inter-word}[uppercase]{text-transform:uppercase}[capitalize]{text-transform:capitalize}[italic]{font-style:italic}[bold]{font-weight:bolder}[book]{font-weight:400}[light]{font-weight:200}[thin]{font-weight:lightest}[serif]{font-family:var(--serif)}[highlight]{color:var(--text-color-1);position:relative}[highlight]:before{background:hsla(calc(var(--hue)*1.2),50%,75%,20%);border-left:2px solid var(--brand-color-3);border-right:2px solid var(--brand-color-3);content:" ";height:100%;left:-.15em;padding:0 .1em;position:absolute;top:1px;width:100%}em{font-size:2.5em;font-style:normal;font-weight:lighter;position:relative;top:.2em}a{color:var(--brand-color-2);display:inline-block;font-size:1em}slyd{--fluid-type-min-size:1.25;--fluid-type-max-size:2.5;--fluid-type-min-screen:20;--fluid-type-max-screen:88;font-size:calc(var(--fluid-type-min-size)*1rem + (var(--fluid-type-max-size) - var(--fluid-type-min-size))*(100vw - var(--fluid-type-min-screen)*1rem)/(var(--fluid-type-max-screen) - var(--fluid-type-min-screen)));font-weight:200;line-height:1.5}@media (orientation:landscape){slyd{--fluid-type-min-size:1;--fluid-type-max-size:2.25}}p{--fluid-type-min-size:1.25;--fluid-type-max-size:2.5;--fluid-type-min-screen:20;--fluid-type-max-screen:88;font-size:calc(var(--fluid-type-min-size)*1rem + (var(--fluid-type-max-size) - var(--fluid-type-min-size))*(100vw - var(--fluid-type-min-screen)*1rem)/(var(--fluid-type-max-screen) - var(--fluid-type-min-screen)));font-weight:300;margin:0;max-width:var(--max-linelength)}p[lead]{font-weight:200;line-height:1.5}@media (orientation:landscape){p{--max-linelength:40vw;--fluid-type-min-size:1;--fluid-type-max-size:2.25}}@media (orientation:portrait){p{margin:0 var(--spacing-3)}}small{color:var(--text-color-2);display:inline-block;font-size:1.25em;font-weight:300;letter-spacing:1px}h1,h2,h3,h4,h5,h6{--fluid-type-min-size:1;--fluid-type-max-size:2;--fluid-type-min-screen:20;--fluid-type-max-screen:88;font-size:calc(var(--fluid-type-min-size)*1rem + (var(--fluid-type-max-size) - var(--fluid-type-min-size))*(100vw - var(--fluid-type-min-screen)*1rem)/(var(--fluid-type-max-screen) - var(--fluid-type-min-screen)));line-height:1.3;margin:0;padding:0}@media (orientation:portrait){h1,h2,h3,h4,h5,h6{margin:0 7.5vmax}}h1{--fluid-type-min-size:2;--fluid-type-max-size:5;color:var(--text-color-1);font-weight:lighter;letter-spacing:.2em}@media (orientation:portrait){h1{--fluid-type-min-size:1.5;--fluid-type-max-size:4.5}}h2{--fluid-type-min-size:1.5;--fluid-type-max-size:3.5;color:var(--text-color-2);font-weight:200;letter-spacing:3px}h3,h4,h5,h6{--fluid-type-min-size:1.25;--fluid-type-max-size:2.5;color:var(--text-color-3);font-weight:300;letter-spacing:2px}h4{--fluid-type-min-size:1.25;--fluid-type-max-size:2;font-weight:400}h5{--fluid-type-min-size:.75;--fluid-type-max-size:1.5;font-weight:500}h6{--fluid-type-min-size:.5;--fluid-type-max-size:1;font-weight:600}[color=text-1]{color:var(--text-color-1)}[color=text-2]{color:var(--text-color-2)}[color=text-3]{color:var(--text-color-3)}[color=brand-1]{color:var(--brand-color-1)}[color=brand-2]{color:var(--brand-color-2)}[color=brand-3]{color:var(--brand-color-3)}[bg=surface-1]{background-color:var(--surface-1)}[bg=surface-2]{background-color:var(--surface-2)}[stack],slyd{gap:var(--spacing-1)}[shelf],[stack],slyd{align-content:center;display:grid;justify-items:center}[shelf]{gap:var(--spacing-3);grid-auto-flow:column}@media (orientation:portrait){[shelf]{grid-auto-flow:row}}[split]{display:grid;grid-auto-flow:column;grid-template-columns:1fr 1fr}slyd-group{perspective:30px}[depth-7] 2 | pre{transform:translateZ(10px)}[depth-6],h1{transform:translateZ(8px)}[ampersand],[depth-5],blockquote,h2{transform:translateZ(6px)}[depth-4],h3,picture{transform:translateZ(4px)}[depth-3],button,h4{transform:translateZ(3px)}[depth-2],a,h5,h6{transform:translateZ(2px)}[depth-1],small{transform:translateZ(1px)}[no-depth]{transform:translateZ(0)}slyds{background:var(--surface-1);color:var(--text-color-1);display:grid;font-family:var(--sans-serif);grid-auto-columns:100vw;grid-auto-flow:column;grid-template-rows:100vh;height:100vh;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;width:100vw}slyds>*{scroll-snap-align:center;scroll-snap-stop:always}slyds{-webkit-overflow-scrolling:touch;overflow-x:scroll;overflow-y:hidden;overscroll-behavior-x:contain}slyds::-webkit-scrollbar{background-color:var(--surface-1);height:1px}slyds::-webkit-scrollbar-thumb{background-color:var(--brand-color-1)}slyd{height:100vh;position:relative;text-align:center;width:100vw}slyd:focus-visible{outline:none}slyd{--darkness:50%;background-image:radial-gradient(circle,hsla(0,0%,0%,var(--darkness)) 0,hsla(0,0%,0%,var(--darkness)) 100%),var(--image);background-position:50%;background-size:cover}slyd[slow-zoom][slyd-active=true]{transform:translateZ(2px);transform-style:preserve-3d;transition:transform 20s cubic-bezier(.51,.01,.68,.99)}slyd>h1:first-child,slyd>h2:first-child,slyd>h3:first-child{color:var(--text-color-1)}slyd>picture:only-child{padding:0 10vw}slyd-group{display:grid;grid-auto-flow:row;grid-auto-rows:100vh;grid-template-columns:100vw;position:relative;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory}slyd-group>*{scroll-snap-align:center;scroll-snap-stop:always;transform-style:preserve-3d}slyd-group{-webkit-overflow-scrolling:touch;overflow-x:hidden;overflow-y:scroll;overscroll-behavior-y:contain}slyds>slyd-group>slyd:first-child:after{-webkit-animation:bounce-down 2s ease-in-out infinite;animation:bounce-down 2s ease-in-out infinite;bottom:2vh;color:var(--text-color-2);content:"↓";font-size:1.5rem;left:calc(50vw - .5em);position:absolute}slyds>slyd-group:not(:last-child)>slyd:last-child:after,slyds>slyd:after{-webkit-animation:bounce-right 2s ease-in-out infinite;animation:bounce-right 2s ease-in-out infinite;bottom:calc(50vh - .5em);color:var(--text-color-2);content:"→";font-size:1.5rem;position:absolute;right:2vw}slyds>slyd-group:last-child>slyd:last-child:after{bottom:1vh;color:#fff;content:"✓";font-size:2rem;left:calc(50vw - .5em);position:absolute}@-webkit-keyframes bounce-down{50%{transform:translateY(1vmax)}}@keyframes bounce-down{50%{transform:translateY(1vmax)}}@-webkit-keyframes bounce-right{50%{transform:translateX(1vmax)}}@keyframes bounce-right{50%{transform:translateX(1vmax)}}button{--button-theme:var(--hue);--bg:hsla(var(--button-theme),50%,75%,80%);--bg-hover:hsl(var(--button-theme) 50% 80%);--text:hsl(var(--button-theme) 60% 15%);--fluid-type-min-size:.75;--fluid-type-max-size:1.5;--fluid-type-min-screen:20;--fluid-type-max-screen:88;align-items:center;-webkit-backdrop-filter:blur(var(--bg-blur));backdrop-filter:blur(var(--bg-blur));background:var(--bg);block-size:2.5em;border:2px solid transparent;border-radius:3rem;color:var(--text);cursor:pointer;display:inline-grid;font-size:calc(var(--fluid-type-min-size)*1rem + (var(--fluid-type-max-size) - var(--fluid-type-min-size))*(100vw - var(--fluid-type-min-screen)*1rem)/(var(--fluid-type-max-screen) - var(--fluid-type-min-screen)));gap:.5em;grid-auto-flow:columns;line-height:1.4;margin:0;padding:0 1.25em;position:relative;transition:background-color .3s ease;white-space:nowrap}button:hover{background:var(--bg-hover)}button:active{top:2px}button:focus-visible{outline:none}button[secondary]{--button-theme:calc(var(--hue)*1.5)}button[ghost]{--bg-hover:hsla(var(--hue),80%,40%,10%);--text:var(--brand-color-1);background:none;border:2px solid var(--bg);color:var(--bg)}button[link]{--bg-hover:transparent;--text:var(--brand-color-1);background:none}button[link]:hover{text-decoration:underline}ol,ul{--fluid-type-min-size:1.25;--fluid-type-max-size:2.5;--fluid-type-min-screen:20;--fluid-type-max-screen:88;display:grid;font-size:calc(var(--fluid-type-min-size)*1rem + (var(--fluid-type-max-size) - var(--fluid-type-min-size))*(100vw - var(--fluid-type-min-screen)*1rem)/(var(--fluid-type-max-screen) - var(--fluid-type-min-screen)));gap:.5rem;margin:0 10vw;padding:0;text-align:left}ol[tight],ul[tight]{margin:0}ul>li:before{-webkit-margin-end:1rem;margin-inline-end:1rem;position:relative;top:-.075em}ol{counter-reset:slyd-list-counter;list-style:none}ol>li{counter-increment:slyd-list-counter}ol>li:before{content:"0" counter(slyd-list-counter);position:relative;top:.1em}li{align-items:flex-start;display:inline-flex;font-weight:300;max-width:var(--max-linelength)}li:before{color:var(--text-color-3);content:"»";font-size:1.5em;font-weight:700;line-height:1;margin-right:2rem}blockquote,li:before{font-family:var(--serif)}blockquote{--fluid-type-min-size:2;--fluid-type-max-size:3;--fluid-type-min-screen:20;--fluid-type-max-screen:88;font-size:calc(var(--fluid-type-min-size)*1rem + (var(--fluid-type-max-size) - var(--fluid-type-min-size))*(100vw - var(--fluid-type-min-screen)*1rem)/(var(--fluid-type-max-screen) - var(--fluid-type-min-screen)));margin-inline:10%;position:relative;text-align:center}blockquote:before{color:var(--text-color-3);content:"“";font-size:20vmax;left:0;position:absolute;top:-14vmax}blockquote>p{letter-spacing:-2px}blockquote>footer{color:var(--brand-color-3);font-family:var(--sans-serif);font-size:.5em;font-weight:200}blockquote>footer:before{background-color:var(--brand-color-2);block-size:1px;content:"";display:block;inline-size:1em;margin:0 auto 1em}hr{-webkit-border-after:none;-webkit-border-before:1px solid var(--brand-color-2);border-block-end:none;border-block-start:1px solid var(--brand-color-2);inline-size:140%;margin:3rem -20%!important;padding:0;position:relative}[push-top="0"]{-webkit-margin-before:0;margin-block-start:0}[push-top="1"]{-webkit-margin-before:2vmax;margin-block-start:2vmax}[push-top="2"]{-webkit-margin-before:5vmax;margin-block-start:5vmax}[push-top="3"]{-webkit-margin-before:10vmax;margin-block-start:10vmax}[push-bottom="0"]{-webkit-margin-after:0;margin-block-end:0}[push-bottom="1"]{-webkit-margin-after:2vmax;margin-block-end:2vmax}[push-bottom="2"]{-webkit-margin-after:5vmax;margin-block-end:5vmax}[push-bottom="3"]{-webkit-margin-after:10vmax;margin-block-end:10vmax}picture{display:inline-block}picture>img{block-size:100%;inline-size:100%;-o-object-fit:contain;object-fit:contain}picture>img[cover]{-o-object-fit:cover;object-fit:cover}video{-o-object-fit:contain;object-fit:contain}video[full-width]{inline-size:100%}video[cover],video[full-height]{block-size:100%}video[cover]{inline-size:100%;-o-object-fit:cover;object-fit:cover}video[background-video]{inset:0;position:absolute}code[class*=language-],pre[class*=language-]{--fluid-type-min-size:.5;--fluid-type-max-size:1;--fluid-type-min-screen:20;--fluid-type-max-screen:88;color:var(--text-color-1);display:inline-block;font-family:Dank Mono,Operator Mono,Inconsolata,Fira Mono,SF Mono,Monaco,Droid Sans Mono,Source Code Pro,monospace;font-size:calc(var(--fluid-type-min-size)*1rem + (var(--fluid-type-max-size) - var(--fluid-type-min-size))*(100vw - var(--fluid-type-min-screen)*1rem)/(var(--fluid-type-max-screen) - var(--fluid-type-min-screen)))}.line-numbers .line-numbers-rows{border-right:1px solid #333;width:2.5em}.token:matches(.property,.keyword,.tag,.function){color:var(--brand-color-1)}.token:matches(.selector,.attr-name,.string,.operator,.char,.builtin,.inserted){color:var(--brand-color-2)}.token:matches(.parameter,.punctuation){color:var(--brand-color-3)}.token:matches(.attr-value){color:var(--text-color-1)}.line-numbers-rows>span:before{color:var(--text-color-3)} -------------------------------------------------------------------------------- /dist/slyd.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var e=function(e){var t=/\blang(?:uage)?-([\w-]+)\b/i,n=0,r={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof o?new o(e.type,r.util.encode(e.content),e.alias):Array.isArray(e)?e.map(r.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(E instanceof o)){if(g&&v!=t.length-1){if(f.lastIndex=w,!(A=f.exec(e)))break;for(var S=A.index+(d?A[1].length:0),j=A.index+A[0].length,O=v,_=w,T=t.length;O"+i.content+""},!e.document)return e.addEventListener&&(r.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),o=n.language,i=n.code,a=n.immediateClose;e.postMessage(r.highlight(i,r.languages[o],o)),a&&e.close()}),!1)),r;var i=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return i&&(r.filename=i.src,r.manual||i.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(r.highlightAll):window.setTimeout(r.highlightAll,16):document.addEventListener("DOMContentLoaded",r.highlightAll))),r}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});"undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof global&&(global.Prism=e),e.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},e.languages.markup.tag.inside["attr-value"].inside.entity=e.languages.markup.entity,e.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(e.languages.markup.tag,"addInlined",{value:function(t,n){var r={};r["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:e.languages[n]},r.cdata=/^$/i;var o={"included-cdata":{pattern://i,inside:r}};o["language-"+n]={pattern:/[\s\S]+/,inside:e.languages[n]};var i={};i[t]={pattern:RegExp(/(<__[\s\S]*?>)(?:\s*|[\s\S])*?(?=<\/__>)/.source.replace(/__/g,t),"i"),lookbehind:!0,greedy:!0,inside:o},e.languages.insertBefore("markup","cdata",i)}}),e.languages.xml=e.languages.extend("markup",{}),e.languages.html=e.languages.markup,e.languages.mathml=e.languages.markup,e.languages.svg=e.languages.markup,function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?[\s\S]*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:RegExp("url\\((?:"+t.source+"|.*?)\\)","i"),selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},n.tag))}(e),e.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},e.languages.javascript=e.languages.extend("clike",{"class-name":[e.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+)n?|\d+n|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,function:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),e.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,e.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,lookbehind:!0,inside:e.languages.javascript},{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,inside:e.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,lookbehind:!0,inside:e.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,lookbehind:!0,inside:e.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),e.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\${[^}]+}/,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:e.languages.javascript}},string:/[\s\S]+/}}}),e.languages.markup&&e.languages.markup.tag.addInlined("script","javascript"),e.languages.js=e.languages.javascript,"undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(t){t=t||document;var n={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"};Array.prototype.slice.call(t.querySelectorAll("pre[data-src]")).forEach((function(t){if(!t.hasAttribute("data-src-loaded")){for(var r,o=t.getAttribute("data-src"),i=t,a=/\blang(?:uage)?-([\w-]+)\b/i;i&&!a.test(i.className);)i=i.parentNode;if(i&&(r=(t.className.match(a)||[,""])[1]),!r){var c=(o.match(/\.(\w+)$/)||[,""])[1];r=n[c]||c}var s=document.createElement("code");s.className="language-"+r,t.textContent="",s.textContent="Loading…",t.appendChild(s);var l=new XMLHttpRequest;l.open("GET",o,!0),l.onreadystatechange=function(){4==l.readyState&&(l.status<400&&l.responseText?(s.textContent=l.responseText,e.highlightElement(s),t.setAttribute("data-src-loaded","")):400<=l.status?s.textContent="✖ Error "+l.status+" while fetching file: "+l.statusText:s.textContent="✖ Error: File does not exist or is empty")},l.send(null)}})),e.plugins.toolbar&&e.plugins.toolbar.registerButton("download-file",(function(e){var t=e.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&t.hasAttribute("data-src")&&t.hasAttribute("data-download-link")){var n=t.getAttribute("data-src"),r=document.createElement("a");return r.textContent=t.getAttribute("data-download-link-label")||"Download",r.setAttribute("download",""),r.href=n,r}}))},document.addEventListener("DOMContentLoaded",(function(){self.Prism.fileHighlight()}))),function(){if("undefined"!=typeof self&&self.Prism&&self.document){var e="line-numbers",t=/\n(?!$)/g,n=function(e){var n=r(e)["white-space"];if("pre-wrap"===n||"pre-line"===n){var o=e.querySelector("code"),i=e.querySelector(".line-numbers-rows"),a=e.querySelector(".line-numbers-sizer"),c=o.textContent.split(t);a||((a=document.createElement("span")).className="line-numbers-sizer",o.appendChild(a)),a.style.display="block",c.forEach((function(e,t){a.textContent=e||"\n";var n=a.getBoundingClientRect().height;i.children[t].style.height=n+"px"})),a.textContent="",a.style.display="none"}},r=function(e){return e?window.getComputedStyle?getComputedStyle(e):e.currentStyle||null:null};window.addEventListener("resize",(function(){Array.prototype.forEach.call(document.querySelectorAll("pre."+e),n)})),Prism.hooks.add("complete",(function(e){if(e.code){var r=e.element,o=r.parentNode;if(o&&/pre/i.test(o.nodeName)&&!r.querySelector(".line-numbers-rows")){for(var i=!1,a=/(?:^|\s)line-numbers(?:\s|$)/,c=r;c;c=c.parentNode)if(a.test(c.className)){i=!0;break}if(i){r.className=r.className.replace(a," "),a.test(o.className)||(o.className+=" line-numbers");var s,l=e.code.match(t),u=l?l.length+1:1,p=new Array(u+1).join("");(s=document.createElement("span")).setAttribute("aria-hidden","true"),s.className="line-numbers-rows",s.innerHTML=p,o.hasAttribute("data-start")&&(o.style.counterReset="linenumber "+(parseInt(o.getAttribute("data-start"),10)-1)),e.element.appendChild(s),n(o),Prism.hooks.run("line-numbers",e)}}}})),Prism.hooks.add("line-numbers",(function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})),Prism.plugins.lineNumbers={getLine:function(t,n){if("PRE"===t.tagName&&t.classList.contains(e)){var r=t.querySelector(".line-numbers-rows"),o=parseInt(t.getAttribute("data-start"),10)||1,i=o+(r.children.length-1);nMath.pow(2,32)-1)throw new RangeError("Invalid array length");var t=[];return t.length=e,t}function n(e,t){var n=arguments.length>2?arguments[2]:[];if(!1===a(e))throw new TypeError(Object.prototype.toString.call(e)+"is not a function.");return e.apply(t,n)}function r(e,t){return e[t]}function o(e,t){return t in e}function i(e){return"[object Array]"===Object.prototype.toString.call(e)}function a(e){return"function"==typeof e}function c(e){return Boolean(e)}function s(e){var t=Number(e);return isNaN(t)?0:1/t==1/0||1/t==-1/0||t===1/0||t===-1/0?t:(t<0?-1:1)*Math.floor(Math.abs(t))}function l(e){var t=s(e);return t<=0?0:Math.min(t,Math.pow(2,53)-1)}function u(t){if(null===t||t===e)throw TypeError();return Object(t)}function p(e,t){return u(e)[t]}function f(t,n){var r=p(t,n);if(null===r||r===e)return e;if(!1===a(r))throw new TypeError("Method not callable: "+n);return r}function h(e){switch(typeof e){case"undefined":return"undefined";case"boolean":return"boolean";case"number":return"number";case"string":return"string";case"symbol":return"symbol";default:return null===e?"null":"Symbol"in this&&e instanceof this.Symbol?"symbol":"object"}}function d(e,t){var n=r(e,"prototype");return"object"!==h(n)&&(n=t),n}function g(e){return"object"===h(e)&&"function"==typeof e&&!!e.prototype}function y(t,r){if("object"!==h(t["[[Iterator]]"]))throw new Error(Object.prototype.toString.call(t["[[Iterator]]"])+"is not an Object.");var o=t["[[Iterator]]"],i=f(o,"return");if(i===e)return r;try{var a=n(i,o)}catch(e){var c=e}if(r)return r;if(c)throw c;if("object"!==h(a))throw new TypeError("Iterator's return method returned a non-object.");return r}function b(e){var t=function(e){if(arguments.length<2)var t=n(e["[[NextMethod]]"],e["[[Iterator]]"]);else t=n(e["[[NextMethod]]"],e["[[Iterator]]"],[arguments[1]]);if("object"!==h(t))throw new TypeError("bad iterator");return t}(e);return!0!==function(e){if("object"!==h(e))throw new Error(Object.prototype.toString.call(e)+"is not an Object.");return c(r(e,"done"))}(t)&&t}function m(e){if("object"!==h(e))throw new Error(Object.prototype.toString.call(e)+"is not an Object.");return r(e,"value")}function v(e,t){if("string"===t)var o=["toString","valueOf"];else o=["valueOf","toString"];for(var i=0;i1?arguments[1]:e;if("object"===h(t)){if(arguments.length<2)var o="default";else r===String?o="string":r===Number&&(o="number");var i="function"==typeof this.Symbol&&"symbol"==typeof this.Symbol.toPrimitive?f(t,this.Symbol.toPrimitive):e;if(i!==e){var a=n(i,t,[o]);if("object"!==h(a))return a;throw new TypeError("Cannot convert exotic object to primitive.")}return"default"===o&&(o="number"),v(t,o)}return t}(t,"string"));default:return String(t)}}var S,j,O;function _(e,t,n){var r={value:n,writable:!0,enumerable:!0,configurable:!0};try{return Object.defineProperty(e,t,r),!0}catch(e){return!1}}function T(e,t,n){var r=_(e,t,n);if(!r)throw new TypeError("Cannot assign value `"+Object.prototype.toString.call(n)+"` to property `"+Object.prototype.toString.call(t)+"` on object `"+Object.prototype.toString.call(e)+"`");return r}function A(e,t){if("boolean"!==h(t))throw new Error;var n={};return _(n,"value",e),_(n,"done",t),n}function k(e,t,n){var r={value:n,writable:!0,enumerable:!1,configurable:!0};Object.defineProperty(e,t,r)}if("Date"in this&&"now"in this.Date&&"getTime"in this.Date.prototype||(Date.now=function(){return(new Date).getTime()}),"document"in this||"undefined"==typeof WorkerGlobalScope&&"function"!=typeof importScripts&&(this.HTMLDocument?this.Document=this.HTMLDocument:(this.Document=this.HTMLDocument=document.constructor=new Function("return function Document() {}")(),this.Document.prototype=document)),"Element"in this&&"HTMLElement"in this||function(){function e(){return l--||clearTimeout(t),!(!document.body||document.body.prototype||!/(complete|interactive)/.test(document.readyState)||(a(document,!0),t&&document.body.prototype&&clearTimeout(t),!document.body.prototype))}if(!window.Element||window.HTMLElement){window.Element=window.HTMLElement=new Function("return function Element() {}")();var t,n=document.appendChild(document.createElement("body")),r=n.appendChild(document.createElement("iframe")).contentWindow.document,o=Element.prototype=r.appendChild(r.createElement("*")),i={},a=function(e,t){var n,r,o,c=e.childNodes||[],s=-1;if(1===e.nodeType&&e.constructor!==Element)for(n in e.constructor=Element,i)r=i[n],e[n]=r;for(;o=t&&c[++s];)a(o,t);return e},c=document.getElementsByTagName("*"),s=document.createElement,l=100;o.attachEvent("onpropertychange",(function(e){for(var t,n=e.propertyName,r=!i.hasOwnProperty(n),a=o[n],s=i[n],l=-1;t=c[++l];)1===t.nodeType&&(r||t[n]===s)&&(t[n]=a);i[n]=a})),o.constructor=Element,o.hasAttribute||(o.hasAttribute=function(e){return null!==this.getAttribute(e)}),e()||(document.onreadystatechange=e,t=setInterval(e,25)),document.createElement=function(e){var t=s(String(e).toLowerCase());return a(t)},document.removeChild(n)}else window.HTMLElement=window.Element}(),"defineProperty"in Object&&function(){try{return Object.defineProperty({},"test",{value:42}),!0}catch(e){return!1}}()||(S=Object.defineProperty,j=Object.prototype.hasOwnProperty("__defineGetter__"),O="A property cannot both have accessors and be writable or have a value",Object.defineProperty=function(e,t,n){if(S&&(e===window||e===document||e===Element.prototype||e instanceof Element))return S(e,t,n);if(null===e||!(e instanceof Object||"object"==typeof e))throw new TypeError("Object.defineProperty called on non-object");if(!(n instanceof Object))throw new TypeError("Property description must be an object");var r=String(t),o="value"in n||"writable"in n,i="get"in n&&typeof n.get,a="set"in n&&typeof n.set;if(i){if("function"!==i)throw new TypeError("Getter must be a function");if(!j)throw new TypeError("Getters & setters cannot be defined on this javascript engine");if(o)throw new TypeError(O);Object.__defineGetter__.call(e,r,n.get)}else e[r]=n.value;if(a){if("function"!==a)throw new TypeError("Setter must be a function");if(!j)throw new TypeError("Getters & setters cannot be defined on this javascript engine");if(o)throw new TypeError(O);Object.__defineSetter__.call(e,r,n.set)}return"value"in n&&(e[r]=n.value),e}),"isArray"in Array||k(Array,"isArray",(function(e){return i(e)})),"forEach"in Array.prototype||k(Array.prototype,"forEach",(function(t){var i=u(this),c=i instanceof String?i.split(""):i,s=l(r(i,"length"));if(!1===a(t))throw new TypeError(t+" is not a function");for(var p=arguments.length>1?arguments[1]:e,f=0;f=n)return-1;if(i>=0)var a=-0===i?0:i;else(a=n+i)<0&&(a=0);for(;a1?arguments[1]:e,f=0;f2?arguments[2]:e,r=arguments.length>1?arguments[1]:[];if(!g(e))throw new TypeError("F must be a constructor.");if(!g(t))throw new TypeError("newTarget must be a constructor.");if(t===e)return new(Function.prototype.bind.apply(e,[null].concat(r)));var o=P(t,Object.prototype);return n(e,o,r)}(c,[a])}function N(e){var t=arguments.length>1?arguments[1]:f(e,Symbol.iterator),r=n(t,e);if("object"!==h(r))throw new TypeError("bad iterator");var o=p(r,"next"),i=Object.create(null);return i["[[Iterator]]"]=r,i["[[NextMethod]]"]=o,i["[[Done]]"]=!1,i}"getPrototypeOf"in Object||k(Object,"getPrototypeOf",(function(e){if(e!==Object(e))throw new TypeError("Object.getPrototypeOf called on non-object");var t=e.__proto__;return t||null===t?t:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?Object.prototype:null})),"keys"in Object&&function(){return 2===Object.keys(arguments).length}(1,2)&&function(){try{return Object.keys(""),!0}catch(e){return!1}}()||k(Object,"keys",function(){var t=Object.prototype.hasOwnProperty,n=Object.prototype.toString,r=Object.prototype.propertyIsEnumerable,o=!r.call({toString:null},"toString"),i=r.call((function(){}),"prototype"),a=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],c=function(e){var t=e.constructor;return t&&t.prototype===e},s={$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},l=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!s["$"+e]&&t.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{c(window[e])}catch(e){return!0}}catch(e){return!0}return!1}(),u=function(e){if("undefined"==typeof window||!l)return c(e);try{return c(e)}catch(e){return!1}};return function(r){var c="[object Function]"===n.call(r),s=function(e){var t=n.call(e),r="[object Arguments]"===t;return r||(r="[object Array]"!==t&&null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&"[object Function]"===n.call(e.callee)),r}(r),l="[object String]"===n.call(r),p=[];if(r===e||null===r)throw new TypeError("Cannot convert undefined or null to object");var f=i&&c;if(l&&r.length>0&&!t.call(r,0))for(var h=0;h0)for(var d=0;d1?arguments[1]:e,f=I(i,0),h=0,d=0;h1?arguments[1]:e,p=I(i,c),f=0;f0?arguments[0]:e;if(null===o||o===e)return n;var i=n.add;if(!a(i))throw new TypeError("Set.prototype.add is not a function");try{for(var c=N(o);;){var s=b(c);if(!1===s)return n;var l=m(s);try{i.call(n,l)}catch(e){return y(c,e)}}}catch(e){if(!Array.isArray(o)&&"[object Arguments]"!==Object.prototype.toString.call(o)&&!o.callee)throw e;var u,p=o.length;for(u=0;u=0&&c>=0&&{top:n,bottom:r,left:o,right:i,width:a,height:c}}function s(e){var t;try{t=e.getBoundingClientRect()}catch(e){}return t?(t.width&&t.height||(t={top:t.top,right:t.right,bottom:t.bottom,left:t.left,width:t.right-t.left,height:t.bottom-t.top}),t):{top:0,bottom:0,left:0,right:0,width:0,height:0}}function l(e,t){for(var n=t;n;){if(n==e)return!0;n=u(n)}return!1}function u(e){var t=e.parentNode;return t&&11==t.nodeType&&t.host?t.host:t&&t.assignedSlot?t.assignedSlot.parentNode:t}r.prototype.THROTTLE_TIMEOUT=100,r.prototype.POLL_INTERVAL=null,r.prototype.USE_MUTATION_OBSERVER=!0,r.prototype.observe=function(e){if(!this._observationTargets.some((function(t){return t.element==e}))){if(!e||1!=e.nodeType)throw new Error("target must be an Element");this._registerInstance(),this._observationTargets.push({element:e,entry:null}),this._monitorIntersections(),this._checkForIntersections()}},r.prototype.unobserve=function(e){this._observationTargets=this._observationTargets.filter((function(t){return t.element!=e})),this._observationTargets.length||(this._unmonitorIntersections(),this._unregisterInstance())},r.prototype.disconnect=function(){this._observationTargets=[],this._unmonitorIntersections(),this._unregisterInstance()},r.prototype.takeRecords=function(){var e=this._queuedEntries.slice();return this._queuedEntries=[],e},r.prototype._initThresholds=function(e){var t=e||[0];return Array.isArray(t)||(t=[t]),t.sort().filter((function(e,t,n){if("number"!=typeof e||isNaN(e)||e<0||e>1)throw new Error("threshold must be a number between 0 and 1 inclusively");return e!==n[t-1]}))},r.prototype._parseRootMargin=function(e){var t=(e||"0px").split(/\s+/).map((function(e){var t=/^(-?\d*\.?\d+)(px|%)$/.exec(e);if(!t)throw new Error("rootMargin must be specified in pixels or percent");return{value:parseFloat(t[1]),unit:t[2]}}));return t[1]=t[1]||t[0],t[2]=t[2]||t[0],t[3]=t[3]||t[1],t},r.prototype._monitorIntersections=function(){this._monitoringIntersections||(this._monitoringIntersections=!0,this.POLL_INTERVAL?this._monitoringInterval=setInterval(this._checkForIntersections,this.POLL_INTERVAL):(i(e,"resize",this._checkForIntersections,!0),i(t,"scroll",this._checkForIntersections,!0),this.USE_MUTATION_OBSERVER&&"MutationObserver"in e&&(this._domObserver=new MutationObserver(this._checkForIntersections),this._domObserver.observe(t,{attributes:!0,childList:!0,characterData:!0,subtree:!0}))))},r.prototype._unmonitorIntersections=function(){this._monitoringIntersections&&(this._monitoringIntersections=!1,clearInterval(this._monitoringInterval),this._monitoringInterval=null,a(e,"resize",this._checkForIntersections,!0),a(t,"scroll",this._checkForIntersections,!0),this._domObserver&&(this._domObserver.disconnect(),this._domObserver=null))},r.prototype._checkForIntersections=function(){var e=this._rootIsInDom(),t=e?this._getRootRect():{top:0,bottom:0,left:0,right:0,width:0,height:0};this._observationTargets.forEach((function(r){var i=r.element,a=s(i),c=this._rootContainsTarget(i),l=r.entry,u=e&&c&&this._computeTargetAndRootIntersection(i,t),p=r.entry=new n({time:o(),target:i,boundingClientRect:a,rootBounds:t,intersectionRect:u});l?e&&c?this._hasCrossedThreshold(l,p)&&this._queuedEntries.push(p):l&&l.isIntersecting&&this._queuedEntries.push(p):this._queuedEntries.push(p)}),this),this._queuedEntries.length&&this._callback(this.takeRecords(),this)},r.prototype._computeTargetAndRootIntersection=function(n,r){if("none"!=e.getComputedStyle(n).display){for(var o=s(n),i=u(n),a=!1;!a;){var l=null,p=1==i.nodeType?e.getComputedStyle(i):{};if("none"==p.display)return;if(i==this.root||i==t?(a=!0,l=r):i!=t.body&&i!=t.documentElement&&"visible"!=p.overflow&&(l=s(i)),l&&!(o=c(l,o)))break;i=u(i)}return o}},r.prototype._getRootRect=function(){var e;if(this.root)e=s(this.root);else{var n=t.documentElement,r=t.body;e={top:0,left:0,right:n.clientWidth||r.clientWidth,width:n.clientWidth||r.clientWidth,bottom:n.clientHeight||r.clientHeight,height:n.clientHeight||r.clientHeight}}return this._expandRectByRootMargin(e)},r.prototype._expandRectByRootMargin=function(e){var t=this._rootMarginValues.map((function(t,n){return"px"==t.unit?t.value:t.value*(n%2?e.width:e.height)/100})),n={top:e.top-t[0],right:e.right+t[1],bottom:e.bottom+t[2],left:e.left-t[3]};return n.width=n.right-n.left,n.height=n.bottom-n.top,n},r.prototype._hasCrossedThreshold=function(e,t){var n=e&&e.isIntersecting?e.intersectionRatio||0:-1,r=t.isIntersecting?t.intersectionRatio||0:-1;if(n!==r)for(var o=0;o{const[n]=e.filter((e=>e.isIntersecting));n&&t.callbacks.forEach((e=>e(n)))}),{root:document.querySelector("slyds"),rootMargin:"0px 0px 1px 0px",threshold:1});document.querySelectorAll("slyd").forEach((t=>e.observe(t)))}document.querySelectorAll("slyd").forEach((e=>e.setAttribute("aria-role","article")));const n={slyds:{active:void 0}},r=e=>e.querySelectorAll("[lazy-src]").forEach((e=>{e.setAttribute("src",e.getAttribute("lazy-src")),e.removeAttribute("lazy-src")})),o=e=>Array.from(e.querySelectorAll("video")).filter((e=>e.hasAttribute("src")&&e.paused)).forEach((e=>e.play())),i=e=>e.querySelectorAll("video").forEach((e=>e.pause()));var a;a=e=>{var t;(()=>{const{active:e}=n.slyds;e&&(e.removeAttribute("slyd-active"),e.removeAttribute("tabIndex"),i(e))})(),(({target:e})=>{n.slyds.active=e,n.slyds.active.setAttribute("slyd-active",!0),e.setAttribute("tabIndex",-1),r(e),o(e)})(e),t=n.slyds.active.id,window.location.hash=t},t.callbacks.add(a),window.location.hash&&(window.onload=()=>window.location=window.location)}(); 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slyd", 3 | "version": "0.1.0", 4 | "author": "Adam Argyle", 5 | "description": "Snappy, responsive, touch optimized, bi-directional presentation framework", 6 | "keywords": [ 7 | "slides", 8 | "deck", 9 | "presentation", 10 | "slyd" 11 | ], 12 | "main": "dist/slyd.js", 13 | "module": "app/slyd/index.js", 14 | "style": "app/slyd/index.css", 15 | "scripts": { 16 | "start": "npm run concurrent", 17 | "concurrent": "concurrently --kill-others \"npm run dev:js\" \"npm run dev:css\" \"npm run dev:server\"", 18 | "bundle": "concurrently \"rollup -c\" \"postcss app/slyd/index.css -o app/slyd.css\"", 19 | "dev:js": "rollup -c -w", 20 | "dev:css": "postcss app/slyd/index.css -o app/slyd.css -w", 21 | "dev:server": "browser-sync start --server 'app' --files 'app/index.html,app/slyd.css,app/slyd.js' --no-open --no-notify", 22 | "build": "npm run dist:js && npm run dist:css", 23 | "dist:js": "rollup -c --environment NODE_ENV:production", 24 | "dist:css": "postcss app/slyd/index.css -o dist/slyd.css" 25 | }, 26 | "homepage": "https://slyd.netlify.com", 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/argyleink/slyd" 30 | }, 31 | "license": "ISC", 32 | "dependencies": {}, 33 | "devDependencies": { 34 | "browser-sync": "^2.27.7", 35 | "concurrently": "^7.0.0", 36 | "cssnano": "^5.0.17", 37 | "import-http": "^0.3.1", 38 | "postcss": "^8.4.6", 39 | "postcss-cli": "^9.1.0", 40 | "postcss-easings": "^3.0.1", 41 | "postcss-import": "^14.0.2", 42 | "postcss-loader": "^6.2.1", 43 | "postcss-preset-env": "^7.3.1", 44 | "rollup": "^2.67.1", 45 | "rollup-plugin-node-resolve": "^5.2.0", 46 | "rollup-plugin-postcss": "^4.0.2", 47 | "rollup-plugin-terser": "^7.0.2" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const postcssPresetEnv = require('postcss-preset-env') 2 | const postcssImport = require('postcss-import') 3 | const postcsseasings = require('postcss-easings') 4 | const postcssnano = require('cssnano') 5 | 6 | const is_prod = process.env.NODE_ENV 7 | ? true 8 | : false 9 | 10 | const dev_plugins = [ 11 | postcsseasings(), 12 | postcssImport(), 13 | postcssPresetEnv({ 14 | stage: 0, 15 | features: { 16 | 'logical-properties-and-values': false, 17 | 'prefers-color-scheme-query': false, 18 | 'gap-properties': false, 19 | 'custom-properties': false, 20 | 'place-properties': false, 21 | 'not-pseudo-class': false, 22 | 'focus-visible-pseudo-class': false, 23 | 'focus-within-pseudo-class': false, 24 | 'color-functional-notation': false, 25 | } 26 | }), 27 | ] 28 | 29 | const prod_plugins = [ 30 | postcssnano({preset: 'default'}), 31 | ] 32 | 33 | const plugins = is_prod 34 | ? [...dev_plugins, ...prod_plugins] 35 | : dev_plugins 36 | 37 | module.exports = { 38 | plugins 39 | } -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve' 2 | import postcss from 'rollup-plugin-postcss' 3 | import { terser } from "rollup-plugin-terser" 4 | import { default as importHTTP } from 'import-http/rollup' 5 | 6 | const is_prod = process.env.NODE_ENV 7 | ? true 8 | : false 9 | 10 | const dev_plugins = [ 11 | resolve(), 12 | importHTTP(), 13 | postcss({ 14 | extract: false, 15 | inject: false, 16 | }) 17 | ] 18 | 19 | const prod_plugins = [ 20 | terser(), 21 | ] 22 | 23 | const plugins = is_prod 24 | ? [...dev_plugins, ...prod_plugins] 25 | : dev_plugins 26 | 27 | export default { 28 | input: 'app/index.js', 29 | output: { 30 | file: is_prod ? 'dist/slyd.js' : 'app/slyd.js', 31 | format: is_prod ? 'iife' : 'es', 32 | }, 33 | plugins, 34 | watch: { 35 | exclude: ['node_modules/**'], 36 | } 37 | } --------------------------------------------------------------------------------