diff --git a/frontend/src/app/features/home/task-card.component.ts b/frontend/src/app/features/home/task-card.component.ts index ea60b99..10f0fc6 100644 --- a/frontend/src/app/features/home/task-card.component.ts +++ b/frontend/src/app/features/home/task-card.component.ts @@ -48,9 +48,11 @@ export interface ToggleEvent { border-radius: var(--radius-card); box-shadow: var(--shadow-card); cursor: pointer; - transition: transform 0.15s, border-color 0.25s, background 0.25s; + transition: transform var(--dur-press) var(--ease-out), + border-color var(--dur-settle) var(--ease-out), background var(--dur-settle) var(--ease-out); } - .card:active { transform: scale(0.99); } + /* Respuesta al toque: visible e inmediata (es el control que el niño más pulsa). */ + .card:active { transform: scale(0.97); } .card__tile { width: var(--tile-size); height: var(--tile-size); @@ -68,16 +70,25 @@ export interface ToggleEvent { font-weight: 700; font-size: 1.15rem; text-transform: uppercase; + /* Las mayúsculas necesitan tracking positivo para respirar (legibilidad). */ + letter-spacing: 0.03em; color: var(--text-strong); } .card__tts { all: unset; cursor: pointer; font-size: 26px; - padding: 6px; + width: var(--touch-min); + height: var(--touch-min); + display: flex; + align-items: center; + justify-content: center; border-radius: 50%; flex: none; + transition: transform var(--dur-press) var(--ease-out), + background var(--dur-settle) var(--ease-out); } + .card__tts:active { transform: scale(0.9); background: var(--surface-softer); } .card__check { width: var(--touch-check); height: var(--touch-check); diff --git a/frontend/src/app/features/parents/keypad.component.ts b/frontend/src/app/features/parents/keypad.component.ts index 415d516..9ee4323 100644 --- a/frontend/src/app/features/parents/keypad.component.ts +++ b/frontend/src/app/features/parents/keypad.component.ts @@ -56,7 +56,9 @@ import { AuthService } from '../../core/auth.service'; justify-content: center; font-size: 28px; color: var(--text-2); + transition: transform var(--dur-press) var(--ease-out); } + .key-screen__back:active { transform: scale(0.94); } .key-screen__title { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: 1.4rem; } .dots { display: flex; gap: 18px; } .dots--error { animation: shake 0.4s ease; } @@ -79,7 +81,7 @@ import { AuthService } from '../../core/auth.service'; font-weight: 700; font-size: 1.8rem; color: var(--text-strong); - transition: transform 0.1s; + transition: transform var(--dur-press) var(--ease-out); } .key:active { transform: scale(0.94); } .key--fn { background: var(--surface-softer); font-size: 1.4rem; } diff --git a/frontend/src/app/features/profiles/profile-select.component.scss b/frontend/src/app/features/profiles/profile-select.component.scss index 7b68e2f..41fa474 100644 --- a/frontend/src/app/features/profiles/profile-select.component.scss +++ b/frontend/src/app/features/profiles/profile-select.component.scss @@ -73,14 +73,15 @@ border: var(--card-border-width) solid color-mix(in srgb, var(--c) 35%, #fff); border-radius: var(--radius-card); box-shadow: var(--shadow-card); - transition: transform 0.15s, box-shadow 0.2s; + transition: transform var(--dur-press) var(--ease-out), box-shadow var(--dur-settle) var(--ease-out); animation: slideUp 0.4s ease both; &:hover { transform: translateY(-4px); box-shadow: var(--shadow-soft); } - &:active { transform: scale(0.98); } + // Mantiene la elevación del hover al pulsar: sin salto entre ambos estados. + &:active { transform: translateY(-2px) scale(0.97); } &__mascot { font-size: 84px; diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 2b9ba73..c9d7481 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -81,6 +81,16 @@ button { font-family: var(--font-display); } +// Mata el retardo de doble-tap del navegador en la tablet kiosko: la pulsación +// debe responder al instante (se conserva el scroll y el pinch-zoom de página). +button, +a, +select, +input, +[role='button'] { + touch-action: manipulation; +} + // --- Helpers del panel de padres (formularios de administración) --- .adm-card { background: var(--surface); @@ -112,6 +122,7 @@ button { background: var(--accent-blue); color: #fff; cursor: pointer; + transition: transform var(--dur-press) var(--ease-out); } .adm-btn:active { transform: scale(0.97); } .adm-btn:disabled { opacity: 0.4; cursor: default; } @@ -120,9 +131,17 @@ button { cursor: pointer; color: var(--accent-pink); font-size: 1.2rem; - padding: 4px 8px; + // Área táctil mínima real aunque el glifo sea pequeño. + min-width: var(--touch-min); + min-height: var(--touch-min); + display: inline-flex; + align-items: center; + justify-content: center; border-radius: 8px; + transition: transform var(--dur-press) var(--ease-out), background var(--dur-settle) var(--ease-out); } +.adm-del:active { transform: scale(0.9); background: var(--surface-softer); } +.adm-del:disabled { opacity: 0.35; cursor: default; } .adm-list { display: flex; flex-direction: column; gap: 10px; } .adm-item { display: flex; @@ -136,12 +155,21 @@ button { .adm-chip { display: inline-flex; align-items: center; + justify-content: center; gap: 6px; - padding: 4px 12px; + // Los chips actúan como botones (selector de días): área táctil de 44px mínimo. + min-height: 44px; + padding: 8px 16px; + border: 0; border-radius: var(--radius-pill); background: var(--surface-softer); + font-family: var(--font-display); font-size: 0.9rem; color: var(--text-1); + cursor: pointer; + transition: transform var(--dur-press) var(--ease-out), background var(--dur-settle) var(--ease-out), + color var(--dur-settle) var(--ease-out); } +.adm-chip:active { transform: scale(0.95); } .adm-empty { color: var(--text-3); padding: var(--space-4); text-align: center; } .adm-label { font-weight: 600; color: var(--text-1); } diff --git a/frontend/src/styles/_theme.scss b/frontend/src/styles/_theme.scss index 3b47807..e5dd73d 100644 --- a/frontend/src/styles/_theme.scss +++ b/frontend/src/styles/_theme.scss @@ -68,9 +68,19 @@ --touch-check: 60px; // check de completar --touch-nav: 64px; // botones de navegación ‹ › --touch-pin: 84px; // teclas del PIN + --touch-min: 48px; // mínimo absoluto para cualquier control tocable --card-min-height: 92px; --card-border-width: 3px; + // ----- Movimiento (duraciones y curvas únicas de la app) ----- + // La pulsación responde al instante (~100ms); el asentamiento es corto y sin + // rebote por defecto. La curva "spring" (con sobreimpulso) se reserva para + // momentos con impulso físico (completar tarea, celebraciones). + --dur-press: 100ms; + --dur-settle: 250ms; + --ease-out: cubic-bezier(0.25, 1, 0.5, 1); + --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); + // ----- Espaciado base ----- --space-1: 4px; --space-2: 8px;