Skip to main content

Overview

The project uses a component-based CSS architecture with a centralized custom properties system. All styles are written in vanilla CSS with no preprocessors or CSS-in-JS frameworks.

CSS Custom Properties (Variables)

All color values are defined as CSS custom properties in css/style.css:1-31:

Color System

:root {
    /* Colores del header y del footer */
    --header-yellow: #ffce00;
    --footer-background-blue: #1f2937;

    /* Colores principales del sitio */
    --primary-blue: #003366;
    --primary-blue-dark: #002244;
    --background-gray: #f5f5f5;
    --white: #ffffff;

    /* Colores de texto */
    --text-gray-light: #6a6f7b;
    --text-gray: #374151;
    --text-gray-dark: #1f2937;

    /* Colores de bordes y fondos */
    --border-light: #e5e7eb;
    --border-lighter: #f3f4f6;
    --bg-blue-light: #eff6ff;
    --bg-blue-lighter: #dbeafe;
    --border-blue: #bfdbfe;

    /* Colores de estado */
    --success-green: #059669;
    --success-green-dark: #047857;

    /* Colores neutros */
    --neutral-light: #f3f4f6;
    --neutral-dark: #d1d5db;
}
Why Custom Properties?
  • Single source of truth: Change a color once, update everywhere
  • Easy theming: Swap out the color scheme by changing the :root values
  • Better maintainability: Semantic names like --primary-blue instead of #003366

Color Usage Patterns

VariableUsageExamples
--primary-bluePrimary actions, headings, linksButton backgrounds, h1-h3 titles
--primary-blue-darkHover states for primary actionsButton hover effects
--header-yellowHeader backgroundTop navigation bar
--footer-background-blueFooter backgroundBottom section
--background-grayPage backgroundBody background color
--text-gray-lightSecondary text, descriptionsParagraph text, labels
--text-grayPrimary textBody copy
--border-lightDividers, input bordersForm field borders
--bg-blue-lightInfo boxes, highlightsInformation panels
--success-greenSuccess states, confirm buttonsConfirmation actions

CSS Reset

The project includes a minimal CSS reset in css/style.css:33-59:
/* CSS Reset */
* {
    margin: 0;
    padding: 0;
    border: 0;
    box-sizing: border-box;
}

body {
    width: 100%;
    font-family: Arial, Helvetica, sans-serif;
}

ol, ul {
    list-style: none;
}

table {
    border-collapse: collapse;
    border-spacing: 0;
}

a {
    text-decoration: none;
    color: inherit;
}
This reset is intentionally minimal to:
  • Remove browser default styles
  • Set box-sizing: border-box globally (makes width calculations easier)
  • Normalize margins and padding
  • Remove list bullets
  • Remove link underlines (added back via hover states)

Global Styles

Base layout and typography styles are defined in css/style.css:61-123:

Body & Layout

body {
    background-color: var(--background-gray);
}

main {
    display: flex;
    flex-direction: column;
    margin: 0px auto;
    max-width: 900px;
}
Key points:
  • Light gray background for visual separation
  • Main content container centered with max-width of 900px
  • Flexbox column layout for vertical stacking

Typography

The project uses Arial, Helvetica, sans-serif as the font stack:
body {
    font-family: Arial, Helvetica, sans-serif;
}
No custom fonts are loaded. This keeps the project lightweight and ensures fast loading times. If you want to add custom fonts, see the Customization guide.

Title Sections

#titulo {
    margin: 20px 0px;
}

#titulo > h1 {
    color: var(--primary-blue);
}

#titulo > p {
    margin-top: 20px;
    color: var(--text-gray-light);
}
Every page has a title section with:
  • Blue h1 heading
  • Gray descriptive paragraph
  • 20px spacing

Info Boxes

.info {
    margin-block: 30px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    background-color: var(--bg-blue-light);
    text-align: left;
    padding: 30px;
    border-radius: 10px;
}

.info > h3 {
    display: flex;
    flex-direction: row;
    gap: 15px;
    align-items: center;
    color: var(--primary-blue);
    margin-bottom: 15px;
}
Consistent information panels across all pages with:
  • Light blue background
  • Icon + heading combination
  • 10px border radius
  • 30px padding

Component Styles

Header Structure

header {
    background-color: var(--header-yellow);
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: 25px 100px;
    align-content: center;
}

header img {
    height: 55px;
    aspect-ratio: 445/103;
}
Responsive behavior:
  • Horizontal layout with flex
  • Logo on left, navigation on right
  • 100px horizontal padding
  • Menu button hidden

Mobile Navigation

