pub / tw2html

Checks online status of streams on twitch.tv and lets you watch them
git clone https://https://src.jayvii.de/pub/tw2html.git
Home | Log | Files | Exports | Refs | README | RSS

commit 74f22e214c4daf0ac27e07b71d6837e07c994f78
Author: JayVii <jayvii[AT]posteo[DOT]de>
Date:   Sat, 24 Feb 2024 17:17:43 +0100

Initial code dump

Diffstat:
Aassets/css/all.css | 2443+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aassets/css/custom.css | 42++++++++++++++++++++++++++++++++++++++++++
Aassets/css/loading.css | 283+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aassets/img/chat_mono.svg | 1+
Aassets/img/play_mono.svg | 1+
Aassets/img/streamlink_mono.svg | 1+
Aassets/img/twitch.png | 0
Aassets/img/twitch_144.png | 0
Aassets/img/twitch_16.png | 0
Aassets/img/twitch_168.png | 0
Aassets/img/twitch_192.png | 0
Aassets/img/twitch_256.png | 0
Aassets/img/twitch_32.png | 0
Aassets/img/twitch_48.png | 0
Aassets/img/twitch_72.png | 0
Aassets/img/twitch_96.png | 0
Aassets/img/twitch_mono.svg | 1+
Aassets/js/twitch.js | 45+++++++++++++++++++++++++++++++++++++++++++++
Aindex.php | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amanifest.json | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20 files changed, 3086 insertions(+), 0 deletions(-)

