/* ============================================================
   mobile.css — Jobs&Dots VISUAL REDESIGN  (≤768px ONLY)
   Loaded via <link media="(max-width:768px)"> — never hits desktop.
   ============================================================ */

/* ── MOBILE TOKENS ─────────────────────────────────────────── */
:root {
  --m-gutter: 20px;
  --m-gutter-xs: 14px;
  --m-section-y: 56px;
  --m-gap: 12px;
  --m-card-pad: 18px;
  --m-bottom-nav-h: 64px;
  --m-safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* ── BODY: reserve space for bottom nav ────────────────────── */
body {
  padding-bottom: calc(var(--m-bottom-nav-h) + var(--m-safe-bottom)) !important;
}

/* ── B1: HEADER TOP OFFSET — trim excess breathing room ─────── */
/* index.html sets --header-clear = 64px + max(28px,safe-area) ≈ 92px for a
   ~58px header (≈28px of excess). Redefining the token with !important wins
   over index's @media :root and cascades to hero/sections/pages uniformly. */
:root {
  --header-clear: calc(58px + max(8px, env(safe-area-inset-top))) !important;
}

/* ── CONTAINER ─────────────────────────────────────────────── */
.container { padding: 0 var(--m-gutter) }

/* ── SECTIONS ──────────────────────────────────────────────── */
.section {
  padding: calc(var(--header-clear) + 32px) 0 var(--m-section-y);
}
.section-sm { padding: var(--m-section-y) 0 }
section { padding: var(--m-section-y) var(--m-gutter) }

/* ── HEADER: simplified ────────────────────────────────────── */
/* Bottom nav replaces hamburger — hide it */
#mobile-menu-btn { display: none !important }
/* Hide desktop auth buttons in header on mobile */
#btn-entrar, #btn-registro { display: none !important }
.header-inner { justify-content: space-between }

/* ── HERO ──────────────────────────────────────────────────── */
.hero {
  min-height: 100dvh;
  padding: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
/* Signature element: warm editorial gradient unique to job board */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 20% 15%, rgba(255,106,0,.22) 0%, transparent 55%),
    radial-gradient(ellipse at 85% 85%, rgba(255,106,0,.10) 0%, transparent 45%);
  pointer-events: none;
  z-index: 0;
}
#hero-canvas { display: none !important }
.hero-content {
  padding: calc(var(--header-clear) + 28px) var(--m-gutter) 52px;
  position: relative;
  z-index: 1;
}
/* ── BUG 4: logged-out home — excessive gap above the first element (mobile
   logo / hero). The hero is min-height:100dvh + justify-content:center, so the
   content is vertically centered, leaving a large empty band on top. Top-align
   it and clamp the container top padding to max(--header-clear + 8px, 60px) so
   the first element sits ~8-12px below the fixed header. `#app .hero(-content)`
   (1,1,0) outranks index.html's `.hero{padding:…!important}` (2347) and
   `.hero-content{padding:…!important}` (2349). */
#app .hero {
  justify-content: flex-start !important;
  padding-top: max(calc(var(--header-clear) + 8px), 60px) !important;
}
#app .hero-content { padding-top: 0 !important; }

/* ── BUG 5: logged-out home — mobile logo not centered. #hero-mobile-logo has
   inline `text-align:left`, and its 420px-wide SVG overflows narrow screens,
   pulling it left. Center the block and make the SVG responsive. */
#hero-mobile-logo { text-align: center !important; }
#hero-mobile-logo svg {
  display: block;
  margin-left: auto;
  margin-right: auto;
  max-width: 70%;
  height: auto;
}
/* Fraunces for the hero headline — editorial, distinctive */
.hero h1, .hero-h1 {
  font-family: 'Fraunces', Georgia, serif !important;
  font-size: clamp(32px, 9.5vw, 48px) !important;
  line-height: 1.08 !important;
  letter-spacing: -.035em !important;
  font-weight: 700 !important;
  margin-bottom: 18px;
}
.hero-sub {
  font-size: 15px;
  line-height: 1.65;
  color: var(--text-muted);
  max-width: 100%;
  margin-bottom: 32px;
}
.hero-ctas {
  flex-direction: column !important;
  align-items: stretch !important;
  gap: 10px !important;
}
.hero-ctas .btn {
  width: 100% !important;
  justify-content: center !important;
  padding: 16px 24px !important;
  font-size: 15px !important;
  font-weight: 600 !important;
  border-radius: 14px !important;
}
.hero-ctas .btn-primary {
  box-shadow: 0 0 40px rgba(255,106,0,.35) !important;
}
.hero-badges {
  flex-wrap: wrap !important;
  justify-content: flex-start !important;
  gap: 8px !important;
  margin-top: 24px;
}
.hero-stats {
  flex-direction: row !important;
  justify-content: space-between !important;
  margin-top: 40px;
  padding: 20px 16px;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-lg);
  gap: 0 !important;
}
.stat-divider {
  display: block !important;
  width: 1px;
  background: var(--card-border);
  align-self: stretch;
}
.stat-num { font-size: 22px !important; font-weight: 700 }
.stat-item { text-align: center; flex: 1; padding: 0 8px }

/* ── SEARCH BAR ────────────────────────────────────────────── */
.search-bar, .search-box {
  flex-direction: column !important;
  padding: 14px !important;
  gap: 10px !important;
  border-radius: 18px !important;
  background: var(--bg3) !important;
  border: 1px solid var(--card-border-strong) !important;
}
.search-bar input, .search-field {
  width: 100% !important;
  min-width: 0 !important;
}
.search-bar button, .search-btn {
  width: 100% !important;
  justify-content: center !important;
  border-radius: 10px !important;
}

/* ── SECTION TITLES with orange underline accent ───────────── */
/* NOTE: .section-title is a legacy/unused class in index.html. The real
   landing-section headings are bare <h2> inside <section><div class="container">.
   There are only 6 <section> elements (all landing), so `section h2` is safe.
   The bar is centered to match the centered landing section headers. */
.section-title {
  font-size: clamp(24px, 6vw, 32px) !important;
  letter-spacing: -.025em;
}
/* Underline accent only (don't resize the real inline-styled headings).
   section h2 = the 4 landing section headers; each section has exactly one. */
.section-title::after,
section h2::after {
  content: '';
  display: block;
  width: 36px;
  height: 3px;
  background: var(--orange);
  border-radius: 2px;
  margin: 12px auto 0;
}
.section-sub {
  font-size: 14px;
  color: var(--text-muted);
  margin-top: 16px;
}

