/* Employee portal mobile styles -- Asistencia PWA */
/*
 * Layered ON TOP of the design system (tokens.css -> base.css ->
 * components.css). Only portal-specific rules live here; canonical DS classes
 * (.ds-card, .ds-stack, .ds-gap-*, .ds-text-muted, h1/h2) are NOT redefined --
 * they come from the DS stylesheets so light/dark mode work for free.
 * Everything below is token-driven; the only literal is #000 on the camera
 * viewfinder.
 */

/* ── Layout ─────────────────────────────────────────── */
.ds-mobile {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: var(--ds-fs-base);
    background: var(--ds-bg-page);
    color: var(--ds-text);
    min-height: 100vh;
    min-height: 100dvh; /* dynamic viewport: no jump as the mobile URL bar shows/hides */
}

.ds-mobile__main {
    max-width: 480px;
    margin: 0 auto;
    padding: 1.5rem 1rem;
}

/* ── Form inputs ─────────────────────────────────────── */
/* The portal does NOT load Bootstrap, so .form-control gets its colors/border
 * from components.css but not Bootstrap's block/full-width reset. Provide the
 * layout here, scoped to the portal so the authenticated app is untouched. */
.ds-mobile .form-control,
.ds-mobile .form-select,
.ds-mobile textarea,
.ds-mobile input[type="text"],
.ds-mobile input[type="password"],
.ds-mobile input[type="email"],
.ds-mobile input[type="number"],
.ds-mobile input[type="date"],
.ds-mobile input[type="tel"] {
    display: block;
    width: 100%;
    box-sizing: border-box;
    min-height: 48px;
}
.ds-mobile textarea { min-height: 88px; }

/* ── Buttons ────────────────────────────────────────── */
/* Portal wants full-width, 48px+ touch targets; the DS .btn doesn't. */
.ds-btn {
    display: block;
    width: 100%;
    padding: 0.75rem 1rem;
    background: var(--ds-bg-muted);
    color: var(--ds-text);
    text-align: center;
    text-decoration: none;
    border-radius: var(--ds-radius-md);
    font-size: var(--ds-fs-base);
    font-weight: var(--ds-fw-medium);
    border: none;
    cursor: pointer;
    min-height: 48px;
    line-height: 1.4;
}
.ds-btn--primary {
    background: var(--ds-brand-600);
    color: var(--ds-text-on-brand);
}
.ds-btn--primary:hover {
    background: var(--ds-brand-700);
    color: var(--ds-text-on-brand);
}
.ds-btn--big {
    font-size: var(--ds-fs-lg);
    padding: 1rem 1.5rem;
    min-height: 60px;
    border-radius: var(--ds-radius-lg);
    font-weight: var(--ds-fw-bold);
}

/* ── Record list ─────────────────────────────────────── */
.ds-record-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.ds-record-item {
    background: var(--ds-bg-surface);
    border-radius: var(--ds-radius-md);
    padding: 0.75rem 1rem;
    display: flex;
    gap: 0.75rem;
    align-items: center;
    box-shadow: var(--ds-shadow-sm);
    font-size: var(--ds-fs-sm);
}
.ds-record__type {
    font-weight: var(--ds-fw-semibold);
    min-width: 3.5rem;
}
.ds-record__time {
    color: var(--ds-text-muted);
    flex: 1;
}
.ds-record__site {
    color: var(--ds-text-muted);
    font-size: var(--ds-fs-xs);
}

/* ── Alerts ─────────────────────────────────────────── */
.ds-alert {
    padding: 0.875rem 1rem;
    border-radius: var(--ds-radius-md);
    font-size: var(--ds-fs-sm);
    background: var(--ds-bg-muted);
    color: var(--ds-text);
}
.ds-alert--error {
    background: var(--ds-danger-bg);
    color: var(--ds-danger);
}
.ds-alert--success {
    background: var(--ds-success-bg);
    color: var(--ds-success);
}
.ds-alert--info {
    background: var(--ds-info-bg);
    color: var(--ds-info);
}
.ds-alert--warning {
    /* Used by the punch result for "fichada registrada — ubicación no
       verificada" (showResult(..., "warning")). Was previously undefined, so
       the most safety-relevant punch state rendered as a neutral grey alert. */
    background: var(--ds-warning-bg);
    color: var(--ds-warning);
}

/* ── Punch page ─────────────────────────────────────── */
.ds-mobile__punch video {
    width: 100%;
    /* Bound the live camera: a portrait stream used to grow unbounded and push
       the action buttons off-screen. Fixed aspect + cap keeps the frame in view. */
    aspect-ratio: 3 / 4;
    max-height: 60svh;
    object-fit: cover;
    border-radius: var(--ds-radius-lg);
    background: #000; /* camera viewfinder frame, not chrome -- intentional literal */
}

/* ── Nav links (pre-auth ds-mobile shell only) ───────── */
/* Scoped to .ds-mobile so it never clobbers the DS sidebar (.ds-sidebar__item)
 * used by base_portal -- that chrome is styled entirely by components.css. */
.ds-mobile nav a {
    display: flex;
    align-items: center;
    padding: 0.75rem 1rem;
    background: var(--ds-bg-surface);
    border-radius: var(--ds-radius-md);
    text-decoration: none;
    color: var(--ds-brand-600);
    font-weight: var(--ds-fw-medium);
    box-shadow: var(--ds-shadow-sm);
    min-height: 48px;
    line-height: 1.4;
}
.ds-mobile nav a:hover {
    background: var(--ds-bg-hover);
}

