{"id":49,"date":"2026-03-27T09:01:34","date_gmt":"2026-03-27T08:01:34","guid":{"rendered":"https:\/\/magicmastering.es\/?page_id=49"},"modified":"2026-05-05T08:09:27","modified_gmt":"2026-05-05T06:09:27","slug":"magicmastering","status":"publish","type":"page","link":"https:\/\/magicmastering.es\/","title":{"rendered":""},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n  <meta charset=\"UTF-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\/>\n  <title>Magic Mastering<\/title>\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Bebas+Neue&#038;family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&#038;display=swap\" rel=\"stylesheet\"\/>\n  <style>\n    :root {\n      --bg: #080810;\n      --surface: #0f0f1a;\n      --card: #13131f;\n      --border: #1e1e30;\n      --gold: #c8922a;\n      --gold-light: #e8b84b;\n      --gold-dim: #7a5618;\n      --text: #e8e8f0;\n      --muted: #7070a0;\n      --accent2: #00e5ff;\n      --danger: #ff4d6d;\n    }\n\n    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n    html, body { height: 100%; }\n\n    body {\n      background: var(--bg);\n      color: var(--text);\n      font-family: 'DM Sans', sans-serif;\n      font-weight: 300;\n      overflow-x: hidden;\n      min-height: 100vh;\n      display: flex;\n      flex-direction: column;\n    }\n\n    \/* \u2500\u2500 NOISE OVERLAY \u2500\u2500 *\/\n    body::before {\n      content: '';\n      position: fixed; inset: 0;\n      background-image: url(\"data:image\/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http:\/\/www.w3.org\/2000\/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'\/%3E%3C\/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.04'\/%3E%3C\/svg%3E\");\n      pointer-events: none; z-index: 1000; opacity: .5;\n    }\n\n    \/* \u2500\u2500 RADIAL BG \u2500\u2500 *\/\n    body::after {\n      content: '';\n      position: fixed; inset: 0;\n      background:\n        radial-gradient(ellipse 60% 50% at 50% 0%, rgba(200,146,42,.10) 0%, transparent 65%),\n        radial-gradient(ellipse 35% 40% at 85% 80%, rgba(124,77,255,.07) 0%, transparent 55%),\n        radial-gradient(ellipse 30% 30% at 10% 70%, rgba(0,229,255,.05) 0%, transparent 50%);\n      pointer-events: none; z-index: 0;\n    }\n\n    \/* \u2500\u2500 NAV \u2500\u2500 *\/\n    nav {\n      position: relative; z-index: 10;\n      display: flex; align-items: center; justify-content: center;\n      padding: 1.4rem 2rem;\n      border-bottom: 1px solid var(--border);\n      background: rgba(8,8,16,.92);\n      backdrop-filter: blur(14px);\n    }\n    .nav-logo {\n      font-family: 'Bebas Neue', sans-serif;\n      font-size: 1.8rem;\n      letter-spacing: .14em;\n      background: linear-gradient(135deg, var(--gold), var(--gold-light));\n      -webkit-background-clip: text; -webkit-text-fill-color: transparent;\n    }\n\n    \/* \u2500\u2500 MAIN LAYOUT \u2500\u2500 *\/\n    main {\n      position: relative; z-index: 1;\n      flex: 1;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      padding: 2.5rem 1.5rem 3rem;\n    }\n\n    .app-wrapper {\n      width: 100%;\n      max-width: 680px;\n      display: flex;\n      flex-direction: column;\n      gap: 2rem;\n    }\n\n    \/* \u2500\u2500 HEADER ABOVE CARD \u2500\u2500 *\/\n    .app-header {\n      text-align: center;\n      margin-bottom: .5rem;\n      animation: fadeUp .7s ease both;\n    }\n    .app-badge {\n      display: inline-block;\n      font-size: .68rem; font-weight: 500; letter-spacing: .2em; text-transform: uppercase;\n      color: var(--gold); border: 1px solid var(--gold-dim);\n      padding: .3rem .9rem; border-radius: 2rem;\n      margin-bottom: 1rem;\n    }\n    .app-title {\n      font-family: 'Bebas Neue', sans-serif;\n      font-size: clamp(2.4rem, 6vw, 4rem);\n      letter-spacing: .05em; line-height: 1;\n      background: linear-gradient(160deg, #fff 20%, var(--gold-light) 60%, var(--gold) 100%);\n      -webkit-background-clip: text; -webkit-text-fill-color: transparent;\n      margin-bottom: .7rem;\n    }\n    .app-sub {\n      color: var(--muted); font-size: .92rem; line-height: 1.6;\n    }\n\n    \/* \u2500\u2500 UPLOAD CARD \u2500\u2500 *\/\n    .upload-card {\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: 1.2rem;\n      padding: 2rem;\n      position: relative;\n      overflow: hidden;\n      animation: fadeUp .8s .1s ease both;\n    }\n    .upload-card::before {\n      content: '';\n      position: absolute; top: -50px; right: -50px;\n      width: 180px; height: 180px;\n      background: radial-gradient(circle, rgba(200,146,42,.12), transparent 70%);\n      border-radius: 50%;\n      pointer-events: none;\n    }\n\n    \/* drag & drop zone *\/\n    #dropzone {\n      border: 2px dashed var(--border);\n      border-radius: .8rem;\n      padding: 5rem 2rem;\n      min-height: 260px;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      text-align: center;\n      cursor: pointer;\n      transition: border-color .25s, background .25s;\n      position: relative;\n    }\n    #dropzone.dragover {\n      border-color: var(--gold);\n      background: rgba(200,146,42,.06);\n    }\n    #dropzone input[type=file] {\n      position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; height: 100%;\n    }\n    .dz-icon { font-size: 3rem; margin-bottom: 1rem; display: block; }\n    .dz-text { color: var(--muted); font-size: 1rem; line-height: 1.7; }\n    .dz-text strong { color: var(--gold-light); font-weight: 500; font-size: 1.05rem; }\n    .dz-formats {\n      margin-top: .7rem; font-size: .78rem; color: var(--muted);\n      letter-spacing: .04em;\n    }\n\n    \/* file info *\/\n    #file-info {\n      display: none;\n      margin-top: 1rem;\n      background: rgba(200,146,42,.07);\n      border: 1px solid var(--gold-dim);\n      border-radius: .6rem;\n      padding: .8rem 1.1rem;\n      font-size: .85rem;\n      align-items: center; gap: .8rem;\n    }\n    #file-info .fi-icon { font-size: 1.3rem; }\n    #file-info .fi-name { color: var(--gold-light); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px; }\n    #file-info .fi-size { color: var(--muted); font-size: .76rem; }\n\n    \/* progress *\/\n    #progress-wrap {\n      display: none; margin-top: 1.2rem;\n    }\n    .prog-label {\n      display: flex; justify-content: space-between;\n      font-size: .78rem; color: var(--muted); margin-bottom: .45rem;\n    }\n    .prog-bar-bg {\n      height: 5px; background: var(--border); border-radius: 3px; overflow: hidden;\n    }\n    .prog-bar-fill {\n      height: 100%;\n      background: linear-gradient(90deg, var(--gold), var(--gold-light));\n      border-radius: 3px;\n      width: 0%;\n      transition: width .15s linear;\n    }\n    .prog-steps {\n      display: flex; gap: .4rem; flex-wrap: wrap;\n      margin-top: .9rem;\n    }\n    .step-chip {\n      font-size: .68rem; padding: .28rem .65rem;\n      border-radius: 2rem; border: 1px solid var(--border);\n      color: var(--muted);\n      transition: all .3s;\n    }\n    .step-chip.active { border-color: var(--gold); color: var(--gold-light); background: rgba(200,146,42,.1); }\n    .step-chip.done { border-color: #1a7a4a; color: #3ddc84; background: rgba(61,220,132,.08); }\n\n    \/* action btn *\/\n    #master-btn {\n      width: 100%; margin-top: 1.3rem;\n      padding: .95rem; border-radius: .5rem;\n      font-size: .92rem; font-weight: 500;\n      cursor: pointer; border: none;\n      background: linear-gradient(135deg, var(--gold), var(--gold-light));\n      color: #080810;\n      transition: opacity .2s, transform .2s, box-shadow .2s;\n      display: none;\n      letter-spacing: .03em;\n    }\n    #master-btn:disabled { opacity: .5; cursor: not-allowed; transform: none !important; }\n    #master-btn:not(:disabled):hover { transform: translateY(-2px); box-shadow: 0 8px 28px rgba(200,146,42,.4); }\n\n    \/* error *\/\n    #error-box {\n      display: none; margin-top: 1rem;\n      background: rgba(255,77,109,.07);\n      border: 1px solid rgba(255,77,109,.4);\n      border-radius: .6rem; padding: .85rem 1.1rem;\n      color: #ff7096; font-size: .83rem;\n    }\n\n    \/* result *\/\n    #result-box {\n      display: none;\n      margin-top: 1.3rem;\n      background: rgba(61,220,132,.07);\n      border: 1px solid #1a7a4a;\n      border-radius: .8rem;\n      padding: 1.3rem 1.5rem;\n      text-align: center;\n    }\n    #result-box .res-icon { font-size: 1.8rem; }\n    #result-box h4 { color: #3ddc84; font-size: .95rem; font-weight: 500; margin: .4rem 0 .25rem; }\n    #result-box p { color: var(--muted); font-size: .8rem; }\n    #download-btn {\n      margin-top: 1rem;\n      display: inline-flex; align-items: center; gap: .5rem;\n      padding: .7rem 1.4rem; border-radius: .4rem;\n      background: linear-gradient(135deg, #1a7a4a, #3ddc84);\n      color: #080810; font-weight: 500; font-size: .85rem;\n      text-decoration: none; cursor: pointer;\n      transition: transform .2s, box-shadow .2s;\n    }\n    #download-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(61,220,132,.35); }\n\n    \/* \u2500\u2500 FEATURES PANEL \u2500\u2500 *\/\n    .features-panel {\n      display: flex;\n      flex-direction: column;\n      gap: 1rem;\n      animation: fadeUp .8s .2s ease both;\n    }\n\n    .features-title {\n      font-family: 'Bebas Neue', sans-serif;\n      font-size: 1.4rem; letter-spacing: .06em;\n      color: #fff; margin-bottom: .4rem;\n    }\n\n    .features-list {\n      list-style: none;\n      display: grid;\n      grid-template-columns: 1fr 1fr;\n      gap: .8rem;\n    }\n    @media (max-width: 500px) {\n      .features-list { grid-template-columns: 1fr; }\n    }\n    .features-list li {\n      display: flex; align-items: flex-start; gap: .75rem;\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: .7rem;\n      padding: .9rem 1rem;\n    }\n    .feat-icon {\n      width: 34px; height: 34px; flex-shrink: 0;\n      border-radius: .4rem;\n      background: rgba(200,146,42,.09);\n      border: 1px solid var(--gold-dim);\n      display: flex; align-items: center; justify-content: center;\n      font-size: 1rem;\n    }\n    .feat-text strong { display: block; color: var(--text); font-weight: 500; margin-bottom: .15rem; font-size: .83rem; }\n    .feat-text span { color: var(--muted); font-size: .76rem; line-height: 1.4; }\n\n    \/* divider *\/\n    .feat-divider {\n      height: 1px; background: var(--border); margin: .3rem 0;\n    }\n\n    \/* pro upsell *\/\n    .pro-box {\n      background: linear-gradient(135deg, rgba(200,146,42,.08), rgba(200,146,42,.03));\n      border: 1px solid var(--gold-dim);\n      border-radius: .9rem;\n      padding: 1.2rem 1.4rem;\n      margin-top: .2rem;\n    }\n    .pro-box-label {\n      font-size: .66rem; font-weight: 500; letter-spacing: .18em; text-transform: uppercase;\n      color: var(--gold); margin-bottom: .5rem;\n    }\n    .pro-box h4 { font-size: .95rem; font-weight: 500; color: var(--text); margin-bottom: .3rem; }\n    .pro-box p { color: var(--muted); font-size: .8rem; line-height: 1.5; margin-bottom: .8rem; }\n    .pro-box .pro-price {\n      font-family: 'Bebas Neue', sans-serif;\n      font-size: 1.8rem; letter-spacing: .04em;\n      background: linear-gradient(135deg, var(--gold), var(--gold-light));\n      -webkit-background-clip: text; -webkit-text-fill-color: transparent;\n      display: inline-block; margin-bottom: .7rem;\n    }\n    .pro-box .pro-price span {\n      font-family: 'DM Sans', sans-serif;\n      font-size: .85rem; color: var(--muted);\n      -webkit-text-fill-color: var(--muted);\n    }\n    .pro-cta {\n      display: inline-flex; align-items: center; gap: .45rem;\n      padding: .65rem 1.4rem; border-radius: .4rem;\n      font-size: .83rem; font-weight: 500;\n      background: linear-gradient(135deg, var(--gold), var(--gold-light));\n      color: #080810; text-decoration: none;\n      transition: transform .2s, box-shadow .2s;\n    }\n    .pro-cta:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(200,146,42,.4); }\n\n    \/* \u2500\u2500 FOOTER \u2500\u2500 *\/\n    footer {\n      position: relative; z-index: 1;\n      border-top: 1px solid var(--border);\n      padding: 1.4rem 2rem;\n      text-align: center;\n    }\n    .footer-text { color: var(--muted); font-size: .78rem; }\n    .footer-email { color: var(--gold-light); text-decoration: none; }\n    .footer-email:hover { text-decoration: underline; }\n\n    \/* \u2500\u2500 ANIMATIONS \u2500\u2500 *\/\n    @keyframes fadeUp {\n      from { opacity: 0; transform: translateY(20px); }\n      to   { opacity: 1; transform: translateY(0); }\n    }\n\n    \/* scrollbar *\/\n    ::-webkit-scrollbar { width: 6px; }\n    ::-webkit-scrollbar-track { background: var(--bg); }\n    ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }\n  <\/style>\n<\/head>\n<body>\n\n<!-- NAV -->\n<nav>\n  <div class=\"nav-logo\">Magic Mastering<\/div>\n<\/nav>\n\n<!-- MAIN -->\n<main>\n  <div class=\"app-wrapper\">\n\n    <!-- HEADER -->\n    <div class=\"app-header\">\n      <div class=\"app-badge\">\u2726 Masterizaci\u00f3n Profesional Online \u00b7 Gratis \u2726<\/div>\n      <h1 class=\"app-title\">Masteriza tu m\u00fasica al instante<\/h1>\n      <p class=\"app-sub\">Sube tu archivo de audio, procesamos autom\u00e1ticamente y descarga tu master listo para streaming.<\/p>\n    <\/div>\n\n    <!-- UPLOAD TOOL -->\n    <div class=\"upload-card\">\n      <div id=\"dropzone\">\n        <input type=\"file\" id=\"audio-input\" accept=\"audio\/mp3,audio\/mpeg,audio\/wav,audio\/flac,audio\/aac,audio\/ogg\" \/>\n        <span class=\"dz-icon\">\ud83c\udfb5<\/span>\n        <div class=\"dz-text\">\n          <strong>Arrastra tu archivo aqu\u00ed<\/strong><br>\n          o haz clic para seleccionar\n        <\/div>\n        <div class=\"dz-formats\">MP3 \u00b7 WAV \u00b7 FLAC \u00b7 AAC \u00b7 hasta 100 MB<\/div>\n      <\/div>\n\n      <div id=\"file-info\">\n        <span class=\"fi-icon\">\ud83c\udfb6<\/span>\n        <div>\n          <div class=\"fi-name\" id=\"fi-name\">\u2014<\/div>\n          <div class=\"fi-size\" id=\"fi-size\">\u2014<\/div>\n        <\/div>\n      <\/div>\n\n      <button id=\"master-btn\" onclick=\"startMastering()\">\u26a1 Masterizar ahora<\/button>\n\n      <div id=\"progress-wrap\">\n        <div class=\"prog-label\">\n          <span id=\"prog-text\">Analizando audio\u2026<\/span>\n          <span id=\"prog-pct\">0%<\/span>\n        <\/div>\n        <div class=\"prog-bar-bg\"><div class=\"prog-bar-fill\" id=\"prog-fill\"><\/div><\/div>\n        <div class=\"prog-steps\">\n          <span class=\"step-chip\" id=\"chip-1\">\ud83d\udcca An\u00e1lisis<\/span>\n          <span class=\"step-chip\" id=\"chip-2\">\ud83c\udf9a EQ<\/span>\n          <span class=\"step-chip\" id=\"chip-3\">\ud83d\udd0a Compresor<\/span>\n          <span class=\"step-chip\" id=\"chip-4\">\u2728 Limiter<\/span>\n          <span class=\"step-chip\" id=\"chip-5\">\ud83d\udce6 Exportar<\/span>\n        <\/div>\n      <\/div>\n\n      <div id=\"error-box\"><\/div>\n\n      <div id=\"result-box\">\n        <div class=\"res-icon\">\ud83c\udfc6<\/div>\n        <h4>\u00a1Masterizaci\u00f3n completada!<\/h4>\n        <p>Tu archivo est\u00e1 listo. Sonido optimizado para streaming.<\/p>\n        <a id=\"download-btn\" href=\"#\" download>\u2b07 Descargar Master<\/a>\n      <\/div>\n    <\/div>\n\n    <!-- FEATURES PANEL -->\n    <div class=\"features-panel\">\n      <div>\n        <div class=\"features-title\">\u00bfQu\u00e9 incluye?<\/div>\n      <\/div>\n      <ul class=\"features-list\">\n        <li>\n          <div class=\"feat-icon\">\ud83d\udcca<\/div>\n          <div class=\"feat-text\">\n            <strong>An\u00e1lisis espectral autom\u00e1tico<\/strong>\n            <span>Detectamos el balance de frecuencias de tu mezcla para un procesado preciso.<\/span>\n          <\/div>\n        <\/li>\n        <li>\n          <div class=\"feat-icon\">\ud83c\udf9a<\/div>\n          <div class=\"feat-text\">\n            <strong>Ecualizaci\u00f3n adaptativa<\/strong>\n            <span>Correcci\u00f3n basada en referencias de la industria musical.<\/span>\n          <\/div>\n        <\/li>\n        <li>\n          <div class=\"feat-icon\">\ud83d\udd0a<\/div>\n          <div class=\"feat-text\">\n            <strong>Compresi\u00f3n transparente<\/strong>\n            <span>Cohesi\u00f3n din\u00e1mica sin sacrificar el punch de tu m\u00fasica.<\/span>\n          <\/div>\n        <\/li>\n        <li>\n          <div class=\"feat-icon\">\u2728<\/div>\n          <div class=\"feat-text\">\n            <strong>Limiter final -0.1 dBFS<\/strong>\n            <span>Loudness optimizado para Spotify, Apple Music y YouTube.<\/span>\n          <\/div>\n        <\/li>\n        <li>\n          <div class=\"feat-icon\">\ud83d\udce5<\/div>\n          <div class=\"feat-text\">\n            <strong>Descarga inmediata<\/strong>\n            <span>Obt\u00e9n tu WAV masterizado al instante, sin registro.<\/span>\n          <\/div>\n        <\/li>\n      <\/ul>\n\n      <div class=\"feat-divider\"><\/div>\n\n      <div class=\"pro-box\">\n        <div class=\"pro-box-label\">\u2726 \u00bfQuieres m\u00e1s?<\/div>\n        <h4>Masterizaci\u00f3n Manual Pro<\/h4>\n        <p>Un ingeniero profesional masteriza tu canci\u00f3n a mano. WAV 24bit, stems admitidos, 1 revisi\u00f3n incluida. Entrega en 24\u201348h.<\/p>\n        <div class=\"pro-price\">9.99\u20ac <span>\/ canci\u00f3n<\/span><\/div><br>\n        <a class=\"pro-cta\" href=\"mailto:diversitymusicrecords@gmail.com?subject=Solicitud%20de%20masterizaci\u00f3n%20personalizada&#038;body=Hola%2C%20me%20interesa%20el%20servicio%20de%20masterizaci\u00f3n%20personalizada%20por%209.99\u20ac.\">\u2709 Contratar Pro<\/a>\n      <\/div>\n    <\/div>\n\n  <\/div>\n<\/main>\n\n<!-- FOOTER -->\n<footer>\n  <p class=\"footer-text\">\n    \u00a9 2025 Magic Mastering \u00b7 Contacto: <a href=\"mailto:diversitymusicrecords@gmail.com\" class=\"footer-email\">diversitymusicrecords@gmail.com<\/a>\n  <\/p>\n<\/footer>\n\n<script>\n  \/* \u2500\u2500 DRAG & DROP STYLING \u2500\u2500 *\/\n  const dz = document.getElementById('dropzone');\n  dz.addEventListener('dragover', e => { e.preventDefault(); dz.classList.add('dragover'); });\n  dz.addEventListener('dragleave', () => dz.classList.remove('dragover'));\n  dz.addEventListener('drop', e => { e.preventDefault(); dz.classList.remove('dragover'); handleFile(e.dataTransfer.files[0]); });\n\n  const audioInput = document.getElementById('audio-input');\n  audioInput.addEventListener('change', () => handleFile(audioInput.files[0]));\n\n  let selectedFile = null;\n\n  function handleFile(file) {\n    if (!file) return;\n    const allowed = ['audio\/mp3','audio\/mpeg','audio\/wav','audio\/flac','audio\/aac','audio\/ogg','audio\/x-flac'];\n    if (!allowed.includes(file.type) && !file.name.match(\/\\.(mp3|wav|flac|aac|ogg)$\/i)) {\n      showError('Formato no soportado. Por favor sube un archivo MP3, WAV, FLAC o AAC.');\n      return;\n    }\n    if (file.size > 100 * 1024 * 1024) {\n      showError('El archivo supera el l\u00edmite de 100 MB.');\n      return;\n    }\n    selectedFile = file;\n    hideAll();\n\n    const fi = document.getElementById('file-info');\n    fi.style.display = 'flex';\n    document.getElementById('fi-name').textContent = file.name;\n    document.getElementById('fi-size').textContent = formatSize(file.size);\n\n    const mb = document.getElementById('master-btn');\n    mb.style.display = 'block';\n    mb.disabled = false;\n    mb.textContent = '\u26a1 Masterizar ahora';\n  }\n\n  function formatSize(bytes) {\n    if (bytes < 1024 * 1024) return (bytes \/ 1024).toFixed(1) + ' KB';\n    return (bytes \/ (1024 * 1024)).toFixed(2) + ' MB';\n  }\n\n  function showError(msg) {\n    const eb = document.getElementById('error-box');\n    eb.style.display = 'block';\n    eb.textContent = '\u26a0 ' + msg;\n  }\n\n  function hideAll() {\n    document.getElementById('error-box').style.display = 'none';\n    document.getElementById('result-box').style.display = 'none';\n    document.getElementById('progress-wrap').style.display = 'none';\n    ['chip-1','chip-2','chip-3','chip-4','chip-5'].forEach(id => {\n      const el = document.getElementById(id);\n      el.classList.remove('active','done');\n    });\n  }\n\n  \/* \u2500\u2500 MASTERING SIMULATION \u2500\u2500 *\/\n  const steps = [\n    { chip: 'chip-1', label: 'Analizando espectro\u2026',  pct: 20 },\n    { chip: 'chip-2', label: 'Aplicando EQ\u2026',          pct: 40 },\n    { chip: 'chip-3', label: 'Comprimiendo din\u00e1mica\u2026', pct: 65 },\n    { chip: 'chip-4', label: 'Limiter y loudness\u2026',    pct: 85 },\n    { chip: 'chip-5', label: 'Exportando\u2026',            pct: 100 },\n  ];\n\n  async function startMastering() {\n    if (!selectedFile) return;\n    hideAll();\n\n    const btn = document.getElementById('master-btn');\n    btn.disabled = true;\n    btn.textContent = '\u23f3 Procesando\u2026';\n\n    const pw = document.getElementById('progress-wrap');\n    pw.style.display = 'block';\n\n    for (let i = 0; i < steps.length; i++) {\n      const s = steps[i];\n      if (i > 0) document.getElementById(steps[i-1].chip).classList.replace('active','done');\n      document.getElementById(s.chip).classList.add('active');\n      setProgress(s.pct, s.label);\n      await sleep(900 + Math.random() * 600);\n    }\n    document.getElementById(steps[steps.length-1].chip).classList.replace('active','done');\n\n    try {\n      const blob = await processAudio(selectedFile);\n      showResult(blob, selectedFile.name);\n    } catch(err) {\n      showError('Error al procesar el audio: ' + err.message);\n    }\n\n    btn.disabled = false;\n    btn.textContent = '\ud83d\udd04 Masterizar de nuevo';\n  }\n\n  function setProgress(pct, label) {\n    document.getElementById('prog-fill').style.width = pct + '%';\n    document.getElementById('prog-pct').textContent = pct + '%';\n    document.getElementById('prog-text').textContent = label;\n  }\n\n  function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }\n\n  \/* \u2500\u2500 WEB AUDIO PROCESSING \u2500\u2500 *\/\n  async function processAudio(file) {\n    const arrayBuffer = await file.arrayBuffer();\n    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n    const decoded = await audioCtx.decodeAudioData(arrayBuffer);\n\n    const offlineCtx = new OfflineAudioContext(\n      decoded.numberOfChannels,\n      decoded.length,\n      decoded.sampleRate\n    );\n\n    const source = offlineCtx.createBufferSource();\n    source.buffer = decoded;\n\n    const hiShelf = offlineCtx.createBiquadFilter();\n    hiShelf.type = 'highshelf';\n    hiShelf.frequency.value = 10000;\n    hiShelf.gain.value = 2;\n\n    const loShelf = offlineCtx.createBiquadFilter();\n    loShelf.type = 'lowshelf';\n    loShelf.frequency.value = 100;\n    loShelf.gain.value = 1.5;\n\n    const hp = offlineCtx.createBiquadFilter();\n    hp.type = 'highpass';\n    hp.frequency.value = 30;\n\n    const comp = offlineCtx.createDynamicsCompressor();\n    comp.threshold.value = -18;\n    comp.knee.value = 6;\n    comp.ratio.value = 3;\n    comp.attack.value = 0.005;\n    comp.release.value = 0.15;\n\n    const gain = offlineCtx.createGain();\n    gain.gain.value = 1.15;\n\n    source.connect(hp).connect(loShelf).connect(hiShelf).connect(comp).connect(gain).connect(offlineCtx.destination);\n    source.start(0);\n\n    const rendered = await offlineCtx.startRendering();\n    return audioBufferToWav(rendered);\n  }\n\n  \/* \u2500\u2500 PCM \u2192 WAV \u2500\u2500 *\/\n  function audioBufferToWav(buffer) {\n    const numChannels = buffer.numberOfChannels;\n    const sampleRate = buffer.sampleRate;\n    const length = buffer.length;\n    const bitsPerSample = 16;\n    const byteRate = sampleRate * numChannels * bitsPerSample \/ 8;\n    const blockAlign = numChannels * bitsPerSample \/ 8;\n    const dataSize = length * numChannels * bitsPerSample \/ 8;\n    const ab = new ArrayBuffer(44 + dataSize);\n    const view = new DataView(ab);\n\n    function write(offset, str) { for (let i=0;i<str.length;i++) view.setUint8(offset+i, str.charCodeAt(i)); }\n    write(0,'RIFF');\n    view.setUint32(4, 36 + dataSize, true);\n    write(8,'WAVE'); write(12,'fmt ');\n    view.setUint32(16, 16, true);\n    view.setUint16(20, 1, true);\n    view.setUint16(22, numChannels, true);\n    view.setUint32(24, sampleRate, true);\n    view.setUint32(28, byteRate, true);\n    view.setUint16(32, blockAlign, true);\n    view.setUint16(34, bitsPerSample, true);\n    write(36,'data');\n    view.setUint32(40, dataSize, true);\n\n    let offset = 44;\n    for (let i = 0; i < length; i++) {\n      for (let ch = 0; ch < numChannels; ch++) {\n        const sample = Math.max(-1, Math.min(1, buffer.getChannelData(ch)[i]));\n        view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true);\n        offset += 2;\n      }\n    }\n    return new Blob([ab], { type: 'audio\/wav' });\n  }\n\n  function showResult(blob, originalName) {\n    document.getElementById('progress-wrap').style.display = 'none';\n    const rb = document.getElementById('result-box');\n    rb.style.display = 'block';\n\n    const masterName = originalName.replace(\/\\.[^.]+$\/, '') + '_MASTER.wav';\n    const url = URL.createObjectURL(blob);\n    const dlBtn = document.getElementById('download-btn');\n    dlBtn.href = url;\n    dlBtn.download = masterName;\n    dlBtn.textContent = '\u2b07 Descargar ' + masterName;\n\n    setTimeout(() => URL.revokeObjectURL(url), 600000);\n  }\n<\/script>\n<\/body>\n<\/html>\n\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Magic Mastering Magic Mastering \u2726 Masterizaci\u00f3n Profesional Online \u00b7 Gratis \u2726 Masteriza tu m\u00fasica al instante Sube tu archivo de audio, procesamos autom\u00e1ticamente y descarga tu master listo para streaming. \ud83c\udfb5 Arrastra tu archivo aqu\u00ed o haz clic para seleccionar MP3 \u00b7 WAV \u00b7 FLAC \u00b7 AAC \u00b7 hasta 100 MB \ud83c\udfb6 \u2014 \u2014 \u26a1 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-49","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/magicmastering.es\/index.php?rest_route=\/wp\/v2\/pages\/49","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/magicmastering.es\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/magicmastering.es\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/magicmastering.es\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/magicmastering.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=49"}],"version-history":[{"count":105,"href":"https:\/\/magicmastering.es\/index.php?rest_route=\/wp\/v2\/pages\/49\/revisions"}],"predecessor-version":[{"id":160,"href":"https:\/\/magicmastering.es\/index.php?rest_route=\/wp\/v2\/pages\/49\/revisions\/160"}],"wp:attachment":[{"href":"https:\/\/magicmastering.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=49"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}