/* ── JOB CARDS: left orange border, arrow indicator ────────── */
.job-cards-grid {
  grid-template-columns: 1fr !important;
  gap: 10px !important;
}
.job-card {
  padding: var(--m-card-pad) !important;
  border-left: 3px solid var(--orange) !important;
  border-radius: var(--radius) !important;
  background: rgba(255,255,255,.05) !important;
  border-top: 1px solid var(--card-border) !important;
  border-right: 1px solid var(--card-border) !important;
  border-bottom: 1px solid var(--card-border) !important;
}
/* No ::after arrow — each card already renders a "Ver oferta ›" button. */
.job-title {
  font-size: 15px !important;
  font-weight: 600 !important;
  line-height: 1.3;
}
.job-tags { flex-wrap: wrap !important; gap: 4px !important; margin-top: 10px }

/* ── BUG 2: protect the job-card footer (meta + "Ver oferta") — keep it a
   single nowrap row so the button stays anchored right and never drops to a
   new line / shifts left. The meta block shrinks; the button doesn't. */
.offers-page #jobs-list .job-card > div:last-child {
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
}
.offers-page #jobs-list .job-card > div:last-child > div:first-child {
  min-width: 0 !important;
  overflow: hidden !important;
}
.offers-page #jobs-list .job-card .btn { flex-shrink: 0 !important; }

/* ── PRICING / PLAN CARDS ──────────────────────────────────── */
.pricing-grid, .plan-grid { grid-template-columns: 1fr !important }
.plan-card { padding: 24px 20px !important; border-radius: var(--radius-lg) }
.plan-price { font-size: 40px !important; letter-spacing: -.03em }

/* ── STEPS / TRUST / GRIDS ─────────────────────────────────── */
.steps-grid, .trust-grid, .footer-grid, .offers-layout {
  grid-template-columns: 1fr !important;
  gap: var(--m-gap) !important;
}
.step-card, .trust-card { padding: var(--m-card-pad) !important }

/* ── DUAL CTA ──────────────────────────────────────────────── */
.dual-cta .flex { flex-direction: column !important; gap: 16px !important }
.dual-card { padding: 28px 20px !important; min-width: 0 !important; width: 100% }

/* ── KPI / METRICS (2-col) ─────────────────────────────────── */
.kpi-grid { grid-template-columns: 1fr 1fr !important; gap: 10px !important }
.kpi-card { padding: 14px !important; border-radius: var(--radius) }
.ats-metric { padding: 12px 14px !important }
.ats-metric-val { font-size: 22px !important; font-weight: 700 }

/* ── DASHBOARD / SIDEBAR ───────────────────────────────────── */
.dashboard, .dashboard-layout, .dash-layout {
  flex-direction: column !important;
}
.sidebar, .dash-sidebar {
  width: 100% !important;
  min-width: 0 !important;
  height: auto !important;
  position: static !important;
  border-right: none !important;
  border-bottom: 1px solid var(--card-border) !important;
  flex-direction: row !important;
  overflow-x: auto !important;
  gap: 4px !important;
  padding: 8px !important;
  -webkit-overflow-scrolling: touch;
}
.sidebar::-webkit-scrollbar { display: none }
.sidebar-link {
  padding: 8px 12px !important;
  font-size: 11px !important;
  white-space: nowrap !important;
  flex-shrink: 0 !important;
  border-radius: 8px !important;
}
.sidebar-label { display: none !important }
.dash-content {
  margin-left: 0 !important;
  padding: 16px !important;
  width: 100% !important;
  min-width: 0 !important;
}

/* ── KANBAN (touch scroll) ─────────────────────────────────── */
.kanban {
  display: flex !important;
  flex-direction: row !important;
  overflow-x: auto !important;
  gap: 12px !important;
  padding-bottom: 12px !important;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.kanban::-webkit-scrollbar { display: none }
.kanban-col {
  min-width: 270px !important;
  flex-shrink: 0 !important;
  scroll-snap-align: start;
}

/* ── TABLES (touch scroll) ─────────────────────────────────── */
.table-wrapper, .offers-table {
  overflow-x: auto !important;
  -webkit-overflow-scrolling: touch;
}
.data-table { min-width: 480px !important }
.data-table th, .data-table td {
  padding: 10px 12px !important;
  font-size: 12px !important;
}

/* ── FORMS ─────────────────────────────────────────────────── */
.register-box { padding: 28px 20px !important; border-radius: var(--radius-xl) }
.register-box h2 { font-size: 22px !important }
.form-row, .offer-form .form-grid-2 {
  grid-template-columns: 1fr !important;
  flex-direction: column !important;
}
.step-actions { flex-direction: column !important; gap: 10px !important }
.step-actions .btn { width: 100% !important; justify-content: center !important }
/* iOS zoom guard: no font-size below 16px on inputs */
input:not([type=checkbox]):not([type=radio]):not([type=range]),
select, textarea { font-size: 16px !important }

/* ── B2: MODALS → BOTTOM SHEETS (slide-up · drag handle · backdrop-close) ──
   Unifies a prior inconsistency: index.html only turned .modal into a
   bottom-sheet at ≤480px while mobile.css top-anchored it 481–768px (they
   fought at ≤480). Now EVERY class-based .modal-overlay/.modal dialog is one
   consistent bottom sheet across the whole ≤768px range. Open/close is still
   driven entirely by index.html's `.modal-overlay.active` toggle (openModal/
   closeModal) and the global backdrop-tap close at index.html:3205 — we only
   restyle and animate; no JS open/close logic is touched. */
/* NOTE on specificity: index.html's inline <style> (line ~2720) loads AFTER
   this file and carries `.modal{width:…!important}` plus per-id rules like
   `#modal-oferta .modal`. To win deterministically without touching those
   desktop-leaking rules, every declaration below is scoped under
   `.modal-overlay …` (≥2 classes) and the two wide modals get an id-bearing
   override. */
.modal-overlay {
  padding: 0 !important;
  align-items: flex-end !important;   /* sheet sticks to bottom edge */
  overflow: hidden !important;        /* the sheet scrolls, not the backdrop */
}
.modal-overlay .modal {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  max-height: 90dvh !important;
  overflow-y: auto !important;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0 !important;
  margin: 0 !important;
  padding-top: 26px;                                       /* room for handle */
  padding-bottom: calc(24px + var(--m-safe-bottom)) !important;
  transform: translateY(100%);
  transition: transform .32s cubic-bezier(.32, .72, 0, 1);
}
/* Wide modals (#modal-oferta/#modal-editar-oferta) carry id-specific inline
   widths — match their specificity + win to force full-bleed sheets. */
#modal-oferta.modal-overlay .modal,
#modal-editar-oferta.modal-overlay .modal { width: 100% !important; max-width: 100% !important; }
/* Slide up only while the overlay is active (the class index.html toggles). */
.modal-overlay.active .modal { transform: translateY(0); }

/* Drag-handle affordance — pure CSS, no DOM change, appears on every sheet.
   position:sticky keeps it pinned while the sheet content scrolls. */
.modal-overlay .modal::before {
  content: '';
  position: sticky;
  top: 0;
  display: block;
  width: 38px;
  height: 4px;
  margin: -14px auto 14px;
  background: var(--card-border-strong, #555);
  border-radius: 2px;
  flex-shrink: 0;
  z-index: 2;
}
/* Chat modal is already a custom flex bottom-sheet (padding:0) — skip handle
   so it doesn't get a negative-margin clip. */
#modal-chat .modal { padding-top: 0 !important; }
#modal-chat .modal::before { display: none; }

/* Generic fallback for any other sheet-like container that ISN'T a .modal. */
[class*="modal"]:not(.modal-overlay):not(.modal-close):not(.modal),
[class*="sheet"]:not(#m-settings-sheet),
[id*="modal"]:not(.modal-overlay),
[id*="sheet"] {
  width: calc(100vw - 16px) !important;
  max-width: 100% !important;
  min-width: 0 !important;
  max-height: 90dvh !important;
  overflow-y: auto !important;
  border-radius: var(--radius-xl) !important;
  margin: 0 auto !important;
}
.modal-close,
[class*="modal-close"],
[class*="sheet-close"] {
  min-width: 44px !important;
  min-height: 44px !important;
}
@media (prefers-reduced-motion: reduce) {
  .modal { transition: none; }
}

/* ── FOOTER ────────────────────────────────────────────────── */
.footer { padding: 40px var(--m-gutter) 24px !important }

/* ── FINAL CTA ─────────────────────────────────────────────── */
.final-cta { padding: 56px var(--m-gutter) !important }
.cta-btns { flex-direction: column !important; align-items: stretch !important; gap: 10px !important }
.cta-btns .btn { width: 100% !important; justify-content: center !important }

/* ── B4: PROFILE (mi-perfil) — mobile layout ───────────────── */
/* index.html mi-perfil uses padding-top:156px, an absolute banner inset
   left/right:48px, and an absolute avatar at top:145px — all too large on
   phones. Pull the top offset down to the header clearance and shrink the
   banner insets so the avatar/header read correctly. */
#miperfil-banner {
  left: var(--m-gutter) !important;
  right: var(--m-gutter) !important;
  height: 140px !important;
}
.profile-grid, .perfil-grid, [class*="profile-layout"] {
  grid-template-columns: 1fr !important;
  flex-direction: column !important;
}
.profile-card, .perfil-card {
  padding: var(--m-card-pad) !important;
  width: 100% !important;
}

/* ── B5: UNA PAUSA + CHATBOT — sit above bottom nav ────────── */
#pausa-btn {
  bottom: calc(var(--m-bottom-nav-h) + var(--m-safe-bottom) + 12px) !important;
  right: 14px !important;
  z-index: 1500 !important;
  min-height: 44px !important;
}
#chatbot-bubble {
  bottom: calc(var(--m-bottom-nav-h) + var(--m-safe-bottom) + 68px) !important;
  right: 16px !important;
  z-index: 1500 !important;
  width: 48px !important;
  height: 48px !important;
}
/* Chat panel opens above the bubble, clear of the bottom nav, full width */
#chatbot-window {
  bottom: calc(var(--m-bottom-nav-h) + var(--m-safe-bottom) + 124px) !important;
  right: 8px !important;
  left: 8px !important;
  width: auto !important;
  max-width: 100% !important;
  z-index: 1500 !important;
}

