Overview
Card components are used throughout the application to present options and actions in a visually appealing, clickable format. There are two main card variations:
opcion-cita - Appointment action cards (used on homepage)
opcion-identificacion - Identification method cards (used on iniciar-solicitud page)
Appointment Cards (opcion-cita)
Used on the homepage to present options for starting or managing appointments.
HTML Structure
< div id = "opciones-cita" >
< div class = "opcion-cita" >
< h2 > Iniciar Solicitud de Cita </ h2 >
< p > Puede iniciar la solicitud con los datos de su DNI/NIE o sin ellos si lo ha perdido o se lo han
robado. </ p >
< a href = "./iniciar-solicitud.html" >
< span >< 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.5 21h-6.5a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v5" />
< path d = "M16 3v4" />
< path d = "M8 3v4" />
< path d = "M4 11h16" />
< path d = "M16 19h6" />
< path d = "M19 16v6" />
</ svg ></ span >
< span > Iniciar Solicitud </ span >
</ a >
</ div >
< div class = "opcion-cita" >
< h2 > Anular / Consultar Cita </ h2 >
< p > Si ya dispone de una cita, puede consultarla o anularla desde aquí. </ p >
< a href = "./iniciar-solicitud.html" >
< span >< 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.5 21h-6.5a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v8" />
< path d = "M16 3v4" />
< path d = "M8 3v4" />
< path d = "M4 11h16" />
< path d = "M16 19h6" />
</ svg ></ span >
< span > Anular o Consultar </ span >
</ a >
</ div >
</ div >
CSS Styles
From css/index.css:
#opciones-cita {
display : flex ;
flex-direction : row ;
justify-content : center ;
gap : 25 px ;
}
.opcion-cita span {
display : flex ;
}
#opciones-cita > div {
width : 50 % ;
background-color : var ( --white );
display : flex ;
flex-direction : column ;
justify-content : center ;
padding : 50 px ;
border-radius : 10 px ;
}
.opcion-cita > h2 {
margin-bottom : 20 px ;
color : var ( --primary-blue );
}
.opcion-cita > p {
margin-bottom : 15 px ;
color : var ( --text-gray-light );
}
.opcion-cita > a {
display : flex ;
flex-direction : row ;
justify-content : center ;
align-items : center ;
gap : 10 px ;
padding : 20 px 40 px ;
border-radius : 10 px ;
background-color : var ( --primary-blue );
color : var ( --white );
font-size : 15 px ;
font-weight : bold ;
cursor : pointer ;
transition : all 0.3 s ease ;
}
.opcion-cita > a :hover {
opacity : .9 ;
scale : .99 ;
}
.opcion-cita:nth-child ( 2 ) > a {
background-color : var ( --border-light );
color : var ( --text-gray-dark );
}
Responsive Behavior
/* Breakpoints para tablets o más pequeño */
@media ( width <= 1024 px ) {
#opciones-cita {
flex-wrap : wrap ;
width : 100 % ;
}
#opciones-cita > div {
width : 100 % ;
}
}
Identification Cards (opcion-identificacion)
Used on the “Iniciar Solicitud” page to choose authentication method.
HTML Structure
< div id = "opciones-identificacion" >
< div class = "opcion-identificacion" >
< h2 > Con datos del DNI/NIE </ h2 >
< p > Acceda utilizando los datos de su Documento Nacional de Identidad o Número de Identificación de
Extranjero. </ p >
< a href = "./seleccionar-cita.html" >
< span >
< svg xmlns = "http://www.w3.org/2000/svg" width = "24" height = "24" fill = "none" stroke = "currentColor"
stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2" >
< path stroke = "none" d = "M0 0h24v24H0z" />
< path d = "M7 12h3v4H7z" />
< path d = "M10 6H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-6" />
< path
d = "M10 4a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1zM14 16h2M14 12h4" />
</ svg ></ span >
< span > Continuar con DNI/NIE </ span >
</ a >
</ div >
< div class = "opcion-identificacion" >
< h2 > Con certificado electrónico </ h2 >
< p > Utilice su certificado electrónico o DNIe para un acceso más rápido y seguro. </ p >
< a href = "./seleccionar-cita.html" >
< span >
< svg xmlns = "http://www.w3.org/2000/svg" width = "24" height = "24" fill = "none" stroke = "currentColor"
stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2" >
< path stroke = "none" d = "M0 0h24v24H0z" />
< path
d = "m16.555 3.843 3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1-4.069 0l-.301-.301-6.558 6.558a2 2 0 0 1-1.239.578L5.172 21H4a1 1 0 0 1-.993-.883L3 20v-1.172a2 2 0 0 1 .467-1.284l.119-.13L4 17h2v-2h2v-2l2.144-2.144-.301-.301a2.877 2.877 0 0 1 0-4.069l2.643-2.643a2.877 2.877 0 0 1 4.069 0zM15 9h.01" />
</ svg ></ span >
< span > Continuar con Cl@ve </ span >
</ a >
</ div >
</ div >
CSS Styles
From css/iniciar-solicitud.css:
#opciones-identificacion {
display : flex ;
flex-direction : row ;
justify-content : center ;
gap : 25 px ;
}
.opcion-identificacion span {
display : flex ;
}
#opciones-identificacion > div {
width : 50 % ;
background-color : var ( --white );
display : flex ;
flex-direction : column ;
justify-content : center ;
padding : 50 px ;
border-radius : 10 px ;
}
.opcion-identificacion > h2 {
margin-bottom : 20 px ;
color : var ( --primary-blue );
}
.opcion-identificacion > p {
margin-bottom : 15 px ;
color : var ( --text-gray-light );
}
.opcion-identificacion > a {
display : flex ;
flex-direction : row ;
justify-content : center ;
align-items : center ;
gap : 10 px ;
padding : 20 px 40 px ;
border-radius : 10 px ;
background-color : var ( --primary-blue );
color : var ( --white );
font-size : 15 px ;
font-weight : 700 ;
cursor : pointer ;
transition : all 0.3 s ease ;
}
.opcion-identificacion > a :hover {
opacity : .9 ;
scale : .99 ;
}
.opcion-identificacion:nth-child ( 2 ) > a {
background-color : var ( --border-light );
color : var ( --text-gray-dark );
}
Responsive Behavior
@media ( width <= 1024 px ) {
#opciones-identificacion {
flex-wrap : wrap ;
width : 100 % ;
}
#opciones-identificacion > div {
width : 100 % ;
}
}
Card Anatomy
Each card consists of:
Container - .opcion-cita or .opcion-identificacion
Heading - <h2> with card title
Description - <p> with explanatory text
Action Link - <a> styled as button with icon and text
Color Variations
The second card in each group has different button styling:
/* First card - Primary blue button */
.opcion-cita > a {
background-color : var ( --primary-blue );
color : var ( --white );
}
/* Second card - Gray button */
.opcion-cita:nth-child ( 2 ) > a {
background-color : var ( --border-light );
color : var ( --text-gray-dark );
}
Usage Examples
Basic Two-Card Layout
< div id = "opciones-cita" >
< div class = "opcion-cita" >
< h2 > Option 1 Title </ h2 >
< p > Description of option 1. </ p >
< a href = "./page1.html" >
< span >
< svg > <!-- icon --> </ svg >
</ span >
< span > Button Text </ span >
</ a >
</ div >
< div class = "opcion-cita" >
< h2 > Option 2 Title </ h2 >
< p > Description of option 2. </ p >
< a href = "./page2.html" >
< span >
< svg > <!-- icon --> </ svg >
</ span >
< span > Button Text </ span >
</ a >
</ div >
</ div >
Three-Card Layout
< div id = "opciones-cita" >
< div class = "opcion-cita" >
< h2 > Option 1 </ h2 >
< p > Description </ p >
< a href = "#" >< span > Action </ span ></ a >
</ div >
< div class = "opcion-cita" >
< h2 > Option 2 </ h2 >
< p > Description </ p >
< a href = "#" >< span > Action </ span ></ a >
</ div >
< div class = "opcion-cita" >
< h2 > Option 3 </ h2 >
< p > Description </ p >
< a href = "#" >< span > Action </ span ></ a >
</ div >
</ div >
Single Card (Full Width)
< div id = "opciones-cita" >
< div class = "opcion-cita" style = "width: 100%;" >
< h2 > Single Action </ h2 >
< p > This is the only available option. </ p >
< a href = "./next-page.html" >
< span > Continue </ span >
</ a >
</ div >
</ div >
Customization
Changing Card Background
.opcion-cita {
background : linear-gradient ( 135 deg , #f5f7fa 0 % , #c3cfe2 100 % );
}
Adding Shadows
#opciones-cita > div {
box-shadow : 0 4 px 6 px rgba ( 0 , 0 , 0 , 0.1 );
transition : all 0.3 s ease ;
}
#opciones-cita > div :hover {
box-shadow : 0 10 px 20 px rgba ( 0 , 0 , 0 , 0.15 );
transform : translateY ( -2 px );
}
/* Green button for first card */
.opcion-cita:first-child > a {
background-color : #10b981 ;
}
/* Red button for second card */
.opcion-cita:nth-child ( 2 ) > a {
background-color : #ef4444 ;
color : white ;
}
< a href = "./page.html" class = "icon-only" >
< svg xmlns = "http://www.w3.org/2000/svg" width = "24" height = "24" viewBox = "0 0 24 24" >
<!-- icon path -->
</ svg >
</ a >
a .icon-only {
padding : 15 px ;
border-radius : 50 % ;
width : 60 px ;
height : 60 px ;
}
Responsive Breakpoints
Desktop (> 1024px)
Two-column side-by-side layout
Each card: 50% width
Gap: 25px between cards
Padding: 50px inside each card
Tablet & Mobile (≤ 1024px)
Single-column stacked layout
Each card: 100% width
Cards stack vertically
Same 25px gap maintained
Accessibility Features
Uses semantic heading tags (<h2>) for titles
Descriptive link text (not “click here”)
Icons wrapped in <span> elements
Proper link elements with href attributes
Cards are keyboard accessible via Tab key
Enter/Space activates links
Focus states visible with outline
Logical tab order (left to right, top to bottom)
< a href = "./iniciar-solicitud.html" aria-label = "Iniciar solicitud de cita para DNI o Pasaporte" >
< span aria-hidden = "true" >
< svg > <!-- decorative icon --> </ svg >
</ span >
< span > Iniciar Solicitud </ span >
</ a >
Decorative icons marked with aria-hidden="true"
Descriptive aria-label on links if needed
Text content provides context
Add focus indicator for better accessibility: .opcion-cita > a :focus {
outline : 3 px solid var ( --primary-blue );
outline-offset : 2 px ;
}
.opcion-cita > a :focus-visible {
outline : 3 px solid var ( --primary-blue );
outline-offset : 2 px ;
}
Interactive States
Hover Effect
.opcion-cita > a :hover {
opacity : .9 ;
scale : .99 ;
}
Effect:
Slight transparency (90% opacity)
Slight scale down (99% size)
Creates “pressed” button effect
Active State
.opcion-cita > a :active {
scale : .97 ;
opacity : .85 ;
}
Disabled State (Optional)
< a href = "#" class = "disabled" aria-disabled = "true" >
< span > Coming Soon </ span >
</ a >
.opcion-cita > a .disabled {
background-color : #d1d5db ;
color : #6b7280 ;
cursor : not-allowed ;
pointer-events : none ;
opacity : 0.6 ;
}
Advanced Features
Loading State
< a href = "#" class = "loading" >
< span class = "spinner" ></ span >
< span > Loading... </ span >
</ a >
.spinner {
width : 20 px ;
height : 20 px ;
border : 2 px solid rgba ( 255 , 255 , 255 , 0.3 );
border-top-color : white ;
border-radius : 50 % ;
animation : spin 0.6 s linear infinite ;
}
@keyframes spin {
to { transform : rotate ( 360 deg ); }
}
Badge/Notification
< div class = "opcion-cita" >
< h2 >
Iniciar Solicitud de Cita
< span class = "badge" > Nuevo </ span >
</ h2 >
< p > Description </ p >
< a href = "#" >< span > Action </ span ></ a >
</ div >
.badge {
display : inline-block ;
background-color : #ef4444 ;
color : white ;
font-size : 12 px ;
padding : 4 px 8 px ;
border-radius : 12 px ;
font-weight : bold ;
margin-left : 10 px ;
}
Common Issues
Cards Not Side-by-Side
Problem: Cards stack vertically on desktop.
Solution: Check flex properties:
#opciones-cita {
display : flex ;
flex-direction : row ; /* Not column */
flex-wrap : wrap ;
}
Uneven Card Heights
Problem: Cards have different heights.
Solution: Use flexbox stretch:
#opciones-cita {
align-items : stretch ; /* Default, but ensure it's set */
}
#opciones-cita > div {
display : flex ;
flex-direction : column ;
}
.opcion-cita > a {
margin-top : auto ; /* Push button to bottom */
}
Problem: Link doesn’t respond to clicks.
Solutions:
Remove pointer-events: none if present
Check for overlapping elements (z-index)
Verify href attribute is set
Check JavaScript isn’t preventing default
Best Practices
Design:
Limit to 2-3 cards per row for readability
Keep card heights consistent
Use icons that clearly represent the action
Maintain adequate spacing between cards
Ensure text is concise and actionable
Development:
Use semantic HTML (headings, links, not divs)
Include descriptive link text
Test keyboard navigation
Verify responsive behavior on all screen sizes
Add focus states for accessibility
Use CSS transitions for smooth interactions
Examples in Project
Homepage Cards
Location: index.html (lines 51-86)
“Iniciar Solicitud de Cita” card
“Anular / Consultar Cita” card
Identification Cards
Location: iniciar-solicitud.html (lines 51-86)
“Con datos del DNI/NIE” card
“Con certificado electrónico” card
Both card types share similar structure and styling but are used in different contexts. The CSS is nearly identical, allowing for easy reuse across pages.