@media (width <=480px) {
    #menu-toggle {
        display: flex;
        flex-direction: row;
        align-items: center;
        background-color: transparent;
    }

    nav {
        display: none;
        width: 100%;
        background: var(--header-yellow);
    }

    nav ul {
        flex-direction: column;
        gap: 10px;
        padding: 15px 0;
    }
}
JavaScript toggles the visible-nav class:
.visible-nav {
    display: block;
}
footer {
    background-color: var(--footer-background-blue);
    color: var(--white);
    padding: 0 50px;
}

footer > #content {
    display: flex;
    flex-direction: row;
    gap: 5%;
    padding: 30px 50px;
}

footer > #content > div {
    width: 30%;
}
Three-column layout:
  1. Logo + government info (30%)
  2. Enlaces de interés (30%)
  3. Contacto y ayuda (30%)
  4. 5% gaps between columns
On mobile (≤480px), switches to vertical stacking:
@media (width <=480px) {
    footer > #content {
        display: flex;
        flex-direction: column;
        width: 100%;
        gap: 10px;
        padding-inline: 0;
    }

    footer > #content > div {
        width: 100%;
    }
}

Option Cards (css/index.css, css/iniciar-solicitud.css)

Both the homepage and start request page use similar card layouts:
#opciones-cita {
    display: flex;
    flex-direction: row;
    justify-content: center;
    gap: 25px;
}

#opciones-cita > div {
    width: 50%;
    background-color: var(--white);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 50px;
    border-radius: 10px;
}
Card buttons:
.opcion-cita > a {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    gap: 10px;
    padding: 20px 40px;
    border-radius: 10px;
    background-color: var(--primary-blue);
    color: var(--white);
    font-size: 15px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.3s ease;
}

.opcion-cita > a:hover {
    opacity: .9;
    scale: .99;
}
Hover Effect Pattern:
  • Reduce opacity to 0.9
  • Slightly scale down to 0.99
  • 0.3s ease transition
This creates a subtle “press” effect that’s used throughout the application.
Primary vs Secondary Buttons:
/* Primary button (first card) */
.opcion-cita > a {
    background-color: var(--primary-blue);
    color: var(--white);
}

/* Secondary button (second card) */
.opcion-cita:nth-child(2) > a {
    background-color: var(--border-light);
    color: var(--text-gray-dark);
}

Form Styles (css/seleccionar-cita.css)

Form Container

#formulario-cita {
    background-color: var(--white);
    border-radius: 10px;
    padding: 30px;
    margin-bottom: 30px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
Subtle shadow for depth (1px offset, 3px blur, 10% opacity).

Form Sections

.seccion-formulario h2 {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--primary-blue);
    font-size: 1.3rem;
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 2px solid var(--border-light);
}
Section headings include:
  • Inline SVG icon
  • 10px gap between icon and text
  • Bottom border for visual separation

Input Fields

.campo-formulario input,
.campo-formulario select,
.campo-formulario textarea {
    width: 100%;
    padding: 12px 16px;
    border: 2px solid var(--border-light);
    border-radius: 8px;
    font-size: 16px;
    transition: border-color 0.3s ease;
    box-sizing: border-box;
    font-family: Arial, Helvetica, sans-serif;
}
Focus states:
.campo-formulario input:focus,
.campo-formulario select:focus,
.campo-formulario textarea:focus {
    outline: none;
    border-color: var(--primary-blue);
    box-shadow: 0 0 0 3px rgba(0, 51, 102, 0.1);
}
Accessibility: The blue focus ring (3px with 10% opacity) provides clear visual feedback while maintaining the design aesthetic.
Invalid states:
.campo-formulario input:invalid {
    border-color: #ef4444;
}

Two-Column Layout

.campos-fila {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}

.campos-fila .campo-formulario {
    flex: 1;
    min-width: 200px;
}
Flexible grid that:
  • Displays fields side-by-side on desktop
  • Wraps to single column when space is tight
  • Maintains 200px minimum width per field

Form Buttons

.botones-formulario {
    display: flex;
    gap: 20px;
    justify-content: center;
    margin-top: 30px;
    flex-wrap: wrap;
}

.botones-formulario a,
.botones-formulario button {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 15px 30px;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    min-width: 150px;
    justify-content: center;
}
Button variants:
ButtonBackgroundText ColorUse Case
#btn-volver--border-light--text-grayBack/Cancel
#btn-continuar--primary-blue--whiteSubmit/Continue

Summary Styles (css/resumen.css)

Status Badge