/* ── B6: OFERTAS listing — full-width single column ────────── */
.ofertas-grid, .job-list, .offers-list,
[class*="ofertas-list"], [class*="jobs-grid"],
.offers-page .job-cards-grid {
  grid-template-columns: 1fr !important;
  gap: 10px !important;
}
.oferta-card, .job-item, [class*="oferta-card"] {
  width: 100% !important;
  border-radius: var(--radius) !important;
  padding: var(--m-card-pad) !important;
  border-left: 3px solid var(--orange) !important;
}

/* ── B7: SETTINGS BOTTOM SHEET (language only) ─────────────── */
#m-settings-sheet {
  position: fixed;
  bottom: calc(var(--m-bottom-nav-h) + var(--m-safe-bottom));
  left: 0; right: 0;
  background: var(--bg2);
  border-top: 1px solid var(--card-border);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  padding: 20px var(--m-gutter) 24px;
  z-index: 1800;
  transform: translateY(110%);
  transition: transform .3s ease;
  box-shadow: 0 -8px 32px rgba(0,0,0,.4);
}
#m-settings-sheet.open { transform: translateY(0); }
#m-settings-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.5);
  z-index: 1799;
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}
#m-settings-backdrop.open { opacity: 1; pointer-events: auto; }
#m-settings-sheet-title {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 16px;
  color: var(--text);
}
#m-settings-langs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
#m-settings-langs button {
  flex: 1 0 28%;
  min-height: 44px;
  background: var(--bg3);
  border: 1px solid var(--card-border);
  border-radius: 10px;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#m-settings-langs button:active { background: rgba(255,106,0,.15); }
#m-settings-desktop-msg {
  font-size: 13px;
  color: var(--text-dim);
  margin-top: 16px;
  padding: 12px;
  border: 1px solid var(--card-border);
  border-radius: var(--radius-sm, 8px);
}
#m-settings-close {
  position: absolute;
  top: 12px; right: 12px;
  min-width: 44px; min-height: 44px;
  background: none; border: none;
  color: var(--text-muted);
  font-size: 22px; line-height: 1; cursor: pointer;
}

/* ── FIX 1: hide header search + bell on mobile ────────────── */
/* The bell ACTION moves to the bottom nav ("Avisos"). We hide the bell ICON
   (#hin-bell) but NOT #bell-wrap — because #bell-dropdown is a child of the
   wrap and must stay renderable so the bottom nav can open it. */
.h-int-search,
#header-search-results,
#hin-bell {
  display: none !important;
}
#bell-wrap { margin: 0 !important; }
/* Notif dropdown: full-width on mobile (index sets right:80px;width:340px
   which overflows narrow screens). */
#bell-dropdown {
  top: calc(var(--header-clear) + 4px) !important;
  left: 8px !important;
  right: 8px !important;
  width: auto !important;
  max-width: 100% !important;
}

/* ── FIX 3: notification badge on the "Avisos" nav item ────── */
.m-nav-item[data-badge]::after {
  content: attr(data-badge);
  position: absolute;
  top: 2px;
  right: calc(50% - 20px);
  min-width: 16px;
  height: 16px;
  background: var(--orange);
  color: #fff;
  border-radius: 8px;
  font-size: 9px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  padding: 0 4px;
  pointer-events: none;
}

