Style guide

Media queries & breakpoints

These are the defined breakpoints:

$mobile:         375px
$mobile-large:   400px
$mobile-wide:    576px
$tablet:         768px
$tablet-wide:    992px
$desktop:        1200px
$desktop-large:  1400px

Media queries exist for each breakpoint as $min-… (min-width) and $max-… (max-width) variations, used like this:

div
	@media ($min-tablet)
		// min-width: 768px
		
	@media ($max-tablet)
		// max-width: 767px (breakpoint - 1)

In addition, you can use the media queries @media ($darkmode) as a shortcut for @media (prefers-color-scheme: dark).


Grids

Grids follow the Bootstrap 12-column-grid conventions.

.row
	.col
	.col
	.col
.row
	.col
	.col
	.col
	.col
.row
	.col-4
	.col-8
.row
	.col
	.col-3
	.col-2

Use size classes on the row to determine the breakpoints for grids. (These are temporary and need to be finalized)

.row.row-xs
	.col
	.col
	.col
.row.row-lg
	.col-3
	.col-6
	.col-3

Forms

Following the Bootstrap conventions, these components and classes are available:

Optional help text
Validation error text
form.form-md
	.form-group
		label.form-label(for="exampleInput") Text input
		input.form-control#exampleInput(type="text" aria-describedby="exampleInputHelp" placeholder="Optional placeholder")
		.form-text#exampleInputHelp Optional help text
	.form-group
		label.form-label(for="exampleTextarea") Textarea
		textarea.form-control#exampleTextarea(placeholder="Optional placeholder" rows="3")
		.validation-message
			+icon("error")
			|  Validation error text
	.form-group
		label.form-label(for="exampleSelect") Select
		select.form-select#exampleSelect(aria-label="Default select example")
			option(selected) A select menu
			option(value="1") One
			option(value="2") Two
			option(value="3") Three
	.form-group
		label.form-label(for="exampleFileInput") File input
		input.form-control#exampleFileInput(type="file")
	.form-group
		label.form-label(for="exampleDisabledInput") Disabled text input
		input.form-control#exampleDisabledInput(type="text" disabled value="This input is disabled")

You can also use form controls without borders and horizontal padding.

.form-group
	input.form-control.plaintext#exampleInputPlain(type="text" value="This is a text input")

And small and large form controls.

.form-group
	input.form-control.form-control-sm(type="text" value="This is an input with class .form-control-sm")
.form-group
	input.form-control.form-control-lg(type="text" value="This is an input with class .form-control-lg")
.form-group
	select.form-select.form-control-sm
		option(selected) A small select menu

Use input groups to combine inputs with icons, text, … Add the .plaintext class to omit borders.

@example.com
.form-group
	.input-group
		.input-group-text
			+icon("location")
		input.form-control(type="text" placeholder="Add location")
.form-group
	.input-group
		.input-group-text €
		input.form-control.form-control-sm(type="text" placeholder="Value")
.form-group
	.input-group
		input.form-control(type="text" placeholder="username")
		.input-group-text @example.com
.form-group
	.input-group.plaintext
		.input-group-text
			+icon("event")
		input.form-control(type="text" placeholder="username")

Checkboxes & radio buttons

Checkboxes
Switches
Radio buttons
.row.row-sm
	.col
		.form-group
			.form-label Checkboxes
			label.form-check
				input.form-check-input(type="checkbox" checked)
				.form-check-label Option
			label.form-check
				input.form-check-input(type="checkbox")
				.form-check-label Option
			label.form-check
				input.form-check-input(type="checkbox" disabled)
				.form-check-label Disabled option
	.col
		.form-group
			.form-label Switches
			label.form-check
				input.form-switch-input(type="checkbox" checked)
				.form-check-label Option
			label.form-check
				input.form-switch-input(type="checkbox")
				.form-check-label Option
			label.form-check
				input.form-switch-input(type="checkbox" disabled)
				.form-check-label Disabled option								
	.col
		.form-group
			.form-label Radio buttons
			label.form-check
				input.form-radio-input(type="radio" name="styleguideRadios" checked)
				.form-check-label Option
			label.form-check
				input.form-radio-input(type="radio" name="styleguideRadios")
				.form-check-label Option
			label.form-check
				input.form-radio-input(type="radio" name="styleguideRadios" disabled)
				.form-check-label Disabled option

Buttons

