{"id":21594,"date":"2026-07-21T15:03:13","date_gmt":"2026-07-21T15:03:13","guid":{"rendered":"https:\/\/buykapra.com\/?p=21594"},"modified":"2026-07-21T15:40:47","modified_gmt":"2026-07-21T15:40:47","slug":"21594","status":"publish","type":"post","link":"https:\/\/buykapra.com\/es\/21594\/","title":{"rendered":"Buykapra\u00a0Special Tools for Girls"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Buykapra Special Tools for Girls \u2014 Free Quizzes, Calculators &#038; Planners<\/title>\n<meta name=\"description\" content=\"Buykapra's free collection of quizzes, calculators and planners for beauty, health, weddings and everyday life \u2014 made for girls, no sign-up needed.\">\n\n<!-- ====================================================================\n  ADSENSE: paste your AdSense verification \/ auto-ads script tag here,\n  right below this comment, once your account is approved.\n  <script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXXXX\" crossorigin=\"anonymous\"><\/script>\n===================================================================== -->\n\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,300;0,9..144,500;0,9..144,600;1,9..144,500&#038;family=Work+Sans:wght@400;500;600;700&#038;display=swap\" rel=\"stylesheet\">\n\n<style>\n:root{\n  --cream:#FAF3EC;\n  --paper:#FFFDFA;\n  --plum:#2E1F2E;\n  --plum-soft:#5B4A5C;\n  --rose:#C1487B;\n  --rose-deep:#9C3564;\n  --sage:#7C8B6F;\n  --gold:#C79A45;\n  --border:#E8DCD1;\n  --shadow: 0 1px 2px rgba(46,31,46,0.06), 0 8px 24px rgba(46,31,46,0.06);\n  --radius: 4px;\n}\n*{box-sizing:border-box;}\nhtml{scroll-behavior:smooth;}\nbody{\n  margin:0;\n  background:var(--cream);\n  color:var(--plum);\n  font-family:'Work Sans', sans-serif;\n  -webkit-font-smoothing:antialiased;\n}\nh1,h2,h3,h4{\n  font-family:'Fraunces', serif;\n  font-weight:600;\n  margin:0;\n  letter-spacing:-0.01em;\n}\np{margin:0;}\na{color:inherit;}\n::selection{background:var(--rose);color:#fff;}\n@media (prefers-reduced-motion: reduce){\n  *{animation-duration:0.001ms !important; transition-duration:0.001ms !important;}\n}\n\n\/* ---------- Layout shell ---------- *\/\n.wrap{max-width:1160px; margin:0 auto; padding:0 28px;}\n\n\/* ---------- Header \/ Hero ---------- *\/\nheader.hero{\n  border-bottom:1px solid var(--border);\n  padding-top:22px;\n}\n.top-row{\n  display:flex; align-items:center; justify-content:space-between;\n  padding-bottom:18px;\n}\n.brand{\n  display:flex; align-items:baseline; gap:10px;\n}\n.brand .mark{\n  font-family:'Fraunces', serif;\n  font-style:italic;\n  font-size:15px;\n  color:var(--rose-deep);\n  border:1px solid var(--rose-deep);\n  border-radius:50%;\n  width:30px;height:30px;\n  display:flex;align-items:center;justify-content:center;\n  flex-shrink:0;\n}\n.brand-name{font-size:17px; font-weight:600; letter-spacing:0.01em;}\n@media (max-width:700px){ .brand-name{font-size:14px;} }\nnav.top-nav{display:flex; gap:22px; font-size:13.5px; font-weight:500;}\nnav.top-nav a{text-decoration:none; color:var(--plum-soft); border-bottom:1px solid transparent; padding-bottom:2px;}\nnav.top-nav a:hover{color:var(--rose-deep); border-color:var(--rose-deep);}\n\n.hero-main{\n  display:grid;\n  grid-template-columns: 1.15fr 0.85fr;\n  gap:48px;\n  padding:56px 0 60px;\n  align-items:end;\n}\n.hero-eyebrow{\n  font-size:12px; letter-spacing:0.14em; text-transform:uppercase;\n  color:var(--rose-deep); font-weight:600; margin-bottom:14px; display:block;\n}\n.hero-main h1{\n  font-size:clamp(38px, 5vw, 60px);\n  line-height:1.02;\n  color:var(--plum);\n}\n.hero-main h1 em{\n  font-style:italic; color:var(--rose-deep);\n}\n.hero-sub{\n  margin-top:18px;\n  font-size:16.5px;\n  color:var(--plum-soft);\n  max-width:46ch;\n  line-height:1.55;\n}\n.hero-side{\n  border-left:1px solid var(--border);\n  padding-left:32px;\n  font-size:13.5px;\n  color:var(--plum-soft);\n  line-height:1.7;\n}\n.hero-side .num{\n  font-family:'Fraunces', serif;\n  font-size:44px;\n  color:var(--gold);\n  display:block;\n  line-height:1;\n  margin-bottom:6px;\n}\n\n\/* ---------- Category sections ---------- *\/\nmain{padding-bottom:80px;}\n.category{\n  padding:52px 0 8px;\n  border-bottom:1px solid var(--border);\n}\n.category-head{\n  display:flex; align-items:baseline; gap:16px;\n  margin-bottom:26px;\n}\n.category-head .tag{\n  font-family:'Fraunces', serif; font-style:italic;\n  font-size:13px; color:var(--gold);\n  white-space:nowrap;\n}\n.category-head h2{font-size:26px;}\n.category-desc{\n  font-size:14px; color:var(--plum-soft); margin:-14px 0 26px; max-width:60ch;\n}\n\n.grid{\n  display:grid;\n  grid-template-columns:repeat(3, 1fr);\n  gap:18px;\n  padding-bottom:44px;\n}\n.card{\n  background:var(--paper);\n  border:1px solid var(--border);\n  border-radius:var(--radius);\n  padding:22px 20px 20px;\n  cursor:pointer;\n  text-align:left;\n  font-family:inherit;\n  display:flex; flex-direction:column; gap:12px;\n  min-height:150px;\n  transition:transform .15s ease, box-shadow .15s ease, border-color .15s ease;\n  position:relative;\n}\n.card:hover{\n  transform:translateY(-3px);\n  box-shadow:var(--shadow);\n  border-color:var(--rose);\n}\n.card:focus-visible{outline:2px solid var(--rose-deep); outline-offset:3px;}\n.card .spec{\n  font-size:10.5px; letter-spacing:0.1em; color:var(--gold); font-weight:600;\n}\n.card h3{font-size:18px; line-height:1.25;}\n.card p{font-size:13px; color:var(--plum-soft); line-height:1.5;}\n.card .go{\n  margin-top:auto;\n  font-size:12.5px; font-weight:600; color:var(--rose-deep);\n  display:flex; align-items:center; gap:6px;\n}\n.card .go svg{width:12px;height:12px; transition:transform .15s ease;}\n.card:hover .go svg{transform:translateX(3px);}\n\n@media (max-width: 880px){\n  .grid{grid-template-columns:repeat(2,1fr);}\n  .hero-main{grid-template-columns:1fr; gap:22px;}\n  .hero-side{border-left:none; border-top:1px solid var(--border); padding-left:0; padding-top:20px;}\n}\n@media (max-width: 560px){\n  .grid{grid-template-columns:1fr;}\n  nav.top-nav{display:none;}\n}\n\n\/* ---------- Modal ---------- *\/\n.modal-backdrop{\n  position:fixed; inset:0; background:rgba(46,31,46,0.55);\n  display:none; align-items:flex-start; justify-content:center;\n  padding:40px 20px; overflow-y:auto; z-index:100;\n  backdrop-filter: blur(2px);\n}\n.modal-backdrop.open{display:flex;}\n.modal{\n  background:var(--paper);\n  border-radius:6px;\n  max-width:640px; width:100%;\n  padding:0;\n  box-shadow:0 20px 60px rgba(46,31,46,0.35);\n  animation:rise .22s ease;\n}\n@keyframes rise{from{opacity:0; transform:translateY(14px);} to{opacity:1; transform:translateY(0);}}\n.modal-head{\n  display:flex; align-items:flex-start; justify-content:space-between;\n  padding:26px 28px 18px; border-bottom:1px solid var(--border);\n}\n.modal-head .tag{font-size:10.5px; letter-spacing:0.1em; color:var(--gold); font-weight:600; display:block; margin-bottom:6px;}\n.modal-head h3{font-size:23px;}\n.modal-close{\n  background:none; border:1px solid var(--border); border-radius:50%;\n  width:32px; height:32px; cursor:pointer; color:var(--plum-soft);\n  font-size:16px; line-height:1; flex-shrink:0;\n  display:flex; align-items:center; justify-content:center;\n}\n.modal-close:hover{border-color:var(--rose-deep); color:var(--rose-deep);}\n.modal-body{padding:24px 28px 30px; font-size:14.5px; line-height:1.6;}\n\n\/* ---------- form elements used inside tools ---------- *\/\n.field{margin-bottom:16px;}\n.field label{display:block; font-size:12.5px; font-weight:600; color:var(--plum-soft); margin-bottom:6px; text-transform:uppercase; letter-spacing:0.04em;}\n.field input[type=text], .field input[type=number], .field input[type=date], .field select, .field textarea{\n  width:100%; padding:10px 12px; border:1px solid var(--border); border-radius:4px;\n  font-family:inherit; font-size:14.5px; background:#fff; color:var(--plum);\n}\n.field textarea{resize:vertical; min-height:70px;}\n.choice-row{display:flex; flex-wrap:wrap; gap:8px;}\n.choice-row button{\n  padding:8px 14px; border:1px solid var(--border); border-radius:20px; background:#fff;\n  font-family:inherit; font-size:13px; cursor:pointer; color:var(--plum-soft);\n}\n.choice-row button.selected{background:var(--rose); border-color:var(--rose); color:#fff;}\n.choice-row button:hover{border-color:var(--rose-deep);}\n.btn{\n  background:var(--rose-deep); color:#fff; border:none; padding:11px 22px;\n  border-radius:24px; font-family:inherit; font-weight:600; font-size:14px; cursor:pointer;\n  margin-top:4px;\n}\n.btn:hover{background:var(--rose);}\n.btn.secondary{background:none; color:var(--rose-deep); border:1px solid var(--rose-deep);}\n.btn.secondary:hover{background:var(--rose); color:#fff; border-color:var(--rose);}\n.result-box{\n  margin-top:18px; padding:18px; background:var(--cream); border:1px solid var(--border);\n  border-radius:6px;\n}\n.result-box h4{font-size:16px; margin-bottom:8px; color:var(--rose-deep);}\n.result-box .big{font-family:'Fraunces',serif; font-size:26px; margin-bottom:4px;}\n.swatch-row{display:flex; gap:8px; margin-top:10px; flex-wrap:wrap;}\n.swatch{width:36px; height:36px; border-radius:50%; border:1px solid rgba(0,0,0,0.08);}\n.hidden{display:none !important;}\nul.tool-list{margin:10px 0 0; padding-left:20px;}\nul.tool-list li{margin-bottom:6px;}\n.small-muted{font-size:12px; color:var(--plum-soft); margin-top:10px;}\n.progress-dots{display:flex; gap:5px; margin-bottom:16px;}\n.progress-dots span{width:6px; height:6px; border-radius:50%; background:var(--border);}\n.progress-dots span.active{background:var(--rose-deep);}\ntable.simple{width:100%; border-collapse:collapse; margin-top:10px; font-size:13.5px;}\ntable.simple th, table.simple td{text-align:left; padding:6px 4px; border-bottom:1px solid var(--border);}\n.ad-slot{\n  border:1px dashed var(--border); border-radius:6px; padding:18px; text-align:center;\n  font-size:11.5px; color:var(--plum-soft); letter-spacing:0.05em; text-transform:uppercase;\n  margin:52px 0;\n}\n\n\/* ---------- Footer ---------- *\/\nfooter{\n  border-top:1px solid var(--border); padding:36px 0 40px;\n  font-size:12.5px; color:var(--plum-soft);\n  display:flex; justify-content:space-between; flex-wrap:wrap; gap:14px;\n}\nfooter a{text-decoration:underline; text-decoration-color:var(--border);}\n<\/style>\n<\/head>\n<body>\n\n<header class=\"hero\">\n  <div class=\"wrap\">\n    <div class=\"top-row\">\n      <div class=\"brand\">\n        <span class=\"mark\">B<\/span>\n        <span class=\"brand-name\">Buykapra <span style=\"font-weight:400; color:var(--plum-soft);\">Special Tools for Girls<\/span><\/span>\n      <\/div>\n      <nav class=\"top-nav\">\n        <a href=\"#beauty\">Beauty &amp; Fashion<\/a>\n        <a href=\"#health\">Health &amp; Lifestyle<\/a>\n        <a href=\"#lifestyle\">Wedding &amp; Love<\/a>\n        <a href=\"#home\">Home<\/a>\n        <a href=\"#career\">Career &amp; Money<\/a>\n        <a href=\"#fun\">Just for Fun<\/a>\n      <\/nav>\n    <\/div>\n    <div class=\"hero-main\">\n      <div>\n        <span class=\"hero-eyebrow\">Buykapra \u00b7 Nineteen free tools, no sign-up<\/span>\n        <h1>Special tools <em>for girls<\/em>,<br>made simple.<\/h1>\n        <p class=\"hero-sub\">Quizzes, calculators and planners for the everyday moments \u2014 a new palette, a due date, a wedding hashtag, a name for the baby. Pick a card. Get your answer. Pin it for later.<\/p>\n      <\/div>\n      <div class=\"hero-side\">\n        <span class=\"num\">55+<\/span>\n        Tools sorted into six collections \u2014 beauty &amp; fashion, health &amp; lifestyle, wedding &amp; love, home, career &amp; money, and just-for-fun. Everything runs right here in your browser.\n      <\/div>\n    <\/div>\n  <\/div>\n<\/header>\n\n<main>\n  <div class=\"wrap\">\n\n    <!-- BEAUTY & STYLE -->\n    <section class=\"category\" id=\"beauty\">\n      <div class=\"category-head\">\n        <span class=\"tag\">Collection No. 01<\/span>\n        <h2>Beauty &amp; Fashion<\/h2>\n      <\/div>\n      <p class=\"category-desc\">Outfits, color, shade and style \u2014 figure out what actually suits you.<\/p>\n      <div class=\"grid\" id=\"grid-beauty\"><\/div>\n    <\/section>\n\n    <!-- HEALTH & LIFESTYLE -->\n    <section class=\"category\" id=\"health\">\n      <div class=\"category-head\">\n        <span class=\"tag\">Collection No. 02<\/span>\n        <h2>Health &amp; Lifestyle<\/h2>\n      <\/div>\n      <p class=\"category-desc\">Dates, cycles, habits and self-care. Informational only \u2014 always double check anything medical with your doctor.<\/p>\n      <div class=\"grid\" id=\"grid-health\"><\/div>\n    <\/section>\n\n    <div class=\"ad-slot\">Advertisement space \u2014 AdSense unit<\/div>\n\n    <!-- WEDDING & RELATIONSHIPS -->\n    <section class=\"category\" id=\"lifestyle\">\n      <div class=\"category-head\">\n        <span class=\"tag\">Collection No. 03<\/span>\n        <h2>Wedding &amp; Relationships<\/h2>\n      <\/div>\n      <p class=\"category-desc\">For weddings, showers, gifting and everything love-related.<\/p>\n      <div class=\"grid\" id=\"grid-lifestyle\"><\/div>\n    <\/section>\n\n    <!-- HOME & ORGANIZATION -->\n    <section class=\"category\" id=\"home\">\n      <div class=\"category-head\">\n        <span class=\"tag\">Collection No. 04<\/span>\n        <h2>Home &amp; Organization<\/h2>\n      <\/div>\n      <p class=\"category-desc\">Schedules, budgets and planners for keeping a household running.<\/p>\n      <div class=\"grid\" id=\"grid-home\"><\/div>\n    <\/section>\n\n    <div class=\"ad-slot\">Advertisement space \u2014 AdSense unit<\/div>\n\n    <!-- CAREER & FINANCE -->\n    <section class=\"category\" id=\"career\">\n      <div class=\"category-head\">\n        <span class=\"tag\">Collection No. 05<\/span>\n        <h2>Career &amp; Finance<\/h2>\n      <\/div>\n      <p class=\"category-desc\">Resumes, rates and budgets for building the life you want.<\/p>\n      <div class=\"grid\" id=\"grid-career\"><\/div>\n    <\/section>\n\n    <!-- FUN -->\n    <section class=\"category\" id=\"fun\">\n      <div class=\"category-head\">\n        <span class=\"tag\">Collection No. 06<\/span>\n        <h2>Just for Fun<\/h2>\n      <\/div>\n      <p class=\"category-desc\">Zero stakes, maximum pin-ability. For entertainment only.<\/p>\n      <div class=\"grid\" id=\"grid-fun\"><\/div>\n    <\/section>\n\n    <div class=\"ad-slot\">Advertisement space \u2014 AdSense unit<\/div>\n\n  <\/div>\n<\/main>\n\n<footer>\n  <div class=\"wrap\" style=\"display:flex; justify-content:space-between; flex-wrap:wrap; gap:14px; width:100%;\">\n    <span>\u00a9 <span id=\"year\"><\/span> Buykapra Special Tools for Girls. All tools are for entertainment and general informational purposes only, not medical, financial or professional advice.<\/span>\n    <span><a href=\"#\" id=\"privacy-link\">Privacy Policy<\/a> \u00b7 <a href=\"#\" id=\"about-link\">About<\/a> \u00b7 <a href=\"#\" id=\"contact-link\">Contact<\/a><\/span>\n  <\/div>\n<\/footer>\n\n<!-- Modal -->\n<div class=\"modal-backdrop\" id=\"modalBackdrop\">\n  <div class=\"modal\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"modalTitle\">\n    <div class=\"modal-head\">\n      <div>\n        <span class=\"tag\" id=\"modalTag\">Tool<\/span>\n        <h3 id=\"modalTitle\">Tool name<\/h3>\n      <\/div>\n      <button class=\"modal-close\" id=\"modalClose\" aria-label=\"Close\">\u2715<\/button>\n    <\/div>\n    <div class=\"modal-body\" id=\"modalBody\"><\/div>\n  <\/div>\n<\/div>\n\n<script>\ndocument.getElementById('year').textContent = new Date().getFullYear();\n\n\/* ============================================================\n   UTILITIES\n============================================================ *\/\nfunction el(tag, attrs={}, ...children){\n  const e = document.createElement(tag);\n  for(const k in attrs){\n    if(k === 'class') e.className = attrs[k];\n    else if(k === 'html') e.innerHTML = attrs[k];\n    else if(k.startsWith('on')) e.addEventListener(k.substring(2), attrs[k]);\n    else e.setAttribute(k, attrs[k]);\n  }\n  children.forEach(c=>{\n    if(typeof c === 'string') e.appendChild(document.createTextNode(c));\n    else if(c) e.appendChild(c);\n  });\n  return e;\n}\nfunction pick(arr){ return arr[Math.floor(Math.random()*arr.length)]; }\nfunction fmtDate(d){ return d.toLocaleDateString('en-US', {weekday:'short', year:'numeric', month:'short', day:'numeric'}); }\n\n\/* ============================================================\n   MODAL CONTROL\n============================================================ *\/\nconst backdrop = document.getElementById('modalBackdrop');\nconst modalTag = document.getElementById('modalTag');\nconst modalTitle = document.getElementById('modalTitle');\nconst modalBody = document.getElementById('modalBody');\n\nfunction openTool(tool){\n  modalTag.textContent = tool.tag;\n  modalTitle.textContent = tool.title;\n  modalBody.innerHTML = '';\n  tool.render(modalBody);\n  backdrop.classList.add('open');\n  document.body.style.overflow = 'hidden';\n}\nfunction closeModal(){\n  backdrop.classList.remove('open');\n  document.body.style.overflow = '';\n}\ndocument.getElementById('modalClose').addEventListener('click', closeModal);\nbackdrop.addEventListener('click', (e)=>{ if(e.target === backdrop) closeModal(); });\ndocument.addEventListener('keydown', (e)=>{ if(e.key === 'Escape') closeModal(); });\n\n\/* ============================================================\n   TOOL 1 \u2014 SKIN TONE \/ COLOR SEASON ANALYZER\n============================================================ *\/\nconst seasons = {\n  Spring: {desc:\"Warm, clear and bright. You glow in colors that feel sunlit.\", colors:['#FF9F55','#FFD35B','#7FBF7F','#FF6F61','#4FC1E9']},\n  Summer: {desc:\"Cool, soft and muted. You suit gentle, dusty shades.\", colors:['#A7BFE8','#C6A1C7','#B0B8B9','#E8A0B4','#9CC3C0']},\n  Autumn: {desc:\"Warm, rich and earthy. Deep, spiced tones love you back.\", colors:['#B5651D','#8A9A5B','#C97A3D','#7A4B3A','#D4A017']},\n  Winter: {desc:\"Cool, deep and high-contrast. Bold, saturated color is your friend.\", colors:['#1B1B3A','#C41E3A','#0F4C81','#5B2C6F','#E5E4E2']}\n};\nfunction renderColorSeason(container){\n  let answers = {undertone:null, contrast:null, eyes:null};\n  container.appendChild(el('p',{}, \"Three quick questions about your natural coloring.\"));\n  const qBox = el('div');\n  container.appendChild(qBox);\n\n  function group(label, options, key){\n    const wrap = el('div', {class:'field'});\n    wrap.appendChild(el('label',{}, label));\n    const row = el('div',{class:'choice-row'});\n    options.forEach(opt=>{\n      const b = el('button', {type:'button', onclick:()=>{\n        answers[key] = opt.value;\n        [...row.children].forEach(c=>c.classList.remove('selected'));\n        b.classList.add('selected');\n        maybeShowResult();\n      }}, opt.label);\n      row.appendChild(b);\n    });\n    wrap.appendChild(row);\n    return wrap;\n  }\n\n  qBox.appendChild(group(\"Your veins look mostly:\", [\n    {label:'Green (warm)', value:'warm'},\n    {label:'Blue\/purple (cool)', value:'cool'},\n    {label:'Both \/ not sure (neutral)', value:'neutral'},\n  ], 'undertone'));\n\n  qBox.appendChild(group(\"Next to your face, gold jewelry looks:\", [\n    {label:'Better than silver', value:'warm'},\n    {label:'Silver looks better', value:'cool'},\n    {label:'Both look fine', value:'neutral'},\n  ], 'contrast2'));\n\n  qBox.appendChild(group(\"Your natural hair vs. eye contrast is:\", [\n    {label:'Low \/ soft', value:'low'},\n    {label:'High \/ striking', value:'high'},\n  ], 'contrast'));\n\n  const resultBox = el('div', {class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  function maybeShowResult(){\n    if(!answers.undertone || !answers.contrast2 || !answers.contrast) return;\n    const warmScore = [answers.undertone, answers.contrast2].filter(v=>v==='warm').length;\n    const coolScore = [answers.undertone, answers.contrast2].filter(v=>v==='cool').length;\n    let season;\n    const isWarm = warmScore > coolScore;\n    const isHigh = answers.contrast === 'high';\n    if(isWarm && isHigh) season = 'Spring';\n    else if(isWarm && !isHigh) season = 'Autumn';\n    else if(!isWarm && isHigh) season = 'Winter';\n    else season = 'Summer';\n    const s = seasons[season];\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML = '';\n    resultBox.appendChild(el('h4', {}, \"Your color season\"));\n    resultBox.appendChild(el('div', {class:'big'}, season));\n    resultBox.appendChild(el('p', {}, s.desc));\n    const swRow = el('div', {class:'swatch-row'});\n    s.colors.forEach(c=> swRow.appendChild(el('div',{class:'swatch', style:`background:${c}`})));\n    resultBox.appendChild(swRow);\n    resultBox.appendChild(el('p', {class:'small-muted'}, \"Shop lipstick, blush and clothing in these families for the most flattering match.\"));\n  }\n}\n\n\/* ============================================================\n   TOOL 2 \u2014 CAPSULE WARDROBE PLANNER\n============================================================ *\/\nconst capsuleBase = {\n  minimal: ['White tee','Black tee','Straight-leg jeans','Tailored trousers','Neutral blazer','White sneakers','Simple flats','Trench coat','Crewneck sweater','Midi slip skirt'],\n  boho: ['Flowy midi dress','Wide-leg linen pants','Crochet top','Denim jacket','Fringe bag','Ankle boots','Printed scarf','Off-shoulder blouse','Suede skirt','Layering necklaces'],\n  classic: ['Button-down shirt','Pencil skirt','Wool coat','Cashmere sweater','Tailored blazer','Loafers','Silk blouse','Straight trousers','Pearl studs','Structured tote'],\n  edgy: ['Leather jacket','Black skinny jeans','Graphic tee','Combat boots','Oversized blazer','Slip dress','Chunky belt','Mesh top layer','Cargo pants','Statement sunglasses']\n};\nfunction renderCapsule(container){\n  container.appendChild(el('p', {}, \"Pick your style and season \u2014 get a 10-piece starter capsule.\"));\n  const styleField = el('div', {class:'field'});\n  styleField.appendChild(el('label', {}, \"Style\"));\n  const styleSel = el('select', {}, ...Object.keys(capsuleBase).map(k=> el('option',{value:k}, k[0].toUpperCase()+k.slice(1))));\n  styleField.appendChild(styleSel);\n  container.appendChild(styleField);\n\n  const seasonField = el('div', {class:'field'});\n  seasonField.appendChild(el('label', {}, \"Season\"));\n  const seasonSel = el('select', {}, ...['Spring\/Summer','Fall\/Winter'].map(s=>el('option',{value:s},s)));\n  seasonField.appendChild(seasonSel);\n  container.appendChild(seasonField);\n\n  const resultBox = el('div', {class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  const btn = el('button', {class:'btn', onclick:()=>{\n    const style = styleSel.value;\n    const season = seasonSel.value;\n    const items = [...capsuleBase[style]];\n    const extra = season === 'Spring\/Summer' ? 'Straw tote or sun hat' : 'Wool scarf or knit beanie';\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML = '';\n    resultBox.appendChild(el('h4', {}, `Your ${style} capsule \u2014 ${season}`));\n    const list = el('ul', {class:'tool-list'});\n    items.forEach(i=> list.appendChild(el('li',{}, i)));\n    list.appendChild(el('li',{}, extra));\n    resultBox.appendChild(list);\n    resultBox.appendChild(el('p', {class:'small-muted'}, \"Mix and match \u2014 10-12 well-chosen pieces should give you 20+ outfit combinations.\"));\n  }}, \"Build my capsule\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 3 \u2014 FOUNDATION SHADE MATCHER\n============================================================ *\/\nfunction renderShadeMatcher(container){\n  container.appendChild(el('p', {}, \"Answer two questions to find your foundation shade family.\"));\n  let depth=null, undertone=null;\n  const depthField = el('div',{class:'field'});\n  depthField.appendChild(el('label',{},\"How deep is your skin tone?\"));\n  const depthRow = el('div',{class:'choice-row'});\n  ['Fair','Light','Medium','Tan','Deep','Rich Deep'].forEach(d=>{\n    const b = el('button',{type:'button', onclick:()=>{depth=d; [...depthRow.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); show();}}, d);\n    depthRow.appendChild(b);\n  });\n  depthField.appendChild(depthRow);\n  container.appendChild(depthField);\n\n  const undertoneField = el('div',{class:'field'});\n  undertoneField.appendChild(el('label',{},\"Your undertone\"));\n  const undertoneRow = el('div',{class:'choice-row'});\n  ['Warm (golden\/yellow)','Cool (pink\/red)','Neutral\/Olive'].forEach(u=>{\n    const b = el('button',{type:'button', onclick:()=>{undertone=u; [...undertoneRow.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); show();}}, u);\n    undertoneRow.appendChild(b);\n  });\n  undertoneField.appendChild(undertoneRow);\n  container.appendChild(undertoneField);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  function show(){\n    if(!depth || !undertone) return;\n    const codeMap = {'Fair':'10-15','Light':'20-25','Medium':'30-35','Tan':'40-45','Deep':'50-55','Rich Deep':'60-65'};\n    const letter = undertone.startsWith('Warm') ? 'W' : undertone.startsWith('Cool') ? 'C' : 'N';\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML = '';\n    resultBox.appendChild(el('h4',{},\"Your shade family\"));\n    resultBox.appendChild(el('div',{class:'big'}, `${depth} ${letter}`));\n    resultBox.appendChild(el('p',{}, `Look for shade codes around ${codeMap[depth]}${letter} \u2014 most brands (Fenty, MAC, Est\u00e9e Lauder) use similar numbering. ${undertone.split(' ')[0]} undertone means avoiding shades that pull the opposite direction (too ashy or too orange).`));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"Tip: swatch on your jawline in daylight, not your hand \u2014 hands are often a different tone than your face.\"));\n  }\n}\n\n\/* ============================================================\n   TOOL 4 \u2014 HAIRSTYLE FINDER (FACE SHAPE QUIZ)\n============================================================ *\/\nconst faceShapeStyles = {\n  Oval: ['Almost any style works \u2014 try blunt bangs or a sleek low bun','Long layers','Curtain bangs'],\n  Round: ['Long layers past the chin to elongate','Side-swept bangs','High ponytail or bun to add height'],\n  Square: ['Soft waves to soften the jaw','Side part with layers','Chin-length lob with texture'],\n  Heart: ['Chin-length bob to balance a narrower jaw','Side-swept fringe','Waves starting at the cheekbone'],\n  Long: ['Blunt bangs to shorten the face','Waves or curls for width','Chin-length styles rather than very long hair'],\n};\nfunction renderHairstyleFinder(container){\n  container.appendChild(el('p',{}, \"Three quick questions about your face shape.\"));\n  let forehead=null, jaw=null, length=null;\n  function group(label, options, setter){\n    const wrap = el('div',{class:'field'});\n    wrap.appendChild(el('label',{}, label));\n    const row = el('div',{class:'choice-row'});\n    options.forEach(o=>{\n      const b = el('button',{type:'button', onclick:()=>{setter(o); [...row.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); compute();}}, o);\n      row.appendChild(b);\n    });\n    wrap.appendChild(row);\n    return wrap;\n  }\n  container.appendChild(group(\"Your forehead is:\", ['Narrow','Wide\/round'], v=>forehead=v));\n  container.appendChild(group(\"Your jawline is:\", ['Soft\/rounded','Angular','Pointed'], v=>jaw=v));\n  container.appendChild(group(\"Your face length feels:\", ['About as long as it is wide','Noticeably longer than wide'], v=>length=v));\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  function compute(){\n    if(!forehead || !jaw || !length) return;\n    let shape;\n    if(length === 'Noticeably longer than wide') shape = 'Long';\n    else if(jaw === 'Angular' && forehead === 'Wide\/round') shape = 'Square';\n    else if(jaw === 'Pointed') shape = 'Heart';\n    else if(jaw === 'Soft\/rounded' && forehead === 'Wide\/round') shape = 'Round';\n    else shape = 'Oval';\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your face shape\"));\n    resultBox.appendChild(el('div',{class:'big'}, shape));\n    const list = el('ul',{class:'tool-list'});\n    faceShapeStyles[shape].forEach(s=> list.appendChild(el('li',{},s)));\n    resultBox.appendChild(list);\n  }\n}\n\n\/* ============================================================\n   TOOL 5 \u2014 NAIL ART IDEA GENERATOR\n============================================================ *\/\nconst nailColors = ['soft lilac','classic red','sage green','milky white','espresso brown','baby blue','buttery yellow','deep burgundy','rose gold chrome','black'];\nconst nailStyles = ['French tip','ombr\u00e9 fade','minimalist single line','marble swirl','glitter accent nail','negative space','tiny florals','geometric lines','swirls','checkerboard'];\nconst nailOccasions = ['everyday wear','a wedding guest look','a beach vacation','a holiday party','a first date','back-to-school','a birthday night out','date night'];\nfunction renderNailArt(container){\n  const resultBox = el('div',{class:'result-box hidden'});\n  const btn = el('button',{class:'btn', onclick:()=>{\n    const idea = `${pick(nailColors)} with a ${pick(nailStyles)}, perfect for ${pick(nailOccasions)}`;\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your nail art idea\"));\n    resultBox.appendChild(el('p',{class:'big', style:'font-size:19px;'}, idea.charAt(0).toUpperCase()+idea.slice(1)));\n  }}, \"Generate an idea\");\n  container.appendChild(el('p',{},\"Tap for a random nail art combo \u2014 color, style and occasion.\"));\n  container.appendChild(btn);\n  container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   TOOL 6 \u2014 PERIOD \/ CYCLE TRACKER (calendar-based, not medical)\n============================================================ *\/\nfunction renderCycleTracker(container){\n  container.appendChild(el('p',{}, \"For general planning only \u2014 this is not medical advice.\"));\n  const dateField = el('div',{class:'field'});\n  dateField.appendChild(el('label',{},\"First day of your last period\"));\n  const dateInput = el('input',{type:'date'});\n  dateField.appendChild(dateInput);\n  container.appendChild(dateField);\n\n  const lenField = el('div',{class:'field'});\n  lenField.appendChild(el('label',{},\"Average cycle length (days)\"));\n  const lenInput = el('input',{type:'number', value:'28', min:'20', max:'40'});\n  lenField.appendChild(lenInput);\n  container.appendChild(lenField);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  const btn = el('button',{class:'btn', onclick:()=>{\n    if(!dateInput.value) return;\n    const start = new Date(dateInput.value+'T00:00:00');\n    const len = parseInt(lenInput.value) || 28;\n    const next1 = new Date(start); next1.setDate(start.getDate()+len);\n    const next2 = new Date(start); next2.setDate(start.getDate()+len*2);\n    const ovulation = new Date(start); ovulation.setDate(start.getDate()+len-14);\n    const fertileStart = new Date(ovulation); fertileStart.setDate(ovulation.getDate()-5);\n    const fertileEnd = new Date(ovulation); fertileEnd.setDate(ovulation.getDate()+1);\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Estimated calendar\"));\n    const table = el('table',{class:'simple'});\n    table.appendChild(el('tr',{}, el('th',{},'Next period (est.)'), el('td',{}, fmtDate(next1))));\n    table.appendChild(el('tr',{}, el('th',{},'Following period (est.)'), el('td',{}, fmtDate(next2))));\n    table.appendChild(el('tr',{}, el('th',{},'Estimated ovulation'), el('td',{}, fmtDate(ovulation))));\n    table.appendChild(el('tr',{}, el('th',{},'Estimated fertile window'), el('td',{}, `${fmtDate(fertileStart)} \u2013 ${fmtDate(fertileEnd)}`)));\n    resultBox.appendChild(table);\n    resultBox.appendChild(el('p',{class:'small-muted'},\"Estimates only, based on averages. Cycles vary \u2014 talk to a doctor for anything medical.\"));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 7 \u2014 PREGNANCY DUE DATE CALCULATOR\n============================================================ *\/\nfunction renderDueDate(container){\n  container.appendChild(el('p',{}, \"Uses Naegele's rule \u2014 an estimate only. For general planning purposes.\"));\n  const dateField = el('div',{class:'field'});\n  dateField.appendChild(el('label',{},\"First day of last menstrual period (LMP)\"));\n  const dateInput = el('input',{type:'date'});\n  dateField.appendChild(dateInput);\n  container.appendChild(dateField);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  const btn = el('button',{class:'btn', onclick:()=>{\n    if(!dateInput.value) return;\n    const lmp = new Date(dateInput.value+'T00:00:00');\n    const due = new Date(lmp); due.setDate(lmp.getDate()+280);\n    const t1 = new Date(lmp);\n    const t2 = new Date(lmp); t2.setDate(lmp.getDate()+13*7);\n    const t3 = new Date(lmp); t3.setDate(lmp.getDate()+27*7);\n    const today = new Date();\n    const weeksAlong = Math.max(0, Math.floor((today-lmp)\/(1000*60*60*24*7)));\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Estimated due date\"));\n    resultBox.appendChild(el('div',{class:'big'}, fmtDate(due)));\n    resultBox.appendChild(el('p',{}, weeksAlong <= 42 ? `That's about ${weeksAlong} weeks along today.` : ''));\n    const table = el('table',{class:'simple'});\n    table.appendChild(el('tr',{}, el('th',{},'1st trimester begins'), el('td',{}, fmtDate(t1))));\n    table.appendChild(el('tr',{}, el('th',{},'2nd trimester begins'), el('td',{}, fmtDate(t2))));\n    table.appendChild(el('tr',{}, el('th',{},'3rd trimester begins'), el('td',{}, fmtDate(t3))));\n    resultBox.appendChild(table);\n    resultBox.appendChild(el('p',{class:'small-muted'},\"An estimate \u2014 only about 1 in 20 babies arrive on the exact due date. Confirm dates with your provider.\"));\n  }}, \"Calculate due date\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 8 \u2014 BABY NAME GENERATOR\n============================================================ *\/\nconst babyNames = {\n  girl: {classic:['Elizabeth','Margaret','Charlotte','Eleanor','Catherine','Anne','Victoria','Josephine'],\n    modern:['Willow','Nova','Everly','Aria','Luna','Harper','Aurora','Sadie'],\n    nature:['Ivy','Hazel','Wren','Dahlia','Iris','Fern','Rose','Sage'],\n    vintage:['Mabel','Edith','Ruth','Florence','Alice','Beatrice','Clara','Dorothy']},\n  boy: {classic:['William','James','Alexander','Benjamin','Henry','Theodore','Samuel','Edward'],\n    modern:['Kai','Rowan','Ezra','Asher','Jasper','Leo','Milo','Beckett'],\n    nature:['Forrest','River','Cedar','Rock','Reed','Colt','Fox','Sterling'],\n    vintage:['Walter','Arthur','Frank','Oliver','George','Albert','Leonard','Herbert']},\n  neutral: {classic:['Jordan','Morgan','Riley','Casey','Taylor','Reese','Avery','Quinn'],\n    modern:['Rowan','Sky','Justice','Rain','Ocean','Phoenix','Dakota','Sage'],\n    nature:['River','Wren','Bay','Fern','Sage','Robin','Lark','Birch'],\n    vintage:['Frankie','Charlie','Ellis','Marion','Shirley','Lane','Wynn','Bay']}\n};\nfunction renderBabyNames(container){\n  container.appendChild(el('p',{}, \"Choose a category and get three name suggestions.\"));\n  let gender='girl', style='classic';\n  const genderField = el('div',{class:'field'});\n  genderField.appendChild(el('label',{},\"Looking for\"));\n  const gRow = el('div',{class:'choice-row'});\n  [['girl','Girl'],['boy','Boy'],['neutral','Gender-neutral']].forEach(([v,l])=>{\n    const b = el('button',{type:'button', onclick:()=>{gender=v; [...gRow.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected');}}, l);\n    if(v==='girl') b.classList.add('selected');\n    gRow.appendChild(b);\n  });\n  genderField.appendChild(gRow);\n  container.appendChild(genderField);\n\n  const styleField = el('div',{class:'field'});\n  styleField.appendChild(el('label',{},\"Style\"));\n  const sRow = el('div',{class:'choice-row'});\n  [['classic','Classic'],['modern','Modern'],['nature','Nature'],['vintage','Vintage']].forEach(([v,l])=>{\n    const b = el('button',{type:'button', onclick:()=>{style=v; [...sRow.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected');}}, l);\n    if(v==='classic') b.classList.add('selected');\n    sRow.appendChild(b);\n  });\n  styleField.appendChild(sRow);\n  container.appendChild(styleField);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  const btn = el('button',{class:'btn', onclick:()=>{\n    const pool = [...babyNames[gender][style]];\n    const picks = [];\n    while(picks.length < 3 &#038;&#038; pool.length){\n      const idx = Math.floor(Math.random()*pool.length);\n      picks.push(pool.splice(idx,1)[0]);\n    }\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Name suggestions\"));\n    const list = el('ul',{class:'tool-list'});\n    picks.forEach(n=> list.appendChild(el('li',{}, el('span',{style:'font-family:Fraunces,serif; font-size:17px;'}, n))));\n    resultBox.appendChild(list);\n  }}, \"Generate names\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 9 \u2014 WEDDING COUNTDOWN & BUDGET PLANNER\n============================================================ *\/\nfunction renderWeddingPlanner(container){\n  const dateField = el('div',{class:'field'});\n  dateField.appendChild(el('label',{},\"Wedding date\"));\n  const dateInput = el('input',{type:'date'});\n  dateField.appendChild(dateInput);\n  container.appendChild(dateField);\n\n  const budgetField = el('div',{class:'field'});\n  budgetField.appendChild(el('label',{},\"Total budget (USD)\"));\n  const budgetInput = el('input',{type:'number', placeholder:'e.g. 25000'});\n  budgetField.appendChild(budgetInput);\n  container.appendChild(budgetField);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  const btn = el('button',{class:'btn', onclick:()=>{\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    if(dateInput.value){\n      const wed = new Date(dateInput.value+'T00:00:00');\n      const today = new Date(); today.setHours(0,0,0,0);\n      const days = Math.ceil((wed-today)\/(1000*60*60*24));\n      resultBox.appendChild(el('h4',{},\"Countdown\"));\n      resultBox.appendChild(el('div',{class:'big'}, days >= 0 ? `${days} days to go` : \"That date has passed \u2014 congratulations!\"));\n    }\n    const budget = parseFloat(budgetInput.value);\n    if(budget){\n      const breakdown = [\n        ['Venue & catering', 0.45],['Photography & video', 0.11],['Attire & beauty', 0.08],\n        ['Flowers & d\u00e9cor', 0.09],['Music & entertainment', 0.08],['Stationery', 0.03],\n        ['Rings', 0.05],['Planner\/coordinator', 0.07],['Miscellaneous\/buffer', 0.04]\n      ];\n      resultBox.appendChild(el('h4',{style:'margin-top:16px;'},\"Suggested budget breakdown\"));\n      const table = el('table',{class:'simple'});\n      breakdown.forEach(([label, pct])=>{\n        table.appendChild(el('tr',{}, el('th',{}, label), el('td',{}, `$${Math.round(budget*pct).toLocaleString()} (${Math.round(pct*100)}%)`)));\n      });\n      resultBox.appendChild(table);\n    }\n    resultBox.appendChild(el('p',{class:'small-muted'},\"Guideline percentages based on typical US wedding spending \u2014 adjust to your priorities.\"));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 10 \u2014 BMI CALCULATOR\n============================================================ *\/\nfunction renderBMI(container){\n  container.appendChild(el('p',{}, \"BMI is a rough general-population screening number, not a full picture of health. Use it as one data point only.\"));\n  const hField = el('div',{class:'field'});\n  hField.appendChild(el('label',{},\"Height (inches)\"));\n  const hInput = el('input',{type:'number', placeholder:'e.g. 65'});\n  hField.appendChild(hInput);\n  container.appendChild(hField);\n\n  const wField = el('div',{class:'field'});\n  wField.appendChild(el('label',{},\"Weight (lbs)\"));\n  const wInput = el('input',{type:'number', placeholder:'e.g. 140'});\n  wField.appendChild(wInput);\n  container.appendChild(wField);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  const btn = el('button',{class:'btn', onclick:()=>{\n    const h = parseFloat(hInput.value), w = parseFloat(wInput.value);\n    if(!h || !w) return;\n    const bmi = (w \/ (h*h)) * 703;\n    let category;\n    if(bmi < 18.5) category = 'Below the typical range';\n    else if(bmi < 25) category = 'Within the typical range';\n    else if(bmi < 30) category = 'Above the typical range';\n    else category = 'Well above the typical range';\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your BMI\"));\n    resultBox.appendChild(el('div',{class:'big'}, bmi.toFixed(1)));\n    resultBox.appendChild(el('p',{}, category));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"BMI doesn't account for muscle mass, frame size or overall health. Talk to a doctor for a fuller picture.\"));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 11 \u2014 WEDDING HASHTAG GENERATOR\n============================================================ *\/\nfunction renderHashtagGen(container){\n  const f1 = el('div',{class:'field'});\n  f1.appendChild(el('label',{},\"Partner 1 first\/last name\"));\n  const i1 = el('input',{type:'text', placeholder:'e.g. Emma Reyes'});\n  f1.appendChild(i1);\n  container.appendChild(f1);\n\n  const f2 = el('div',{class:'field'});\n  f2.appendChild(el('label',{},\"Partner 2 first\/last name\"));\n  const i2 = el('input',{type:'text', placeholder:'e.g. Jake Miller'});\n  f2.appendChild(i2);\n  container.appendChild(f2);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  const btn = el('button',{class:'btn', onclick:()=>{\n    const a = i1.value.trim().split(' ');\n    const b = i2.value.trim().split(' ');\n    if(!a[0] || !b[0]) return;\n    const aFirst = a[0], aLast = a[1]||'';\n    const bFirst = b[0], bLast = b[1]||'';\n    const ideas = new Set();\n    ideas.add(`#${aFirst}And${bFirst}`);\n    ideas.add(`#${aFirst}Meets${bFirst}`);\n    if(aLast && bLast) ideas.add(`#The${aLast}${bLast}Wedding`);\n    if(aLast) ideas.add(`#${aFirst}Becomes${aLast==bLast?'':''}${bLast||aLast}`.replace('##','#'));\n    ideas.add(`#${aFirst}${bFirst}${new Date().getFullYear()}`);\n    ideas.add(`#${aFirst}Ties${bFirst}Down`);\n    ideas.add(`#${aFirst}Plus${bFirst}Forever`);\n    ideas.add(`#${aFirst}${bFirst}IDo`);\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Hashtag ideas\"));\n    const list = el('ul',{class:'tool-list'});\n    [...ideas].slice(0,7).forEach(h=> list.appendChild(el('li',{}, h.replace(\/\\s+\/g,''))));\n    resultBox.appendChild(list);\n  }}, \"Generate hashtags\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 12 \u2014 SHOWER CHECKLIST GENERATOR\n============================================================ *\/\nconst showerChecklists = {\n  bridal: ['Set date & guest list','Book venue','Send invitations (6-8 wks out)','Plan menu & cake','Choose theme & d\u00e9cor','Plan games\/activities','Order favors','Coordinate gift registry sharing','Arrange photography','Plan seating & tables','Prep thank-you cards for the bride'],\n  baby: ['Set date & guest list','Book venue','Send invitations (4-6 wks out)','Confirm baby registry link','Plan menu & diaper cake\/cake','Choose theme & d\u00e9cor','Plan games (guess the belly size, etc.)','Order favors','Arrange photography','Plan seating','Prep thank-you cards for mom-to-be']\n};\nfunction renderShowerChecklist(container){\n  const typeField = el('div',{class:'field'});\n  typeField.appendChild(el('label',{},\"Shower type\"));\n  const row = el('div',{class:'choice-row'});\n  const resultBox = el('div',{class:'result-box hidden'});\n  [['bridal','Bridal Shower'],['baby','Baby Shower']].forEach(([v,l])=>{\n    const b = el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(c=>c.classList.remove('selected'));\n      b.classList.add('selected');\n      resultBox.classList.remove('hidden');\n      resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{}, `${l} checklist`));\n      const list = el('ul',{class:'tool-list'});\n      showerChecklists[v].forEach(item=>{\n        const li = el('li',{});\n        const label = el('label',{style:'display:flex; gap:8px; align-items:flex-start; cursor:pointer;'});\n        label.appendChild(el('input',{type:'checkbox'}));\n        label.appendChild(el('span',{}, item));\n        li.appendChild(label);\n        list.appendChild(li);\n      });\n      resultBox.appendChild(list);\n    }}, l);\n    row.appendChild(b);\n  });\n  typeField.appendChild(row);\n  container.appendChild(typeField);\n  container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   TOOL 13 \u2014 GIFT IDEA GENERATOR\n============================================================ *\/\nconst giftIdeas = {\n  mom:{cozy:['A weighted blanket','Silk pillowcase set','Herbal tea sampler'], experience:['Spa day gift card','Cooking class for two','Weekend getaway'], practical:['Nice robe','Instant Pot','Photo book of the family']},\n  bestfriend:{cozy:['Matching pajama sets','A candle from her favorite scent','Comfy oversized sweater'], experience:['Concert tickets','Wine tasting outing','Paint & sip class'], practical:['Cute planner','Portable phone charger','Personalized tote bag']},\n  sister:{cozy:['Fuzzy socks & hot cocoa set','Skincare gift set','Soft throw blanket'], experience:['Mani-pedi date','Escape room outing','Trip to an amusement park'], practical:['Jewelry organizer','Kindle e-reader','Cute daily planner']},\n  coworker:{cozy:['Nice mug & tea set','Desk plant','Scented candle'], experience:['Coffee shop gift card','Lunch out gift card',''], practical:['Desk organizer','Notebook & pen set','Water bottle']},\n  partner:{cozy:['Matching hoodies','A blanket for movie nights','Comfy slippers'], experience:['Weekend trip','Dinner reservation','Concert tickets'], practical:['Watch','Wallet','Personalized item with an inside joke']}\n};\nfunction renderGiftGen(container){\n  let who=null, vibe=null;\n  const f1 = el('div',{class:'field'});\n  f1.appendChild(el('label',{},\"Who are you shopping for?\"));\n  const r1 = el('div',{class:'choice-row'});\n  [['mom','Mom'],['bestfriend','Best Friend'],['sister','Sister'],['coworker','Coworker'],['partner','Partner']].forEach(([v,l])=>{\n    const b = el('button',{type:'button', onclick:()=>{who=v; [...r1.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); compute();}}, l);\n    r1.appendChild(b);\n  });\n  f1.appendChild(r1);\n  container.appendChild(f1);\n\n  const f2 = el('div',{class:'field'});\n  f2.appendChild(el('label',{},\"What kind of gift?\"));\n  const r2 = el('div',{class:'choice-row'});\n  [['cozy','Cozy & comforting'],['experience','An experience'],['practical','Practical & useful']].forEach(([v,l])=>{\n    const b = el('button',{type:'button', onclick:()=>{vibe=v; [...r2.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); compute();}}, l);\n    r2.appendChild(b);\n  });\n  f2.appendChild(r2);\n  container.appendChild(f2);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  function compute(){\n    if(!who || !vibe) return;\n    const ideas = giftIdeas[who][vibe].filter(Boolean);\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Gift ideas\"));\n    const list = el('ul',{class:'tool-list'});\n    ideas.forEach(i=> list.appendChild(el('li',{}, i)));\n    resultBox.appendChild(list);\n  }\n}\n\n\/* ============================================================\n   TOOL 14 \u2014 AESTHETIC \/ VIBE QUIZ\n============================================================ *\/\nconst vibeResults = {\n  cottagecore: {name:'Cottagecore', desc:'Soft, pastoral and homemade \u2014 think flower pressing, fresh bread and gingham.'},\n  y2k: {name:'Y2K', desc:'Butterfly clips, low-rise and metallics \u2014 playful, nostalgic maximalism.'},\n  darkacademia: {name:'Dark Academia', desc:'Tweed, candlelight and old libraries \u2014 moody and literary.'},\n  coastal: {name:'Coastal Grandma', desc:'Linen, neutral tones and salt air \u2014 easy, breezy elegance.'},\n  minimalist: {name:'Modern Minimalist', desc:'Clean lines, neutral palettes and negative space \u2014 less but better.'}\n};\nfunction renderVibeQuiz(container){\n  const questions = [\n    {q:\"Your ideal Saturday involves:\", opts:[['A farmer\\'s market and baking bread','cottagecore'],['Thrifting for the perfect throwback piece','y2k'],['A cafe with a good book','darkacademia'],['A long beach walk','coastal'],['Reorganizing your space','minimalist']]},\n    {q:\"Your dream living room has:\", opts:[['Dried flowers everywhere','cottagecore'],['Bright colors and lava lamps','y2k'],['Dark wood and stacks of books','darkacademia'],['White linen and rattan','coastal'],['One statement piece, nothing else','minimalist']]},\n    {q:\"Your go-to color palette:\", opts:[['Sage & cream','cottagecore'],['Hot pink & silver','y2k'],['Burgundy & navy','darkacademia'],['Sand & white','coastal'],['Black, white & one accent','minimalist']]},\n  ];\n  const scores = {cottagecore:0,y2k:0,darkacademia:0,coastal:0,minimalist:0};\n  let current = 0;\n  const qWrap = el('div');\n  const dots = el('div',{class:'progress-dots'});\n  questions.forEach((_,i)=> dots.appendChild(el('span', i===0?{class:'active'}:{})));\n  container.appendChild(dots);\n  container.appendChild(qWrap);\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  function renderQ(){\n    qWrap.innerHTML='';\n    if(current >= questions.length){\n      const winner = Object.entries(scores).sort((a,b)=>b[1]-a[1])[0][0];\n      const r = vibeResults[winner];\n      resultBox.classList.remove('hidden');\n      resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"Your aesthetic\"));\n      resultBox.appendChild(el('div',{class:'big'}, r.name));\n      resultBox.appendChild(el('p',{}, r.desc));\n      const retry = el('button',{class:'btn secondary', style:'margin-top:12px;', onclick:()=>{\n        Object.keys(scores).forEach(k=>scores[k]=0); current=0; resultBox.classList.add('hidden');\n        [...dots.children].forEach((d,i)=>d.classList.toggle('active', i===0));\n        renderQ();\n      }}, \"Retake quiz\");\n      resultBox.appendChild(retry);\n      return;\n    }\n    [...dots.children].forEach((d,i)=>d.classList.toggle('active', i===current));\n    const item = questions[current];\n    qWrap.appendChild(el('p',{style:'font-weight:600; margin-bottom:10px;'}, item.q));\n    const row = el('div',{class:'choice-row', style:'flex-direction:column; align-items:flex-start;'});\n    item.opts.forEach(([label, key])=>{\n      const b = el('button',{type:'button', style:'width:100%; text-align:left; border-radius:6px;', onclick:()=>{\n        scores[key]++;\n        current++;\n        renderQ();\n      }}, label);\n      row.appendChild(b);\n    });\n    qWrap.appendChild(row);\n  }\n  renderQ();\n}\n\n\/* ============================================================\n   TOOL 15 \u2014 JOURNALING PROMPT GENERATOR\n============================================================ *\/\nconst journalPrompts = [\n  \"What's something you did today that your younger self would be proud of?\",\n  \"What is a boundary you need to set, and with whom?\",\n  \"Describe a moment this week you felt truly at ease.\",\n  \"What are you holding onto that it might be time to release?\",\n  \"Write about a person who changed your perspective on something.\",\n  \"What does your ideal ordinary Tuesday look like?\",\n  \"What's a compliment you received that you should believe more?\",\n  \"What would you do differently if you weren't afraid of judgment?\",\n  \"List three things that are quietly going right in your life.\",\n  \"What's a habit you're proud of building?\",\n  \"Write a letter to yourself one year from today.\",\n  \"What does 'enough' feel like to you right now?\"\n];\nfunction renderJournalPrompt(container){\n  const box = el('div',{class:'result-box'});\n  box.appendChild(el('h4',{},\"Today's prompt\"));\n  const text = el('p',{class:'big', style:'font-size:20px; line-height:1.3;'}, pick(journalPrompts));\n  box.appendChild(text);\n  container.appendChild(box);\n  const btn = el('button',{class:'btn', style:'margin-top:16px;', onclick:()=>{ text.textContent = pick(journalPrompts); }}, \"Give me another\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 16 \u2014 NAME COMPATIBILITY CALCULATOR\n============================================================ *\/\nfunction renderNameCompat(container){\n  const f1 = el('div',{class:'field'});\n  f1.appendChild(el('label',{},\"Name one\"));\n  const i1 = el('input',{type:'text', placeholder:'e.g. Emma'});\n  f1.appendChild(i1);\n  container.appendChild(f1);\n\n  const f2 = el('div',{class:'field'});\n  f2.appendChild(el('label',{},\"Name two\"));\n  const i2 = el('input',{type:'text', placeholder:'e.g. Liam'});\n  f2.appendChild(i2);\n  container.appendChild(f2);\n\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n\n  function computeScore(a,b){\n    const combined = (a+b).toLowerCase().replace(\/[^a-z]\/g,'');\n    let hash = 0;\n    for(let i=0;i<combined.length;i++){ hash = (hash * 31 + combined.charCodeAt(i)) % 97; }\n    return 40 + (hash % 61); \/\/ 40-100 range, deterministic &#038; \"fun\"\n  }\n  const messages = [\n    [90, \"Written in the stars \u2728\"],\n    [75, \"A really strong match!\"],\n    [55, \"Good potential, worth exploring.\"],\n    [0, \"Opposites \u2014 could still work with effort!\"]\n  ];\n  const btn = el('button',{class:'btn', onclick:()=>{\n    const a = i1.value.trim(), b = i2.value.trim();\n    if(!a || !b) return;\n    const score = computeScore(a,b);\n    const msg = messages.find(m=>score>=m[0])[1];\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},`${a} + ${b}`));\n    resultBox.appendChild(el('div',{class:'big'}, `${score}%`));\n    resultBox.appendChild(el('p',{}, msg));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"For entertainment only \u2014 a fun, not-scientific pairing calculator.\"));\n  }}, \"Calculate compatibility\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 17 \u2014 \"WHAT ERA DO YOU BELONG IN\" QUIZ\n============================================================ *\/\nconst eraResults = {\n  fifties: {name:'The 1950s', desc:'Diners, full skirts and doo-wop \u2014 you love charm and structure.'},\n  seventies:{name:'The 1970s', desc:'Bohemian, warm and free-spirited \u2014 you belong at a rooftop sunset party.'},\n  nineties:{name:'The 1990s', desc:'Grunge meets minimalism \u2014 effortlessly cool, a little rebellious.'},\n  y2k:{name:'The Y2K Era', desc:'Bright, bold and a little chaotic in the best way \u2014 main character energy.'},\n  regency:{name:'The Regency Era', desc:'Candlelit ballrooms and witty letters \u2014 you\\'d have thrived writing love notes.'}\n};\nfunction renderEraQuiz(container){\n  const questions = [\n    {q:\"Pick a soundtrack:\", opts:[['Doo-wop harmonies','fifties'],['Warm acoustic guitar','seventies'],['Grunge guitar riffs','nineties'],['Bubblegum pop','y2k'],['Orchestral strings','regency']]},\n    {q:\"Pick a night out:\", opts:[['A milkshake at the diner','fifties'],['A rooftop party at sunset','seventies'],['A dingy but iconic concert','nineties'],['Mall arcade with friends','y2k'],['A candlelit ball','regency']]},\n    {q:\"Pick a wardrobe staple:\", opts:[['Full swing skirt','fifties'],['Bell-bottoms','seventies'],['Flannel & combat boots','nineties'],['Low-rise jeans & tiny bag','y2k'],['Empire-waist gown','regency']]},\n  ];\n  const scores = {fifties:0,seventies:0,nineties:0,y2k:0,regency:0};\n  let current = 0;\n  const qWrap = el('div');\n  container.appendChild(qWrap);\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n  function renderQ(){\n    qWrap.innerHTML='';\n    if(current >= questions.length){\n      const winner = Object.entries(scores).sort((a,b)=>b[1]-a[1])[0][0];\n      const r = eraResults[winner];\n      resultBox.classList.remove('hidden');\n      resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"You belong in...\"));\n      resultBox.appendChild(el('div',{class:'big'}, r.name));\n      resultBox.appendChild(el('p',{}, r.desc));\n      const retry = el('button',{class:'btn secondary', style:'margin-top:12px;', onclick:()=>{\n        Object.keys(scores).forEach(k=>scores[k]=0); current=0; resultBox.classList.add('hidden'); renderQ();\n      }}, \"Retake quiz\");\n      resultBox.appendChild(retry);\n      return;\n    }\n    const item = questions[current];\n    qWrap.appendChild(el('p',{style:'font-weight:600; margin-bottom:10px;'}, item.q));\n    const row = el('div',{class:'choice-row', style:'flex-direction:column; align-items:flex-start;'});\n    item.opts.forEach(([label,key])=>{\n      const b = el('button',{type:'button', style:'width:100%; text-align:left; border-radius:6px;', onclick:()=>{ scores[key]++; current++; renderQ(); }}, label);\n      row.appendChild(b);\n    });\n    qWrap.appendChild(row);\n  }\n  renderQ();\n}\n\n\/* ============================================================\n   TOOL 18 \u2014 ZODIAC PERSONALITY GENERATOR\n============================================================ *\/\nconst zodiacData = [\n  {sign:'Capricorn', start:[12,22], end:[1,19], traits:'disciplined, ambitious and quietly funny once you know them.'},\n  {sign:'Aquarius', start:[1,20], end:[2,18], traits:'independent, original, and a little ahead of the curve.'},\n  {sign:'Pisces', start:[2,19], end:[3,20], traits:'dreamy, empathetic, and deeply intuitive.'},\n  {sign:'Aries', start:[3,21], end:[4,19], traits:'bold, direct, and first to try new things.'},\n  {sign:'Taurus', start:[4,20], end:[5,20], traits:'steady, loyal, and a lover of comfort and good food.'},\n  {sign:'Gemini', start:[5,21], end:[6,20], traits:'curious, witty, and great in conversation.'},\n  {sign:'Cancer', start:[6,21], end:[7,22], traits:'nurturing, sentimental, and fiercely protective of loved ones.'},\n  {sign:'Leo', start:[7,23], end:[8,22], traits:'warm, confident, and a natural in the spotlight.'},\n  {sign:'Virgo', start:[8,23], end:[9,22], traits:'thoughtful, detail-oriented, and quietly the one holding things together.'},\n  {sign:'Libra', start:[9,23], end:[10,22], traits:'diplomatic, charming, and always looking for balance.'},\n  {sign:'Scorpio', start:[10,23], end:[11,21], traits:'intense, magnetic, and fiercely loyal once trust is earned.'},\n  {sign:'Sagittarius', start:[11,22], end:[12,21], traits:'adventurous, honest, and always planning the next trip.'}\n];\nfunction renderZodiac(container){\n  const f = el('div',{class:'field'});\n  f.appendChild(el('label',{},\"Your birth date\"));\n  const dateInput = el('input',{type:'date'});\n  f.appendChild(dateInput);\n  container.appendChild(f);\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n  const btn = el('button',{class:'btn', onclick:()=>{\n    if(!dateInput.value) return;\n    const d = new Date(dateInput.value+'T00:00:00');\n    const m = d.getMonth()+1, day = d.getDate();\n    let match = zodiacData.find(z=>{\n      const [sm,sd] = z.start, [em,ed] = z.end;\n      if(sm === em) return m===sm && day>=sd && day<=ed;\n      if(sm > em){ \/\/ wraps around new year (Capricorn)\n        return (m===sm && day>=sd) || (m===em && day<=ed);\n      }\n      return (m===sm &#038;&#038; day>=sd) || (m===em && day<=ed) || (m>sm && m<em);\n    });\n    if(!match) match = zodiacData[0];\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your sign\"));\n    resultBox.appendChild(el('div',{class:'big'}, match.sign));\n    resultBox.appendChild(el('p',{}, `You're typically ${match.traits}`));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"For fun \u2014 not a scientific personality assessment.\"));\n  }}, \"Reveal my sign\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL 19 \u2014 PINTEREST BOARD NAME GENERATOR\n============================================================ *\/\nconst boardPrefixes = ['Dreamy','Cozy','Modern','Whimsical','Golden Hour','Soft','Everyday','Curated','Wildflower','Sun-Kissed'];\nconst boardSuffixes = ['Inspo','Vibes','Moodboard','Edit','Diaries','Aesthetic','Corner','Collection','Notes','Mood'];\nfunction renderBoardNameGen(container){\n  const f = el('div',{class:'field'});\n  f.appendChild(el('label',{},\"Board theme (e.g. 'home decor', 'wedding', 'skincare')\"));\n  const input = el('input',{type:'text', placeholder:'Type a theme...'});\n  f.appendChild(input);\n  container.appendChild(f);\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n  const btn = el('button',{class:'btn', onclick:()=>{\n    const theme = input.value.trim();\n    if(!theme) return;\n    const cap = theme.replace(\/\\b\\w\/g, c=>c.toUpperCase());\n    const names = new Set();\n    while(names.size < 5){\n      names.add(`${pick(boardPrefixes)} ${cap} ${pick(boardSuffixes)}`);\n    }\n    resultBox.classList.remove('hidden');\n    resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Board name ideas\"));\n    const list = el('ul',{class:'tool-list'});\n    [...names].forEach(n=> list.appendChild(el('li',{}, n)));\n    resultBox.appendChild(list);\n  }}, \"Generate board names\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   SHARED HELPERS FOR NEW TOOLS\n============================================================ *\/\nfunction renderGenericQuiz(container, questions, resolver){\n  const scores = {};\n  let current = 0;\n  const dots = el('div',{class:'progress-dots'});\n  questions.forEach((_,i)=>dots.appendChild(el('span', i===0?{class:'active'}:{})));\n  const qWrap = el('div');\n  container.appendChild(dots);\n  container.appendChild(qWrap);\n  const resultBox = el('div',{class:'result-box hidden'});\n  container.appendChild(resultBox);\n  function renderQ(){\n    qWrap.innerHTML='';\n    if(current>=questions.length){\n      const r = resolver(scores);\n      resultBox.classList.remove('hidden');\n      resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{}, r.label || \"Your result\"));\n      resultBox.appendChild(el('div',{class:'big'}, r.title));\n      if(r.desc) resultBox.appendChild(el('p',{}, r.desc));\n      const retry = el('button',{class:'btn secondary', style:'margin-top:12px;', onclick:()=>{\n        Object.keys(scores).forEach(k=>delete scores[k]); current=0; resultBox.classList.add('hidden'); renderQ();\n      }},\"Retake quiz\");\n      resultBox.appendChild(retry);\n      return;\n    }\n    [...dots.children].forEach((d,i)=>d.classList.toggle('active', i===current));\n    const item = questions[current];\n    qWrap.appendChild(el('p',{style:'font-weight:600;margin-bottom:10px;'}, item.q));\n    const row = el('div',{class:'choice-row', style:'flex-direction:column; align-items:flex-start;'});\n    item.opts.forEach(([label,key])=>{\n      const b = el('button',{type:'button', style:'width:100%; text-align:left; border-radius:6px;', onclick:()=>{\n        scores[key] = (scores[key]||0)+1; current++; renderQ();\n      }}, label);\n      row.appendChild(b);\n    });\n    qWrap.appendChild(row);\n  }\n  renderQ();\n}\nfunction topScore(scores){ return Object.entries(scores).sort((a,b)=>b[1]-a[1])[0][0]; }\nfunction copyBtn(getText, labelText='Copy text'){\n  return el('button',{class:'btn secondary', style:'margin-top:10px;', onclick:async (e)=>{\n    try{ await navigator.clipboard.writeText(getText()); e.target.textContent='Copied!'; setTimeout(()=>e.target.textContent=labelText,1400); }\n    catch(err){ alert('Select and copy the text manually.'); }\n  }}, labelText);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 OUTFIT PLANNER\n============================================================ *\/\nconst outfitData = {\n  casual:{cool:'Oversized sweater, straight jeans, sneakers, crossbody bag.', mild:'Fitted tee, jeans, light cardigan, sneakers.', warm:'Sundress, sandals, straw bag, sunglasses.'},\n  work:{cool:'Turtleneck, tailored trousers, blazer, ankle boots.', mild:'Button-down, midi skirt, loafers, blazer.', warm:'Sleeveless blouse, linen trousers, flats.'},\n  date:{cool:'Fitted sweater, leather skirt, ankle boots, statement earrings.', mild:'Slip dress with a light jacket, heeled sandals.', warm:'Flowy sundress, strappy sandals, delicate jewelry.'},\n  party:{cool:'Sequin top, tailored pants, heels, bold lip.', mild:'Little black dress, heels, clutch.', warm:'Bright mini dress, strappy heels, statement earrings.'}\n};\nfunction renderOutfitPlanner(container){\n  let occasion=null, weather=null;\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"Occasion\"));\n  const r1=el('div',{class:'choice-row'});\n  [['casual','Casual day'],['work','Work'],['date','Date night'],['party','Party']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{occasion=v; [...r1.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); show();}}, l); r1.appendChild(b);\n  });\n  f1.appendChild(r1); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Weather\"));\n  const r2=el('div',{class:'choice-row'});\n  [['cool','Cool \/ cold'],['mild','Mild'],['warm','Warm \/ hot']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{weather=v; [...r2.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); show();}}, l); r2.appendChild(b);\n  });\n  f2.appendChild(r2); container.appendChild(f2);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  function show(){\n    if(!occasion||!weather) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Outfit idea\"));\n    resultBox.appendChild(el('p',{class:'big', style:'font-size:18px;'}, outfitData[occasion][weather]));\n  }\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 OUTFIT COLOR MATCHER\n============================================================ *\/\nconst colorWheel = {\n  Red:['Cream','Navy','Olive','Blush'], Pink:['Grey','White','Sage','Burgundy'],\n  Orange:['Navy','Denim Blue','Cream','Olive'], Yellow:['Grey','Lavender','Navy','White'],\n  Green:['Cream','Camel','Navy','Blush'], Blue:['White','Camel','Blush','Mustard'],\n  Purple:['Grey','Mustard','Cream','Sage'], Black:['Any color works','Red','White','Camel'],\n  White:['Any color works','Navy','Black','Olive'], Brown:['Cream','Sky Blue','Sage','Mustard']\n};\nfunction renderColorMatcher(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Pick your base clothing color\"));\n  const row=el('div',{class:'choice-row'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  Object.keys(colorWheel).forEach(c=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(x=>x.classList.remove('selected')); b.classList.add('selected');\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{}, `Pairs well with ${c}`));\n      const list=el('ul',{class:'tool-list'}); colorWheel[c].forEach(x=>list.appendChild(el('li',{},x)));\n      resultBox.appendChild(list);\n    }}, c); row.appendChild(b);\n  });\n  f.appendChild(row); container.appendChild(f); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 DRESS FOR BODY SHAPE FINDER\n============================================================ *\/\nconst bodyShapeDresses = {\n  Hourglass:'Wrap dresses and fitted styles that follow your natural waist.',\n  Pear:'A-line skirts and dresses that skim the hips, with detail up top.',\n  Apple:'Empire waistlines and flowy fabric that skim the midsection.',\n  Rectangle:'Belted dresses or peplum styles to create waist definition.',\n  'Inverted Triangle':'Full skirts and A-line dresses to balance broader shoulders.'\n};\nfunction renderBodyShapeFinder(container){\n  container.appendChild(el('p',{},\"Pick the description closest to you.\"));\n  const row=el('div',{class:'choice-row', style:'flex-direction:column; align-items:flex-start;'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  const opts = [\n    ['Hourglass','Shoulders and hips are similar width, waist is noticeably narrower'],\n    ['Pear','Hips are wider than shoulders'],\n    ['Apple','Waist is fuller, shoulders\/hips are narrower'],\n    ['Rectangle','Shoulders, waist and hips are similar width'],\n    ['Inverted Triangle','Shoulders are wider than hips'],\n  ];\n  opts.forEach(([shape,desc])=>{\n    const b=el('button',{type:'button', style:'width:100%; text-align:left; border-radius:6px;', onclick:()=>{\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"Your body shape\"));\n      resultBox.appendChild(el('div',{class:'big'}, shape));\n      resultBox.appendChild(el('p',{}, bodyShapeDresses[shape]));\n    }}, `${shape} \u2014 ${desc}`); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 WEDDING OUTFIT PLANNER\n============================================================ *\/\nconst weddingOutfitData = {\n  bride:{indoor:'Structured gown with a cathedral or chapel veil.', outdoor:'Lightweight fabric like chiffon, with flat or block-heel shoes.'},\n  guest:{indoor:'Midi or maxi dress in a jewel tone \u2014 avoid white and black-tie-only shades.', outdoor:'Flowy dress with wedges \u2014 avoid stilettos on grass.'},\n  bridesmaid:{indoor:'Match the wedding palette with a floor-length dress.', outdoor:'Breathable fabric in the wedding palette, comfortable flats or low heels.'}\n};\nfunction renderWeddingOutfit(container){\n  let role=null, venue=null;\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"Your role\"));\n  const r1=el('div',{class:'choice-row'});\n  [['bride','Bride'],['guest','Guest'],['bridesmaid','Bridesmaid']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{role=v; [...r1.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); show();}}, l); r1.appendChild(b);\n  });\n  f1.appendChild(r1); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Venue\"));\n  const r2=el('div',{class:'choice-row'});\n  [['indoor','Indoor \/ formal'],['outdoor','Outdoor \/ garden']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{venue=v; [...r2.children].forEach(c=>c.classList.remove('selected')); b.classList.add('selected'); show();}}, l); r2.appendChild(b);\n  });\n  f2.appendChild(r2); container.appendChild(f2);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  function show(){\n    if(!role||!venue) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Outfit suggestion\"));\n    resultBox.appendChild(el('p',{}, weddingOutfitData[role][venue]));\n  }\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 LIPSTICK COLOR MATCHER\n============================================================ *\/\nconst lipstickData = {\n  Fair:['Soft pink','Peachy nude','Rosy mauve'], Light:['Coral','Berry','Warm nude'],\n  Medium:['Brick red','Terracotta','Rosewood'], Tan:['True red','Deep berry','Warm brown-nude'],\n  Deep:['Deep plum','Bright fuchsia','Rich burgundy']\n};\nfunction renderLipstickMatcher(container){\n  const row=el('div',{class:'choice-row'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  container.appendChild(el('p',{},\"Pick your skin depth:\"));\n  Object.keys(lipstickData).forEach(d=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(x=>x.classList.remove('selected')); b.classList.add('selected');\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{}, `Shades for ${d} skin`));\n      const list=el('ul',{class:'tool-list'}); lipstickData[d].forEach(s=>list.appendChild(el('li',{},s)));\n      resultBox.appendChild(list);\n    }}, d); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 SKINCARE ROUTINE BUILDER\n============================================================ *\/\nconst skincareSteps = {\n  dry:{am:['Gentle cream cleanser','Hydrating toner','Serum with hyaluronic acid','Rich moisturizer','SPF 30+'], pm:['Oil cleanser then cream cleanser','Hydrating toner','Retinol (2-3x\/week)','Rich night cream']},\n  oily:{am:['Gel cleanser','Balancing toner','Niacinamide serum','Lightweight gel moisturizer','SPF 30+ (matte)'], pm:['Gel cleanser','Salicylic acid treatment (2-3x\/week)','Oil-free moisturizer']},\n  combo:{am:['Gentle foaming cleanser','Balancing toner','Vitamin C serum','Lightweight lotion','SPF 30+'], pm:['Double cleanse','Exfoliating acid (2x\/week)','Light moisturizer']},\n  sensitive:{am:['Fragrance-free cleanser','Soothing toner (optional)','Calming serum (centella\/panthenol)','Barrier-repair moisturizer','Mineral SPF 30+'], pm:['Fragrance-free cleanser','Barrier repair cream']}\n};\nfunction renderSkincareRoutine(container){\n  const row=el('div',{class:'choice-row'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  container.appendChild(el('p',{},\"Pick your skin type:\"));\n  [['dry','Dry'],['oily','Oily'],['combo','Combination'],['sensitive','Sensitive']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(x=>x.classList.remove('selected')); b.classList.add('selected');\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"Morning routine\"));\n      const amList=el('ul',{class:'tool-list'}); skincareSteps[v].am.forEach(s=>amList.appendChild(el('li',{},s))); resultBox.appendChild(amList);\n      resultBox.appendChild(el('h4',{style:'margin-top:14px;'},\"Evening routine\"));\n      const pmList=el('ul',{class:'tool-list'}); skincareSteps[v].pm.forEach(s=>pmList.appendChild(el('li',{},s))); resultBox.appendChild(pmList);\n      resultBox.appendChild(el('p',{class:'small-muted'},\"Introduce actives (retinol\/acids) gradually and always patch test.\"));\n    }}, l); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 HAIR COLOR FINDER\n============================================================ *\/\nfunction renderHairColorFinder(container){\n  container.appendChild(el('p',{},\"Uses the same warm\/cool logic as your color season.\"));\n  let undertone=null;\n  const row=el('div',{class:'choice-row'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  [['warm','Warm undertone (gold jewelry, green veins)'],['cool','Cool undertone (silver jewelry, blue veins)'],['neutral','Neutral \/ not sure']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(x=>x.classList.remove('selected')); b.classList.add('selected');\n      const options = v==='warm' ? ['Golden brown','Honey blonde','Copper red','Caramel balayage']\n        : v==='cool' ? ['Ash brown','Platinum blonde','Cool black','Cherry red']\n        : ['Chocolate brown','Beige blonde','Soft black','Chestnut'];\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"Flattering hair colors for you\"));\n      const list=el('ul',{class:'tool-list'}); options.forEach(o=>list.appendChild(el('li',{},o)));\n      resultBox.appendChild(list);\n    }}, l); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 OVULATION CALCULATOR\n============================================================ *\/\nfunction renderOvulationCalc(container){\n  container.appendChild(el('p',{},\"For general planning only \u2014 not medical advice.\"));\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"First day of last period\"));\n  const dateInput=el('input',{type:'date'}); f1.appendChild(dateInput); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Average cycle length (days)\"));\n  const lenInput=el('input',{type:'number', value:'28', min:'20', max:'40'}); f2.appendChild(lenInput); container.appendChild(f2);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    if(!dateInput.value) return;\n    const start=new Date(dateInput.value+'T00:00:00'); const len=parseInt(lenInput.value)||28;\n    const ovulation=new Date(start); ovulation.setDate(start.getDate()+len-14);\n    const fertileStart=new Date(ovulation); fertileStart.setDate(ovulation.getDate()-5);\n    const fertileEnd=new Date(ovulation); fertileEnd.setDate(ovulation.getDate()+1);\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Estimated ovulation\"));\n    resultBox.appendChild(el('div',{class:'big'}, fmtDate(ovulation)));\n    resultBox.appendChild(el('p',{}, `Fertile window: ${fmtDate(fertileStart)} \u2013 ${fmtDate(fertileEnd)}`));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 WATER INTAKE CALCULATOR\n============================================================ *\/\nfunction renderWaterIntake(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Your weight (lbs)\"));\n  const input=el('input',{type:'number', placeholder:'e.g. 140'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const w=parseFloat(input.value); if(!w) return;\n    const oz = w * 0.5; const liters = oz*0.0295735;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Suggested daily water intake\"));\n    resultBox.appendChild(el('div',{class:'big'}, `${Math.round(oz)} oz (${liters.toFixed(1)} L)`));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"General guideline (about half your body weight in ounces) \u2014 adjust for activity level and climate.\"));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 CALORIE CALCULATOR\n============================================================ *\/\nfunction renderCalorieCalc(container){\n  container.appendChild(el('p',{},\"Estimates maintenance calories using the Mifflin-St Jeor formula.\"));\n  const fields = [['age','Age','number','28'],['height','Height (inches)','number','65'],['weight','Weight (lbs)','number','140']];\n  const inputs = {};\n  fields.forEach(([key,label,type,ph])=>{\n    const f=el('div',{class:'field'}); f.appendChild(el('label',{},label));\n    const i=el('input',{type, placeholder:'e.g. '+ph}); inputs[key]=i; f.appendChild(i); container.appendChild(f);\n  });\n  const actField=el('div',{class:'field'}); actField.appendChild(el('label',{},\"Activity level\"));\n  const actSel=el('select',{});\n  [['1.2','Sedentary (little exercise)'],['1.375','Light exercise 1-3x\/week'],['1.55','Moderate exercise 3-5x\/week'],['1.725','Very active 6-7x\/week']].forEach(([v,l])=> actSel.appendChild(el('option',{value:v},l)));\n  actField.appendChild(actSel); container.appendChild(actField);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const age=parseFloat(inputs.age.value), hIn=parseFloat(inputs.height.value), wLb=parseFloat(inputs.weight.value);\n    if(!age||!hIn||!wLb) return;\n    const cm = hIn*2.54, kg = wLb*0.453592;\n    const bmr = (10*kg) + (6.25*cm) - (5*age) - 161;\n    const tdee = bmr * parseFloat(actSel.value);\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Estimated daily maintenance calories\"));\n    resultBox.appendChild(el('div',{class:'big'}, `${Math.round(tdee)} kcal\/day`));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"An estimate, not a prescription. Individual needs vary \u2014 a registered dietitian can help you personalize this.\"));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 WEIGHT LOSS PLANNER (general, healthy-range framing)\n============================================================ *\/\nfunction renderWeightLossPlanner(container){\n  container.appendChild(el('p',{},\"A general, educational estimate \u2014 not a diet prescription. Please consult a doctor or dietitian for personal guidance.\"));\n  const fields=[['age','Age','28'],['height','Height (inches)','65'],['weight','Current weight (lbs)','160']];\n  const inputs={};\n  fields.forEach(([key,label,ph])=>{\n    const f=el('div',{class:'field'}); f.appendChild(el('label',{},label));\n    const i=el('input',{type:'number', placeholder:'e.g. '+ph}); inputs[key]=i; f.appendChild(i); container.appendChild(f);\n  });\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const age=parseFloat(inputs.age.value), hIn=parseFloat(inputs.height.value), wLb=parseFloat(inputs.weight.value);\n    if(!age||!hIn||!wLb) return;\n    const cm=hIn*2.54, kg=wLb*0.453592;\n    const bmr=(10*kg)+(6.25*cm)-(5*age)-161;\n    const maintenance = bmr*1.375;\n    const safeTarget = Math.max(1200, Math.round(maintenance-500));\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"A general, moderate approach\"));\n    resultBox.appendChild(el('p',{}, `Estimated maintenance calories: ~${Math.round(maintenance)} kcal\/day.`));\n    resultBox.appendChild(el('p',{}, `A widely-used moderate deficit (about 500 kcal\/day) would put you around ${safeTarget} kcal\/day, which is generally associated with roughly 1 lb of loss per week.`));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"This is general education, not individual medical advice \u2014 sustainable, gradual change and professional guidance matter more than any calculator.\"));\n  }}, \"Get a general estimate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 SLEEP CALCULATOR (bedtime by wake time)\n============================================================ *\/\nfunction renderSleepCalc(container){\n  container.appendChild(el('p',{},\"Based on 90-minute sleep cycles plus ~15 minutes to fall asleep.\"));\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"What time do you need to wake up?\"));\n  const input=el('input',{type:'time', value:'07:00'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    if(!input.value) return;\n    const [h,m]=input.value.split(':').map(Number);\n    const wake=new Date(); wake.setHours(h,m,0,0);\n    const options=[6,5,4,3].map(cycles=>{\n      const bedtime=new Date(wake.getTime() - (cycles*90+15)*60000);\n      return `${bedtime.toLocaleTimeString('en-US',{hour:'numeric', minute:'2-digit'})} (${cycles} cycles, ${(cycles*1.5).toFixed(1)} hrs)`;\n    });\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Ideal bedtimes\"));\n    const list=el('ul',{class:'tool-list'}); options.forEach(o=>list.appendChild(el('li',{},o)));\n    resultBox.appendChild(list);\n  }}, \"Calculate bedtimes\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 SELF-CARE PLANNER\n============================================================ *\/\nconst selfCareIdeas = {\n  '10':['Stretch for 5 minutes','Make a cup of tea and drink it slowly',\"Write down 3 things you're grateful for\",'Step outside for fresh air'],\n  '30':['Take a relaxing shower or bath','Go for a short walk','Do a face mask while listening to a podcast','Tidy one small space'],\n  '60+':['Cook yourself a nice meal','Watch a comfort movie','Do a full skincare routine','Journal and reflect on your week','Call a friend you miss']\n};\nfunction renderSelfCarePlanner(container){\n  const row=el('div',{class:'choice-row'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  container.appendChild(el('p',{},\"How much time do you have?\"));\n  [['10','10 minutes'],['30','30 minutes'],['60+','An hour or more']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(x=>x.classList.remove('selected')); b.classList.add('selected');\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"Self-care ideas\"));\n      const list=el('ul',{class:'tool-list'}); selfCareIdeas[v].forEach(i=>list.appendChild(el('li',{},i)));\n      resultBox.appendChild(list);\n    }}, l); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 WEDDING CHECKLIST GENERATOR (timeline-based)\n============================================================ *\/\nconst weddingTimeline = [\n  ['12+ months before', ['Set budget & guest count','Book venue','Hire planner (optional)']],\n  ['9 months before', ['Choose photographer & caterer','Order dress','Book entertainment']],\n  ['6 months before', ['Send save-the-dates','Book hair & makeup','Plan honeymoon']],\n  ['3 months before', ['Send invitations','Finalize menu','Order favors']],\n  ['1 month before', ['Final dress fitting','Confirm all vendors','Write vows']],\n  ['1 week before', ['Confirm final headcount','Pack for honeymoon','Delegate day-of tasks']]\n];\nfunction renderWeddingChecklist(container){\n  container.appendChild(el('p',{},\"A general timeline \u2014 check off as you go.\"));\n  weddingTimeline.forEach(([period, tasks])=>{\n    const block=el('div',{style:'margin-bottom:16px;'});\n    block.appendChild(el('h4',{style:'font-size:14px; color:var(--rose-deep); margin-bottom:6px;'}, period));\n    const list=el('ul',{class:'tool-list'});\n    tasks.forEach(t=>{\n      const li=el('li',{});\n      const label=el('label',{style:'display:flex; gap:8px; align-items:flex-start; cursor:pointer;'});\n      label.appendChild(el('input',{type:'checkbox'})); label.appendChild(el('span',{},t));\n      li.appendChild(label); list.appendChild(li);\n    });\n    block.appendChild(list); container.appendChild(block);\n  });\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 ANNIVERSARY COUNTDOWN\n============================================================ *\/\nfunction renderAnniversaryCountdown(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Your anniversary date (any year)\"));\n  const input=el('input',{type:'date'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    if(!input.value) return;\n    const anniv=new Date(input.value+'T00:00:00');\n    const today=new Date(); today.setHours(0,0,0,0);\n    let next=new Date(today.getFullYear(), anniv.getMonth(), anniv.getDate());\n    if(next < today) next=new Date(today.getFullYear()+1, anniv.getMonth(), anniv.getDate());\n    const days=Math.ceil((next-today)\/(1000*60*60*24));\n    const years = next.getFullYear() - anniv.getFullYear();\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Countdown\"));\n    resultBox.appendChild(el('div',{class:'big'}, `${days} days to go`));\n    resultBox.appendChild(el('p',{}, years>0 ? `That'll be ${years} year${years>1?'s':''} together.` : ''));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 LOVE LANGUAGE QUIZ\n============================================================ *\/\nconst loveLanguageResults = {\n  words:{title:'Words of Affirmation', desc:'Verbal compliments and encouragement mean the most to you.'},\n  time:{title:'Quality Time', desc:'Undivided attention and shared moments matter most to you.'},\n  gifts:{title:'Receiving Gifts', desc:'Thoughtful gifts as symbols of love speak loudest to you.'},\n  acts:{title:'Acts of Service', desc:'Doing helpful things for you feels like love.'},\n  touch:{title:'Physical Touch', desc:'Hugs, hand-holding, and closeness mean the most to you.'}\n};\nfunction renderLoveLanguageQuiz(container){\n  const questions=[\n    {q:\"What makes you feel most loved?\", opts:[['Hearing \"I love you\" and genuine compliments','words'],['Someone giving me their full attention','time'],['A thoughtful, unexpected gift','gifts'],['Someone helping with something I need done','acts'],['A hug or holding hands','touch']]},\n    {q:\"What hurts you most in a relationship?\", opts:[['Harsh or careless words','words'],['Feeling ignored','time'],['Forgotten special occasions','gifts'],['Broken promises to help','acts'],['Lack of physical affection','touch']]},\n    {q:\"Your ideal date night is:\", opts:[['A heartfelt conversation','words'],['An uninterrupted evening together','time'],['Exchanging a small surprise gift','gifts'],['They planned\/cooked everything for you','acts'],['Cuddled up on the couch','touch']]},\n  ];\n  renderGenericQuiz(container, questions, (scores)=>{\n    const winner = topScore(scores); const r = loveLanguageResults[winner];\n    return {label:\"Your love language\", title:r.title, desc:r.desc};\n  });\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 RELATIONSHIP COMPATIBILITY QUIZ\n============================================================ *\/\nfunction renderRelationshipCompatQuiz(container){\n  const questions=[\n    {q:\"How do you handle disagreements?\", opts:[['Talk it out right away','direct'],['Need space first, then talk','space'],['Try to find a compromise quickly','compromise']]},\n    {q:\"How do you show you care?\", opts:[['Saying it outright','direct'],['Doing something thoughtful','compromise'],['Giving them room but checking in','space']]},\n    {q:\"Your ideal weekend with a partner:\", opts:[['Planned activities together','direct'],['A relaxed, unplanned day','space'],['A mix of togetherness and downtime','compromise']]},\n  ];\n  renderGenericQuiz(container, questions, (scores)=>{\n    const winner = topScore(scores);\n    const map = {\n      direct:{title:'Communicator', desc:'You value openness and directness \u2014 look for a partner who communicates just as clearly.'},\n      space:{title:'Independent', desc:'You value autonomy \u2014 a partner who respects space will suit you well.'},\n      compromise:{title:'Balancer', desc:'You naturally seek middle ground \u2014 you do well with a flexible, easygoing partner.'}\n    };\n    return {label:\"Your relationship style\", title:map[winner].title, desc:map[winner].desc};\n  });\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 BRIDAL TIMELINE PLANNER\n============================================================ *\/\nfunction renderBridalTimeline(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Wedding date\"));\n  const input=el('input',{type:'date'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    if(!input.value) return;\n    const wed=new Date(input.value+'T00:00:00');\n    const milestones = [\n      [12,'Book venue & set budget'], [9,'Order dress & book photographer'],\n      [6,'Send save-the-dates'], [4,'Book hair & makeup trial'],\n      [2,'Send invitations'], [1,'Final dress fitting'], [0.25,'Confirm final headcount']\n    ];\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your personalized timeline\"));\n    const table=el('table',{class:'simple'});\n    milestones.forEach(([monthsBefore, task])=>{\n      const d=new Date(wed); d.setDate(d.getDate() - Math.round(monthsBefore*30));\n      table.appendChild(el('tr',{}, el('th',{}, fmtDate(d)), el('td',{}, task)));\n    });\n    resultBox.appendChild(table);\n  }}, \"Build my timeline\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 CLEANING SCHEDULE GENERATOR\n============================================================ *\/\nconst cleaningTasks = {\n  daily:['Wipe kitchen counters','Do dishes','Make the bed','Wipe bathroom sink'],\n  weekly:['Vacuum all rooms','Mop floors','Clean bathrooms fully','Change bed sheets','Take out recycling'],\n  monthly:['Wipe baseboards','Clean inside fridge','Dust ceiling fans\/vents','Wash windows','Deep clean oven']\n};\nfunction renderCleaningSchedule(container){\n  container.appendChild(el('p',{},\"A simple, sustainable rhythm.\"));\n  Object.entries(cleaningTasks).forEach(([freq, tasks])=>{\n    const block=el('div',{style:'margin-bottom:16px;'});\n    block.appendChild(el('h4',{style:'font-size:14px; color:var(--rose-deep); margin-bottom:6px; text-transform:capitalize;'}, freq));\n    const list=el('ul',{class:'tool-list'}); tasks.forEach(t=>list.appendChild(el('li',{},t)));\n    block.appendChild(list); container.appendChild(block);\n  });\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 MEAL PLANNER (weekly skeleton)\n============================================================ *\/\nconst mealIdeas = {\n  balanced:['Grilled chicken & veggies','Salmon with rice','Turkey chili','Stir-fry with tofu or beef','Veggie pasta','Tacos','Sheet-pan dinner'],\n  vegetarian:['Chickpea curry','Veggie stir-fry','Caprese pasta','Black bean tacos','Veggie stuffed peppers','Lentil soup','Homemade pizza'],\n  lowcarb:['Grilled chicken & salad','Zucchini noodles with meatballs','Egg & veggie scramble','Steak & roasted vegetables','Lettuce-wrap tacos','Baked fish & greens','Cauliflower fried rice']\n};\nfunction renderMealPlanner(container){\n  const days=['Mon','Tue','Wed','Thu','Fri','Sat','Sun'];\n  const row=el('div',{class:'choice-row'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  container.appendChild(el('p',{},\"Choose a style for a 7-day dinner plan:\"));\n  [['balanced','Balanced'],['vegetarian','Vegetarian'],['lowcarb','Low-carb']].forEach(([v,l])=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(x=>x.classList.remove('selected')); b.classList.add('selected');\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"Your weekly dinner plan\"));\n      const table=el('table',{class:'simple'});\n      days.forEach((d,i)=> table.appendChild(el('tr',{}, el('th',{},d), el('td',{}, mealIdeas[v][i]))));\n      resultBox.appendChild(table);\n    }}, l); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 GROCERY BUDGET CALCULATOR\n============================================================ *\/\nfunction renderGroceryBudget(container){\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"Household size\"));\n  const sizeInput=el('input',{type:'number', value:'2', min:'1'}); f1.appendChild(sizeInput); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Spending level\"));\n  const levelSel=el('select',{});\n  [['low','Thrifty'],['moderate','Moderate'],['generous','Generous']].forEach(([v,l])=>levelSel.appendChild(el('option',{value:v},l)));\n  f2.appendChild(levelSel); container.appendChild(f2);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const perPersonWeekly = {low:55, moderate:80, generous:115};\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const size=parseInt(sizeInput.value)||1;\n    const weekly = size * perPersonWeekly[levelSel.value];\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Estimated grocery budget\"));\n    resultBox.appendChild(el('div',{class:'big'}, `$${weekly}\/week`));\n    resultBox.appendChild(el('p',{}, `About $${Math.round(weekly*4.33)}\/month for a household of ${size}.`));\n    resultBox.appendChild(el('p',{class:'small-muted'},\"Rough US averages \u2014 actual costs vary by region and diet.\"));\n  }}, \"Estimate budget\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 PANTRY INVENTORY MANAGER (in-memory for this session)\n============================================================ *\/\nfunction renderPantryManager(container){\n  container.appendChild(el('p',{},\"Add items as you stock up \u2014 this list stays for your current session.\"));\n  const items = [];\n  const f=el('div',{class:'field', style:'display:flex; gap:8px;'});\n  const input=el('input',{type:'text', placeholder:'e.g. Rice, 2 bags', style:'flex:1;'});\n  f.appendChild(input);\n  container.appendChild(f);\n  const listBox=el('ul',{class:'tool-list'});\n  container.appendChild(listBox);\n  function renderList(){\n    listBox.innerHTML='';\n    items.forEach((item, idx)=>{\n      const li=el('li',{style:'display:flex; justify-content:space-between; align-items:center;'});\n      li.appendChild(el('span',{}, item));\n      li.appendChild(el('button',{class:'btn secondary', style:'padding:2px 10px; margin:0; font-size:11px;', onclick:()=>{ items.splice(idx,1); renderList(); }}, \"Remove\"));\n      listBox.appendChild(li);\n    });\n  }\n  const addBtn=el('button',{class:'btn', onclick:()=>{\n    if(!input.value.trim()) return;\n    items.push(input.value.trim()); input.value=''; renderList();\n  }}, \"Add item\");\n  container.appendChild(addBtn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 CHORE PLANNER\n============================================================ *\/\nfunction renderChorePlanner(container){\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"Names (comma separated)\"));\n  const namesInput=el('input',{type:'text', placeholder:'e.g. Sarah, Alex, Jordan'}); f1.appendChild(namesInput); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Chores (comma separated)\"));\n  const choresInput=el('input',{type:'text', placeholder:'e.g. Dishes, Trash, Vacuum, Laundry'}); f2.appendChild(choresInput); container.appendChild(f2);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const names=namesInput.value.split(',').map(s=>s.trim()).filter(Boolean);\n    const chores=choresInput.value.split(',').map(s=>s.trim()).filter(Boolean);\n    if(!names.length||!chores.length) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"This week's assignments\"));\n    const table=el('table',{class:'simple'});\n    chores.forEach((chore,i)=> table.appendChild(el('tr',{}, el('th',{},chore), el('td',{}, names[i % names.length]))));\n    resultBox.appendChild(table);\n    resultBox.appendChild(el('p',{class:'small-muted'},\"Rotate names manually next week for fairness, or re-run this tool.\"));\n  }}, \"Assign chores\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 HOME DECOR STYLE PLANNER\n============================================================ *\/\nconst decorStyles = {\n  scandi:{name:'Scandinavian', items:['Light wood furniture','Neutral linen textiles','Simple pendant lighting','Cozy throw blankets']},\n  boho:{name:'Bohemian', items:['Rattan furniture','Layered rugs','Macrame wall hangings','Lots of plants']},\n  modern:{name:'Modern Minimalist', items:['Clean-lined furniture','Monochrome palette','Statement lighting','Minimal decor']},\n  farmhouse:{name:'Modern Farmhouse', items:['Shiplap or wood accents','Neutral palette with black accents','Woven baskets','Vintage-inspired fixtures']}\n};\nfunction renderDecorPlanner(container){\n  const row=el('div',{class:'choice-row'});\n  const resultBox=el('div',{class:'result-box hidden'});\n  container.appendChild(el('p',{},\"Pick a style you're drawn to:\"));\n  Object.entries(decorStyles).forEach(([key, data])=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      [...row.children].forEach(x=>x.classList.remove('selected')); b.classList.add('selected');\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{}, `${data.name} shopping list`));\n      const list=el('ul',{class:'tool-list'}); data.items.forEach(i=>list.appendChild(el('li',{},i)));\n      resultBox.appendChild(list);\n    }}, data.name); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(resultBox);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 RESUME BUILDER (generates copyable plain-text resume)\n============================================================ *\/\nfunction renderResumeBuilder(container){\n  const fields = [\n    ['name','Full name','text'],['contact','Phone \/ email','text'],\n    ['summary','Professional summary (1-2 sentences)','textarea'],\n    ['experience','Experience (one role per line: Title, Company, Years \u2014 details)','textarea'],\n    ['education','Education (Degree, School, Year)','textarea'],\n    ['skills','Skills (comma separated)','text']\n  ];\n  const inputs={};\n  fields.forEach(([key,label,type])=>{\n    const f=el('div',{class:'field'}); f.appendChild(el('label',{},label));\n    const i = type==='textarea' ? el('textarea',{}) : el('input',{type:'text'});\n    inputs[key]=i; f.appendChild(i); container.appendChild(f);\n  });\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const v = k => inputs[k].value.trim();\n    const text = `${v('name')}\\n${v('contact')}\\n\\nSUMMARY\\n${v('summary')}\\n\\nEXPERIENCE\\n${v('experience')}\\n\\nEDUCATION\\n${v('education')}\\n\\nSKILLS\\n${v('skills')}`;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your resume text\"));\n    const pre=el('textarea',{style:'width:100%; min-height:220px; font-family:monospace; font-size:12.5px;'});\n    pre.value = text; pre.readOnly=true;\n    resultBox.appendChild(pre);\n    resultBox.appendChild(copyBtn(()=>pre.value));\n  }}, \"Generate resume\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 COVER LETTER GENERATOR\n============================================================ *\/\nfunction renderCoverLetterGen(container){\n  const fields=[['name','Your name'],['job','Job title'],['company','Company name'],['skill','A key strength to highlight'],['why','Why you want this role (short phrase)']];\n  const inputs={};\n  fields.forEach(([key,label])=>{\n    const f=el('div',{class:'field'}); f.appendChild(el('label',{},label));\n    const i=el('input',{type:'text'}); inputs[key]=i; f.appendChild(i); container.appendChild(f);\n  });\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const v=k=>inputs[k].value.trim();\n    if(!v('name')||!v('job')||!v('company')) return;\n    const text = `Dear Hiring Manager,\\n\\nI'm excited to apply for the ${v('job')} position at ${v('company')}. ${v('why') ? v('why')+'. ' : ''}My background has given me strong experience in ${v('skill')||'this field'}, and I'm confident I could bring real value to your team.\\n\\nI'd welcome the chance to discuss how my skills align with what ${v('company')} is looking for. Thank you for your time and consideration.\\n\\nSincerely,\\n${v('name')}`;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your cover letter draft\"));\n    const pre=el('textarea',{style:'width:100%; min-height:220px; font-family:monospace; font-size:12.5px;'});\n    pre.value=text; pre.readOnly=true; resultBox.appendChild(pre);\n    resultBox.appendChild(copyBtn(()=>pre.value));\n  }}, \"Generate letter\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 SALARY CALCULATOR\n============================================================ *\/\nfunction renderSalaryCalc(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Hourly rate (USD)\"));\n  const hourly=el('input',{type:'number', placeholder:'e.g. 25'}); f.appendChild(hourly); container.appendChild(f);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Hours per week\"));\n  const hours=el('input',{type:'number', value:'40'}); f2.appendChild(hours); container.appendChild(f2);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const h=parseFloat(hourly.value), hrs=parseFloat(hours.value)||40;\n    if(!h) return;\n    const weekly=h*hrs, annual=weekly*52, monthly=annual\/12;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Estimated earnings\"));\n    const table=el('table',{class:'simple'});\n    table.appendChild(el('tr',{}, el('th',{},'Weekly'), el('td',{}, `$${weekly.toLocaleString(undefined,{maximumFractionDigits:0})}`)));\n    table.appendChild(el('tr',{}, el('th',{},'Monthly'), el('td',{}, `$${monthly.toLocaleString(undefined,{maximumFractionDigits:0})}`)));\n    table.appendChild(el('tr',{}, el('th',{},'Annual'), el('td',{}, `$${annual.toLocaleString(undefined,{maximumFractionDigits:0})}`)));\n    resultBox.appendChild(table);\n    resultBox.appendChild(el('p',{class:'small-muted'},\"Before taxes and deductions.\"));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 FREELANCE RATE CALCULATOR\n============================================================ *\/\nfunction renderFreelanceRate(container){\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"Target annual income (USD)\"));\n  const income=el('input',{type:'number', placeholder:'e.g. 70000'}); f1.appendChild(income); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Billable hours per week\"));\n  const hours=el('input',{type:'number', value:'25'}); f2.appendChild(hours); container.appendChild(f2);\n  const f3=el('div',{class:'field'}); f3.appendChild(el('label',{},\"Weeks off per year\"));\n  const weeksOff=el('input',{type:'number', value:'4'}); f3.appendChild(weeksOff); container.appendChild(f3);\n  const f4=el('div',{class:'field'}); f4.appendChild(el('label',{},\"Annual business expenses (USD)\"));\n  const expenses=el('input',{type:'number', value:'3000'}); f4.appendChild(expenses); container.appendChild(f4);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const inc=parseFloat(income.value), hrs=parseFloat(hours.value), off=parseFloat(weeksOff.value)||0, exp=parseFloat(expenses.value)||0;\n    if(!inc||!hrs) return;\n    const workingWeeks = 52-off;\n    const totalHours = workingWeeks*hrs;\n    const rate = (inc+exp)\/totalHours;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your target hourly rate\"));\n    resultBox.appendChild(el('div',{class:'big'}, `$${rate.toFixed(0)}\/hr`));\n    resultBox.appendChild(el('p',{class:'small-muted'},`Based on ${totalHours.toFixed(0)} billable hours\/year, covering income + expenses.`));\n  }}, \"Calculate my rate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 BUDGET PLANNER (50\/30\/20)\n============================================================ *\/\nfunction renderBudgetPlanner(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Monthly take-home income (USD)\"));\n  const input=el('input',{type:'number', placeholder:'e.g. 4000'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const inc=parseFloat(input.value); if(!inc) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"50\/30\/20 breakdown\"));\n    const table=el('table',{class:'simple'});\n    table.appendChild(el('tr',{}, el('th',{},'Needs (50%)'), el('td',{}, `$${(inc*0.5).toFixed(0)}`)));\n    table.appendChild(el('tr',{}, el('th',{},'Wants (30%)'), el('td',{}, `$${(inc*0.3).toFixed(0)}`)));\n    table.appendChild(el('tr',{}, el('th',{},'Savings\/debt (20%)'), el('td',{}, `$${(inc*0.2).toFixed(0)}`)));\n    resultBox.appendChild(table);\n    resultBox.appendChild(el('p',{class:'small-muted'},\"A popular general guideline \u2014 adjust to your own priorities and debt situation.\"));\n  }}, \"Break down my budget\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 SAVINGS GOAL TRACKER\n============================================================ *\/\nfunction renderSavingsGoal(container){\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"Savings goal (USD)\"));\n  const goal=el('input',{type:'number', placeholder:'e.g. 5000'}); f1.appendChild(goal); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"Current savings (USD)\"));\n  const current=el('input',{type:'number', value:'0'}); f2.appendChild(current); container.appendChild(f2);\n  const f3=el('div',{class:'field'}); f3.appendChild(el('label',{},\"Monthly contribution (USD)\"));\n  const monthly=el('input',{type:'number', placeholder:'e.g. 300'}); f3.appendChild(monthly); container.appendChild(f3);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const g=parseFloat(goal.value), c=parseFloat(current.value)||0, m=parseFloat(monthly.value);\n    if(!g||!m) return;\n    const remaining=g-c;\n    if(remaining<=0){\n      resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n      resultBox.appendChild(el('h4',{},\"You've already reached your goal! \ud83c\udf89\"));\n      return;\n    }\n    const months=Math.ceil(remaining\/m);\n    const doneDate=new Date(); doneDate.setMonth(doneDate.getMonth()+months);\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Time to reach your goal\"));\n    resultBox.appendChild(el('div',{class:'big'}, `${months} month${months>1?'s':''}`));\n    resultBox.appendChild(el('p',{}, `Estimated: around ${doneDate.toLocaleDateString('en-US',{month:'long', year:'numeric'})}.`));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 NAME AESTHETIC GENERATOR\n============================================================ *\/\nconst aestheticFonts = [\n  s=>s.split('').join('\u02da '), s=>'\u2727 '+s.split('').join('.')+' \u2727',\n  s=>s.toUpperCase().split('').join(' '), s=>'\ua4b0 '+s+' \ua4b1',\n  s=>s.split('').map(c=>c+'\\u0301').join(''), s=>'\u300e'+s+'\u300f'\n];\nfunction renderNameAesthetic(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Your name\"));\n  const input=el('input',{type:'text', placeholder:'e.g. Sofia'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const name=input.value.trim(); if(!name) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Aesthetic name styles\"));\n    const list=el('ul',{class:'tool-list'});\n    aestheticFonts.forEach(fn=>{ try{ list.appendChild(el('li',{style:'font-size:16px;'}, fn(name))); }catch(e){} });\n    resultBox.appendChild(list);\n  }}, \"Generate styles\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 INSTAGRAM BIO GENERATOR\n============================================================ *\/\nconst bioTemplates = [\n  n=>`\u2728 ${n} things I love \u2728 | living my best life | dm for collabs`,\n  n=>`${n} vibes only \ud83c\udf19 | small joys, big dreams`,\n  n=>`here for the ${n} | coffee-fueled | always planning the next trip \u2708\ufe0f`,\n  n=>`${n} enthusiast | probably thinking about snacks rn`,\n  n=>`chasing sunsets & good ${n} \ud83c\udf05`\n];\nfunction renderInstaBioGen(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"A word\/phrase about you (interest, vibe, job)\"));\n  const input=el('input',{type:'text', placeholder:'e.g. plants, coffee, travel'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const w=input.value.trim(); if(!w) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Bio ideas\"));\n    const list=el('ul',{class:'tool-list'});\n    bioTemplates.forEach(fn=> list.appendChild(el('li',{}, fn(w))));\n    resultBox.appendChild(list);\n  }}, \"Generate bios\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 PINTEREST CAPTION GENERATOR\n============================================================ *\/\nconst pinCaptionTemplates = [\n  t=>`${t} inspiration you'll want to save \ud83d\udccc`,\n  t=>`The ultimate ${t} guide \u2014 pin for later!`,\n  t=>`${t} ideas that actually work`,\n  t=>`Everything you need to know about ${t}`,\n  t=>`${t}: your new go-to inspo board`\n];\nfunction renderPinCaptionGen(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Topic\"));\n  const input=el('input',{type:'text', placeholder:'e.g. cottagecore bedroom'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const t=input.value.trim(); if(!t) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Caption ideas\"));\n    const list=el('ul',{class:'tool-list'});\n    pinCaptionTemplates.forEach(fn=>list.appendChild(el('li',{}, fn(t))));\n    resultBox.appendChild(list);\n  }}, \"Generate captions\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 TIKTOK CAPTION GENERATOR\n============================================================ *\/\nconst tiktokTemplates = [\n  v=>`POV: you finally figured out ${v} \ud83d\ude2d #fyp`,\n  v=>`tell me you're into ${v} without telling me`,\n  v=>`this ${v} hack changed everything`,\n  v=>`rating my ${v} era out of 10`,\n  v=>`things about ${v} nobody tells you`\n];\nfunction renderTiktokCaptionGen(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Video topic\/vibe\"));\n  const input=el('input',{type:'text', placeholder:'e.g. morning routine'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const v=input.value.trim(); if(!v) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Caption ideas\"));\n    const list=el('ul',{class:'tool-list'});\n    tiktokTemplates.forEach(fn=>list.appendChild(el('li',{}, fn(v))));\n    resultBox.appendChild(list);\n    resultBox.appendChild(el('p',{class:'small-muted'},\"#fyp #foryou #\"+v.replace(\/\\s+\/g,'')));\n  }}, \"Generate captions\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 VISION BOARD GENERATOR (affirmation cards by life area)\n============================================================ *\/\nconst visionAreas = {\n  Career:['I am building a career I\\'m proud of','New opportunities find me easily','I grow a little more capable every day'],\n  Health:['I honor my body with rest and movement','I am becoming stronger and more energized','I choose habits that support my future self'],\n  Love:['I attract relationships built on mutual respect','I give and receive love easily','I am worthy of a calm, secure love'],\n  Home:['My space reflects peace and intention','I create a home that feels like a retreat','Abundance flows into my life'],\n  'Money':['I make confident, informed financial choices','My income grows as I grow','I am building lasting financial security']\n};\nfunction renderVisionBoard(container){\n  container.appendChild(el('p',{},\"Pick the areas you want to focus on.\"));\n  let selected = new Set();\n  const row=el('div',{class:'choice-row'});\n  Object.keys(visionAreas).forEach(area=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      if(selected.has(area)){ selected.delete(area); b.classList.remove('selected'); }\n      else{ selected.add(area); b.classList.add('selected'); }\n    }}, area); row.appendChild(b);\n  });\n  container.appendChild(row);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', style:'margin-top:12px;', onclick:()=>{\n    if(!selected.size) return;\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Your vision board\"));\n    [...selected].forEach(area=>{\n      const card=el('div',{style:'margin-top:12px; padding:12px; border:1px solid var(--border); border-radius:6px;'});\n      card.appendChild(el('div',{style:'font-weight:600; color:var(--rose-deep); font-size:12px; text-transform:uppercase; letter-spacing:0.05em; margin-bottom:4px;'}, area));\n      card.appendChild(el('div',{style:'font-family:Fraunces,serif; font-size:16px;'}, pick(visionAreas[area])));\n      resultBox.appendChild(card);\n    });\n  }}, \"Build my board\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 WALLPAPER CREATOR (downloadable phone wallpaper)\n============================================================ *\/\nconst wallpaperPalettes = {\n  Blush:['#F7D9E3','#E8A0B4','#C1487B'], Sage:['#E4EBDD','#B7C7A3','#7C8B6F'],\n  Lavender:['#E9E1F7','#C6A1C7','#8D6FA0'], Sunset:['#FFE3C2','#FFB07C','#C1487B']\n};\nfunction renderWallpaperCreator(container){\n  const f1=el('div',{class:'field'}); f1.appendChild(el('label',{},\"Color palette\"));\n  const paletteSel=el('select',{}); Object.keys(wallpaperPalettes).forEach(p=>paletteSel.appendChild(el('option',{value:p},p)));\n  f1.appendChild(paletteSel); container.appendChild(f1);\n  const f2=el('div',{class:'field'}); f2.appendChild(el('label',{},\"A short quote or word\"));\n  const quoteInput=el('input',{type:'text', placeholder:'e.g. stay soft', value:'stay soft'}); f2.appendChild(quoteInput); container.appendChild(f2);\n  const canvas=el('canvas',{width:'320', height:'568', style:'width:160px; height:284px; border-radius:12px; border:1px solid var(--border); display:block; margin:14px 0;'});\n  container.appendChild(canvas);\n  function draw(){\n    const ctx=canvas.getContext('2d');\n    const colors=wallpaperPalettes[paletteSel.value];\n    const grad=ctx.createLinearGradient(0,0,0,568);\n    grad.addColorStop(0,colors[0]); grad.addColorStop(0.5,colors[1]); grad.addColorStop(1,colors[2]);\n    ctx.fillStyle=grad; ctx.fillRect(0,0,320,568);\n    ctx.fillStyle='rgba(255,255,255,0.9)'; ctx.font='italic 28px Georgia'; ctx.textAlign='center';\n    const text=quoteInput.value.trim()||'stay soft';\n    ctx.fillText(text, 160, 300);\n  }\n  draw();\n  paletteSel.addEventListener('change', draw); quoteInput.addEventListener('input', draw);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    const link=document.createElement('a');\n    link.download='wallpaper.png'; link.href=canvas.toDataURL('image\/png'); link.click();\n  }}, \"Download wallpaper\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 HABIT TRACKER (in-memory weekly grid)\n============================================================ *\/\nfunction renderHabitTracker(container){\n  container.appendChild(el('p',{},\"Add habits and check off each day \u2014 resets when you close this window.\"));\n  const habits = [];\n  const days=['M','T','W','T','F','S','S'];\n  const f=el('div',{class:'field', style:'display:flex; gap:8px;'});\n  const input=el('input',{type:'text', placeholder:'e.g. Drink water', style:'flex:1;'});\n  f.appendChild(input); container.appendChild(f);\n  const tableWrap=el('div');\n  container.appendChild(tableWrap);\n  function renderTable(){\n    tableWrap.innerHTML='';\n    if(!habits.length) return;\n    const table=el('table',{class:'simple'});\n    const headRow=el('tr',{}); headRow.appendChild(el('th',{},'Habit'));\n    days.forEach(d=>headRow.appendChild(el('th',{style:'text-align:center;'},d)));\n    table.appendChild(headRow);\n    habits.forEach(h=>{\n      const tr=el('tr',{}); tr.appendChild(el('td',{},h.name));\n      h.checks.forEach((val,i)=>{\n        const td=el('td',{style:'text-align:center;'});\n        const cb=el('input',{type:'checkbox'});\n        cb.checked=val; cb.addEventListener('change',()=>{ h.checks[i]=cb.checked; });\n        td.appendChild(cb); tr.appendChild(td);\n      });\n      table.appendChild(tr);\n    });\n    tableWrap.appendChild(table);\n  }\n  const addBtn=el('button',{class:'btn', onclick:()=>{\n    if(!input.value.trim()) return;\n    habits.push({name:input.value.trim(), checks:[false,false,false,false,false,false,false]});\n    input.value=''; renderTable();\n  }}, \"Add habit\");\n  container.appendChild(addBtn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 DAILY AFFIRMATION GENERATOR\n============================================================ *\/\nconst affirmations = [\n  \"I am exactly where I need to be right now.\",\n  \"My potential is limitless and my effort matters.\",\n  \"I choose peace over worry today.\",\n  \"I am worthy of good things.\",\n  \"I trust myself to figure things out.\",\n  \"Today, I show myself the same kindness I show others.\",\n  \"I release what I can't control.\",\n  \"I am proud of how far I've come.\",\n  \"Small steps still move me forward.\",\n  \"I am allowed to rest without guilt.\"\n];\nfunction renderAffirmationGen(container){\n  const box=el('div',{class:'result-box'});\n  box.appendChild(el('h4',{},\"Today's affirmation\"));\n  const text=el('p',{class:'big', style:'font-size:19px;'}, pick(affirmations));\n  box.appendChild(text); container.appendChild(box);\n  const btn=el('button',{class:'btn', style:'margin-top:16px;', onclick:()=>{ text.textContent = pick(affirmations); }}, \"Give me another\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 MOOD TRACKER (in-memory session log)\n============================================================ *\/\nfunction renderMoodTracker(container){\n  container.appendChild(el('p',{},\"Log how you're feeling \u2014 this stays for your current session.\"));\n  const log = [];\n  const row=el('div',{class:'choice-row'});\n  const logBox=el('div',{style:'margin-top:16px;'});\n  const moods = ['\ud83d\ude0a Great','\ud83d\ude42 Good','\ud83d\ude10 Okay','\ud83d\ude14 Low','\ud83d\ude23 Struggling'];\n  moods.forEach(m=>{\n    const b=el('button',{type:'button', onclick:()=>{\n      log.unshift({mood:m, time:new Date().toLocaleTimeString('en-US',{hour:'numeric', minute:'2-digit'})});\n      renderLog();\n    }}, m); row.appendChild(b);\n  });\n  container.appendChild(row); container.appendChild(logBox);\n  function renderLog(){\n    logBox.innerHTML='';\n    if(!log.length) return;\n    logBox.appendChild(el('h4',{style:'font-size:14px; margin-bottom:8px;'},\"Today's log\"));\n    const list=el('ul',{class:'tool-list'});\n    log.forEach(entry=> list.appendChild(el('li',{}, `${entry.time} \u2014 ${entry.mood}`)));\n    logBox.appendChild(list);\n  }\n}\n\n\/* ============================================================\n   NEW TOOL \u2014 BIRTHDAY COUNTDOWN\n============================================================ *\/\nfunction renderBirthdayCountdown(container){\n  const f=el('div',{class:'field'}); f.appendChild(el('label',{},\"Your birth date\"));\n  const input=el('input',{type:'date'}); f.appendChild(input); container.appendChild(f);\n  const resultBox=el('div',{class:'result-box hidden'}); container.appendChild(resultBox);\n  const btn=el('button',{class:'btn', onclick:()=>{\n    if(!input.value) return;\n    const bday=new Date(input.value+'T00:00:00');\n    const today=new Date(); today.setHours(0,0,0,0);\n    let next=new Date(today.getFullYear(), bday.getMonth(), bday.getDate());\n    if(next<today) next=new Date(today.getFullYear()+1, bday.getMonth(), bday.getDate());\n    const days=Math.ceil((next-today)\/(1000*60*60*24));\n    const turning = next.getFullYear() - bday.getFullYear();\n    resultBox.classList.remove('hidden'); resultBox.innerHTML='';\n    resultBox.appendChild(el('h4',{},\"Countdown\"));\n    resultBox.appendChild(el('div',{class:'big'}, days===0 ? \"It's today! \ud83c\udf89\" : `${days} days to go`));\n    resultBox.appendChild(el('p',{}, `Turning ${turning}.`));\n  }}, \"Calculate\");\n  container.appendChild(btn);\n}\n\n\/* ============================================================\n   TOOL REGISTRY\n============================================================ *\/\nconst TOOLS = [\n  {id:'color-season', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Quiz', title:'Color Season Analyzer', teaser:\"Find out if you're a Spring, Summer, Autumn or Winter.\", render:renderColorSeason},\n  {id:'capsule', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Planner', title:'Capsule Wardrobe Generator', teaser:'A 10-piece starter capsule built around your style.', render:renderCapsule},\n  {id:'shade', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Matcher', title:'Makeup Shade Finder', teaser:'Find your foundation shade family in under a minute.', render:renderShadeMatcher},\n  {id:'hairstyle', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Quiz', title:'Hairstyle Finder', teaser:'Best cuts and styles for your face shape.', render:renderHairstyleFinder},\n  {id:'nailart', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Generator', title:'Nail Art Idea Generator', teaser:'Random color + style + occasion combos.', render:renderNailArt},\n  {id:'outfit-planner', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Planner', title:'Outfit Planner', teaser:'Occasion + weather = an instant outfit idea.', render:renderOutfitPlanner},\n  {id:'color-matcher', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Matcher', title:'Outfit Color Matcher', teaser:'What colors actually pair with what you already own.', render:renderColorMatcher},\n  {id:'body-shape', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Quiz', title:'Dress for Body Shape Finder', teaser:'The silhouettes that flatter your shape.', render:renderBodyShapeFinder},\n  {id:'wedding-outfit', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Planner', title:'Wedding Outfit Planner', teaser:'What to wear as bride, guest or bridesmaid.', render:renderWeddingOutfit},\n  {id:'lipstick', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Matcher', title:'Lipstick Color Matcher', teaser:'Your most flattering lip shades.', render:renderLipstickMatcher},\n  {id:'skincare', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Builder', title:'Skincare Routine Builder', teaser:'AM\/PM routine steps for your skin type.', render:renderSkincareRoutine},\n  {id:'haircolor', category:'beauty', tag:'Beauty &#038; Fashion \u00b7 Finder', title:'Hair Color Finder', teaser:'The shades that flatter your undertone.', render:renderHairColorFinder},\n\n  {id:'cycle', category:'health', tag:'Health &#038; Lifestyle \u00b7 Tracker', title:'Period Tracker', teaser:'Estimate your next period and fertile window.', render:renderCycleTracker},\n  {id:'ovulation', category:'health', tag:'Health &#038; Lifestyle \u00b7 Calculator', title:'Ovulation Calculator', teaser:'A quick estimate of your fertile window.', render:renderOvulationCalc},\n  {id:'duedate', category:'health', tag:'Health &#038; Lifestyle \u00b7 Calculator', title:'Pregnancy Due Date Calculator', teaser:'Estimate your due date and trimester dates.', render:renderDueDate},\n  {id:'water', category:'health', tag:'Health &#038; Lifestyle \u00b7 Calculator', title:'Water Intake Calculator', teaser:'How much water to aim for daily.', render:renderWaterIntake},\n  {id:'calorie', category:'health', tag:'Health &#038; Lifestyle \u00b7 Calculator', title:'Calorie Calculator', teaser:'Estimate your daily maintenance calories.', render:renderCalorieCalc},\n  {id:'weightloss', category:'health', tag:'Health &#038; Lifestyle \u00b7 Planner', title:'Weight Loss Planner', teaser:'A general, moderate-approach estimate.', render:renderWeightLossPlanner},\n  {id:'bmi', category:'health', tag:'Health &#038; Lifestyle \u00b7 Calculator', title:'BMI Calculator', teaser:'A general screening number \u2014 one data point among many.', render:renderBMI},\n  {id:'sleep', category:'health', tag:'Health &#038; Lifestyle \u00b7 Calculator', title:'Sleep Calculator', teaser:'The best bedtimes based on your wake-up time.', render:renderSleepCalc},\n  {id:'selfcare', category:'health', tag:'Health &#038; Lifestyle \u00b7 Planner', title:'Self-Care Planner', teaser:'Ideas that fit the time you actually have.', render:renderSelfCarePlanner},\n  {id:'journal', category:'health', tag:'Health &#038; Lifestyle \u00b7 Generator', title:'Journaling Prompt Generator', teaser:'A fresh prompt whenever you need one.', render:renderJournalPrompt},\n  {id:'mood', category:'health', tag:'Health &#038; Lifestyle \u00b7 Tracker', title:'Mood Tracker', teaser:'Log how you\\'re feeling throughout the day.', render:renderMoodTracker},\n  {id:'habit', category:'health', tag:'Health &#038; Lifestyle \u00b7 Tracker', title:'Habit Tracker', teaser:'A simple weekly grid for the habits you\\'re building.', render:renderHabitTracker},\n\n  {id:'weddingplan', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Planner', title:'Wedding Budget Calculator', teaser:'Countdown to the big day and a budget breakdown.', render:renderWeddingPlanner},\n  {id:'weddingchecklist', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Checklist', title:'Wedding Checklist Generator', teaser:'A month-by-month wedding planning timeline.', render:renderWeddingChecklist},\n  {id:'babynames', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Generator', title:'Baby Name Generator', teaser:'Classic, modern, nature or vintage names.', render:renderBabyNames},\n  {id:'anniversary', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Countdown', title:'Anniversary Reminder', teaser:'Count down to your next anniversary.', render:renderAnniversaryCountdown},\n  {id:'lovelanguage', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Quiz', title:'Love Language Quiz', teaser:'Find your primary love language.', render:renderLoveLanguageQuiz},\n  {id:'relcompat', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Quiz', title:'Relationship Compatibility Quiz', teaser:'Your relationship style, at a glance.', render:renderRelationshipCompatQuiz},\n  {id:'bridaltimeline', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Planner', title:'Bridal Timeline Planner', teaser:'A personalized wedding-planning timeline.', render:renderBridalTimeline},\n  {id:'hashtag', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Generator', title:'Wedding Hashtag Generator', teaser:'Fun hashtag ideas from both your names.', render:renderHashtagGen},\n  {id:'shower', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Checklist', title:'Bridal\/Baby Shower Checklist', teaser:'A ready-made shower checklist.', render:renderShowerChecklist},\n  {id:'gift', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Generator', title:'Gift Idea Generator', teaser:'Tell us who and what kind \u2014 get real ideas.', render:renderGiftGen},\n  {id:'namecompat', category:'lifestyle', tag:'Wedding &#038; Love \u00b7 Calculator', title:'Name Compatibility Calculator', teaser:'A playful compatibility percentage for two names.', render:renderNameCompat},\n\n  {id:'cleaning', category:'home', tag:'Home \u00b7 Schedule', title:'Cleaning Schedule Generator', teaser:'Daily, weekly and monthly cleaning tasks.', render:renderCleaningSchedule},\n  {id:'mealplan', category:'home', tag:'Home \u00b7 Planner', title:'Meal Planner', teaser:'A 7-day dinner plan in your preferred style.', render:renderMealPlanner},\n  {id:'grocery', category:'home', tag:'Home \u00b7 Calculator', title:'Grocery Budget Calculator', teaser:'A realistic weekly grocery estimate.', render:renderGroceryBudget},\n  {id:'pantry', category:'home', tag:'Home \u00b7 Manager', title:'Pantry Inventory Manager', teaser:'Track what\\'s in stock this session.', render:renderPantryManager},\n  {id:'chores', category:'home', tag:'Home \u00b7 Planner', title:'Chore Planner', teaser:'Fair chore assignments for your household.', render:renderChorePlanner},\n  {id:'decor', category:'home', tag:'Home \u00b7 Planner', title:'Home Decoration Planner', teaser:'A shopping list for your decor style.', render:renderDecorPlanner},\n\n  {id:'resume', category:'career', tag:'Career &#038; Finance \u00b7 Builder', title:'Resume Builder', teaser:'A clean, copyable resume in minutes.', render:renderResumeBuilder},\n  {id:'coverletter', category:'career', tag:'Career &#038; Finance \u00b7 Generator', title:'Cover Letter Generator', teaser:'A personalized draft, ready to edit.', render:renderCoverLetterGen},\n  {id:'salary', category:'career', tag:'Career &#038; Finance \u00b7 Calculator', title:'Salary Calculator', teaser:'Hourly rate to weekly, monthly and annual.', render:renderSalaryCalc},\n  {id:'freelance', category:'career', tag:'Career &#038; Finance \u00b7 Calculator', title:'Freelance Rate Calculator', teaser:'The hourly rate you actually need to charge.', render:renderFreelanceRate},\n  {id:'budgetplanner', category:'career', tag:'Career &#038; Finance \u00b7 Planner', title:'Budget Planner (50\/30\/20)', teaser:'A simple monthly budget breakdown.', render:renderBudgetPlanner},\n  {id:'savingsgoal', category:'career', tag:'Career &#038; Finance \u00b7 Tracker', title:'Savings Goal Tracker', teaser:'How long until you hit your goal.', render:renderSavingsGoal},\n\n  {id:'era', category:'fun', tag:'Just for Fun \u00b7 Quiz', title:'What Era Do You Belong In?', teaser:'From the 1950s to the Regency era.', render:renderEraQuiz},\n  {id:'zodiac', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'Zodiac Personality Generator', teaser:'Your sign and its signature traits.', render:renderZodiac},\n  {id:'boardname', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'Pinterest Board Name Generator', teaser:'Catchy board names for any theme.', render:renderBoardNameGen},\n  {id:'vibe', category:'fun', tag:'Just for Fun \u00b7 Quiz', title:'What\\'s Your Aesthetic?', teaser:'Cottagecore, Y2K, dark academia and more.', render:renderVibeQuiz},\n  {id:'nameaesthetic', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'Name Aesthetic Generator', teaser:'Stylized versions of your name to pin.', render:renderNameAesthetic},\n  {id:'instabio', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'Instagram Bio Generator', teaser:'Bio ideas based on your vibe.', render:renderInstaBioGen},\n  {id:'pincaption', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'Pinterest Caption Generator', teaser:'Save-worthy captions for any topic.', render:renderPinCaptionGen},\n  {id:'tiktokcaption', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'TikTok Caption Generator', teaser:'Caption + hashtag ideas for your video.', render:renderTiktokCaptionGen},\n  {id:'visionboard', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'Vision Board Creator', teaser:'Affirmation cards for the life you\\'re building.', render:renderVisionBoard},\n  {id:'wallpaper', category:'fun', tag:'Just for Fun \u00b7 Creator', title:'Wallpaper Creator', teaser:'A downloadable phone wallpaper, your colors.', render:renderWallpaperCreator},\n  {id:'affirmation', category:'fun', tag:'Just for Fun \u00b7 Generator', title:'Daily Affirmation Generator', teaser:'A new affirmation whenever you need one.', render:renderAffirmationGen},\n  {id:'birthday', category:'fun', tag:'Just for Fun \u00b7 Countdown', title:'Birthday Countdown Tool', teaser:'Days left until your next birthday.', render:renderBirthdayCountdown},\n];\n\nconst arrowSvg = '<svg viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M2 6H10M10 6L6.5 2.5M10 6L6.5 9.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>';\n\nconst grids = {beauty:'grid-beauty', health:'grid-health', lifestyle:'grid-lifestyle', home:'grid-home', career:'grid-career', fun:'grid-fun'};\nlet counters = {beauty:0, health:0, lifestyle:0, fun:0};\nTOOLS.forEach(tool=>{\n  counters[tool.category]++;\n  const specLabel = `SPECIMEN ${String(counters[tool.category]).padStart(2,'0')}`;\n  const card = el('button', {class:'card', type:'button', onclick:()=>openTool(tool), 'aria-haspopup':'dialog'},\n    el('span',{class:'spec'}, specLabel),\n    el('h3',{}, tool.title),\n    el('p',{}, tool.teaser),\n    el('span',{class:'go'}, 'Open tool', (()=>{const s=document.createElement('span'); s.innerHTML=arrowSvg; return s;})())\n  );\n  document.getElementById(grids[tool.category]).appendChild(card);\n});\n\n\/* Footer placeholder links *\/\n['privacy-link','about-link','contact-link'].forEach(id=>{\n  document.getElementById(id).addEventListener('click', (e)=>{\n    e.preventDefault();\n    alert('Add your Privacy Policy, About and Contact pages here before submitting to AdSense \u2014 these pages are required for approval.');\n  });\n});\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Buykapra Special Tools for Girls \u2014 Free Quizzes, Calculators &#038; Planners B Buykapra Special Tools for Girls Beauty &amp; Fashion Health &amp; Lifestyle Wedding &amp; Love Home Career &amp; Money Just for Fun Buykapra \u00b7 Nineteen free tools, no sign-up Special tools for girls,made simple. Quizzes, calculators and planners for the everyday moments \u2014 a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-21594","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/posts\/21594","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/comments?post=21594"}],"version-history":[{"count":5,"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/posts\/21594\/revisions"}],"predecessor-version":[{"id":21604,"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/posts\/21594\/revisions\/21604"}],"wp:attachment":[{"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/media?parent=21594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/categories?post=21594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buykapra.com\/es\/wp-json\/wp\/v2\/tags?post=21594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}