/* ── FIX 4: logout button inside settings sheet ────────────── */
#m-settings-logout {
  width: 100%;
  margin-top: 20px;
  padding: 14px;
  background: rgba(255,80,80,.08);
  border: 1px solid rgba(255,80,80,.22);
  border-radius: var(--radius-sm, 8px);
  color: var(--error, #FF5050);
  font-size: 14px;
  font-weight: 600;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  min-height: 48px;
  display: block;
  -webkit-tap-highlight-color: transparent;
}
#m-settings-logout:active { background: rgba(255,80,80,.18); }

/* ── PROBLEMA 1: OFERTAS FILTERS — sticky trigger + bottom-sheet panel ─────
   Showing the desktop .filters-panel inline on mobile was unusable. Now the
   panel is parked off-screen and slides up as a bottom sheet when the injected
   full-width #m-filter-btn ("Filtrar ofertas") is tapped. JS (initFilterSheet)
   toggles .m-filters-open + a backdrop; "Aplicar filtros" / backdrop tap close
   it. Selector .offers-page .filters-panel (0,2,0) beats the bare inline
   `.filters-panel{display:none}` (0,1,0) regardless of source order. */
@media (max-width: 768px) {
  /* Sticky full-width trigger above the listing */
  #m-filter-btn {
    display: flex !important;
    align-items: center;
    justify-content: center;
    gap: 8px;
    position: sticky;
    top: calc(var(--header-clear) + 4px);
    z-index: 90;
    width: 100%;
    height: 44px;
    margin: 0 0 16px;
    background: var(--bg3, rgba(255,255,255,.04));
    border: 1px solid var(--orange);
    border-radius: 12px;
    color: var(--orange);
    font-size: 14px;
    font-weight: 600;
    font-family: 'Inter', sans-serif;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  #m-filter-btn svg { stroke: var(--orange); flex-shrink: 0; }
  #m-filter-btn:active { background: rgba(255,106,0,.14); }

  /* BUG 1: in place the panel stays hidden — index.html sets #app.style.transform
     on every nav (index.html:3150), which makes #app the containing block for
     position:fixed, so a fixed panel inside .offers-page anchors to the page
     (appears at its bottom, off-screen) instead of the viewport. Fix: JS
     (openFilterSheet) PORTALS the panel to <body> and tags it .m-filters-portal;
     these body-level rules then position it as a real viewport bottom sheet. */
  .offers-page .filters-panel { display: none !important; }

  /* Portaled bottom sheet (child of <body>, so no .offers-page ancestor) */
  .filters-panel.m-filters-portal {
    display: flex !important;
    flex-direction: column;
    gap: 14px;
    background: var(--bg2) !important;
    border: none !important;
    border-top: 1px solid var(--card-border) !important;
    position: fixed !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    max-height: 85dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    z-index: 2010;
    margin: 0 !important;
    border-radius: 16px 16px 0 0 !important;
    box-shadow: 0 -8px 32px rgba(0,0,0,.45);
    transform: translateY(110%);
    transition: transform .3s ease;
    padding: 16px !important;
    padding-bottom: calc(16px + var(--m-safe-bottom)) !important;
  }
  .filters-panel.m-filters-portal.m-filters-open { transform: translateY(0); }

  /* PASO 2 redesign: label above each control, full-width 44px inputs */
  .filters-panel.m-filters-portal .filter-section { margin: 0 !important; }
  .filters-panel.m-filters-portal .filter-section h4 {
    font-size: 12px !important;
    color: var(--text-dim) !important;
    margin-bottom: 4px !important;
    letter-spacing: 0 !important;
  }
  .filters-panel.m-filters-portal .input,
  .filters-panel.m-filters-portal input:not([type=checkbox]):not([type=radio]),
  .filters-panel.m-filters-portal select {
    width: 100% !important;
    min-height: 44px !important;
    font-size: 16px !important;
    border-radius: 10px !important;
    box-sizing: border-box !important;
  }
  /* Hide secondary filters on mobile (gated by class added in JS, so desktop
     is untouched). Keep: contrato, modalidad, salario, ubicación. */
  .m-filter-section-hidden { display: none !important; }

  /* Secondary "Limpiar filtros" link below Aplicar (injected by JS) */
  #m-clear-filters {
    background: none;
    border: none;
    color: var(--text-dim);
    font-size: 13px;
    font-family: 'Inter', sans-serif;
    padding: 6px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  /* Backdrop injected by initFilterSheet() */
  #m-filter-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.5);
    z-index: 2005;
    opacity: 0;
    pointer-events: none;
    transition: opacity .3s ease;
  }
  #m-filter-backdrop.open { opacity: 1; pointer-events: auto; }

  /* ── FIX 1: ordenación ("Más recientes"/"Más valoradas") — the native
     <select> #filtro-orden mis-anchors its OS picker because #app carries a
     transform on every nav (index.html:3150), so the picker opens far from the
     field. Replace it with a custom bottom-sheet picker (initSortSheet in
     mobile-enhance.js) whose sheet is portaled to <body> (no transformed
     ancestor). The native select stays in the DOM (hidden) as the value source
     that applyFilters() reads. */
  /* BUG 2: scope the page-header column layout to a class added by JS to the
     page top-bar only (the count + sort control), so it can never cascade into
     anything else. */
  .offers-page .offers-header.m-offers-topbar {
    flex-direction: column !important;
    align-items: stretch !important;
  }
  .offers-page #filtro-orden { display: none !important; }
  #m-sort-btn {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    min-height: 44px;
    padding: 0 14px;
    background: var(--bg3, rgba(255,255,255,.04));
    border: 1px solid var(--card-border);
    border-radius: 10px;
    color: var(--text);
    font-size: 15px;
    font-family: 'Inter', sans-serif;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  #m-sort-btn svg { stroke: var(--text-dim); flex-shrink: 0; }
  #m-sort-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.5);
    z-index: 2015;
    opacity: 0;
    pointer-events: none;
    transition: opacity .3s ease;
  }
  #m-sort-backdrop.open { opacity: 1; pointer-events: auto; }
  #m-sort-sheet {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: var(--bg3, var(--bg2));
    border-radius: 16px 16px 0 0;
    /* above the bottom nav (z 2000) so the whole sheet is visible */
    z-index: 2020;
    max-height: 60dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 8px 0 calc(16px + var(--m-safe-bottom));
    transform: translateY(110%);
    transition: transform .3s ease;
    box-shadow: 0 -8px 32px rgba(0,0,0,.45);
  }
  #m-sort-sheet.open { transform: translateY(0); }
  #m-sort-sheet .m-sort-title {
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--text-dim);
    font-weight: 600;
    padding: 12px 16px 8px;
  }
  .m-sort-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 14px 16px;
    min-height: 48px;
    background: none;
    border: none;
    color: var(--text);
    font-size: 15px;
    font-family: 'Inter', sans-serif;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .m-sort-option.active { color: var(--orange); font-weight: 600; }
  .m-sort-option:active { background: rgba(255,255,255,.06); }

  /* ── PROBLEMA 2: OFERTAS double scroll — the document is the only scroller.
     Release any viewport-locked height / inner overflow on the offers-page
     containers so content flows in one page scroll. The filters bottom sheet
     above is fixed-positioned and keeps its own overflow-y, so it's excluded. */
  .offers-page,
  .offers-page .container,
  .offers-layout,
  .offers-page aside,
  .offers-page #jobs-list,
  .offers-page .offers-header {
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow: visible !important;
  }
}

