{"id":1735,"date":"2026-08-06T02:33:48","date_gmt":"2026-08-06T02:33:48","guid":{"rendered":"https:\/\/guiadeprecos.com.br\/?page_id=1735"},"modified":"2026-08-12T03:09:40","modified_gmt":"2026-08-12T03:09:40","slug":"analise-produtos","status":"publish","type":"page","link":"https:\/\/guiadeprecos.com.br\/analise-produtos\/","title":{"rendered":"An\u00e1lises de produtos"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"pt-BR\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>An\u00e1lises de Produtos \u2014 Guia de Pre\u00e7os<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,500&#038;family=Work+Sans:wght@400;500;600;700&#038;family=Space+Mono:wght@400;700&#038;display=swap\" rel=\"stylesheet\">\n<style>\n  :root{\n    --ink:#131921;\n    --navy:#232F3E;\n    --orange:#FF9900;\n    --orange-deep:#E47911;\n    --smile:#FFD814;\n    --bg:#F3F3F1;\n    --paper:#FBFAF7;\n    --text:#0F1111;\n    --muted:#565959;\n    --line:#D5D9D9;\n    --radius:10px;\n\n    \/* Tokens espec\u00edficos desta se\u00e7\u00e3o \u2014 \"arquivo de veredito\" *\/\n    --verdict-yes:#1E7B34;\n    --verdict-yes-bg:#E9F6EC;\n    --verdict-mid:#B5650A;\n    --verdict-mid-bg:#FDF1E3;\n    --verdict-no:#B3261E;\n    --verdict-no-bg:#FBEAE9;\n    --tab-shadow: 0 1px 0 rgba(0,0,0,.04);\n  }\n\n  *{box-sizing:border-box;}\n  html{scroll-behavior:smooth;}\n  body{\n    margin:0;\n    background:var(--bg);\n    color:var(--text);\n    font-family:'Work Sans', sans-serif;\n    -webkit-font-smoothing:antialiased;\n  }\n  img{max-width:100%;display:block;}\n  a{color:inherit;}\n\n  .wrap{max-width:1180px;margin:0 auto;padding:0 24px;}\n\n  \/* ---------- HEADER ---------- *\/\n  .top-bar{\n    background:var(--navy);\n    color:#fff;\n    font-family:'Space Mono', monospace;\n    font-size:12px;\n    letter-spacing:.04em;\n    text-transform:uppercase;\n    padding:10px 0;\n  }\n  .top-bar .wrap{display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;}\n  .top-bar a{text-decoration:none; opacity:.85;}\n  .top-bar a:hover{opacity:1;}\n\n  header.hero{\n    background:\n      radial-gradient(120% 160% at 0% 0%, rgba(255,153,0,.16), transparent 55%),\n      var(--ink);\n    color:#fff;\n    padding:64px 0 56px;\n    border-bottom:6px solid var(--orange);\n    position:relative;\n    overflow:hidden;\n  }\n  header.hero::after{\n    content:\"\";\n    position:absolute;\n    right:-60px; top:-60px;\n    width:320px; height:320px;\n    background:radial-gradient(circle, rgba(255,216,20,.10), transparent 70%);\n    pointer-events:none;\n  }\n  .eyebrow{\n    font-family:'Space Mono', monospace;\n    font-size:12px;\n    letter-spacing:.14em;\n    text-transform:uppercase;\n    color:var(--smile);\n    display:flex;\n    align-items:center;\n    gap:10px;\n    margin:0 0 18px;\n  }\n  .eyebrow::before{\n    content:\"\";\n    width:22px; height:2px;\n    background:var(--orange);\n    display:inline-block;\n  }\n  h1.hero-title{\n    font-family:'Fraunces', serif;\n    font-weight:700;\n    font-size:clamp(32px, 5vw, 54px);\n    line-height:1.05;\n    margin:0 0 18px;\n    max-width:15ch;\n  }\n  h1.hero-title em{\n    font-style:italic;\n    font-weight:500;\n    color:var(--orange);\n  }\n  .hero-sub{\n    font-size:16px;\n    line-height:1.6;\n    color:#D8DCE1;\n    max-width:52ch;\n    margin:0 0 28px;\n  }\n  .hero-meta{\n    display:flex;\n    gap:28px;\n    flex-wrap:wrap;\n    font-family:'Space Mono', monospace;\n    font-size:12px;\n    color:#9CA6B2;\n  }\n  .hero-meta strong{\n    color:#fff;\n    font-size:20px;\n    font-family:'Fraunces', serif;\n    font-weight:600;\n    display:block;\n  }\n\n  \/* ---------- FILTER BAR ---------- *\/\n  .filter-bar{\n    background:var(--paper);\n    border-bottom:1px solid var(--line);\n    position:sticky;\n    top:0;\n    z-index:20;\n  }\n  .filter-row{\n    display:flex;\n    align-items:center;\n    gap:10px;\n    padding:14px 0;\n    overflow-x:auto;\n    scrollbar-width:none;\n  }\n  .filter-row::-webkit-scrollbar{display:none;}\n  .filter-label{\n    font-family:'Space Mono', monospace;\n    font-size:11px;\n    text-transform:uppercase;\n    letter-spacing:.06em;\n    color:var(--muted);\n    white-space:nowrap;\n    margin-right:4px;\n  }\n  .chip{\n    font-family:'Space Mono', monospace;\n    font-size:12px;\n    text-transform:uppercase;\n    letter-spacing:.03em;\n    white-space:nowrap;\n    padding:8px 16px;\n    border-radius:999px;\n    border:1px solid var(--line);\n    background:#fff;\n    color:var(--text);\n    cursor:pointer;\n    transition:all .15s ease;\n  }\n  .chip:hover{border-color:var(--orange);}\n  .chip.active{\n    background:var(--ink);\n    border-color:var(--ink);\n    color:#fff;\n  }\n\n  \/* ---------- SECTION HEADS ---------- *\/\n  .section{padding:52px 0;}\n  .section-head{\n    display:flex;\n    justify-content:space-between;\n    align-items:flex-end;\n    gap:16px;\n    margin-bottom:28px;\n    border-bottom:2px solid var(--ink);\n    padding-bottom:14px;\n  }\n  .section-head h2{\n    font-family:'Fraunces', serif;\n    font-weight:600;\n    font-size:26px;\n    margin:0;\n  }\n  .section-head .count{\n    font-family:'Space Mono', monospace;\n    font-size:12px;\n    color:var(--muted);\n  }\n\n  \/* ---------- CARD GRID (\"FICH\u00c1RIO\") ---------- *\/\n  .grid{\n    display:grid;\n    grid-template-columns:repeat(auto-fill, minmax(270px, 1fr));\n    gap:22px;\n  }\n\n  .card{\n    background:var(--paper);\n    border:1px solid var(--line);\n    border-radius:var(--radius);\n    overflow:hidden;\n    position:relative;\n    text-decoration:none !important;\n    display:flex;\n    flex-direction:column;\n    transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;\n    box-shadow:var(--tab-shadow);\n  }\n  .card, .card:hover, .card:visited, .card:active, .card *{\n    text-decoration:none !important;\n  }\n  .card:hover{\n    transform:translateY(-4px);\n    box-shadow:0 14px 28px rgba(19,25,33,.12);\n    border-color:var(--ink);\n  }\n\n  \/* etiqueta lateral tipo \"aba de arquivo\" \u2014 o elemento assinatura da p\u00e1gina *\/\n  .card::before{\n    content:attr(data-tab);\n    position:absolute;\n    top:14px;\n    left:-1px;\n    background:var(--orange);\n    color:var(--ink);\n    font-family:'Space Mono', monospace;\n    font-size:10px;\n    font-weight:700;\n    letter-spacing:.06em;\n    text-transform:uppercase;\n    padding:4px 10px 4px 14px;\n    border-radius:0 6px 6px 0;\n    z-index:2;\n  }\n\n  .card-media{\n    position:relative;\n    aspect-ratio:4\/3;\n    background:#EDEDEB;\n    overflow:hidden;\n  }\n  .card-media img{\n    width:100%;height:100%;object-fit:cover;\n    transition:transform .3s ease;\n  }\n  .card:hover .card-media img{transform:scale(1.045);}\n  .card-media .placeholder{\n    width:100%;height:100%;\n    display:flex;align-items:center;justify-content:center;\n    color:var(--muted);\n    font-family:'Space Mono', monospace;\n    font-size:11px;\n    text-transform:uppercase;\n  }\n\n  .verdict{\n    position:absolute;\n    right:10px; bottom:10px;\n    font-family:'Space Mono', monospace;\n    font-size:11px;\n    font-weight:700;\n    text-transform:uppercase;\n    letter-spacing:.03em;\n    padding:5px 10px;\n    border-radius:6px;\n    backdrop-filter: blur(2px);\n  }\n  .verdict.yes{background:var(--verdict-yes-bg); color:var(--verdict-yes);}\n  .verdict.mid{background:var(--verdict-mid-bg); color:var(--verdict-mid);}\n  .verdict.no{background:var(--verdict-no-bg); color:var(--verdict-no);}\n\n  .card-body{\n    padding:18px 18px 20px;\n    display:flex;\n    flex-direction:column;\n    gap:10px;\n    flex:1;\n  }\n  .card-cat{\n    font-family:'Space Mono', monospace;\n    font-size:11px;\n    text-transform:uppercase;\n    letter-spacing:.05em;\n    color:var(--orange-deep);\n  }\n  .card-title{\n    font-family:'Fraunces', serif !important;\n    font-weight:600;\n    font-size:18px;\n    line-height:1.3;\n    color:var(--text) !important;\n    margin:0;\n  }\n  .card-excerpt{\n    font-size:13.5px;\n    line-height:1.55;\n    color:var(--muted);\n    margin:0;\n    flex:1;\n  }\n  .card-foot{\n    display:flex;\n    justify-content:space-between;\n    align-items:center;\n    font-family:'Space Mono', monospace;\n    font-size:11px;\n    color:var(--muted);\n    border-top:1px dashed var(--line);\n    padding-top:10px;\n    margin-top:4px;\n  }\n  .card-foot .read{\n    color:var(--ink);\n    font-weight:700;\n    display:flex;\n    align-items:center;\n    gap:4px;\n  }\n  .card-foot .read::after{content:\"\u2192\"; transition:transform .15s ease;}\n  .card:hover .card-foot .read::after{transform:translateX(3px);}\n\n  \/* ---------- EMPTY \/ LOADING STATES ---------- *\/\n  .state-box{\n    grid-column:1\/-1;\n    text-align:center;\n    padding:60px 20px;\n    color:var(--muted);\n    font-family:'Space Mono', monospace;\n    font-size:13px;\n  }\n  .state-box .big{\n    font-family:'Fraunces', serif;\n    font-size:20px;\n    color:var(--text);\n    margin-bottom:8px;\n    font-weight:600;\n  }\n  .skeleton{\n    background:linear-gradient(90deg, #EDEDEB 25%, #F6F6F4 37%, #EDEDEB 63%);\n    background-size:400% 100%;\n    animation:shimmer 1.4s ease infinite;\n  }\n  @keyframes shimmer{\n    0%{background-position:100% 0;}\n    100%{background-position:0 0;}\n  }\n  .card.skeleton-card .card-media{background:none;}\n  .card.skeleton-card .card-media,\n  .card.skeleton-card .line{\n    background:linear-gradient(90deg, #EDEDEB 25%, #F6F6F4 37%, #EDEDEB 63%);\n    background-size:400% 100%;\n    animation:shimmer 1.4s ease infinite;\n  }\n  .card.skeleton-card .line{height:12px; border-radius:4px; margin:6px 0;}\n\n  \/* pagination *\/\n  .load-more{\n    display:flex;\n    justify-content:center;\n    margin-top:36px;\n  }\n  .btn-load{\n    font-family:'Space Mono', monospace;\n    font-size:12px;\n    text-transform:uppercase;\n    letter-spacing:.05em;\n    background:var(--ink);\n    color:#fff;\n    border:none;\n    padding:14px 30px;\n    border-radius:999px;\n    cursor:pointer;\n    transition:background .15s ease;\n  }\n  .btn-load:hover{background:var(--orange-deep);}\n  .btn-load:disabled{background:var(--line); color:var(--muted); cursor:default;}\n\n  footer{\n    background:var(--navy);\n    color:#B7C0CB;\n    padding:30px 0;\n    font-size:13px;\n    text-align:center;\n  }\n  footer a{color:var(--smile); text-decoration:none;}\n\n  @media (max-width:640px){\n    header.hero{padding:44px 0 40px;}\n    .hero-meta{gap:20px;}\n    .section{padding:36px 0;}\n    .grid{grid-template-columns:repeat(auto-fill, minmax(150px,1fr)); gap:14px;}\n    .card-title{font-size:16px;}\n  }\n\n  @media (prefers-reduced-motion: reduce){\n    *{animation:none !important; transition:none !important;}\n  }\n\n  \/* =========================================================================\n     TELA CHEIA \u2014 mesma t\u00e9cnica usada na home e no plugin de lista de\n     presentes. O tema prende o conte\u00fado custom dentro de um container\n     central com largura m\u00e1xima; aqui a gente percorre os elementos-pai a\n     partir de .gp-analises e abre cada um (max-width:none, sem padding,\n     overflow vis\u00edvel), depois mede se sobrou faixa branca na lateral e\n     corrige com margem negativa. Sem isso, esta p\u00e1gina ficaria presa numa\n     coluna central como o resto do blog do tema.\n  ========================================================================= *\/\n  .gp-analises{ width:100%; max-width:none; }\n<\/style>\n<\/head>\n<body>\n\n<div class=\"gp-analises\">\n  <div class=\"top-bar\">\n    <div class=\"wrap\">\n      <span>GUIA DE PRE\u00c7OS \u00b7 TESTES E AN\u00c1LISES<\/span>\n      <a href=\"\/\">\u2190 Voltar para a Home<\/a>\n    <\/div>\n  <\/div>\n\n  <header class=\"hero\">\n    <div class=\"wrap\">\n      <p class=\"eyebrow\">Arquivo de an\u00e1lises<\/p>\n      <h1 class=\"hero-title\">A gente testa, compara e diz se <em>vale a pena<\/em>.<\/h1>\n      <p class=\"hero-sub\">An\u00e1lises reais de produtos que passaram pelo Guia de Pre\u00e7os \u2014 o que funcionou, o que decepcionou, e para quem cada um faz sentido.<\/p>\n      <div class=\"hero-meta\">\n        <div><strong id=\"stat-total\">\u2014<\/strong>an\u00e1lises publicadas<\/div>\n        <div><strong id=\"stat-cats\">\u2014<\/strong>categorias cobertas<\/div>\n      <\/div>\n    <\/div>\n  <\/header>\n\n  <div class=\"filter-bar\">\n    <div class=\"wrap\">\n      <div class=\"filter-row\" id=\"filterRow\">\n        <span class=\"filter-label\">Filtrar<\/span>\n        <button class=\"chip active\" data-cat=\"all\">Todas<\/button>\n        <!-- categorias inseridas via JS -->\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <main class=\"section\">\n    <div class=\"wrap\">\n      <div class=\"section-head\">\n        <h2>\u00daltimas an\u00e1lises<\/h2>\n        <span class=\"count\" id=\"resultCount\"><\/span>\n      <\/div>\n      <div class=\"grid\" id=\"grid\">\n        <!-- skeleton inicial -->\n        <div class=\"card skeleton-card\"><div class=\"card-media\"><\/div><div class=\"card-body\"><div class=\"line\" style=\"width:40%\"><\/div><div class=\"line\" style=\"width:90%\"><\/div><div class=\"line\" style=\"width:70%\"><\/div><\/div><\/div>\n        <div class=\"card skeleton-card\"><div class=\"card-media\"><\/div><div class=\"card-body\"><div class=\"line\" style=\"width:40%\"><\/div><div class=\"line\" style=\"width:90%\"><\/div><div class=\"line\" style=\"width:70%\"><\/div><\/div><\/div>\n        <div class=\"card skeleton-card\"><div class=\"card-media\"><\/div><div class=\"card-body\"><div class=\"line\" style=\"width:40%\"><\/div><div class=\"line\" style=\"width:90%\"><\/div><div class=\"line\" style=\"width:70%\"><\/div><\/div><\/div>\n        <div class=\"card skeleton-card\"><div class=\"card-media\"><\/div><div class=\"card-body\"><div class=\"line\" style=\"width:40%\"><\/div><div class=\"line\" style=\"width:90%\"><\/div><div class=\"line\" style=\"width:70%\"><\/div><\/div><\/div>\n      <\/div>\n      <div class=\"load-more\" id=\"loadMoreWrap\" style=\"display:none;\">\n        <button class=\"btn-load\" id=\"btnLoadMore\">Carregar mais an\u00e1lises<\/button>\n      <\/div>\n    <\/div>\n  <\/main>\n\n  <footer>\n    <div class=\"wrap\">\n      Guia de Pre\u00e7os \u2014 an\u00e1lises independentes de produtos. <a href=\"\/\">guiadeprecos.com.br<\/a>\n    <\/div>\n  <\/footer>\n<\/div><!-- \/.gp-analises -->\n\n<script>\n\/* =========================================================================\n   TELA CHEIA \u2014 for\u00e7a a p\u00e1gina a ocupar a largura total, furando o\n   container central que o tema do WordPress imp\u00f5e. Percorre os pais de\n   .gp-analises at\u00e9 o <body>, abre max-width\/padding\/overflow de cada um,\n   e mede\/corrige qualquer faixa branca residual nas laterais.\n========================================================================= *\/\n(function(){\n  function abrirContainer(el){\n    if (!el || el === document.body){\n      el && (el.style.overflowX = 'visible');\n      return;\n    }\n    const cs = getComputedStyle(el);\n    if (cs.maxWidth !== 'none') el.style.maxWidth = 'none';\n    el.style.width = '100%';\n    el.style.marginLeft = '0';\n    el.style.marginRight = '0';\n    if (parseFloat(cs.paddingLeft) > 0) el.style.paddingLeft = '0';\n    if (parseFloat(cs.paddingRight) > 0) el.style.paddingRight = '0';\n    el.style.overflowX = 'visible';\n  }\n\n  function corrigirFaixasLaterais(){\n    const raiz = document.querySelector('.gp-analises');\n    if (!raiz) return;\n    const rect = raiz.getBoundingClientRect();\n    const folgaEsquerda = rect.left;\n    const folgaDireita = window.innerWidth - rect.right;\n    if (folgaEsquerda > 1) raiz.style.marginLeft = (-folgaEsquerda) + 'px';\n    if (folgaDireita > 1) raiz.style.marginRight = (-folgaDireita) + 'px';\n  }\n\n  function aplicar(){\n    const raiz = document.querySelector('.gp-analises');\n    if (!raiz) return;\n    let el = raiz.parentElement;\n    while (el){\n      abrirContainer(el);\n      el = el.parentElement;\n    }\n    document.documentElement.style.overflowX = 'hidden';\n    document.body.style.overflowX = 'hidden';\n    document.body.style.maxWidth = 'none';\n    document.body.style.margin = '0';\n    corrigirFaixasLaterais();\n  }\n\n  \/\/ roda logo, e de novo depois de um instante \u2014 alguns temas reajustam\n  \/\/ o layout via JS pr\u00f3prio depois do load inicial.\n  aplicar();\n  window.addEventListener('load', aplicar);\n  setTimeout(aplicar, 300);\n  setTimeout(aplicar, 1000);\n  window.addEventListener('resize', corrigirFaixasLaterais);\n})();\n<\/script>\n\n<script>\n(function(){\n  \/* =====================================================================\n     CONFIGURA\u00c7\u00c3O\n     - CATEGORY_SLUG: slug da categoria\/tag do WordPress usada para marcar\n       os posts de \"an\u00e1lise de produtos\". Troque aqui se usar outro nome.\n     - Usa o mesmo esquema de fallback de permalink da homepage (tenta REST\n       API padr\u00e3o, cai para ?p= \/ ?rest_route= se o WP estiver em modo Plain).\n  ===================================================================== *\/\n  const SITE_URL = window.location.origin; \/\/ ajuste se rodar fora do dom\u00ednio do site\n  const CATEGORY_SLUG = 'analise-produtos';\n  const PER_PAGE = 9;\n\n  const grid = document.getElementById('grid');\n  const filterRow = document.getElementById('filterRow');\n  const resultCount = document.getElementById('resultCount');\n  const statTotal = document.getElementById('stat-total');\n  const statCats = document.getElementById('stat-cats');\n  const loadMoreWrap = document.getElementById('loadMoreWrap');\n  const btnLoadMore = document.getElementById('btnLoadMore');\n\n  let currentPage = 1;\n  let currentCat = 'all';\n  let categoryId = null;\n  let allLoadedPosts = [];\n  let categoriesMap = {}; \/\/ id -> {name, slug}\n\n  function verdictFromPost(post){\n    \/\/ Tenta ler um \"veredito\" de um campo customizado (ACF\/meta) chamado\n    \/\/ 'veredito'; se n\u00e3o existir, cai para leitura de tags conhecidas.\n    const meta = (post.acf && post.acf.veredito) || (post.meta && post.meta.veredito);\n    if (meta) return normalizeVerdict(meta);\n\n    const tags = (post._embedded && post._embedded['wp:term'])\n      ? [].concat(...post._embedded['wp:term']).map(t => (t.slug||'').toLowerCase())\n      : [];\n    if (tags.includes('vale-a-pena')) return {cls:'yes', label:'Vale a pena'};\n    if (tags.includes('nao-recomendo') || tags.includes('n\u00e3o-recomendo')) return {cls:'no', label:'N\u00e3o recomendo'};\n    if (tags.includes('com-ressalvas')) return {cls:'mid', label:'Com ressalvas'};\n    return null;\n  }\n\n  function normalizeVerdict(v){\n    v = String(v).toLowerCase();\n    if (v.includes('vale')) return {cls:'yes', label:'Vale a pena'};\n    if (v.includes('n\u00e3o') || v.includes('nao')) return {cls:'no', label:'N\u00e3o recomendo'};\n    return {cls:'mid', label:'Com ressalvas'};\n  }\n\n  function stripHtml(html){\n    const tmp = document.createElement('div');\n    tmp.innerHTML = html || '';\n    return (tmp.textContent || tmp.innerText || '').trim();\n  }\n\n  function getFeaturedImage(post){\n    try{\n      const media = post._embedded['wp:featuredmedia'][0];\n      if (!media || media.code) return null; \/\/ WP retornou objeto de erro em vez de m\u00eddia\n      return (media.media_details\n        && media.media_details.sizes\n        && media.media_details.sizes.medium_large\n        && media.media_details.sizes.medium_large.source_url)\n        || media.source_url\n        || null;\n    }catch(e){ return null; }\n  }\n\n  function getCategoryLabel(post){\n    try{\n      const terms = [].concat(...post._embedded['wp:term']);\n      const cat = terms.find(t => t.taxonomy === 'category');\n      return cat ? cat.name : 'An\u00e1lise';\n    }catch(e){ return 'An\u00e1lise'; }\n  }\n\n  function getCategorySlugsOf(post){\n    try{\n      const terms = [].concat(...post._embedded['wp:term']);\n      return terms.filter(t => t.taxonomy === 'category').map(t => t.slug);\n    }catch(e){ return []; }\n  }\n\n  function formatDate(iso){\n    try{\n      const d = new Date(iso);\n      return d.toLocaleDateString('pt-BR', {day:'2-digit', month:'short', year:'numeric'});\n    }catch(e){ return ''; }\n  }\n\n  \/* --------- fetch com fallback (Plain permalinks \/ ?rest_route=) --------- *\/\n  async function fetchJSON(paths){\n    for (const path of paths){\n      try{\n        const res = await fetch(path, {headers:{'Accept':'application\/json'}});\n        if (res.ok) return await res.json();\n      }catch(e){ \/* tenta pr\u00f3ximo *\/ }\n    }\n    throw new Error('Falha ao buscar: ' + paths[0]);\n  }\n\n  async function resolveCategoryId(slug){\n    const paths = [\n      `${SITE_URL}\/wp-json\/wp\/v2\/categories?slug=${slug}`,\n      `${SITE_URL}\/?rest_route=\/wp\/v2\/categories&slug=${slug}`\n    ];\n    const data = await fetchJSON(paths);\n    return (data && data[0]) ? data[0].id : null;\n  }\n\n  async function fetchAllCategoriesUsed(postsCategoryId){\n    const paths = [\n      `${SITE_URL}\/wp-json\/wp\/v2\/categories?per_page=100`,\n      `${SITE_URL}\/?rest_route=\/wp\/v2\/categories&per_page=100`\n    ];\n    try{\n      return await fetchJSON(paths);\n    }catch(e){ return []; }\n  }\n\n  async function fetchPosts(page, catId){\n    \/\/ Sem categoria configurada, n\u00e3o busca posts do site inteiro \u2014 evita\n    \/\/ mostrar conte\u00fado fora do tema desta p\u00e1gina.\n    if (!catId) return [];\n    let base = `${SITE_URL}\/wp-json\/wp\/v2\/posts?categories=${catId}&_embed&per_page=${PER_PAGE}&page=${page}`;\n    let fallback = `${SITE_URL}\/?rest_route=\/wp\/v2\/posts&categories=${catId}&_embed&per_page=${PER_PAGE}&page=${page}`;\n    return await fetchJSON([base, fallback]);\n  }\n\n  function renderChips(cats){\n    cats.forEach(c => {\n      const btn = document.createElement('button');\n      btn.className = 'chip';\n      btn.dataset.cat = c.slug;\n      btn.textContent = c.name;\n      btn.addEventListener('click', () => onFilterClick(c.slug));\n      filterRow.appendChild(btn);\n    });\n  }\n\n  function onFilterClick(slug){\n    currentCat = slug;\n    document.querySelectorAll('.chip').forEach(ch => {\n      ch.classList.toggle('active', ch.dataset.cat === slug);\n    });\n    const filtered = slug === 'all'\n      ? allLoadedPosts\n      : allLoadedPosts.filter(p => getCategorySlugsOf(p).includes(slug));\n    paintGrid(filtered);\n  }\n\n  function cardTemplate(post){\n    const img = getFeaturedImage(post);\n    const cat = getCategoryLabel(post);\n    const verdict = verdictFromPost(post);\n    const excerpt = stripHtml(post.excerpt && post.excerpt.rendered).slice(0, 110);\n    const title = stripHtml(post.title && post.title.rendered);\n    const tabLabel = cat.length > 14 ? cat.slice(0,12) + '\u2026' : cat;\n\n    return `\n      <a class=\"card\" href=\"${post.link}\" data-tab=\"${tabLabel}\">\n        <div class=\"card-media\">\n          ${img ? `<img decoding=\"async\" src=\"${img}\" alt=\"${title}\" loading=\"lazy\">` : `<div class=\"placeholder\">Sem imagem<\/div>`}\n          ${verdict ? `<span class=\"verdict ${verdict.cls}\">${verdict.label}<\/span>` : ''}\n        <\/div>\n        <div class=\"card-body\">\n          <span class=\"card-cat\">${cat}<\/span>\n          <h3 class=\"card-title\">${title}<\/h3>\n          <p class=\"card-excerpt\">${excerpt}${excerpt.length >= 110 ? '\u2026' : ''}<\/p>\n          <div class=\"card-foot\">\n            <span>${formatDate(post.date)}<\/span>\n            <span class=\"read\">Ler an\u00e1lise<\/span>\n          <\/div>\n        <\/div>\n      <\/a>\n    `;\n  }\n\n  function paintGrid(posts){\n    if (!posts.length){\n      grid.innerHTML = `\n        <div class=\"state-box\">\n          <div class=\"big\">Nenhuma an\u00e1lise por aqui ainda<\/div>\n          Assim que uma nova an\u00e1lise for publicada nessa categoria, ela aparece automaticamente.\n        <\/div>`;\n      resultCount.textContent = '';\n      return;\n    }\n    grid.innerHTML = posts.map(cardTemplate).join('');\n    resultCount.textContent = `${posts.length} ${posts.length === 1 ? 'resultado' : 'resultados'}`;\n  }\n\n  function showErrorState(){\n    grid.innerHTML = `\n      <div class=\"state-box\">\n        <div class=\"big\">N\u00e3o foi poss\u00edvel carregar as an\u00e1lises agora<\/div>\n        Verifique se a categoria \"${CATEGORY_SLUG}\" existe no WordPress, ou tente atualizar a p\u00e1gina.\n      <\/div>`;\n  }\n\n  function showCategoryMissingState(){\n    grid.innerHTML = `\n      <div class=\"state-box\">\n        <div class=\"big\">A categoria \"${CATEGORY_SLUG}\" ainda n\u00e3o existe no WordPress<\/div>\n        Crie essa categoria em Posts \u2192 Categorias e marque os posts de an\u00e1lise com ela.\n        Assim que isso for feito, eles aparecem aqui automaticamente.\n      <\/div>`;\n    resultCount.textContent = '';\n    statTotal.textContent = '0';\n    statCats.textContent = '\u2014';\n  }\n\n  async function init(){\n    try{\n      categoryId = await resolveCategoryId(CATEGORY_SLUG);\n\n      if (!categoryId){\n        showCategoryMissingState();\n        return;\n      }\n\n      const [posts, allCats] = await Promise.all([\n        fetchPosts(1, categoryId),\n        fetchAllCategoriesUsed()\n      ]);\n\n      allLoadedPosts = posts || [];\n      paintGrid(allLoadedPosts);\n\n      \/\/ monta filtros s\u00f3 com categorias realmente presentes nos posts carregados\n      const usedSlugs = new Set();\n      allLoadedPosts.forEach(p => getCategorySlugsOf(p).forEach(s => usedSlugs.add(s)));\n      const relevantCats = (allCats || []).filter(c => usedSlugs.has(c.slug));\n      renderChips(relevantCats);\n\n      statTotal.textContent = allLoadedPosts.length;\n      statCats.textContent = relevantCats.length || '\u2014';\n\n      if (allLoadedPosts.length === PER_PAGE){\n        loadMoreWrap.style.display = 'flex';\n      }\n    }catch(err){\n      console.error(err);\n      showErrorState();\n    }\n  }\n\n  btnLoadMore.addEventListener('click', async () => {\n    btnLoadMore.disabled = true;\n    btnLoadMore.textContent = 'Carregando\u2026';\n    currentPage += 1;\n    try{\n      const more = await fetchPosts(currentPage, categoryId);\n      if (!more.length){\n        loadMoreWrap.style.display = 'none';\n        return;\n      }\n      allLoadedPosts = allLoadedPosts.concat(more);\n      onFilterClick(currentCat);\n      statTotal.textContent = allLoadedPosts.length;\n      if (more.length < PER_PAGE) loadMoreWrap.style.display = 'none';\n    }catch(e){\n      console.error(e);\n    }finally{\n      btnLoadMore.disabled = false;\n      btnLoadMore.textContent = 'Carregar mais an\u00e1lises';\n    }\n  });\n\n  init();\n})();\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>An\u00e1lises de Produtos \u2014 Guia de Pre\u00e7os GUIA DE PRE\u00c7OS \u00b7 TESTES E AN\u00c1LISES \u2190 Voltar para a Home Arquivo de an\u00e1lises A gente testa, compara e diz se vale a pena. An\u00e1lises reais de produtos que passaram pelo Guia de Pre\u00e7os \u2014 o que funcionou, o que decepcionou, e para quem cada um faz [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"blank","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-1735","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>An\u00e1lises de produtos -<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/guiadeprecos.com.br\/analise-produtos\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"An\u00e1lises de produtos -\" \/>\n<meta property=\"og:description\" content=\"An\u00e1lises de Produtos \u2014 Guia de Pre\u00e7os GUIA DE PRE\u00c7OS \u00b7 TESTES E AN\u00c1LISES \u2190 Voltar para a Home Arquivo de an\u00e1lises A gente testa, compara e diz se vale a pena. An\u00e1lises reais de produtos que passaram pelo Guia de Pre\u00e7os \u2014 o que funcionou, o que decepcionou, e para quem cada um faz [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/guiadeprecos.com.br\/analise-produtos\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-12T03:09:40+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minuto\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/guiadeprecos.com.br\\\/analise-produtos\\\/\",\"url\":\"https:\\\/\\\/guiadeprecos.com.br\\\/analise-produtos\\\/\",\"name\":\"An\u00e1lises de produtos -\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/guiadeprecos.com.br\\\/#website\"},\"datePublished\":\"2026-08-06T02:33:48+00:00\",\"dateModified\":\"2026-08-12T03:09:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/guiadeprecos.com.br\\\/analise-produtos\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/guiadeprecos.com.br\\\/analise-produtos\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/guiadeprecos.com.br\\\/analise-produtos\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"In\u00edcio\",\"item\":\"https:\\\/\\\/guiadeprecos.com.br\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"An\u00e1lises de produtos\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/guiadeprecos.com.br\\\/#website\",\"url\":\"https:\\\/\\\/guiadeprecos.com.br\\\/\",\"name\":\"\",\"description\":\"My WordPress Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/guiadeprecos.com.br\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"An\u00e1lises de produtos -","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/guiadeprecos.com.br\/analise-produtos\/","og_locale":"pt_BR","og_type":"article","og_title":"An\u00e1lises de produtos -","og_description":"An\u00e1lises de Produtos \u2014 Guia de Pre\u00e7os GUIA DE PRE\u00c7OS \u00b7 TESTES E AN\u00c1LISES \u2190 Voltar para a Home Arquivo de an\u00e1lises A gente testa, compara e diz se vale a pena. An\u00e1lises reais de produtos que passaram pelo Guia de Pre\u00e7os \u2014 o que funcionou, o que decepcionou, e para quem cada um faz [&hellip;]","og_url":"https:\/\/guiadeprecos.com.br\/analise-produtos\/","article_modified_time":"2026-08-12T03:09:40+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. tempo de leitura":"1 minuto"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/guiadeprecos.com.br\/analise-produtos\/","url":"https:\/\/guiadeprecos.com.br\/analise-produtos\/","name":"An\u00e1lises de produtos -","isPartOf":{"@id":"https:\/\/guiadeprecos.com.br\/#website"},"datePublished":"2026-08-06T02:33:48+00:00","dateModified":"2026-08-12T03:09:40+00:00","breadcrumb":{"@id":"https:\/\/guiadeprecos.com.br\/analise-produtos\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/guiadeprecos.com.br\/analise-produtos\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/guiadeprecos.com.br\/analise-produtos\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"In\u00edcio","item":"https:\/\/guiadeprecos.com.br\/"},{"@type":"ListItem","position":2,"name":"An\u00e1lises de produtos"}]},{"@type":"WebSite","@id":"https:\/\/guiadeprecos.com.br\/#website","url":"https:\/\/guiadeprecos.com.br\/","name":"","description":"My WordPress Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/guiadeprecos.com.br\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"}]}},"_links":{"self":[{"href":"https:\/\/guiadeprecos.com.br\/?rest_route=\/wp\/v2\/pages\/1735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/guiadeprecos.com.br\/?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/guiadeprecos.com.br\/?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/guiadeprecos.com.br\/?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/guiadeprecos.com.br\/?rest_route=%2Fwp%2Fv2%2Fcomments&post=1735"}],"version-history":[{"count":3,"href":"https:\/\/guiadeprecos.com.br\/?rest_route=\/wp\/v2\/pages\/1735\/revisions"}],"predecessor-version":[{"id":1740,"href":"https:\/\/guiadeprecos.com.br\/?rest_route=\/wp\/v2\/pages\/1735\/revisions\/1740"}],"wp:attachment":[{"href":"https:\/\/guiadeprecos.com.br\/?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}