/* ──────────────────────────────────────────────
   operio-components.css — componentes base del sistema
   de diseño. Solo los 10 listados en CLAUDE.md.
   No crear componentes nuevos sin aprobación del equipo.
   ────────────────────────────────────────────── */

* {
    font-family: var(--op-font);
    box-sizing: border-box;
}

body {
    color: var(--op-text);
    background: var(--op-bg);
}

@media (prefers-reduced-motion: no-preference) {
    .op-btn, .op-input, .op-status-chip {
        transition: background-color var(--op-motion-duration) var(--op-motion-ease),
                    border-color var(--op-motion-duration) var(--op-motion-ease),
                    color var(--op-motion-duration) var(--op-motion-ease);
    }
}

.op-btn:focus-visible,
.op-input:focus-visible,
.op-navbar__link:focus-visible,
.op-menu__trigger:focus-visible,
.op-menu__item:focus-visible,
.op-input-icon__toggle:focus-visible,
a:focus-visible {
    outline: 2px solid var(--op-accent);
    outline-offset: 2px;
}

.tabular-nums {
    font-variant-numeric: tabular-nums;
}

/* ── Tipografía — utilidades ───────────────────── */
.op-h1 { font-size: var(--op-fs-24); font-weight: 700; margin: 0 0 var(--op-4); }
.op-h2 { font-size: var(--op-fs-20); font-weight: 700; margin: var(--op-6) 0 var(--op-3); }
.op-text { font-size: var(--op-fs-16); color: var(--op-text); }
.op-text-muted { font-size: var(--op-fs-14); color: var(--op-text-muted); }
.op-text-subtle { font-size: var(--op-fs-14); color: var(--op-text-subtle); }
.op-label { font-size: var(--op-fs-12); font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--op-text-muted); }

.op-toast {
    background: var(--op-ok-soft);
    color: var(--op-ok);
    border-radius: var(--op-radius-control);
    padding: var(--op-3) var(--op-4);
    font-size: var(--op-fs-14);
    font-weight: 500;
    margin-bottom: var(--op-4);
}

/* ── Button — 3 variantes únicamente ──────────── */
.op-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--op-2);
    min-height: 44px;
    padding: 0 var(--op-4);
    border-radius: var(--op-radius-control);
    font-size: var(--op-fs-16);
    font-weight: 500;
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    line-height: 1;
}

.op-btn--primary {
    background: var(--op-accent);
    color: var(--op-text-invert);
}

.op-btn--primary:hover {
    background: var(--op-accent-press);
    color: var(--op-text-invert);
}

.op-btn--ghost {
    background: transparent;
    border-color: var(--op-border-strong);
    color: var(--op-accent-press);
}

.op-btn--ghost:hover {
    background: var(--op-surface);
    color: var(--op-accent-press);
}

.op-btn--danger {
    background: transparent;
    border-color: var(--op-bad-soft);
    color: var(--op-bad);
}

.op-btn--danger:hover {
    background: var(--op-bad-soft);
    color: var(--op-bad);
}

.op-btn--block {
    width: 100%;
}

/* ── Input ─────────────────────────────────────── */
.op-field {
    display: flex;
    flex-direction: column;
    gap: var(--op-1);
    margin-bottom: var(--op-4);
}

.op-field label {
    font-size: var(--op-fs-12);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .02em;
    color: var(--op-text-muted);
}

.op-input {
    min-height: 44px;
    border-radius: var(--op-radius-control);
    border: 1px solid var(--op-border-strong);
    padding: 0 var(--op-3);
    font-size: var(--op-fs-16);
    color: var(--op-text);
    background: var(--op-bg);
    width: 100%;
}

textarea.op-input {
    min-height: 88px;
    padding: var(--op-3);
}

.op-input::placeholder {
    color: var(--op-text-subtle);
}

.op-input.is-invalid,
.op-input.input-validation-error {
    border-color: var(--op-bad);
}

/* Edge/IE dibujan su propio ojo de "revelar contraseña" y su botón "x" de
   borrado encima de cualquier input con texto — se duplican con el ícono
   propio de .op-input-icon__toggle. Los quitamos en todos los .op-input. */
.op-input::-ms-reveal,
.op-input::-ms-clear {
    display: none;
}

/* ── Input con ícono (pantallas de login) ──────── */
.op-input-icon {
    position: relative;
}

.op-input-icon__icon {
    position: absolute;
    left: var(--op-3);
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    color: var(--op-text-subtle);
    pointer-events: none;
}

.op-input--icon {
    /* var(--op-3) del ícono + 18px de ancho + var(--op-2) de aire */
    padding-left: calc(var(--op-3) + 18px + var(--op-2));
}

.op-input--icon-toggle {
    padding-right: 44px; /* = ancho de .op-input-icon__toggle */
}

.op-input-icon__toggle {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--op-text-subtle);
    cursor: pointer;
    padding: 0;
}

