{"id":737,"date":"2026-02-11T18:52:14","date_gmt":"2026-02-11T23:52:14","guid":{"rendered":"https:\/\/onetapdock.com\/menu\/"},"modified":"2026-02-18T20:01:13","modified_gmt":"2026-02-19T01:01:13","slug":"menu","status":"publish","type":"page","link":"https:\/\/onetapdock.com\/en\/menu\/","title":{"rendered":"Menu"},"content":{"rendered":"<!doctype html>\n<html lang=\"es-PE\">\n<head>\n  <meta charset=\"utf-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\" \/>\n  <title>Men\u00fa \u2014 OneTap Voice<\/title>\n\n  <style>\n    \/* =================== MEN\u00da MINIMALISTA (sin fondo) =================== *\/\n    :root{\n      --text:#111;\n      --muted:#666;\n      --rule:#e7e7e7;\n      --max: 900px;\n      --padX: clamp(16px, 4.4vw, 22px);\n      --padY: clamp(40px, 7vw, 80px);\n      --player-space: 210px; \/* espacio para que el player no tape contenido *\/\n    }\n    *{ box-sizing:border-box; }\n    body{\n      margin:0;\n      color:var(--text);\n      font-family: -apple-system, BlinkMacSystemFont, \"Helvetica Neue\", Arial, sans-serif;\n      line-height:1.6;\n      background:#fff;\n    }\n    #tts-content{\n      max-width: var(--max);\n      margin: 0 auto;\n      padding: var(--padY) var(--padX) calc(var(--player-space) + env(safe-area-inset-bottom));\n    }\n    header.menu-head{\n      text-align:center;\n      margin-bottom: clamp(44px, 7vw, 70px);\n    }\n    header.menu-head h1{\n      margin:0;\n      font-size: clamp(34px, 6.5vw, 48px);\n      font-weight: 600;\n      letter-spacing:-0.02em;\n    }\n    header.menu-head p{\n      margin: 12px 0 0;\n      font-size: clamp(16px, 3.6vw, 18px);\n      color: var(--muted);\n    }\n\n    section.menu-sec{ margin-bottom: clamp(46px, 6.5vw, 70px); }\n    section.menu-sec h2{\n      margin:0 0 26px;\n      font-size: 22px;\n      letter-spacing: .15em;\n      font-weight: 600;\n    }\n\n    .item{ margin-bottom: 28px; }\n    .item:last-child{ margin-bottom: 0; }\n\n    .row{\n      display:flex;\n      justify-content:space-between;\n      gap: 18px;\n      align-items: baseline;\n    }\n    .name{\n      margin:0;\n      font-size: 20px;\n      font-weight: 500;\n      letter-spacing: -0.01em;\n      min-width: 0;\n    }\n    .price{\n      margin:0;\n      font-size: 18px;\n      font-weight: 500;\n      white-space: nowrap;\n    }\n    .desc{\n      margin: 6px 0 0;\n      color: var(--muted);\n    }\n\n    .simple-list .item{ margin-bottom: 14px; }\n    .simple-list .name,\n    .simple-list .price{ font-size: 18px; font-weight: 450; }\n\n    \/* =================== OneTap Voice \u2014 Floating Liquid Glass (NEGRO) =================== *\/\n    :root{\n      --otv-radius: 999px;\n      --otv-shadow: 0 7px 20px rgba(0,0,0,.10);\n      --otv-border: rgba(0,0,0,.10);\n      --otv-glass: rgba(255,255,255,.80);\n      --otv-glass2: rgba(255,255,255,.55);\n      --otv-text: rgba(0,0,0,.92);\n      --otv-muted: rgba(0,0,0,.58);\n      --otv-btn-bg: rgba(0,0,0,.05);\n      --otv-btn-bd: rgba(0,0,0,.10);\n      --otv-btn-bg-h: rgba(0,0,0,.08);\n    }\n\n    .otv-float{\n      position: fixed;\n      left: 50%;\n      transform: translateX(-50%);\n      bottom: calc(12px + env(safe-area-inset-bottom));\n      z-index: 999999;\n      width: min(980px, calc(100vw - 16px));\n      pointer-events: none;\n    }\n\n    .otv-pill{\n      pointer-events: auto;\n      position: relative;\n      display: grid;\n      grid-template-columns: 1fr auto;\n      gap: 10px;\n      align-items: center;\n\n      border-radius: var(--otv-radius);\n      border: 1px solid var(--otv-border);\n      background:\n        radial-gradient(900px 120px at 20% 0%, rgba(255,255,255,.75), transparent 60%),\n        linear-gradient(180deg, var(--otv-glass), var(--otv-glass2));\n      backdrop-filter: blur(18px) saturate(160%);\n      -webkit-backdrop-filter: blur(18px) saturate(160%);\n      box-shadow: var(--otv-shadow);\n      overflow: hidden;\n      padding: 10px;\n    }\n    .otv-pill::before{\n      content:\"\";\n      position:absolute;\n      inset:0;\n      border-radius: var(--otv-radius);\n      pointer-events:none;\n      border: 1px solid rgba(255,255,255,.55);\n      mask: linear-gradient(#000, transparent 72%);\n      opacity:.6;\n    }\n\n    .otv-left{\n      min-width: 0;\n      display:flex;\n      gap: 10px;\n      align-items:center;\n      padding-left: 6px;\n    }\n    .otv-badge{\n      width: 44px;\n      height: 44px;\n      border-radius: 16px;\n      background: rgba(255,255,255,.60);\n      border: 1px solid rgba(0,0,0,.08);\n      display:grid;\n      place-items:center;\n      flex: 0 0 auto;\n    }\n    .otv-badge svg{ width: 22px; height: 22px; color: var(--otv-text); opacity:.95; }\n\n    \/* \u2705 Meta responsive: 2 l\u00edneas sin ser tapado *\/\n    .otv-meta{\n      min-width: 0;\n      display:flex;\n      flex-direction: column;\n      gap: 2px;\n      padding-right: 8px;\n    }\n    .otv-title{\n      font-weight: 800;\n      letter-spacing: -0.01em;\n      color: var(--otv-text);\n      white-space: nowrap;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      font-size: 14px;\n      line-height: 1.15;\n    }\n    .otv-sub{\n      font-weight: 650;\n      color: var(--otv-muted);\n      overflow: hidden;\n      text-overflow: ellipsis;\n      display: -webkit-box;\n      -webkit-line-clamp: 2;\n      -webkit-box-orient: vertical;\n      line-height: 1.2;\n      font-size: 12px;\n      max-height: calc(1.2em * 2);\n    }\n\n    .otv-right{\n      display:flex;\n      gap: 8px;\n      align-items:center;\n      padding-right: 4px;\n      flex: 0 0 auto;\n    }\n\n    .otv-btn{\n      width: 46px;\n      height: 46px;\n      border-radius: 18px;\n      border: 1px solid var(--otv-btn-bd);\n      background: var(--otv-btn-bg);\n      color: var(--otv-text);\n      display:grid;\n      place-items:center;\n      cursor:pointer;\n      user-select:none;\n      transition: transform .08s ease, background .18s ease, border-color .18s ease;\n    }\n    .otv-btn:hover{ background: var(--otv-btn-bg-h); border-color: rgba(0,0,0,.14); }\n    .otv-btn:active{ transform: scale(.98); }\n    .otv-btn:focus-visible{ outline: 3px solid rgba(0,0,0,.18); outline-offset: 3px; }\n    .otv-btn.primary{\n      background: rgba(0,0,0,.92);\n      color: rgba(255,255,255,.95);\n      border-color: rgba(0,0,0,.85);\n    }\n    .otv-btn svg{ width: 20px; height: 20px; }\n\n    .otv-drawer{\n      pointer-events: auto;\n      margin-top: 10px;\n      border-radius: 22px;\n      border: 1px solid rgba(0,0,0,.10);\n      background: rgba(255,255,255,.75);\n      backdrop-filter: blur(18px) saturate(160%);\n      -webkit-backdrop-filter: blur(18px) saturate(160%);\n      box-shadow: 0 18px 60px rgba(0,0,0,.12);\n      overflow:hidden;\n\n      max-height: 0;\n      opacity: 0;\n      transform: translateY(6px);\n      transition: max-height .22s ease, opacity .18s ease, transform .18s ease;\n    }\n    .otv-float.is-open .otv-drawer{\n      max-height: 120px;\n      opacity: 1;\n      transform: translateY(0);\n    }\n    .otv-drawer-inner{\n      padding: 12px 14px 14px;\n      display:flex;\n      gap: 12px;\n      align-items:center;\n      flex-wrap: wrap;\n    }\n    .otv-rate{\n      flex: 1 1 520px;\n      display:flex;\n      gap: 10px;\n      align-items:center;\n      padding: 12px 12px;\n      border-radius: 16px;\n      border: 1px solid rgba(0,0,0,.10);\n      background: rgba(0,0,0,.04);\n      color: var(--otv-text);\n    }\n    .otv-rate label{\n      font-size: 12px;\n      font-weight: 800;\n      color: var(--otv-muted);\n      white-space: nowrap;\n    }\n    .otv-rate input[type=\"range\"]{ width: 100%; accent-color: rgba(0,0,0,.85); }\n    .otv-rateval{\n      min-width: 56px;\n      text-align:right;\n      font-variant-numeric: tabular-nums;\n      font-weight: 900;\n      color: var(--otv-text);\n    }\n\n    .otv-reading{\n      outline: 2px solid rgba(0,0,0,.18);\n      outline-offset: 6px;\n      border-radius: 12px;\n      scroll-margin-bottom: 160px;\n    }\n\n    @media (max-width: 560px){\n      .otv-left{ gap: 8px; padding-left: 4px; }\n      .otv-badge{ width: 40px; height: 40px; border-radius: 14px; }\n      .otv-btn{ width: 42px; height: 42px; border-radius: 16px; }\n      .otv-right{ gap: 6px; }\n      .otv-title{ font-size: 13px; }\n      .otv-sub{ font-size: 12px; }\n    }\n    @media (prefers-reduced-motion: reduce){\n      .otv-drawer{ transition:none; }\n      .otv-btn{ transition:none; }\n    }\n  <\/style>\n<\/head>\n\n<body>\n\n  <!-- =================== MEN\u00da (ejemplo) =================== -->\n  <div id=\"tts-content\">\n    <header class=\"menu-head\">\n      <h1>RESTAURANTE AURORA<\/h1>\n      <p>Cocina Contempor\u00e1nea \u00b7 Sabores de Autor<\/p>\n    <\/header>\n\n    <section class=\"menu-sec\">\n      <h2>ENTRADAS<\/h2>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Tiradito de Salm\u00f3n Andino<\/h3>\n          <span class=\"price\">39 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Salm\u00f3n fresco, leche de tigre de maracuy\u00e1, aceite de cilantro y crocante de quinua.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Burrata &#038; Prosciutto<\/h3>\n          <span class=\"price\">42 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Burrata italiana, prosciutto, tomates confitados y reducci\u00f3n bals\u00e1mica.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Causa Lime\u00f1a de Langostinos<\/h3>\n          <span class=\"price\">36 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Causa tradicional con langostinos salteados y alioli de aj\u00ed amarillo.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Pulpo a la Parrilla<\/h3>\n          <span class=\"price\">48 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Pulpo grillado, papas nativas y salsa anticuchera suave.<\/p>\n      <\/div>\n    <\/section>\n\n    <section class=\"menu-sec\">\n      <h2>PLATOS PRINCIPALES<\/h2>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Risotto de Lomo Fino<\/h3>\n          <span class=\"price\">65 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Risotto cremoso con lomo salteado, champi\u00f1ones y parmesano.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Salm\u00f3n en Costra de Hierbas<\/h3>\n          <span class=\"price\">62 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Con pur\u00e9 r\u00fastico y vegetales asados.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Fettuccine Trufado<\/h3>\n          <span class=\"price\">58 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Pasta fresca, crema de trufa negra y l\u00e1minas de parmesano.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Arroz Meloso de Mariscos<\/h3>\n          <span class=\"price\">68 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Langostinos, calamar y pulpo en fondo marino especiado.<\/p>\n      <\/div>\n    <\/section>\n\n    <section class=\"menu-sec\">\n      <h2>PARRILLA<\/h2>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Bife Ancho Angus (300g)<\/h3>\n          <span class=\"price\">85 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Con papas fritas artesanales o ensalada fresca.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Tomahawk (Para compartir)<\/h3>\n          <span class=\"price\">165 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Corte premium acompa\u00f1ado de vegetales grillados.<\/p>\n      <\/div>\n    <\/section>\n\n    <section class=\"menu-sec\">\n      <h2>OPCIONES LIGERAS<\/h2>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Ensalada Aurora<\/h3>\n          <span class=\"price\">34 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Mix de hojas, palta, fresas, nueces caramelizadas y queso azul.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Bowl Mediterr\u00e1neo<\/h3>\n          <span class=\"price\">32 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Quinua, garbanzos, vegetales grillados y salsa tahini.<\/p>\n      <\/div>\n    <\/section>\n\n    <section class=\"menu-sec\">\n      <h2>POSTRES<\/h2>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Volc\u00e1n de Chocolate<\/h3>\n          <span class=\"price\">29 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Con helado artesanal de vainilla.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Cheesecake de Maracuy\u00e1<\/h3>\n          <span class=\"price\">27 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Base crocante y coulis natural.<\/p>\n      <\/div>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <h3 class=\"name\">Cr\u00e8me Br\u00fbl\u00e9e<\/h3>\n          <span class=\"price\">28 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Cl\u00e1sico franc\u00e9s con costra caramelizada.<\/p>\n      <\/div>\n    <\/section>\n\n    <section class=\"menu-sec simple-list\">\n      <h2>COCTELER\u00cdA<\/h2>\n\n      <div class=\"item\">\n        <div class=\"row\">\n          <span class=\"name\">Chilcano Cl\u00e1sico<\/span>\n          <span class=\"price\">32 soles<\/span>\n        <\/div>\n        <p class=\"desc\">Pisco, ginger ale y lim\u00f3n.<\/p>\n      <\/div>\n\n      <div class=\"item\"><div class=\"row\"><span class=\"name\">Margarita de Maracuy\u00e1<\/span><span class=\"price\">34 soles<\/span><\/div><\/div>\n      <div class=\"item\"><div class=\"row\"><span class=\"name\">Aperol Spritz<\/span><span class=\"price\">36 soles<\/span><\/div><\/div>\n      <div class=\"item\"><div class=\"row\"><span class=\"name\">Negroni<\/span><span class=\"price\">38 soles<\/span><\/div><\/div>\n    <\/section>\n\n    <section class=\"menu-sec simple-list\">\n      <h2>BEBIDAS<\/h2>\n      <div class=\"item\"><div class=\"row\"><span class=\"name\">Agua sin gas \/ con gas<\/span><span class=\"price\">10 soles<\/span><\/div><\/div>\n      <div class=\"item\"><div class=\"row\"><span class=\"name\">Gaseosas<\/span><span class=\"price\">9 soles<\/span><\/div><\/div>\n      <div class=\"item\"><div class=\"row\"><span class=\"name\">Caf\u00e9 Espresso<\/span><span class=\"price\">8 soles<\/span><\/div><\/div>\n      <div class=\"item\"><div class=\"row\"><span class=\"name\">Capuccino<\/span><span class=\"price\">12 soles<\/span><\/div><\/div>\n    <\/section>\n  <\/div>\n\n  <!-- =================== OneTap Voice (plantilla) =================== -->\n  <div class=\"otv-float\" id=\"otvFloat\" role=\"region\" aria-label=\"OneTap Voice\">\n    <div class=\"otv-pill\">\n      <div class=\"otv-left\">\n        <div class=\"otv-badge\" aria-hidden=\"true\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\">\n            <path d=\"M12 3a3 3 0 0 0-3 3v6a3 3 0 1 0 6 0V6a3 3 0 0 0-3-3Z\" fill=\"currentColor\"\/>\n            <path d=\"M7 11v1a5 5 0 0 0 10 0v-1\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\/>\n            <path d=\"M12 19v2\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\/>\n          <\/svg>\n        <\/div>\n        <div class=\"otv-meta\" aria-live=\"polite\" aria-atomic=\"true\">\n          <div class=\"otv-title\" id=\"otvTitle\">OneTap Voice<\/div>\n          <div class=\"otv-sub\" id=\"otvSub\">Presiona play para leer<\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"otv-right\" aria-label=\"Controles\">\n        <button class=\"otv-btn\" id=\"otvPrev\" type=\"button\" title=\"Atr\u00e1s\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\">\n            <path d=\"M6 5v14\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\/>\n            <path d=\"M19 6l-9 6 9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n          <\/svg>\n        <\/button>\n\n        <button class=\"otv-btn primary\" id=\"otvPlayPause\" type=\"button\" title=\"Reproducir \/ Pausar\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\" id=\"otvPPIcon\">\n            <path d=\"M9 7l10 5-10 5V7z\" fill=\"currentColor\"\/>\n          <\/svg>\n        <\/button>\n\n        <button class=\"otv-btn\" id=\"otvNext\" type=\"button\" title=\"Siguiente\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\">\n            <path d=\"M18 5v14\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\/>\n            <path d=\"M5 6l9 6-9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/>\n          <\/svg>\n        <\/button>\n\n        <button class=\"otv-btn\" id=\"otvStop\" type=\"button\" title=\"Detener\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\">\n            <rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"2\" fill=\"currentColor\"\/>\n          <\/svg>\n        <\/button>\n\n        <button class=\"otv-btn\" id=\"otvMore\" type=\"button\" title=\"Opciones\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\">\n            <path d=\"M6 12h.01M12 12h.01M18 12h.01\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\"\/>\n          <\/svg>\n        <\/button>\n      <\/div>\n    <\/div>\n\n    <div class=\"otv-drawer\" aria-label=\"Opciones de lectura\">\n      <div class=\"otv-drawer-inner\">\n        <div class=\"otv-rate\" role=\"group\" aria-label=\"Velocidad de lectura\">\n          <label for=\"otvRate\">Velocidad<\/label>\n          <input id=\"otvRate\" type=\"range\" min=\"0.7\" max=\"1.4\" step=\"0.1\" value=\"1.0\" \/>\n          <div class=\"otv-rateval\" id=\"otvRateVal\">1.0\u00d7<\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <script>\n    (function(){\n      const $ = (s, r=document) => r.querySelector(s);\n\n      const floatEl = $(\"#otvFloat\");\n      const titleEl = $(\"#otvTitle\");\n      const subEl   = $(\"#otvSub\");\n\n      const btnPrev = $(\"#otvPrev\");\n      const btnPP   = $(\"#otvPlayPause\");\n      const btnNext = $(\"#otvNext\");\n      const btnStop = $(\"#otvStop\");\n      const btnMore = $(\"#otvMore\");\n\n      const ppIcon  = $(\"#otvPPIcon\");\n\n      const rateEl  = $(\"#otvRate\");\n      const rateVal = $(\"#otvRateVal\");\n\n      const root = document.getElementById(\"tts-content\") || document.body;\n\n      \/\/ \u2705 Cola estable: se crea al dar Play (snapshot)\n      let queue = [];      \/\/ [{el, text}]\n      let qIndex = 0;\n\n      \/\/ \u2705 Runner robusto para m\u00f3viles (evita saltos por callbacks raros)\n      let runId = 0;\n      let playingAll = false;\n\n      const clean = (t) => (t||\"\").replace(\/\\u00A0\/g,\" \").replace(\/\\s+\/g,\" \").trim();\n\n      function setPlayIcon(state){\n        if(state === \"pause\"){\n          ppIcon.innerHTML = '<rect x=\"7\" y=\"6\" width=\"3\" height=\"12\" rx=\"1\" fill=\"currentColor\"><\/rect><rect x=\"14\" y=\"6\" width=\"3\" height=\"12\" rx=\"1\" fill=\"currentColor\"><\/rect>';\n        } else {\n          ppIcon.innerHTML = '<path d=\"M9 7l10 5-10 5V7z\" fill=\"currentColor\"><\/path>';\n        }\n      }\n\n      function setStatus(text){ subEl.textContent = text; }\n\n      function clearHighlight(){\n        document.querySelectorAll(\".otv-reading\").forEach(el => el.classList.remove(\"otv-reading\"));\n      }\n\n      function highlight(el){\n        clearHighlight();\n        if(!el) return;\n        el.classList.add(\"otv-reading\");\n        \/\/ \u2705 NO auto-scroll: evita reflow que rompe TTS en m\u00f3viles\n      }\n\n      function buildQueue(){\n        const out = [];\n\n        \/\/ Lectura estructurada: secciones -> categor\u00eda -> platos (orden garantizado)\n        const sections = Array.from(root.querySelectorAll(\"section.menu-sec\"));\n\n        if(sections.length){\n          for(const sec of sections){\n            const h2 = sec.querySelector(\"h2\");\n            const cat = clean(h2?.textContent || \"\");\n            if(cat) out.push({ el: h2 || sec, text: cat });\n\n            const items = Array.from(sec.querySelectorAll(\".item\"));\n            for(const it of items){\n              const name  = clean(it.querySelector(\".name\")?.textContent || \"\");\n              const desc  = clean(it.querySelector(\".desc\")?.textContent || \"\");\n              const price = clean(it.querySelector(\".price\")?.textContent || \"\");\n\n              const line = clean(`${name}${price ? `. Precio: ${price}` : \"\"}${desc ? `. ${desc}` : \"\"}`);\n              if(line) out.push({ el: it, text: line });\n            }\n          }\n          return out;\n        }\n\n        \/\/ Fallback general\n        return Array.from(root.querySelectorAll(\"h1,h2,h3,p,li\"))\n          .map(el => ({ el, text: clean(el.textContent) }))\n          .filter(x => x.text.length >= 6);\n      }\n\n      function chooseVoice(){\n        const voices = window.speechSynthesis?.getVoices ? window.speechSynthesis.getVoices() : [];\n        return voices.find(v => (v.lang || \"\").toLowerCase().startsWith(\"es\")) || null;\n      }\n\n      function stopAll(msg){\n        runId++;\n        playingAll = false;\n        clearHighlight();\n        setPlayIcon(\"play\");\n        if(\"speechSynthesis\" in window) window.speechSynthesis.cancel();\n        if(msg) setStatus(msg);\n      }\n\n      function speakOnce(text, localRunId, ondone){\n        if(!(\"speechSynthesis\" in window)){\n          setStatus(\"Tu navegador no soporta lectura por voz.\");\n          return;\n        }\n\n        window.speechSynthesis.cancel();\n\n        const u = new SpeechSynthesisUtterance(text);\n        u.lang = \"es-PE\";\n        u.rate = Number(rateEl.value || 1.0);\n        u.pitch = 1;\n\n        const v = chooseVoice();\n        if(v) u.voice = v;\n\n        let called = false;\n        const done = () => {\n          if(called) return;\n          called = true;\n          if(localRunId !== runId) return;\n          ondone && ondone();\n        };\n\n        u.onend = done;\n        u.onerror = done;\n\n        window.speechSynthesis.speak(u);\n      }\n\n      function playFrom(index){\n        queue = buildQueue();\n        if(!queue.length){\n          setStatus(\"No encontr\u00e9 texto para leer.\");\n          return;\n        }\n\n        runId++;\n        const localRunId = runId;\n\n        qIndex = Math.max(0, Math.min(index, queue.length - 1));\n        playingAll = true;\n        setPlayIcon(\"pause\");\n\n        const step = () => {\n          if(localRunId !== runId) return;\n          if(!playingAll) return;\n\n          if(qIndex >= queue.length){\n            playingAll = false;\n            setPlayIcon(\"play\");\n            setStatus(\"Fin del men\u00fa.\");\n            return;\n          }\n\n          const { el, text } = queue[qIndex];\n          highlight(el);\n          setStatus(`Leyendo ${qIndex + 1} de ${queue.length} \u00b7 ${Number(rateEl.value || 1).toFixed(1)}\u00d7`);\n\n          speakOnce(text, localRunId, () => {\n            if(localRunId !== runId) return;\n            qIndex++;\n            step();\n          });\n        };\n\n        step();\n      }\n\n      \/\/ UI\n      btnMore.addEventListener(\"click\", () => floatEl.classList.toggle(\"is-open\"));\n\n      rateVal.textContent = `${Number(rateEl.value).toFixed(1)}\u00d7`;\n      rateEl.addEventListener(\"input\", () => {\n        rateVal.textContent = `${Number(rateEl.value).toFixed(1)}\u00d7`;\n        const synth = window.speechSynthesis;\n        if(synth && (synth.speaking || synth.paused)){\n          \/\/ reinicia desde el bloque actual (no \u201cretrocede\u201d)\n          stopAll();\n          playFrom(qIndex);\n        } else {\n          setStatus(`Velocidad: ${Number(rateEl.value).toFixed(1)}\u00d7`);\n        }\n      });\n\n      btnPP.addEventListener(\"click\", () => {\n        const synth = window.speechSynthesis;\n\n        if(synth && synth.speaking && !synth.paused){\n          synth.pause();\n          playingAll = false;\n          setPlayIcon(\"play\");\n          setStatus(\"Pausado.\");\n          return;\n        }\n\n        if(synth && synth.paused){\n          synth.resume();\n          playingAll = true;\n          setPlayIcon(\"pause\");\n          setStatus(`Reproduciendo \u00b7 ${Number(rateEl.value || 1).toFixed(1)}\u00d7`);\n          return;\n        }\n\n        \/\/ arrancar desde inicio\n        playFrom(0);\n      });\n\n      btnStop.addEventListener(\"click\", () => stopAll(\"Presiona play para leer\"));\n\n      btnNext.addEventListener(\"click\", () => {\n        if(!queue.length) queue = buildQueue();\n        stopAll();\n        playFrom(Math.min(qIndex + 1, queue.length - 1));\n      });\n\n      btnPrev.addEventListener(\"click\", () => {\n        if(!queue.length) queue = buildQueue();\n        stopAll();\n        playFrom(Math.max(0, qIndex - 1));\n      });\n\n      \/\/ Init\n      titleEl.textContent = \"OneTap Voice\";\n      setStatus(\"Presiona play para leer\");\n      setPlayIcon(\"play\");\n\n      if(\"speechSynthesis\" in window && window.speechSynthesis.onvoiceschanged !== undefined){\n        window.speechSynthesis.onvoiceschanged = () => {};\n      }\n    })();\n  <\/script>\n<\/body>\n<\/html><p class=\"wp-block-paragraph\"><\/p>","protected":false},"excerpt":{"rendered":"<p>Men\u00fa \u2014 OneTap Voice RESTAURANTE AURORA Cocina Contempor\u00e1nea \u00b7 Sabores de Autor ENTRADAS Tiradito de Salm\u00f3n Andino 39 soles Salm\u00f3n fresco, leche de tigre de maracuy\u00e1, aceite de cilantro y crocante de quinua. Burrata &#038; Prosciutto 42 soles Burrata italiana, prosciutto, tomates confitados y reducci\u00f3n bals\u00e1mica. Causa Lime\u00f1a de Langostinos 36 soles Causa tradicional con [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-with-title","meta":{"_uag_custom_page_level_css":"","footnotes":""},"class_list":["post-737","page","type-page","status-publish","hentry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"trp-custom-language-flag":false,"mailpoet_newsletter_max":false,"woocommerce_thumbnail":false,"woocommerce_single":false,"woocommerce_gallery_thumbnail":false},"uagb_author_info":{"display_name":"OneTapDockWordpress","author_link":"https:\/\/onetapdock.com\/en\/author\/onetapdockwordpress\/"},"uagb_comment_info":0,"uagb_excerpt":"Men\u00fa \u2014 OneTap Voice RESTAURANTE AURORA Cocina Contempor\u00e1nea \u00b7 Sabores de Autor ENTRADAS Tiradito de Salm\u00f3n Andino 39 soles Salm\u00f3n fresco, leche de tigre de maracuy\u00e1, aceite de cilantro y crocante de quinua. Burrata &#038; Prosciutto 42 soles Burrata italiana, prosciutto, tomates confitados y reducci\u00f3n bals\u00e1mica. Causa Lime\u00f1a de Langostinos 36 soles Causa tradicional con&hellip;","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/pages\/737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/comments?post=737"}],"version-history":[{"count":18,"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/pages\/737\/revisions"}],"predecessor-version":[{"id":1180,"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/pages\/737\/revisions\/1180"}],"wp:attachment":[{"href":"https:\/\/onetapdock.com\/en\/wp-json\/wp\/v2\/media?parent=737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}