/* ══════════════ PASS 4 FIXES ══════════════ */

/* ── FIX 1: re-enable text selection on mobile ─────────────── */
/* (A7: index.html has NO global user-select:none — only the CV watermark and
   blocked/blurred content. This is a defensive enable so text inside onclick
   cards can be long-pressed/selected; buttons stay non-selectable.) */
body, p, h1, h2, h3, h4, span, li, td, th,
.card, [class*="card"], [class*="content"], [class*="text"], [class*="desc"] {
  -webkit-user-select: text !important;
  user-select: text !important;
}
button, [role="button"], .btn, a {
  -webkit-user-select: none !important;
  user-select: none !important;
}

/* ── FIX 2: header transparent (home) / hide-on-scroll-down ── */
#main-header { transition: background .3s ease, transform .3s ease; }
#main-header.m-header-transparent {
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border-bottom-color: transparent !important;
  box-shadow: none !important;
}
#main-header.m-header-hidden {
  transform: translateY(-110%) !important;
}

/* ── FIX 3: Avisos full-page overlay ───────────────────────── */
#m-avisos-page {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 1900;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .3s ease;
}
#m-avisos-page.open { transform: translateX(0); }
#m-avisos-header {
  display: flex;
  align-items: center;
  gap: 12px;
  /* BUG 4a / 6b: the avisos overlay (z-index 1900) sits ON TOP of the site
     header (z-index 900), so it needs no header clearance — only safe-area.
     The old calc(--header-clear + 8px) left a ~74px empty gap above "‹ Avisos". */
  padding: calc(env(safe-area-inset-top, 0px) + 12px) var(--m-gutter) 14px;
  border-bottom: 1px solid var(--card-border);
  background: var(--bg2);
  flex-shrink: 0;
}
#m-avisos-back {
  background: none;
  border: none;
  color: var(--text);
  cursor: pointer;
  min-width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  -webkit-tap-highlight-color: transparent;
}
#m-avisos-back:active { background: rgba(255,255,255,.06); }
#m-avisos-title {
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
}
#m-avisos-content {
  flex: 1;
  overflow-y: auto;
  padding: 16px var(--m-gutter)
           calc(var(--m-bottom-nav-h) + var(--m-safe-bottom) + 16px);
  -webkit-overflow-scrolling: touch;
}
#m-avisos-content .notification,
#m-avisos-content [class*="notif-item"],
#m-avisos-content [class*="bell-item"] {
  position: static !important;
  width: 100% !important;
  border-radius: var(--radius) !important;
  margin-bottom: 10px !important;
  padding: var(--m-card-pad) !important;
}

/* ── FIX 4: dashboard empresa mobile ───────────────────────── */
#app[data-mpage="dashboard-empresa"] .dashboard {
  padding-top: calc(var(--header-clear) + 8px) !important;
}
/* Hide crowding header actions (publish still reachable via the dashboard's
   own panel navigation / sidebar). */
button[onclick*="compartirPaginaEmpresa"],
.btn-purple[onclick*="nueva-oferta"] {
  display: none !important;
}
/* "El equipo de VengaJobs…" banner: stack, tighter padding */
.banner-agencia {
  flex-direction: column !important;
  align-items: flex-start !important;
  padding: var(--m-card-pad) !important;
  gap: 10px !important;
}

/* ── FIX 7: ofertas "Aplicar filtros" submit button ────────── */
#m-apply-filters {
  width: 100%;
  margin-top: 4px;
  height: 48px;
  padding: 0 14px;
  background: var(--orange);
  border: none;
  border-radius: 12px;
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  min-height: 48px;
  -webkit-tap-highlight-color: transparent;
}
#m-apply-filters:active { background: var(--orange-deep, #E55F00); }

/* ── FIX 8: inicio candidato/empresa panels (inline-styled) ── */
/* These pages have no ids/classes — scoped via #app[data-mpage]. */
#app[data-mpage="inicio-candidato"] > div,
#app[data-mpage="inicio-empresa"] > div {
  padding-top: calc(var(--header-clear) + 8px) !important;
}
#app[data-mpage="inicio-candidato"] [style*="padding:28px 40px"],
#app[data-mpage="inicio-empresa"] [style*="padding:28px 40px"] {
  padding: 20px var(--m-gutter) !important;
}
#app[data-mpage="inicio-candidato"] [style*="repeat(3,1fr)"],
#app[data-mpage="inicio-empresa"] [style*="repeat(3,1fr)"],
#app[data-mpage="inicio-candidato"] [style*="repeat(2,1fr)"],
#app[data-mpage="inicio-empresa"] [style*="repeat(2,1fr)"] {
  grid-template-columns: 1fr !important;
}

/* ── BUG 1 (CAMBIO 1 & 2): inicio empresa/candidato — 3 pasos en vertical.
   Antes dependía de #app[data-mpage="inicio-*"], que initPageEnhancements()
   asigna de forma asíncrona → en la primera carga el atributo aún no está y los
   pasos se veían en horizontal. Ahora usa la clase .m-inicio-steps (presente en
   el HTML desde el render) → sin flash y sin depender de data-mpage. */
.m-inicio-steps {
  display: flex !important;
  flex-direction: column !important;
  gap: 12px !important;
}
.m-inicio-steps > div {
  width: 100% !important;
  margin-bottom: 0 !important;
  padding: 16px !important;
  border-radius: 12px !important;
  display: grid !important;
  grid-template-columns: auto 1fr !important;
  column-gap: 12px !important;
  align-items: center !important;
}
/* número (empresa) o icono (candidato) = primer hijo → columna izquierda,
   abarcando ambas filas (título + descripción) */
.m-inicio-steps > div > div:first-child {
  grid-row: 1 / span 2 !important;
  margin-bottom: 0 !important;
  align-self: center !important;
}
/* BUG 1: ocultar "Completar perfil" en el inicio de candidato (móvil) */
.m-inicio-hide { display: none !important; }

/* ── CAMBIO 3: candidato dashboard — "Ver más ofertas" + "Ver mi CV" en fila,
   y panel inline (toggle) con selector de formato + CV en solo lectura.
   Inyectado por initCVPanel() en mobile-enhance.js. */
