Style Guide
How Styles are applied
All application-wide styles — colors, component defaults, and theme variables — are configured through Vuetify's plugin interface. The createVuetify() call receives a theme definition and component defaults that apply globally:
export const createVuetifyPlugin = (i18n: ReturnType<typeof createI18n>) =>
createVuetify({
...(useEnvConfig().value.SC_THEME === SchulcloudTheme.DEFAULT
? dbcThemeOptions
: federalStateThemeOptions),
defaults: {
VTextField: { variant: "underlined", color: "primary" },
// ...
},
});
The theme itself is built on a base theme (base-vuetify-theme.options.ts) that defines colors, surface tokens, and CSS variables for the entire application:
const baseTheme: ThemeDefinition = {
dark: false,
colors: {
primary: "#9e292b",
// ...
}
};
Instance-specific themes (e.g. for federal states) extend or override values from this base. Vuetify then generates CSS variables (e.g. --v-theme-primary) from these definitions, making them available everywhere via rgba(var(--v-theme-primary)).
Colors
Colors are included as CSS properties, often with transparency:
color: rgba(var(--v-theme-primary));
background-color: rgba(var(--v-theme-on-surface), 0.6);
Theme
Federal State Instances
src/themes/vuetify-theme.options.ts
| Color | Token | Hex | Usage |
|---|---|---|---|
primary | #2370CB | Button, Toolbar, Switch, Checkbox, Select, Progress Bar | |
primary-darken-1 | #1e599c | DataTable Header, Sort Icon | |
primary-lighten | #e9f1fa | Card Header (e.g. News) | |
on-surface-light / on-surface /on-background / on-white | #0f3551 | Text, Icons, Chip Text, Alert Text | |
surface-light | #f2f5f9 | Boards (in Rooms), Filters (in Tasks) |
dBildungscloud
src/themes/base-vuetify-theme.options.ts
| Color | Token | Hex | Usage |
|---|---|---|---|
primary | #9e292b | Button, Toolbar, Switch, Checkbox, Select, Progress Bar | |
primary-darken-1 | #800416 | DataTable Header, Sort Icon | |
primary-lighten | #f5eaea | Card Header (e.g. News) | |
on-surface-light / on-surface /on-background / on-white | #3a424b | Text, Icons, Chip Text, Alert Text | |
surface-light | #f3f4f4 | Boards (in Rooms), Filters (in Tasks) |
Background
src/themes/base-vuetify-theme.options.ts
| Color | Token | Hex | Usage |
|---|---|---|---|
surface-variant | #4E555D | Avatar, Tooltip (Background) | |
on-surface-variant | #F7F7F8 | Text/Icons on surface-variant | |
white | #ffffff | Toolbar, Board |
Info, Warning, Error
src/themes/base-vuetify-theme.options.ts
| Color | Token | Hex | Usage |
|---|---|---|---|
info | #0a7ac9 | Alert, Chip | |
success | #13ba98 | Alert, Status Icon | |
warning | #ff8311 | Alert, Chip, Status Icon (Tool deactivated/outdated) | |
error | #ed0122 | Alert, Chip, Status Icon, Error Text |
Rooms
Room Colors
src/styles/utility/_room-colors.scss
| Color | CSS Class | Hex |
|---|---|---|
.room-color--blue-grey | #455b6a | |
.room-color--pink | #ec407a | |
.room-color--red | #d50000 | |
.room-color--orange | #ef6c00 | |
.room-color--olive | #827717 | |
.room-color--green | #689f38 | |
.room-color--turquoise | #009688 | |
.room-color--light-blue | #0091ea | |
.room-color--blue | #304ffe | |
.room-color--magenta | #d500f9 | |
.room-color--purple | #9c27b0 | |
.room-color--brown | #795548 | |
.room-color--yellow | #ffc107 |
Boards
Card Background Colors (lighten5)
src/utils/color.utils.ts
Note: Hex values are computed at runtime via
colors[color]["lighten5"]from Vuetify's color palette and are shown here for reference only. Use theColorsenum in code.
| Color | Colors Enum | Hex |
|---|---|---|
transparent | #ffffff | |
lightGreen | #f1f8e9 | |
green | #e8f5e9 | |
cyan | #e0f7fa | |
blue | #e3f2fd | |
indigo | #e8eaf6 | |
purple | #f3e5f5 | |
pink | #fce4ec | |
deepOrange | #fbe9e7 | |
amber | #fff8e1 | |
blueGrey | #eceff1 |
Font Color in CK5 Editor
src/modules/feature/editor/config.ts
| Color | Label | Hex |
|---|---|---|
| Olive Green | #827717 | |
| Green | #388E3C | |
| Turquoise | #00838F | |
| Blue | #1976D2 | |
| Indigo | #3F51B5 | |
| Dark Purple | #673AB7 | |
| Purple | #9C27B0 | |
| Pink | #D81B60 | |
| Red | #D32F2F |
Text Highlighting in CK5 Editor
src/modules/feature/editor/config.ts
| Color | Label | Hex |
|---|---|---|
| Light Green | #DCEDC8 | |
| Green | #C8E6C9 | |
| Turquoise | #B2EBF2 | |
| Blue | #BBDEFB | |
| Indigo | #C5CAE9 | |
| Dark Purple | #E1BEE7 | |
| Pink | #F8BBD0 | |
| Orange | #FFCCBC | |
| Yellow | #FFECB3 |
Typography
Typography is defined via CSS variables and Vuetify utility classes, applied directly in templates and stylesheets:
<!-- Room abbreviation in avatar (RoomGridItem.vue) e.g. for Math 5a -->
<span class="text-h1 text-white">Ma</span>
<!-- Board file element: Metadata (FileAttributes.vue) -->
<span class="text-caption">3 Files · 1.2 MB</span>
.board-title {
font-family: var(--font-accent);
font-size: var(--heading-1);
}
Fonts
src/styles/css-variables/_typography.scss
| Variable | Font Family | Usage |
|---|---|---|
--font-primary | PT Sans, System Fallback | Body text, UI elements |
--font-accent | PT Sans Narrow, System Fallback | Headings (h1–h6) |
Typographic Scale
Headings
src/styles/utility/_typography.scss
| Element | CSS Variable | Size | Weight | Line-Height |
|---|---|---|---|---|
h1 | --heading-1 | 2.0625rem (33 px) | normal | --line-height-body (1.3) |
h2 | --heading-2 | 1.625rem (26 px) | normal | --line-height-body (1.3) |
h3 | --heading-3 | 1.375rem (22 px) | bold | --line-height-body (1.3) |
h4 | --heading-4 | 1.25rem (20 px) | bold | --line-height-lg (1.4) |
h5 | --heading-5 | 1.125rem (18 px) | bold | --line-height-lg (1.4) |
h6 | --heading-6 | 1rem (16 px) | bold | --line-height-lg (1.4) |
Vuetify Typography
Vuetify provides its own text classes that can be used independently of the HTML element:
| Class | Size | Usage |
|---|---|---|
.text-h1 – .text-h6 | --heading-1 – --heading-6 (see Headings table) | Heading style without semantic h element |
.text-subtitle-1 | 1 rem | Section labels, form labels |
.text-subtitle-2 | 0.875 rem | Secondary labels, due dates |
.text-body-1 | 1 rem | Default body text, card titles |
.text-body-2 | 0.875 rem | Secondary text, hint text |
.text-caption | 0.75 rem | Metadata, file attributes |
Font Size Classes
src/styles/utility/_typography.scss
| Class | CSS Variable | Size |
|---|---|---|
.text-xs | --text-xs | 0.694rem (≈ 11 px) |
.text-sm | --text-sm | 0.833rem (≈ 13 px) |
.text-md | --text-md | 1rem (16 px) |
.text-lg | --text-lg | 1.2rem (≈ 19 px) |
Line-Heights
| Variable | Value | Usage |
|---|---|---|
--line-height-md | 1.2 | Board title |
--line-height-body | 1.3 | h1–h3, Body text |
--line-height-lg | 1.4 | h4–h6 |
--line-height-xl | 1.5 | Text in boards |
Spacing
Vuetify Spacing Scale
Vuetify uses 4px as the base unit with utility classes following the pattern {property}{direction}-{n}:
<VCard class="pa-4">…</VCard> <!-- padding: 16px; -->
<VCard class="mt-6 mb-2">…</VCard> <!-- margin-top: 24px; margin-bottom: 8px; -->
<VCard class="mx-auto">…</VCard> <!-- margin-left: auto; margin-right: auto; -->
- Property:
m(margin),p(padding) - Direction:
ttop,bbottom,lleft,rright,xhorizontal,yvertical, none = all sides
| px | 4 | 8 | 12 | 16 | 20 | 24 | 32 | 40 | 48 | 64 |
|---|---|---|---|---|---|---|---|---|---|---|
| n | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 |
Layout Sizes
Layout sizes are defined as CSS variables for consistent structural dimensions across the application:
src/styles/css-variables/_layout-sizes.scss
| Variable | Value | Usage |
|---|---|---|
--topbar-height | 50px | Height of the top navigation bar |
--breadcrumbs-height | 22px | Height of the breadcrumb row |
--footer-height | 50px | Height of the footer |
--content-min-width | 30ch | Minimum content width |
--content-max-width | 80ch | Maximum content width (text) |
--content-limited-width | 1200px | Maximum page width |
Icons
Material Design Icons
src/components/icons/material/index.ts
The outline variant is preferred (e.g. mdiAccountOutline instead of mdiAccount). Icons are imported and passed as a prop to components or as a property in configuration objects:
import { mdiNewspaperVariantOutline, mdiFolderOpenOutline } from "@icons/material";
<!-- directly to VIcon (Dashboard.page.vue) -->
<VIcon size="14" class="mr-1" :icon="mdiNewspaperVariantOutline" />
<!-- as a prop to a custom component (FolderContentElement.vue) -->
<ContentElementBar :icon="mdiFolderOpenOutline">
// RoomBoardCard.vue – icon as a property in menu actions (RoomDotMenu)
actions.push({
icon: mdiTrashCanOutline,
action: () => emit("delete-board"),
name: t("common.actions.delete"),
});
Icons are used in:
- UI elements: menu, sidebar, tabs, icon buttons
- Content types: tasks, folders, boards, board-elements
A full searchable overview of all available icons is at pictogrammers.com/library/mdi.
Custom Icons
src/components/icons/custom/
Custom SVG icons as Vue components, registered as Vuetify aliases in base-vuetify-theme.options.ts:
<VIcon icon="$h5pOutline" />
| Alias | Datei |
|---|---|
$gridRowOutline | grid-row-outline.vue |
$h5pOutline | h5p-outline.vue |
$langIconDe | lang-icon-de.vue |