2024-12-15 23:07:09 +00:00
< script setup >
import { color } from "~/composables/colors.ts"
import Button from "~/components/ui/Button.vue"
import Card from "~/components/ui/Card.vue"
2024-12-17 18:04:23 +00:00
import Link from "~/components/ui/Link.vue"
2024-12-16 12:18:29 +00:00
import Layout from "~/components/ui/Layout.vue"
2024-12-17 18:04:23 +00:00
import Alert from "~/components/ui/Alert.vue"
2024-12-16 12:18:29 +00:00
import Spacer from "~/components/ui/layout/Spacer.vue"
2024-12-15 23:07:09 +00:00
< / script >
2024-12-17 18:04:23 +00:00
< Link disabled to = "#theme-color-definitions" > Want to fix colors?< / Link >
< Link solid primary to = "#change-a-color-value" > Change a color value< / Link >
< Link solid primary to = "#alter-the-shade-of-a-color" > Alter the shade of a color< / Link >
< Link solid primary to = "#choose-a-different-style-for-a-specific-variant" > Modify a specific variant< / Link >
2024-12-06 12:54:17 +00:00
# Using Color
2024-12-15 23:07:09 +00:00
## Add color via props
[Alerts ](components/ui/alert ) support [Pastel ](#pastel ) attributes. [Buttons ](components/ui/button ) accept [Color ](#color ) and [Variant ](#variant ) attributes. [Cards ](components/ui/card ) accept [Pastel ](#pastel ), [Variant ](#variant ), [Neutral ](#neutral ) and [Raised ](#raised ) attributes.
2024-12-16 12:18:29 +00:00
< Layout flex >
2024-12-15 23:07:09 +00:00
```vue-html
2024-12-16 12:18:29 +00:00
< Card solid red title = '🌈' / >
2024-12-15 23:07:09 +00:00
```
2024-12-16 12:18:29 +00:00
< div class = "preview" >
< Card solid red title = '🌈' / >
< / div >
< / Layout >
2024-12-15 23:07:09 +00:00
## Add color to a any component or Html tag
2024-12-16 12:18:29 +00:00
1. Choose either:
2024-12-15 23:07:09 +00:00
- [base color ](#colors ) (`primary | secondary | destructive`) or
- [pastel color ](#pastel ) (`blue | red | green | yellow`) or
- [neutral beige or gray ](#neutral ) (`default`) for surfaces
2. Choose a [variant ](#color-variants ) (`solid | ghost | outline`)
3. Add [interactivity and raise the surface ](#interactive-andor-raised )
2024-12-16 12:18:29 +00:00
< Layout flex >
2024-12-15 23:07:09 +00:00
```vue
< script setup >
import { color } from "~/composables/colors.ts";
< / script >
< template >
< div v-bind = "color('primary solid interactive raised')" / >
< / template >
```
2024-12-16 12:18:29 +00:00
< div class = "preview" >
< div :class = "$style.swatch" v-bind = "color('primary solid interactive raised')" / >
< / div >
< / Layout >
2024-12-15 23:07:09 +00:00
## Base colors
2024-12-16 14:04:01 +00:00
Keep most of the screen neutral. Secondary surfaces indicate actionability. Use them sparingly. Primary and destructive surfaces immediately catch the eye. Use them only once or twice per screen.
2024-12-15 23:07:09 +00:00
### Neutral
2024-12-16 14:04:01 +00:00
Use neutral colors for non-interactive surfaces
< Layout flex >
< div class = "force-dark-theme" >
< div v-bind = "color('default solid')" >
< div :class = "$style.swatch" v-bind = "color('default solid')" / >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('default solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "$style.swatch" v-bind = "color('default solid raised')" / >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('default solid raised interactive')" / >
< / div >
< / div >
< div class = "force-light-theme" >
< div v-bind = "color('default solid')" >
< div :class = "$style.swatch" v-bind = "color('default solid')" / >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('default solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "$style.swatch" v-bind = "color('default solid raised')" / >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('default solid raised interactive')" / >
< / div >
< / div >
< / Layout >
2024-12-15 23:07:09 +00:00
### Color
2024-12-16 14:04:01 +00:00
#### Primary
Only use for at most one call-to-action on a screen
< Layout flex >
< div class = "force-dark-theme" >
< div v-bind = "color('default solid')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('primary solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('primary solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('primary solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('primary solid raised interactive')" / >
< / div >
< / div >
< div class = "force-light-theme" >
< div v-bind = "color('default solid')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('primary solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('primary solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('primary solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('primary solid raised interactive')" / >
< / div >
< / div >
< / Layout >
#### Secondary
2024-12-15 23:07:09 +00:00
2024-12-17 14:19:47 +00:00
Use for interactive items and non-permanent surfaces such as menus and modals
2024-12-15 23:07:09 +00:00
2024-12-16 14:04:01 +00:00
< Layout flex >
< div class = "force-dark-theme" >
< div v-bind = "color('default solid')" >
< div :class = "$style.swatch" v-bind = "color('secondary solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('secondary solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "$style.swatch" v-bind = "color('secondary solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('secondary solid raised interactive')" / >
< / div >
< / div >
< div class = "force-light-theme" >
< div v-bind = "color('default solid')" >
< div :class = "$style.swatch" v-bind = "color('secondary solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('secondary solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "$style.swatch" v-bind = "color('secondary solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('secondary solid raised interactive')" / >
< / div >
< / div >
< / Layout >
2024-12-15 23:07:09 +00:00
2024-12-16 14:04:01 +00:00
#### Destructive
2024-12-15 23:07:09 +00:00
2024-12-16 14:04:01 +00:00
Use for dangerous actions
2024-12-15 23:07:09 +00:00
2024-12-16 14:04:01 +00:00
< Layout flex >
< div class = "force-dark-theme" >
< div v-bind = "color('default solid')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('destructive solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('destructive solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('destructive solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('destructive solid raised interactive')" / >
< / div >
< / div >
< div class = "force-light-theme" >
< div v-bind = "color('default solid')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('destructive solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('destructive solid interactive')" / >
< / div > < div v-bind = "color('default solid raised')" >
< div :class = "[$style.swatch, $style.deemphasized]" v-bind = "color('destructive solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('destructive solid raised interactive')" / >
< / div >
< / div >
< / Layout >
2024-12-15 23:07:09 +00:00
### Pastel
2024-12-16 14:04:01 +00:00
Use `Blue` , `Red` , `Purple` , `Green` , `Yellow` for user-defined tags and for friendly messages such as
Alerts
2024-12-15 23:07:09 +00:00
< div :class = "$style.swatch" v-bind = "color('blue solid interactive')" / >
< div :class = "$style.swatch" v-bind = "color('red solid interactive')" / >
< div :class = "$style.swatch" v-bind = "color('purple solid interactive')" / >
< div :class = "$style.swatch" v-bind = "color('green solid interactive')" / >
< div :class = "$style.swatch" v-bind = "color('yellow solid interactive')" / >
### Variant
2024-12-16 14:04:01 +00:00
You can de-emphasize interactive elements by hiding their background and/or outline.
`Solid` (default), `Ghost` , `Outline` :
2024-12-15 23:07:09 +00:00
< Button round shadow icon = "bi-x" solid / >
2024-12-16 14:04:01 +00:00
2024-12-15 23:07:09 +00:00
< div :class = "$style.swatch" v-bind = "color('solid raised')" >
2024-12-16 14:04:01 +00:00
< Button round icon = "bi-x" ghost / >
< Spacer / >
< Button round icon = "bi-x" outline / >
2024-12-15 23:07:09 +00:00
< / div >
< br / >
< Button round shadow icon = "bi-x" primary solid / >
2024-12-16 14:04:01 +00:00
2024-12-15 23:07:09 +00:00
< div :class = "$style.swatch" v-bind = "color('primary solid')" >
2024-12-16 14:04:01 +00:00
< Button round icon = "bi-x" primary ghost / >
< Spacer / >
< Button round icon = "bi-x" primary outline / >
2024-12-15 23:07:09 +00:00
< / div >
### Interactive and/or Raised
2024-12-16 14:04:01 +00:00
Use raised surfaces sparingly, about ¼ of the screen. Only use raised surfaces to highlight one area of a component over others. Good examples are `aside` s such as the sidebar or info-boxes.
Space out interactive surfaces.
< Layout >
< div class = "force-light-theme" >
< Layout flex >
< div >
< div v-bind = "color('default solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('secondary solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('primary solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" aria-pressed = "true" / >
< / div >
< / div > < div >
< div v-bind = "color('default raised solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('secondary raised solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('primary raised solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" aria-pressed = "true" / >
< / div >
< / div >
< / Layout >
2024-12-15 23:07:09 +00:00
< / div >
2024-12-16 14:04:01 +00:00
< div class = "force-dark-theme" >
< Layout flex >
< div >
< div v-bind = "color('default solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('secondary solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('primary solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive')" aria-pressed = "true" / >
< / div > < br / > Normal
< / div > < div >
< div v-bind = "color('default raised solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('secondary raised solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" aria-pressed = "true" / >
< / div >
< div v-bind = "color('primary raised solid')" >
< div :class = "[$style.swatch]" v-bind = "color('solid raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" disabled / >
< div :class = "[$style.swatch]" v-bind = "color('solid interactive raised')" aria-pressed = "true" / >
< / div > < br / > < strong > Raised< / strong >
< / div >
< / Layout >
2024-12-15 23:07:09 +00:00
< / div >
2024-12-16 14:04:01 +00:00
< / Layout >
< Layout flex style = "align-items: center;" >
| neutral |
| --------- |
| secondary |
| primary |
| (normal) | interactive | disabled | pressed |
| -------- | ----------- | -------- | ------- |
< / Layout >
2024-12-15 23:07:09 +00:00
## Palette
The color palette consists of Blues, Reds, Grays, Beiges, as well as pastel blue/red/green/yellow.
2024-12-16 12:18:29 +00:00
`fw-blue-010 - 100 - 400..900`
< div :class = "[$style.swatch, $style.tiny]" style = "background:var(--fw-blue-010)" / >
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-blue-100)" / >
2024-12-16 12:18:29 +00:00
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-blue-400)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-blue-500)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-blue-600)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-blue-700)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-blue-800)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-blue-900)" / >
2024-12-16 12:18:29 +00:00
`fw-red-010 - 100 - 400..900`
2024-12-15 23:07:09 +00:00
2024-12-16 12:18:29 +00:00
< div :class = "[$style.swatch, $style.tiny]" style = "background:var(--fw-red-010)" / >
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-red-100)" / >
2024-12-16 12:18:29 +00:00
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-red-400)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-red-500)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-red-600)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-red-700)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-red-800)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-red-900)" / >
2024-12-16 12:18:29 +00:00
`fw-gray-100..800 - 850 - 900 - 950 - 960 - 970`
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-100)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-200)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-300)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-400)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-500)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-600)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-700)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-800)" / >
< div :class = "[$style.swatch, $style.tiny]" style = "background:var(--fw-gray-850)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-gray-900)" / >
< div :class = "[$style.swatch, $style.tiny]" style = "background:var(--fw-gray-950)" / >
< div :class = "[$style.swatch, $style.tiny]" style = "background:var(--fw-gray-960)" / >
< div :class = "[$style.swatch, $style.tiny]" style = "background:var(--fw-gray-970)" / >
2024-12-16 12:18:29 +00:00
`fw-beige-100..400`
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-beige-100)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-beige-200)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-beige-300)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-beige-400)" / >
---
2024-12-16 12:18:29 +00:00
`fw-pastel-blue-1..4`
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-blue-1)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-blue-2)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-blue-3)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-blue-4)" / >
2024-12-16 12:18:29 +00:00
`fw-pastel-red-1..4`
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-red-1)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-red-2)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-red-3)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-red-4)" / >
2024-12-16 12:18:29 +00:00
`fw-pastel-purple-1..4`
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-purple-1)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-purple-2)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-purple-3)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-purple-4)" / >
2024-12-16 12:18:29 +00:00
`fw-pastel-green-1..4`
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-green-1)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-green-2)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-green-3)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-green-4)" / >
2024-12-16 12:18:29 +00:00
`fw-pastel-yellow-1..4`
2024-12-15 23:07:09 +00:00
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-yellow-1)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-yellow-2)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-yellow-3)" / >
< div :class = "[$style.swatch, $style.small]" style = "background:var(--fw-pastel-yellow-4)" / >
2024-12-16 12:18:29 +00:00
---
In addition, we have a single shade of orange used for secondary indicators such as active tabs: `fw-secondary`
2024-12-15 23:07:09 +00:00
< div :class = "$style.swatch" style = "background:var(--fw-secondary)" / >
## Theme
Many browsers automatically turn on "night mode" to lower the light emission of the screen. Users can override the browser theme in their settings menu.
In both "dark mode" and "light mode", the colors must provide adequate contrast and consistency.
2024-12-16 12:18:29 +00:00
All colors added through the `color` or the `propsToColor` function in `composable/colors.ts` respect this setting. If you need to define new colors, use the following syntax in your `scss` :
```scss
@include light-theme {
--my-new-color: var(--fw-blue-400);
}
@include dark-theme {
--my-new-color: var(--fw-blue-800);
}
```
It's good practice to limit the scope of a variable to the module that needs it:
```vue
< template >
< div :class = "$style.newColor" / >
< / template >
< style module lang = "scss" >
@include light-theme {
--foreground-color: var(--fw-blue-400);
--background-color: var(--fw-beige-100);
}
@include dark-theme {
--foreground-color: var(--fw-pastel-blue-1);
--background-color: var(--fw-gray-960);
}
.new-color {
color: var(--foreground-color);
background-color: var(--background-color);
}
< / style >
```
Read more about [style modules in the corresponding vue docs ](https://vuejs.org/api/sfc-css-features.html#css-modules ).
2024-12-16 14:04:01 +00:00
For testing purposes and side-by-side comparisons, you can add the classes `force-dark-theme` and `force-light-theme` .
2024-12-15 23:07:09 +00:00
## Semantic colors
We use semantic color variables that can mean a different shade depending on the currently chosen theme
- primary
- secondary (default)
- destructive
## Color variants
For each semantic color, we set a foreground and a background. In addition, we need to check context: A button should have a stronger shade when the mouse is hovering over it. When a surface is raised over another surface, it should have a stronger shade, too.
2024-12-16 12:18:29 +00:00
**Variants:**
- ghost (default for most things except buttons)
2024-12-15 23:07:09 +00:00
2024-12-16 12:18:29 +00:00
> affects text color but leaves the border and background transparent.
> Make sure to provide a surface beneath with adequate contrast.
2024-12-15 23:07:09 +00:00
- outline
2024-12-16 12:18:29 +00:00
> affects text color and border and leaves the background transparent
> Make sure to provide a surface beneath with adequate contrast.
2024-12-15 23:07:09 +00:00
- solid (default for buttons)
2024-12-16 12:18:29 +00:00
> affects text color, border color and background color
2024-12-15 23:07:09 +00:00
2024-12-17 14:19:47 +00:00
[-> Example: #variant ](#variant )
2024-12-16 12:18:29 +00:00
**Variants can optionally be made interactive and/or raised:**
2024-12-15 23:07:09 +00:00
- no alteration (default)
- raised
2024-12-16 12:18:29 +00:00
> affects text color, border color and background color
2024-12-15 23:07:09 +00:00
- interactive
2024-12-16 12:18:29 +00:00
> user interaction affects text color, border color and background color
>
> - can be disabled
> - can be active
> - can be exact-active
> - can be hovering
2024-12-15 23:07:09 +00:00
- interactive-raised
2024-12-16 12:18:29 +00:00
> combine `raised` and `interactive`
2024-12-17 14:19:47 +00:00
[-> Example: #interactive-and-or-raised ](#interactive-and-or-raised )
2024-12-15 23:07:09 +00:00
2024-12-17 18:04:23 +00:00
## Theme color definitions
All colors are defined in `front/src/style/colors.scss` .
Its structure is as follows:
< Layout stack style = "--width:100%; background:#0002;" >
< Card solid purple title = "(1) Palette" >
Defining [all funkwhale color values ](#palette )
< / Card >
< Card solid blue title = "(2) Choosing the semantic colors from the palette" >
both for light and dark theme, and both normal and raised:
- default
- secondary
- primary
- destructive
- blue
- red
- purple
- green
- yellow
< / Card >
< Card solid green title = "(3) Applying colors" >
(for all elements not managed by vitepress)
- (a) Applying colors to things with no explicit Variant props, such as headings and paragraphs, simple links, focusable elements
- (b) Applying colors to things with explicit Variant props: - solid (and default buttons) - ghost - outline
2024-12-17 18:22:38 +00:00
< / Card >
2024-12-17 18:04:23 +00:00
< / Layout >
## Change a color value
For example, you want to make all blue hues more cyan-ish or mute all reds.
- Find the color value you want to change in **section 1 (Palette)**
- Change it
- Keep this page open and check under [Palette ](#palette ) if the colors are still in harmony with each other. Also make sure all recommended color combinations still meet the relevant WCGA2 recommendations for contrast
## Alter the shade of a color
In funkwhale components, we use semantic color names such as `primary` , `destructive` , `default` (neutral). Now, you find, for example, that a secondary button has low contrast in light mode, and you decide to alter the text color.
- Find the relevant section in **section 2 (hoosing the semantic colors from the palette)** . In our example, it's `.secondary` under `theme-light` .
- You see that the values are `--color: var(--fw-gray-700);` and `--background-color: var(--fw-gray-200);` , and you change `--color` to `var(--fw-gray-900)` .
- Test your changes. If nothing changes, then there is a Css rule with higher precedence. Find and eliminate these sorts of competing rules.
## Choose a different style for a specific variant
For example, you want to add visible lines around ghost links and buttons when the user hovers over them.
- Find the variant class in **section 3 (Applying colors)** . In our example, it is `.ghost` .
- In our example, we would add the line `border-color: var(--hover-border-color);` under `&:hover` to make the outline on interactive items visible on hover.
- Make sure to test all affected components before committing and merging the changes
2024-12-15 23:07:09 +00:00
< style module >
.swatch {
2024-12-16 14:04:01 +00:00
transition:all .15s, filter 0s;
2024-12-15 23:07:09 +00:00
border-radius: 2em;
min-width: 3.2em;
min-height: 3.2em;
margin: 1ch;
display: inline-flex;
box-shadow: 1px 2px 7px #0003 , 0px 0px 1px #0009 ;
align-items:center;
justify-items:center;
2024-12-16 12:18:29 +00:00
position:relative;
2024-12-16 14:04:01 +00:00
& ::after {
2024-12-16 12:18:29 +00:00
position:absolute;
inset:13%;
content:"fw";
line-height:2.68em;
font-size:80%;
text-align: center;
transform:rotate(15deg);
letter-spacing:-.02em;
font-weight:800;
}
2024-12-16 14:04:01 +00:00
& :is(:not(:global(.solid)):not(:hover),:has(*))::after {
2024-12-16 12:18:29 +00:00
opacity:0
}
2024-12-16 14:04:01 +00:00
}
:not(:hover)>.deemphasized {
filter:blur(4px);
opacity:.5;
& ::after {
opacity:0;
}
2024-12-15 23:07:09 +00:00
}
2024-12-16 12:18:29 +00:00
.small, .tiny {
2024-12-15 23:07:09 +00:00
margin: .25rem;
min-width: 1.6em;
min-height: 1.6em;
box-shadow: 1px 2px 4px #0002 , 0px 0px 1px #0007 ;
2024-12-16 12:18:29 +00:00
& ::after{
font-size:43%;
outline: none;
}
2024-12-15 23:07:09 +00:00
}
.tiny{
margin: .5rem .25rem;
min-width: 1em;
min-height: 1em;
box-shadow: 1px 2px 4px #0002 , 0px 0px 1px #0007 ;
2024-12-16 12:18:29 +00:00
& ::after{
font-size:27%;
}
2024-12-15 23:07:09 +00:00
}
< / style >