.m-cv-btn-row {
  display: flex;
  gap: 10px;
  width: 100%;
}
.m-cv-btn-row .m-cv-btn-secondary,
.m-cv-btn-row #m-ver-cv-btn {
  flex: 1 !important;
  height: 44px !important;
  min-height: 44px !important;
  border-radius: 10px !important;
  font-size: 14px !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.m-cv-btn-row .m-cv-btn-secondary {
  background: transparent !important;
  border: 1px solid var(--orange) !important;
  color: var(--orange) !important;
}
#m-ver-cv-btn {
  background: var(--orange);
  color: #fff;
  font-weight: 600;
  border: none;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
#m-cv-panel { display: none; margin: 16px 0; }
#m-cv-panel.open { display: block; }
#m-cv-tabs { display: flex; gap: 6px; margin-bottom: 12px; }
.m-cv-tab {
  flex: 1;
  height: 40px;
  border-radius: 8px;
  border: 1px solid var(--card-border);
  background: var(--bg2);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.m-cv-tab.active {
  background: var(--orange);
  color: #fff;
  border-color: var(--orange);
}
/* CAMBIO 1: un único scroll (el de la página). Sin altura fija ni overflow
   propio — el CV crece en altura natural. */
#m-cv-doc-wrap {
  border-radius: 12px;
  background: #fff;
}
/* read-only: hide any edit/save action buttons that render inside the viewer */
#m-cv-doc [onclick*="editar"],
#m-cv-doc [onclick*="guardar"],
#m-cv-doc .btn-editar,
#m-cv-doc .cv-edit-btn { display: none !important; }

/* ── Panel lateral de "Mi CV" (desktop .cv-panel) reubicado debajo del CV en
   móvil. Inyectado por buildCVPanel()/populateSidePanel() en mobile-enhance.js.
   El contenido reusa clases globales (.upgrade-box, .badge, .btn); aquí solo
   damos el apilado vertical a ancho completo y el espaciado. */
#m-cv-side {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#m-cv-side .btn { width: 100%; }

/* CAMBIO 2: el botón "Crear alerta" (#alertas-container) debe tener el mismo
   formato que "Descargar PDF" (#btn-descargar-pdf): full-width, texto centrado,
   padding 13px 16px, font-size 14px, peso 600. El botón original es btn-sm con
   font-size:12px inline, así que forzamos con !important. */
#alertas-container button[onclick*="abrirModalNuevaAlerta"] {
  display: flex !important;
  width: 100% !important;
  padding: 13px 16px !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  align-items: center !important;
  justify-content: center !important;
}

/* CAMBIO 6: el logo del header móvil (#header-logo-mobile-header, visible en las
   páginas internas) es demasiado pequeño. Lo aumentamos ~28% (160x35 → 205x45)
   manteniendo el centrado (el contenedor usa left:50% + translateX(-50%)). */
#header-logo-mobile-header svg {
  width: 205px !important;
  height: 45px !important;
}

/* CAMBIOS 4 & 5: aviso "disponible en escritorio" (inyectado por showDesktopOnly
   en mobile-enhance.js). Modal mínimo, centrado, coherente con tokens. */
.m-desktop-only-overlay {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0,0,0,.6);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.m-desktop-only-card {
  width: 100%;
  max-width: 340px;
  background: var(--bg2);
  border: 1px solid var(--card-border);
  border-radius: 18px;
  padding: 28px 24px;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0,0,0,.45);
}
.m-desktop-only-icon { font-size: 40px; margin-bottom: 12px; }
.m-desktop-only-card h3 {
  font-size: 18px;
  font-weight: 800;
  color: var(--text);
  margin: 0 0 10px;
  font-family: 'Inter', sans-serif;
}
.m-desktop-only-card p {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-muted);
  margin: 0 0 18px;
}
.m-desktop-only-link {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 13px 16px;
  margin-bottom: 10px;
  border-radius: 12px;
  background: var(--orange);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  font-family: 'Inter', sans-serif;
}
.m-desktop-only-close {
  display: block;
  width: 100%;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid var(--card-border);
  background: transparent;
  color: var(--text-muted);
  font-size: 14px;
  font-weight: 600;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ── CAMBIO 4: ocultar "+ Nueva" en la vista de Avisos (clase añadida por JS) */
.m-hidden { display: none !important; }

/* ── FIX 2: al abrir "Ver mi CV", oculta el listado de candidaturas (clase
   añadida por toggleCVPanel) para que no se duplique bajo el CV. */
.m-cv-hidden { display: none !important; }

/* ── FIX 3: home empresa — ocultar los CTAs "Publicar una oferta" y
   "Ver candidatos" en móvil (no tienen id/clase propios → por su onclick). */
#app[data-mpage="inicio-empresa"] button[onclick*="_requestedPanel='nueva-oferta'"],
#app[data-mpage="inicio-empresa"] button[onclick*="_requestedPanel='candidatos'"] {
  display: none !important;
}

/* ── BOTTOM NAVIGATION BAR ─────────────────────────────────── */
#m-bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: calc(var(--m-bottom-nav-h) + var(--m-safe-bottom));
  z-index: 2000;
  display: flex;
  align-items: flex-start;
  padding: 8px 8px 0;
  padding-bottom: var(--m-safe-bottom);
  background: rgba(10,10,10,.9);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border-top: 1px solid rgba(255,255,255,.09);
  gap: 4px;
}
.m-nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 50px;
  min-height: 50px;
  background: none;
  border: none;
  cursor: pointer;
  border-radius: 12px;
  padding: 0 4px;
  color: var(--text-dim);
  transition: color .15s ease, background .15s ease;
  position: relative;
  -webkit-tap-highlight-color: transparent;
}
.m-nav-item svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  stroke-width: 1.8;
}
.m-nav-label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .01em;
  line-height: 1;
  font-family: 'Inter', sans-serif;
}
.m-nav-item.active { color: var(--orange) }
.m-nav-item.active::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 24px;
  height: 2px;
  background: var(--orange);
  border-radius: 0 0 3px 3px;
}
.m-nav-item:active { background: rgba(255,255,255,.06) }
.m-nav-item:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}
/* FAB: center Publicar item elevated */
.m-nav-fab {
  color: #fff !important;
  background: var(--orange) !important;
  border-radius: 14px !important;
  height: 50px !important;
  margin-top: -10px !important;
  box-shadow: 0 4px 20px rgba(255,106,0,.45) !important;
  flex: 1.1;
}
.m-nav-fab::before { display: none !important }
.m-nav-fab svg { width: 20px !important; height: 20px !important }
.m-nav-fab .m-nav-label { font-size: 9px !important }
.m-nav-fab:active { background: var(--orange-deep) !important; transform: scale(.97) }

/* ── FOCUS / A11Y ──────────────────────────────────────────── */
#mobile-nav-overlay a:focus-visible,
#mobile-nav-overlay button:focus-visible,
#mobile-menu-btn:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

/* ══════════════ PASS 5 — TACTILE FEEDBACK & SHEET POLISH ══════════════ */

