* Try CarbonAds * Move location * add border, fix adblock msg * Fix advertisement label look (#636) Ever since changes for Carbon ads were introduced, the label did not match the appearance of the card, leaving the bottom right corner of the card not round. With more recent changes, where border was added, that became even more apparent - now the border covers the label, which does not look good; this effect only becomes worse when zooming. This commit attempts to mitigate these issues with the following: - To fix the border issues, label's absolute position is now calculated from the card wrapper, where the border is applied. This allows label to cover the border for seamless look. That is done by changing position of the card wrapper to relative instead of doing so for the ad contents container. - The label now tries to take over the border, to do so the bottom and right relative positions have been changed to -3px. - To account for the position change, the label is now a bit more padded, to make text content of it to look more or less as before, otherwise it would shift a bit. Not sure if the padding changes are accurate, but it does look close to how it looked before. * Fix message again * Update user ads position * Remove privacy toggles (placebo and didn't do anything) * Remove other code * Link docs page Co-authored-by: Sasha Sorokin <10401817+Brawaru@users.noreply.github.com>
1195 lines
32 KiB
Vue
1195 lines
32 KiB
Vue
<template>
|
|
<div ref="layout" class="layout">
|
|
<header class="site-header" role="presentation">
|
|
<section class="navbar columns" role="navigation">
|
|
<section class="skip column" role="presentation">
|
|
<a href="#main">Skip to Main Content</a>
|
|
<a
|
|
v-show="!!registeredSkipLink"
|
|
:href="(registeredSkipLink || {}).id"
|
|
>{{ (registeredSkipLink || {}).text }}</a
|
|
>
|
|
</section>
|
|
<section class="logo column" role="presentation">
|
|
<NuxtLink to="/" aria-label="Modrinth home page">
|
|
<ModrinthLogo aria-hidden="true" class="text-logo" />
|
|
</NuxtLink>
|
|
</section>
|
|
<section class="nav-group columns" role="presentation">
|
|
<section class="nav" aria-label="Page links">
|
|
<div class="styled-tabs">
|
|
<NuxtLink to="/mods" class="tab">
|
|
<span>Mods</span>
|
|
</NuxtLink>
|
|
<NuxtLink to="/plugins" class="tab">
|
|
<span>Plugins</span>
|
|
</NuxtLink>
|
|
<NuxtLink to="/resourcepacks" class="tab">
|
|
<span>Resource Packs</span>
|
|
</NuxtLink>
|
|
<NuxtLink to="/modpacks" class="tab">
|
|
<span>Modpacks</span>
|
|
</NuxtLink>
|
|
</div>
|
|
</section>
|
|
<section class="column-grow user-outer" aria-label="Account links">
|
|
<section class="user-controls">
|
|
<button
|
|
class="control-button"
|
|
title="Switch theme"
|
|
@click="changeTheme"
|
|
>
|
|
<MoonIcon
|
|
v-if="$colorMode.value === 'light'"
|
|
aria-hidden="true"
|
|
/>
|
|
<SunIcon v-else aria-hidden="true" />
|
|
</button>
|
|
<nuxt-link
|
|
v-if="$auth.user"
|
|
to="/create/project"
|
|
class="control-button"
|
|
title="Create project"
|
|
>
|
|
<PlusIcon aria-hidden="true" />
|
|
</nuxt-link>
|
|
<nuxt-link
|
|
v-if="$auth.user"
|
|
to="/notifications"
|
|
class="control-button"
|
|
title="Notifications"
|
|
>
|
|
<NotificationIcon aria-hidden="true" />
|
|
<div v-if="$user.notifications.length > 0" class="bubble">
|
|
{{ $user.notifications.length }}
|
|
</div>
|
|
</nuxt-link>
|
|
<nuxt-link
|
|
v-if="
|
|
$auth.user &&
|
|
($auth.user.role === 'moderator' ||
|
|
$auth.user.role === 'admin')
|
|
"
|
|
to="/moderation"
|
|
class="control-button"
|
|
title="Moderation"
|
|
>
|
|
<ModerationIcon aria-hidden="true" />
|
|
<div v-if="moderationNotifications > 0" class="bubble">
|
|
{{ moderationNotifications }}
|
|
</div>
|
|
</nuxt-link>
|
|
<div v-if="$auth.user" ref="mobileMenu" class="dropdown">
|
|
<button class="control" value="Profile Dropdown">
|
|
<img
|
|
:src="$auth.user.avatar_url"
|
|
class="user-icon"
|
|
aria-hidden="true"
|
|
alt="Your avatar"
|
|
/>
|
|
<DropdownIcon class="caret" />
|
|
</button>
|
|
<ul class="content card" @click="removeFocus">
|
|
<li>
|
|
<NuxtLink
|
|
class="item"
|
|
:to="`/user/${$auth.user.username}`"
|
|
@click="removeFocus"
|
|
>
|
|
<div class="title profile-link">
|
|
<div class="username">@{{ $auth.user.username }}</div>
|
|
<div class="prompt">Go to my profile</div>
|
|
</div>
|
|
</NuxtLink>
|
|
</li>
|
|
<hr class="divider" />
|
|
<li>
|
|
<NuxtLink class="item" to="/create/project">
|
|
<PlusIcon class="icon" />
|
|
<span class="title">Create a project</span>
|
|
</NuxtLink>
|
|
</li>
|
|
<hr class="divider" />
|
|
<li>
|
|
<NuxtLink class="item" to="/notifications">
|
|
<NotificationIcon class="icon" />
|
|
<span class="title">Notifications</span>
|
|
</NuxtLink>
|
|
</li>
|
|
<li>
|
|
<NuxtLink class="item" to="/settings/follows">
|
|
<HeartIcon class="icon" />
|
|
<span class="title">Following</span>
|
|
</NuxtLink>
|
|
</li>
|
|
<li>
|
|
<NuxtLink class="item" to="/settings">
|
|
<SettingsIcon class="icon" />
|
|
<span class="title">Settings</span>
|
|
</NuxtLink>
|
|
</li>
|
|
<li>
|
|
<NuxtLink
|
|
v-if="
|
|
$auth.user.role === 'moderator' ||
|
|
$auth.user.role === 'admin'
|
|
"
|
|
class="item"
|
|
to="/moderation"
|
|
>
|
|
<ModerationIcon class="icon" />
|
|
<span class="title">Moderation</span>
|
|
</NuxtLink>
|
|
</li>
|
|
<li>
|
|
<button class="item" @click="changeTheme">
|
|
<MoonIcon
|
|
v-if="$colorMode.value === 'light'"
|
|
class="icon"
|
|
/>
|
|
<SunIcon v-else class="icon" />
|
|
<span class="dropdown-item__text">Change theme</span>
|
|
</button>
|
|
</li>
|
|
<hr class="divider" />
|
|
<li>
|
|
<button class="item" @click="logout">
|
|
<LogOutIcon class="icon" />
|
|
<span class="dropdown-item__text">Log out</span>
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<section v-else class="auth-prompt">
|
|
<a :href="authUrl" class="log-in-button">
|
|
<GitHubIcon aria-hidden="true" />
|
|
Sign in with GitHub</a
|
|
>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
<section ref="mobileNavBar" class="mobile-navbar">
|
|
<div class="top-row">
|
|
<NuxtLink to="/" class="tab" @click.native="closeBrowseMenu()">
|
|
<HomeIcon />
|
|
</NuxtLink>
|
|
<div class="spacer"></div>
|
|
<button class="tab browse" @click="toggleBrowseMenu()">
|
|
<DropdownIcon :class="{ closed: !isBrowseMenuOpen }" />
|
|
<span>Browse</span>
|
|
</button>
|
|
<div class="spacer"></div>
|
|
<button class="tab" @click="toggleMobileMenu()">
|
|
<HamburgerIcon v-if="!isMobileMenuOpen" />
|
|
<CrossIcon v-else />
|
|
</button>
|
|
</div>
|
|
<div
|
|
:class="{ 'disable-childern': !isBrowseMenuOpen }"
|
|
class="project-types"
|
|
>
|
|
<NuxtLink
|
|
:tabindex="isBrowseMenuOpen ? 0 : -1"
|
|
to="/mods"
|
|
class="tab"
|
|
@click.native="closeBrowseMenu()"
|
|
>
|
|
<span>Mods</span>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
:tabindex="isBrowseMenuOpen ? 0 : -1"
|
|
to="/plugins"
|
|
class="tab"
|
|
@click.native="closeBrowseMenu()"
|
|
>
|
|
<span>Plugins</span>
|
|
</NuxtLink>
|
|
|
|
<NuxtLink
|
|
:tabindex="isBrowseMenuOpen ? 0 : -1"
|
|
to="/resourcepacks"
|
|
class="tab"
|
|
@click.native="closeBrowseMenu()"
|
|
>
|
|
<span>Resource Packs</span>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
:tabindex="isBrowseMenuOpen ? 0 : -1"
|
|
to="/modpacks"
|
|
class="tab"
|
|
@click.native="closeBrowseMenu()"
|
|
>
|
|
<span>Modpacks</span>
|
|
</NuxtLink>
|
|
</div>
|
|
</section>
|
|
<section ref="mobileMenu" class="mobile-menu">
|
|
<div class="mobile-menu-wrapper">
|
|
<div class="items-container rows">
|
|
<NuxtLink
|
|
v-if="$auth.user"
|
|
class="item user-item"
|
|
:to="`/user/${$auth.user.username}`"
|
|
>
|
|
<img :src="$auth.user.avatar_url" class="user-icon" />
|
|
<div class="profile-link">
|
|
<div class="username">@{{ $auth.user.username }}</div>
|
|
<div class="prompt">Go to my profile</div>
|
|
</div>
|
|
</NuxtLink>
|
|
<button v-if="$auth.user" class="item log-out" @click="logout">
|
|
<LogOutIcon class="icon" />
|
|
<span class="dropdown-item__text">Log out</span>
|
|
</button>
|
|
<NuxtLink v-if="$auth.user" class="item" to="/create/project">
|
|
<PlusIcon class="icon" />
|
|
<span class="title">Create a project</span>
|
|
</NuxtLink>
|
|
<NuxtLink v-if="$auth.user" class="item" to="/settings">
|
|
<SettingsIcon class="icon" />
|
|
<span class="title">Settings</span>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
v-if="
|
|
$auth.user &&
|
|
($auth.user.role === 'moderator' || $auth.user.role === 'admin')
|
|
"
|
|
class="item"
|
|
to="/moderation"
|
|
>
|
|
<ModerationIcon class="icon" />
|
|
<span class="title">Moderation</span>
|
|
</NuxtLink>
|
|
<NuxtLink v-if="$auth.user" class="item" to="/settings/follows">
|
|
<HeartIcon class="icon" />
|
|
<span class="title">Following</span>
|
|
</NuxtLink>
|
|
<NuxtLink v-if="$auth.user" class="item" to="/notifications">
|
|
<NotificationIcon class="icon" />
|
|
<span class="title">Notifications</span>
|
|
</NuxtLink>
|
|
<button class="item" @click="changeTheme">
|
|
<MoonIcon v-if="$colorMode.value === 'light'" class="icon" />
|
|
<SunIcon v-else class="icon" />
|
|
<span class="dropdown-item__text">Change theme</span>
|
|
</button>
|
|
<a v-if="!$auth.user" :href="authUrl" class="item log-in">
|
|
<GitHubIcon aria-hidden="true" />
|
|
Sign in with GitHub</a
|
|
>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</header>
|
|
<main>
|
|
<notifications
|
|
group="main"
|
|
position="bottom right"
|
|
:max="5"
|
|
:class="{ 'browse-menu-open': isBrowseMenuOpen }"
|
|
:ignore-duplicates="true"
|
|
:duration="10000"
|
|
/>
|
|
<Nuxt id="main" />
|
|
</main>
|
|
<footer>
|
|
<div class="logo-info" role="region" aria-label="Modrinth information">
|
|
<ModrinthLogo aria-hidden="true" class="text-logo" />
|
|
<p>
|
|
Modrinth is
|
|
<a
|
|
target="_blank"
|
|
href="https://github.com/modrinth"
|
|
class="text-link"
|
|
>
|
|
open source</a
|
|
>.
|
|
</p>
|
|
<p>
|
|
{{ owner }}/{{ slug }} {{ branch }}@<a
|
|
target="_blank"
|
|
:href="'https://github.com/' + owner + '/' + slug + '/tree/' + hash"
|
|
class="text-link"
|
|
>{{ hash.substring(0, 7) }}</a
|
|
>
|
|
</p>
|
|
<p>© Rinth, Inc.</p>
|
|
</div>
|
|
<div class="links links-1" role="region" aria-label="Legal">
|
|
<h4 aria-hidden="true">Legal</h4>
|
|
<nuxt-link to="/legal/terms">Terms</nuxt-link>
|
|
<nuxt-link to="/legal/privacy">Privacy</nuxt-link>
|
|
<nuxt-link to="/legal/rules">Rules</nuxt-link>
|
|
<a
|
|
target="_blank"
|
|
href="https://github.com/modrinth/knossos/blob/master/LICENSE.md"
|
|
>
|
|
License
|
|
</a>
|
|
</div>
|
|
<div class="links links-2" role="region" aria-label="Resources">
|
|
<h4 aria-hidden="true">Resources</h4>
|
|
<a target="_blank" href="https://blog.modrinth.com">Blog</a>
|
|
<a target="_blank" href="https://discord.gg/EUHuJHt">Discord</a>
|
|
<a target="_blank" href="https://github.com/modrinth/knossos">GitHub</a>
|
|
<a target="_blank" href="https://docs.modrinth.com">Docs</a>
|
|
</div>
|
|
<div class="buttons">
|
|
<button class="iconified-button" @click="changeTheme">
|
|
<MoonIcon v-if="$colorMode.value === 'light'" aria-hidden="true" />
|
|
<SunIcon v-else aria-hidden="true" />
|
|
Change theme
|
|
</button>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import ClickOutside from 'vue-click-outside'
|
|
|
|
import ModrinthLogo from '~/assets/images/text-logo.svg?inline'
|
|
|
|
import HamburgerIcon from '~/assets/images/utils/hamburger.svg?inline'
|
|
import CrossIcon from '~/assets/images/utils/x.svg?inline'
|
|
|
|
import NotificationIcon from '~/assets/images/sidebar/notifications.svg?inline'
|
|
import SettingsIcon from '~/assets/images/sidebar/settings.svg?inline'
|
|
import ModerationIcon from '~/assets/images/sidebar/admin.svg?inline'
|
|
import HomeIcon from '~/assets/images/sidebar/home.svg?inline'
|
|
|
|
import MoonIcon from '~/assets/images/utils/moon.svg?inline'
|
|
import SunIcon from '~/assets/images/utils/sun.svg?inline'
|
|
import PlusIcon from '~/assets/images/utils/plus.svg?inline'
|
|
import DropdownIcon from '~/assets/images/utils/dropdown.svg?inline'
|
|
import LogOutIcon from '~/assets/images/utils/log-out.svg?inline'
|
|
import HeartIcon from '~/assets/images/utils/heart.svg?inline'
|
|
|
|
import GitHubIcon from '~/assets/images/utils/github.svg?inline'
|
|
|
|
const overflowStyle = 'scroll'
|
|
|
|
export default {
|
|
components: {
|
|
ModrinthLogo,
|
|
MoonIcon,
|
|
SunIcon,
|
|
LogOutIcon,
|
|
GitHubIcon,
|
|
NotificationIcon,
|
|
HomeIcon,
|
|
CrossIcon,
|
|
HamburgerIcon,
|
|
SettingsIcon,
|
|
ModerationIcon,
|
|
PlusIcon,
|
|
DropdownIcon,
|
|
HeartIcon,
|
|
},
|
|
directives: {
|
|
ClickOutside,
|
|
},
|
|
data() {
|
|
return {
|
|
isDropdownOpen: false,
|
|
owner: process.env.owner || 'modrinth',
|
|
slug: process.env.slug || 'knossos',
|
|
branch: process.env.branch || 'master',
|
|
hash: process.env.hash || 'unknown',
|
|
isMobileMenuOpen: false,
|
|
isBrowseMenuOpen: false,
|
|
registeredSkipLink: null,
|
|
moderationNotifications: 0,
|
|
}
|
|
},
|
|
async fetch() {
|
|
await Promise.all([
|
|
this.$store.dispatch('user/fetchAll', { force: true }),
|
|
this.$store.dispatch('tag/fetchAllTags'),
|
|
this.$store.dispatch('cosmetics/fetchCosmetics', this.$cookies),
|
|
])
|
|
if (
|
|
(this.$auth.user && this.$auth.user.role === 'moderator') ||
|
|
(this.$auth.user && this.$auth.user.role === 'admin')
|
|
) {
|
|
const [projects, reports] = (
|
|
await Promise.all([
|
|
this.$axios.get(`moderation/projects`, this.$defaultHeaders()),
|
|
this.$axios.get(`report`, this.$defaultHeaders()),
|
|
])
|
|
).map((it) => it.data)
|
|
|
|
this.moderationNotifications = projects.length + reports.length
|
|
}
|
|
},
|
|
computed: {
|
|
authUrl() {
|
|
return `${process.env.authURLBase}auth/init?url=${process.env.domain}${this.$route.path}`
|
|
},
|
|
},
|
|
watch: {
|
|
$route() {
|
|
this.$refs.mobileMenu.className = 'mobile-menu'
|
|
this.isMobileMenuOpen =
|
|
this.$refs.mobileMenu.className === 'mobile-menu active'
|
|
|
|
document.body.style.overflowY = overflowStyle
|
|
|
|
this.$store.dispatch('user/fetchAll')
|
|
},
|
|
},
|
|
beforeCreate() {
|
|
if (this.$route.query.code) {
|
|
this.$router.push(this.$route.path)
|
|
}
|
|
},
|
|
created() {
|
|
this.$nuxt.$on('registerSkipLink', (data) => {
|
|
this.registeredSkipLink = data
|
|
})
|
|
},
|
|
methods: {
|
|
toggleMobileMenu() {
|
|
window.scrollTo(0, 0)
|
|
const currentlyActive =
|
|
this.$refs.mobileMenu.className === 'mobile-menu active'
|
|
this.$refs.mobileMenu.className = `mobile-menu${
|
|
currentlyActive ? '' : ' active'
|
|
}`
|
|
document.body.scrollTop = 0
|
|
|
|
document.body.style.overflowY =
|
|
document.body.style.overflowY !== 'hidden' ? 'hidden' : overflowStyle
|
|
|
|
this.isMobileMenuOpen = !currentlyActive
|
|
|
|
if (this.isMobileMenuOpen) {
|
|
this.$refs.mobileNavBar.className = `mobile-navbar`
|
|
this.$refs.layout.className = `layout`
|
|
|
|
this.isBrowseMenuOpen = false
|
|
}
|
|
},
|
|
toggleBrowseMenu() {
|
|
const currentlyActive =
|
|
this.$refs.mobileNavBar.className === 'mobile-navbar expanded'
|
|
this.$refs.mobileNavBar.className = `mobile-navbar${
|
|
currentlyActive ? '' : ' expanded'
|
|
}`
|
|
this.$refs.layout.className = `layout${
|
|
currentlyActive ? '' : ' expanded-mobile-nav'
|
|
}`
|
|
|
|
this.isBrowseMenuOpen = !currentlyActive
|
|
|
|
if (this.isBrowseMenuOpen) {
|
|
this.$refs.mobileMenu.className = `mobile-menu`
|
|
|
|
this.isMobileMenuOpen = false
|
|
}
|
|
},
|
|
closeBrowseMenu() {
|
|
this.$refs.mobileNavBar.className = `mobile-navbar`
|
|
this.$refs.layout.className = `layout`
|
|
|
|
this.isBrowseMenuOpen = false
|
|
},
|
|
async logout() {
|
|
this.$cookies.set('auth-token-reset', true)
|
|
// If users logs out on dashboard, force redirect on the home page to clear cookies
|
|
if (this.$route.path.startsWith('/settings')) {
|
|
window.location.href = '/'
|
|
} else {
|
|
await this.$router.go(null)
|
|
|
|
this.$notify({
|
|
group: 'main',
|
|
title: 'Logged Out',
|
|
text: 'You have logged out successfully!',
|
|
type: 'success',
|
|
})
|
|
}
|
|
},
|
|
changeTheme() {
|
|
this.$colorMode.preference =
|
|
this.$colorMode.value === 'dark' ? 'light' : 'dark'
|
|
},
|
|
removeFocus() {
|
|
document.activeElement.blur() // This doesn't work, sadly. Help
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.skip a {
|
|
clip: rect(1px, 1px, 1px, 1px);
|
|
height: 1px;
|
|
overflow: hidden;
|
|
position: absolute;
|
|
white-space: nowrap;
|
|
width: 1px;
|
|
}
|
|
|
|
.skip a:focus {
|
|
clip: auto;
|
|
height: auto;
|
|
overflow: auto;
|
|
position: absolute;
|
|
width: auto;
|
|
padding: 0.5rem 0.75rem;
|
|
background-color: var(--color-brand);
|
|
color: var(--color-brand-inverted);
|
|
border-radius: var(--size-rounded-max);
|
|
margin: 0 0.5rem 0 0;
|
|
box-shadow: inset 0px -1px 1px rgba(17, 24, 39, 0.1);
|
|
z-index: 1;
|
|
}
|
|
|
|
.layout {
|
|
min-height: 100vh;
|
|
background-color: var(--color-bg);
|
|
display: block;
|
|
|
|
@media screen and (min-width: 1024px) {
|
|
min-height: calc(100vh - var(--spacing-card-bg));
|
|
}
|
|
|
|
@media screen and (max-width: 750px) {
|
|
margin-bottom: calc(var(--size-mobile-navbar-height) + 2rem);
|
|
}
|
|
|
|
.site-header {
|
|
margin-top: var(--spacing-card-md);
|
|
margin-bottom: var(--spacing-card-md);
|
|
max-width: 100vw;
|
|
|
|
@media screen and (min-width: 1024px) {
|
|
border-radius: var(--size-rounded-sm);
|
|
max-width: 1280px;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
|
|
.navbar {
|
|
margin: 0 var(--spacing-card-lg);
|
|
padding: 0 var(--spacing-card-lg);
|
|
max-width: 1280px;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
|
|
@media screen and (max-width: 750px) {
|
|
justify-content: center;
|
|
}
|
|
|
|
section.logo {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
color: var(--color-text-dark);
|
|
|
|
a {
|
|
align-items: center;
|
|
display: flex;
|
|
}
|
|
|
|
.small-logo {
|
|
display: block;
|
|
}
|
|
|
|
svg {
|
|
height: 1.75rem;
|
|
width: auto;
|
|
}
|
|
|
|
.badge {
|
|
margin-left: 0.25rem;
|
|
display: none;
|
|
@media screen and (min-width: 430px) {
|
|
display: unset;
|
|
}
|
|
}
|
|
|
|
button {
|
|
background: none;
|
|
border: none;
|
|
margin: 0 0 0 0.5rem;
|
|
padding: 0;
|
|
|
|
svg {
|
|
height: 1.5rem;
|
|
width: 1.5rem;
|
|
}
|
|
}
|
|
}
|
|
|
|
section.nav-group {
|
|
display: flex;
|
|
flex-grow: 5;
|
|
|
|
section.nav {
|
|
flex-grow: 5;
|
|
|
|
.styled-tabs {
|
|
display: flex;
|
|
position: relative;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
margin-top: 3px;
|
|
margin-left: 2rem;
|
|
|
|
a {
|
|
margin-left: 0;
|
|
margin-right: auto;
|
|
}
|
|
|
|
a.tab {
|
|
padding: 0;
|
|
margin-right: 1rem;
|
|
display: flex;
|
|
align-items: flex-start;
|
|
|
|
&--alpha::after {
|
|
content: 'Alpha';
|
|
background-color: var(--color-warning-bg);
|
|
color: var(--color-warning-text);
|
|
border-radius: 1rem;
|
|
padding: 0.25rem 0.5rem;
|
|
margin-left: 0.4rem;
|
|
font-size: 0.7rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.user-outer {
|
|
z-index: 20;
|
|
}
|
|
|
|
section.user-controls {
|
|
align-items: center;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
position: relative;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
min-width: 12rem;
|
|
|
|
.control-button {
|
|
display: flex;
|
|
max-width: 2rem;
|
|
padding: 0.5rem;
|
|
background-color: var(--color-raised-bg);
|
|
border-radius: var(--size-rounded-max);
|
|
margin: 0 0.5rem 0 0;
|
|
box-shadow: inset 0px -1px 1px rgba(17, 24, 39, 0.1);
|
|
|
|
&:hover,
|
|
&:focus-visible {
|
|
background-color: var(--color-button-bg-hover);
|
|
color: var(--color-button-text-hover);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(--color-button-bg-active);
|
|
color: var(--color-button-text-active);
|
|
}
|
|
|
|
svg {
|
|
height: 1rem;
|
|
width: 1rem;
|
|
}
|
|
|
|
.bubble {
|
|
position: absolute;
|
|
margin-left: 0.5rem;
|
|
bottom: 1rem;
|
|
border-radius: 0.9rem;
|
|
height: 0.8rem;
|
|
padding: 0 0.25rem;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
font-size: 0.6rem;
|
|
background-color: var(--color-brand);
|
|
color: var(--color-brand-inverted);
|
|
}
|
|
}
|
|
|
|
.hide-desktop {
|
|
display: none;
|
|
}
|
|
|
|
.dropdown {
|
|
position: relative;
|
|
|
|
.control {
|
|
align-items: center;
|
|
background: none;
|
|
display: flex;
|
|
justify-content: center;
|
|
padding: 0;
|
|
|
|
.user-icon {
|
|
border-radius: 100%;
|
|
height: 2rem;
|
|
outline: 2px solid var(--color-raised-bg);
|
|
width: 2rem;
|
|
}
|
|
|
|
.caret {
|
|
color: inherit;
|
|
margin-left: 0.25rem;
|
|
width: 1rem;
|
|
}
|
|
}
|
|
|
|
.content {
|
|
border: 1px solid var(--color-divider-dark);
|
|
list-style: none;
|
|
margin: 0.5rem 0 0 0;
|
|
max-width: 25rem;
|
|
min-width: 12rem;
|
|
opacity: 0;
|
|
padding: 1rem;
|
|
position: absolute;
|
|
right: -1rem;
|
|
transform: scaleY(0.9);
|
|
transform-origin: top;
|
|
transition: all 0.1s ease-in-out 0.05s, color 0s ease-in-out 0s,
|
|
background-color 0s ease-in-out 0s,
|
|
border-color 0s ease-in-out 0s;
|
|
visibility: hidden;
|
|
width: max-content;
|
|
z-index: 1;
|
|
|
|
.divider {
|
|
background-color: var(--color-divider-dark);
|
|
border: none;
|
|
color: var(--color-divider-dark);
|
|
height: 1px;
|
|
margin: 0.5rem 0;
|
|
}
|
|
|
|
.item {
|
|
align-items: center;
|
|
background: none;
|
|
border-radius: 0.5rem;
|
|
box-sizing: border-box;
|
|
color: inherit;
|
|
display: flex;
|
|
padding: 0.5rem;
|
|
width: 100%;
|
|
|
|
.icon {
|
|
margin-right: 0.5rem;
|
|
height: 20px;
|
|
width: 20px;
|
|
}
|
|
}
|
|
|
|
.item:hover,
|
|
.item:focus {
|
|
background-color: var(--color-bg);
|
|
}
|
|
|
|
.profile-link {
|
|
.prompt {
|
|
margin-top: 0.25rem;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 1300px) {
|
|
.content {
|
|
margin-right: 1rem;
|
|
}
|
|
}
|
|
}
|
|
|
|
.dropdown:hover .user-icon,
|
|
.dropdown:focus .user-icon,
|
|
.dropdown:focus-within .user-icon {
|
|
outline-color: var(--color-raised-bg-hover);
|
|
}
|
|
|
|
.dropdown:hover .content {
|
|
opacity: 1;
|
|
transform: scaleY(1);
|
|
visibility: visible;
|
|
}
|
|
}
|
|
|
|
section.auth-prompt {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 100%;
|
|
margin: 0;
|
|
|
|
.log-in-button {
|
|
margin: 0 auto;
|
|
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
text-align: center;
|
|
border-radius: var(--size-rounded-max);
|
|
background-color: var(--color-brand);
|
|
white-space: nowrap;
|
|
//outline: none; Bad for accessibility
|
|
color: var(--color-brand-inverted);
|
|
padding: 0.5rem 0.75rem;
|
|
|
|
svg {
|
|
vertical-align: middle;
|
|
margin-right: 0.5rem;
|
|
}
|
|
|
|
&:hover,
|
|
&:focus {
|
|
background-color: var(--color-brand-hover);
|
|
}
|
|
|
|
&:active {
|
|
background-color: var(--color-brand-active);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 750px) {
|
|
section.nav-group {
|
|
display: none;
|
|
|
|
.hide-desktop {
|
|
display: unset;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.mobile-navbar {
|
|
display: none;
|
|
width: 100%;
|
|
transition: height 0.25s ease-in-out;
|
|
height: var(--size-mobile-navbar-height);
|
|
position: fixed;
|
|
left: 0;
|
|
bottom: 0;
|
|
background-color: var(--color-raised-bg);
|
|
box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.3);
|
|
z-index: 6;
|
|
flex-direction: column;
|
|
border-radius: var(--size-rounded-card) var(--size-rounded-card) 0 0;
|
|
|
|
overflow: hidden;
|
|
|
|
.tab {
|
|
background: none;
|
|
display: flex;
|
|
flex-basis: 0;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-direction: row;
|
|
gap: 0.25rem;
|
|
font-weight: bold;
|
|
padding: 0;
|
|
transition: color ease-in-out 0.15s;
|
|
color: var(--color-text-inactive);
|
|
text-align: center;
|
|
|
|
svg {
|
|
height: 1.75rem;
|
|
width: 1.75rem;
|
|
}
|
|
|
|
&:hover,
|
|
&:focus {
|
|
color: var(--color-text);
|
|
}
|
|
|
|
&.nuxt-link-exact-active {
|
|
svg {
|
|
color: var(--color-brand);
|
|
}
|
|
|
|
color: var(--color-text);
|
|
}
|
|
}
|
|
|
|
.top-row {
|
|
min-height: var(--size-mobile-navbar-height);
|
|
display: flex;
|
|
width: 100%;
|
|
|
|
.browse {
|
|
flex-grow: 10;
|
|
|
|
svg {
|
|
transition: transform 0.125s ease-in-out;
|
|
|
|
&.closed {
|
|
transform: rotate(180deg);
|
|
}
|
|
}
|
|
}
|
|
|
|
.tab {
|
|
&:first-child {
|
|
margin-left: 2rem;
|
|
}
|
|
|
|
&:last-child {
|
|
margin-right: 2rem;
|
|
}
|
|
}
|
|
|
|
.spacer {
|
|
flex-grow: 1;
|
|
}
|
|
}
|
|
|
|
.disable-childern {
|
|
a {
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
.project-types {
|
|
margin-top: 0.5rem;
|
|
display: flex;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
row-gap: 0.5rem;
|
|
|
|
.tab {
|
|
flex: 0 0 fit-content;
|
|
background-color: var(--color-button-bg);
|
|
padding: 0.5rem 1.25rem;
|
|
margin: 0 0.25rem;
|
|
border-radius: var(--size-rounded-max);
|
|
|
|
&.nuxt-link-exact-active {
|
|
background-color: var(--color-brand);
|
|
color: var(--color-brand-inverted);
|
|
}
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 750px) {
|
|
display: flex;
|
|
}
|
|
|
|
&.expanded {
|
|
height: var(--size-mobile-navbar-height-expanded);
|
|
}
|
|
}
|
|
}
|
|
|
|
.mobile-menu {
|
|
display: none;
|
|
position: absolute;
|
|
top: 0;
|
|
background-color: var(--color-bg);
|
|
height: 100%;
|
|
width: 100%;
|
|
z-index: 5;
|
|
|
|
.mobile-menu-wrapper {
|
|
max-height: calc(100vh - var(--size-mobile-navbar-height));
|
|
margin-bottom: var(--size-mobile-navbar-height);
|
|
overflow-y: auto;
|
|
margin-top: auto;
|
|
|
|
.items-container {
|
|
margin: 1rem 2rem;
|
|
|
|
button {
|
|
box-sizing: unset;
|
|
}
|
|
|
|
.item {
|
|
padding: 1rem 2rem;
|
|
background-color: var(--color-raised-bg);
|
|
border-radius: var(--size-rounded-md);
|
|
align-items: center;
|
|
justify-content: center;
|
|
display: flex;
|
|
column-gap: 0.25rem;
|
|
width: calc(100% - 4rem);
|
|
max-width: 18rem;
|
|
|
|
&.nuxt-link-exact-active {
|
|
color: var(--color-button-text-active);
|
|
|
|
svg {
|
|
color: var(--color-brand);
|
|
}
|
|
}
|
|
|
|
&.log-in {
|
|
color: var(--color-brand-inverted);
|
|
background-color: var(--color-brand);
|
|
}
|
|
|
|
&.log-out {
|
|
color: white;
|
|
background-color: var(--color-badge-red-bg);
|
|
}
|
|
|
|
&.user-item {
|
|
flex-direction: column;
|
|
row-gap: 0.5rem;
|
|
//width: 8rem;
|
|
max-width: 18rem;
|
|
flex-grow: 0;
|
|
|
|
.profile-link {
|
|
text-align: center;
|
|
|
|
.prompt {
|
|
color: var(--color-text-secondary);
|
|
}
|
|
}
|
|
|
|
.user-icon {
|
|
width: 4rem;
|
|
height: 4rem;
|
|
border-radius: var(--size-rounded-max);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
div {
|
|
flex-grow: 1;
|
|
justify-content: end;
|
|
align-items: center;
|
|
row-gap: 1rem;
|
|
}
|
|
|
|
&.active {
|
|
display: flex;
|
|
|
|
@media screen and (min-width: 750px) {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
main {
|
|
grid-area: main;
|
|
}
|
|
|
|
footer {
|
|
margin: 6rem 0 2rem 0;
|
|
text-align: center;
|
|
display: grid;
|
|
grid-template:
|
|
'logo-info logo-info' auto
|
|
'links-1 links-2' auto
|
|
'buttons buttons' auto
|
|
/ 1fr 1fr;
|
|
|
|
.logo-info {
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
max-width: 20rem;
|
|
margin-bottom: 1rem;
|
|
grid-area: logo-info;
|
|
|
|
.text-logo {
|
|
width: 10rem;
|
|
height: auto;
|
|
}
|
|
}
|
|
|
|
.links {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin-bottom: 1rem;
|
|
|
|
h4 {
|
|
color: var(--color-text-dark);
|
|
margin: 0 0 1rem 0;
|
|
}
|
|
|
|
a {
|
|
margin: 0 0 1rem 0;
|
|
}
|
|
|
|
&.links-1 {
|
|
grid-area: links-1;
|
|
}
|
|
|
|
&.links-2 {
|
|
grid-area: links-2;
|
|
}
|
|
}
|
|
|
|
.buttons {
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
grid-area: buttons;
|
|
|
|
button,
|
|
a {
|
|
background-color: var(--color-raised-bg);
|
|
|
|
margin-bottom: 0.5rem;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
|
|
&:hover,
|
|
&:focus-visible {
|
|
background-color: var(--color-button-bg-hover);
|
|
}
|
|
}
|
|
}
|
|
|
|
@media screen and (min-width: 1024px) {
|
|
display: flex;
|
|
text-align: unset;
|
|
|
|
.logo-info {
|
|
margin-right: 2rem;
|
|
}
|
|
|
|
.links {
|
|
margin-right: 2rem;
|
|
}
|
|
|
|
.buttons {
|
|
width: unset;
|
|
margin-left: 0;
|
|
|
|
button,
|
|
a {
|
|
margin-right: unset;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1024px) {
|
|
.layout {
|
|
main {
|
|
.alpha-alert {
|
|
margin: 1rem;
|
|
|
|
.wrapper {
|
|
padding: 1rem 2rem 1rem 1rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|