Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/lucavallini/aibar-frontend/llms.txt

Use this file to discover all available pages before exploring further.

Aibar SRL App implements a complete dark/light theme system without any third-party library. The visual layer is built entirely on CSS custom properties defined in src/styles.css: a :root block sets the light-mode palette, and a .tema-oscuro class on document.body overrides every relevant variable for dark mode. Angular’s ThemeService drives the class toggle reactively via a signal<boolean> — any component that injects the service gets instant, reactive access to the current theme state. The user’s preference is persisted to localStorage so it survives page refreshes and new sessions.

ThemeService

File: src/app/core/services/theme.service.ts ThemeService is the single source of truth for the active theme. It uses Angular’s signal primitive together with effect() to keep the DOM and localStorage in sync with the signal’s value automatically.
import { Injectable, signal, effect } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class ThemeService {
  private storageKey = 'aibar_theme';

  esOscuro = signal<boolean>(this.leerPreferenciaGuardada());

  constructor() {
    effect(() => {
      document.body.classList.toggle('tema-oscuro', this.esOscuro());
      localStorage.setItem(this.storageKey, this.esOscuro() ? 'oscuro' : 'claro');
    });
  }

  alternar(): void {
    this.esOscuro.set(!this.esOscuro());
  }

  private leerPreferenciaGuardada(): boolean {
    return localStorage.getItem(this.storageKey) === 'oscuro';
  }
}
How it works step by step:
  1. On construction, leerPreferenciaGuardada() reads localStorage and initialises the esOscuro signal to true if the stored value is 'oscuro', otherwise false.
  2. The effect() registered in the constructor runs immediately on creation and re-runs every time esOscuro changes. It calls document.body.classList.toggle('tema-oscuro', this.esOscuro()) — passing true adds the class, false removes it — and writes the new preference string back to localStorage.
  3. Calling alternar() flips the signal, which automatically triggers the effect, updates the class, and saves the preference.
esOscuro is a signal — read it in component templates as themeService.esOscuro(). Because themeService is declared public in Header, the template can directly bind the toggle button label or icon to the current theme state: {{ themeService.esOscuro() ? '☀️' : '🌙' }}.

CSS Custom Properties

All visual tokens are defined as CSS custom properties on :root for light mode, and overridden under .tema-oscuro for dark mode. Components reference variables like var(--color-primario) — never hard-coded colour values — so the entire palette switches instantly when the class is toggled.

Light Mode (:root)

:root {
  color-scheme: light;

  --altura-header: 64px;
  --ancho-sidebar: 240px;

  --color-fondo: #f8faf9;
  --color-fondo-panel: #ffffff;
  --color-fondo-suave: #f1f5f3;
  --color-texto: #161d1a;
  --color-texto-secundario: #63716c;
  --color-borde: #e2ebe7;

  --color-primario: #106b56;
  --color-primario-hover: #0b5a47;
  --color-primario-claro: #e6f3ef;

  --color-sidebar-fondo: #ffffff;
  --color-sidebar-texto: #4e5f59;
  --color-sidebar-activo: #0f5f4d;
  --color-sidebar-hover: #f0f6f3;
  --color-sidebar-activo-fondo: #e2f0eb;

  --color-acento: #2f8a73;
  --color-error: #b42318;
  --color-error-fondo: #fef3f2;
  --color-exito: #087443;
  --color-exito-fondo: #ecfdf3;
  --color-alerta: #8a5a00;
  --color-alerta-fondo: #fffaeb;
  --color-info: #175cd3;
  --color-info-fondo: #eff6ff;
  --color-neutro: #4b5563;
  --color-neutro-fondo: #f3f4f6;

  --radio: 8px;
  --sombra: 0 1px 2px rgb(18 28 24 / 0.06), 0 8px 24px rgb(18 28 24 / 0.04);
  --sombra-modal: 0 20px 48px rgb(18 28 24 / 0.2);
}

Dark Mode (.tema-oscuro)