diff --git a/assets/css/all.css b/assets/css/all.css @@ -0,0 +1,2443 @@ +/* + Miniport by HTML5 UP + html5up.net | @ajlkn + Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) +*/ + +html, body, div, span, applet, object, +iframe, h1, h2, h3, h4, h5, h6, p, blockquote, +pre, a, abbr, acronym, address, big, cite, +code, del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, b, +u, i, center, dl, dt, dd, ol, ul, li, fieldset, +form, label, legend, table, caption, tbody, +tfoot, thead, tr, th, td, article, aside, +canvas, details, embed, figure, figcaption, +footer, header, hgroup, menu, nav, output, ruby, +section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline;} + +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block;} + +body { + line-height: 1; +} + +ol, ul { + list-style: none; +} + +blockquote, q { + quotes: none; +} + + blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none; + } + +table { + border-collapse: collapse; + border-spacing: 0; +} + +body { + -webkit-text-size-adjust: none; +} + +mark { + background-color: transparent; + color: inherit; +} + +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +input, select, textarea { + -moz-appearance: none; + -webkit-appearance: none; + -ms-appearance: none; + appearance: none; +} + +/* Basic */ + + html { + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + body { + padding-top: 3.5em; + } + + body.is-preload *, body.is-preload *:before, body.is-preload *:after { + -moz-animation: none !important; + -webkit-animation: none !important; + -ms-animation: none !important; + animation: none !important; + -moz-transition: none !important; + -webkit-transition: none !important; + -ms-transition: none !important; + transition: none !important; + } + + body, input, textarea, select { + font-family: 'Open Sans', sans-serif; + line-height: 1.85em; + color: #888; + font-weight: 300; + font-size: 13pt; + } + + a { + -moz-transition: color .2s ease-in-out; + -webkit-transition: color .2s ease-in-out; + -ms-transition: color .2s ease-in-out; + transition: color .2s ease-in-out; + color: #43B3E0; + text-decoration: underline; + } + + a:hover { + color: #43bff0 !important; + } + + a img { + border: 0; + } + + b, strong { + font-weight: 600; + color: #3e3e3e; + } + + i, em { + font-style: italic; + } + + sub { + position: relative; + top: 0.5em; + font-size: 0.8em; + } + + sup { + position: relative; + top: -0.5em; + font-size: 0.8em; + } + + blockquote { + border-left: solid 0.75em #eee; + padding: 1em 0 1em 1.5em; + font-style: italic; + } + + h1, h2, h3, h4, h5, h6 { + color: #3e3e3e; + margin: 0 0 0.75em 0; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration: none; + color: inherit; + } + + h2, h3, h4, h5, h6 { + font-weight: 700; + } + + h1 { + font-size: 3.25em; + letter-spacing: -0.025em; + font-weight: 300; + } + + h1 strong { + font-weight: 700; + } + + h2 { + font-size: 2em; + letter-spacing: -0.015em; + } + + h3 { + font-size: 1.5em; + letter-spacing: -0.015em; + } + + em, i { + font-style: italic; + } + + br.clear { + clear: both; + } + + hr { + border: 0; + border-top: solid 1px #444; + border-top-color: rgba(0, 0, 0, 0.35); + box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.1); + height: 1px; + margin: 3em 0; + } + + p, ul, ol, dl, table { + margin-bottom: 2em; + } + + header { + margin: 0 0 3em 0; + } + + header > p { + font-size: 1.25em; + margin: 0; + } + + footer { + margin: 3em 0 0 0; + } + + footer > p { + font-size: 1.25em; + } + +/* Container */ + + .container { + margin: 0 auto; + max-width: calc(100% - 50px); + width: 1200px; + } + + .container.medium { + width: 900px; + } + + @media screen and (max-width: 1680px) { + + .container { + width: 1200px; + } + + .container.medium { + width: 900px; + } + + } + + @media screen and (max-width: 1280px) { + + .container { + width: 960px; + } + + .container.medium { + width: 720px; + } + + } + + @media screen and (max-width: 980px) { + + .container { + width: 100%; + } + + .container.medium { + width: 75%; + } + + } + + @media screen and (max-width: 736px) { + + .container { + width: 100%; + max-width: calc(100% - 30px); + } + + .container.medium { + width: 100%; + } + + } + +/* Row */ + + .row { + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + align-items: stretch; + } + + .row > * { + box-sizing: border-box; + } + + .row.gtr-uniform > * > :last-child { + margin-bottom: 0; + } + + .row.aln-left { + justify-content: flex-start; + } + + .row.aln-center { + justify-content: center; + } + + .row.aln-right { + justify-content: flex-end; + } + + .row.aln-top { + align-items: flex-start; + } + + .row.aln-middle { + align-items: center; + } + + .row.aln-bottom { + align-items: flex-end; + } + + .row > .imp { + order: -1; + } + + .row > .col-1 { + width: 8.33333%; + } + + .row > .off-1 { + margin-left: 8.33333%; + } + + .row > .col-2 { + width: 16.66667%; + } + + .row > .off-2 { + margin-left: 16.66667%; + } + + .row > .col-3 { + width: 25%; + } + + .row > .off-3 { + margin-left: 25%; + } + + .row > .col-4 { + width: 33.33333%; + } + + .row > .off-4 { + margin-left: 33.33333%; + } + + .row > .col-5 { + width: 41.66667%; + } + + .row > .off-5 { + margin-left: 41.66667%; + } + + .row > .col-6 { + width: 50%; + } + + .row > .off-6 { + margin-left: 50%; + } + + .row > .col-7 { + width: 58.33333%; + } + + .row > .off-7 { + margin-left: 58.33333%; + } + + .row > .col-8 { + width: 66.66667%; + } + + .row > .off-8 { + margin-left: 66.66667%; + } + + .row > .col-9 { + width: 75%; + } + + .row > .off-9 { + margin-left: 75%; + } + + .row > .col-10 { + width: 83.33333%; + } + + .row > .off-10 { + margin-left: 83.33333%; + } + + .row > .col-11 { + width: 91.66667%; + } + + .row > .off-11 { + margin-left: 91.66667%; + } + + .row > .col-12 { + width: 100%; + } + + .row > .off-12 { + margin-left: 100%; + } + + .row.gtr-0 { + margin-top: 0px; + margin-left: 0px; + } + + .row.gtr-0 > * { + padding: 0px 0 0 0px; + } + + .row.gtr-0.gtr-uniform { + margin-top: 0px; + } + + .row.gtr-0.gtr-uniform > * { + padding-top: 0px; + } + + .row.gtr-25 { + margin-top: -6.25px; + margin-left: -6.25px; + } + + .row.gtr-25 > * { + padding: 6.25px 0 0 6.25px; + } + + .row.gtr-25.gtr-uniform { + margin-top: -6.25px; + } + + .row.gtr-25.gtr-uniform > * { + padding-top: 6.25px; + } + + .row.gtr-50 { + margin-top: -12.5px; + margin-left: -12.5px; + } + + .row.gtr-50 > * { + padding: 12.5px 0 0 12.5px; + } + + .row.gtr-50.gtr-uniform { + margin-top: -12.5px; + } + + .row.gtr-50.gtr-uniform > * { + padding-top: 12.5px; + } + + .row { + margin-top: -25px; + margin-left: -25px; + } + + .row > * { + padding: 25px 0 0 25px; + } + + .row.gtr-uniform { + margin-top: -25px; + } + + .row.gtr-uniform > * { + padding-top: 25px; + } + + .row.gtr-150 { + margin-top: -37.5px; + margin-left: -37.5px; + } + + .row.gtr-150 > * { + padding: 37.5px 0 0 37.5px; + } + + .row.gtr-150.gtr-uniform { + margin-top: -37.5px; + } + + .row.gtr-150.gtr-uniform > * { + padding-top: 37.5px; + } + + .row.gtr-200 { + margin-top: -50px; + margin-left: -50px; + } + + .row.gtr-200 > * { + padding: 50px 0 0 50px; + } + + .row.gtr-200.gtr-uniform { + margin-top: -50px; + } + + .row.gtr-200.gtr-uniform > * { + padding-top: 50px; + } + + @media screen and (max-width: 1680px) { + + .row { + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + align-items: stretch; + } + + .row > * { + box-sizing: border-box; + } + + .row.gtr-uniform > * > :last-child { + margin-bottom: 0; + } + + .row.aln-left { + justify-content: flex-start; + } + + .row.aln-center { + justify-content: center; + } + + .row.aln-right { + justify-content: flex-end; + } + + .row.aln-top { + align-items: flex-start; + } + + .row.aln-middle { + align-items: center; + } + + .row.aln-bottom { + align-items: flex-end; + } + + .row > .imp-xlarge { + order: -1; + } + + .row > .col-1-xlarge { + width: 8.33333%; + } + + .row > .off-1-xlarge { + margin-left: 8.33333%; + } + + .row > .col-2-xlarge { + width: 16.66667%; + } + + .row > .off-2-xlarge { + margin-left: 16.66667%; + } + + .row > .col-3-xlarge { + width: 25%; + } + + .row > .off-3-xlarge { + margin-left: 25%; + } + + .row > .col-4-xlarge { + width: 33.33333%; + } + + .row > .off-4-xlarge { + margin-left: 33.33333%; + } + + .row > .col-5-xlarge { + width: 41.66667%; + } + + .row > .off-5-xlarge { + margin-left: 41.66667%; + } + + .row > .col-6-xlarge { + width: 50%; + } + + .row > .off-6-xlarge { + margin-left: 50%; + } + + .row > .col-7-xlarge { + width: 58.33333%; + } + + .row > .off-7-xlarge { + margin-left: 58.33333%; + } + + .row > .col-8-xlarge { + width: 66.66667%; + } + + .row > .off-8-xlarge { + margin-left: 66.66667%; + } + + .row > .col-9-xlarge { + width: 75%; + } + + .row > .off-9-xlarge { + margin-left: 75%; + } + + .row > .col-10-xlarge { + width: 83.33333%; + } + + .row > .off-10-xlarge { + margin-left: 83.33333%; + } + + .row > .col-11-xlarge { + width: 91.66667%; + } + + .row > .off-11-xlarge { + margin-left: 91.66667%; + } + + .row > .col-12-xlarge { + width: 100%; + } + + .row > .off-12-xlarge { + margin-left: 100%; + } + + .row.gtr-0 { + margin-top: 0px; + margin-left: 0px; + } + + .row.gtr-0 > * { + padding: 0px 0 0 0px; + } + + .row.gtr-0.gtr-uniform { + margin-top: 0px; + } + + .row.gtr-0.gtr-uniform > * { + padding-top: 0px; + } + + .row.gtr-25 { + margin-top: -6.25px; + margin-left: -6.25px; + } + + .row.gtr-25 > * { + padding: 6.25px 0 0 6.25px; + } + + .row.gtr-25.gtr-uniform { + margin-top: -6.25px; + } + + .row.gtr-25.gtr-uniform > * { + padding-top: 6.25px; + } + + .row.gtr-50 { + margin-top: -12.5px; + margin-left: -12.5px; + } + + .row.gtr-50 > * { + padding: 12.5px 0 0 12.5px; + } + + .row.gtr-50.gtr-uniform { + margin-top: -12.5px; + } + + .row.gtr-50.gtr-uniform > * { + padding-top: 12.5px; + } + + .row { + margin-top: -25px; + margin-left: -25px; + } + + .row > * { + padding: 25px 0 0 25px; + } + + .row.gtr-uniform { + margin-top: -25px; + } + + .row.gtr-uniform > * { + padding-top: 25px; + } + + .row.gtr-150 { + margin-top: -37.5px; + margin-left: -37.5px; + } + + .row.gtr-150 > * { + padding: 37.5px 0 0 37.5px; + } + + .row.gtr-150.gtr-uniform { + margin-top: -37.5px; + } + + .row.gtr-150.gtr-uniform > * { + padding-top: 37.5px; + } + + .row.gtr-200 { + margin-top: -50px; + margin-left: -50px; + } + + .row.gtr-200 > * { + padding: 50px 0 0 50px; + } + + .row.gtr-200.gtr-uniform { + margin-top: -50px; + } + + .row.gtr-200.gtr-uniform > * { + padding-top: 50px; + } + + } + + @media screen and (max-width: 1280px) { + + .row { + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + align-items: stretch; + } + + .row > * { + box-sizing: border-box; + } + + .row.gtr-uniform > * > :last-child { + margin-bottom: 0; + } + + .row.aln-left { + justify-content: flex-start; + } + + .row.aln-center { + justify-content: center; + } + + .row.aln-right { + justify-content: flex-end; + } + + .row.aln-top { + align-items: flex-start; + } + + .row.aln-middle { + align-items: center; + } + + .row.aln-bottom { + align-items: flex-end; + } + + .row > .imp-large { + order: -1; + } + + .row > .col-1-large { + width: 8.33333%; + } + + .row > .off-1-large { + margin-left: 8.33333%; + } + + .row > .col-2-large { + width: 16.66667%; + } + + .row > .off-2-large { + margin-left: 16.66667%; + } + + .row > .col-3-large { + width: 25%; + } + + .row > .off-3-large { + margin-left: 25%; + } + + .row > .col-4-large { + width: 33.33333%; + } + + .row > .off-4-large { + margin-left: 33.33333%; + } + + .row > .col-5-large { + width: 41.66667%; + } + + .row > .off-5-large { + margin-left: 41.66667%; + } + + .row > .col-6-large { + width: 50%; + } + + .row > .off-6-large { + margin-left: 50%; + } + + .row > .col-7-large { + width: 58.33333%; + } + + .row > .off-7-large { + margin-left: 58.33333%; + } + + .row > .col-8-large { + width: 66.66667%; + } + + .row > .off-8-large { + margin-left: 66.66667%; + } + + .row > .col-9-large { + width: 75%; + } + + .row > .off-9-large { + margin-left: 75%; + } + + .row > .col-10-large { + width: 83.33333%; + } + + .row > .off-10-large { + margin-left: 83.33333%; + } + + .row > .col-11-large { + width: 91.66667%; + } + + .row > .off-11-large { + margin-left: 91.66667%; + } + + .row > .col-12-large { + width: 100%; + } + + .row > .off-12-large { + margin-left: 100%; + } + + .row.gtr-0 { + margin-top: 0px; + margin-left: 0px; + } + + .row.gtr-0 > * { + padding: 0px 0 0 0px; + } + + .row.gtr-0.gtr-uniform { + margin-top: 0px; + } + + .row.gtr-0.gtr-uniform > * { + padding-top: 0px; + } + + .row.gtr-25 { + margin-top: -6.25px; + margin-left: -6.25px; + } + + .row.gtr-25 > * { + padding: 6.25px 0 0 6.25px; + } + + .row.gtr-25.gtr-uniform { + margin-top: -6.25px; + } + + .row.gtr-25.gtr-uniform > * { + padding-top: 6.25px; + } + + .row.gtr-50 { + margin-top: -12.5px; + margin-left: -12.5px; + } + + .row.gtr-50 > * { + padding: 12.5px 0 0 12.5px; + } + + .row.gtr-50.gtr-uniform { + margin-top: -12.5px; + } + + .row.gtr-50.gtr-uniform > * { + padding-top: 12.5px; + } + + .row { + margin-top: -25px; + margin-left: -25px; + } + + .row > * { + padding: 25px 0 0 25px; + } + + .row.gtr-uniform { + margin-top: -25px; + } + + .row.gtr-uniform > * { + padding-top: 25px; + } + + .row.gtr-150 { + margin-top: -37.5px; + margin-left: -37.5px; + } + + .row.gtr-150 > * { + padding: 37.5px 0 0 37.5px; + } + + .row.gtr-150.gtr-uniform { + margin-top: -37.5px; + } + + .row.gtr-150.gtr-uniform > * { + padding-top: 37.5px; + } + + .row.gtr-200 { + margin-top: -50px; + margin-left: -50px; + } + + .row.gtr-200 > * { + padding: 50px 0 0 50px; + } + + .row.gtr-200.gtr-uniform { + margin-top: -50px; + } + + .row.gtr-200.gtr-uniform > * { + padding-top: 50px; + } + + } + + @media screen and (max-width: 980px) { + + .row { + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + align-items: stretch; + } + + .row > * { + box-sizing: border-box; + } + + .row.gtr-uniform > * > :last-child { + margin-bottom: 0; + } + + .row.aln-left { + justify-content: flex-start; + } + + .row.aln-center { + justify-content: center; + } + + .row.aln-right { + justify-content: flex-end; + } + + .row.aln-top { + align-items: flex-start; + } + + .row.aln-middle { + align-items: center; + } + + .row.aln-bottom { + align-items: flex-end; + } + + .row > .imp-medium { + order: -1; + } + + .row > .col-1-medium { + width: 8.33333%; + } + + .row > .off-1-medium { + margin-left: 8.33333%; + } + + .row > .col-2-medium { + width: 16.66667%; + } + + .row > .off-2-medium { + margin-left: 16.66667%; + } + + .row > .col-3-medium { + width: 25%; + } + + .row > .off-3-medium { + margin-left: 25%; + } + + .row > .col-4-medium { + width: 33.33333%; + } + + .row > .off-4-medium { + margin-left: 33.33333%; + } + + .row > .col-5-medium { + width: 41.66667%; + } + + .row > .off-5-medium { + margin-left: 41.66667%; + } + + .row > .col-6-medium { + width: 50%; + } + + .row > .off-6-medium { + margin-left: 50%; + } + + .row > .col-7-medium { + width: 58.33333%; + } + + .row > .off-7-medium { + margin-left: 58.33333%; + } + + .row > .col-8-medium { + width: 66.66667%; + } + + .row > .off-8-medium { + margin-left: 66.66667%; + } + + .row > .col-9-medium { + width: 75%; + } + + .row > .off-9-medium { + margin-left: 75%; + } + + .row > .col-10-medium { + width: 83.33333%; + } + + .row > .off-10-medium { + margin-left: 83.33333%; + } + + .row > .col-11-medium { + width: 91.66667%; + } + + .row > .off-11-medium { + margin-left: 91.66667%; + } + + .row > .col-12-medium { + width: 100%; + } + + .row > .off-12-medium { + margin-left: 100%; + } + + .row.gtr-0 { + margin-top: 0px; + margin-left: 0px; + } + + .row.gtr-0 > * { + padding: 0px 0 0 0px; + } + + .row.gtr-0.gtr-uniform { + margin-top: 0px; + } + + .row.gtr-0.gtr-uniform > * { + padding-top: 0px; + } + + .row.gtr-25 { + margin-top: -6.25px; + margin-left: -6.25px; + } + + .row.gtr-25 > * { + padding: 6.25px 0 0 6.25px; + } + + .row.gtr-25.gtr-uniform { + margin-top: -6.25px; + } + + .row.gtr-25.gtr-uniform > * { + padding-top: 6.25px; + } + + .row.gtr-50 { + margin-top: -12.5px; + margin-left: -12.5px; + } + + .row.gtr-50 > * { + padding: 12.5px 0 0 12.5px; + } + + .row.gtr-50.gtr-uniform { + margin-top: -12.5px; + } + + .row.gtr-50.gtr-uniform > * { + padding-top: 12.5px; + } + + .row { + margin-top: -25px; + margin-left: -25px; + } + + .row > * { + padding: 25px 0 0 25px; + } + + .row.gtr-uniform { + margin-top: -25px; + } + + .row.gtr-uniform > * { + padding-top: 25px; + } + + .row.gtr-150 { + margin-top: -37.5px; + margin-left: -37.5px; + } + + .row.gtr-150 > * { + padding: 37.5px 0 0 37.5px; + } + + .row.gtr-150.gtr-uniform { + margin-top: -37.5px; + } + + .row.gtr-150.gtr-uniform > * { + padding-top: 37.5px; + } + + .row.gtr-200 { + margin-top: -50px; + margin-left: -50px; + } + + .row.gtr-200 > * { + padding: 50px 0 0 50px; + } + + .row.gtr-200.gtr-uniform { + margin-top: -50px; + } + + .row.gtr-200.gtr-uniform > * { + padding-top: 50px; + } + + } + + @media screen and (max-width: 736px) { + + .row { + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + align-items: stretch; + } + + .row > * { + box-sizing: border-box; + } + + .row.gtr-uniform > * > :last-child { + margin-bottom: 0; + } + + .row.aln-left { + justify-content: flex-start; + } + + .row.aln-center { + justify-content: center; + } + + .row.aln-right { + justify-content: flex-end; + } + + .row.aln-top { + align-items: flex-start; + } + + .row.aln-middle { + align-items: center; + } + + .row.aln-bottom { + align-items: flex-end; + } + + .row > .imp-small { + order: -1; + } + + .row > .col-1-small { + width: 8.33333%; + } + + .row > .off-1-small { + margin-left: 8.33333%; + } + + .row > .col-2-small { + width: 16.66667%; + } + + .row > .off-2-small { + margin-left: 16.66667%; + } + + .row > .col-3-small { + width: 25%; + } + + .row > .off-3-small { + margin-left: 25%; + } + + .row > .col-4-small { + width: 33.33333%; + } + + .row > .off-4-small { + margin-left: 33.33333%; + } + + .row > .col-5-small { + width: 41.66667%; + } + + .row > .off-5-small { + margin-left: 41.66667%; + } + + .row > .col-6-small { + width: 50%; + } + + .row > .off-6-small { + margin-left: 50%; + } + + .row > .col-7-small { + width: 58.33333%; + } + + .row > .off-7-small { + margin-left: 58.33333%; + } + + .row > .col-8-small { + width: 66.66667%; + } + + .row > .off-8-small { + margin-left: 66.66667%; + } + + .row > .col-9-small { + width: 75%; + } + + .row > .off-9-small { + margin-left: 75%; + } + + .row > .col-10-small { + width: 83.33333%; + } + + .row > .off-10-small { + margin-left: 83.33333%; + } + + .row > .col-11-small { + width: 91.66667%; + } + + .row > .off-11-small { + margin-left: 91.66667%; + } + + .row > .col-12-small { + width: 100%; + } + + .row > .off-12-small { + margin-left: 100%; + } + + .row.gtr-0 { + margin-top: 0px; + margin-left: 0px; + } + + .row.gtr-0 > * { + padding: 0px 0 0 0px; + } + + .row.gtr-0.gtr-uniform { + margin-top: 0px; + } + + .row.gtr-0.gtr-uniform > * { + padding-top: 0px; + } + + .row.gtr-25 { + margin-top: -3.75px; + margin-left: -3.75px; + } + + .row.gtr-25 > * { + padding: 3.75px 0 0 3.75px; + } + + .row.gtr-25.gtr-uniform { + margin-top: -3.75px; + } + + .row.gtr-25.gtr-uniform > * { + padding-top: 3.75px; + } + + .row.gtr-50 { + margin-top: -7.5px; + margin-left: -7.5px; + } + + .row.gtr-50 > * { + padding: 7.5px 0 0 7.5px; + } + + .row.gtr-50.gtr-uniform { + margin-top: -7.5px; + } + + .row.gtr-50.gtr-uniform > * { + padding-top: 7.5px; + } + + .row { + margin-top: -15px; + margin-left: -15px; + } + + .row > * { + padding: 15px 0 0 15px; + } + + .row.gtr-uniform { + margin-top: -15px; + } + + .row.gtr-uniform > * { + padding-top: 15px; + } + + .row.gtr-150 { + margin-top: -22.5px; + margin-left: -22.5px; + } + + .row.gtr-150 > * { + padding: 22.5px 0 0 22.5px; + } + + .row.gtr-150.gtr-uniform { + margin-top: -22.5px; + } + + .row.gtr-150.gtr-uniform > * { + padding-top: 22.5px; + } + + .row.gtr-200 { + margin-top: -30px; + margin-left: -30px; + } + + .row.gtr-200 > * { + padding: 30px 0 0 30px; + } + + .row.gtr-200.gtr-uniform { + margin-top: -30px; + } + + .row.gtr-200.gtr-uniform > * { + padding-top: 30px; + } + + } + +/* Form */ + + form label { + color: #3e3e3e; + font-weight: 700; + display: block; + margin: 0 0 0.5em 0; + } + + form input[type=text], + form input[type=email], + form input[type=password], + form select, + form textarea { + -moz-transition: background .2s ease-in-out, box-shadow .2s ease-in-out; + -webkit-transition: background .2s ease-in-out, box-shadow .2s ease-in-out; + -ms-transition: background .2s ease-in-out, box-shadow .2s ease-in-out; + transition: background .2s ease-in-out, box-shadow .2s ease-in-out; + -webkit-appearance: none; + display: block; + border: 0; + padding: 0.75em; + font-size: 1em; + border-radius: 8px; + border: solid 1px #ddd; + background: #fff; + color: #bbb; + box-shadow: inset 0px 2px 3px 1px rgba(0, 0, 0, 0.05), 0px 1px 0px 0px rgba(255, 255, 255, 0.025); + width: 100%; + } + + form input[type=text]:focus, + form input[type=email]:focus, + form input[type=password]:focus, + form select:focus, + form textarea:focus { + background: #fafafa; + box-shadow: inset 0px 2px 5px 0px rgba(0, 0, 0, 0.05), 0px 1px 0px 0px rgba(255, 255, 255, 0.025), inset 0px 0px 2px 1px #43bff0; + } + + form textarea { + height: 15em; + } + + form .actions:last-child { + margin-bottom: 0; + } + + form ::-webkit-input-placeholder { + color: #555 !important; + } + + form :-moz-placeholder { + color: #555 !important; + } + + form ::-moz-placeholder { + color: #555 !important; + } + + form :-ms-input-placeholder { + color: #555 !important; + } + + form ::-moz-focus-inner { + border: 0; + } + +/* Tables */ + + table { + width: 100%; + } + + table.default { + width: 100%; + } + + table.default tr { + border-top: solid 1px #eee; + } + + table.default tr:first-child { + border-top: 0; + } + + table.default td { + padding: 0.5em 1em 0.5em 1em; + } + + table.default th { + text-align: left; + padding: 0.5em 1em 0.5em 1em; + font-weight: 600; + margin: 0 0 1em 0; + } + + table.default thead { + background: #4f4f4f; + color: #fff; + } + +/* Section/Article */ + + section, article { + margin-bottom: 3em; + } + + section > :last-child, + article > :last-child, + section:last-child, + article:last-child { + margin-bottom: 0; + } + +/* Image */ + + .image { + display: inline-block; + position: relative; + } + + .image img { + display: block; + width: 100%; + } + + .image.fit { + display: block; + width: 100%; + } + + .image.featured { + display: block; + width: 100%; + margin: 0 0 2em 0; + } + + .image.left { + float: left; + margin: 0 2em 2em 0; + } + + .image.centered { + display: block; + margin: 0 0 2em 0; + } + + .image.centered img { + margin: 0 auto; + width: auto; + } + +/* Button */ + + input[type="button"], + input[type="submit"], + input[type="reset"], + button, + .button { + background-image: url("images/bg.png"), -moz-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + background-image: url("images/bg.png"), -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + background-image: url("images/bg.png"), -ms-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + background-image: url("images/bg.png"), linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + -moz-transition: background-color .2s ease-in-out; + -webkit-transition: background-color .2s ease-in-out; + -ms-transition: background-color .2s ease-in-out; + transition: background-color .2s ease-in-out; + -webkit-appearance: none; + position: relative; + display: inline-block; + color: #fff !important; + text-decoration: none; + font-weight: 700; + border: 0; + outline: 0; + cursor: pointer; + border-radius: 8px; + text-shadow: -1px -1px 0.5px rgba(0, 0, 0, 0.5); + overflow: hidden; + box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 0, 0.5), inset 0px 2px 1px 0px rgba(255, 255, 255, 0.75); + background-color: #43B3E0; + padding: 1em 2.35em 1em 2.35em; + font-size: 1.1em; + max-width: 24em; + } + + input[type="button"]:hover, + input[type="submit"]:hover, + input[type="reset"]:hover, + button:hover, + .button:hover { + background-color: #43bff0; + color: #fff !important; + } + + input[type="button"]:active, + input[type="submit"]:active, + input[type="reset"]:active, + button:active, + .button:active { + background-color: #3BA8D3; + top: 1px; + } + + input[type="button"].large, + input[type="submit"].large, + input[type="reset"].large, + button.large, + .button.large { + font-size: 1.5em; + letter-spacing: -0.025em; + } + + input[type="button"].alt, + input[type="submit"].alt, + input[type="reset"].alt, + button.alt, + .button.alt { + background-color: #444; + box-shadow: inset 0px 0px 0px 1px #242424, inset 0px 2px 1px 0px rgba(255, 255, 255, 0.2); + } + + input[type="button"].alt:hover, + input[type="submit"].alt:hover, + input[type="reset"].alt:hover, + button.alt:hover, + .button.alt:hover { + background-color: #4f4f4f; + color: #fff !important; + } + + input[type="button"].alt:active, + input[type="submit"].alt:active, + input[type="reset"].alt:active, + button.alt:active, + .button.alt:active { + background-color: #3f3f3f; + } + +/* List */ + + ul { + list-style: disc; + padding-left: 1em; + } + + ul li { + padding-left: 0.5em; + } + + ol { + list-style: decimal; + padding-left: 1.25em; + } + + ol li { + padding-left: 0.25em; + } + +/* Social */ + + ul.social { + cursor: default; + margin: 0; + list-style: none; + padding-left: 0; + } + + ul.social li { + position: relative; + display: inline-block; + margin: 0.25em; + top: 0; + padding-left: 0; + } + + ul.social li a { + -moz-transition: top .2s ease-in-out; + -webkit-transition: top .2s ease-in-out; + -ms-transition: top .2s ease-in-out; + transition: top .2s ease-in-out; + display: block; + width: 48px; + height: 48px; + border-radius: 6px; + top: 0; + position: relative; + } + + ul.social li a:before { + background-image: url("images/bg.png"), -moz-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + background-image: url("images/bg.png"), -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + background-image: url("images/bg.png"), -ms-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + background-image: url("images/bg.png"), linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2)); + -moz-transition: background-color .2s ease-in-out; + -webkit-transition: background-color .2s ease-in-out; + -ms-transition: background-color .2s ease-in-out; + transition: background-color .2s ease-in-out; + background-color: #444; + border-radius: 6px; + box-shadow: inset 0px 0px 0px 1px #282828, inset 0px 2px 1px 0px rgba(255, 255, 255, 0.1); + color: #2E2E2E !important; + display: block; + font-size: 26px; + height: 48px; + line-height: 48px; + text-align: center; + outline: 0; + overflow: hidden; + text-shadow: 1px 1px 0px rgba(255, 255, 255, 0.1); + width: 48px; + } + + ul.social li a.fa-twitter { + background-color: #2DAAE4; + } + + ul.social li a.fa-facebook-f { + background-color: #3C5A98; + } + + ul.social li a.fa-dribbble { + background-color: #C4376B; + } + + ul.social li a.fa-linkedin-in { + background-color: #006599; + } + + ul.social li a.fa-tumblr { + background-color: #51718A; + } + + ul.social li a.fa-google-plus { + background-color: #DA2713; + } + + ul.social li a.fa-github { + background-color: #FAFAFA; + } + + ul.social li a.fa-rss { + background-color: #F2600B; + } + + ul.social li a.fa-instagram { + background-color: #E0D7C8; + } + + ul.social li a.fa-foursquare { + background-color: #39A3D4; + } + + ul.social li a.fa-skype { + background-color: #10BEF1; + } + + ul.social li a.fa-soundcloud { + background-color: #FE5419; + } + + ul.social li a.fa-youtube { + background-color: #BF2E25; + } + + ul.social li a.fa-blogger { + background-color: #FF6501; + } + + ul.social li a.fa-flickr { + background-color: #0062DB; + } + + ul.social li a.fa-vimeo { + background-color: #4C8AB0; + } + + ul.social li a:hover { + top: -5px; + } + + ul.social li a:hover:before { + background-color: transparent; + } + +/* Actions */ + + ul.actions { + list-style: none; + padding-left: 0; + } + + ul.actions li { + display: inline-block; + margin: 0 0 0 1em; + padding-left: 0; + } + + ul.actions li:first-child { + margin-left: 0; + } + +/* Box */ + + .box { + background: #fff; + box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 0, 0.15), 0px 2px 3px 0px rgba(0, 0, 0, 0.1); + text-align: center; + padding: 2em; + } + + .box.style1 { + padding: 3em 2em 3.5em 2em; + } + + .box.style1 h3 { + margin-bottom: 0.5em; + } + + .box.style2 h3 { + margin-bottom: 0.25em; + } + + .box.style2 .image { + position: relative; + left: 2em; + top: 2em; + margin: -4em 0 4em -4em; + width: auto; + } + +/* Icons */ + + .icon { + text-decoration: none; + text-decoration: none; + } + + .icon:before { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; + text-transform: none !important; + font-family: 'Font Awesome 5 Free'; + font-weight: 400; + } + + .icon:before { + font-size: 1.25em; + } + + .icon > .label { + display: none; + } + + .icon.solid:before { + font-weight: 900; + } + + .icon.brands:before { + font-family: 'Font Awesome 5 Brands'; + } + + .icon.featured { + color: #EA8A95; + display: block; + margin: 0 0 1.5em 0; + cursor: default; + } + + .icon.featured:before { + font-size: 6em; + } + +/* Wrappers */ + + .wrapper { + background-image: url("images/bg.png"); + box-shadow: inset 0px 1px 0px 0px rgba(0, 0, 0, 0.05), inset 0px 2px 3px 0px rgba(0, 0, 0, 0.1); + padding: 8em 0 8em 0; + text-align: center; + } + + .wrapper.style1 { + background-image: none; + background-color: #fff; + } + + .wrapper.style2 { + background-color: #fafafa; + text-shadow: 1px 1px 0px #fff; + } + + .wrapper.style3 { + background-color: #f4f4f4; + text-shadow: 1px 1px 0px #fff; + } + + .wrapper.style4 { + background-color: #303030; + color: #999; + text-shadow: -1px -1px 0px #181818; + } + + .wrapper.style4 h1, .wrapper.style4 h2, .wrapper.style4 h3, .wrapper.style4 h4, .wrapper.style4 h5, .wrapper.style4 h6 { + color: #fff; + } + + .wrapper.style4 form input[type=text], + .wrapper.style4 form input[type=password], + .wrapper.style4 form select, + .wrapper.style4 form textarea { + border: none; + background: #282828; + } + + .wrapper.style4 form input[type=text]:focus, + .wrapper.style4 form input[type=password]:focus, + .wrapper.style4 form select:focus, + .wrapper.style4 form textarea:focus { + background: #252525; + } + +/* Nav */ + + #nav { + background-color: #282828; + text-align: center; + position: fixed; + left: 0; + top: 0; + width: 100%; + z-index: 10000; + cursor: default; + height: 3.5em; + line-height: 3.5em; + } + + #nav ul { + margin-bottom: 0; + list-style: none; + padding-left: 0; + } + + #nav li { + display: inline-block; + padding-left: 0; + } + + #nav a { + -moz-transition: background-color .2s ease-in-out; + -webkit-transition: background-color .2s ease-in-out; + -ms-transition: background-color .2s ease-in-out; + transition: background-color .2s ease-in-out; + position: relative; + display: block; + color: #fff; + text-decoration: none; + outline: 0; + font-weight: 600; + border-radius: 8px; + color: #fff; + height: 2.5em; + line-height: 2.5em; + padding: 0 1.25em; + } + + #nav a:hover { + color: #fff !important; + background: #383838; + } + + #nav a.active { + background: #484848; + } + + #nav a.active:before { + content: ''; + display: block; + position: absolute; + bottom: -0.6em; + left: 50%; + margin-left: -0.75em; + border-left: solid 0.75em transparent; + border-right: solid 0.75em transparent; + border-top: solid 0.6em #282828; + } + +/* Articles */ + + body > article { + margin-bottom: 0; + } + + #top { + padding: 10em 0 10em 0; + text-align: left; + } + + #top .image { + border-radius: 100%; + width: 20em; + height: 20em; + margin: 0; + } + + #top .image img { + border-radius: 100%; + } + + #top h1 { + margin-top: 0.35em; + } + + #top p { + font-size: 1.5em; + line-height: 1.75em; + } + + #top p a { + color: inherit; + } + + #contact footer { + font-size: 0.9em; + } + +/* Copyright */ + + #copyright { + color: #666; + font-size: 1em; + line-height: 1em; + list-style: none; + padding-left: 0; + margin-bottom: 0; + } + + #copyright li { + display: inline-block; + border-left: solid 1px rgba(0, 0, 0, 0.5); + box-shadow: -1px 0px 0px 0px rgba(255, 255, 255, 0.1); + padding: 0 0 0 1em; + margin: 0 0 0 1em; + } + + #copyright li:first-child { + border: 0; + box-shadow: none; + padding-left: 0; + margin-left: 0; + } + + #copyright a { + -moz-transition: color .2s ease-in-out; + -webkit-transition: color .2s ease-in-out; + -ms-transition: color .2s ease-in-out; + transition: color .2s ease-in-out; + color: inherit; + } + + #copyright a:hover { + color: #777; + } + +/* Large */ + + @media screen and (max-width: 1280px) { + + /* Basic */ + + body { + font-size: 11pt; + } + + input, textarea, select { + font-size: 11pt; + } + + header { + margin: 0 0 4em 0; + } + + /* Wrappers */ + + .wrapper { + padding: 5em 0 5em 0; + text-align: center; + } + + .wrapper.style4 .row-special { + margin: 2em 0 0 0; + padding: 2em 0 2em 0; + } + + /* Articles */ + + #top { + padding: 8em 0; + } + + #top .image { + width: 24em; + height: 24em; + margin: 0; + } + + } + +/* Medium */ + + @media screen and (max-width: 980px) { + + /* Articles */ + + #top { + text-align: center; + padding: 5em 0; + } + + #top .image { + margin: 0 auto 2em auto; + } + + } + +/* Small */ + + @media screen and (max-width: 736px) { + + /* Basic */ + + body { + padding-top: 44px; + } + + body, input, textarea, select { + line-height: 1.75em; + font-size: 10pt; + letter-spacing: 0; + } + + h1, h2, h3, h4, h5, h6 { + font-size: 1.25em; + margin: 0 0 0.4em 0; + } + + h1 { + font-size: 2.25em; + line-height: 1.25em; + } + + header { + margin: 0 0 2em 0; + } + + header > p { + font-size: 1.25em; + } + + footer { + margin: 2.5em 0 0 0; + } + + footer > p { + font-size: 1.25em; + } + + hr { + margin: 1.5em 0 2em 0; + } + + /* Section/Article */ + + section, article { + clear: both; + } + + /* Button */ + + input[type="button"], + input[type="submit"], + input[type="reset"], + button, + .button { + text-align: center; + font-size: 1.2em; + width: 100%; + padding: 1em 0 1em 0; + } + + input[type="button"].large, + input[type="submit"].large, + input[type="reset"].large, + button.large, + .button.large { + font-size: 1.2em; + letter-spacing: 0; + } + + /* Social */ + + ul.social { + padding: 1em 0.5em 0 0.5em; + } + + ul.social li { + margin: 0.5em 0.5em 0.5em 0.5em; + } + + ul.social li a { + top: 0 !important; + } + + ul.social li a:before { + background-color: transparent !important; + } + + /* Actions */ + + ul.actions { + margin: 0; + } + + ul.actions li { + display: block; + margin: 15px 0 0 0; + } + + ul.actions li:first-child { + margin-top: 0; + } + + /* Box */ + + .box { + padding: 30px 20px 30px 20px; + margin: 0 0 20px 0 !important; + } + + .box h3 { + margin-bottom: 0.25em; + } + + .box .image.centered { + margin-bottom: 1em; + } + + .box .image.featured { + position: relative; + left: 20px; + top: 20px; + margin: -50px 0 50px -40px; + width: auto; + } + + .box.style1 { + max-width: 32em; + margin-left: auto !important; + margin-right: auto !important; + } + + .box.style2 { + max-width: 32em; + margin-left: auto !important; + margin-right: auto !important; + } + + /* Wrappers */ + + .wrapper { + padding: 3em 0; + text-align: center; + } + + /* Nav */ + + #nav { + height: 44px; + line-height: 44px; + } + + #nav a { + padding: 0 0.75em; + height: inherit; + line-height: inherit; + border-radius: 0; + } + + #nav a:hover { + background-color: transparent; + } + + /* Articles */ + + #top { + padding: 3em 0; + } + + #top .image { + width: 15em; + height: 15em; + margin-bottom: 0; + } + + #top p { + font-size: 1em; + } + + #contact footer { + margin: 0; + } + + /* Copyright */ + + #copyright { + font-size: 1em; + margin: 0; + } + + #copyright li { + display: block; + margin: 1em 0 0 0; + padding: 0; + box-shadow: none; + border-left: 0; + } + + #copyright li:first-child { + margin-top: 0; + } + + } + diff --git a/assets/css/custom.css b/assets/css/custom.css @@ -0,0 +1,42 @@ +html, body { + height: 100%; + min-height: 100vh; + font-size: 105% !important; + scroll-behavior: smooth; +} +.button { + background-color: #5a03b9 !important; +} +.button:hover { + background-color: #8144c4 !important; +} +/* DarkMode */ +@media (prefers-color-scheme: dark) { + html { + background: #111; + color: #eee; + } + nav { + background: #000 !important; + color: #fff; + } + h1, h2, h3, h4, h5, h6, p, strong { + color: #ddd !important; + } +} +/* Blinking dot */ +.pulse { + animation: 2s blink infinite; +} +@keyframes blink { + 0% { + opacity: 0; + } + 50% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + diff --git a/assets/css/loading.css b/assets/css/loading.css @@ -0,0 +1,283 @@ +/* Loading Animation */ +.wrapper-loading { + position: relative; + margin: auto; + width: 100%; + aspect-ratio: 1/1; + max-width: 400px; + min-width: 100px; + background-color: transparent; + border: none; +} +.wrapper-loading .box-wrap { + width: 70%; + height: 70%; + margin: calc((100% - 70%) / 2) calc((100% - 70%) / 2); + position: relative; + transform: rotate(-45deg); +} +.wrapper-loading .box-wrap .box { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background: rgba(135, 0, 0, 0.6); + background: linear-gradient( + to right, + #141562, + #486fbc, + #eab5a1, + #8dd6ff, + #4973c9, + #d07ca7, + #f4915e, + #f5919e, + #b46f89, + #141562, + #486fbc + ); + background-position: 0% 50%; + background-size: 1000% 1000%; + visibility: hidden; +} +.wrapper-loading .box-wrap .box.one { + animation: moveGradient 15s infinite, oneMove 3.5s infinite; +} +.wrapper-loading .box-wrap .box.two { + animation: moveGradient 15s infinite, twoMove 3.5s 0.15s infinite; +} +.wrapper-loading .box-wrap .box.three { + animation: moveGradient 15s infinite, threeMove 3.5s 0.3s infinite; +} +.wrapper-loading .box-wrap .box.four { + animation: moveGradient 15s infinite, fourMove 3.5s 0.575s infinite; +} +.wrapper-loading .box-wrap .box.five { + animation: moveGradient 15s infinite, fiveMove 3.5s 0.725s infinite; +} +.wrapper-loading .box-wrap .box.six { + animation: moveGradient 15s infinite, sixMove 3.5s 0.875s infinite; +} + +@keyframes moveGradient { + to { + background-position: 100% 50%; + } +} + +@keyframes oneMove { + 0% { + visibility: visible; + clip-path: inset(0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 14.2857% { + clip-path: inset(0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 28.5714% { + clip-path: inset(35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 42.8571% { + clip-path: inset(35% 70% 35% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 57.1428% { + clip-path: inset(35% 70% 35% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 71.4285% { + clip-path: inset(0% 70% 70% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 85.7142% { + clip-path: inset(0% 70% 70% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 100% { + clip-path: inset(0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } +} + +@keyframes twoMove { + 0% { + visibility: visible; + clip-path: inset(0% 70% 70% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 14.2857% { + clip-path: inset(0% 70% 70% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 28.5714% { + clip-path: inset(0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 42.8571% { + clip-path: inset(0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 57.1428% { + clip-path: inset(35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 71.4285% { + clip-path: inset(35% 70% 35% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 85.7142% { + clip-path: inset(35% 70% 35% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 100% { + clip-path: inset(0% 70% 70% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } +} + +@keyframes threeMove { + 0% { + visibility: visible; + clip-path: inset(35% 70% 35% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 14.2857% { + clip-path: inset(35% 70% 35% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 28.5714% { + clip-path: inset(0% 70% 70% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 42.8571% { + clip-path: inset(0% 70% 70% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 57.1428% { + clip-path: inset(0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 71.4285% { + clip-path: inset(0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 85.7142% { + clip-path: inset(35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 100% { + clip-path: inset(35% 70% 35% 0 round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } +} + +@keyframes fourMove { + 0% { + visibility: visible; + clip-path: inset(35% 0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 14.2857% { + clip-path: inset(35% 0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 28.5714% { + clip-path: inset(35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 42.8571% { + clip-path: inset(70% 35% 0% 35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 57.1428% { + clip-path: inset(70% 35% 0% 35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 71.4285% { + clip-path: inset(70% 0 0 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 85.7142% { + clip-path: inset(70% 0 0 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 100% { + clip-path: inset(35% 0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } +} + +@keyframes fiveMove { + 0% { + visibility: visible; + clip-path: inset(70% 0 0 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 14.2857% { + clip-path: inset(70% 0 0 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 28.5714% { + clip-path: inset(35% 0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 42.8571% { + clip-path: inset(35% 0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 57.1428% { + clip-path: inset(35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 71.4285% { + clip-path: inset(70% 35% 0% 35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 85.7142% { + clip-path: inset(70% 35% 0% 35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 100% { + clip-path: inset(70% 0 0 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } +} + +@keyframes sixMove { + 0% { + visibility: visible; + clip-path: inset(70% 35% 0% 35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 14.2857% { + clip-path: inset(70% 35% 0% 35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 28.5714% { + clip-path: inset(70% 0 0 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 42.8571% { + clip-path: inset(70% 0 0 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 57.1428% { + clip-path: inset(35% 0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 71.4285% { + clip-path: inset(35% 0% 35% 70% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 85.7142% { + clip-path: inset(35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } + 100% { + clip-path: inset(70% 35% 0% 35% round 5%); + animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1); + } +} diff --git a/assets/img/chat_mono.svg b/assets/img/chat_mono.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>forum-outline</title><path fill="#fff" d="M15,4V11H5.17L4,12.17V4H15M16,2H3A1,1 0 0,0 2,3V17L6,13H16A1,1 0 0,0 17,12V3A1,1 0 0,0 16,2M21,6H19V15H6V17A1,1 0 0,0 7,18H18L22,22V7A1,1 0 0,0 21,6Z" /></svg> diff --git a/assets/img/play_mono.svg b/assets/img/play_mono.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>motion-play-outline</title><path fill="#fff" d="M10 16.5L16 12L10 7.5M22 12C22 6.46 17.54 2 12 2C10.83 2 9.7 2.19 8.62 2.56L9.32 4.5C10.17 4.16 11.06 3.97 12 3.97C16.41 3.97 20.03 7.59 20.03 12C20.03 16.41 16.41 20.03 12 20.03C7.59 20.03 3.97 16.41 3.97 12C3.97 11.06 4.16 10.12 4.5 9.28L2.56 8.62C2.19 9.7 2 10.83 2 12C2 17.54 6.46 22 12 22C17.54 22 22 17.54 22 12M5.47 3.97C6.32 3.97 7 4.68 7 5.47C7 6.32 6.32 7 5.47 7C4.68 7 3.97 6.32 3.97 5.47C3.97 4.68 4.68 3.97 5.47 3.97Z" /></svg> diff --git a/assets/img/streamlink_mono.svg b/assets/img/streamlink_mono.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>link-circle-outline</title><path fill="#fff" d="M10 16H11V14H10C9.67 14 8 13.9 8 12C8 10.17 9.54 10 10 10H11V8H10C8.39 8 6 9.07 6 12C6 14.94 8.39 16 10 16M13 16H14C15.61 16 18 14.94 18 12C18 9.07 15.61 8 14 8H13V10H14C14.33 10 16 10.1 16 12C16 13.83 14.46 14 14 14H13V16M9 13H15V11H9V13M8.17 2.76C9.39 2.26 10.69 2 12 2C13.31 2 14.61 2.26 15.83 2.76C17.04 3.26 18.14 4 19.07 4.93C20 5.86 20.74 6.96 21.24 8.17C21.74 9.39 22 10.69 22 12C22 14.65 20.95 17.2 19.07 19.07C17.2 20.95 14.65 22 12 22C10.69 22 9.39 21.74 8.17 21.24C6.96 20.74 5.86 20 4.93 19.07C3.05 17.2 2 14.65 2 12C2 9.35 3.05 6.8 4.93 4.93C5.86 4 6.96 3.26 8.17 2.76M6.34 17.66C7.84 19.16 9.88 20 12 20C14.12 20 16.16 19.16 17.66 17.66C19.16 16.16 20 14.12 20 12C20 9.88 19.16 7.84 17.66 6.34C16.16 4.84 14.12 4 12 4C9.88 4 7.84 4.84 6.34 6.34C4.84 7.84 4 9.88 4 12C4 14.12 4.84 16.16 6.34 17.66Z" /></svg> diff --git a/assets/img/twitch.png b/assets/img/twitch.png Binary files differ. diff --git a/assets/img/twitch_144.png b/assets/img/twitch_144.png Binary files differ. diff --git a/assets/img/twitch_16.png b/assets/img/twitch_16.png Binary files differ. diff --git a/assets/img/twitch_168.png b/assets/img/twitch_168.png Binary files differ. diff --git a/assets/img/twitch_192.png b/assets/img/twitch_192.png Binary files differ. diff --git a/assets/img/twitch_256.png b/assets/img/twitch_256.png Binary files differ. diff --git a/assets/img/twitch_32.png b/assets/img/twitch_32.png Binary files differ. diff --git a/assets/img/twitch_48.png b/assets/img/twitch_48.png Binary files differ. diff --git a/assets/img/twitch_72.png b/assets/img/twitch_72.png Binary files differ. diff --git a/assets/img/twitch_96.png b/assets/img/twitch_96.png Binary files differ. diff --git a/assets/img/twitch_mono.svg b/assets/img/twitch_mono.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>twitch</title><path fill="#fff" d="M11.64 5.93H13.07V10.21H11.64M15.57 5.93H17V10.21H15.57M7 2L3.43 5.57V18.43H7.71V22L11.29 18.43H14.14L20.57 12V2M19.14 11.29L16.29 14.14H13.43L10.93 16.64V14.14H7.71V3.43H19.14Z" /></svg> diff --git a/assets/js/twitch.js b/assets/js/twitch.js @@ -0,0 +1,45 @@ +function toggle_player(stream, img64) { + var img = document.querySelector("#img-" + stream); + var ply = document.querySelector("#play-" + stream); + if (img != null) { + var player = document.createElement("iframe"); + player.allowFullscreen = "true"; + player.width = "100%"; + player.height = "100%"; + player.frameborder = "0"; + player.scrolling = "no"; + player.style = "display:block;vertical-align:top;width:100%;max-width:853px;max-height:480px;aspect-ratio:16/9;margin-left:auto;margin-right:auto;margin-top:5px;margin-bottom:5px;'"; + player.src = "https://player.twitch.tv/?channel=" + stream + "&parent=" + window.location.hostname; + player.id = "play-" + stream; + img.replaceWith(player); + } + if (ply != null) { + var image = document.createElement("img"); + image.style = "display:block;vertical-align:top;width:100%;max-width:853px;max-height:480px;aspect-ratio:16/9;margin-left:auto;margin-right:auto;margin-top:5px;margin-bottom:5px;'"; + //image.src = "https://static-cdn.jtvnw.net/previews-ttv/live_user_" + stream + "-853x480.jpg"; + image.src = img64; + image.id = "img-" + stream; + ply.replaceWith(image); + } +} +function toggle_chat(stream) { + var plho = document.querySelector("#chat-placeholder-" + stream); + var chat = document.querySelector("#chat-" + stream); + if (chat != null) { + var placeholder = document.createElement("div"); + placeholder.id = "chat-placeholder-" + stream; + chat.replaceWith(placeholder); + } + if (plho != null) { + var chatembed = document.createElement("iframe"); + chatembed.width = "100%"; + chatembed.height = "100vh"; + chatembed.frameborder = "0"; + chatembed.scrolling = "auto"; + chatembed.style = "display:block;vertical-align:top;max-width:853px;max-height:853px;min-height:480px;margin-left:auto;margin-right:auto;margin-top:5px;margin-bottom:5px;'"; + chatembed.src = "https://www.twitch.tv/embed/" + stream + "/chat?parent=" + window.location.hostname; + chatembed.id = "chat-" + stream; + plho.replaceWith(chatembed); + } +} + diff --git a/index.php b/index.php @@ -0,0 +1,213 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Twitch Streams</title> + <link rel="icon" type="image/png" href="/assets/img/twitch.png"> + <link crossorigin="use-credentials" rel="manifest" href="/manifest.json"> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> + <!--<link rel="stylesheet" href="assets/css/main.css" />--> +</head> + +<?php + +// Start timer +$time0 = time(); + +// Fetch GET and POST arguments +// "streams" via GET -> Show Loading Screen +// "Streams" via POST -> Load Streams +if (!is_null($_GET["streams"])) { + $loading_screen = true; + $channels = explode(",", $_GET["streams"]); + +} else { + $loading_screen = false; + $channels = unserialize($_POST["streams"]); +} + +// Prepare streams array +$streams = array( + "stream" => $channels, + "desc" => array(), + "game" => array(), + "status" => array(), + "img" => array(), + "time" => array() +); + +// Check whether to load streams or show the loading screen +if (!$loading_screen) { + + // Check Online Status of streams + for ($i = 0; $i < sizeof($streams["stream"]); $i++) { + + // Fetch Stream Preview Image + $img = file_get_contents( + "https://static-cdn.jtvnw.net/previews-ttv/live_user_" . + $streams["stream"][$i] . + "-853x480.jpg" + ); + $img_base64 = "data:image/jpg;base64," . base64_encode($img); + + // Check Online-Status via HTTP status code + $http_code = preg_replace( + '/^.*(\d{3}).*/', + '\1', + $http_response_header[0] + ); + + if (!($http_code == "200")) { + + // Stream is not online! + array_push($streams["status"], 0); + $desc = ""; + $game = ""; + $img_base64 = ""; + + } else { + + // Stream is online! + array_push($streams["status"], 1); + + // Fetch HTML + $html = file_get_contents("https://m.twitch.tv/" . $streams["stream"][$i]); + $html = str_replace(array("\r", "\n"), "", $html); + + // Parse Game Name + $pattern = '/^.*<p.*?Playing <a.*?>(.*?)<\/a>.*$/'; + $replacement = '\1'; + $game = substr(strip_tags(preg_replace($pattern, $replacement, $html)), 0, 100); + + // Parse Stream Description + $html = preg_replace('/<script.*<\/script>/', '', $html); + $html = explode(">", $html); + $desc_raw = implode("", preg_grep('/name="description"/', $html)); + $pattern = '/^.*content="(.*?)".*$/'; + $replacement = '\1'; + $desc = substr(strip_tags(preg_replace($pattern, $replacement, $desc_raw)), 0, 500); + + } + + // Fill Streams array + array_push($streams["desc"], $desc); + array_push($streams["game"], $game); + array_push($streams["img"], $img_base64); + array_push($streams["time"], (time() - $time0)); + + } + + // Generate Main Menu + if (array_sum($streams["status"]) > 0) { + $beep_color = "#0f0"; + $beep_class = "pulse"; + } else { + $beep_color = "#f00"; + $beep_class = "nopulse"; + } + $menu_items = "<li><strong style='color:#fff;'>" . + "<span style='color:" . $beep_color . + "' class='" . $beep_class . "'>•</span>" . + "Live: " . array_sum($streams["status"]) . + "</strong></li>"; + + // Generate Content List + $content = ""; + $content_menu = "<h1>Streams</h1>"; + for ($i = 0; $i < sizeof($streams["stream"]); $i++) { + if ($streams["status"][$i] > 0) { + // $content_menu = $content_menu . "<li style='display:inline-block;'><a style='display:inline-block;margin:3px;text-align:center;' class='button' href='#" . $streams["stream"][$i] . "'>" . $streams["stream"][$i] . "</a></li>"; + $content = $content . "<div id='" . $streams["stream"][$i] . "'></div>"; + $content = $content . "<h2>" . $streams["stream"][$i] . "</h2>"; + $content = $content . "<p><span style='color:#3fa8d2;margin-right:1em;'>" . $streams["game"][$i] . "</span>" . $streams["desc"][$i] . "</p>"; + $content = $content . "<div>"; + $content = $content . "<img id='img-" . $streams["stream"][$i] . "' style='display:block;vertical-align:top;width:100%;max-width:853px;max-height:480px;aspect-ratio:16/9;margin-left:auto;margin-right:auto;margin-top:5px;margin-bottom:5px;' src='" . $streams["img"][$i] . "'>"; + + $content = $content . "<div style='display:block;width:100%;margin:10px;margin-left:auto;margin-right:auto;max-width:853px;'>"; + $content = $content . "<div id='chat-placeholder-" . $streams["stream"][$i] . "'></div>"; + /* Stream-Embedding and Chat-Embedding */ + //$content = $content . "<a style='display:inline-block;margin:3px;margin-left:auto;margin-right:auto;width:100%;max-width:853px;text-align:center;' class='button' href='javascript:toggle_player(\"" . $streams["stream"][$i] . "\", \"" . $streams["img"][$i] . "\");toggle_chat(\"" . $streams["stream"][$i] . "\");' title='Player'><img style='width:100%;max-height:calc(80px - 53.15px);color:#fff;' src='/assets/img/play_mono.svg'></a>"; + /* Chat-Embedding */ + //$content = $content . "<a style='display:inline-block;margin:3px;margin-left:auto;margin-right:auto;width:100%;max-width:853px;text-align:center;' class='button' href='javascript:toggle_chat(\"" . $streams["stream"][$i] . "\")' title='Chat'><img style='width:100%;max-height:calc(80px - 53.15px);color:#fff;' src='/assets/img/chat_mono.svg'></a>"; + /* Multi-Row */ + $content = $content . "<div style='display:flex;width:100%;margin:10px;margin-left:auto;margin-right:auto;max-width:830px;'>"; + /* Stream-Embedding */ + $content = $content . "<a style='display:inline-block;margin:3px;width:100%;text-align:center;' class='button' href='javascript:toggle_player(\"" . $streams["stream"][$i] . "\", \"" . $streams["img"][$i] . "\")' title='Player'><img style='width:100%;max-height:calc(80px - 53.15px);color:#fff;' src='/assets/img/play_mono.svg'></a>"; + /* Stream (New Tab) */ + //$content = $content . "<a style='display:inline-block;margin:3px;width:100%;text-align:center;' class='button' target='_blank' href='https://m.twitch.tv/" . $streams["stream"][$i] . "' title='Twitch'><img style='width:100%;max-height:calc(80px - 53.15px);color:#fff;' src='/assets/img/twitch_mono.svg'></a>"; + /* Streamlink */ + $content = $content . "<a style='display:inline-block;margin:3px;width:100%;text-align:center;' class='button' href='streamlink://twitch.tv/" . $streams["stream"][$i] . "?title=" . rawurlencode($streams["desc"][$i]) . "' title='Streamlink'><img style='width:100%;max-height:calc(80px - 53.15px);color:#fff;' src='/assets/img/streamlink_mono.svg'></a>"; + /* Chat (New Tab) */ + $content = $content . "<a style='display:inline-block;margin:3px;width:100%;text-align:center;' class='button' target='_blank' href='https://m.twitch.tv/popout/" . $streams["stream"][$i] . "/chat' title='Chat'><img style='width:100%;max-height:calc(80px - 53.15px);color:#fff;' src='/assets/img/chat_mono.svg'></a>"; + /* Chat-Embedding */ + //$content = $content . "<a style='display:inline-block;margin:3px;width:100%;text-align:center;' class='button' href='javascript:toggle_chat(\"" . $streams["stream"][$i] . "\")' title='Chat'><img style='width:100%;max-height:calc(80px - 53.15px);color:#fff;' src='/assets/img/chat_mono.svg'></a>"; + $content = $content . "</div>"; + $content = $content . "</div><br>"; + $content = $content . "<hr>"; + } + } + $content = "<ul class='container'>" . $content_menu . "</ul><br>" . $content; +} else { + // Generate Loading Screen items + $menu_items = "<li><strong style='color:#fff;'>Loading Twitch Streams <span style='color:#ff0;' class='pulse'>&#8226;</span></strong></li>"; + $content = "<h1 style='text-align:center;'>Please be patient</h1><p style='text-align:center;'>Loading " . sizeof($streams["stream"]) . " streams. This may take a moment.</p><br>"; + $content = $content . "<div class='wrapper-loading'><div class='box-wrap'><div class='box one'></div><div class='box two'></div><div class='box three'></div><div class='box four'></div><div class='box five'></div><div class='box six'></div></div></div>"; + $content = $content . "<form id='channels' action='/' method='post'><input type='hidden' id='streams' name='streams', value='" . serialize($streams["stream"]) . "'>"; + $content = $content . "<script>setTimeout(function(){document.querySelector('#channels').submit()}, 1000);</script>"; +} +?> + + +<!--<body class="is-preload">--> +<body> + + <nav id="nav" style="font-size:1.5em!important;position:absolute!important;"> + <ul class="container"> +<?php + echo "<li><a href=\"javascript:window.location = '/?streams=" . implode(",", $streams["stream"]) . "';\" title=\"Reload\" style=\"color:#fff;padding-left:0.5em;padding-right:0.5em;\">&#x21bb;</a></li>"; + echo $menu_items; +?> + </ul> + </nav> + + + <!-- List --> + <article id="top" class="wrapper"> + <div class="container"> +<?php + echo $content; +?> + </div> + <div class="container"> + <details> + <summary>Developer Information</summary> +<?php + echo "<p>&#9201; " . ((time() -$time0) / sizeof($streams["stream"])) . "s</p>"; +?> + <table> + <thead> + <tr><th></th><th>Username</th><th>Online</th><th>Time</th><th>Desription</th></tr> + </thead> + <tbody> +<?php + for ($i = 0; $i < sizeof($streams["stream"]); $i++) { + echo "<tr>"; + echo "<td>" . ($i + 1) . "</td>"; + echo "<td><a href='https://twitch.tv/" . $streams["stream"][$i] . "'>" . $streams["stream"][$i] . "</a></td>"; + echo "<td>" . array("&#10008;", "&#10003;")[$streams["status"][$i]] . "</td>"; + echo "<td>" . $streams["time"][$i] . "</td>"; + echo "<td>" . $streams["desc"][$i] . "</td>"; + echo "</tr>"; + } +?> + </tbody> + </table> + </details> + </div> + </article> +</body> + +</html> +<?php + exit; +?> diff --git a/manifest.json b/manifest.json @@ -0,0 +1,56 @@ +{ + "name":"Twitch Streams", + "short_name":"Twitch", + "start_url":"/", + "display":"standalone", + "scope":"/", + "background_color":"#000000", + "description":"Currently online live streams.", + "icons":[ + { + "src":"/assets/img/twitch_16.png", + "sizes":"16x16", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_48.png", + "sizes":"32x32", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_48.png", + "sizes":"48x48", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_72.png", + "sizes":"72x72", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_96.png", + "sizes":"96x96", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_144.png", + "sizes":"144x144", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_168.png", + "sizes":"168x168", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_192.png", + "sizes":"192x192", + "type":"image/png" + }, + { + "src":"/assets/img/twitch_256.png", + "sizes":"256x256", + "type":"image/png" + } + ] +}