Color-Mode

UX Feature


Component

The brightness mode component, @/components/ui/ColorMode.vue is invoked by <ShipBow />:

<!--------@/components/ship/ColorMode.vue-------------------------------------->
<template>
  <ClientOnly>
    <UButton
        class="h-fit mr-1 ml-0 pl-0"
        :icon="isDark ? 'i-heroicons-sun-20-solid' : 'i-heroicons-moon-20-solid'"
        variant="link"
        :aria-label="isDark ? 'Switch to light mode' : 'Switch to dark mode'"
        @click="isDark = !isDark"
        :ui="{
            leadingIcon: 'text-(--ui-text) size-8 align-bottom'
         }"
    />
  </ClientOnly>
</template>

<script setup lang="ts">
const colorMode = useColorMode()
const isDark = computed({
  get () {
    return colorMode.value === 'dark'
  },
  set () {
    colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
  }
})
</script>
<!--------@/components/ship/ColorMode.vue-------------------------------------->

Images

Original Image

Original Raster Image

The original logo was designed for a site with a white background. With support for dark-mode implemented, the original image was visually jarring against the black background. It either had to be rendered with the blacks and whites reversed (colors preserved), or swapped with a dark mode image. Using a single file instead of two, reduces initial page load size, and reduces asset count for maint, loading and caching.

Filtered Image

These utility filters were configured to support dark mode using one image:

<img
    src="/images/hero/logo.png"
    class="dark:invert dark:hue-rotate-180"
/>

To create the rectangular logo, the non-text areas of the raster image were converted to paths and saved as vector. Then the text layers were added.

The non-text areas of the raster image was converted to vector by a bitmap trace using brightness cutoff and edge detection, prioritizing sharp edges. Barnacle nodes were removed, and the path was simplified. Unnecessary nodes were eliminated, and curves were smoothed using the node tool.

The original logo was created with proprietary image editing software, using private fonts. A similar, open-source font was found for the text, 'SAVE THE GROVE...'. For Again, no matching free font was found.

To recreate the 'Again` text, a bitmap-traced path was extracted the same way as for the non text area. The path was then modified, node-by-node, until the letters matched the ones in the original image.

The resulting image is resolution-agnostic, and supports CSS styling, including dynamic stroke and fill.

TODO: Create tags for dynamic fills. For now, use an alternate dark-mode version.

Copyright @ 2025 Anne Brown