/* ── TOUCH PRESS STATES — kill sticky :hover, add :active scale ──────────
   On touch the desktop :hover (translateY(-2px) glow on primary/purple,
   translateX(4px) on .job-card) latches after a tap and only clears on the
   next tap elsewhere. Neutralise those transforms at ≤768px and give every
   interactive element an immediate press response instead. */
.btn-primary:hover, .btn-purple:hover, .btn-secondary:hover,
.btn-outline:hover, .btn-ghost:hover,
.job-card:hover, .plan-card:hover, .step-card:hover, .trust-card:hover {
  transform: none !important;
}
.job-card:hover::before { background: transparent !important; }
.btn:active,
button:not(.m-nav-item):not(.modal-close):active,
[role="button"]:active {
  transform: scale(.97) !important;
  opacity: .88;
  transition: transform .1s ease, opacity .1s ease;
}
.job-card:active, .oferta-card:active,
.plan-card:active, .step-card:active, .trust-card:active,
.dual-card:active, [class*="oferta-card"]:active {
  transform: scale(.99) !important;
  transition: transform .1s ease;
}

/* ══════════════ PASS 6 — DASHBOARD MOBILE BUG FIXES ══════════════ */
@media (max-width: 768px) {

  /* ── BUG 3: DASHBOARD EXCESSIVE TOP MARGIN ───────────────────────────
     index.html:2591 forces `.dashboard{padding-top:calc(64px+max(28px,
     safe))}` ≈ 92px — ~26px more than the real header clearance. Pin it to
     --header-clear + 10px. `#app .dashboard` (1,1,0) outranks the inline
     `.dashboard` (0,1,0) rule deterministically, regardless of source order,
     and covers both empresa & candidate dashboards. */
  #app .dashboard {
    padding-top: calc(var(--header-clear) + 4px) !important;
  }
  /* PROBLEMA 3: pull the first content block ("El equipo de VengaJobs…")
     tight under the header. dash-content's 16px top padding stacked on top of
     the dashboard offset left too much air above the first .dash-panel block.
     `main.dash-content` (0,1,1 + !important) outranks index's
     `.dash-content{padding:16px!important}` and trims only the top. */
  .dash-content,
  main.dash-content {
    padding-top: 12px !important;
  }
  /* PROBLEMA 3b: the dashboard sidebar is the horizontal nav bar on mobile and
     the only entry point to its panels (equipo / archivadas / reseñas /
     analytics / extranjería) — so keep it visible, but strip its dead vertical
     space: hide the decorative brand block (logo + name + "Verificada") and
     tighten padding so the nav links sit as a slim strip under the header. */
  .dashboard .sidebar { padding: 6px 8px !important; }
  .dashboard .sidebar .sidebar-nav > div:first-child { display: none !important; }

  /* ── BUG 2: DOUBLE SCROLL — single page scroll only ──────────────────
     The dashboard shell and main content carry viewport-locked heights
     (.dashboard{min-height:100dvh}, .dash-content{min-height:calc(100dvh-
     108px)}, base .sidebar{height:calc(100dvh-108px);overflow-y:auto}) that
     spawn an inner scroller alongside the document scroll. Release the heights
     and the inner vertical overflow so content flows in ONE page scroll.
     NOTE: the mobile sidebar is intentionally a HORIZONTAL scroller
     (overflow-x:auto), so it is deliberately excluded here — only its locked
     height is freed, never its overflow-x. */
  #app .dashboard {
    min-height: 0 !important;
    height: auto !important;
    overflow: visible !important;
  }
  .dash-content,
  main.dash-content {
    min-height: 0 !important;
    height: auto !important;
    max-height: none !important;
    overflow-y: visible !important;
  }
  .sidebar,
  .dash-sidebar {
    height: auto !important;
    max-height: none !important;   /* free the locked height; keep overflow-x */
  }

  /* ── PROBLEMA 4: ANALYTICS "Rendimiento por oferta" → vertical cards ──
     The multi-column table (5–9 cols) is unreadable on a phone even with a
     horizontal scroll. Hide the table outright and let buildAnalyticsCards()
     (mobile-enhance.js) render one card per row into a
     .m-analytics-cards-container inserted just before each table. */
  #dash-panel-analytics table { display: none !important; }
  .m-analytics-cards-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 0 var(--m-gutter) 16px;
  }
  .m-analytics-card {
    background: var(--card);
    border: 1px solid var(--card-border);
    border-radius: 10px;
    padding: 14px;
  }
  .m-analytics-card-title {
    font-size: 16px;
    font-weight: 700;
    line-height: 1.3;
    margin-bottom: 12px;
    color: var(--text);
  }
  .m-analytics-card-metrics {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px 14px;
  }
  .m-analytics-metric {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }
  .m-analytics-metric .m-metric-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--text-dim);
    line-height: 1.2;
  }
  .m-analytics-metric .m-metric-value {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    line-height: 1.3;
    overflow-wrap: anywhere;
  }
  .table-wrapper {
    display: block !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  .data-table { min-width: 520px !important; }

  /* ── BUG 5: dashboard empresa "Mis ofertas" table — Oferta/Candidatos
     columns overlap. Root cause: index's `.data-table{table-layout:fixed}`
     with only a 35% first-column hint crushes the other 4 columns. Switch to
     content-sized columns (table-layout:auto) + nowrap and let the
     .table-wrapper scroll horizontally (Opción B: 5 columns). */
  #mis-ofertas-tabla.table-wrapper { overflow-x: auto !important; }
  #mis-ofertas-tabla .data-table {
    table-layout: auto !important;
    min-width: 600px !important;
  }
  #mis-ofertas-tabla .data-table th,
  #mis-ofertas-tabla .data-table td {
    white-space: nowrap !important;
    overflow: visible !important;
  }
  #mis-ofertas-tabla .data-table th:first-child,
  #mis-ofertas-tabla .data-table td:first-child { width: auto !important; }
  /* the title cell stacks a title + a meta sub-line; let that sub wrap so the
     first column doesn't stretch the whole table excessively */
  #mis-ofertas-tabla .data-table td:first-child > div { white-space: normal; }
}

/* ══════════════ BUG 1 & 7 — OFFER-DETAIL MODALS: SINGLE SCROLL ══════════════ */
/* "Ver oferta" (openJobDetail → #modal-oferta) and the candidate offer modal
   (#modal-oferta-detalle) showed a double scroll: the overlay scrolled (it
   carries an inline `overflow-y:auto`, and #modal-oferta-detalle's .modal even
   has inline `max-height:none`) AND the sheet scrolled. Lock the overlay, make
   the .modal the ONLY scroller (max-height:90dvh; overflow-y:auto), and free
   every inner child so nothing nests a second scroll. */