.estado-cita {
    text-align: center;
    padding: 30px;
    margin-bottom: 40px;
    background: linear-gradient(135deg, var(--bg-blue-light) 0%, var(--bg-blue-lighter) 100%);
    border-radius: 12px;
    border: 2px solid var(--border-blue);
}
Gradient background from light to lighter blue (135° diagonal).

Summary Tables

.tabla-resumen {
    width: 100%;
    border-collapse: collapse;
    margin-top: 10px;
}

.tabla-resumen td {
    padding: 12px 0;
    border-bottom: 1px solid var(--border-lighter);
    vertical-align: top;
}

.tabla-resumen td:first-child {
    color: var(--text-gray-light);
    font-weight: 500;
    width: 35%;
    padding-right: 20px;
}

.tabla-resumen td:last-child {
    color: var(--text-gray);
    font-weight: 400;
}
Layout:
  • First column (labels): 35% width, gray, medium weight
  • Second column (values): 65% width, darker, normal weight
  • Bottom borders between rows
  • No border on last row

Action Buttons

#btn-modificar {
    background-color: var(--neutral-light);
    color: var(--text-gray);
    border: 2px solid var(--border-light);
}

#btn-confirmar {
    background-color: var(--success-green);
    color: var(--white);
}

#btn-imprimir {
    background-color: var(--primary-blue);
    color: var(--white);
}
Three distinct button styles:
  1. Modify: Neutral with border (secondary action)
  2. Confirm: Green (primary success action)
  3. Print: Blue (utility action)

Responsive Design Strategy

The project uses mobile-first breakpoints with @media queries:

Breakpoints

BreakpointTargetKey Changes
DefaultMobile-first baseOptimized for small screens
481px - 1024pxTabletsReduced padding, adjusted layouts
>1024pxDesktopFull layout with max-width constraints
  • Single column layouts
  • Hamburger menu
  • Stacked footer
  • Reduced padding
  • Touch-friendly targets (min 44x44px)

Common Responsive Patterns

Padding reduction:
@media (width <=1024px) {
    main {
        padding-inline: 1rem;
    }
}
Layout switching:
@media (width <=1024px) {
    #opciones-cita {
        flex-wrap: wrap;
        width: 100%;
    }

    #opciones-cita > div {
        width: 100%;
    }
}
Font size adjustments:
@media (width <=480px) {
    .estado-cita h2 {
        font-size: 1.3rem;
    }
}

SVG Icons

All icons are inline SVG elements, not external files:
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" 
     fill="none" stroke="currentColor" stroke-width="2" 
     stroke-linecap="round" stroke-linejoin="round">
    <path stroke="none" d="M0 0h24v24H0z" fill="none" />
    <path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
    <path d="M9 12l2 2l4 -4" />
</svg>
Benefits of Inline SVG:
  • No extra HTTP requests
  • Icons inherit currentColor (text color)
  • Easy to style with CSS
  • Scalable at any size
The stroke="currentColor" attribute ensures icons match the text color of their parent element.

Animations & Transitions

Subtle animations enhance the user experience:

Transition Pattern

transition: all 0.3s ease;
Used consistently across:
  • Button hover states
  • Input focus states
  • Link hover effects

Hover Effects

Buttons:
.opcion-cita > a:hover {
    opacity: .9;
    scale: .99;
}
Links:
header a:hover {
    text-decoration: underline;
}

.enlaces-footer > a:hover {
    opacity: .8;
}
All transitions are kept to 0.3 seconds with ease timing for smooth, natural motion.

Performance Considerations

No Build Step

Vanilla CSS loads instantly with no compilation required

Minimal CSS

Total CSS size < 10KB (all files combined)

No External Dependencies

No CSS frameworks or libraries to download

Modern Features

CSS custom properties, flexbox, modern selectors

Best Practices

1

Use Custom Properties

Always reference color variables instead of hardcoding hex values:
/* Good */
color: var(--primary-blue);

/* Bad */
color: #003366;
2

Follow BEM-like Naming

Use descriptive class names:
  • .seccion-formulario (section)
  • .campo-formulario (field)
  • .botones-formulario (buttons)
3

Keep Specificity Low

Avoid deeply nested selectors:
/* Good */
.tabla-resumen td { }

/* Bad */
.contenedor-resumen .seccion-resumen .tabla-resumen tbody tr td { }
4

Mobile-First Approach

Write base styles for mobile, then enhance for larger screens:
/* Base (mobile) */
.elemento { width: 100%; }

/* Enhanced (desktop) */
@media (width > 1024px) {
    .elemento { width: 50%; }
}

Next Steps

Project Structure

Learn about the file and folder organization

Customization Guide

Customize colors, fonts, and layout to match your needs

Build docs developers (and LLMs) love