.op-input-icon__toggle svg {
    width: 18px;
    height: 18px;
}

/* El atributo hidden nativo no siempre alcanza a un <svg> (solo lo
   forzaba el reboot de Bootstrap, que el login de Admin no carga) —
   se declara explícito para que el toggle de ojo abierto/cerrado
   funcione igual con o sin Bootstrap en la página. */
.op-input-icon__toggle svg[hidden] {
    display: none;
}

.op-field-error {
    font-size: var(--op-fs-14);
    color: var(--op-bad);
}

/* ── StatusChip ────────────────────────────────── */
.op-status-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--op-1);
    height: 26px;
    padding: 0 var(--op-2);
    border-radius: var(--op-radius-pill);
    font-size: var(--op-fs-12);
    font-weight: 700;
}

.op-status-chip::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.op-status-chip--ok      { background: var(--op-ok-soft);   color: var(--op-ok); }
.op-status-chip--wait    { background: var(--op-wait-soft); color: var(--op-wait); }
.op-status-chip--bad     { background: var(--op-bad-soft);  color: var(--op-bad); }
.op-status-chip--off     { background: var(--op-off-soft);  color: var(--op-off); }

/* ── EmptyState ────────────────────────────────── */
.op-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--op-2);
    padding: var(--op-12) var(--op-4);
}

.op-empty-state__logo {
    opacity: .35;
    width: 64px;
    height: 64px;
}

.op-empty-state__title {
    font-size: var(--op-fs-16);
    font-weight: 700;
    color: var(--op-text);
}

.op-empty-state__support {
    font-size: var(--op-fs-14);
    color: var(--op-text-muted);
    max-width: 32ch;
}

/* ── Navbar ────────────────────────────────────── */
.op-navbar {
    border-bottom: 1px solid var(--op-border);
    box-shadow: none;
}

.op-navbar__brand {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: var(--op-fs-20);
    font-weight: 500;
    color: var(--op-text);
    text-decoration: none;
}

.op-navbar__link {
    position: relative;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: var(--op-fs-16);
    font-weight: 500;
    color: var(--op-text);
    text-decoration: none;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
}

.op-navbar__link--active {
    color: var(--op-accent-press);
}

.op-navbar__link--active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 8px;
    height: 2px;
    border-radius: var(--op-radius-pill);
    background: var(--op-accent-press);
}

.op-navbar__link--muted {
    color: var(--op-text-muted);
}

.op-navbar__link--danger {
    color: var(--op-bad);
}

/* ── Filas de lista (ej. clientes, historial de citas) ── */
.op-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--op-3);
    min-height: 44px;
    padding: var(--op-3) 0;
    border-bottom: 1px solid var(--op-border);
}

.op-row__title {
    font-size: var(--op-fs-16);
    font-weight: 500;
    color: var(--op-text);
}

a.op-row__title {
    text-decoration: none;
}

a.op-row__title:hover {
    color: var(--op-accent-press);
}

.op-row__support {
    font-size: var(--op-fs-14);
    color: var(--op-text-muted);
}

.op-row__actions {
    display: flex;
    gap: var(--op-2);
    flex-wrap: wrap;
}

.op-card {
    background: var(--op-bg);
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-card);
    box-shadow: var(--op-shadow-card);
    padding: var(--op-4);
}

.op-card--form {
    width: 100%;
    max-width: 30em;
}

/* ── Lista de detalle (par etiqueta/valor dentro de una tarjeta) ── */
.op-detail-list {
    display: flex;
    flex-direction: column;
}

.op-detail-list__row {
    display: flex;
    justify-content: space-between;
    gap: var(--op-3);
    padding: var(--op-2) 0;
    border-bottom: 1px solid var(--op-border);
}

.op-detail-list__row:last-child {
    border-bottom: none;
}

.op-search-form {
    max-width: 26em;
}

/* ── Search — input con ícono integrado, sin botón separado ── */
.op-search {
    position: relative;
}

.op-search__icon {
    position: absolute;
    left: var(--op-3);
    top: 50%;
    transform: translateY(-50%);
    color: var(--op-text-subtle);
    pointer-events: none;
}

.op-search__input {
    padding-left: calc(var(--op-3) + 18px + var(--op-2));
}

/* ── Fila de cliente — toda la fila es clickeable ─────────
   El <a> con .op-client-row__link se estira sobre la fila (stretched-link
   de Bootstrap); las acciones necesitan z-index encima de ese overlay. */
.op-client-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--op-3);
    min-height: 44px;
    padding: var(--op-3) 0;
    border-bottom: 1px solid var(--op-border);
}

.op-client-row__link {
    position: absolute;
    inset: 0;
}

.op-client-row__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--op-accent-soft);
    color: var(--op-accent-press);
    font-size: var(--op-fs-14);
    font-weight: 500;
}

.op-client-row__body {
    flex-grow: 1;
    min-width: 0;
}

