The stored `colors` key names a palette — rhema (the default, Jadeite), aquamarine, black-and-white, or dracula — and the Appearance page of /settings cycles it live, like the theme and icon toggles beside it. Each palette carries a dark and a light appearance under the existing `theme` key; dracula's light side is derived, the official palette ships only dark. The appearance decision moves off token comparison: Theme now answers is_dark() from the ground/text luminance, so palettes beyond the original two get the right per-profile fallback tones.
51 lines
1.0 KiB
Vue
51 lines
1.0 KiB
Vue
<script setup lang="ts">
|
||
// The one banner surface: claw down, auth required, stream drops. An
|
||
// inline band, dismissible when the caller allows it.
|
||
defineProps<{
|
||
variant: 'error' | 'warn' | 'info'
|
||
dismissible?: boolean
|
||
}>()
|
||
|
||
defineEmits<{ dismiss: [] }>()
|
||
</script>
|
||
|
||
<template>
|
||
<div class="banner" :class="variant" role="status">
|
||
<span class="banner-mark" aria-hidden="true">{{
|
||
variant === 'error' ? '✗' : variant === 'warn' ? '△' : '·'
|
||
}}</span>
|
||
<span class="banner-text"><slot /></span>
|
||
<slot name="actions" />
|
||
<button v-if="dismissible" class="banner-dismiss" title="dismiss" @click="$emit('dismiss')">
|
||
×
|
||
</button>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.banner-mark {
|
||
color: inherit;
|
||
flex: none;
|
||
}
|
||
|
||
.banner.error .banner-mark {
|
||
color: var(--error);
|
||
}
|
||
|
||
.banner.warn .banner-mark {
|
||
color: var(--warn);
|
||
}
|
||
|
||
.banner.info .banner-mark {
|
||
color: var(--info);
|
||
}
|
||
|
||
.banner-dismiss {
|
||
padding: 0 8px;
|
||
border: none;
|
||
background: none;
|
||
color: var(--text3);
|
||
font-size: 14px;
|
||
}
|
||
</style>
|