mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
refactor progress
This commit is contained in:
parent
d497806443
commit
8ba1b68a21
@ -17,7 +17,7 @@ I like cats (Neko is the Japanese word for cat), I'm a weeb/nerd, I own the doma
|
||||
### Super easy mode setup
|
||||
1. Deploy a Server/VPS
|
||||
|
||||
*Recomended Specs:*
|
||||
*Recomended Specs:* (Note: these may not be correct, I did a small round testing, 4c/4gb worked fine with small hickups here and there)
|
||||
|
||||
| Resolution | Cores | Ram | Recommendation |
|
||||
|------------|-------|-------|------------------|
|
||||
|
@ -8,6 +8,7 @@
|
||||
"parser": "@typescript-eslint/parser"
|
||||
},
|
||||
"rules": {
|
||||
"vue/valid-v-for": "off",
|
||||
"no-case-declarations": "off",
|
||||
"no-dupe-class-members": "off",
|
||||
"no-console": "off",
|
||||
|
@ -19,21 +19,35 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.12.0",
|
||||
"animejs": "^3.1.0",
|
||||
"axios": "^0.19.1",
|
||||
"bulma": "^0.8.0",
|
||||
"date-fns": "^2.9.0",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"simple-markdown": "^0.7.2",
|
||||
"sweetalert2": "^9.6.1",
|
||||
"typed-vuex": "^0.1.15",
|
||||
"v-tooltip": "^2.0.3",
|
||||
"vue": "^2.6.10",
|
||||
"vue-class-component": "^7.0.2",
|
||||
"vue-context": "^5.0.0",
|
||||
"vue-notification": "^1.3.20",
|
||||
"vue-property-decorator": "^8.3.0",
|
||||
"typed-vuex": "^0.1.15",
|
||||
"vue-router": "^3.1.5",
|
||||
"vuex": "^3.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/animejs": "^3.1.0",
|
||||
"@types/vue": "^2.0.0",
|
||||
"@types/w3c-image-capture": "^1.0.2",
|
||||
"@vue/cli-plugin-eslint": "^4.1.0",
|
||||
"@vue/cli-plugin-typescript": "^4.1.0",
|
||||
"@vue/cli-plugin-vuex": "^4.1.0",
|
||||
"@vue/cli-service": "^4.1.0",
|
||||
"@vue/eslint-config-prettier": "^5.0.0",
|
||||
"@vue/eslint-config-typescript": "^4.0.0",
|
||||
"autoprefixer": "^9.7.4",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-prettier": "^3.1.1",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
|
@ -1,571 +0,0 @@
|
||||
<template>
|
||||
<div class="video-player">
|
||||
<div ref="video" class="video">
|
||||
<div ref="container" class="video-container">
|
||||
<video
|
||||
ref="player"
|
||||
tabindex="0"
|
||||
@click.stop.prevent
|
||||
@contextmenu.stop.prevent
|
||||
@wheel.stop.prevent="onWheel"
|
||||
@mousemove.stop.prevent="onMouseMove"
|
||||
@mousedown.stop.prevent="onMouseDown"
|
||||
@mouseup.stop.prevent="onMouseUp"
|
||||
@mouseenter.stop.prevent="onMouseEnter"
|
||||
@mouseleave.stop.prevent="onMouseLeave"
|
||||
@keydown.stop.prevent="onKeyDown"
|
||||
@keyup.stop.prevent="onKeyUp"
|
||||
/>
|
||||
<div v-if="!playing" class="video-overlay">
|
||||
<i @click.stop.prevent="toggleMedia" class="fas fa-play-circle" />
|
||||
</div>
|
||||
<div ref="aspect" class="aspect" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<div class="neko">
|
||||
<img src="@/assets/logo.svg" alt="n.eko" />
|
||||
<span><b>n</b>.eko</span>
|
||||
</div>
|
||||
<ul>
|
||||
<li>
|
||||
<i
|
||||
alt="Request Control"
|
||||
:class="[{ enabled: hosting }, 'request', 'fas', 'fa-keyboard']"
|
||||
@click.stop.prevent="toggleControl"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<i
|
||||
alt="Play/Pause"
|
||||
:class="[playing ? 'fa-pause-circle' : 'fa-play-circle', 'play', 'fas']"
|
||||
@click.stop.prevent="toggleMedia"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<div class="volume">
|
||||
<input
|
||||
@input="setVolume"
|
||||
:class="[volume === 0 ? 'fa-volume-mute' : 'fa-volume-up', 'fas']"
|
||||
ref="volume"
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<i @click.stop.prevent="fullscreen" alt="Full Screen" class="fullscreen fas fa-expand-alt" />
|
||||
</li>
|
||||
</ul>
|
||||
<div class="right"></div>
|
||||
</div>
|
||||
<div class="connect" v-if="!connected">
|
||||
<div class="window">
|
||||
<div class="logo">
|
||||
<img src="@/assets/logo.svg" alt="n.eko" />
|
||||
<span><b>n</b>.eko</span>
|
||||
</div>
|
||||
<form class="message" v-if="!connecting" @submit.stop.prevent="connect">
|
||||
<span>Please enter the password:</span>
|
||||
<input type="text" placeholder="Username" v-model="username" />
|
||||
<input type="password" placeholder="Password" v-model="password" />
|
||||
<button type="submit" class="button" @click.stop.prevent="connect">
|
||||
Connect
|
||||
</button>
|
||||
</form>
|
||||
<div class="spinner" v-if="connecting">
|
||||
<div class="double-bounce1"></div>
|
||||
<div class="double-bounce2"></div>
|
||||
</div>
|
||||
<div class="loader" v-if="connecting" />
|
||||
</div>
|
||||
</div>
|
||||
<notifications group="neko" position="bottom left" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.video-player {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
.video {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.video-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 16 / 9 * 100vh;
|
||||
|
||||
video {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
background: #000;
|
||||
|
||||
&::-webkit-media-controls {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.video-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba($color: $style-darker, $alpha: 0.2);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
&::before {
|
||||
font-size: 120px;
|
||||
color: rgba($color: $style-light, $alpha: 0.4);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.aspect {
|
||||
display: block;
|
||||
padding-bottom: 56.25%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 60px;
|
||||
background: $style-darker;
|
||||
padding: 0 50px;
|
||||
display: flex;
|
||||
|
||||
.neko {
|
||||
flex: 1; /* shorthand for: flex-grow: 1, flex-shrink: 1, flex-basis: 0 */
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 150px;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
float: left;
|
||||
height: 54px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: $style-light;
|
||||
font-size: 30px;
|
||||
line-height: 56px;
|
||||
|
||||
b {
|
||||
font-weight: 900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
padding: 0 10px;
|
||||
color: $style-light;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
|
||||
.request {
|
||||
color: rgba($color: $style-light, $alpha: 0.5);
|
||||
|
||||
&.enabled {
|
||||
color: $style-light;
|
||||
}
|
||||
}
|
||||
|
||||
.volume {
|
||||
display: block;
|
||||
margin-top: 3px;
|
||||
|
||||
input[type='range'] {
|
||||
-webkit-appearance: none;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
width: 200px;
|
||||
height: 20px;
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
border-radius: 12px;
|
||||
background: $style-light;
|
||||
cursor: pointer;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
&::-webkit-slider-runnable-track {
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
cursor: pointer;
|
||||
background: $style-primary;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
color: $style-light;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.connect {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba($color: $style-darker, $alpha: 0.8);
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.window {
|
||||
width: 300px;
|
||||
background: $style-light;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
|
||||
.logo {
|
||||
color: $style-darker;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
filter: invert(100%);
|
||||
height: 90px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 30px;
|
||||
line-height: 56px;
|
||||
|
||||
b {
|
||||
font-weight: 900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
span {
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
input {
|
||||
border: solid 1px rgba($color: $style-darker, $alpha: 0.4);
|
||||
padding: 3px;
|
||||
line-height: 20px;
|
||||
border-radius: 5px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
padding: 4px;
|
||||
background: $style-primary;
|
||||
color: $style-light;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
|
||||
.double-bounce1,
|
||||
.double-bounce2 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: $style-primary;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
-webkit-animation: sk-bounce 2s infinite ease-in-out;
|
||||
animation: sk-bounce 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.double-bounce2 {
|
||||
-webkit-animation-delay: -1s;
|
||||
animation-delay: -1s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-bounce {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Ref, Watch, Vue } from 'vue-property-decorator'
|
||||
import { EVENT } from '~/client/events'
|
||||
|
||||
@Component({ name: 'stream-video' })
|
||||
export default class extends Vue {
|
||||
@Ref('player') readonly _player!: HTMLVideoElement
|
||||
@Ref('container') readonly _container!: HTMLElement
|
||||
@Ref('aspect') readonly _aspect!: HTMLElement
|
||||
@Ref('video') readonly _video!: HTMLElement
|
||||
@Ref('volume') readonly _volume!: HTMLInputElement
|
||||
|
||||
private focused = false
|
||||
private playing = false
|
||||
private username = ''
|
||||
private password = ''
|
||||
|
||||
get connected() {
|
||||
return this.$accessor.connected
|
||||
}
|
||||
|
||||
get connecting() {
|
||||
return this.$accessor.connecting
|
||||
}
|
||||
|
||||
get hosting() {
|
||||
return this.$accessor.remote.hosting
|
||||
}
|
||||
|
||||
get volume() {
|
||||
return this.$accessor.video.volume
|
||||
}
|
||||
|
||||
get stream() {
|
||||
return this.$accessor.video.stream
|
||||
}
|
||||
|
||||
@Watch('volume')
|
||||
onVolumeChanged(volume: number) {
|
||||
if (this._player) {
|
||||
this._player.volume = this.volume / 100
|
||||
}
|
||||
}
|
||||
|
||||
@Watch('stream')
|
||||
onStreamChanged(stream?: MediaStream) {
|
||||
if (!this._player || !stream) {
|
||||
return
|
||||
}
|
||||
|
||||
if ('srcObject' in this._player) {
|
||||
this._player.srcObject = this.stream
|
||||
} else {
|
||||
// @ts-ignore
|
||||
this._player.src = window.URL.createObjectURL(this.stream) // for older browsers
|
||||
}
|
||||
|
||||
if (this._player.paused) {
|
||||
this.toggleMedia()
|
||||
}
|
||||
}
|
||||
|
||||
mounted() {
|
||||
window.addEventListener('resize', this.onResise)
|
||||
this.onResise()
|
||||
this._player.volume = this.volume / 100
|
||||
this._volume.value = `${this.volume}`
|
||||
this.onStreamChanged(this.stream)
|
||||
}
|
||||
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.onResise)
|
||||
}
|
||||
|
||||
toggleMedia() {
|
||||
if (!this.playing) {
|
||||
this._player
|
||||
.play()
|
||||
.then(() => {
|
||||
const { videoWidth, videoHeight } = this._player
|
||||
this.$accessor.video.setResolution({ width: videoWidth, height: videoHeight })
|
||||
this.playing = true
|
||||
this.onResise()
|
||||
})
|
||||
.catch(err => {})
|
||||
} else {
|
||||
this._player.pause()
|
||||
this.playing = false
|
||||
}
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.$client.connect(this.password, this.username)
|
||||
}
|
||||
|
||||
toggleControl() {
|
||||
if (!this.connected) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.hosting) {
|
||||
this.$client.sendMessage(EVENT.CONTROL.REQUEST)
|
||||
} else {
|
||||
this.$client.sendMessage(EVENT.CONTROL.RELEASE)
|
||||
}
|
||||
}
|
||||
|
||||
setVolume() {
|
||||
this.$accessor.video.setVolume(parseInt(this._volume.value))
|
||||
}
|
||||
|
||||
fullscreen() {
|
||||
this._video.requestFullscreen()
|
||||
}
|
||||
|
||||
onMousePos(e: MouseEvent) {
|
||||
const { w, h } = this.$accessor.video.resolution
|
||||
const rect = this._player.getBoundingClientRect()
|
||||
this.$client.sendData('mousemove', {
|
||||
x: Math.round((w / rect.width) * (e.clientX - rect.left)),
|
||||
y: Math.round((h / rect.height) * (e.clientY - rect.top)),
|
||||
})
|
||||
}
|
||||
|
||||
onWheel(e: WheelEvent) {
|
||||
if (!this.hosting) {
|
||||
return
|
||||
}
|
||||
this.onMousePos(e)
|
||||
this.$client.sendData('wheel', {
|
||||
x: (e.deltaX * -1) / 10,
|
||||
y: (e.deltaY * -1) / 10,
|
||||
}) // TODO: Add user settings
|
||||
}
|
||||
|
||||
onMouseDown(e: MouseEvent) {
|
||||
if (!this.hosting) {
|
||||
return
|
||||
}
|
||||
this.onMousePos(e)
|
||||
this.$client.sendData('mousedown', { key: e.button })
|
||||
}
|
||||
|
||||
onMouseUp(e: MouseEvent) {
|
||||
if (!this.hosting) {
|
||||
return
|
||||
}
|
||||
this.onMousePos(e)
|
||||
this.$client.sendData('mouseup', { key: e.button })
|
||||
}
|
||||
|
||||
onMouseMove(e: MouseEvent) {
|
||||
if (!this.hosting) {
|
||||
return
|
||||
}
|
||||
this.onMousePos(e)
|
||||
}
|
||||
|
||||
onMouseEnter(e: MouseEvent) {
|
||||
this._player.focus()
|
||||
this.focused = true
|
||||
}
|
||||
|
||||
onMouseLeave(e: MouseEvent) {
|
||||
this.focused = false
|
||||
}
|
||||
|
||||
onKeyDown(e: KeyboardEvent) {
|
||||
if (!this.focused || !this.hosting) {
|
||||
return
|
||||
}
|
||||
this.$client.sendData('keydown', { key: e.keyCode })
|
||||
}
|
||||
|
||||
onKeyUp(e: KeyboardEvent) {
|
||||
if (!this.focused || !this.hosting) {
|
||||
return
|
||||
}
|
||||
this.$client.sendData('keyup', { key: e.keyCode })
|
||||
}
|
||||
|
||||
onResise() {
|
||||
const aspect = this.$accessor.video.aspect
|
||||
if (!aspect) {
|
||||
return
|
||||
}
|
||||
const { horizontal, vertical } = aspect
|
||||
this._container.style.maxWidth = `${(horizontal / vertical) * this._video.offsetHeight}px`
|
||||
this._aspect.style.paddingBottom = `${(vertical / horizontal) * 100}%`
|
||||
}
|
||||
}
|
||||
</script>
|
190
client/src/app.vue
Normal file
190
client/src/app.vue
Normal file
@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<div id="neko">
|
||||
<main class="neko-main">
|
||||
<div class="header-container">
|
||||
<div class="neko">
|
||||
<img src="@/assets/logo.svg" alt="n.eko" />
|
||||
<span><b>n</b>.eko</span>
|
||||
</div>
|
||||
<i class="fas fa-bars toggle" @click="toggle" />
|
||||
</div>
|
||||
<div class="video-container">
|
||||
<neko-video ref="video" />
|
||||
</div>
|
||||
<div class="room-container">
|
||||
<neko-members />
|
||||
<div class="room-menu">
|
||||
<div class="settings">
|
||||
<neko-menu />
|
||||
</div>
|
||||
<div class="controls">
|
||||
<neko-controls />
|
||||
</div>
|
||||
<div class="emoji">
|
||||
<neko-emoji />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<neko-side v-if="side" />
|
||||
<neko-connect v-if="!connected" />
|
||||
<neko-about v-if="about" />
|
||||
<notifications group="neko" position="top left" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
#neko {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
|
||||
.neko-main {
|
||||
max-width: 100%;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
|
||||
.header-container {
|
||||
background: $background-tertiary;
|
||||
height: $menu-height;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
|
||||
.toggle {
|
||||
display: block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
background: $background-primary;
|
||||
justify-self: flex-end;
|
||||
border-radius: 3px;
|
||||
margin: 5px 10px 0 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.neko {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 150px;
|
||||
margin-left: 20px;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
float: left;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 30px;
|
||||
line-height: 30px;
|
||||
|
||||
b {
|
||||
font-weight: 900;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.video-container {
|
||||
background: rgba($color: #000, $alpha: 0.4);
|
||||
max-width: 100%;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.room-container {
|
||||
background: $background-tertiary;
|
||||
height: $controls-height;
|
||||
max-width: 100%;
|
||||
flex-shrink: 0;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
|
||||
.room-menu {
|
||||
max-width: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
|
||||
.settings {
|
||||
margin-left: 10px;
|
||||
flex: 1;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.controls {
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
margin-right: 10px;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component, Ref } from 'vue-property-decorator'
|
||||
|
||||
import Connect from '~/components/connect.vue'
|
||||
import Video from '~/components/video.vue'
|
||||
import Menu from '~/components/menu.vue'
|
||||
import Side from '~/components/side.vue'
|
||||
import Controls from '~/components/controls.vue'
|
||||
import Members from '~/components/members.vue'
|
||||
import Emoji from '~/components/emoji.vue'
|
||||
import About from '~/components/about.vue'
|
||||
|
||||
@Component({
|
||||
name: 'neko',
|
||||
components: {
|
||||
'neko-connect': Connect,
|
||||
'neko-video': Video,
|
||||
'neko-menu': Menu,
|
||||
'neko-side': Side,
|
||||
'neko-controls': Controls,
|
||||
'neko-members': Members,
|
||||
'neko-emoji': Emoji,
|
||||
'neko-about': About,
|
||||
},
|
||||
})
|
||||
export default class extends Vue {
|
||||
@Ref('video') video!: Video
|
||||
|
||||
get about() {
|
||||
return this.$accessor.client.about
|
||||
}
|
||||
|
||||
get side() {
|
||||
return this.$accessor.client.side
|
||||
}
|
||||
|
||||
get connected() {
|
||||
return this.$accessor.connected
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.$accessor.client.toggleSide()
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,10 +1,31 @@
|
||||
$text-family: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif;;
|
||||
$text-size: 14px;
|
||||
$text-normal: #dcddde;
|
||||
$text-muted: #72767d;
|
||||
$text-link: #00b0f4;
|
||||
|
||||
$interactive-normal: #b9bbbe;
|
||||
$interactive-hover: #dcddde;
|
||||
$interactive-active: #fff;
|
||||
$interactive-muted: #4f545c;
|
||||
|
||||
$background-primary: #36393f;
|
||||
$background-secondary: #2f3136;
|
||||
$background-tertiary: #202225;
|
||||
$background-accent: #4f545c;
|
||||
$background-floating: #18191c;
|
||||
$background-modifier-hover: rgba(79, 84, 92, 0.16);
|
||||
$background-modifier-active: rgba(79, 84, 92, 0.24);
|
||||
$background-modifier-selected: rgba(79, 84, 92, 0.32);
|
||||
$background-modifier-accent: hsla(0, 0%, 100%, 0.06);
|
||||
|
||||
$elevation-low: 0 1px 0 rgba(4, 4, 5, 0.2), 0 1.5px 0 rgba(6, 6, 7, 0.05), 0 2px 0 rgba(4, 4, 5, 0.05);
|
||||
$elevation-high: 0 8px 16px rgba(0, 0, 0, 0.24);
|
||||
|
||||
$style-dark: #2c2c2c;
|
||||
$style-darker: #1a1a1a;
|
||||
$style-light: #fafafa;
|
||||
$style-primary: #19bd9c;
|
||||
$style-error: #d32f2f;
|
||||
|
||||
$menu-height: 40px;
|
||||
$controls-height: 125px;
|
||||
$side-width: 300px;
|
||||
|
||||
$style-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
$style-font-color: $style-dark;
|
||||
$style-font-size: 14px;
|
||||
|
BIN
client/src/assets/styles/fonts/whitney-300.woff
Normal file
BIN
client/src/assets/styles/fonts/whitney-300.woff
Normal file
Binary file not shown.
BIN
client/src/assets/styles/fonts/whitney-400.woff
Normal file
BIN
client/src/assets/styles/fonts/whitney-400.woff
Normal file
Binary file not shown.
BIN
client/src/assets/styles/fonts/whitney-500.woff
Normal file
BIN
client/src/assets/styles/fonts/whitney-500.woff
Normal file
Binary file not shown.
BIN
client/src/assets/styles/fonts/whitney-600.woff
Normal file
BIN
client/src/assets/styles/fonts/whitney-600.woff
Normal file
Binary file not shown.
BIN
client/src/assets/styles/fonts/whitney-700.woff
Normal file
BIN
client/src/assets/styles/fonts/whitney-700.woff
Normal file
Binary file not shown.
@ -8,16 +8,20 @@
|
||||
|
||||
// Import Vendor
|
||||
@import "vendor/font-awesome";
|
||||
@import "vendor/font-whitney";
|
||||
@import "vendor/swal";
|
||||
@import "vendor/tooltip";
|
||||
@import "vendor/github";
|
||||
// @import "vendor/bulma";
|
||||
|
||||
html, body {
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
background-color: $style-dark;
|
||||
font-family: $style-font-family;
|
||||
font-size: $style-font-size;
|
||||
color: $style-font-color;
|
||||
background-color: $background-tertiary;
|
||||
font-family: $text-family;
|
||||
font-size: $text-size;
|
||||
color: $text-normal;
|
||||
overflow: hidden;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
min-width: 320px;
|
||||
}
|
||||
|
||||
}
|
245
client/src/assets/styles/vendor/_bulma.scss
vendored
Normal file
245
client/src/assets/styles/vendor/_bulma.scss
vendored
Normal file
@ -0,0 +1,245 @@
|
||||
@import "~bulma/sass/utilities/initial-variables.sass";
|
||||
@import "~bulma/sass/utilities/functions.sass";
|
||||
@import "~bulma/sass/utilities/derived-variables.sass";
|
||||
@import "~bulma/sass/utilities/animations.sass";
|
||||
@import "~bulma/sass/utilities/mixins.sass";
|
||||
@import "~bulma/sass/utilities/controls.sass";
|
||||
|
||||
// $black: hsl(0, 0%, 4%);
|
||||
// $black-bis: hsl(0, 0%, 7%);
|
||||
// $black-ter: hsl(0, 0%, 14%);
|
||||
|
||||
// $grey-darker: hsl(0, 0%, 21%);
|
||||
// $grey-dark: hsl(0, 0%, 29%);
|
||||
// $grey: hsl(0, 0%, 48%);
|
||||
// $grey-light: hsl(0, 0%, 71%);
|
||||
// $grey-lighter: hsl(0, 0%, 86%);
|
||||
// $grey-lightest: hsl(0, 0%, 93%);
|
||||
|
||||
// $white-ter: hsl(0, 0%, 96%);
|
||||
// $white-bis: hsl(0, 0%, 98%);
|
||||
// $white: hsl(0, 0%, 100%);
|
||||
|
||||
// $orange: hsl(14, 100%, 53%);
|
||||
// $yellow: hsl(48, 100%, 67%);
|
||||
// $green: hsl(141, 53%, 53%);
|
||||
// $turquoise: hsl(171, 100%, 41%);
|
||||
// $cyan: hsl(204, 71%, 53%);
|
||||
// $blue: hsl(217, 71%, 53%);
|
||||
// $purple: hsl(271, 100%, 71%);
|
||||
// $red: hsl(348, 86%, 61%);
|
||||
|
||||
// Typography
|
||||
$family-sans-serif: $text-family;
|
||||
// $family-monospace: monospace;
|
||||
// $render-mode: optimizeLegibility;
|
||||
|
||||
// $size-1: 3rem;
|
||||
// $size-2: 2.5rem;
|
||||
// $size-3: 2rem;
|
||||
// $size-4: 1.5rem;
|
||||
// $size-5: 1.25rem;
|
||||
// $size-6: 1rem;
|
||||
// $size-7: 0.75rem;
|
||||
|
||||
// $weight-light: 300;
|
||||
// $weight-normal: 400;
|
||||
// $weight-medium: 500;
|
||||
// $weight-semibold: 600;
|
||||
// $weight-bold: 700;
|
||||
|
||||
// Spacing
|
||||
// $block-spacing: 1.5rem;
|
||||
|
||||
// Responsiveness
|
||||
// The container horizontal gap, which acts as the offset for breakpoints
|
||||
// $gap: 32px;
|
||||
// 960, 1152, and 1344 have been chosen because they are divisible by both 12 and 16
|
||||
// $tablet: 769px;
|
||||
// 960px container + 4rem
|
||||
// $desktop: 960px + (2 * // $gap);
|
||||
// 1152px container + 4rem
|
||||
// $widescreen: 1152px + (2 * // $gap);
|
||||
// $widescreen-enabled: true;
|
||||
// 1344px container + 4rem
|
||||
// $fullhd: 1344px + (2 * // $gap);
|
||||
// $fullhd-enabled: true;
|
||||
|
||||
// Miscellaneous
|
||||
// $easing: ease-out;
|
||||
// $radius-small: 2px;
|
||||
// $radius: 4px;
|
||||
// $radius-large: 6px;
|
||||
// $radius-rounded: 290486px;
|
||||
// $speed: 86ms;
|
||||
|
||||
// Flags
|
||||
// $variable-columns: true;
|
||||
|
||||
// $primary: $turquoise;
|
||||
// $info: $cyan;
|
||||
// $success: $green;
|
||||
// $warning: $yellow;
|
||||
// $danger: $red;
|
||||
|
||||
// $light: $white-ter;
|
||||
// $dark: $grey-darker;
|
||||
|
||||
// Invert colors
|
||||
// $orange-invert: findColorInvert($orange);
|
||||
// $yellow-invert: findColorInvert($yellow);
|
||||
// $green-invert: findColorInvert($green);
|
||||
// $turquoise-invert: findColorInvert($turquoise);
|
||||
// $cyan-invert: findColorInvert($cyan);
|
||||
// $blue-invert: findColorInvert($blue);
|
||||
// $purple-invert: findColorInvert($purple);
|
||||
// $red-invert: findColorInvert($red);
|
||||
|
||||
// $primary-invert: findColorInvert($primary);
|
||||
// $primary-light: findLightColor($primary);
|
||||
// $primary-dark: findDarkColor($primary);
|
||||
// $info-invert: findColorInvert($info);
|
||||
// $info-light: findLightColor($info);
|
||||
// $info-dark: findDarkColor($info);
|
||||
// $success-invert: findColorInvert($success);
|
||||
// $success-light: findLightColor($success);
|
||||
// $success-dark: findDarkColor($success);
|
||||
// $warning-invert: findColorInvert($warning);
|
||||
// $warning-light: findLightColor($warning);
|
||||
// $warning-dark: findDarkColor($warning);
|
||||
// $danger-invert: findColorInvert($danger);
|
||||
// $danger-light: findLightColor($danger);
|
||||
// $danger-dark: findDarkColor($danger);
|
||||
// $light-invert: findColorInvert($light);
|
||||
// $dark-invert: findColorInvert($dark);
|
||||
|
||||
// General colors
|
||||
// $scheme-main: $white;
|
||||
// $scheme-main-bis: $white-bis;
|
||||
// $scheme-main-ter: $white-ter;
|
||||
// $scheme-invert: $black;
|
||||
// $scheme-invert-bis: $black-bis;
|
||||
// $scheme-invert-ter: $black-ter;
|
||||
|
||||
// $background: $white-ter;
|
||||
$border: $grey-light;
|
||||
$border-hover: $grey;
|
||||
// $border-light: $grey-lightest;
|
||||
// $border-light-hover: $grey-light;
|
||||
|
||||
// Text colors
|
||||
// $text: $grey-dark;
|
||||
// $text-invert: findColorInvert($text);
|
||||
// $text-light: $grey;
|
||||
// $text-strong: $grey-darker;
|
||||
|
||||
// Code colors
|
||||
// $code: $red;
|
||||
// $code-background: $background;
|
||||
|
||||
// $pre: $text;
|
||||
// $pre-background: $background;
|
||||
|
||||
// Link colors
|
||||
// $link: $blue;
|
||||
// $link-invert: findColorInvert($link);
|
||||
// $link-light: findLightColor($link);
|
||||
// $link-dark: findDarkColor($link);
|
||||
// $link-visited: $purple;
|
||||
|
||||
// $link-hover: $grey-darker;
|
||||
// $link-hover-border: $grey-light;
|
||||
|
||||
// $link-focus: $grey-darker;
|
||||
// $link-focus-border: $blue;
|
||||
|
||||
// $link-active: $grey-darker;
|
||||
// $link-active-border: $grey-dark;
|
||||
|
||||
// Typography
|
||||
// $family-primary: $family-sans-serif;
|
||||
// $family-secondary: $family-sans-serif;
|
||||
// $family-code: $family-monospace;
|
||||
|
||||
// $size-small: $size-7;
|
||||
// $size-normal: $size-6;
|
||||
// $size-medium: $size-5;
|
||||
// $size-large: $size-4;
|
||||
|
||||
// Lists and maps
|
||||
// $custom-colors: null;
|
||||
// $custom-shades: null;
|
||||
|
||||
// $colors: mergeColorMaps(("white": ($white, $black), "black": ($black, $white), "light": ($light, $light-invert), "dark": ($dark, $dark-invert), "primary": ($primary, $primary-invert, $primary-light, $primary-dark), "link": ($link, $link-invert, $link-light, $link-dark), "info": ($info, $info-invert, $info-light, $info-dark), "success": ($success, $success-invert, $success-light, $success-dark), "warning": ($warning, $warning-invert, $warning-light, $warning-dark), "danger": ($danger, $danger-invert, $danger-light, $danger-dark)), $custom-colors);
|
||||
// $shades: mergeColorMaps(("black-bis": $black-bis, "black-ter": $black-ter, "grey-darker": $grey-darker, "grey-dark": $grey-dark, "grey": $grey, "grey-light": $grey-light, "grey-lighter": $grey-lighter, "white-ter": $white-ter, "white-bis": $white-bis), $custom-shades);
|
||||
// $sizes: $size-1 $size-2 $size-3 $size-4 $size-5 $size-6 $size-7;
|
||||
|
||||
@import "~bulma/sass/base/minireset";
|
||||
@import "~bulma/sass/base/generic";
|
||||
@import "~bulma/sass/base/helpers";
|
||||
|
||||
@import "~bulma/sass/elements/box.sass";
|
||||
@import "~bulma/sass/elements/button.sass";
|
||||
@import "~bulma/sass/elements/container.sass";
|
||||
@import "~bulma/sass/elements/content.sass";
|
||||
@import "~bulma/sass/elements/icon.sass";
|
||||
@import "~bulma/sass/elements/image.sass";
|
||||
@import "~bulma/sass/elements/notification.sass";
|
||||
@import "~bulma/sass/elements/progress.sass";
|
||||
@import "~bulma/sass/elements/table.sass";
|
||||
@import "~bulma/sass/elements/tag.sass";
|
||||
@import "~bulma/sass/elements/title.sass";
|
||||
@import "~bulma/sass/elements/other.sass";
|
||||
|
||||
// $input-color: $text-strong;
|
||||
// $input-background-color: $scheme-main;
|
||||
// $input-border-color: $border;
|
||||
// $input-height: $control-height;
|
||||
// $input-shadow: inset 0 0.0625em 0.125em rgba($scheme-invert, 0.05);
|
||||
// $input-placeholder-color: rgba($input-color, 0.3);
|
||||
// $input-hover-color: $text-strong;
|
||||
// $input-hover-border-color: $border-hover;
|
||||
// $input-focus-color: $text-strong;
|
||||
// $input-focus-border-color: $link;
|
||||
// $input-focus-box-shadow-size: 0 0 0 0.125em;
|
||||
// $input-focus-box-shadow-color: rgba($link, 0.25);
|
||||
// $input-disabled-color: $text-light;
|
||||
// $input-disabled-background-color: $background;
|
||||
// $input-disabled-border-color: $background;
|
||||
// $input-disabled-placeholder-color: rgba($input-disabled-color, 0.3);
|
||||
// $input-arrow: $link;
|
||||
// $input-icon-color: $border;
|
||||
// $input-icon-active-color: $text;
|
||||
// $input-radius: $radius;
|
||||
|
||||
@import "~bulma/sass/form/shared.sass";
|
||||
|
||||
// $textarea-padding: $control-padding-horizontal;
|
||||
// $textarea-max-height: 40em;
|
||||
// $textarea-min-height: 8em;
|
||||
@import "~bulma/sass/form/input-textarea.sass";
|
||||
@import "~bulma/sass/form/checkbox-radio.sass";
|
||||
@import "~bulma/sass/form/select.sass";
|
||||
@import "~bulma/sass/form/file.sass";
|
||||
@import "~bulma/sass/form/tools.sass";
|
||||
|
||||
// @import "~bulma/sass/components/breadcrumb.sass";
|
||||
// @import "~bulma/sass/components/card.sass";
|
||||
// @import "~bulma/sass/components/dropdown.sass";
|
||||
// @import "~bulma/sass/components/level.sass";
|
||||
// @import "~bulma/sass/components/list.sass";
|
||||
// @import "~bulma/sass/components/media.sass";
|
||||
// @import "~bulma/sass/components/menu.sass";
|
||||
// @import "~bulma/sass/components/message.sass";
|
||||
// @import "~bulma/sass/components/modal.sass";
|
||||
// @import "~bulma/sass/components/navbar.sass";
|
||||
// @import "~bulma/sass/components/pagination.sass";
|
||||
// @import "~bulma/sass/components/panel.sass";
|
||||
@import "~bulma/sass/components/tabs.sass";
|
||||
|
||||
@import "~bulma/sass/grid/columns.sass";
|
||||
@import "~bulma/sass/grid/tiles.sass";
|
||||
|
||||
// @import "~bulma/sass/layout/hero.sass";
|
||||
// @import "~bulma/sass/layout/section.sass";
|
||||
// @import "~bulma/sass/layout/footer.sass";
|
29
client/src/assets/styles/vendor/_font-whitney.scss
vendored
Normal file
29
client/src/assets/styles/vendor/_font-whitney.scss
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
@font-face{
|
||||
font-family:Whitney;
|
||||
font-weight:300;
|
||||
src:url("fonts/whitney-300.woff") format("woff")
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family:Whitney;
|
||||
font-weight:400;
|
||||
src:url("fonts/whitney-400.woff") format("woff")
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family:Whitney;
|
||||
font-weight:500;
|
||||
src:url("fonts/whitney-500.woff") format("woff")
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family:Whitney;
|
||||
font-weight:600;
|
||||
src:url("fonts/whitney-600.woff") format("woff")
|
||||
}
|
||||
|
||||
@font-face{
|
||||
font-family:Whitney;
|
||||
font-weight:700;
|
||||
src:url("fonts/whitney-700.woff") format("woff")
|
||||
}
|
957
client/src/assets/styles/vendor/_github.scss
vendored
Normal file
957
client/src/assets/styles/vendor/_github.scss
vendored
Normal file
@ -0,0 +1,957 @@
|
||||
@font-face {
|
||||
font-family: octicons-link;
|
||||
src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
|
||||
}
|
||||
|
||||
.markdown-body .octicon {
|
||||
display: inline-block;
|
||||
fill: currentColor;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.markdown-body .anchor {
|
||||
float: left;
|
||||
line-height: 1;
|
||||
margin-left: -20px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.markdown-body .anchor:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.markdown-body h1 .octicon-link,
|
||||
.markdown-body h2 .octicon-link,
|
||||
.markdown-body h3 .octicon-link,
|
||||
.markdown-body h4 .octicon-link,
|
||||
.markdown-body h5 .octicon-link,
|
||||
.markdown-body h6 .octicon-link {
|
||||
color: $text-normal;
|
||||
vertical-align: middle;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor,
|
||||
.markdown-body h2:hover .anchor,
|
||||
.markdown-body h3:hover .anchor,
|
||||
.markdown-body h4:hover .anchor,
|
||||
.markdown-body h5:hover .anchor,
|
||||
.markdown-body h6:hover .anchor {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body h1:hover .anchor .octicon-link,
|
||||
.markdown-body h2:hover .anchor .octicon-link,
|
||||
.markdown-body h3:hover .anchor .octicon-link,
|
||||
.markdown-body h4:hover .anchor .octicon-link,
|
||||
.markdown-body h5:hover .anchor .octicon-link,
|
||||
.markdown-body h6:hover .anchor .octicon-link {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
color: $text-normal;
|
||||
line-height: 1.5;
|
||||
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c {
|
||||
color: #6a737d;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c1,
|
||||
.markdown-body .pl-s .pl-v {
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-e,
|
||||
.markdown-body .pl-en {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.markdown-body .pl-s .pl-s1,
|
||||
.markdown-body .pl-smi {
|
||||
color: #24292e;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ent {
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.markdown-body .pl-k {
|
||||
color: #d73a49;
|
||||
}
|
||||
|
||||
.markdown-body .pl-pds,
|
||||
.markdown-body .pl-s,
|
||||
.markdown-body .pl-s .pl-pse .pl-s1,
|
||||
.markdown-body .pl-sr,
|
||||
.markdown-body .pl-sr .pl-cce,
|
||||
.markdown-body .pl-sr .pl-sra,
|
||||
.markdown-body .pl-sr .pl-sre {
|
||||
color: #032f62;
|
||||
}
|
||||
|
||||
.markdown-body .pl-smw,
|
||||
.markdown-body .pl-v {
|
||||
color: #e36209;
|
||||
}
|
||||
|
||||
.markdown-body .pl-bu {
|
||||
color: #b31d28;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ii {
|
||||
background-color: #b31d28;
|
||||
color: #fafbfc;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c2 {
|
||||
background-color: #d73a49;
|
||||
color: #fafbfc;
|
||||
}
|
||||
|
||||
.markdown-body .pl-c2:before {
|
||||
content: "^M";
|
||||
}
|
||||
|
||||
.markdown-body .pl-sr .pl-cce {
|
||||
color: #22863a;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ml {
|
||||
color: #735c0f;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mh,
|
||||
.markdown-body .pl-mh .pl-en,
|
||||
.markdown-body .pl-ms {
|
||||
color: #005cc5;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi {
|
||||
color: #24292e;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mb {
|
||||
color: #24292e;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown-body .pl-md {
|
||||
background-color: #ffeef0;
|
||||
color: #b31d28;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi1 {
|
||||
background-color: #f0fff4;
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mc {
|
||||
background-color: #ffebda;
|
||||
color: #e36209;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mi2 {
|
||||
background-color: #005cc5;
|
||||
color: #f6f8fa;
|
||||
}
|
||||
|
||||
.markdown-body .pl-mdr {
|
||||
color: #6f42c1;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.markdown-body .pl-ba {
|
||||
color: #586069;
|
||||
}
|
||||
|
||||
.markdown-body .pl-sg {
|
||||
color: #959da5;
|
||||
}
|
||||
|
||||
.markdown-body .pl-corl {
|
||||
color: #032f62;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown-body details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.markdown-body summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.markdown-body a:active,
|
||||
.markdown-body a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: inherit;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 2em;
|
||||
margin: .67em 0;
|
||||
}
|
||||
|
||||
.markdown-body img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
.markdown-body code,
|
||||
.markdown-body kbd,
|
||||
.markdown-body pre {
|
||||
font-family: monospace,monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.markdown-body [type=checkbox] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-body * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.markdown-body input {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
color: $text-link;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown-body a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown-body strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid $background-primary;
|
||||
height: 0;
|
||||
margin: 15px 0;
|
||||
overflow: hidden;
|
||||
|