.
Some checks failed
Publish to OCI Registry / publish (push) Has been cancelled
Testing / test (pull_request) Has been cancelled
Testing / test (push) Waiting to run

This commit is contained in:
Mrrp 2025-03-05 22:34:37 -08:00
parent 36576a27f3
commit c2095d0b13
29 changed files with 5941 additions and 0 deletions

View file

@ -0,0 +1,5 @@
<template>
<div class="rounded-lg bg-surface-1 transition-colors ease-in-out duration-300 p-4 m-2">
<slot></slot>
</div>
</template>

View file

@ -0,0 +1,15 @@
<script setup>
const props = defineProps({
color: String,
});
</script>
<template>
<button
:class='"border-none w-full text-black rounded-full bg-gradient-to-r opacity-80 hover:opacity-100 duration-200 transition-all" +
" from-" + props.color + "-300 " + "to-" + props.color + "-200"'>
<slot></slot>
</button>
</template>

View file

@ -0,0 +1,24 @@
<script setup>
import Card from './Card.vue';
// Slots (Header, Body, Footer)
const props = defineProps({
color: String,
cardClass: String
});
const slots = defineSlots();
</script>
<template>
<Card :class='props.cardClass + " flex justify-center flex-col border-2 border-" + props.color'>
<slot name="header"></slot>
<slot></slot>
<div class="flex w-full h-full">
<div class="self-end w-full flex justify-center">
<slot name="footer"></slot>
</div>
</div>
</Card>
</template>

View file

@ -0,0 +1,5 @@
<template>
<div class="rounded-lg bg-surface-0 transition-colors ease-in-out border border-border duration-300 p-2 m-2">
<slot></slot>
</div>
</template>

View file

@ -0,0 +1,108 @@
<template>
</template>
<script>
export default {
data() {
return {
// Define color steps (100, 200, ..., 900, 950)
colorSteps: [100, 200, 300, 400, 500, 600, 700, 800, 900, 950],
// Store computed colors
computedColors: {},
requestedColorNames: [
'--color-surface-0',
'--color-surface-1',
'--color-surface-2',
'--color-text',
'--color-accent',
'--color-accent-hover',
'--color-border',
'--color-rosewater',
'--color-flamingo',
'--color-pink',
'--color-mauve',
'--color-red',
'--color-maroon',
'--color-peach',
'--color-yellow',
'--color-teal',
'--color-sky',
'--color-sapphire',
'--color-blue',
'--color-lavender',
'--color-overlay-0',
'--color-overlay-1',
'--color-overlay-2'
]
};
},
mounted() {
this.computeColors();
},
methods: {
// Method to fetch the CSS variable and convert it to HSL, then adjust lightness
rgbToHsl(r, g, b) {
r /= 255;
g /= 255;
b /= 255;
let max = Math.max(r, g, b);
let min = Math.min(r, g, b);
let h = 0, s = 0, l = (max + min) / 2;
if (max !== min) {
let d = max - min;
s = (l > 0.5) ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h * 360, s * 100, l * 100]; // Return in degrees for hue and percentages for saturation and lightness
},
// Method to compute the color adjustments (lightness + hue)
computeColors() {
// Loop through each requested color
this.requestedColorNames.forEach((name) => {
this.colorSteps.forEach((step) => {
// Fetch the RGB color from the root CSS variable
const color = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
if (!color) {
console.log(`Color ${name} not found`);
return;
}
// Extract RGB values from the color string (either #rrggbb or rgb(r, g, b))
let r, g, b;
if (color.startsWith('rgb')) {
[r, g, b] = color.match(/\d+/g).map(Number);
} else if (color.startsWith('#')) {
r = parseInt(color.slice(1, 3), 16);
g = parseInt(color.slice(3, 5), 16);
b = parseInt(color.slice(5, 7), 16);
}
// Convert the RGB values to HSL
const [hue, saturation, lightness] = this.rgbToHsl(r, g, b);
// Adjust the lightness based on the step (100-900 + 950)
const adjustedLightness = 100 - (step / 10);
// Update the computed color for the current step
this.computedColors[step] = `hsl(${hue}, ${saturation}%, ${adjustedLightness}%)`;
// Dynamically update the CSS variable for this color
document.documentElement.style.setProperty(`${name}-${step}`, this.computedColors[step]);
});
});
}
}
};
</script>

View file

@ -0,0 +1,5 @@
<template>
<div class="flex justify-center">
<slot></slot>
</div>
</template>

View file

@ -0,0 +1,34 @@
<script setup lang="ts">
// Modal.vue
// Assume component existing means it's open
// Closing a modal emits a close event
// Ensure everything outside of modal gets darkened to 80% opacity
const emit = defineEmits(['close']);
</script>
<template>
<div>
<div class="modal-overlay" @click="emit('close')">
<div class="modal-content max-w-[50rem]" @click.stop>
<slot></slot>
</div>
</div>
</div>
</template>
<style>
.modal-overlay {
@apply fixed top-0 left-0 flex justify-center w-screen h-screen;
background-color: rgba(0, 0, 0, 0.2);
overflow: scroll;
}
.modal-content {
@apply bg-overlay-0 max-h-[48rem];
padding: 1rem;
border-radius: 0.5rem;
overflow: scroll;
}
</style>

View file

@ -0,0 +1,56 @@
<script setup lang="ts">
const theme: Ref<string> = ref("mocha");
import Card from './Card.vue';
onBeforeMount(() => {
theme.value = localStorage.getItem("theme") || "mocha";
document.documentElement.setAttribute("data-theme", theme.value);
});
const availableThemes = [
"mocha",
"latte",
"yule-night",
"yule-day",
"midsummer-twilight",
"midsummer-daylight",
"fireworks-night",
"parade-day",
"harvest-twilight",
"golden-hour",
"stargazer",
"daydreamer",
];
const changeTheme = (newTheme: string) => {
theme.value = newTheme;
document.documentElement.setAttribute("data-theme", newTheme);
localStorage.setItem("theme", newTheme);
};
</script>
<template>
<nav class="flex justify-center">
<Card class="flex flex-wrap justify-center max-w-[40rem] border border-border">
<NuxtLink to="/">Home</NuxtLink>
<NuxtLink to="/servers">Servers</NuxtLink>
<NuxtLink to="/diagnostics">Diagnostics</NuxtLink>
<NuxtLink to="/projects">Projects</NuxtLink>
<a href="https://vtt.smgames.club" target="_blank">Foundry VTT</a>
<a href="https://oekaki.smgames.club" target="_blank">Oekaki</a>
<a href="https://social.smgames.club/" target="_blank">Social</a>
<a href="https://madstar.studio" target="_blank">Shop</a>
<!-- Icon inline dropdown for theme switching (use paint palette icon) -->
<!-- Only show an icon, no title or label -->
<select v-model="theme" @change="changeTheme(theme)">
<option v-for="t in availableThemes" :key="t" :value="t">{{ t }}</option>
</select>
<HueComputer :key=theme />
</Card>
</nav>
</template>
<style>
a {
@apply m-2
}
</style>