.tema-oscuro {
  color-scheme: dark;

  --color-fondo: #111614;
  --color-fondo-panel: #1a201d;
  --color-fondo-suave: #202824;
  --color-texto: #edf3f1;
  --color-texto-secundario: #a9b9b3;
  --color-borde: #2b3732;

  --color-primario: #73c7b0;
  --color-primario-hover: #91d8c5;
  --color-primario-claro: #203b33;

  --color-sidebar-fondo: #171d1a;
  --color-sidebar-texto: #b7c9c2;
  --color-sidebar-activo: #dff7ef;
  --color-sidebar-hover: #202824;
  --color-sidebar-activo-fondo: #1f4037;

  --color-acento: #73c7b0;
  --color-error: #f97066;
  --color-error-fondo: #3a1716;
  --color-exito: #6ce9a6;
  --color-exito-fondo: #102a1d;
  --color-alerta: #fdb022;
  --color-alerta-fondo: #2b2111;
  --color-info: #84caff;
  --color-info-fondo: #13243b;
  --color-neutro: #c5ced8;
  --color-neutro-fondo: #20252c;

  --sombra: 0 1px 2px rgb(0 0 0 / 0.24), 0 8px 24px rgb(0 0 0 / 0.18);
  --sombra-modal: 0 20px 48px rgb(0 0 0 / 0.5);
}

Key Variable Reference

VariableLightDarkPurpose
--color-primario#106b56#73c7b0Primary action colour (buttons, links, active states)
--color-fondo#f8faf9#111614Page background
--color-fondo-panel#ffffff#1a201dCard, table, and modal backgrounds
--color-fondo-suave#f1f5f3#202824Subtle background for table headers and inputs
--color-texto#161d1a#edf3f1Primary body text
--color-texto-secundario#63716c#a9b9b3Secondary/muted text
--color-borde#e2ebe7#2b3732Borders for tables, inputs, cards
--color-sidebar-fondo#ffffff#171d1aSidebar background
--color-sidebar-activo#0f5f4d#dff7efActive nav item text colour
--color-sidebar-activo-fondo#e2f0eb#1f4037Active nav item background
--radio8px8pxUniversal border radius

Status Badge Colours

styles.css defines semantic CSS classes for every status value used in the app. These classes share the .badge visual shape (pill, small font, bold) and map to the semantic colour tokens so they adapt automatically to dark and light mode.
/* Green — success palette */
.disponible, .finalizado, .alta, .administrador {
  background: var(--color-exito-fondo);
  color: var(--color-exito);
}

/* Amber — warning palette */
.viajando, .pendiente {
  background: var(--color-alerta-fondo);
  color: var(--color-alerta);
}

/* Blue — info palette */
.en_curso, .edicion, .empleado {
  background: var(--color-info-fondo);
  color: var(--color-info);
}

/* Red — error palette */
.inactivo, .cancelado, .cancelacion {
  background: var(--color-error-fondo);
  color: var(--color-error);
}

/* Grey — neutral palette */
.baja {
  background: var(--color-neutro-fondo);
  color: var(--color-neutro);
}
ClassPaletteEntities that use it
disponibleGreenChofer status, Camion status
viajandoAmberChofer status
inactivoRedChofer status, Camion status
pendienteAmberViaje status
en_cursoBlueViaje status
finalizadoGreenViaje status
canceladoRedViaje status
altaGreenAuditoría action type
edicionBlueAuditoría action type
cancelacionRedAuditoría action type
bajaGreyAuditoría action type
administradorGreenUsuario role
empleadoBlueUsuario role
To use a status badge in a template, apply the class name that matches the status string directly:
<span class="badge" [class]="chofer.estado">{{ chofer.estado }}</span>

Using the Theme in Components

Component-level CSS should always reference custom properties rather than raw colour values. This ensures the component responds to theme changes without any additional code.
/* example: viajes.css */
.estado-label {
  color: var(--color-texto-secundario);
  font-size: 0.8rem;
}

.card-viaje {
  background: var(--color-fondo-panel);
  border: 1px solid var(--color-borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
}

.card-viaje:hover {
  border-color: var(--color-primario);
}

Toggling Programmatically

Any component can trigger a theme change by injecting ThemeService and calling alternar():
import { Component } from '@angular/core';
import { ThemeService } from '../../../core/services/theme.service';

@Component({ /* ... */ })
export class MiComponente {
  constructor(public themeService: ThemeService) {}

  cambiarTema(): void {
    this.themeService.alternar();
  }
}
<button (click)="cambiarTema()">
  @if (themeService.esOscuro()) {
    ☀️ Cambiar a modo claro
  } @else {
    🌙 Cambiar a modo oscuro
  }
</button>
The body transition rule ensures the switch is visually smooth:
body {
  transition: background-color 0.2s, color 0.2s;
}

Build docs developers (and LLMs) love