+
+
+
-
-
-
-
-
-
-
-
-
+
+ {{ route.fullPath }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ criticalErrorMessage.header }}
+
-
+
@@ -394,31 +601,61 @@ async function checkUpdates() {
justify-content: center;
cursor: pointer;
transition: all ease-in-out 0.1s;
- background-color: var(--color-raised-bg);
+ background-color: transparent;
color: var(--color-base);
- border-radius: 0;
- height: 3.25rem;
+ height: 100%;
+ width: 3rem;
+ position: relative;
+ box-shadow: none;
+
+ &:last-child {
+ padding-right: 0.75rem;
+ width: 3.75rem;
+ }
+
+ svg {
+ width: 1.25rem;
+ height: 1.25rem;
+ }
+
+ &::before {
+ content: '';
+ border-radius: 999999px;
+ width: 3rem;
+ height: 3rem;
+ aspect-ratio: 1 / 1;
+ margin-block: auto;
+ position: absolute;
+ background-color: transparent;
+ scale: 0.9;
+ transition: all ease-in-out 0.2s;
+ z-index: -1;
+ }
&.close {
&:hover,
&:active {
- background-color: var(--color-red);
color: var(--color-accent-contrast);
+
+ &::before {
+ background-color: var(--color-red);
+ }
}
}
&:hover,
&:active {
- background-color: var(--color-button-bg);
color: var(--color-contrast);
+
+ &::before {
+ background-color: var(--color-button-bg);
+ scale: 1;
+ }
}
}
}
.app-container {
- --appbar-height: 3.25rem;
- --sidebar-width: 4.5rem;
-
height: 100vh;
display: flex;
flex-direction: row;
@@ -546,16 +783,139 @@ async function checkUpdates() {
padding: var(--gap-sm) 0;
}
}
+
+.app-grid-layout,
+.app-contents {
+ --top-bar-height: 3.75rem;
+ --left-bar-width: 5rem;
+ --right-bar-width: 300px;
+}
+
+.app-grid-layout {
+ display: grid;
+ grid-template: 'status status' 'nav dummy';
+ grid-template-columns: auto 1fr;
+ grid-template-rows: auto 1fr;
+ position: relative;
+ //z-index: 0;
+ background-color: var(--color-raised-bg);
+ height: 100vh;
+}
+
+.app-grid-navbar {
+ grid-area: nav;
+}
+
+.app-grid-statusbar {
+ grid-area: status;
+}
+
+.app-contents {
+ position: absolute;
+ z-index: 1;
+ left: 5rem;
+ top: 3.75rem;
+ right: 0;
+ bottom: 0;
+ height: calc(100vh - 3.75rem);
+ background-color: var(--color-bg);
+ border-top-left-radius: var(--radius-xl);
+
+ display: grid;
+ grid-template-columns: 1fr 300px;
+ //grid-template-columns: 1fr 0px;
+ transition: grid-template-columns 0.4s ease-in-out;
+}
+
+.loading-indicator-container {
+ border-top-left-radius: var(--radius-xl);
+ overflow: hidden;
+}
+
+.app-sidebar {
+ overflow: visible;
+ width: 300px;
+ position: relative;
+ height: calc(100vh - 3.75rem);
+ background: var(--brand-gradient-bg);
+
+ --color-button-bg: var(--brand-gradient-button);
+ --color-button-bg-hover: var(--brand-gradient-border);
+ --color-divider: var(--brand-gradient-border);
+ --color-divider-dark: var(--brand-gradient-border);
+}
+
+.app-sidebar::after {
+ content: '';
+ position: absolute;
+ bottom: 250px;
+ left: 0;
+ right: 0;
+ height: 5rem;
+ background: var(--brand-gradient-fade-out-color);
+ pointer-events: none;
+}
+
+.app-sidebar.has-plus::after {
+ display: none;
+}
+
+.app-sidebar::before {
+ content: '';
+ box-shadow: -15px 0 15px -15px rgba(0, 0, 0, 0.2) inset;
+ top: 0;
+ bottom: 0;
+ left: -2rem;
+ width: 2rem;
+ position: absolute;
+ pointer-events: none;
+}
+
+.app-viewport {
+ flex-grow: 1;
+ height: 100%;
+ overflow: auto;
+ overflow-x: hidden;
+}
+
+//::-webkit-scrollbar-track {
+// background-color: transparent; /* Make it transparent if needed */
+// margin-block: 5px;
+// margin-right: 5px;
+//}
+
+.app-contents::before {
+ z-index: 1;
+ content: '';
+ position: fixed;
+ left: 5rem;
+ top: 3.75rem;
+ right: -5rem;
+ bottom: -5rem;
+ border-radius: var(--radius-xl);
+ //box-shadow: 1px 1px 15px rgba(0, 0, 0, 0.2) inset;
+ box-shadow:
+ 1px 1px 15px rgba(0, 0, 0, 0.2) inset,
+ inset 1px 1px 1px rgba(255, 255, 255, 0.23);
+ pointer-events: none;
+}
+
+.sidebar-teleport-content {
+ display: contents;
+}
+
+.sidebar-default-content {
+ display: none;
+}
+
+.sidebar-teleport-content:empty + .sidebar-default-content {
+ display: contents;
+}
diff --git a/apps/app-frontend/src/components/RowDisplay.vue b/apps/app-frontend/src/components/RowDisplay.vue
index 3c333cc5f..06891b0e1 100644
--- a/apps/app-frontend/src/components/RowDisplay.vue
+++ b/apps/app-frontend/src/components/RowDisplay.vue
@@ -260,7 +260,6 @@ onUnmounted(() => {
align-items: center;
justify-content: center;
width: 100%;
- padding: 1rem;
gap: 1rem;
-ms-overflow-style: none;
@@ -294,16 +293,16 @@ onUnmounted(() => {
a {
margin: 0;
- font-size: var(--font-size-lg);
+ font-size: var(--font-size-md);
font-weight: bolder;
white-space: nowrap;
- color: var(--color-contrast);
+ color: var(--color-base);
}
svg {
- height: 1.5rem;
- width: 1.5rem;
- color: var(--color-contrast);
+ height: 1.25rem;
+ width: 1.25rem;
+ color: var(--color-base);
}
}
diff --git a/apps/app-frontend/src/components/modrinth-loading-indicator.js b/apps/app-frontend/src/components/modrinth-loading-indicator.js
deleted file mode 100644
index 27b0c3a3f..000000000
--- a/apps/app-frontend/src/components/modrinth-loading-indicator.js
+++ /dev/null
@@ -1,136 +0,0 @@
-import { computed, defineComponent, h, onBeforeUnmount, ref, watch } from 'vue'
-import { useLoading } from '@/store/state.js'
-
-export default defineComponent({
- props: {
- throttle: {
- type: Number,
- default: 50,
- },
- duration: {
- type: Number,
- default: 500,
- },
- height: {
- type: Number,
- default: 3,
- },
- color: {
- type: [String, Boolean],
- default:
- 'repeating-linear-gradient(to right, var(--color-brand) 0%, var(--color-brand) 100%)',
- },
- offsetWidth: {
- type: String,
- default: '208px',
- },
- offsetHeight: {
- type: String,
- default: '52px',
- },
- },
- setup(props, { slots }) {
- const indicator = useLoadingIndicator({
- duration: props.duration,
- throttle: props.throttle,
- })
-
- onBeforeUnmount(() => indicator.clear)
-
- const loading = useLoading()
-
- watch(loading, (newValue) => {
- if (newValue.barEnabled) {
- if (newValue.loading) {
- indicator.start()
- } else {
- indicator.finish()
- }
- }
- })
-
- return () =>
- h(
- 'div',
- {
- style: {
- position: 'fixed',
- top: props.offsetHeight,
- right: 0,
- left: props.offsetWidth,
- pointerEvents: 'none',
- width: `calc((100vw - ${props.offsetWidth}) * ${indicator.progress.value / 100})`,
- height: `${props.height}px`,
- opacity: indicator.isLoading.value ? 1 : 0,
- background: props.color || undefined,
- backgroundSize: `${(100 / indicator.progress.value) * 100}% auto`,
- transition: 'width 0.1s, height 0.4s, opacity 0.4s',
- zIndex: 6,
- },
- },
- slots,
- )
- },
-})
-
-function useLoadingIndicator(opts) {
- const progress = ref(0)
- const isLoading = ref(false)
- const step = computed(() => 10000 / opts.duration)
-
- let _timer = null
- let _throttle = null
-
- function start() {
- clear()
- progress.value = 0
- if (opts.throttle) {
- _throttle = setTimeout(() => {
- isLoading.value = true
- _startTimer()
- }, opts.throttle)
- } else {
- isLoading.value = true
- _startTimer()
- }
- }
- function finish() {
- progress.value = 100
- _hide()
- }
-
- function clear() {
- clearInterval(_timer)
- clearTimeout(_throttle)
- _timer = null
- _throttle = null
- }
-
- function _increase(num) {
- progress.value = Math.min(100, progress.value + num)
- }
-
- function _hide() {
- clear()
- setTimeout(() => {
- isLoading.value = false
- setTimeout(() => {
- progress.value = 0
- }, 400)
- }, 500)
- }
-
- function _startTimer() {
- _timer = setInterval(() => {
- _increase(step.value)
- }, 100)
- }
-
- return {
- progress,
- isLoading,
- start,
- finish,
- clear,
- }
-}
diff --git a/apps/app-frontend/src/components/ui/AccountsCard.vue b/apps/app-frontend/src/components/ui/AccountsCard.vue
index 50080490d..fe1defb0f 100644
--- a/apps/app-frontend/src/components/ui/AccountsCard.vue
+++ b/apps/app-frontend/src/components/ui/AccountsCard.vue
@@ -2,19 +2,23 @@
-
-
diff --git a/apps/app-frontend/src/components/ui/ContextMenu.vue b/apps/app-frontend/src/components/ui/ContextMenu.vue
index 9614d3fe0..a0ca9417e 100644
--- a/apps/app-frontend/src/components/ui/ContextMenu.vue
+++ b/apps/app-frontend/src/components/ui/ContextMenu.vue
@@ -25,7 +25,6 @@
+
+
+
+
+
+
+
+
+
+
+ {{ formatCategory(instance.loader) }} {{ instance.game_version }}
+
+
+
+
+
+
+ Back to instance
+
+
+
+
+
+
diff --git a/apps/app-frontend/src/components/ui/JavaDetectionModal.vue b/apps/app-frontend/src/components/ui/JavaDetectionModal.vue
index c5209625c..c5a7aca53 100644
--- a/apps/app-frontend/src/components/ui/JavaDetectionModal.vue
+++ b/apps/app-frontend/src/components/ui/JavaDetectionModal.vue
@@ -73,8 +73,6 @@ function setJavaInstall(javaInstall) {
diff --git a/apps/app-frontend/src/components/ui/NavTabs.vue b/apps/app-frontend/src/components/ui/NavTabs.vue
new file mode 100644
index 000000000..fa739af38
--- /dev/null
+++ b/apps/app-frontend/src/components/ui/NavTabs.vue
@@ -0,0 +1,164 @@
+
+
+
+
+
+
diff --git a/apps/app-frontend/src/components/ui/PromotionWrapper.vue b/apps/app-frontend/src/components/ui/PromotionWrapper.vue
index 69b540652..a9a6a6fba 100644
--- a/apps/app-frontend/src/components/ui/PromotionWrapper.vue
+++ b/apps/app-frontend/src/components/ui/PromotionWrapper.vue
@@ -1,75 +1,23 @@
-
+
75% of ad revenue goes to creators