{"id":9999,"date":"2026-06-03T16:51:53","date_gmt":"2026-06-03T16:51:53","guid":{"rendered":"https:\/\/www.trujiz.com\/app-trujizband\/"},"modified":"2026-06-03T16:51:53","modified_gmt":"2026-06-03T16:51:53","slug":"app-trujizband","status":"publish","type":"page","link":"https:\/\/www.trujiz.com\/en\/app-trujizband\/","title":{"rendered":"App TrujizBand"},"content":{"rendered":"<p><!DOCTYPE html><br \/>\n<html lang=\"es\"><br \/>\n<head><br \/>\n<meta charset=\"UTF-8\"><br \/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><br \/>\n<title>TrujizBand \u2013 Estudio de Trompeta<\/title>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Oswald:wght@300;400;600;700&#038;family=Space+Mono:wght@400;700&#038;display=swap\" rel=\"stylesheet\">\n<style>\n  :root {\n    --gold: #D4A017; --gold-light: #F5C842;\n    --teal: #0E8A7A; --teal-light: #12B5A0; --teal-dim: #0a5c52;\n    --dark: #0A0A0A; --dark2: #141414; --dark3: #1E1E1E; --dark4: #2A2A2A;\n    --red: #C0392B; --green: #27AE60;\n    --text: #F0EAD6; --text-dim: #888;\n  }\n  * { box-sizing: border-box; margin: 0; padding: 0; }\n  body { background: var(--dark); color: var(--text); font-family: 'Space Mono', monospace; min-height: 100vh; overflow-x: hidden; }<\/p>\n<p>  \/* Header con gradiente dorado-teal *\/\n  header {\n    background: linear-gradient(135deg, var(--dark2) 60%, #0a1f1c 100%);\n    border-bottom: 2px solid var(--gold);\n    padding: 12px 20px; display: flex; align-items: center; gap: 12px;\n    position: sticky; top: 0; z-index: 100;\n  }\n  header h1 { font-family: 'Oswald', sans-serif; font-size: 1.5rem; font-weight: 700; letter-spacing: 3px; color: var(--gold); text-transform: uppercase; }\n  header span { font-size: 0.65rem; color: var(--teal-light); letter-spacing: 2px; }<\/p>\n<p>  .tabs { display: flex; background: var(--dark2); border-bottom: 1px solid var(--dark4); overflow-x: auto; }\n  .tab { padding: 12px 18px; cursor: pointer; font-family: 'Oswald', sans-serif; font-size: 0.8rem; letter-spacing: 2px; text-transform: uppercase; color: var(--text-dim); border-bottom: 3px solid transparent; white-space: nowrap; transition: all 0.2s; user-select: none; }\n  .tab:hover { color: var(--text); }\n  .tab.active { color: var(--gold); border-bottom-color: var(--gold); background: #0d1a18; }<\/p>\n<p>  .panel { display: none; padding: 20px; max-width: 700px; margin: 0 auto; }\n  .panel.active { display: block; }<\/p>\n<p>  \/* T\u00edtulos de secci\u00f3n con acento teal *\/\n  .sec-title {\n    font-family: 'Oswald', sans-serif; font-size: 1.1rem; letter-spacing: 3px;\n    text-transform: uppercase; color: var(--gold); margin-bottom: 16px;\n    border-left: 4px solid var(--teal);\n    padding-left: 10px;\n  }<\/p>\n<p>  \/* RUTINA *\/\n  .exercise-list { display: flex; flex-direction: column; gap: 10px; }\n  .exercise-card { background: var(--dark3); border: 1px solid var(--dark4); border-radius: 6px; padding: 14px 16px; display: flex; align-items: center; gap: 14px; cursor: pointer; transition: border-color 0.2s, background 0.2s; }\n  .exercise-card:hover { border-color: var(--gold); background: var(--dark4); }\n  .exercise-card.done { opacity: 0.5; border-color: var(--green); }\n  .exercise-card.active-ex { border-color: var(--gold); background: #1a1500; }\n  .ex-num { font-family: 'Oswald', sans-serif; font-size: 1.4rem; font-weight: 700; color: var(--gold); min-width: 36px; text-align: center; }\n  .ex-info { flex: 1; }\n  .ex-name { font-family: 'Oswald', sans-serif; font-size: 0.95rem; letter-spacing: 1px; }\n  .ex-desc { font-size: 0.65rem; color: var(--text-dim); margin-top: 3px; letter-spacing: 1px; }\n  .ex-time { font-size: 0.75rem; color: var(--gold-light); background: #1a1200; border: 1px solid var(--gold); padding: 3px 8px; border-radius: 4px; font-weight: 700; }\n  .ex-done-mark { color: var(--green); font-size: 1.2rem; }<\/p>\n<p>  .timer-box { background: var(--dark3); border: 2px solid var(--teal); border-radius: 10px; padding: 16px; margin-bottom: 14px; text-align: center; }\n  .timer-label { font-family: 'Oswald', sans-serif; font-size: 0.75rem; letter-spacing: 3px; color: var(--teal-light); text-transform: uppercase; }\n  .timer-ex-name { font-family: 'Oswald', sans-serif; font-size: 1rem; color: var(--gold); margin: 4px 0 10px; }\n  .timer-display { font-family: 'Oswald', sans-serif; font-size: 2.4rem; font-weight: 700; color: var(--text); letter-spacing: 4px; line-height: 1; }\n  .timer-display.urgent { color: var(--red); animation: pulse 0.5s infinite alternate; }\n  @keyframes pulse { from { opacity:1; } to { opacity:0.4; } }\n  .timer-progress { height: 6px; background: var(--dark4); border-radius: 3px; margin: 10px 0; overflow: hidden; }\n  .timer-bar { height: 100%; background: linear-gradient(90deg, var(--gold), var(--gold-light)); border-radius: 3px; transition: width 1s linear; }\n  .total-bar { background: var(--dark3); border-radius: 6px; padding: 10px 14px; margin-bottom: 14px; display: flex; align-items: center; justify-content: space-between; font-size: 0.75rem; color: var(--text-dim); }\n  .total-bar strong { color: var(--gold); font-size: 0.9rem; }<\/p>\n<p>  \/* BOTONES *\/\n  .btn { font-family: 'Oswald', sans-serif; font-size: 0.85rem; letter-spacing: 2px; text-transform: uppercase; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer; transition: all 0.2s; }\n  .btn-gold { background: var(--gold); color: var(--dark); }\n  .btn-gold:hover { background: var(--gold-light); }\n  .btn-outline { background: transparent; color: var(--gold); border: 1px solid var(--gold); }\n  .btn-outline:hover { background: #1a1200; }\n  .btn-red { background: var(--red); color: #fff; }\n  .btn-red:hover { background: #e74c3c; }\n  .btn-green { background: var(--green); color: #fff; }\n  .btn-teal { background: var(--teal); color: #fff; }\n  .btn-teal:hover { background: var(--teal-light); }\n  .btn-row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }<\/p>\n<p>  \/* Barra de progreso con gradiente dorado-teal *\/\n  .timer-bar { height: 100%; background: linear-gradient(90deg, var(--teal), var(--gold)); border-radius: 3px; transition: width 1s linear; }\n  .ln-progress-bar { height: 100%; background: linear-gradient(90deg, var(--teal), var(--gold-light)); transition: width 0.5s linear; border-radius: 4px; }<\/p>\n<p>  \/* AFINADOR *\/\n  .tuner-display { background: var(--dark3); border: 2px solid var(--teal); border-radius: 12px; padding: 24px 20px; margin-bottom: 14px; text-align: center; }\n  .tuner-note { font-family: 'Oswald', sans-serif; font-size: 5rem; font-weight: 700; line-height: 1; color: var(--text); transition: color 0.2s; }\n  .tuner-note.in-tune { color: var(--teal-light); }\n  .tuner-note.sharp { color: #e67e22; }\n  .tuner-note.flat { color: #3498db; }\n  .tuner-cents { font-size: 1.2rem; color: var(--text-dim); margin: 6px 0; font-weight: 700; }\n  .tuner-freq { font-size: 0.75rem; color: var(--text-dim); letter-spacing: 2px; }\n  .tuner-meter { position: relative; height: 20px; background: var(--dark4); border-radius: 10px; margin: 14px 0 6px; overflow: visible; }\n  .tuner-meter-center { position: absolute; left: 50%; top: -4px; width: 2px; height: 28px; background: var(--teal); transform: translateX(-50%); }\n  .tuner-needle { position: absolute; top: 50%; left: 50%; width: 16px; height: 16px; border-radius: 50%; background: var(--text); transform: translate(-50%,-50%); transition: left 0.1s ease; box-shadow: 0 0 8px rgba(255,255,255,0.5); }\n  .tuner-needle.in-tune { background: var(--teal-light); box-shadow: 0 0 12px var(--teal-light); }\n  .tuner-needle.sharp { background: #e67e22; }\n  .tuner-needle.flat { background: #3498db; }\n  .tuner-status { font-family: 'Oswald', sans-serif; font-size: 1rem; letter-spacing: 3px; text-transform: uppercase; margin: 10px 0 14px; min-height: 26px; text-align: center; }\n  .status-intune { color: var(--teal-light); }\n  .status-sharp { color: #e67e22; }\n  .status-flat { color: #3498db; }\n  .status-wait { color: var(--text-dim); }\n  .tuner-note-ref { display: grid; grid-template-columns: repeat(6,1fr); gap: 8px; margin-top: 14px; }\n  .note-chip { background: var(--dark3); border: 1px solid var(--dark4); border-radius: 5px; padding: 8px 4px; text-align: center; font-family: 'Oswald', sans-serif; font-size: 0.85rem; cursor: pointer; transition: all 0.2s; }\n  .note-chip:hover { border-color: var(--gold); color: var(--gold); }\n  .note-chip .chip-freq { font-size: 0.55rem; color: var(--text-dim); display: block; }\n  .note-name-row { display: flex; justify-content: space-between; font-size: 0.6rem; color: var(--text-dim); }<\/p>\n<p>  \/* METRONOMO *\/\n  .metro-bpm-display { font-family: 'Oswald', sans-serif; font-size: 5rem; font-weight: 700; color: var(--gold); line-height: 1; letter-spacing: 2px; }\n  .metro-bpm-label { font-size: 0.7rem; color: var(--text-dim); letter-spacing: 3px; margin-bottom: 20px; }\n  .metro-slider { -webkit-appearance: none; width: 100%; height: 6px; background: var(--dark4); border-radius: 3px; margin: 16px 0; outline: none; }\n  .metro-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 22px; height: 22px; border-radius: 50%; background: var(--gold); cursor: pointer; box-shadow: 0 0 8px rgba(212,160,23,0.5); }\n  .metro-marks { display: flex; justify-content: space-between; font-size: 0.6rem; color: var(--text-dim); margin-bottom: 16px; }\n  .metro-beat-row { display: flex; gap: 10px; justify-content: center; margin: 16px 0; }\n  .beat-dot { width: 18px; height: 18px; border-radius: 50%; background: var(--dark4); border: 2px solid var(--dark4); transition: all 0.05s; }\n  .beat-dot.accent { border-color: var(--gold); }\n  .beat-dot.active { background: var(--gold); box-shadow: 0 0 14px var(--gold); }\n  .beat-dot.accent.active { background: var(--gold-light); box-shadow: 0 0 20px var(--gold-light); }\n  .metro-time-sig { display: flex; gap: 10px; justify-content: center; margin-bottom: 16px; flex-wrap: wrap; }\n  .sig-btn { font-family: 'Oswald', sans-serif; font-size: 0.75rem; letter-spacing: 1px; padding: 6px 14px; border-radius: 4px; border: 1px solid var(--dark4); background: var(--dark3); color: var(--text-dim); cursor: pointer; transition: all 0.2s; }\n  .sig-btn.active { border-color: var(--gold); color: var(--gold); background: #1a1200; }\n  .bpm-presets { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-bottom: 16px; }\n  .preset-btn { font-family: 'Space Mono', monospace; font-size: 0.65rem; padding: 5px 10px; border-radius: 4px; border: 1px solid var(--dark4); background: var(--dark3); color: var(--text-dim); cursor: pointer; transition: all 0.2s; }\n  .preset-btn:hover { border-color: var(--gold); color: var(--gold); }<\/p>\n<p>  \/* NOTAS LARGAS *\/\n  .ln-controls { background: var(--dark3); border: 1px solid var(--dark4); border-radius: 8px; padding: 14px; margin-bottom: 12px; }\n  .ln-label { font-size: 0.7rem; color: var(--text-dim); letter-spacing: 2px; margin-bottom: 6px; text-transform: uppercase; }\n  .ln-value { font-family: 'Oswald', sans-serif; font-size: 2rem; color: var(--gold); font-weight: 700; }\n  .ln-slider { -webkit-appearance: none; width: 100%; height: 4px; background: var(--dark4); border-radius: 2px; margin: 8px 0 4px; outline: none; }\n  .ln-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%; background: var(--gold); cursor: pointer; }\n  .note-sequence { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }\n  .note-seq-btn { font-family: 'Oswald', sans-serif; font-size: 0.85rem; padding: 8px 12px; border-radius: 4px; border: 1px solid var(--dark4); background: var(--dark3); color: var(--text-dim); cursor: pointer; transition: all 0.2s; min-width: 42px; text-align: center; }\n  .note-seq-btn.selected { border-color: var(--gold); color: var(--gold); background: #1a1200; }\n  .note-seq-btn.current-playing { background: var(--gold); color: var(--dark); border-color: var(--gold); }\n  .ln-timer-big { font-family: 'Oswald', sans-serif; font-size: 2.4rem; font-weight: 700; text-align: center; color: var(--text); letter-spacing: 4px; }\n  .ln-progress-wrap { background: var(--dark4); border-radius: 4px; height: 6px; margin-bottom: 12px; overflow: hidden; }\n  .ln-progress-bar { height: 100%; background: linear-gradient(90deg, var(--gold), var(--gold-light)); transition: width 0.5s linear; border-radius: 4px; }\n  .ln-log { background: var(--dark3); border: 1px solid var(--dark4); border-radius: 6px; padding: 12px; max-height: 150px; overflow-y: auto; font-size: 0.7rem; color: var(--text-dim); line-height: 1.8; }\n  .ln-log-entry { border-bottom: 1px solid var(--dark4); padding: 3px 0; }\n  .ln-log-entry:last-child { border-bottom: none; }<\/p>\n<p>  \/* VIDEOS *\/\n  .video-module { background: var(--dark3); border: 1px solid var(--dark4); border-radius: 8px; margin-bottom: 12px; overflow: hidden; transition: border-color 0.2s; }\n  .video-module:hover { border-color: var(--gold); }\n  .video-module-header { padding: 14px 16px; display: flex; align-items: center; gap: 12px; cursor: pointer; }\n  .vm-icon { width: 36px; height: 36px; border-radius: 50%; background: #1a1200; border: 1px solid var(--gold); display: flex; align-items: center; justify-content: center; font-size: 1rem; flex-shrink: 0; }\n  .vm-info { flex: 1; }\n  .vm-title { font-family: 'Oswald', sans-serif; font-size: 0.9rem; letter-spacing: 1px; }\n  .vm-count { font-size: 0.65rem; color: var(--text-dim); margin-top: 2px; }\n  .vm-arrow { color: var(--text-dim); transition: transform 0.2s; }\n  .vm-arrow.open { transform: rotate(90deg); }\n  .video-list { display: none; border-top: 1px solid var(--dark4); }\n  .video-list.open { display: block; }\n  .video-item { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--dark4); text-decoration: none; color: var(--text); transition: background 0.2s; }\n  .video-item:last-child { border-bottom: none; }\n  .video-item:hover { background: var(--dark4); }\n  .video-thumb { width: 70px; height: 44px; border-radius: 4px; object-fit: cover; border: 1px solid var(--dark4); flex-shrink: 0; background: var(--dark4); }\n  .video-item-title { font-size: 0.75rem; line-height: 1.4; }\n  .yt-badge { font-size: 0.6rem; background: var(--red); color: #fff; padding: 2px 6px; border-radius: 3px; margin-top: 3px; display: inline-block; letter-spacing: 1px; font-family: 'Oswald', sans-serif; }<\/p>\n<p>  \/* SESION *\/\n  .session-today { background: var(--dark3); border: 1px solid var(--dark4); border-radius: 8px; padding: 16px; margin-bottom: 14px; }\n  .session-date { font-size: 0.65rem; color: var(--text-dim); letter-spacing: 2px; margin-bottom: 8px; }\n  .session-stats { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-bottom: 14px; }\n  .stat-box { background: var(--dark4); border-radius: 6px; padding: 12px; text-align: center; }\n  .stat-val { font-family: 'Oswald', sans-serif; font-size: 1.8rem; font-weight: 700; color: var(--gold); }\n  .stat-lbl { font-size: 0.6rem; color: var(--text-dim); letter-spacing: 1px; margin-top: 2px; }\n  .notes-area { width: 100%; background: var(--dark4); border: 1px solid var(--dark4); border-radius: 6px; color: var(--text); font-family: 'Space Mono', monospace; font-size: 0.75rem; padding: 12px; resize: vertical; min-height: 90px; outline: none; margin-bottom: 12px; transition: border-color 0.2s; }\n  .notes-area:focus { border-color: var(--gold); }\n  .history-list { display: flex; flex-direction: column; gap: 8px; }\n  .history-item { background: var(--dark3); border: 1px solid var(--dark4); border-radius: 6px; padding: 12px 14px; display: flex; align-items: center; gap: 14px; }\n  .h-date { font-size: 0.65rem; color: var(--text-dim); min-width: 70px; }\n  .h-info { flex: 1; font-size: 0.75rem; }\n  .h-min { font-family: 'Oswald', sans-serif; color: var(--gold); font-size: 0.9rem; }<\/p>\n<p>  \/* SLIDER rutina *\/\n  #rutinaBpmSlider { -webkit-appearance: none; height: 4px; background: var(--dark3); border-radius: 2px; outline: none; }\n  #rutinaBpmSlider::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%; background: var(--gold); cursor: pointer; }\n  #lnBpmSlider { -webkit-appearance: none; height: 3px; background: var(--dark4); border-radius: 2px; outline: none; }\n  #lnBpmSlider::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%; background: var(--gold); cursor: pointer; }<\/p>\n<p>  .toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%) translateY(80px); background: var(--gold); color: var(--dark); font-family: 'Oswald', sans-serif; font-size: 0.85rem; letter-spacing: 2px; padding: 10px 24px; border-radius: 6px; transition: transform 0.3s; z-index: 999; pointer-events: none; }\n  .toast.show { transform: translateX(-50%) translateY(0); }\n  ::-webkit-scrollbar { width: 4px; height: 4px; }\n  ::-webkit-scrollbar-track { background: var(--dark2); }\n  ::-webkit-scrollbar-thumb { background: var(--gold); border-radius: 2px; }\n<\/style>\n<p><\/head><br \/>\n<body><\/p>\n<header>\n<div style=\"font-size:1.5rem\">\ud83c\udfba<\/div>\n<div>\n<h1>TrujizBand<\/h1>\n<p><span>M\u00c9TODO DE ESTUDIO<\/span><\/div>\n<\/header>\n<div class=\"tabs\">\n<div class=\"tab active\" onclick=\"showPanel('afinador',this)\">Afinador<\/div>\n<div class=\"tab\" onclick=\"showPanel('notas',this)\">Notas Largas<\/div>\n<div class=\"tab\" onclick=\"showPanel('metronomo',this)\">Metr\u00f3nomo<\/div>\n<div class=\"tab\" onclick=\"showPanel('videos',this)\">Mis Videos<\/div>\n<div class=\"tab\" onclick=\"showPanel('sesion',this)\">Sesi\u00f3n<\/div>\n<div class=\"tab\" onclick=\"showPanel('rutina',this)\">Rutina<\/div>\n<\/div>\n<p><!-- RUTINA --><\/p>\n<div id=\"panel-rutina\" class=\"panel\">\n<div class=\"sec-title\">Rutina Definitiva \/ 45 min<\/div>\n<div class=\"timer-box\" id=\"timerBox\" style=\"display:none\">\n<div class=\"timer-label\">Ejercicio Activo<\/div>\n<div class=\"timer-ex-name\" id=\"timerExName\">\u2013<\/div>\n<div style=\"display:grid;grid-template-columns:1fr 1px 1fr;gap:0;align-items:center;margin:10px 0;\">\n<div style=\"text-align:center;padding:0 10px;\">\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:4px;\">\u23f1 TIEMPO<\/div>\n<div class=\"timer-display\" id=\"timerDisplay\">00:00<\/div>\n<\/p><\/div>\n<div style=\"background:var(--dark4);height:60px;width:1px;\"><\/div>\n<div style=\"text-align:center;padding:0 10px;\">\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:4px;\">\ud83e\udd41 BPM<\/div>\n<div style=\"display:flex;align-items:center;justify-content:center;gap:6px;\">\n          <button onclick=\"changeRutinaBpm(-5)\" style=\"background:var(--dark4);border:1px solid var(--dark4);color:var(--text);border-radius:4px;width:26px;height:26px;font-size:0.9rem;cursor:pointer;\">\u2212<\/button><\/p>\n<div style=\"font-family:'Oswald',sans-serif;font-size:2.5rem;font-weight:700;color:var(--gold);line-height:1;min-width:60px;text-align:center;\" id=\"rutinaBpmDisplay\">80<\/div>\n<p>          <button onclick=\"changeRutinaBpm(5)\" style=\"background:var(--dark4);border:1px solid var(--dark4);color:var(--text);border-radius:4px;width:26px;height:26px;font-size:0.9rem;cursor:pointer;\">+<\/button>\n        <\/div>\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;\">BPM<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div class=\"timer-progress\">\n<div class=\"timer-bar\" id=\"timerBar\" style=\"width:100%\"><\/div>\n<\/div>\n<div style=\"background:var(--dark4);border-radius:6px;padding:8px 12px;margin-bottom:10px;\">\n      <input type=\"range\" min=\"40\" max=\"220\" value=\"80\" id=\"rutinaBpmSlider\" oninput=\"setRutinaBpm(this.value)\" style=\"width:100%;display:block;margin-bottom:8px;\"><\/p>\n<div style=\"display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;\">\n<div style=\"display:flex;gap:5px;\" id=\"rutinaBeatRow\"><\/div>\n<div style=\"display:flex;gap:5px;align-items:center;flex-wrap:wrap;\">\n          <button class=\"sig-btn active\" id=\"rsig-4\" onclick=\"setRutinaTimeSig(4,this)\">4\/4<\/button><br \/>\n          <button class=\"sig-btn\" id=\"rsig-3\" onclick=\"setRutinaTimeSig(3,this)\">3\/4<\/button><br \/>\n          <button class=\"sig-btn\" id=\"rsig-2\" onclick=\"setRutinaTimeSig(2,this)\">2\/4<\/button><br \/>\n          <button class=\"btn btn-outline\" id=\"rutinaMetroBtn\" onclick=\"toggleRutinaMetro()\" style=\"padding:5px 12px;font-size:0.7rem;\">\u25b6 Metro<\/button>\n        <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div class=\"btn-row\">\n      <button class=\"btn btn-outline\" onclick=\"pauseTimer()\">\u23f8 Pausar<\/button><br \/>\n      <button class=\"btn btn-red\" onclick=\"doStopTimer()\">\u23f9 Parar<\/button><br \/>\n      <button class=\"btn btn-green\" onclick=\"markDone()\">\u2713 Listo<\/button>\n    <\/div>\n<\/p><\/div>\n<div class=\"total-bar\">\n    <span>Progreso sesi\u00f3n:<\/span><br \/>\n    <span><strong id=\"doneCount\">0<\/strong> \/ 11 ejercicios \/ <strong id=\"totalMin\">0<\/strong> min<\/span>\n  <\/div>\n<div class=\"exercise-list\" id=\"exerciseList\"><\/div>\n<div style=\"margin-top:14px\" class=\"btn-row\">\n    <button class=\"btn btn-outline\" onclick=\"resetAll()\">\u21ba Reiniciar<\/button><br \/>\n    <button class=\"btn btn-gold\" onclick=\"startNext()\">\u25b6 Iniciar Siguiente<\/button>\n  <\/div>\n<\/div>\n<p><!-- AFINADOR --><\/p>\n<div id=\"panel-afinador\" class=\"panel active\">\n<div class=\"sec-title\">Afinador Crom\u00e1tico<\/div>\n<div class=\"tuner-display\">\n<div class=\"tuner-note\" id=\"tunerNote\">\u2013<\/div>\n<div class=\"tuner-cents\" id=\"tunerCents\">\u2013 \u00a2<\/div>\n<div class=\"tuner-freq\" id=\"tunerFreq\">\u2013 Hz<\/div>\n<div class=\"tuner-meter\">\n<div style=\"position:absolute;left:10%;top:4px;font-size:0.55rem;color:var(--text-dim)\">\u266d<\/div>\n<div style=\"position:absolute;right:10%;top:4px;font-size:0.55rem;color:var(--text-dim)\">\u266f<\/div>\n<div class=\"tuner-meter-center\"><\/div>\n<div class=\"tuner-needle\" id=\"tunerNeedle\"><\/div>\n<\/p><\/div>\n<div class=\"note-name-row\"><span>-50\u00a2<\/span><span>-25\u00a2<\/span><span>0<\/span><span>+25\u00a2<\/span><span>+50\u00a2<\/span><\/div>\n<\/p><\/div>\n<div class=\"tuner-status status-wait\" id=\"tunerStatus\">Pulsa ACTIVAR para empezar<\/div>\n<div class=\"btn-row\" style=\"margin-bottom:16px;\">\n    <button class=\"btn btn-teal\" id=\"tunerBtn\" onclick=\"toggleTuner()\">\ud83c\udf99 Activar Micr\u00f3fono<\/button>\n  <\/div>\n<div class=\"sec-title\" style=\"font-size:0.8rem;margin-bottom:10px\">Notas de Referencia \/ Trompeta en Si\u266d<\/div>\n<div class=\"tuner-note-ref\" id=\"noteRef\"><\/div>\n<\/div>\n<p><!-- METRONOMO --><\/p>\n<div id=\"panel-metronomo\" class=\"panel\">\n<div class=\"sec-title\">Metr\u00f3nomo<\/div>\n<div style=\"text-align:center;\">\n<div class=\"metro-bpm-display\" id=\"bpmDisplay\">80<\/div>\n<div class=\"metro-bpm-label\">BPM<\/div>\n<p>    <input type=\"range\" min=\"40\" max=\"220\" value=\"80\" class=\"metro-slider\" id=\"bpmSlider\" oninput=\"setBpm(this.value)\"><\/p>\n<div class=\"metro-marks\"><span>40<\/span><span>80<\/span><span>120<\/span><span>160<\/span><span>220<\/span><\/div>\n<div class=\"metro-time-sig\" id=\"timeSig\">\n      <button class=\"sig-btn active\" onclick=\"setTimeSig(4,this)\">4\/4<\/button><br \/>\n      <button class=\"sig-btn\" onclick=\"setTimeSig(3,this)\">3\/4<\/button><br \/>\n      <button class=\"sig-btn\" onclick=\"setTimeSig(2,this)\">2\/4<\/button><br \/>\n      <button class=\"sig-btn\" onclick=\"setTimeSig(6,this)\">6\/8<\/button>\n    <\/div>\n<div class=\"metro-beat-row\" id=\"beatRow\"><\/div>\n<div class=\"bpm-presets\">\n      <button class=\"preset-btn\" onclick=\"setBpmPreset(60)\">Adagio 60<\/button><br \/>\n      <button class=\"preset-btn\" onclick=\"setBpmPreset(76)\">Andante 76<\/button><br \/>\n      <button class=\"preset-btn\" onclick=\"setBpmPreset(96)\">Moderato 96<\/button><br \/>\n      <button class=\"preset-btn\" onclick=\"setBpmPreset(120)\">Allegro 120<\/button><br \/>\n      <button class=\"preset-btn\" onclick=\"setBpmPreset(144)\">Vivace 144<\/button><br \/>\n      <button class=\"preset-btn\" onclick=\"setBpmPreset(176)\">Presto 176<\/button>\n    <\/div>\n<div class=\"btn-row\">\n      <button class=\"btn btn-outline\" onclick=\"tapTempo()\">\ud83d\udc46 Tap Tempo<\/button><br \/>\n      <button class=\"btn btn-gold\" id=\"metroBtn\" onclick=\"toggleMetro()\">\u25b6 Iniciar<\/button>\n    <\/div>\n<div style=\"margin-top:10px;font-size:0.65rem;color:var(--text-dim);\" id=\"tapInfo\"><\/div>\n<\/p><\/div>\n<\/div>\n<p><!-- NOTAS LARGAS --><\/p>\n<div id=\"panel-notas\" class=\"panel\">\n<div class=\"sec-title\">Notas Tenidas \/ M\u00e9todo TrujizBand<\/div>\n<p>  <!-- SELECTOR DE M\u00d3DULO --><\/p>\n<div style=\"display:flex;flex-direction:column;gap:8px;margin-bottom:14px;\" id=\"nlModuleSelector\">\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:2px;\">SELECCIONA EJERCICIO:<\/div>\n<div onclick=\"loadNLModule(1)\" id=\"nlmod1\" style=\"background:var(--gold);color:var(--dark);border-radius:8px;padding:12px 16px;cursor:pointer;display:flex;align-items:center;gap:12px;border:2px solid var(--gold);\">\n<div style=\"font-family:'Oswald',sans-serif;font-size:1.8rem;font-weight:700;min-width:32px;\">1<\/div>\n<div>\n<div style=\"font-family:'Oswald',sans-serif;font-size:0.9rem;letter-spacing:1px;font-weight:700;\">DESCENDENTE \/ Registro Grave<\/div>\n<div style=\"font-size:0.6rem;margin-top:2px;opacity:0.8;\">Sol 2\u00aa l\u00ednea \u2193 Fa#2 \/ bemoles<\/div>\n<\/div>\n<div style=\"margin-left:auto;\">\u25b6<\/div>\n<\/p><\/div>\n<div onclick=\"loadNLModule(2)\" id=\"nlmod2\" style=\"background:var(--dark3);color:var(--text);border-radius:8px;padding:12px 16px;cursor:pointer;display:flex;align-items:center;gap:12px;border:2px solid var(--teal-dim);\">\n<div style=\"font-family:'Oswald',sans-serif;font-size:1.8rem;font-weight:700;color:var(--teal-light);min-width:32px;\">2<\/div>\n<div>\n<div style=\"font-family:'Oswald',sans-serif;font-size:0.9rem;letter-spacing:1px;\">ASCENDENTE \/ Registro Grave<\/div>\n<div style=\"font-size:0.6rem;color:var(--teal-light);margin-top:2px;opacity:0.8;\">Fa#2 \u2191 Sol 2\u00aa l\u00ednea \/ sostenidos<\/div>\n<\/div>\n<div style=\"margin-left:auto;color:var(--teal-light);\">\u25b6<\/div>\n<\/p><\/div>\n<div onclick=\"loadNLModule(3)\" id=\"nlmod3\" style=\"background:var(--dark3);color:var(--text);border-radius:8px;padding:12px 16px;cursor:pointer;display:flex;align-items:center;gap:12px;border:2px solid var(--gold);\">\n<div style=\"font-family:'Oswald',sans-serif;font-size:1.8rem;font-weight:700;color:var(--gold);min-width:32px;\">3<\/div>\n<div>\n<div style=\"font-family:'Oswald',sans-serif;font-size:0.9rem;letter-spacing:1px;\">ASCENDENTE \/ Registro Agudo<\/div>\n<div style=\"font-size:0.6rem;color:var(--text-dim);margin-top:2px;opacity:0.8;\">Sol 2\u00aa l\u00ednea \u2191 Sol agudo \/ sostenidos<\/div>\n<\/div>\n<div style=\"margin-left:auto;color:var(--gold);\">\u25b6<\/div>\n<\/p><\/div>\n<div onclick=\"loadNLModule(4)\" id=\"nlmod4\" style=\"background:var(--dark3);color:var(--text);border-radius:8px;padding:12px 16px;cursor:pointer;display:flex;align-items:center;gap:12px;border:2px solid var(--teal-dim);\">\n<div style=\"font-family:'Oswald',sans-serif;font-size:1.8rem;font-weight:700;color:var(--teal-light);min-width:32px;\">4<\/div>\n<div>\n<div style=\"font-family:'Oswald',sans-serif;font-size:0.9rem;letter-spacing:1px;\">DESCENDENTE \/ Registro Agudo<\/div>\n<div style=\"font-size:0.6rem;color:var(--teal-light);margin-top:2px;opacity:0.8;\">Sol agudo \u2193 Sol 2\u00aa l\u00ednea \/ bemoles<\/div>\n<\/div>\n<div style=\"margin-left:auto;color:var(--teal-light);\">\u25b6<\/div>\n<\/p><\/div>\n<div onclick=\"loadNLModule(5)\" id=\"nlmod5\" style=\"background:var(--dark3);color:var(--text);border-radius:8px;padding:12px 16px;cursor:pointer;display:flex;align-items:center;gap:12px;border:2px solid var(--red);\">\n<div style=\"font-family:'Oswald',sans-serif;font-size:1.8rem;font-weight:700;color:var(--red);min-width:32px;\">5<\/div>\n<div>\n<div style=\"font-family:'Oswald',sans-serif;font-size:0.9rem;letter-spacing:1px;\">ASCENDENTE \/ Sobreagudo \u26a0\ufe0f<\/div>\n<div style=\"font-size:0.6rem;color:#e88;margin-top:2px;opacity:0.8;\">Sol 2\u00aa l\u00ednea \u2191 Do sobreagudo \/ avanzado<\/div>\n<\/div>\n<div style=\"margin-left:auto;color:var(--red);\">\u25b6<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>  <!-- EJERCICIO ACTIVO (se muestra al seleccionar) --><\/p>\n<div id=\"nlExercisePanel\" style=\"display:none;\">\n<p>    <!-- Cabecera m\u00f3dulo activo --><\/p>\n<div style=\"display:flex;align-items:center;gap:10px;margin-bottom:12px;\">\n      <button onclick=\"backToNLModules()\" style=\"background:transparent;border:1px solid var(--dark4);color:var(--text-dim);border-radius:6px;padding:6px 12px;cursor:pointer;font-family:'Oswald',sans-serif;font-size:0.75rem;letter-spacing:1px;\">\u2190 VOLVER<\/button><\/p>\n<div id=\"nlModuleTitle\" style=\"font-family:'Oswald',sans-serif;font-size:0.95rem;color:var(--gold);letter-spacing:2px;\"><\/div>\n<\/p><\/div>\n<p>  <!-- Pentagrama + digitaci\u00f3n --><\/p>\n<div style=\"background:var(--dark3);border:1px solid var(--dark4);border-radius:10px;padding:14px;margin-bottom:12px;\">\n<div style=\"display:grid;grid-template-columns:1fr auto;gap:10px;align-items:center;\">\n<div>\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:6px;\">\ud83c\udfbc TROMPETA EN Si\u266d \/ NOTA ESCRITA<\/div>\n<p>        <svg id=\"staffSvg\" viewBox=\"0 0 260 110\" width=\"100%\" style=\"max-width:300px;display:block;\">\n          <!-- L\u00edneas adicionales ARRIBA (registro agudo) -->\n          <line id=\"extraLineTop1\" x1=\"148\" y1=\"12\" x2=\"172\" y2=\"12\" stroke=\"var(--gold)\" stroke-width=\"2\" display=\"none\"\/>\n          <line id=\"extraLineTop2\" x1=\"148\" y1=\"2\" x2=\"172\" y2=\"2\" stroke=\"var(--gold)\" stroke-width=\"2\" display=\"none\"\/>\n          <!-- Pentagrama -->\n          <line x1=\"30\" y1=\"22\" x2=\"250\" y2=\"22\" stroke=\"#555\" stroke-width=\"1.2\"\/>\n          <line x1=\"30\" y1=\"32\" x2=\"250\" y2=\"32\" stroke=\"#555\" stroke-width=\"1.2\"\/>\n          <line x1=\"30\" y1=\"42\" x2=\"250\" y2=\"42\" stroke=\"#555\" stroke-width=\"1.2\"\/>\n          <line x1=\"30\" y1=\"52\" x2=\"250\" y2=\"52\" stroke=\"#555\" stroke-width=\"1.2\"\/>\n          <line x1=\"30\" y1=\"62\" x2=\"250\" y2=\"62\" stroke=\"#555\" stroke-width=\"1.2\"\/>\n          <text x=\"30\" y=\"60\" font-size=\"52\" fill=\"#888\" font-family=\"serif\">\ud834\udd1e<\/text>\n          <ellipse id=\"noteHead\" cx=\"160\" cy=\"52\" rx=\"9\" ry=\"6.5\" fill=\"var(--gold)\"\/>\n          <line id=\"noteStem\" x1=\"169\" y1=\"52\" x2=\"169\" y2=\"24\" stroke=\"var(--gold)\" stroke-width=\"2\"\/>\n          <text id=\"noteAccidental\" x=\"138\" y=\"56\" font-size=\"22\" fill=\"var(--gold)\" font-family=\"serif\" font-weight=\"bold\"><\/text>\n          <!-- L\u00edneas adicionales ABAJO (registro grave) -->\n          <line id=\"extraLine1\" x1=\"148\" y1=\"72\" x2=\"172\" y2=\"72\" stroke=\"var(--gold)\" stroke-width=\"2\" display=\"none\"\/>\n          <line id=\"extraLine2\" x1=\"148\" y1=\"82\" x2=\"172\" y2=\"82\" stroke=\"var(--gold)\" stroke-width=\"2\" display=\"none\"\/>\n          <line id=\"extraLine3\" x1=\"148\" y1=\"92\" x2=\"172\" y2=\"92\" stroke=\"var(--gold)\" stroke-width=\"2\" display=\"none\"\/>\n          <text id=\"staffLabel\" x=\"160\" y=\"108\" font-size=\"11\" fill=\"#888\" font-family=\"'Oswald',sans-serif\" text-anchor=\"middle\" letter-spacing=\"1\">SOL<\/text>\n        <\/svg>\n      <\/div>\n<div style=\"text-align:center;min-width:90px;\">\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:4px;\">V\u00c1LVULAS<\/div>\n<div style=\"display:flex;gap:8px;justify-content:center;margin-bottom:6px;\">\n<div id=\"v1\" style=\"width:28px;height:28px;border-radius:50%;border:2px solid var(--dark4);background:var(--dark4);display:flex;align-items:center;justify-content:center;font-family:'Oswald',sans-serif;font-size:0.75rem;color:var(--text-dim);transition:all 0.2s;\">1<\/div>\n<div id=\"v2\" style=\"width:28px;height:28px;border-radius:50%;border:2px solid var(--dark4);background:var(--dark4);display:flex;align-items:center;justify-content:center;font-family:'Oswald',sans-serif;font-size:0.75rem;color:var(--text-dim);transition:all 0.2s;\">2<\/div>\n<div id=\"v3\" style=\"width:28px;height:28px;border-radius:50%;border:2px solid var(--dark4);background:var(--dark4);display:flex;align-items:center;justify-content:center;font-family:'Oswald',sans-serif;font-size:0.75rem;color:var(--text-dim);transition:all 0.2s;\">3<\/div>\n<\/p><\/div>\n<div id=\"fingeringText\" style=\"font-family:'Oswald',sans-serif;font-size:0.6rem;color:var(--text-dim);letter-spacing:1px;margin-bottom:10px;\">abierta<\/div>\n<p>        <!-- Nota trompeta GRANDE --><\/p>\n<div id=\"trumpetNoteName\" style=\"font-family:'Oswald',sans-serif;font-size:1.6rem;font-weight:700;color:var(--gold);letter-spacing:1px;line-height:1.1;margin-bottom:4px;\">Sol<\/div>\n<p>        <!-- Nota piano PEQUE\u00d1A --><\/p>\n<div style=\"font-size:0.55rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:2px;\">piano<\/div>\n<div id=\"realPitchName\" style=\"font-family:'Oswald',sans-serif;font-size:0.8rem;color:#666;letter-spacing:1px;\">Fa<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>  <!-- Timer + Metro lado a lado --><\/p>\n<div style=\"display:grid;grid-template-columns:1fr 1px 1fr;background:var(--dark3);border:2px solid var(--dark4);border-radius:10px;margin-bottom:8px;\" id=\"lnTimerPanel\">\n<div style=\"text-align:center;padding:14px 8px;\">\n<div id=\"lnPhaseLabel\" style=\"font-size:0.6rem;color:var(--gold);letter-spacing:2px;margin-bottom:4px;font-family:'Oswald',sans-serif;\">\u23f1 TOCA AHORA<\/div>\n<div class=\"ln-timer-big\" id=\"lnTimer\">00:00<\/div>\n<\/p><\/div>\n<div style=\"background:var(--dark4);width:1px;\"><\/div>\n<div style=\"text-align:center;padding:14px 8px;\">\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:4px;\">\ud83e\udd41 METRO<\/div>\n<div style=\"display:flex;align-items:center;justify-content:center;gap:6px;\">\n        <button onclick=\"lnChangeBpm(-5)\" style=\"background:var(--dark4);border:1px solid var(--dark4);color:var(--text);border-radius:4px;width:24px;height:24px;font-size:0.9rem;cursor:pointer;\">\u2212<\/button><\/p>\n<div style=\"font-family:'Oswald',sans-serif;font-size:2.4rem;font-weight:700;color:var(--gold);line-height:1;min-width:52px;\" id=\"lnBpmDisplay\">90<\/div>\n<p>        <button onclick=\"lnChangeBpm(5)\" style=\"background:var(--dark4);border:1px solid var(--dark4);color:var(--text);border-radius:4px;width:24px;height:24px;font-size:0.9rem;cursor:pointer;\">+<\/button>\n      <\/div>\n<p>      <input type=\"range\" min=\"40\" max=\"160\" value=\"90\" id=\"lnBpmSlider\" oninput=\"lnSetBpm(this.value)\" style=\"width:88%;display:block;margin:6px auto 6px;\"><\/p>\n<div style=\"display:flex;gap:5px;justify-content:center;\" id=\"lnBeatDots\"><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>  <!-- NAVEGACI\u00d3N \u23ee \u23ed justo debajo del metro --><\/p>\n<div style=\"display:flex;gap:8px;align-items:center;margin-bottom:8px;\">\n    <button class=\"btn btn-outline\" onclick=\"jumpNote(-1)\" style=\"flex:1;padding:8px 4px;font-size:0.85rem;\">\u23ee Anterior<\/button><\/p>\n<div style=\"text-align:center;flex:1.2;background:var(--dark3);border:1px solid var(--dark4);border-radius:8px;padding:8px 4px;\">\n<div style=\"font-size:0.55rem;color:var(--text-dim);letter-spacing:2px;\">NOTA<\/div>\n<div id=\"lnCurrentNoteDisplay\" style=\"font-family:'Oswald',sans-serif;font-size:1.4rem;color:var(--gold);letter-spacing:2px;line-height:1.1;\">\u2013<\/div>\n<div id=\"lnNoteCounter\" style=\"font-size:0.55rem;color:var(--text-dim);margin-top:2px;\">0 \/ 0<\/div>\n<\/p><\/div>\n<p>    <button class=\"btn btn-outline\" onclick=\"jumpNote(1)\" style=\"flex:1;padding:8px 4px;font-size:0.85rem;\">Siguiente \u23ed<\/button>\n  <\/div>\n<div class=\"ln-progress-wrap\" style=\"margin-bottom:10px;\">\n<div class=\"ln-progress-bar\" id=\"lnProgressBar\" style=\"width:0%\"><\/div>\n<\/div>\n<div class=\"ln-controls\">\n<div style=\"display:grid;grid-template-columns:1fr 1fr;gap:14px;\">\n<div>\n<div class=\"ln-label\">Duraci\u00f3n por nota<\/div>\n<div class=\"ln-value\" id=\"lnDurVal\">8s<\/div>\n<p>        <input type=\"range\" min=\"4\" max=\"30\" value=\"8\" class=\"ln-slider\" id=\"lnDur\" oninput=\"document.getElementById('lnDurVal').textContent=this.value+'s'\">\n      <\/div>\n<div>\n<div class=\"ln-label\">Descanso<\/div>\n<div class=\"ln-value\" id=\"lnRestVal\">4s<\/div>\n<p>        <input type=\"range\" min=\"2\" max=\"15\" value=\"4\" class=\"ln-slider\" id=\"lnRest\" oninput=\"document.getElementById('lnRestVal').textContent=this.value+'s'\">\n      <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>  <!-- SELECTOR DESCENDENTE \/ ASCENDENTE --><\/p>\n<div style=\"display:flex;gap:8px;margin-bottom:8px;\">\n    <button class=\"sig-btn active\" id=\"dirDesc\" onclick=\"setNoteDirection('desc',this)\" style=\"flex:1;\">\u2193 Descendente (bemoles)<\/button><br \/>\n    <button class=\"sig-btn\" id=\"dirAsc\" onclick=\"setNoteDirection('asc',this)\" style=\"flex:1;\">\u2191 Ascendente (sostenidos)<\/button>\n  <\/div>\n<div class=\"ln-label\" style=\"margin-bottom:8px;\">Notas seleccionadas:<\/div>\n<div class=\"note-sequence\" id=\"noteSeq\"><\/div>\n<p>  <!-- CONTROLES DE VOLUMEN --><\/p>\n<div style=\"background:var(--dark3);border:1px solid var(--dark4);border-radius:8px;padding:12px 14px;margin-bottom:12px;\">\n<div style=\"font-size:0.6rem;color:var(--text-dim);letter-spacing:2px;margin-bottom:10px;\">\ud83c\udf9a VOL\u00daMENES<\/div>\n<div style=\"display:grid;grid-template-columns:1fr 1fr;gap:14px;\">\n<div>\n<div style=\"display:flex;align-items:center;justify-content:space-between;margin-bottom:5px;\">\n<div style=\"font-size:0.65rem;color:var(--text-dim);letter-spacing:1px;\">\ud83c\udfba TROMPETA<\/div>\n<div style=\"font-family:'Oswald',sans-serif;font-size:0.85rem;color:var(--gold);\" id=\"trumpetVolDisplay\">70%<\/div>\n<\/p><\/div>\n<p>        <input type=\"range\" min=\"0\" max=\"100\" value=\"70\" class=\"ln-slider\" id=\"trumpetVolSlider\" oninput=\"setTrumpetVolume(this.value)\" style=\"accent-color:var(--gold);\">\n      <\/div>\n<div>\n<div style=\"display:flex;align-items:center;justify-content:space-between;margin-bottom:5px;\">\n<div style=\"font-size:0.65rem;color:var(--text-dim);letter-spacing:1px;\">\ud83e\udd41 METR\u00d3NOMO<\/div>\n<div style=\"font-family:'Oswald',sans-serif;font-size:0.85rem;color:var(--gold);\" id=\"metroVolDisplay\">70%<\/div>\n<\/p><\/div>\n<p>        <input type=\"range\" min=\"0\" max=\"100\" value=\"70\" class=\"ln-slider\" id=\"metroVolSlider\" oninput=\"setMetroVolume(this.value)\" style=\"accent-color:var(--gold);\">\n      <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div class=\"btn-row\" style=\"margin-bottom:14px;\">\n    <button class=\"btn btn-outline\" id=\"lnSoundBtn\" onclick=\"toggleLnSound()\">\ud83d\udd07 <span id=\"lnSoundLabel\">Sonido OFF<\/span><\/button><br \/>\n    <button class=\"btn btn-outline\" id=\"lnMetroBtn\" onclick=\"toggleLnMetro()\">\ud83e\udd41 <span id=\"lnMetroLabel\">Metro OFF<\/span><\/button><br \/>\n    <button class=\"btn btn-gold\" id=\"lnBtn\" onclick=\"toggleLongNotes()\">\u25b6 Iniciar<\/button><br \/>\n    <button class=\"btn btn-red\" onclick=\"stopLongNotes()\">\u23f9 Parar<\/button>\n  <\/div>\n<div class=\"sec-title\" style=\"font-size:0.8rem;\">Registro<\/div>\n<div class=\"ln-log\" id=\"lnLog\">\n<div style=\"color:var(--text-dim);\">Sin registros a\u00fan&#8230;<\/div>\n<\/div><\/div>\n<p><!-- fin nlExercisePanel -->\n<\/div>\n<p><!-- fin panel-notas --><\/p>\n<p><!-- VIDEOS --><\/p>\n<div id=\"panel-videos\" class=\"panel\">\n<div class=\"sec-title\">Mis Videos \/ TRUJIZ<\/div>\n<div id=\"videoModules\"><\/div>\n<\/div>\n<p><!-- SESION --><\/p>\n<div id=\"panel-sesion\" class=\"panel\">\n<div class=\"sec-title\">Sesi\u00f3n de Hoy<\/div>\n<div class=\"session-today\">\n<div class=\"session-date\" id=\"sessionDate\"><\/div>\n<div class=\"session-stats\">\n<div class=\"stat-box\">\n<div class=\"stat-val\" id=\"statMin\">0<\/div>\n<div class=\"stat-lbl\">Minutos<\/div>\n<\/div>\n<div class=\"stat-box\">\n<div class=\"stat-val\" id=\"statEx\">0<\/div>\n<div class=\"stat-lbl\">Ejercicios<\/div>\n<\/div>\n<div class=\"stat-box\">\n<div class=\"stat-val\" id=\"statStreak\">1<\/div>\n<div class=\"stat-lbl\">Racha d\u00edas<\/div>\n<\/div><\/div>\n<div class=\"ln-label\" style=\"margin-bottom:6px;\">Notas de la sesi\u00f3n:<\/div>\n<p>    <textarea class=\"notes-area\" id=\"sessionNotes\" placeholder=\"\u00bfC\u00f3mo fue la pr\u00e1ctica de hoy?...\"><\/textarea><br \/>\n    <button class=\"btn btn-gold\" style=\"width:100%\" onclick=\"saveSession()\">\ud83d\udcbe Guardar Sesi\u00f3n<\/button>\n  <\/div>\n<div class=\"sec-title\" style=\"margin-top:4px;\">Historial<\/div>\n<div class=\"history-list\" id=\"historyList\"><\/div>\n<\/div>\n<div class=\"toast\" id=\"toast\"><\/div>\n<p><script>\n\/\/ ============================================================\n\/\/ DATOS\n\/\/ ============================================================\nconst EXERCISES = [\n  {num:1, name:\"Calentamiento de Boquilla\", desc:\"Buzzing libre \/ notas largas\", min:3, icon:\"\ud83d\udc8b\"},\n  {num:2, name:\"Notas Largas Graves\", desc:\"Do2 a Sol2 \/ 8 segundos cada nota\", min:5, icon:\"\ud83c\udfb5\"},\n  {num:3, name:\"Notas Largas Agudas\", desc:\"Sol2 a Do4 \/ afinaci\u00f3n y resonancia\", min:5, icon:\"\ud83c\udfb6\"},\n  {num:4, name:\"Flexibilidad \/ Slurs\", desc:\"Lip slurs por arm\u00f3nicos\", min:5, icon:\"\u301c\"},\n  {num:5, name:\"Picado \/ Redondas\", desc:\"Do \/ Re \/ Mi\u2026 picado simple\", min:4, icon:\"\u2022\"},\n  {num:6, name:\"Picado \/ Blancas y Negras\", desc:\"Redondas \u2192 blancas \u2192 negras\", min:4, icon:\"\u2022\u2022\"},\n  {num:7, name:\"Escalas Mayores \/ 1 oct\", desc:\"Do M \/ Sol M \/ Fa M \/ Re M\", min:4, icon:\"\ud83c\udfbc\"},\n  {num:8, name:\"Escalas Mayores \/ 2 oct\", desc:\"Modulaci\u00f3n y extensi\u00f3n de registro\", min:4, icon:\"\ud83d\udcc8\"},\n  {num:9, name:\"Arpegios\", desc:\"Triadas mayores y menores\", min:4, icon:\"\u2666\"},\n  {num:10, name:\"Repertorio \/ Melod\u00eda\", desc:\"Pieza del d\u00eda a tempo lento\", min:5, icon:\"\ud83c\udfba\"},\n  {num:11, name:\"Enfriamiento\", desc:\"Notas largas suaves \/ descenso gradual\", min:2, icon:\"\u2744\ufe0f\"},\n];<\/p>\n<p>\/\/ Transposici\u00f3n Si\u266d: trompeta suena 1 tono (2 semitonos) m\u00e1s grave que lo escrito\n\/\/ Sol\u2192Fa \/ Fa#\u2192Mi \/ Fa\u2192Mi\u266d \/ Mi\u2192Re \/ Mi\u266d\u2192Re\u266d \/ Re\u2192Do \/ Re\u266d\u2192Si(=Do\u266d) \/ Do\u2192Si\u266d\n\/\/ Si\u2192La \/ Si\u266d\u2192La\u266d \/ La\u2192Sol \/ La\u266d\u2192Sol\u266d \/ Sol2\u2192Fa \/ Sol\u266d\u2192Fa\u266d \/ Fa#2\u2192Mi\n\/\/ Digitaciones:\n\/\/ Sol=0 \/ Fa#=2 \/ Fa=1 \/ Mi=1+2 \/ Mi\u266d=2+3 \/ Re=1+3 \/ Re\u266d=2+3\n\/\/ Do=0 \/ Si=2 \/ Si\u266d=1 \/ La=1+2 \/ La\u266d=2+3 \/ Sol2=1+3 \/ Sol\u266d=1+2+3 \/ Fa#2=2<\/p>\n<p>\/\/ DESCENDENTE \u2014 bemoles al bajar\nconst LN_DESC = [\n  {name:\"Sol\",        real:\"Fa\",   y:52, acc:\"\",  v:[0,0,0]},\n  {name:\"Sol\u266d\",       real:\"Fa\u266d\",  y:52, acc:\"\u266d\", v:[0,1,0]},\n  {name:\"Fa\",         real:\"Mi\u266d\",  y:57, acc:\"\",  v:[1,0,0]},\n  {name:\"Mi\",         real:\"Re\",   y:62, acc:\"\",  v:[1,1,0]},\n  {name:\"Mi\u266d\",        real:\"Re\u266d\",  y:62, acc:\"\u266d\", v:[0,1,1]},\n  {name:\"Re\",         real:\"Do\",   y:67, acc:\"\",  v:[1,0,1]},\n  {name:\"Re\u266d\",        real:\"Si\",   y:67, acc:\"\u266d\", v:[1,1,1]},\n  {name:\"Do\",         real:\"Si\u266d\",  y:72, acc:\"\",  v:[0,0,0]},\n  {name:\"Si\",         real:\"La\",   y:77, acc:\"\",  v:[0,1,0]},\n  {name:\"(Si\u266d\/La#)\",  real:\"La\u266d\",  y:77, acc:\"\u266d\", v:[1,0,0]},\n  {name:\"La\",         real:\"Sol\",  y:82, acc:\"\",  v:[1,1,0]},\n  {name:\"La\u266d\",        real:\"Sol\u266d\", y:82, acc:\"\u266d\", v:[0,1,1]},\n  {name:\"Sol2\",       real:\"Fa\",   y:87, acc:\"\",  v:[1,0,1]},\n  {name:\"Fa#2\",       real:\"Mi\",   y:92, acc:\"\u266f\", v:[1,1,1]},\n];<\/p>\n<p>\/\/ NL2 \u2014 ASCENDENTE con sostenidos, desde Fa#2 grave hasta Sol 2\u00aa l\u00ednea\nconst LN_ASC2 = [\n  {name:\"Fa#2\",       real:\"Mi\",   y:92, acc:\"\u266f\", v:[1,1,1]},\n  {name:\"Sol2\",       real:\"Fa\",   y:87, acc:\"\",  v:[1,0,1]},\n  {name:\"(Sol#\/La\u266d)\", real:\"Fa#\",  y:87, acc:\"\u266f\", v:[0,1,1]},\n  {name:\"La\",         real:\"Sol\",  y:82, acc:\"\",  v:[1,1,0]},\n  {name:\"(La#\/Si\u266d)\",  real:\"Sol#\", y:82, acc:\"\u266f\", v:[0,1,1]},\n  {name:\"Si\",         real:\"La\",   y:77, acc:\"\",  v:[0,1,0]},\n  {name:\"Do\",         real:\"Si\u266d\",  y:72, acc:\"\",  v:[0,0,0]},\n  {name:\"Do#\",        real:\"Si\",   y:72, acc:\"\u266f\", v:[1,1,1]},\n  {name:\"Re\",         real:\"Do\",   y:67, acc:\"\",  v:[1,0,1]},\n  {name:\"(Re#\/Mi\u266d)\",  real:\"Do#\",  y:67, acc:\"\u266f\", v:[0,1,1]},\n  {name:\"Mi\",         real:\"Re\",   y:62, acc:\"\",  v:[1,1,0]},\n  {name:\"Fa\",         real:\"Mi\u266d\",  y:57, acc:\"\",  v:[1,0,0]},\n  {name:\"Fa#\",        real:\"Mi\",   y:57, acc:\"\u266f\", v:[0,1,0]},\n  {name:\"Sol\",        real:\"Fa\",   y:52, acc:\"\",  v:[0,0,0]},\n];<\/p>\n<p>\/\/ Dataset activo (empieza descendente)\nvar LN_NOTES_DATA = LN_DESC.slice();\nvar lnDirection = 'desc';<\/p>\n<p>\/\/ Frecuencias reales (piano) \u2014 trompeta Si\u266d suena -2 semitonos\nconst LN_FREQ = {\n  \/\/ Registro grave\n  \"Sol\":346.0, \"Sol\u266d\":326.0, \"Fa\":308.0,\n  \"Mi\":290.6,  \"Mi\u266d\":274.4,\n  \"Re\":259.0,  \"Re\u266d\":244.6,\n  \"Do\":231.0,  \"Si\":218.0,\n  \"(Si\u266d\/La#)\":205.6, \"La\":194.0, \"La\u266d\":183.0,\n  \"Sol2\":173.0, \"(Sol#\/La\u266d)\":163.5,\n  \"Fa#2\":154.2,\n  \/\/ Registro agudo NL3\/4\/5\n  \"Sol#\":326.0, \"La\":370.0,\n  \"(La#\/Si\u266d)\":392.0, \"Si\":415.3,\n  \"Do#\":466.2, \"Re#\":523.3,\n  \"(Mi\u266d\/Re#)\":493.9, \"(Re\u266d\/Do#)\":466.2,\n  \"(Re\u266d\/Si)\":466.2, \"(Si\u266d\/La#)\":392.0, \"(La\u266d\/Sol#)\":349.2,\n  \"Sol5\":659.3, \"Sol#5\":698.5,\n  \"La5\":740.0, \"Si\u266d5\":784.0,\n  \"Si5\":830.6, \"Do6\":880.0,\n  \"(Sol#\/La\u266d)\":163.5, \"(La#\/Si\u266d)\":183.0, \"(Re#\/Mi\u266d)\":274.4,\n  \"Fa#\":326.0, \"Fa\":308.0, \"Mi\":290.6,\n  \"Sol#A\":366.0\n};<\/p>\n<p>const NOTES_REF = [\n  {n:\"Do\",f:261.6},{n:\"Re\",f:293.7},{n:\"Mi\",f:329.6},{n:\"Fa\",f:349.2},\n  {n:\"Sol\",f:392},{n:\"La\",f:440},{n:\"Si\",f:493.9},{n:\"Do5\",f:523.3},\n  {n:\"Re5\",f:587.3},{n:\"Mi5\",f:659.3},{n:\"Fa5\",f:698.5},{n:\"Sol5\",f:784}\n];\nconst NOTE_NAMES = ['Do','Do#','Re','Re#','Mi','Fa','Fa#','Sol','Sol#','La','La#','Si'];<\/p>\n<p>const VIDEO_MODULES = [\n  {title:\"Rutina Definitiva 45 min\", icon:\"\ud83c\udfaf\", videos:[\n    {id:\"8ik551MZKjU\", title:\"Rutina DEFINITIVA: 11 Ejercicios para Sonido, Resistencia y Flexibilidad\"},\n    {id:\"qaiPk5Y-4v4\", title:\"Tu Rutina Ideal: Conecta Cuerpo y Mente con la Trompeta\"},\n  ]},\n  {title:\"Notas Largas y Afinaci\u00f3n\", icon:\"\ud83c\udfb5\", videos:[\n    {id:\"YHk5eu1gmB0\", title:\"Rutina Diaria de Notas Largas: Rectificaci\u00f3n de Afinaci\u00f3n\"},\n    {id:\"y7ABffVJWqk\", title:\"Mi Rutina Diaria con la Trompeta \u2013 Notas Largas\"},\n  ]},\n  {title:\"M\u00f3dulo 2 \/ Picado y Escalas\", icon:\"\ud83d\udcd8\", videos:[\n    {id:\"P_tBoT49CoA\", title:\"Domina el Picado desde la Base: Redondas a Corcheas\"},\n    {id:\"8FocY35riE0\", title:\"C\u00f3mo Dominar el Picado: Ejercicio 1 \u2013 Redondas a Corcheas\"},\n    {id:\"yuhmAj5jPuE\", title:\"Digitaci\u00f3n para Trompeta \u2013 Escalas Mayores Ejercicio #2\"},\n    {id:\"cbXV14uJOLQ\", title:\"Escalas Mayores Ejercicio #3 | Demostraci\u00f3n 8\u00aa alta\"},\n  ]},\n  {title:\"Rutinas Progresivas\", icon:\"\ud83d\udcc8\", videos:[\n    {id:\"D5cGQjQK9XY\", title:\"Rutina #1 Progresiva Diaria con Boquilla\"},\n    {id:\"uWIsvSQAWFM\", title:\"Rutina #2 Progresiva \u2013 Notas Redondas Ejercicio #1\"},\n    {id:\"1mGSg-MuULs\", title:\"Rutina #3 Progresiva \u2013 Notas Blancas Ejercicio 2\"},\n  ]},\n  {title:\"Tutoriales y Covers\", icon:\"\ud83c\udfba\", videos:[\n    {id:\"kCD-ORX_8w4\", title:\"B\u00e9same Mucho (Bolero) | T\u00f3calo Conmigo + Partitura\"},\n    {id:\"sndR5ytjGEQ\", title:\"La Paloma | C\u00f3mo Tocar Esta Melod\u00eda Cl\u00e1sica\"},\n    {id:\"B03IPLSL-nM\", title:\"La Historia de la Trompeta en Solo 8 Minutos\"},\n  ]},\n];<\/p>\n<p>\/\/ ============================================================\n\/\/ ESTADO GLOBAL\n\/\/ ============================================================\nvar audioCtx = null;<\/p>\n<p>\/\/ Rutina\nvar doneExercises = [];\nvar timerInterval = null;\nvar timerSeconds = 0;\nvar timerTotal = 0;\nvar timerPaused = false;\nvar currentExIdx = null;\nvar sessionMinutes = 0;<\/p>\n<p>\/\/ Rutina metr\u00f3nomo\nvar rutinaMetroActive = false;\nvar rutinaMetroBpm = 80;\nvar rutinaMetroBeats = 4;\nvar rutinaMetroBeat = 0;\nvar rutinaMetroTimeout = null;\nvar rutinaMetroCtx = null;<\/p>\n<p>\/\/ Afinador\nvar tunerActive = false;\nvar tunerStream = null;\nvar tunerAnalyser = null;\nvar tunerAnimId = null;<\/p>\n<p>\/\/ Metr\u00f3nomo principal\nvar metroActive = false;\nvar metroBpm = 80;\nvar metroBeats = 4;\nvar metroBeat = 0;\nvar metroTimeout = null;\nvar metroCtx = null;\nvar tapTimes = [];<\/p>\n<p>\/\/ Notas largas\nvar lnActive = false;\nvar lnInterval = null;\nvar lnNotes = LN_DESC.map(function(n){return n.name;});\nvar lnCurrentIdx = 0;\nvar lnPhase = 'play';\nvar lnElapsed = 0;\nvar lnMetroOn = false;\nvar lnSoundOn = false;\nvar lnBpm = 90;\nvar lnMetroTimeout = null;\nvar lnMetroBeat = 0;\nvar lnMetroCtx = null;\nvar lnSoundNodes = [];\nvar lnSoundGain = null;\nvar trumpetVolume = 0.70;\nvar metroVolume   = 0.70;\nvar lnDirection   = 'desc';<\/p>\n<p>\/\/ ============================================================\n\/\/ INIT\n\/\/ ============================================================\nwindow.onload = function() {\n  renderExercises();\n  renderNoteRef();\n  renderNoteSeq();\n  renderVideoModules();\n  renderHistory();\n  updateSessionDate();\n  updateSessionStats();\n  renderBeatRow();\n  renderRutinaBeatRow();\n  renderLnBeatDots();\n  updateStaff(LN_DESC[0].name);\n  updateNoteCounter();\n  \/\/ Selector visible, ejercicio oculto al inicio\n  document.getElementById('nlModuleSelector').style.display = 'flex';\n  document.getElementById('nlExercisePanel').style.display = 'none';\n};<\/p>\n<p>function showPanel(id, el) {\n  document.querySelectorAll('.panel').forEach(function(p){ p.classList.remove('active'); });\n  document.querySelectorAll('.tab').forEach(function(t){ t.classList.remove('active'); });\n  document.getElementById('panel-'+id).classList.add('active');\n  el.classList.add('active');\n}<\/p>\n<p>function showToast(msg) {\n  var t = document.getElementById('toast');\n  t.textContent = msg;\n  t.classList.add('show');\n  setTimeout(function(){ t.classList.remove('show'); }, 2500);\n}<\/p>\n<p>function getAudioCtx() {\n  if (!audioCtx) audioCtx = new (window.AudioContext||window.webkitAudioContext)();\n  return audioCtx;\n}<\/p>\n<p>function playBeep(freq, dur) {\n  var ctx = getAudioCtx();\n  var osc = ctx.createOscillator();\n  var g = ctx.createGain();\n  osc.frequency.value = freq;\n  g.gain.setValueAtTime(0.3, ctx.currentTime);\n  g.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime+dur);\n  osc.connect(g); g.connect(ctx.destination);\n  osc.start(); osc.stop(ctx.currentTime+dur);\n}<\/p>\n<p>function playClick(ctx, accent) {\n  var vol = (typeof metroVolume !== 'undefined' ? metroVolume : 1.0);\n  var osc = ctx.createOscillator();\n  var g = ctx.createGain();\n  osc.type = 'square';\n  osc.frequency.value = accent ? 1200 : 800;\n  g.gain.setValueAtTime((accent ? 0.4 : 0.2) * vol, ctx.currentTime);\n  g.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime+0.05);\n  osc.connect(g); g.connect(ctx.destination);\n  osc.start(); osc.stop(ctx.currentTime+0.05);\n}<\/p>\n<p>\/\/ ============================================================\n\/\/ RUTINA\n\/\/ ============================================================\nfunction renderExercises() {\n  var list = document.getElementById('exerciseList');\n  list.innerHTML = EXERCISES.map(function(ex,i){\n    return '<\/p>\n<div class=\"exercise-card'+(doneExercises.includes(i)?' done':'')+(currentExIdx===i?' active-ex':'')+'\" onclick=\"startExercise('+i+')\">'\n      +'<\/p>\n<div class=\"ex-num\">'+ex.icon+'<\/div>\n<p>'\n      +'<\/p>\n<div class=\"ex-info\">\n<div class=\"ex-name\">'+ex.num+'. '+ex.name+'<\/div>\n<div class=\"ex-desc\">'+ex.desc+'<\/div>\n<\/div>\n<p>'\n      +'<\/p>\n<div class=\"ex-time\">'+ex.min+' min<\/div>\n<p>'\n      +(doneExercises.includes(i)?'<\/p>\n<div class=\"ex-done-mark\">\u2713<\/div>\n<p>':'')\n      +'<\/p><\/div>\n<p>';\n  }).join('');\n  document.getElementById('doneCount').textContent = doneExercises.length;\n  document.getElementById('totalMin').textContent = doneExercises.reduce(function(a,i){return a+EXERCISES[i].min;},0);\n}<\/p>\n<p>function startExercise(idx) {\n  if (timerInterval) clearInterval(timerInterval);\n  currentExIdx = idx;\n  var ex = EXERCISES[idx];\n  timerTotal = ex.min * 60;\n  timerSeconds = timerTotal;\n  timerPaused = false;\n  document.getElementById('timerBox').style.display = '';\n  document.getElementById('timerExName').textContent = ex.name;\n  updateTimerDisplay();\n  renderExercises();\n  timerInterval = setInterval(tickTimer, 1000);\n  window.scrollTo({top:0,behavior:'smooth'});\n}<\/p>\n<p>function tickTimer() {\n  if (timerPaused) return;\n  timerSeconds--;\n  updateTimerDisplay();\n  if (timerSeconds <= 0) {\n    clearInterval(timerInterval); timerInterval = null;\n    playBeep(880, 0.3);\n    showToast('\u2713 Ejercicio completado');\n    markDone();\n  }\n}\n\nfunction updateTimerDisplay() {\n  var m = Math.floor(timerSeconds\/60).toString().padStart(2,'0');\n  var s = (timerSeconds%60).toString().padStart(2,'0');\n  var d = document.getElementById('timerDisplay');\n  d.textContent = m+':'+s;\n  d.className = 'timer-display'+(timerSeconds<=10?' urgent':'');\n  var pct = timerTotal > 0 ? (timerSeconds\/timerTotal*100) : 0;\n  document.getElementById('timerBar').style.width = pct+'%';\n}<\/p>\n<p>function pauseTimer() { timerPaused = !timerPaused; }<\/p>\n<p>function doStopTimer() {\n  if (timerInterval) clearInterval(timerInterval);\n  timerInterval = null;\n  currentExIdx = null;\n  stopRutinaMetro();\n  document.getElementById('timerBox').style.display = 'none';\n  renderExercises();\n}<\/p>\n<p>function markDone() {\n  if (currentExIdx !== null && !doneExercises.includes(currentExIdx)) {\n    doneExercises.push(currentExIdx);\n    sessionMinutes += EXERCISES[currentExIdx].min;\n    updateSessionStats();\n  }\n  doStopTimer();\n  showToast('\u00a1Ejercicio completado! \ud83c\udfba');\n}<\/p>\n<p>function startNext() {\n  var next = EXERCISES.findIndex(function(_,i){ return !doneExercises.includes(i); });\n  if (next === -1) { showToast('\u00a1Rutina completada! \ud83c\udf89'); return; }\n  startExercise(next);\n}<\/p>\n<p>function resetAll() {\n  doneExercises = []; currentExIdx = null;\n  doStopTimer();\n  renderExercises();\n  showToast('Rutina reiniciada');\n}<\/p>\n<p>\/\/ METRO RUTINA\nfunction renderRutinaBeatRow() {\n  var row = document.getElementById('rutinaBeatRow');\n  if (!row) return;\n  row.innerHTML = Array.from({length:rutinaMetroBeats},function(_,i){\n    var active = i===rutinaMetroBeat && rutinaMetroActive;\n    return '<\/p>\n<div style=\"width:14px;height:14px;border-radius:50%;background:'+(active?'var(--gold)':'var(--dark3)')+';border:2px solid '+(i===0?'var(--gold)':'var(--dark4)')+';transition:background 0.05s;box-shadow:'+(active?'0 0 8px var(--gold)':'none')+'\"><\/div>\n<p>';\n  }).join('');\n}<\/p>\n<p>function toggleRutinaMetro() {\n  if (rutinaMetroActive) stopRutinaMetro(); else startRutinaMetro();\n}<\/p>\n<p>function startRutinaMetro() {\n  if (!rutinaMetroCtx) rutinaMetroCtx = new (window.AudioContext||window.webkitAudioContext)();\n  rutinaMetroActive = true; rutinaMetroBeat = 0;\n  document.getElementById('rutinaMetroBtn').textContent = '\u23f9 Metro';\n  document.getElementById('rutinaMetroBtn').style.borderColor = 'var(--red)';\n  document.getElementById('rutinaMetroBtn').style.color = 'var(--red)';\n  tickRutinaMetro();\n}<\/p>\n<p>function stopRutinaMetro() {\n  rutinaMetroActive = false;\n  if (rutinaMetroTimeout) clearTimeout(rutinaMetroTimeout);\n  rutinaMetroBeat = 0;\n  var btn = document.getElementById('rutinaMetroBtn');\n  if (btn) { btn.textContent = '\u25b6 Metro'; btn.style.borderColor = ''; btn.style.color = ''; }\n  renderRutinaBeatRow();\n}<\/p>\n<p>function tickRutinaMetro() {\n  if (!rutinaMetroActive) return;\n  renderRutinaBeatRow();\n  playClick(rutinaMetroCtx, rutinaMetroBeat===0);\n  rutinaMetroBeat = (rutinaMetroBeat+1) % rutinaMetroBeats;\n  rutinaMetroTimeout = setTimeout(tickRutinaMetro, (60\/rutinaMetroBpm)*1000);\n}<\/p>\n<p>function setRutinaBpm(v) {\n  rutinaMetroBpm = parseInt(v);\n  document.getElementById('rutinaBpmDisplay').textContent = rutinaMetroBpm;\n  document.getElementById('rutinaBpmSlider').value = rutinaMetroBpm;\n  if (rutinaMetroActive) { stopRutinaMetro(); startRutinaMetro(); }\n}<\/p>\n<p>function changeRutinaBpm(d) { setRutinaBpm(Math.max(40,Math.min(220,rutinaMetroBpm+d))); }<\/p>\n<p>function setRutinaTimeSig(beats, btn) {\n  document.querySelectorAll('[id^=\"rsig-\"]').forEach(function(b){ b.classList.remove('active'); });\n  btn.classList.add('active');\n  rutinaMetroBeats = beats; rutinaMetroBeat = 0;\n  renderRutinaBeatRow();\n  if (rutinaMetroActive) { stopRutinaMetro(); startRutinaMetro(); }\n}<\/p>\n<p>\/\/ ============================================================\n\/\/ AFINADOR\n\/\/ ============================================================\nfunction renderNoteRef() {\n  var c = document.getElementById('noteRef');\n  c.innerHTML = NOTES_REF.map(function(n){\n    return '<\/p>\n<div class=\"note-chip\" onclick=\"playRefTone('+n.f+')\">'+n.n+'<span class=\"chip-freq\">'+n.f.toFixed(0)+'Hz<\/span><\/div>\n<p>';\n  }).join('');\n}<\/p>\n<p>function playRefTone(freq) {\n  var ctx = getAudioCtx();\n  var osc = ctx.createOscillator();\n  var g = ctx.createGain();\n  osc.type = 'sine'; osc.frequency.value = freq;\n  g.gain.setValueAtTime(0.3, ctx.currentTime);\n  g.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime+1.5);\n  osc.connect(g); g.connect(ctx.destination);\n  osc.start(); osc.stop(ctx.currentTime+1.5);\n}<\/p>\n<p>async function toggleTuner() {\n  if (tunerActive) { stopTuner(); return; }\n  try {\n    tunerStream = await navigator.mediaDevices.getUserMedia({audio:true});\n    var ctx = getAudioCtx();\n    var source = ctx.createMediaStreamSource(tunerStream);\n    tunerAnalyser = ctx.createAnalyser();\n    tunerAnalyser.fftSize = 8192;\n    source.connect(tunerAnalyser);\n    tunerActive = true;\n    document.getElementById('tunerBtn').textContent = '\ud83d\udd34 Desactivar';\n    document.getElementById('tunerStatus').textContent = 'Escuchando...';\n    analyzePitch();\n  } catch(e) { showToast('No se pudo acceder al micr\u00f3fono'); }\n}<\/p>\n<p>function stopTuner() {\n  tunerActive = false;\n  if (tunerStream) tunerStream.getTracks().forEach(function(t){t.stop();});\n  if (tunerAnimId) cancelAnimationFrame(tunerAnimId);\n  document.getElementById('tunerBtn').textContent = '\ud83c\udf99 Activar Micr\u00f3fono';\n  document.getElementById('tunerNote').textContent = '\u2013';\n  document.getElementById('tunerCents').textContent = '\u2013 \u00a2';\n  document.getElementById('tunerFreq').textContent = '\u2013 Hz';\n  document.getElementById('tunerStatus').textContent = 'Micr\u00f3fono desactivado';\n  document.getElementById('tunerStatus').className = 'tuner-status status-wait';\n  document.getElementById('tunerNeedle').style.left = '50%';\n}<\/p>\n<p>function analyzePitch() {\n  if (!tunerActive) return;\n  var buf = new Float32Array(tunerAnalyser.fftSize);\n  tunerAnalyser.getFloatTimeDomainData(buf);\n  var freq = autoCorrelate(buf, audioCtx.sampleRate);\n  if (freq > 50 && freq < 2000) {\n    var r = freqToNote(freq);\n    document.getElementById('tunerNote').textContent = r.note;\n    document.getElementById('tunerFreq').textContent = freq.toFixed(1)+' Hz';\n    document.getElementById('tunerCents').textContent = (r.cents>=0?'+':'')+r.cents.toFixed(0)+' \u00a2';\n    var pct = 50 + (r.cents\/50)*40;\n    var needle = document.getElementById('tunerNeedle');\n    needle.style.left = Math.max(5,Math.min(95,pct))+'%';\n    var cls='', sc='', st='';\n    if (Math.abs(r.cents)<5) { cls='in-tune'; sc='status-intune'; st='\u2713 AFINADO'; }\n    else if (r.cents>0) { cls='sharp'; sc='status-sharp'; st='\u25b2 ALTO +'+r.cents.toFixed(0)+'\u00a2'; }\n    else { cls='flat'; sc='status-flat'; st='\u25bc BAJO '+r.cents.toFixed(0)+'\u00a2'; }\n    document.getElementById('tunerNote').className = 'tuner-note '+cls;\n    needle.className = 'tuner-needle '+cls;\n    document.getElementById('tunerStatus').textContent = st;\n    document.getElementById('tunerStatus').className = 'tuner-status '+sc;\n  } else {\n    document.getElementById('tunerNote').textContent = '\u2013';\n    document.getElementById('tunerNeedle').style.left = '50%';\n  }\n  tunerAnimId = requestAnimationFrame(analyzePitch);\n}<\/p>\n<p>function autoCorrelate(buf, sr) {\n  var SIZE=buf.length, rms=0;\n  for(var i=0;i<SIZE;i++) rms+=buf[i]*buf[i];\n  rms=Math.sqrt(rms\/SIZE);\n  if(rms<0.01) return -1;\n  var r1=0,r2=SIZE-1,th=0.2;\n  for(var i=0;i<SIZE\/2;i++){if(Math.abs(buf[i])<th){r1=i;break;}}\n  for(var i=1;i<SIZE\/2;i++){if(Math.abs(buf[SIZE-i])<th){r2=SIZE-i;break;}}\n  buf=buf.slice(r1,r2); SIZE=buf.length;\n  var c=new Array(SIZE).fill(0);\n  for(var i=0;i<SIZE;i++) for(var j=0;j<SIZE-i;j++) c[i]+=buf[j]*buf[j+i];\n  var d=0; while(c[d]>c[d+1]) d++;\n  var maxval=-1,maxpos=-1;\n  for(var i=d;i<SIZE;i++){if(c[i]>maxval){maxval=c[i];maxpos=i;}}\n  var T0=maxpos, x1=c[T0-1],x2=c[T0],x3=c[T0+1];\n  var a=(x1+x3-2*x2)\/2, b=(x3-x1)\/2;\n  if(a) T0-=b\/(2*a);\n  return sr\/T0;\n}<\/p>\n<p>function freqToNote(freq) {\n  var A4=440, C0=A4*Math.pow(2,-4.75);\n  var h=12*Math.log2(freq\/C0);\n  var idx=Math.round(h)%12;\n  return {note:NOTE_NAMES[((idx%12)+12)%12], cents:(h-Math.round(h))*100};\n}<\/p>\n<p>\/\/ ============================================================\n\/\/ METRONOMO PRINCIPAL\n\/\/ ============================================================\nfunction renderBeatRow() {\n  var row = document.getElementById('beatRow');\n  if (!row) return;\n  row.innerHTML = Array.from({length:metroBeats},function(_,i){\n    return '<\/p>\n<div class=\"beat-dot'+(i===0?' accent':'')+(i===metroBeat&#038;&#038;metroActive?' active':'')+'\" id=\"beat-'+i+'\"><\/div>\n<p>';\n  }).join('');\n}<\/p>\n<p>function setBpm(v) {\n  metroBpm = parseInt(v);\n  document.getElementById('bpmDisplay').textContent = metroBpm;\n  if (metroActive) { stopMetro(); startMetro(); }\n}<\/p>\n<p>function setBpmPreset(v) {\n  metroBpm = v;\n  document.getElementById('bpmDisplay').textContent = v;\n  document.getElementById('bpmSlider').value = v;\n  if (metroActive) { stopMetro(); startMetro(); }\n}<\/p>\n<p>function setTimeSig(beats, btn) {\n  document.querySelectorAll('.metro-time-sig .sig-btn').forEach(function(b){b.classList.remove('active');});\n  btn.classList.add('active');\n  metroBeats = beats; metroBeat = 0;\n  renderBeatRow();\n  if (metroActive) { stopMetro(); startMetro(); }\n}<\/p>\n<p>function toggleMetro() {\n  if (metroActive) stopMetro(); else startMetro();\n}<\/p>\n<p>function startMetro() {\n  if (!metroCtx) metroCtx = new (window.AudioContext||window.webkitAudioContext)();\n  metroActive = true; metroBeat = 0;\n  document.getElementById('metroBtn').textContent = '\u23f9 Detener';\n  tickMetro();\n}<\/p>\n<p>function stopMetro() {\n  metroActive = false;\n  if (metroTimeout) clearTimeout(metroTimeout);\n  document.getElementById('metroBtn').textContent = '\u25b6 Iniciar';\n  renderBeatRow();\n}<\/p>\n<p>function tickMetro() {\n  if (!metroActive) return;\n  renderBeatRow();\n  playClick(metroCtx, metroBeat===0);\n  metroBeat = (metroBeat+1) % metroBeats;\n  metroTimeout = setTimeout(tickMetro, (60\/metroBpm)*1000);\n}<\/p>\n<p>function tapTempo() {\n  var now = Date.now();\n  tapTimes.push(now);\n  if (tapTimes.length > 6) tapTimes.shift();\n  if (tapTimes.length >= 2) {\n    var diffs=[];\n    for(var i=1;i<tapTimes.length;i++) diffs.push(tapTimes[i]-tapTimes[i-1]);\n    var avg=diffs.reduce(function(a,b){return a+b;},0)\/diffs.length;\n    var bpm=Math.round(60000\/avg);\n    if(bpm>=40&&bpm<=220){\n      metroBpm=bpm;\n      document.getElementById('bpmDisplay').textContent=bpm;\n      document.getElementById('bpmSlider').value=bpm;\n      document.getElementById('tapInfo').textContent='Tap: '+bpm+' BPM';\n      if(metroActive){stopMetro();startMetro();}\n    }\n  } else { document.getElementById('tapInfo').textContent='Sigue tocando...'; }\n}\n\n\/\/ ============================================================\n\/\/ NOTAS LARGAS\n\/\/ ============================================================\nfunction renderNoteSeq() {\n  var c = document.getElementById('noteSeq');\n  c.innerHTML = LN_NOTES_DATA.map(function(nd){\n    var sel = lnNotes.includes(nd.name);\n    return '\n\n<div class=\"note-seq-btn'+(sel?' selected':'')+'\" onclick=\"toggleLnNote(\\''+nd.name+'\\',this)\">'+nd.name.replace('2','\u2082')+'<\/div>\n<p>';\n  }).join('');\n}<\/p>\n<p>function toggleLnNote(note, el) {\n  if (lnNotes.includes(note)) {\n    if (lnNotes.length > 1) { lnNotes = lnNotes.filter(function(n){return n!==note;}); el.classList.remove('selected'); }\n  } else {\n    lnNotes.push(note);\n    lnNotes.sort(function(a,b){ return LN_NOTES_DATA.findIndex(function(x){return x.name===a;}) - LN_NOTES_DATA.findIndex(function(x){return x.name===b;}); });\n    el.classList.add('selected');\n  }\n}<\/p>\n<p>function updateStaff(noteName) {\n  var d = LN_NOTES_DATA.find(function(n){return n.name===noteName;});\n  if (!d) return;\n  var cx=160, cy=d.y;\n  document.getElementById('noteHead').setAttribute('cy', cy);\n  document.getElementById('noteHead').setAttribute('cx', cx);<\/p>\n<p>  \/\/ Accidental \u2014 m\u00e1s grande y separado de la cabeza\n  var acc = document.getElementById('noteAccidental');\n  acc.textContent = d.acc;\n  \/\/ \u266d es m\u00e1s alto visualmente, ajustamos Y seg\u00fan tipo\n  var accY = d.acc === '\u266d' ? cy + 7 : cy + 5;\n  acc.setAttribute('y', accY);\n  \/\/ Separaci\u00f3n: accidental a la izquierda con espacio visible\n  acc.setAttribute('x', d.acc ? '130' : '160');<\/p>\n<p>  \/\/ L\u00edneas adicionales ABAJO\n  document.getElementById('extraLine1').setAttribute('display', cy >= 72 ? '' : 'none');\n  document.getElementById('extraLine2').setAttribute('display', cy >= 82 ? '' : 'none');\n  document.getElementById('extraLine3').setAttribute('display', cy >= 92 ? '' : 'none');<\/p>\n<p>  \/\/ L\u00edneas adicionales ARRIBA (registro agudo)\n  var topLine = d.topLine || 0;\n  document.getElementById('extraLineTop1').setAttribute('display', topLine >= 1 ? '' : 'none');\n  document.getElementById('extraLineTop2').setAttribute('display', topLine >= 2 ? '' : 'none');<\/p>\n<p>  \/\/ Plica: notas agudas (y < 42, encima de 3\u00aa l\u00ednea) \u2192 plica IZQUIERDA ABAJO\n  var stem = document.getElementById('noteStem');\n  if (cy < 42) {\n    stem.setAttribute('x1', cx-9); stem.setAttribute('x2', cx-9);\n    stem.setAttribute('y1', cy+1); stem.setAttribute('y2', cy+30);\n  } else {\n    stem.setAttribute('x1', cx+9); stem.setAttribute('x2', cx+9);\n    stem.setAttribute('y1', cy-1); stem.setAttribute('y2', cy-30);\n  }\n\n  var label = noteName.replace(\/2$|5$|6$\/g,'');\n  document.getElementById('staffLabel').textContent = label;\n  \/\/ Nombre trompeta grande a la derecha\n  var el = document.getElementById('trumpetNoteName');\n  if (el) el.textContent = label;\n  document.getElementById('realPitchName').textContent = d.real;\n\n  ['v1','v2','v3'].forEach(function(id, i){\n    var el = document.getElementById(id);\n    if (d.v[i]) {\n      el.style.background='var(--gold)'; el.style.borderColor='var(--gold)';\n      el.style.color='var(--dark)'; el.style.fontWeight='700';\n    } else {\n      el.style.background='var(--dark4)'; el.style.borderColor='var(--dark4)';\n      el.style.color='var(--text-dim)'; el.style.fontWeight='400';\n    }\n  });\n  var pressed = [];\n  if(d.v[0]) pressed.push('1');\n  if(d.v[1]) pressed.push('2');\n  if(d.v[2]) pressed.push('3');\n  document.getElementById('fingeringText').textContent = pressed.length ? pressed.join('+') : '0 (aire)';\n}\n\n\/\/ NL2 \u2014 ASCENDENTE con sostenidos, desde Fa#2 grave hasta Sol 2\u00aa l\u00ednea\n\/\/ NL3 \u2014 ASCENDENTE registro agudo, Sol 2\u00aa l\u00ednea \u2192 Sol agudo (sostenidos)\nconst LN_ASC3 = [\n  {name:\"Sol\",      real:\"Fa\",    y:52, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Sol#\",     real:\"Fa#\",   y:52, acc:\"\u266f\", v:[0,1,1], topLine:0},\n  {name:\"La\",       real:\"Sol\",   y:47, acc:\"\",  v:[1,1,0], topLine:0},\n  {name:\"(La#\/Si\u266d)\",real:\"Sol#\",  y:47, acc:\"\u266f\", v:[1,0,0], topLine:0},\n  {name:\"Si\",       real:\"La\",    y:42, acc:\"\",  v:[0,1,0], topLine:0},\n  {name:\"Do\",       real:\"Si\u266d\",   y:37, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Do#\",      real:\"Si\",    y:37, acc:\"\u266f\", v:[1,1,0], topLine:0},\n  {name:\"Re\",       real:\"Do\",    y:32, acc:\"\",  v:[1,0,0], topLine:0},\n  {name:\"Re#\",      real:\"Do#\",   y:32, acc:\"\u266f\", v:[0,1,0], topLine:0},\n  {name:\"Mi\",       real:\"Re\",    y:27, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Fa\",       real:\"Mi\u266d\",   y:22, acc:\"\",  v:[1,0,0], topLine:0},\n  {name:\"Fa#\",      real:\"Mi\",    y:22, acc:\"\u266f\", v:[0,1,0], topLine:0},\n  {name:\"Sol5\",     real:\"Fa5\",   y:17, acc:\"\",  v:[0,0,0], topLine:0},\n];\n\n\/\/ NL4 \u2014 DESCENDENTE registro agudo (bemoles), Sol agudo \u2192 Sol 2\u00aa l\u00ednea\nconst LN_DESC4 = [\n  {name:\"Sol5\",     real:\"Fa5\",   y:17, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Fa#\",      real:\"Mi\",    y:22, acc:\"\u266f\", v:[0,1,0], topLine:0},\n  {name:\"Fa\",       real:\"Mi\u266d\",   y:22, acc:\"\",  v:[1,0,0], topLine:0},\n  {name:\"Mi\",       real:\"Re\",    y:27, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"(Mi\u266d\/Re#)\",real:\"Re\u266d\",   y:27, acc:\"\u266d\", v:[0,1,0], topLine:0},\n  {name:\"Re\",       real:\"Do\",    y:32, acc:\"\",  v:[1,0,0], topLine:0},\n  {name:\"(Re\u266d\/Do#)\",real:\"Si\",    y:32, acc:\"\u266d\", v:[1,1,0], topLine:0},\n  {name:\"Do\",       real:\"Si\u266d\",   y:37, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Si\",       real:\"La\",    y:42, acc:\"\",  v:[0,1,0], topLine:0},\n  {name:\"(Si\u266d\/La#)\",real:\"La\u266d\",   y:47, acc:\"\u266d\", v:[1,0,0], topLine:0},\n  {name:\"La\",       real:\"Sol\",   y:47, acc:\"\",  v:[1,1,0], topLine:0},\n  {name:\"Sol#\",     real:\"Fa#\",   y:52, acc:\"\u266f\", v:[0,1,1], topLine:0},\n  {name:\"Sol\",      real:\"Fa\",    y:52, acc:\"\",  v:[0,0,0], topLine:0},\n];\n\n\/\/ NL5 \u2014 ASCENDENTE Sol 2\u00aa l\u00ednea \u2192 Do sobreagudo (avanzado)\nconst LN_ASC5 = [\n  {name:\"Sol\",       real:\"Fa\",    y:52, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Sol#\",      real:\"Fa#\",   y:52, acc:\"\u266f\", v:[0,1,1], topLine:0},\n  {name:\"La\",        real:\"Sol\",   y:47, acc:\"\",  v:[1,1,0], topLine:0},\n  {name:\"(La#\/Si\u266d)\", real:\"Sol#\",  y:47, acc:\"\u266f\", v:[1,0,0], topLine:0},\n  {name:\"Si\",        real:\"La\",    y:42, acc:\"\",  v:[0,1,0], topLine:0},\n  {name:\"Do\",        real:\"Si\u266d\",   y:37, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Do#\",       real:\"Si\",    y:37, acc:\"\u266f\", v:[1,1,0], topLine:0},\n  {name:\"Re\",        real:\"Do\",    y:32, acc:\"\",  v:[1,0,0], topLine:0},\n  {name:\"Re#\",       real:\"Do#\",   y:32, acc:\"\u266f\", v:[0,1,0], topLine:0},\n  {name:\"Mi\",        real:\"Re\",    y:27, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Fa\",        real:\"Mi\u266d\",   y:22, acc:\"\",  v:[1,0,0], topLine:0},\n  {name:\"Fa#\",       real:\"Mi\",    y:22, acc:\"\u266f\", v:[0,1,0], topLine:0},\n  {name:\"Sol5\",      real:\"Fa5\",   y:17, acc:\"\",  v:[0,0,0], topLine:0},\n  {name:\"Sol#5\",     real:\"Fa#5\",  y:17, acc:\"\u266f\", v:[0,1,1], topLine:0},\n  {name:\"La5\",        real:\"Sol5\",  y:12, acc:\"\",  v:[1,1,0], topLine:1},\n  {name:\"Si\u266d5\",       real:\"La\u266d5\",  y:12, acc:\"\u266d\", v:[1,0,0], topLine:1},\n  {name:\"Si5\",        real:\"La5\",   y:7,  acc:\"\",  v:[0,1,0], topLine:1},\n  {name:\"Do6\",        real:\"Si\u266d5\",  y:2,  acc:\"\",  v:[0,0,0], topLine:2},\n];\n\nvar currentNLModule = 1;\n\nfunction loadNLModule(num) {\n  currentNLModule = num;\n  var datasets = [null, LN_DESC, LN_ASC2, LN_ASC3, LN_DESC4, LN_ASC5];\n  var titles = ['','NL 1 \/ DESCENDENTE','NL 2 \/ ASCENDENTE','NL 3 \/ ASCENDENTE AGUDO','NL 4 \/ DESCENDENTE AGUDO','NL 5 \/ SOL \u2192 DO SOBREAGUDO \u26a0\ufe0f'];\n  LN_NOTES_DATA = datasets[num].slice();\n  document.getElementById('nlModuleTitle').textContent = titles[num];\n  \/\/ Actualizar estilos m\u00f3dulos\n  for (var i=1; i<=5; i++) {\n    var el = document.getElementById('nlmod'+i);\n    if (!el) continue;\n    var isActive = i===num;\n    var isTeal = i>=3;\n    el.style.background = isActive ? (isTeal?'var(--teal)':'var(--gold)') : 'var(--dark3)';\n    el.style.color = isActive ? 'var(--dark)' : 'var(--text)';\n    el.style.borderColor = isActive ? (isTeal?'var(--teal)':'var(--gold)') : (isTeal?'var(--teal-dim)':'var(--dark4)');\n  }\n  lnNotes = LN_NOTES_DATA.map(function(n){return n.name;});\n  lnCurrentIdx=0; lnPhase='play'; lnElapsed=0;\n  if (lnActive) stopLongNotes();\n  renderNoteSeq();\n  updateStaff(lnNotes[0]);\n  updateNoteCounter();\n  document.getElementById('nlModuleSelector').style.display = 'none';\n  document.getElementById('nlExercisePanel').style.display = 'block';\n}<\/p>\n<p>function backToNLModules() {\n  if (lnActive) stopLongNotes();\n  document.getElementById('nlModuleSelector').style.display = 'flex';\n  document.getElementById('nlExercisePanel').style.display = 'none';\n}<\/p>\n<p>function setNoteDirection(dir, btn) {\n  lnDirection = dir;\n  document.getElementById('dirDesc').classList.toggle('active', dir==='desc');\n  document.getElementById('dirAsc').classList.toggle('active', dir==='asc');\n  LN_NOTES_DATA = dir==='desc' ? LN_DESC.slice() : LN_ASC2.slice();\n  lnNotes = LN_NOTES_DATA.map(function(n){return n.name;});\n  lnCurrentIdx=0; lnPhase='play'; lnElapsed=0;\n  if(lnActive) stopLongNotes();\n  renderNoteSeq();\n  updateStaff(lnNotes[0]);\n  updateNoteCounter();\n}<\/p>\n<p>\/\/ Sonido s\u00edntesis trompeta \u2014 m\u00e9todo robusto con envelope ADSR\nfunction playTrumpetNote(noteName) {\n  if (!lnSoundOn) return;\n  stopTrumpetNote();\n  var ctx = getAudioCtx();\n  \/\/ Buscar frecuencia \u2014 primero exacta, luego por nombre limpio\n  var freq = LN_FREQ[noteName];\n  if (!freq) {\n    \/\/ Intentar con nombre sin par\u00e9ntesis y sin accidentales\n    var clean = noteName.replace(\/[()\/]\/g,'').split('\/')[0].trim();\n    freq = LN_FREQ[clean];\n  }\n  if (!freq) freq = 346.0; \/\/ fallback Sol<\/p>\n<p>  \/\/ Ganancia master con envelope de ataque suave + volumen regulable\n  var targetGain = 0.22 * trumpetVolume;\n  if (targetGain < 0.001) targetGain = 0.001;\n  lnSoundGain = ctx.createGain();\n  lnSoundGain.gain.setValueAtTime(0.001, ctx.currentTime);\n  lnSoundGain.gain.exponentialRampToValueAtTime(targetGain, ctx.currentTime + 0.08);\n  lnSoundGain.gain.setValueAtTime(targetGain, ctx.currentTime + 0.08);\n  lnSoundGain.connect(ctx.destination);\n\n  lnSoundNodes = [];\n\n  \/\/ Osciladores con arm\u00f3nicos para timbre de trompeta\n  \/\/ Fundamental + 2\u00ba + 3\u00ba + 4\u00ba + 5\u00ba arm\u00f3nico con amplitudes ajustadas\n  var harmonics = [\n    {mult:1,   amp:0.6,  type:'sawtooth'},\n    {mult:2,   amp:0.35, type:'sawtooth'},\n    {mult:3,   amp:0.25, type:'sawtooth'},\n    {mult:4,   amp:0.15, type:'square'},\n    {mult:5,   amp:0.08, type:'square'},\n    {mult:6,   amp:0.04, type:'sine'},\n  ];\n\n  harmonics.forEach(function(h){\n    var osc = ctx.createOscillator();\n    var g   = ctx.createGain();\n    osc.type = h.type;\n    osc.frequency.value = freq * h.mult;\n    g.gain.value = h.amp;\n    osc.connect(g);\n    g.connect(lnSoundGain);\n    osc.start(ctx.currentTime);\n    lnSoundNodes.push(osc);\n  });\n}\n\nfunction stopTrumpetNote() {\n  if (!lnSoundNodes.length) return;\n  var ctx = audioCtx;\n  if (lnSoundGain &#038;&#038; ctx) {\n    try {\n      lnSoundGain.gain.cancelScheduledValues(ctx.currentTime);\n      lnSoundGain.gain.setValueAtTime(lnSoundGain.gain.value, ctx.currentTime);\n      lnSoundGain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.1);\n    } catch(e) {}\n  }\n  var nodes = lnSoundNodes.slice();\n  lnSoundNodes = [];\n  setTimeout(function(){\n    nodes.forEach(function(o){ try{ o.stop(); }catch(e){} });\n  }, 130);\n}\n\nfunction toggleLnSound() {\n  lnSoundOn = !lnSoundOn;\n  document.getElementById('lnSoundLabel').textContent = lnSoundOn ? 'Sonido ON' : 'Sonido OFF';\n  document.getElementById('lnSoundBtn').style.borderColor = lnSoundOn ? 'var(--green)' : '';\n  document.getElementById('lnSoundBtn').style.color = lnSoundOn ? 'var(--green)' : '';\n  if (!lnSoundOn) stopTrumpetNote();\n}\n\nfunction setTrumpetVolume(v) {\n  trumpetVolume = parseInt(v) \/ 100;\n  document.getElementById('trumpetVolDisplay').textContent = v + '%';\n  \/\/ Actualiza en tiempo real si hay nota sonando\n  if (lnSoundGain &#038;&#038; audioCtx) {\n    var tgt = 0.22 * trumpetVolume;\n    try { lnSoundGain.gain.setTargetAtTime(tgt < 0.001 ? 0.001 : tgt, audioCtx.currentTime, 0.05); } catch(e) {}\n  }\n}\n\nfunction setMetroVolume(v) {\n  metroVolume = parseInt(v) \/ 100;\n  document.getElementById('metroVolDisplay').textContent = v + '%';\n}\n\n\/\/ Metro notas largas\nfunction renderLnBeatDots() {\n  var row = document.getElementById('lnBeatDots');\n  if (!row) return;\n  row.innerHTML = Array.from({length:4},function(_,i){\n    var active = i===lnMetroBeat &#038;&#038; lnMetroOn;\n    return '\n\n<div style=\"width:10px;height:10px;border-radius:50%;background:'+(active?'var(--gold)':'var(--dark4)')+';border:1px solid '+(i===0?'var(--gold)':'var(--dark4)')+';transition:background 0.05s;\"><\/div>\n<p>';\n  }).join('');\n}<\/p>\n<p>function lnSetBpm(v) {\n  lnBpm = parseInt(v);\n  document.getElementById('lnBpmDisplay').textContent = lnBpm;\n  document.getElementById('lnBpmSlider').value = lnBpm;\n  if (lnMetroOn) { stopLnMetro(); startLnMetro(); }\n}<\/p>\n<p>function lnChangeBpm(d) { lnSetBpm(Math.max(40,Math.min(160,lnBpm+d))); }<\/p>\n<p>function startLnMetro() {\n  stopLnMetro();\n  if (!lnMetroCtx) lnMetroCtx = new (window.AudioContext||window.webkitAudioContext)();\n  lnMetroBeat = 0;\n  function tick() {\n    if (!lnMetroOn) return;\n    renderLnBeatDots();\n    playClick(lnMetroCtx, lnMetroBeat===0);\n    lnMetroBeat = (lnMetroBeat+1) % 4;\n    lnMetroTimeout = setTimeout(tick, (60\/lnBpm)*1000);\n  }\n  tick();\n}<\/p>\n<p>function stopLnMetro() {\n  if (lnMetroTimeout) clearTimeout(lnMetroTimeout);\n  lnMetroBeat = 0;\n  renderLnBeatDots();\n}<\/p>\n<p>function toggleLnMetro() {\n  lnMetroOn = !lnMetroOn;\n  document.getElementById('lnMetroLabel').textContent = lnMetroOn ? 'Metro ON' : 'Metro OFF';\n  document.getElementById('lnMetroBtn').style.borderColor = lnMetroOn ? 'var(--gold)' : '';\n  document.getElementById('lnMetroBtn').style.color = lnMetroOn ? 'var(--gold)' : '';\n  if (lnActive) { if (lnMetroOn) startLnMetro(); else stopLnMetro(); }\n}<\/p>\n<p>\/\/ L\u00f3gica principal notas largas\nfunction toggleLongNotes() {\n  if (lnActive) { pauseLongNotes(); return; }\n  lnActive = true; lnCurrentIdx = 0; lnPhase = 'play'; lnElapsed = 0;\n  document.getElementById('lnBtn').textContent = '\u23f8 Pausar';\n  if (lnMetroOn) startLnMetro();\n  runLnStep();\n}<\/p>\n<p>function pauseLongNotes() {\n  lnActive = false;\n  if (lnInterval) clearInterval(lnInterval);\n  stopTrumpetNote(); stopLnMetro();\n  document.getElementById('lnBtn').textContent = '\u25b6 Reanudar';\n}<\/p>\n<p>function stopLongNotes() {\n  lnActive = false;\n  if (lnInterval) clearInterval(lnInterval);\n  stopTrumpetNote(); stopLnMetro();\n  lnCurrentIdx=0; lnPhase='play'; lnElapsed=0;\n  document.getElementById('lnBtn').textContent = '\u25b6 Iniciar';\n  document.getElementById('lnPhaseLabel').textContent = '\u23f1 TOCA AHORA';\n  document.getElementById('lnPhaseLabel').style.color = 'var(--gold)';\n  document.getElementById('lnTimer').textContent = '00:00';\n  document.getElementById('lnProgressBar').style.width = '0%';\n  document.getElementById('lnTimerPanel').style.borderColor = 'var(--dark4)';\n  updateStaff(lnNotes[0]); renderNoteSeq(); updateNoteCounter();\n}<\/p>\n<p>function runLnStep() {\n  if (!lnActive) return;\n  var dur = parseInt(document.getElementById('lnDur').value);\n  var rest = parseInt(document.getElementById('lnRest').value);\n  var note = lnNotes[lnCurrentIdx];\n  var total = lnPhase==='play' ? dur : rest;\n  lnElapsed = 0;\n  var ph = document.getElementById('lnPhaseLabel');\n  var panel = document.getElementById('lnTimerPanel');\n  if (lnPhase==='play') {\n    ph.textContent = '\ud83c\udfb5 TOCA: '+note;\n    ph.style.color = 'var(--gold)';\n    panel.style.borderColor = 'var(--gold)';\n    updateStaff(note);\n    playTrumpetNote(note);\n    updateNoteCounter();\n  } else {\n    ph.textContent = '\ud83d\ude2e DESCANSO';\n    ph.style.color = 'var(--text-dim)';\n    panel.style.borderColor = 'var(--dark4)';\n    stopTrumpetNote();\n  }\n  document.querySelectorAll('.note-seq-btn').forEach(function(btn,i){\n    btn.classList.toggle('current-playing', lnPhase==='play' && LN_NOTES_DATA[i] && LN_NOTES_DATA[i].name===note);\n  });\n  if (lnInterval) clearInterval(lnInterval);\n  lnInterval = setInterval(function(){\n    lnElapsed++;\n    var rem = total-lnElapsed;\n    document.getElementById('lnTimer').textContent = Math.floor(rem\/60).toString().padStart(2,'0')+':'+(rem%60).toString().padStart(2,'0');\n    document.getElementById('lnProgressBar').style.width = ((lnElapsed\/total)*100)+'%';\n    if (lnElapsed >= total) {\n      clearInterval(lnInterval);\n      if (lnPhase==='play') {\n        addLnLog(note, dur);\n        lnPhase='rest'; runLnStep();\n      } else {\n        lnPhase='play';\n        lnCurrentIdx=(lnCurrentIdx+1)%lnNotes.length;\n        if(lnCurrentIdx===0){ showToast('\u00a1Ronda completa! \ud83c\udfba'); playBeep(660,0.3); }\n        runLnStep();\n      }\n    }\n  }, 1000);\n}<\/p>\n<p>\/\/ NAVEGACI\u00d3N: nota anterior \/ siguiente\nfunction jumpNote(dir) {\n  if (lnInterval) clearInterval(lnInterval);\n  stopTrumpetNote();<\/p>\n<p>  var newIdx = lnCurrentIdx + dir;\n  if (newIdx < 0) newIdx = lnNotes.length - 1;\n  if (newIdx >= lnNotes.length) newIdx = 0;\n  lnCurrentIdx = newIdx;\n  lnPhase = 'play';\n  lnElapsed = 0;<\/p>\n<p>  updateStaff(lnNotes[lnCurrentIdx]);\n  updateNoteCounter();<\/p>\n<p>  document.getElementById('lnTimer').textContent = '00:00';\n  document.getElementById('lnProgressBar').style.width = '0%';\n  document.getElementById('lnPhaseLabel').textContent = '\ud83c\udfb5 TOCA: ' + lnNotes[lnCurrentIdx];\n  document.getElementById('lnPhaseLabel').style.color = 'var(--gold)';\n  document.getElementById('lnTimerPanel').style.borderColor = 'var(--gold)';<\/p>\n<p>  document.querySelectorAll('.note-seq-btn').forEach(function(btn, i){\n    btn.classList.toggle('current-playing', LN_NOTES_DATA[i] && LN_NOTES_DATA[i].name === lnNotes[lnCurrentIdx]);\n  });<\/p>\n<p>  playTrumpetNote(lnNotes[lnCurrentIdx]);<\/p>\n<p>  if (lnActive) {\n    runLnStep();\n  }\n}<\/p>\n<p>function updateNoteCounter() {\n  var noteName = lnNotes[lnCurrentIdx] || '\u2013';\n  var disp = document.getElementById('lnCurrentNoteDisplay');\n  var ctr  = document.getElementById('lnNoteCounter');\n  if (disp) disp.textContent = noteName.replace('2','\u2082');\n  if (ctr)  ctr.textContent  = (lnCurrentIdx + 1) + ' \/ ' + lnNotes.length;\n}<\/p>\n<p>function addLnLog(note, dur) {\n  var log = document.getElementById('lnLog');\n  if (log.firstChild && log.firstChild.textContent.includes('Sin registros')) log.innerHTML='';\n  var entry = document.createElement('div');\n  entry.className = 'ln-log-entry';\n  var now = new Date();\n  var d = LN_NOTES_DATA.find(function(n){return n.name===note;});\n  entry.textContent = now.getHours().toString().padStart(2,'0')+':'+now.getMinutes().toString().padStart(2,'0')+' \u2014 '+note+' (suena '+( d?d.real:'?')+') \/ '+dur+'s';\n  log.insertBefore(entry, log.firstChild);\n}<\/p>\n<p>\/\/ ============================================================\n\/\/ VIDEOS\n\/\/ ============================================================\nfunction renderVideoModules() {\n  var c = document.getElementById('videoModules');\n  c.innerHTML = VIDEO_MODULES.map(function(mod,mi){\n    return '<\/p>\n<div class=\"video-module\">'\n      +'<\/p>\n<div class=\"video-module-header\" onclick=\"toggleModule('+mi+')\">'\n      +'<\/p>\n<div class=\"vm-icon\">'+mod.icon+'<\/div>\n<p>'\n      +'<\/p>\n<div class=\"vm-info\">\n<div class=\"vm-title\">'+mod.title+'<\/div>\n<div class=\"vm-count\">'+mod.videos.length+' video'+(mod.videos.length>1?'s':'')+'<\/div>\n<\/div>\n<p>'\n      +'<\/p>\n<div class=\"vm-arrow\" id=\"vmarrow-'+mi+'\">\u25b6<\/div>\n<p>'\n      +'<\/p><\/div>\n<p>'\n      +'<\/p>\n<div class=\"video-list\" id=\"vmlist-'+mi+'\">'\n      +mod.videos.map(function(v){\n        return '<a class=\"video-item\" href=\"https:\/\/youtu.be\/'+v.id+'\" target=\"_blank\">'\n          +'<img decoding=\"async\" class=\"video-thumb\" src=\"https:\/\/i.ytimg.com\/vi\/'+v.id+'\/mqdefault.jpg\" alt=\"\" loading=\"lazy\">'\n          +'<\/p>\n<div class=\"video-item-title\">'+v.title+'<br \/><span class=\"yt-badge\">\u25b6 YouTube<\/span><\/div>\n<p><\/a>';\n      }).join('')\n      +'<\/div>\n<\/div>\n<p>';\n  }).join('');\n}<\/p>\n<p>function toggleModule(mi) {\n  document.getElementById('vmlist-'+mi).classList.toggle('open');\n  document.getElementById('vmarrow-'+mi).classList.toggle('open');\n}<\/p>\n<p>\/\/ ============================================================\n\/\/ SESION\n\/\/ ============================================================\nfunction updateSessionDate() {\n  document.getElementById('sessionDate').textContent =\n    new Date().toLocaleDateString('es-ES',{weekday:'long',year:'numeric',month:'long',day:'numeric'}).toUpperCase();\n}<\/p>\n<p>function updateSessionStats() {\n  document.getElementById('statMin').textContent = sessionMinutes;\n  document.getElementById('statEx').textContent = doneExercises.length;\n}<\/p>\n<p>function saveSession() {\n  var notes = document.getElementById('sessionNotes').value;\n  var d = new Date(), key = 'session_'+d.toISOString().split('T')[0];\n  try { localStorage.setItem(key, JSON.stringify({date:d.toISOString().split('T')[0], minutes:sessionMinutes, exercises:doneExercises.length, notes:notes})); } catch(e){}\n  renderHistory(); showToast('\u2713 Sesi\u00f3n guardada');\n}<\/p>\n<p>function renderHistory() {\n  var c = document.getElementById('historyList'), sessions=[];\n  try {\n    for(var i=0;i<localStorage.length;i++){\n      var k=localStorage.key(i);\n      if(k&#038;&#038;k.startsWith('session_')){ try{sessions.push(JSON.parse(localStorage.getItem(k)));}catch(e){} }\n    }\n  } catch(e){}\n  sessions.sort(function(a,b){return b.date.localeCompare(a.date);});\n  if(!sessions.length){ c.innerHTML='\n\n<div style=\"color:var(--text-dim);font-size:0.75rem;padding:12px\">Sin historial a\u00fan<\/div>\n<p>'; return; }\n  c.innerHTML=sessions.slice(0,10).map(function(s){\n    return '<\/p>\n<div class=\"history-item\">\n<div class=\"h-date\">'+s.date+'<\/div>\n<div class=\"h-info\">'+s.exercises+' ejercicios \/ '+(s.notes?s.notes.substring(0,40)+'...':'Sin notas')+'<\/div>\n<div class=\"h-min\">'+s.minutes+'m<\/div>\n<\/div>\n<p>';\n  }).join('');\n  document.getElementById('statStreak').textContent = Math.min(sessions.length,7);\n}\n<\/script><br \/>\n<\/body><br \/>\n<\/html><\/p>\n ","protected":false},"excerpt":{"rendered":"<p>TrujizBand \u2013 Estudio de Trompeta \ud83c\udfba TrujizBand M\u00c9TODO DE ESTUDIO Afinador Notas Largas Metr\u00f3nomo Mis Videos Sesi\u00f3n Rutina Rutina Definitiva \/ 45 min Ejercicio Activo \u2013 \u23f1 TIEMPO 00:00 \ud83e\udd41 BPM \u2212 80 + BPM 4\/4 3\/4 2\/4 \u25b6 Metro \u23f8 Pausar \u23f9 Parar \u2713 Listo Progreso sesi\u00f3n: 0 \/ 11 ejercicios \/ 0 min&hellip;&nbsp;<a href=\"https:\/\/www.trujiz.com\/en\/app-trujizband\/\" class=\"\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">App TrujizBand<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"class_list":["post-9999","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>App TrujizBand | Trujiz<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.trujiz.com\/en\/app-trujizband\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"App TrujizBand | Trujiz\" \/>\n<meta property=\"og:description\" content=\"TrujizBand \u2013 Estudio de Trompeta \ud83c\udfba TrujizBand M\u00c9TODO DE ESTUDIO Afinador Notas Largas Metr\u00f3nomo Mis Videos Sesi\u00f3n Rutina Rutina Definitiva \/ 45 min Ejercicio Activo \u2013 \u23f1 TIEMPO 00:00 \ud83e\udd41 BPM \u2212 80 + BPM 4\/4 3\/4 2\/4 \u25b6 Metro \u23f8 Pausar \u23f9 Parar \u2713 Listo Progreso sesi\u00f3n: 0 \/ 11 ejercicios \/ 0 min&hellip;&nbsp;Read More &raquo;App TrujizBand\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.trujiz.com\/en\/app-trujizband\/\" \/>\n<meta property=\"og:site_name\" content=\"Trujiz\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/trujizz\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i.ytimg.com\/vi\/'+v.id+'\/mqdefault.jpg\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/\",\"url\":\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/\",\"name\":\"App TrujizBand | Trujiz\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i.ytimg.com\\\/vi\\\/'+v.id+'\\\/mqdefault.jpg\",\"datePublished\":\"2026-06-03T16:51:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i.ytimg.com\\\/vi\\\/'+v.id+'\\\/mqdefault.jpg\",\"contentUrl\":\"https:\\\/\\\/i.ytimg.com\\\/vi\\\/'+v.id+'\\\/mqdefault.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/app-trujizband\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/www.trujiz.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"App TrujizBand\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/#website\",\"url\":\"https:\\\/\\\/www.trujiz.com\\\/\",\"name\":\"Trujiz\",\"description\":\"Trujiz\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/#\\\/schema\\\/person\\\/6def9be4eed82cf36143304279b29cfa\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.trujiz.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/#\\\/schema\\\/person\\\/6def9be4eed82cf36143304279b29cfa\",\"name\":\"Administraci\u00f3n\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/Barner-pagina-web-trujiz.png\",\"url\":\"https:\\\/\\\/www.trujiz.com\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/Barner-pagina-web-trujiz.png\",\"contentUrl\":\"https:\\\/\\\/www.trujiz.com\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/Barner-pagina-web-trujiz.png\",\"width\":1200,\"height\":628,\"caption\":\"Administraci\u00f3n\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.trujiz.com\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/Barner-pagina-web-trujiz.png\"},\"description\":\"Guillermo Trujillo , conocido art\u00edsticamente como Trujiz , es m\u00fasico cubano, trompetista, escritor y pintor afincado en Espa\u00f1a. Su obra fusiona la m\u00fasica afrocubana con el jazz, la literatura \u00edntima y el arte visual vibrante. Ha trabajado en proyectos internacionales, grabado discos. y creado colecciones art\u00edsticas que transmiten paz, emoci\u00f3n y sabidur\u00eda. En este sitio comparte su universo creativo con quienes buscan inspiraci\u00f3n, belleza y conexi\u00f3n profunda con el arte.\",\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/trujizz\",\"https:\\\/\\\/www.instagram.com\\\/trujiz\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/guillermo-trujiz-10560245\\\/\",\"https:\\\/\\\/www.pinterest.es\\\/trujizband\\\/boards\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UC931ZASROBZxweib0kvmA5Q?view_as=subscriber\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"App TrujizBand | Trujiz","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.trujiz.com\/en\/app-trujizband\/","og_locale":"en_US","og_type":"article","og_title":"App TrujizBand | Trujiz","og_description":"TrujizBand \u2013 Estudio de Trompeta \ud83c\udfba TrujizBand M\u00c9TODO DE ESTUDIO Afinador Notas Largas Metr\u00f3nomo Mis Videos Sesi\u00f3n Rutina Rutina Definitiva \/ 45 min Ejercicio Activo \u2013 \u23f1 TIEMPO 00:00 \ud83e\udd41 BPM \u2212 80 + BPM 4\/4 3\/4 2\/4 \u25b6 Metro \u23f8 Pausar \u23f9 Parar \u2713 Listo Progreso sesi\u00f3n: 0 \/ 11 ejercicios \/ 0 min&hellip;&nbsp;Read More &raquo;App TrujizBand","og_url":"https:\/\/www.trujiz.com\/en\/app-trujizband\/","og_site_name":"Trujiz","article_publisher":"https:\/\/www.facebook.com\/trujizz","og_image":[{"url":"https:\/\/i.ytimg.com\/vi\/'+v.id+'\/mqdefault.jpg","type":"","width":"","height":""}],"twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.trujiz.com\/app-trujizband\/","url":"https:\/\/www.trujiz.com\/app-trujizband\/","name":"App TrujizBand | Trujiz","isPartOf":{"@id":"https:\/\/www.trujiz.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.trujiz.com\/app-trujizband\/#primaryimage"},"image":{"@id":"https:\/\/www.trujiz.com\/app-trujizband\/#primaryimage"},"thumbnailUrl":"https:\/\/i.ytimg.com\/vi\/'+v.id+'\/mqdefault.jpg","datePublished":"2026-06-03T16:51:53+00:00","breadcrumb":{"@id":"https:\/\/www.trujiz.com\/app-trujizband\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.trujiz.com\/app-trujizband\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.trujiz.com\/app-trujizband\/#primaryimage","url":"https:\/\/i.ytimg.com\/vi\/'+v.id+'\/mqdefault.jpg","contentUrl":"https:\/\/i.ytimg.com\/vi\/'+v.id+'\/mqdefault.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.trujiz.com\/app-trujizband\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/www.trujiz.com\/"},{"@type":"ListItem","position":2,"name":"App TrujizBand"}]},{"@type":"WebSite","@id":"https:\/\/www.trujiz.com\/#website","url":"https:\/\/www.trujiz.com\/","name":"Trujiz","description":"Trujiz","publisher":{"@id":"https:\/\/www.trujiz.com\/#\/schema\/person\/6def9be4eed82cf36143304279b29cfa"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.trujiz.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.trujiz.com\/#\/schema\/person\/6def9be4eed82cf36143304279b29cfa","name":"Administraci\u00f3n","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.trujiz.com\/wp-content\/uploads\/2025\/03\/Barner-pagina-web-trujiz.png","url":"https:\/\/www.trujiz.com\/wp-content\/uploads\/2025\/03\/Barner-pagina-web-trujiz.png","contentUrl":"https:\/\/www.trujiz.com\/wp-content\/uploads\/2025\/03\/Barner-pagina-web-trujiz.png","width":1200,"height":628,"caption":"Administraci\u00f3n"},"logo":{"@id":"https:\/\/www.trujiz.com\/wp-content\/uploads\/2025\/03\/Barner-pagina-web-trujiz.png"},"description":"Guillermo Trujillo , conocido art\u00edsticamente como Trujiz , es m\u00fasico cubano, trompetista, escritor y pintor afincado en Espa\u00f1a. Su obra fusiona la m\u00fasica afrocubana con el jazz, la literatura \u00edntima y el arte visual vibrante. Ha trabajado en proyectos internacionales, grabado discos. y creado colecciones art\u00edsticas que transmiten paz, emoci\u00f3n y sabidur\u00eda. En este sitio comparte su universo creativo con quienes buscan inspiraci\u00f3n, belleza y conexi\u00f3n profunda con el arte.","sameAs":["https:\/\/www.facebook.com\/trujizz","https:\/\/www.instagram.com\/trujiz\/","https:\/\/www.linkedin.com\/in\/guillermo-trujiz-10560245\/","https:\/\/www.pinterest.es\/trujizband\/boards\/","https:\/\/www.youtube.com\/channel\/UC931ZASROBZxweib0kvmA5Q?view_as=subscriber"]}]}},"_links":{"self":[{"href":"https:\/\/www.trujiz.com\/en\/wp-json\/wp\/v2\/pages\/9999","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.trujiz.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.trujiz.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.trujiz.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.trujiz.com\/en\/wp-json\/wp\/v2\/comments?post=9999"}],"version-history":[{"count":0,"href":"https:\/\/www.trujiz.com\/en\/wp-json\/wp\/v2\/pages\/9999\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.trujiz.com\/en\/wp-json\/wp\/v2\/media?parent=9999"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}