SCSS System
Flute CMS uses SCSS for styling. SCSS is compiled automatically, supports mixins and utility classes.
SCSS File Structure
Main File app.scss
Create assets/sass/app.scss:
// 1. Theme variables
@import 'theme/variables';
// 2. Components (if overriding)
@import 'components/buttons';
@import 'components/cards';
// 3. Pages
@import 'pages/home';
// 4. Custom styles
.my-custom-element {
// ...
}Recommended Structure
- app.scss
Built-in Mixins
Responsiveness (@media)
.element {
padding: var(--space-xl);
font-size: var(--h2);
@include media(tablet) {
padding: var(--space-lg);
font-size: var(--h3);
}
@include media(mobile) {
padding: var(--space-md);
font-size: var(--h4);
}
}Breakpoints:
| Name | Width | Description |
|---|---|---|
mobile | ≤768px | Phones |
tablet | ≤1024px | Tablets |
desktop | >1024px | Desktop |
Animations (@transition)
.element {
@include transition(all);
&:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-large);
}
}
// Only specific properties
.element {
@include transition(background, color);
}Built-in Utility Classes
Flexbox
<!-- Basic flex -->
<div class="flex">...</div>
<!-- Centering -->
<div class="flex-center">...</div>
<!-- Space-between -->
<div class="flex-between">...</div>
<!-- Column -->
<div class="flex-column">...</div>
<!-- With gap -->
<div class="flex gap-sm">...</div>
<div class="flex gap-md">...</div>
<div class="flex gap-lg">...</div>What they do:
.flex { display: flex; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-column { display: flex; flex-direction: column; }
.gap-sm { gap: var(--space-sm); } // 8px
.gap-md { gap: var(--space-md); } // 16px
.gap-lg { gap: var(--space-lg); } // 24pxGrid
<div class="grid grid-2">...</div> <!-- 2 columns -->
<div class="grid grid-3">...</div> <!-- 3 columns -->
<div class="grid grid-4">...</div> <!-- 4 columns -->Text
<p class="text-center">Centered</p>
<p class="text-left">Left aligned</p>
<p class="text-right">Right aligned</p>
<p class="text-muted">Muted color</p>
<p class="text-accent">Accent color</p>
<p class="text-error">Red</p>
<p class="text-success">Green</p>
<p class="text-warning">Yellow</p>
<p class="font-bold">Bold</p>
<p class="font-medium">Medium</p>Spacing (margin/padding)
<!-- Margin -->
<div class="mt-1">margin-top: 4px</div>
<div class="mt-2">margin-top: 8px</div>
<div class="mt-3">margin-top: 16px</div>
<div class="mt-4">margin-top: 24px</div>
<div class="mt-5">margin-top: 32px</div>
<div class="mb-3">margin-bottom: 16px</div>
<div class="ml-3">margin-left: 16px</div>
<div class="mr-3">margin-right: 16px</div>
<div class="mx-3">margin-left + right: 16px</div>
<div class="my-3">margin-top + bottom: 16px</div>
<!-- Padding -->
<div class="p-3">padding: 16px</div>
<div class="px-3">padding-left + right: 16px</div>
<div class="py-3">padding-top + bottom: 16px</div>
<div class="pt-3">padding-top: 16px</div>Sizing
<div class="w-100">width: 100%</div>
<div class="h-100">height: 100%</div>Visibility
<div class="hidden">display: none</div>
<div class="visible">display: block</div>Overriding Standard Components
Buttons
// assets/sass/components/_buttons.scss
.btn {
// Pill buttons
border-radius: 50px;
// Uppercase
text-transform: uppercase;
font-weight: 600;
letter-spacing: 0.025em;
// Different padding
padding: var(--space-sm) var(--space-xl);
}
// Gradient button
.btn-accent {
background: linear-gradient(135deg, var(--accent), var(--accent-600));
&:hover {
background: linear-gradient(135deg, var(--accent-600), var(--accent-700));
}
}
// Outline with effect
.btn-outline-accent {
background: transparent;
border: 2px solid var(--accent);
color: var(--accent);
&:hover {
background: var(--accent);
color: white;
}
}Cards
// assets/sass/components/_cards.scss
.card {
background: var(--secondary);
border: none;
border-radius: var(--border1);
box-shadow: var(--shadow-medium);
overflow: hidden;
@include transition(all);
&:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-large);
}
}
.card-header {
padding: var(--space-lg);
border-bottom: 1px solid var(--transp-1);
}
.card-body {
padding: var(--space-lg);
}
.card-footer {
padding: var(--space-md) var(--space-lg);
background: var(--third);
border-top: 1px solid var(--transp-1);
}Forms
// assets/sass/components/_forms.scss
.input {
width: 100%;
padding: var(--space-sm) var(--space-md);
background: var(--secondary);
border: 1px solid var(--transp-2);
border-radius: var(--border05);
font-size: var(--p);
color: var(--text);
@include transition(all);
&::placeholder {
color: var(--text-400);
}
&:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-100);
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
// Textarea
textarea.input {
min-height: 120px;
resize: vertical;
}
// Label
.form__label {
display: block;
margin-bottom: var(--space-xs);
font-weight: 500;
font-size: var(--small);
color: var(--text);
}
// Required indicator
.form__label-required::after {
content: ' *';
color: var(--error);
}
// Error state
.input.has-error {
border-color: var(--error);
&:focus {
box-shadow: 0 0 0 3px var(--error-100);
}
}Header
// assets/sass/layouts/_header.scss
.navbar {
position: sticky;
top: 0;
z-index: 100;
background: var(--blurred-background);
backdrop-filter: blur(20px);
border-bottom: 1px solid var(--transp-1);
&__content {
display: flex;
align-items: center;
justify-content: space-between;
height: 64px;
padding: 0 var(--space-lg);
}
&__logo {
img {
height: 32px;
width: auto;
}
}
&__items {
display: flex;
align-items: center;
gap: var(--space-xs);
}
&__items-item {
padding: var(--space-xs) var(--space-sm);
border-radius: var(--border05);
font-size: var(--p);
font-weight: 500;
color: var(--text-muted);
@include transition(all);
&:hover, &.active {
color: var(--text);
background: var(--transp-1);
}
}
}Creating Custom Components
Example: Feature Card
// assets/sass/components/_feature-card.scss
.feature-card {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: var(--space-xl);
background: var(--secondary);
border-radius: var(--border1);
@include transition(all);
&:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-medium);
}
&__icon {
display: flex;
align-items: center;
justify-content: center;
width: 64px;
height: 64px;
margin-bottom: var(--space-md);
background: var(--accent-100);
border-radius: var(--border1);
color: var(--accent);
svg {
width: 32px;
height: 32px;
}
}
&__title {
margin-bottom: var(--space-sm);
font-size: var(--h4);
font-weight: 600;
}
&__description {
color: var(--text-muted);
font-size: var(--small);
line-height: var(--line-height);
}
}Including in app.scss
@import 'theme/variables';
@import 'components/feature-card';BEM Methodology
It is recommended to use BEM for class naming:
// Block
.card { }
// Element
.card__header { }
.card__body { }
.card__footer { }
// Modifier
.card--featured { }
.card--compact { }<div class="card card--featured">
<div class="card__header">...</div>
<div class="card__body">...</div>
</div>Sass Variables (Local)
For convenience, you can use Sass variables inside components:
.my-component {
$padding: var(--space-lg);
$border-radius: var(--border1);
padding: $padding;
border-radius: $border-radius;
&__header {
padding: $padding;
}
}