@media (max-width: 768px) {
  #modal-oferta.modal-overlay,
  #modal-oferta-detalle.modal-overlay {
    overflow: hidden !important;
  }
  #modal-oferta.modal-overlay .modal,
  #modal-oferta-detalle.modal-overlay .modal {
    max-height: 90dvh !important;
    overflow-y: auto !important;
  }
  #modal-oferta-content,
  #modal-oferta-detalle-content,
  #modal-oferta.modal-overlay .modal > *,
  #modal-oferta-detalle.modal-overlay .modal > * {
    max-height: none !important;
    height: auto !important;
    overflow: visible !important;
  }
}

/* ── SMALL PHONES ≤480px ───────────────────────────────────── */
@media (max-width: 480px) {
  :root { --m-gutter: var(--m-gutter-xs) }
  section { padding: 40px var(--m-gutter-xs) }
  .kpi-grid { grid-template-columns: 1fr !important }
  .hero h1, .hero-h1 { font-size: clamp(28px, 9.5vw, 36px) !important }
  .hero-stats { flex-direction: column !important; gap: 16px }
  .stat-divider { display: none !important }
  .stat-item { width: 100%; padding: 0 }
  .m-nav-label { font-size: 9px }
}

/* ── CTA VengaJobs — headhunting cross-sell ───────────────── */
@media (max-width: 768px) {
  .cta-vengajobs-block {
    padding: 16px;
    margin-top: 20px;
  }
  .cta-vengajobs-inner {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .cta-vengajobs-text { min-width: 0 }
  .cta-vengajobs-btn {
    width: 100%;
    justify-content: center;
  }
}

/* ════════════════════════════════════════════════════════════════
   AUDIT MOBILE — vistas/forms/modals no adaptados (430px)
   Causa raíz: grids definidos en estilo INLINE (no en clases), por lo
   que las reglas class-based de arriba no los alcanzan. Se colapsan con
   selectores de atributo [style*=…], scoped por ruta (#app[data-mpage])
   o por id de panel/modal. Misma técnica ya usada arriba (~l.958-962).
   Nada de esto toca index.html ni el desktop.
   ════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {

  /* ── 🔴 Fix A: forms con sidebar de ANCHO FIJO → 1 columna
        (si no, el formulario queda comprimido a ~130px e inutilizable) ── */
  #dash-panel-nueva-oferta [style*="grid-template-columns:1fr 300px"],
  #app[data-mpage="perfil-empresa-editar"] [style*="grid-template-columns:1fr 260px"] {
    grid-template-columns: 1fr !important;
  }

  /* ── 🔴 Fix B: grids de 3 y 4 columnas (inline) → 1 columna ── */
  #dash-panel-nueva-oferta [style*="1fr 1fr 1fr"],
  #app[data-mpage="perfil-empresa-editar"] [style*="1fr 1fr 1fr"],
  #app[data-mpage="trabaja-con-nosotros"] [style*="1fr 1fr 1fr"],
  #app[data-mpage="registro-empresa"] [style*="repeat(3,1fr)"],
  #app[data-mpage="asesoria-laboral"] [style*="repeat(3,1fr)"],
  #app[data-mpage="asesoria-laboral"] [style*="repeat(4,1fr)"],
  #modal-editar-oferta [style*="1fr 1fr 1fr"] {
    grid-template-columns: 1fr !important;
  }

  /* ── 🔴 Fix D: editar-perfil — el preview A4 (#cv-preview-edit, 210mm
        ≈ 794px) provoca desbordamiento horizontal. Se oculta en mobile;
        la edición ocupa todo el ancho y el CV se ve en la ruta dedicada
        cv-preview (ya adaptada). ── */
  #app[data-mpage="editar-perfil"] #cv-preview-edit { display: none !important; }

  /* ── 🟡 Fix C: filas de formulario de 2 col (inline) → apilar.
        (incluye el split form|preview de editar-perfil y la sección de
        equipo de como-funciona). Scoped a rutas tipo formulario/contenido,
        no afecta a tarjetas 2-col intencionales de otras vistas. ── */
  #app[data-mpage="registro-candidato"] [style*="grid-template-columns:1fr 1fr"],
  #app[data-mpage="registro-empresa"] [style*="grid-template-columns:1fr 1fr"],
  #app[data-mpage="editar-perfil"] [style*="grid-template-columns:1fr 1fr"],
  #app[data-mpage="perfil-empresa-editar"] [style*="grid-template-columns:1fr 1fr"],
  #app[data-mpage="asesoria-laboral"] [style*="grid-template-columns:1fr 1fr"],
  #app[data-mpage="como-funciona"] [style*="grid-template-columns:1fr 1fr"],
  #dash-panel-nueva-oferta [style*="grid-template-columns:1fr 1fr"] {
    grid-template-columns: 1fr !important;
  }
}

/* ════════════════════════════════════════════════════════════════
   FIXES MÓVIL — PANEL EMPRESA (FIX-MOB-1..8)
   8 correcciones puntuales: ocultar entradas a vistas no adaptadas
   (expedientes), reforzar scroll de modales densos y dar colchón para
   el teclado virtual. Solo ≤768px; nada toca index.html ni el desktop.
   ════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {

  /* FIX-MOB-1: la página "Expedientes" (Extranjería) no tiene adaptación
     móvil. Ocultar TODAS sus entradas en inicio-empresa: la tarjeta
     "Expedientes parados" (#ie-urgencias) y la tarjeta destacada
     (#ie-exp-top), ambas con onclick="nav('expedientes')" exacto. */
  [onclick="nav('expedientes')"] {
    display: none !important;
  }

  /* FIX-MOB-2: el modal "Nuevo expediente" (#modal-nuevo-expediente) es un
     overlay custom (no .modal-overlay) que el fallback genérico rompe en
     móvil. Ocultar sus disparadores hasta que se adapte. */
  #btn-nuevo-expediente,
  [onclick="abrirNuevoExpediente()"] {
    display: none !important;
  }

  /* FIX-MOB-5: modal-candidato-ats (ficha ATS, contenido denso) — el .modal
     es el único scroller; el contenido fluye sin segundo scroll anidado. */
  #modal-candidato-ats .modal {
    max-height: 88vh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
  #modal-candidato-ats-content {
    max-height: none !important;
    overflow: visible !important;
  }

  /* FIX-MOB-6: modal-editar-oferta (formulario largo) — scroll reforzado y
     colchón inferior para que Cancelar/Guardar queden alcanzables. */
  #modal-editar-oferta .modal {
    max-height: 90vh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding-bottom: 80px !important;
  }
  #modal-editar-oferta .modal form {
    overflow-y: visible !important;
    max-height: none !important;
  }

  /* FIX-MOB-8: modal-invitar-seat (dinámico, .modal-overlay) — scroll +
     espacio para el teclado virtual al enfocar nombre/email. */
  #modal-invitar-seat .modal {
    max-height: 85vh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding-bottom: 60px !important;
  }
}