.op-client-row__name {
    display: block;
    font-size: var(--op-fs-16);
    font-weight: 500;
    color: var(--op-text);
}

.op-client-row__meta {
    font-size: var(--op-fs-14);
    color: var(--op-text-muted);
}

.op-client-row__actions {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: var(--op-2);
    flex-shrink: 0;
}

/* El menú de 3 puntos de Clientes solo aparece al hover/foco/apertura en
   dispositivos con hover (mouse). En touch (sin hover) queda siempre
   visible: no hay forma de "pasar el mouse" para revelarlo.
   Escopado a .op-client-row: .op-menu también se reutiliza en Servicios
   (kebab de la tarjeta, dropdown de Filtrar) y ahí debe verse siempre. */
@media (hover: hover) {
    .op-client-row .op-menu {
        opacity: 0;
    }

    .op-client-row:hover .op-menu,
    .op-client-row:focus-within .op-menu,
    .op-client-row .op-menu:has([aria-expanded="true"]) {
        opacity: 1;
    }
}

.op-menu {
    position: relative;
}

.op-menu__trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--op-radius-control);
    border: 1px solid var(--op-border-strong);
    background: var(--op-bg);
    color: var(--op-text-muted);
    font-size: var(--op-fs-16);
    line-height: 1;
    cursor: pointer;
}

.op-menu__trigger:hover {
    background: var(--op-surface);
}

.op-menu__list {
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-control);
    box-shadow: var(--op-shadow-card);
    padding: var(--op-1);
}

.op-menu__item {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 var(--op-3);
    border-radius: var(--op-radius-control);
    font-size: var(--op-fs-16);
    color: var(--op-bad);
}

.op-menu__item:hover,
.op-menu__item:focus-visible {
    background: var(--op-bad-soft);
    color: var(--op-bad);
}

/* Variante neutral: para items de menú que no son destructivos
   (ej. "Cambiar contraseña", "Editar", opciones de filtro). */
.op-menu__item--neutral {
    color: var(--op-text);
}

.op-menu__item--neutral:hover,
.op-menu__item--neutral:focus-visible {
    background: var(--op-surface);
    color: var(--op-text);
}

.op-menu__item--neutral[aria-current="true"] {
    background: var(--op-accent-soft);
    color: var(--op-accent-press);
}

/* ── AppointmentRow — fila de la agenda (componente clave) ──
   Hora fija a la izquierda, cliente y servicio en medio, chip a la derecha.
   Todo con tokens; nada de valores a mano. */
.op-appointment {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--op-3);
    min-height: 44px;
    padding: var(--op-3) 0;
    border-bottom: 1px solid var(--op-border);
}

/* Toda la fila es clickeable, igual que .op-client-row__link y
   .op-service-card__link: el <a> se estira sobre la fila. */
.op-appointment__link {
    position: absolute;
    inset: 0;
}

.op-appointment__time {
    font-size: var(--op-fs-16);
    font-weight: 700;
    color: var(--op-text);
    min-width: 3.5em;
    flex-shrink: 0;
}

.op-appointment__body {
    flex-grow: 1;
    min-width: 0;
}

.op-appointment__name {
    display: inline-block;
    font-size: var(--op-fs-16);
    font-weight: 500;
    color: var(--op-text);
}

.op-appointment__meta {
    font-size: var(--op-fs-14);
    color: var(--op-text-muted);
}

.op-appointment__aside {
    display: flex;
    align-items: center;
    gap: var(--op-2);
    flex-shrink: 0;
}

/* ── Tarjetas de servicio (distinto al .op-row plano de Clientes) ── */
.op-service-list {
    display: flex;
    flex-direction: column;
}

.op-service-card {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--op-3);
    background: var(--op-bg);
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-card);
    box-shadow: var(--op-shadow-card);
    /* 20px horizontal: sin token exacto en la escala base-4 (16/24), mismo
       criterio que las medidas literales ya documentadas en site.css. */
    padding: var(--op-4) 20px;
    margin-bottom: var(--op-3);
}

.op-service-card:last-child {
    margin-bottom: 0;
}

.op-service-card[hidden] {
    display: none;
}

/* Toda la tarjeta es clickeable, igual que .op-client-row__link: el <a>
   se estira sobre la tarjeta y las acciones necesitan z-index encima. */
.op-service-card__link {
    position: absolute;
    inset: 0;
}

.op-service-card__name {
    display: block;
    font-size: var(--op-fs-16);
    font-weight: 500;
    color: var(--op-text);
}

.op-service-card__meta {
    font-size: var(--op-fs-14);
    color: var(--op-text-muted);
}

.op-service-card__actions {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: var(--op-2);
    flex-shrink: 0;
}

/* Navegación entre días de la agenda */
.op-day-nav {
    display: flex;
    align-items: center;
    gap: var(--op-2);
}

.op-day-nav__label {
    font-size: var(--op-fs-20);
    font-weight: 700;
    color: var(--op-text);
}