Link button
button.btn(type="button") Button
a.btn(href="#") Link button
button.btn.btn-secondary(type="button") Secondary button
button.btn.btn-inverse(type="button") Inverse button
button.btn.btn-destructive(type="button") Destructive button
button.btn(type="button" disabled) Disabled button
button.btn.btn-sm(type="button") Small button
button.btn.btn-lg(type="button") Large button
button.btn.btn-loading(type="button") Loading button

Form layout

Use grids to layout forms.

.row.row-sm
	.col-6
		label.form-label(for="exampleLayout1") Username
		input.form-control#exampleLayout1(type="email" placeholder="Email address")
	.col-6
		label.form-label(for="exampleLayout2") Password
		input.form-control#exampleLayout2(type="password")
input.btn.btn-block(type="submit" value="Submit")

Pill navigation

Standard component for tabbed navigation.

ul.nav-pills
	li: a(href="#") One
	li: a(href="#") Two
	li: .active(aria-current="page") Three
	li: a(href="#") Four

Lists

Use a .list-group for all kinds of item lists.

Person list with names and roles

List with actions and sorting

Item 1
Item 2
.list-group
	label.list-group-item
		.list-group-content Documents
			input.form-switch-input(type="checkbox" checked)
	label.list-group-item
		.list-group-content Events
			input.form-switch-input(type="checkbox")
	label.list-group-item
		.list-group-content Actions
			input.form-switch-input(type="checkbox")

h3.list-heading Person list with names and roles
.list-group
	label.list-group-item
		.graphic
			img(src=$static."img/tmp/avatar4.jpg")
		.list-group-content
			.list-group-person
				.name Some name
				.role Some role
			input.form-check-input(type="checkbox" checked)
	label.list-group-item
		.graphic
			img(src=$static."img/tmp/avatar9.jpg")
		.list-group-content 
			.list-group-person
				.name Another Name
				.role Some role
			input.form-check-input(type="checkbox")

h3.list-heading List with actions and sorting
.list-group
	.list-group-item
		.list-group-content
			.list-group-action.list-group-drag
				+icon("drag")
			.list-group-text Item 1
			a.list-group-action(href="#")
				+icon("edit")
			a.list-group-action(href="#")
				+icon("trash")
	.list-group-item
		.list-group-content
			.list-group-action.list-group-drag
				+icon("drag")
			.list-group-text Item 2
			a.list-group-action(href="#")
				+icon("edit")
			a.list-group-action(href="#")
				+icon("trash")
	.list-group-item.list-group-add
		a.list-group-content(href="#")
			.list-group-action
				+icon("add")
			.list-group-text Add item
	

Icons

The icons are a mix of custom icons and Material icons. The SVGs are injected straight into the HTML. All SVGs should be 32px × 32px, with a 0 0 32 32 viewbox. By default icons have aria-hidden="true", but if you use an icon by itself without any text label, you should provide a label to the mixin.

  • add
  • admin
  • check
  • chevron-down
  • chevron-left
  • chevron-right
  • chevron-up
  • close
  • delete
  • edit
  • error
  • favorite
  • favorited
  • home
  • info
  • minus
  • modules
  • notification
  • plus
  • search
  • add
  • admin
  • check
  • chevron-down
  • chevron-left
  • chevron-right
  • chevron-up
  • close
  • delete
  • edit
  • error
  • favorite
  • favorited
  • home
  • info
  • minus
  • modules
  • notification
  • plus
  • search

Loading spinner

For loading animations, use a .btn-loading button, or just drop a .loading class on any empty element.

Optional message…
p: button.btn.btn-loading(type="button") Loading button
.loading Optional message…

Empty state

When no content is available, use this class to indicate that.

No agenda items
.empty-state No agenda items

Optionally you can use an icon too.

No open actions. You're all set!
🍻
.empty-state No open actions. You're all set!
	.empty-state-icon 🍻

Toasts

Toasts are lightweight notifications, and follow Bootstrap conventions. They can be shown inline, or called with Javascript and shown fixed at the top of the viewport.

Generic inline toast.
Success message toast.
Error message toast with an icon.
Warning message toast with some multiline text just for demonstration purposes.
Succesfully triggered live toast!
+toast(false, true) Generic inline toast.
+toast.success(false, true) Success message toast.
+toast.error(false, true)
	+icon("error")
	|  Error message toast with an icon.
+toast.warning(false, true) Warning message toast with some multiline text just for demonstration purposes.

button.btn.toastTrigger(type="button" data-target="#liveToast") Show live toast
+toast.success#liveToast(false) Succesfully triggered live toast!