/* ── Portal CTA (Marcar fichada) ─────────────────────── */
.ds-portal-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/* ════════════════════════════════════════════════════════
 * Native portal shell (authenticated /app/me/*)
 * ════════════════════════════════════════════════════════
 * Renders the authenticated portal as a mobile app: a sticky header, ONE
 * scrolling content area, and a fixed bottom tab bar — not the desktop sidebar
 * grid. Safe-area insets keep chrome clear of the notch / home indicator
 * (requires viewport-fit=cover, set in base_portal.html).
 */
.ds-portal {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
    font-family: var(--ds-font-sans);
    background: var(--ds-bg-page);
    color: var(--ds-text);
}

/* ── Header (sticky, screen title + account menu) ─────── */
.ds-portal__header {
    position: sticky;
    top: 0;
    z-index: 15;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: var(--ds-topbar-h);
    padding-top: env(safe-area-inset-top);
    padding-right: max(1rem, env(safe-area-inset-right));
    padding-left: max(1rem, env(safe-area-inset-left));
    background: var(--ds-bg-surface);
    border-bottom: 1px solid var(--ds-border);
}

.ds-portal__back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-left: -0.5rem;
    flex-shrink: 0;
    border-radius: var(--ds-radius-md);
    color: var(--ds-text-muted);
    text-decoration: none;
}
.ds-portal__back:hover {
    background: var(--ds-bg-hover);
    color: var(--ds-text);
    text-decoration: none;
}

.ds-portal__title {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-size: var(--ds-fs-md);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ds-portal__header-actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
}

.ds-portal__user {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    background: transparent;
    border: none;
    cursor: pointer;
    color: var(--ds-text);
}

.ds-portal__avatar {
    width: 32px;
    height: 32px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-brand-700);
    color: var(--ds-text-on-brand);
    font-size: var(--ds-fs-xs);
    font-weight: var(--ds-fw-semibold);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
[data-bs-theme="dark"] .ds-portal__avatar { background: var(--ds-brand-500); }

/* ── Main scroller (the only scroll container) ────────── */
.ds-portal__main {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* Leave room for the fixed tab bar + the home-indicator inset it sits above. */
    padding-bottom: calc(var(--ds-tabbar-h) + env(safe-area-inset-bottom));
}

.ds-portal__content {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem max(1rem, env(safe-area-inset-right)) 1.5rem max(1rem, env(safe-area-inset-left));
}

/* Single-card screens (QR de fichada, Marcar fichada) read as a phone form on
   mobile; on desktop the lone card would float top-left in a wide column, so
   center it both axes. Mobile is untouched. */
@media (min-width: 768px) {
    .ds-portal__content--center {
        align-items: center;
        justify-content: center;
        min-height: 100%;
    }
}

/* Toasts: full-width under the sticky header, clear of the notch. */
.ds-portal .ds-alerts {
    top: calc(env(safe-area-inset-top) + var(--ds-topbar-h) + 12px);
    left: max(12px, env(safe-area-inset-left));
    right: max(12px, env(safe-area-inset-right));
    max-width: none;
}

/* ── Bottom tab bar (primary navigation) ──────────────── */
.ds-portal__tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: flex;
    background: var(--ds-bg-surface);
    border-top: 1px solid var(--ds-border);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: var(--ds-shadow-lg);
}

.ds-portal__tab {
    flex: 1;
    min-width: 0;
    min-height: var(--ds-tabbar-h);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 6px 4px;
    color: var(--ds-text-muted);
    text-decoration: none;
    font-size: var(--ds-fs-xs);
    font-weight: var(--ds-fw-medium);
    line-height: 1.1;
}
.ds-portal__tab svg { width: 22px; height: 22px; }
.ds-portal__tab:hover { color: var(--ds-text); text-decoration: none; }
.ds-portal__tab[aria-current="page"] { color: var(--ds-brand-600); }
[data-bs-theme="dark"] .ds-portal__tab[aria-current="page"] { color: var(--ds-brand-300); }
.ds-portal__tab-label {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Attendance record list (cards, not a table) ──────── */
.ds-record-item { align-items: flex-start; }
.ds-record__lead { flex-shrink: 0; }
.ds-record__body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.ds-record__when {
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text);
}
.ds-record__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    color: var(--ds-text-muted);
    font-size: var(--ds-fs-xs);
}

/* ── iOS auth zoom guard: inputs render at ≥16px so focus ─
 * never triggers Safari's auto-zoom. Scoped to both portal shells. */
.ds-portal .form-control,
.ds-portal .form-select,
.ds-portal textarea,
.ds-portal input,
.ds-mobile .form-control,
.ds-mobile .form-select,
.ds-mobile textarea,
.ds-mobile input {
    font-size: var(--ds-fs-md);
}

/* ── Reusable safe-area utilities (mobile-first pattern) ─ */
.ds-safe-top    { padding-top: max(1rem, env(safe-area-inset-top)); }
.ds-safe-bottom { padding-bottom: max(1rem, env(safe-area-inset-bottom)); }
.ds-safe-x {
    padding-right: max(1rem, env(safe-area-inset-right));
    padding-left: max(1rem, env(safe-area-inset-left));
}
