← banjotuna

Enhance fretboard generator with notes at each fret position

f804cfdc0db4233ff89451b7a0315fbe4c962339 · Claude · Feb 1, 2026 00:17

Integrated features from Python fretboard generator script:
- Added 5 more tunings (24 total): Open G Low G, Standard C, D Tuning Reno, Plectrum C, Tenor
- Implemented getNoteAtFret() calculation showing notes at every fret position
- Added proper display note mapping: Ab/Bb (flats) but C#/D#/F# (sharps)
- Enhanced SVG fretboard with:
  - Notes displayed at each fret intersection (toggleable)
  - 5th string starts at fret 6 with proper effective fret calculation
  - Peg indicator for 5th string tuning point
  - Diagonal neck edge transition
  - Ghost/dotted line for 5th string from nut to fret 5
  - Fret markers with symbols (star at 5, double dots at 12)
  - Ordinal fret labels on right side (3rd fret, 5th fret, etc.)
- Added 4-string banjo support with "Other" family category
- Added "Show notes on fretboard" toggle control
- Footer with string position and fret marker legend

https://claude.ai/code/session_01JfA4LA5EzCPiZHbWJ2kyvj

+487 −251 · 1 file changed

  • index.html +487 −251
diff --git a/index.html b/index.html
index e7d71b3..44cd561 100644
--- a/index.html
+++ b/index.html
@@ -15,6 +15,8 @@
             --d-family-light: #E3F5E9;
             --g-family: #2E5C8A;
             --g-family-light: #E3EEF8;
+            --other-family: #7B5BA6;
+            --other-family-light: #F0E8F5;
             --text-primary: #1a1a1a;
             --text-secondary: #444;
             --text-muted: #666;
@@ -216,6 +218,23 @@
             min-width: 50px;
         }
 
+        /* Checkbox toggle for notes */
+        .checkbox-container {
+            display: flex;
+            align-items: center;
+            gap: 8px;
+        }
+
+        .checkbox-container input[type="checkbox"] {
+            width: 18px;
+            height: 18px;
+            cursor: pointer;
+        }
+
+        .checkbox-container span {
+            font-size: 14px;
+        }
+
         /* Buttons */
         .btn {
             padding: 10px 20px;
@@ -277,6 +296,7 @@
         .family-intro.c-family-intro { border-color: var(--c-family); }
         .family-intro.d-family-intro { border-color: var(--d-family); }
         .family-intro.g-family-intro { border-color: var(--g-family); }
+        .family-intro.other-family-intro { border-color: var(--other-family); }
 
         /* ============================================
            TUNINGS GRID
@@ -320,6 +340,11 @@
             background: linear-gradient(to bottom, var(--g-family-light) 0%, #F8FBFE 100%);
         }
 
+        .tuning-card.other-family {
+            border-color: var(--other-family);
+            background: linear-gradient(to bottom, var(--other-family-light) 0%, #FDFBFE 100%);
+        }
+
         .tuning-header {
             display: flex;
             justify-content: space-between;
@@ -332,6 +357,7 @@
         .c-family .tuning-header { border-color: var(--c-family); }
         .d-family .tuning-header { border-color: var(--d-family); }
         .g-family .tuning-header { border-color: var(--g-family); }
+        .other-family .tuning-header { border-color: var(--other-family); }
 
         .tuning-name {
             font-size: 16px;
@@ -345,6 +371,16 @@
             color: var(--text-muted);
         }
 
+        .string-count-badge {
+            display: inline-block;
+            background: #666;
+            color: white;
+            font-size: 10px;
+            padding: 2px 6px;
+            border-radius: 3px;
+            margin-left: 8px;
+        }
+
         .note-sequence {
             font-family: 'Courier New', Consolas, monospace;
             font-size: 20px;
@@ -629,8 +665,8 @@
         <!-- Header -->
         <header class="app-header">
             <h1>INTERACTIVE BANJO TUNINGS REFERENCE</h1>
-            <div class="subtitle">19 Essential Tunings with Octave Notation, Capo Simulation & Fretboard Diagrams</div>
-            <div class="subtitle">5-String Banjo | Organized by Tuning Family</div>
+            <div class="subtitle">24 Tunings with Fretboard Note Charts, Capo Simulation & SVG Diagrams</div>
+            <div class="subtitle">5-String & 4-String Banjo | Organized by Tuning Family</div>
         </header>
 
         <!-- Control Panel -->
@@ -642,6 +678,7 @@
                     <option value="c-family">C-Based Tunings</option>
                     <option value="d-family">D-Based Tunings</option>
                     <option value="g-family">G-Based Tunings</option>
+                    <option value="other-family">Other (4-String)</option>
                 </select>
             </div>
 
@@ -660,13 +697,10 @@
             </div>
 
             <div class="control-group">
-                <label>Notation</label>
-                <div class="toggle-container">
-                    <span class="toggle-label" id="notationLabel">Sharps</span>
-                    <label class="toggle-switch">
-                        <input type="checkbox" id="notationToggle">
-                        <span class="toggle-slider"></span>
-                    </label>
+                <label>Options</label>
+                <div class="checkbox-container">
+                    <input type="checkbox" id="showNotesToggle" checked>
+                    <span>Show notes on fretboard</span>
                 </div>
             </div>
 
@@ -693,7 +727,8 @@
                 Notes shown with Scientific Pitch Notation (SPN) subscripts (e.g., G&#8324; = G above middle C)<br>
                 String order: 5th (drone) &#8594; 4th &#8594; 3rd &#8594; 2nd &#8594; 1st<br>
                 &#916; symbol = changes required from reference tuning | &#8593; = tune up | &#8595; = tune down<br>
-                Circle Key: &#9675; = Standard Open String | &#9679; = Changed String
+                Circle Key: &#9675; = Standard Open String | &#9679; = Changed String<br>
+                Display uses mixed notation: Ab, Bb (flats) but C#, D#, F# (sharps) for musical convention
             </div>
 
             <div id="tuningsContainer"></div>
@@ -702,8 +737,9 @@
         <!-- Fretboards Tab -->
         <div id="fretboards-tab" class="tab-content">
             <div class="reference-box">
-                <strong>FRETBOARD DIAGRAMS:</strong>
-                Select a tuning below to view its fretboard diagram. The 5th string starts at fret 5 (shown with diagonal neck edge).
+                <strong>FRETBOARD NOTE CHARTS:</strong>
+                Select a tuning below to view its complete fretboard diagram with notes at every fret position.<br>
+                5th string starts at fret 6 (shown with diagonal neck edge and peg indicator).<br>
                 Fret markers: &#9679; at frets 3, 7, 10, 15, 17 | &#9733; at fret 5 | &#9679;&#9679; at fret 12
             </div>
 
@@ -840,7 +876,7 @@
             </div>
 
             <div class="legend">
-                Complete Banjo Tunings Reference | 19 Tunings Across 3 Families<br>
+                Complete Banjo Tunings Reference | 24 Tunings Across 4 Families<br>
                 Symbols: &#8593; = tune up | &#8595; = tune down | &#916; = change from reference | SPN = Scientific Pitch Notation<br>
                 &#11088; = Most common | &#9888; = Requires special consideration (string tension, setup)
             </div>
@@ -849,146 +885,229 @@
 
     <script>
         // ============================================
-        // TUNINGS DATA
+        // CHROMATIC SCALE & NOTE UTILITIES
+        // ============================================
+        const CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
+
+        // Normalize note names (flats to sharps, handle case)
+        const NOTE_MAP = {
+            'c': 'C', 'c#': 'C#', 'db': 'C#', 'Db': 'C#',
+            'd': 'D', 'd#': 'D#', 'eb': 'D#', 'Eb': 'D#',
+            'e': 'E', 'fb': 'E', 'Fb': 'E',
+            'f': 'F', 'e#': 'F', 'E#': 'F', 'f#': 'F#', 'gb': 'F#', 'Gb': 'F#',
+            'g': 'G', 'g#': 'G#', 'ab': 'G#', 'Ab': 'G#',
+            'a': 'A', 'a#': 'A#', 'bb': 'A#', 'Bb': 'A#',
+            'b': 'B', 'cb': 'B', 'Cb': 'B', 'b#': 'C', 'B#': 'C',
+            'C': 'C', 'C#': 'C#', 'D': 'D', 'D#': 'D#', 'E': 'E',
+            'F': 'F', 'F#': 'F#', 'G': 'G', 'G#': 'G#', 'A': 'A', 'A#': 'A#', 'B': 'B'
+        };
+
+        // Display note mapping - prefer flats for G# and A# (as per user's Python script)
+        const DISPLAY_NOTE_MAP = {
+            'G#': 'Ab',
+            'A#': 'Bb'
+            // Keep D#, C#, F# as sharps
+        };
+
+        function normalizeNote(note) {
+            return NOTE_MAP[note] || note.toUpperCase();
+        }
+
+        function displayNote(note) {
+            // Convert internal sharp note to preferred display (mix of flats and sharps)
+            if (DISPLAY_NOTE_MAP[note]) {
+                return DISPLAY_NOTE_MAP[note];
+            }
+            return note;
+        }
+
+        function getNoteAtFret(openNote, fret) {
+            const normalized = normalizeNote(openNote);
+            const startIndex = CHROMATIC_SCALE.indexOf(normalized);
+            if (startIndex === -1) return openNote;
+            const newIndex = (startIndex + fret) % 12;
+            return CHROMATIC_SCALE[newIndex];
+        }
+
+        // ============================================
+        // TUNINGS DATA (24 tunings including 4-string)
         // ============================================
         const TUNINGS_DATA = {
             // C-Based Tunings
             "Minstrel Tuning": {
-                strings: ["F4", "C2", "F3", "A3", "C4"],
+                strings: ["f", "C", "F", "A", "C"],
                 family: "c-family",
                 description: "Historical",
                 referenceTuning: "Standard F",
                 deltaChanges: "From Standard F: 4th↓C",
                 capoPositions: { 0: "Not commonly capoed" },
                 songs: "Briggs manual, Coon Hunt",
-                changedStrings: [true, true, true, true, true]
+                changedStrings: [true, true, true, true, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Naomi Weiss": {
-                strings: ["G4", "C2", "G3", "A3", "D4"],
+                strings: ["g", "C", "G", "A", "D"],
                 family: "c-family",
                 description: "Song-Specific",
                 referenceTuning: "Minstrel",
                 deltaChanges: "From Minstrel: 5th↑G, 3rd↑G, 2nd→A (same), 1st↑D",
                 capoPositions: { 2: "Key of D" },
                 songs: '"Naomi Weiss"',
-                changedStrings: [false, false, true, false, true]
+                changedStrings: [false, false, true, false, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Little Birdie": {
-                strings: ["E4", "C2", "G3", "A3", "D4"],
+                strings: ["e", "C", "G", "A", "D"],
                 family: "c-family",
                 description: "Appalachian",
                 referenceTuning: "Naomi Weiss",
                 deltaChanges: "From Naomi Weiss: 5th↓E",
                 capoPositions: { 2: "Key of F# (uncommon)" },
                 songs: '"Little Birdie"',
-                changedStrings: [true, false, false, false, false]
+                changedStrings: [true, false, false, false, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Hook-and-Line": {
-                strings: ["G4", "C2", "G3", "C4", "D4"],
+                strings: ["g", "C", "G", "C", "D"],
                 family: "c-family",
                 description: "Open C Variant",
                 referenceTuning: "Little Birdie",
                 deltaChanges: "From Little Birdie: 5th↑G, 2nd↑C",
                 capoPositions: { 2: "Key of D", 5: "Key of F" },
                 songs: '"Hook and Line"',
-                changedStrings: [true, false, false, true, false]
+                changedStrings: [true, false, false, true, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
-            "Cackling Hen (Open C)": {
-                strings: ["G4", "C2", "G3", "C4", "E4"],
+            "Cackling Hen": {
+                strings: ["g", "C", "G", "C", "E"],
                 family: "c-family",
                 description: "Open C Major",
                 referenceTuning: "Hook-and-Line",
                 deltaChanges: "From Hook-and-Line: 1st↑E",
                 capoPositions: { 0: "Key of C", 2: "Key of D" },
                 songs: "Open C tuning, Irish/Celtic",
-                changedStrings: [false, false, false, false, true]
+                changedStrings: [false, false, false, false, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
-            "Darling Cora (Triple C)": {
-                strings: ["G4", "C2", "G3", "C4", "C4"],
+            "Darling Cora": {
+                strings: ["g", "C", "G", "C", "C"],
                 family: "c-family",
-                description: "Drone Heavy",
+                description: "Drone Heavy (Triple C)",
                 referenceTuning: "Cackling Hen",
                 deltaChanges: "From Cackling Hen: 1st↓C",
                 capoPositions: { 2: "Key of D", 5: "Key of F" },
                 songs: '"Darling Cora"',
-                changedStrings: [false, false, false, false, true]
+                changedStrings: [false, false, false, false, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Double C": {
-                strings: ["G4", "C2", "G3", "C4", "D4"],
+                strings: ["g", "C", "G", "C", "D"],
                 family: "c-family",
                 description: "Old-Time Standard",
                 referenceTuning: "Open G",
                 deltaChanges: "From Open G: 4th↓C, 2nd↑C",
                 capoPositions: { 2: "Key of D", 5: "Key of F" },
                 songs: "Wildwood Flower, Billy in the Lowground",
-                changedStrings: [false, true, false, true, false]
+                changedStrings: [false, true, false, true, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
+            },
+            "Standard C": {
+                strings: ["g", "C", "G", "B", "D"],
+                family: "c-family",
+                description: "C Tuning for Old-Time",
+                referenceTuning: "Open G",
+                deltaChanges: "From Open G: 4th↓C",
+                capoPositions: { 2: "Key of D", 5: "Key of F" },
+                songs: "Old-time repertoire",
+                changedStrings: [false, true, false, false, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
 
             // D-Based Tunings
             "Moonshiner": {
-                strings: ["G4", "D3", "G3", "A3", "D4"],
+                strings: ["g", "D", "G", "A", "D"],
                 family: "d-family",
                 description: "Modal/Dark",
                 referenceTuning: "Standard F",
                 deltaChanges: "From Standard F: 4th↑D, 3rd↑G, 2nd→A (same), 1st↑D",
                 capoPositions: { 2: "Key of A", 5: "Key of C" },
                 songs: '"Moonshiner"',
-                changedStrings: [false, true, false, true, true]
+                changedStrings: [false, true, false, true, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "German War": {
-                strings: ["G4", "D3", "G3", "A3", "F#4"],
+                strings: ["g", "D", "G", "A", "F#"],
                 family: "d-family",
                 description: "Historical",
                 referenceTuning: "Moonshiner",
                 deltaChanges: "From Moonshiner: 1st↓F#",
                 capoPositions: { 2: "Key of A (modal)" },
                 songs: "German war songs",
-                changedStrings: [false, false, false, false, true]
+                changedStrings: [false, false, false, false, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Reuben": {
-                strings: ["G4", "D3", "F#3", "A3", "F#4"],
+                strings: ["g", "D", "F#", "A", "F#"],
                 family: "d-family",
                 description: "Song-Specific",
                 referenceTuning: "German War",
                 deltaChanges: "From German War: 3rd↓F#",
                 capoPositions: { 2: "Key of A (modal)" },
                 songs: '"Reuben"',
-                changedStrings: [false, false, true, false, false]
+                changedStrings: [false, false, true, false, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
-            "F Tuning (Cumberland Gap)": {
-                strings: ["F4", "D3", "G3", "C4", "D4"],
+            "F Tuning": {
+                strings: ["f", "D", "G", "C", "D"],
                 family: "d-family",
-                description: "High Tension",
+                description: "Cumberland Gap",
                 referenceTuning: "Reuben",
                 deltaChanges: "From Reuben: 5th↓F, 3rd↑G, 2nd↑C, 1st↑D",
                 capoPositions: { 2: "Key of G", 5: "Key of Bb" },
                 songs: "Cumberland Gap, Drunkard's Doom",
-                changedStrings: [true, false, true, true, true]
+                changedStrings: [true, false, true, true, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "East Virginia": {
-                strings: ["F4", "F3", "G3", "C4", "D4"],
+                strings: ["f", "F", "G", "C", "D"],
                 family: "d-family",
                 description: "George Gibson Style",
                 referenceTuning: "F Tuning",
                 deltaChanges: "From F Tuning: 4th↑F",
                 capoPositions: { 2: "Key of G", 5: "Key of Bb" },
                 songs: "George Gibson style",
-                changedStrings: [false, true, false, false, false]
+                changedStrings: [false, true, false, false, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
 
             // G-Based Tunings
-            "Standard F": {
-                strings: ["F4", "C3", "F3", "A3", "C4"],
+            "Standard (F)": {
+                strings: ["f", "C", "F", "A", "C"],
                 family: "g-family",
-                description: "Historical Starting Point",
+                description: "Historical Reference",
                 referenceTuning: null,
                 deltaChanges: "(Reference tuning for historical context)",
                 capoPositions: { 2: "Key of G", 5: "Key of Bb" },
                 songs: "General playing, historical reference",
-                changedStrings: [false, false, false, false, false]
+                changedStrings: [false, false, false, false, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Open G": {
-                strings: ["G4", "D3", "G3", "B3", "D4"],
+                strings: ["g", "D", "G", "B", "D"],
                 family: "g-family",
                 description: "Bluegrass Standard",
                 referenceTuning: null,
@@ -996,10 +1115,24 @@
                 capoPositions: { 2: "Key of A", 5: "Key of C", 7: "Key of D" },
                 songs: "Bill Cheatum, Old Joe Clark, Cripple Creek",
                 changedStrings: [true, true, true, true, true],
-                featured: true
+                featured: true,
+                shortStringIndex: 0,
+                shortStringStartFret: 6
+            },
+            "Open G (Low G)": {
+                strings: ["G", "D", "G", "B", "D"],
+                family: "g-family",
+                description: "Open G with Low 5th",
+                referenceTuning: "Open G",
+                deltaChanges: "From Open G: 5th↓G (one octave lower)",
+                capoPositions: { 2: "Key of A", 5: "Key of C" },
+                songs: "Low drone sound",
+                changedStrings: [true, false, false, false, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Open A": {
-                strings: ["A4", "E4", "A4", "C#4", "E4"],
+                strings: ["a", "E", "A", "C#", "E"],
                 family: "g-family",
                 description: "High Tension",
                 referenceTuning: "Open G",
@@ -1007,58 +1140,99 @@
                 capoPositions: { 2: "Key of B", 5: "Key of D" },
                 songs: "Tunes in A key - requires light gauge strings!",
                 changedStrings: [true, true, true, true, true],
-                warning: true
+                warning: true,
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "G Variant": {
-                strings: ["G4", "D3", "G3", "A3", "D4"],
+                strings: ["g", "D", "G", "A", "D"],
                 family: "g-family",
                 description: "Modal G",
                 referenceTuning: "Open G",
                 deltaChanges: "From Open G: 2nd↓A",
                 capoPositions: { 2: "Key of A", 5: "Key of C" },
                 songs: "Leather Britches, Texas, Frosty Morning",
-                changedStrings: [false, false, false, true, false]
+                changedStrings: [false, false, false, true, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "G Modal (Sawmill)": {
-                strings: ["G4", "D3", "G3", "C4", "D4"],
+                strings: ["g", "D", "G", "C", "D"],
                 family: "g-family",
                 description: "Mountain/Modal",
                 referenceTuning: "Open G",
                 deltaChanges: "From Open G: 2nd↑C",
                 capoPositions: { 2: "Key of A", 5: "Key of C" },
                 songs: "Modal tunes, F key songs",
-                changedStrings: [false, false, false, true, false]
+                changedStrings: [false, false, false, true, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "Open D": {
-                strings: ["A4", "D4", "F#4", "A4", "D4"],
+                strings: ["a", "D", "F#", "A", "D"],
                 family: "g-family",
-                description: "Blues/Folk",
+                description: "Blues/Folk (Graveyard)",
                 referenceTuning: "Open G",
-                deltaChanges: "From Open G: all strings ↑2 frets (whole step)",
+                deltaChanges: "From Open G: all strings adjusted for D major",
                 capoPositions: { 2: "Key of E", 3: "Key of F", 5: "Key of G" },
                 songs: 'Most D key tunes, "Graveyard Tuning" - use light strings!',
                 changedStrings: [true, true, true, true, true],
-                warning: true
+                warning: true,
+                shortStringIndex: 0,
+                shortStringStartFret: 6
             },
             "D Modal": {
-                strings: ["A4", "D4", "G4", "A4", "D4"],
+                strings: ["a", "D", "G", "A", "D"],
                 family: "g-family",
                 description: "Celtic/Medieval",
                 referenceTuning: "Open D",
                 deltaChanges: "From Open D: 3rd↓G",
                 capoPositions: { 2: "Key of E (modal)", 5: "Key of G (modal)" },
                 songs: "D modal tunes, medieval tonality",
-                changedStrings: [false, false, true, false, false]
-            }
-        };
+                changedStrings: [false, false, true, false, false],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
+            },
+            "D Tuning (Reno)": {
+                strings: ["a", "D", "G", "B", "E"],
+                family: "g-family",
+                description: "Don Reno Style",
+                referenceTuning: "Open G",
+                deltaChanges: "From Open G: 5th↑A, 1st↑E",
+                capoPositions: { 2: "Key of E", 5: "Key of G" },
+                songs: "Don Reno repertoire",
+                changedStrings: [true, false, false, false, true],
+                shortStringIndex: 0,
+                shortStringStartFret: 6
+            },
 
-        // Note conversion maps
-        const NOTE_ORDER = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
-        const SHARP_TO_FLAT = {
-            'C#': 'Db', 'D#': 'Eb', 'F#': 'Gb', 'G#': 'Ab', 'A#': 'Bb'
-        };
-        const FLAT_TO_SHARP = {
-            'Db': 'C#', 'Eb': 'D#', 'Gb': 'F#', 'Ab': 'G#', 'Bb': 'A#'
+            // Other / 4-String Tunings
+            "Plectrum C": {
+                strings: ["C", "G", "B", "D"],
+                family: "other-family",
+                description: "4-String Plectrum",
+                referenceTuning: null,
+                deltaChanges: "(4-string plectrum standard)",
+                capoPositions: { 0: "Key of C" },
+                songs: "Jazz, Dixieland",
+                changedStrings: [false, false, false, false],
+                shortStringIndex: null,
+                shortStringStartFret: null,
+                stringCount: 4
+            },
+            "Tenor (Standard)": {
+                strings: ["C", "G", "D", "A"],
+                family: "other-family",
+                description: "4-String Tenor CGDA",
+                referenceTuning: null,
+                deltaChanges: "(4-string tenor standard - fifths tuning)",
+                capoPositions: { 0: "Key of C/G" },
+                songs: "Irish, Jazz, Traditional",
+                changedStrings: [false, false, false, false],
+                shortStringIndex: null,
+                shortStringStartFret: null,
+                stringCount: 4
+            }
         };
 
         // ============================================
@@ -1068,11 +1242,10 @@
             familyFilter: 'all',
             capoPosition: 0,
             fretCount: 15,
-            useFlats: false,
+            showNotes: true,
             selectedFretboardTuning: 'Open G'
         };
 
-        // Load from localStorage
         function loadState() {
             const saved = localStorage.getItem('banjoTuningsState');
             if (saved) {
@@ -1085,77 +1258,53 @@
             }
         }
 
-        // Save to localStorage
         function saveState() {
             localStorage.setItem('banjoTuningsState', JSON.stringify(state));
         }
 
         // ============================================
-        // NOTE UTILITIES
+        // NOTE FORMATTING
         // ============================================
-        function parseNote(noteStr) {
-            const match = noteStr.match(/^([A-G][#b]?)(\d)$/);
+        function parseNoteWithOctave(noteStr) {
+            // Handle format like "G4", "C#3", "g" (lowercase = high octave)
+            const match = noteStr.match(/^([A-Ga-g][#b]?)(\d)?$/);
             if (!match) return null;
-            return { note: match[1], octave: parseInt(match[2]) };
-        }
-
-        function formatNote(noteStr, useFlats = false) {
-            const parsed = parseNote(noteStr);
-            if (!parsed) return noteStr;
-
-            let note = parsed.note;
 
-            // Normalize to sharps first
-            if (FLAT_TO_SHARP[note]) {
-                note = FLAT_TO_SHARP[note];
-            }
+            let note = match[1];
+            let octave = match[2] ? parseInt(match[2]) : null;
 
-            // Convert to flats if needed
-            if (useFlats && SHARP_TO_FLAT[note]) {
-                note = SHARP_TO_FLAT[note];
+            // Lowercase note = high octave (convention from Python script)
+            if (note === note.toLowerCase() && !octave) {
+                octave = 4; // High octave for 5th string
+            } else if (!octave) {
+                octave = 3; // Default octave
             }
 
-            // Replace # with sharp symbol and b with flat symbol
-            note = note.replace('#', '\u266F').replace('b', '\u266D');
-
-            return `${note}<sub>${parsed.octave}</sub>`;
+            return { note: normalizeNote(note), octave };
         }
 
-        function transposeNote(noteStr, semitones) {
-            const parsed = parseNote(noteStr);
+        function formatNoteForDisplay(noteStr) {
+            const parsed = parseNoteWithOctave(noteStr);
             if (!parsed) return noteStr;
 
-            let note = parsed.note;
-            let octave = parsed.octave;
-
-            // Normalize to sharps
-            if (FLAT_TO_SHARP[note]) {
-                note = FLAT_TO_SHARP[note];
-            }
-
-            let noteIndex = NOTE_ORDER.indexOf(note);
-            if (noteIndex === -1) return noteStr;
-
-            noteIndex += semitones;
+            let note = displayNote(parsed.note);
+            // Replace # with sharp symbol, b with flat symbol
+            note = note.replace('#', '\u266F').replace('b', '\u266D');
 
-            // Handle octave changes
-            while (noteIndex >= 12) {
-                noteIndex -= 12;
-                octave++;
-            }
-            while (noteIndex < 0) {
-                noteIndex += 12;
-                octave--;
-            }
+            return `${note}<sub>${parsed.octave}</sub>`;
+        }
 
-            return NOTE_ORDER[noteIndex] + octave;
+        function formatSimpleNote(note) {
+            // Format a simple note (no octave) for fretboard display
+            const displayed = displayNote(normalizeNote(note));
+            return displayed.replace('#', '\u266F').replace('b', '\u266D');
         }
 
         // ============================================
         // RENDERING FUNCTIONS
         // ============================================
-        function renderNoteSequence(strings, useFlats) {
-            return strings.map(s => formatNote(s, useFlats)).join(' ');
+        function renderNoteSequence(strings) {
+            return strings.map(s => formatNoteForDisplay(s)).join(' ');
         }
 
         function renderCapoInfo(capoPositions) {
@@ -1164,41 +1313,33 @@
                 .join(' | ');
         }
 
-        function renderEffectiveTuning(strings, capoPosition, useFlats) {
-            if (capoPosition === 0) return null;
-
-            const transposed = strings.map(s => transposeNote(s, capoPosition));
-            return transposed.map(s => formatNote(s, useFlats)).join(' ');
-        }
-
         function renderTuningCard(name, tuning) {
-            const effectiveTuning = renderEffectiveTuning(tuning.strings, state.capoPosition, state.useFlats);
-            const warningClass = tuning.warning ? 'warning' : '';
             const featuredBadge = tuning.featured ? ' &#11088;' : '';
             const warningBadge = tuning.warning ? ' &#9888;' : '';
+            const stringCount = tuning.stringCount || 5;
+            const stringBadge = stringCount === 4 ? '<span class="string-count-badge">4-string</span>' : '';
+
+            // Render nut visual
+            const nutVisual = tuning.changedStrings.map((changed, i) => {
+                const stringNum = stringCount - i;
+                return `<div class="string-circle ${changed ? 'changed' : ''}">${stringNum}</div>`;
+            }).join('');
 
             return `
                 <div class="tuning-card ${tuning.family}">
                     <div class="tuning-header">
-                        <span class="tuning-name">${name}${featuredBadge}${warningBadge}</span>
+                        <span class="tuning-name">${name}${featuredBadge}${warningBadge}${stringBadge}</span>
                         <span class="genre-tag">${tuning.description}</span>
                     </div>
-                    <div class="note-sequence">${renderNoteSequence(tuning.strings, state.useFlats)}</div>
+                    <div class="note-sequence">${renderNoteSequence(tuning.strings)}</div>
                     <div class="nut-visual">
-                        ${tuning.changedStrings.map((changed, i) =>
-                            `<div class="string-circle ${changed ? 'changed' : ''}">${5 - i}</div>`
-                        ).join('')}
+                        ${nutVisual}
                     </div>
                     <div class="tuning-details">
                         <div class="delta-line">&#916;: ${tuning.deltaChanges}</div>
                         <div class="capo-line">${renderCapoInfo(tuning.capoPositions)}</div>
                         <div class="songs-line">${tuning.songs}</div>
                     </div>
-                    ${effectiveTuning ? `
-                        <div class="effective-tuning">
-                            <strong>With Capo ${state.capoPosition}:</strong> ${effectiveTuning}
-                        </div>
-                    ` : ''}
                 </div>
             `;
         }
@@ -1208,7 +1349,8 @@
             const families = {
                 'c-family': { name: 'C-Based Tunings', intro: 'These tunings center around C tonality, ranging from historical minstrel styles to modern old-time favorites. They create bright, modal sounds ideal for melodic playing.' },
                 'd-family': { name: 'D-Based Tunings', intro: 'D-based tunings create darker, more mysterious tonal landscapes. These tunings are favored for modal old-time pieces and offer rich harmonic possibilities.' },
-                'g-family': { name: 'G-Based Tunings', intro: 'The most common family including the standard bluegrass tuning. These tunings range from bright major chords to modal sounds, offering the widest versatility for different playing styles.' }
+                'g-family': { name: 'G-Based Tunings', intro: 'The most common family including the standard bluegrass tuning. These tunings range from bright major chords to modal sounds, offering the widest versatility for different playing styles.' },
+                'other-family': { name: 'Other Tunings (4-String)', intro: '4-string banjo tunings for plectrum and tenor banjos. These instruments are commonly used in jazz, Dixieland, and Irish traditional music.' }
             };
 
             let html = '';
@@ -1236,132 +1378,238 @@
         }
 
         // ============================================
-        // FRETBOARD SVG GENERATOR
+        // FRETBOARD SVG GENERATOR (Enhanced from Python)
         // ============================================
         function generateFretboardSVG(tuningName) {
             const tuning = TUNINGS_DATA[tuningName];
             if (!tuning) return '';
 
-            const fretCount = state.fretCount;
+            const numFrets = state.fretCount;
             const capo = state.capoPosition;
+            const showNotes = state.showNotes;
 
-            // Dimensions
+            const strings = tuning.strings;
+            const numStrings = strings.length;
+            const shortStringIdx = tuning.shortStringIndex;
+            const shortStringStart = tuning.shortStringStartFret;
+
+            // SVG dimensions
+            const marginLeft = 100;
+            const marginRight = 150;
+            const marginTop = 140;
+            const marginBottom = 80;
             const stringSpacing = 55;
             const fretHeight = 50;
-            const leftMargin = 120;
-            const rightMargin = 80;
-            const topMargin = 80;
-            const bottomMargin = 40;
-
-            const numStrings = 5;
-            const width = leftMargin + (fretCount * fretHeight) + rightMargin;
-            const height = topMargin + ((numStrings - 1) * stringSpacing) + bottomMargin;
 
-            // Fret marker positions
-            const singleMarkers = [3, 5, 7, 10, 15, 17];
-            const doubleMarkers = [12];
-            const starMarker = 5;
-
-            let svg = `<svg class="fretboard-svg" width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">`;
+            const fretboardWidth = (numStrings - 1) * stringSpacing;
+            const fretboardHeight = numFrets * fretHeight;
+            const svgWidth = marginLeft + fretboardWidth + marginRight;
+            const svgHeight = marginTop + fretboardHeight + marginBottom;
+
+            const fbLeft = marginLeft;
+            const fbTop = marginTop;
+            const fbRight = fbLeft + fretboardWidth;
+            const bottomY = fbTop + fretboardHeight;
+
+            // Fret markers
+            const markerFrets = [3, 5, 7, 10, 12, 15, 17];
+            const doubleMarkerFrets = [12];
+
+            let svg = `<svg class="fretboard-svg" width="${svgWidth}" height="${svgHeight}" xmlns="http://www.w3.org/2000/svg">`;
+
+            // Styles
+            svg += `
+            <style>
+                .title { font-family: Georgia, serif; font-size: 24px; font-weight: bold; fill: #000; }
+                .subtitle { font-family: Georgia, serif; font-size: 16px; font-style: italic; fill: #333; }
+                .string-label { font-family: 'Courier New', monospace; font-size: 18px; font-weight: bold; fill: #000; }
+                .fret-number { font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; fill: #333; }
+                .note { font-family: Arial, sans-serif; font-size: 12px; font-weight: bold; fill: #000; }
+                .note-circle { fill: white; stroke: #000; stroke-width: 1.5; }
+                .fret-line { stroke: #000; stroke-width: 2; }
+                .string-line { stroke: #444; stroke-width: 1.5; }
+                .nut { stroke: #000; stroke-width: 6; }
+                .fret-marker { fill: #ddd; stroke: none; }
+                .peg { fill: #333; stroke: #000; stroke-width: 1; }
+                .ghost-string { stroke: #999; stroke-width: 1; stroke-dasharray: 3,3; }
+                .fret-marker-symbol { fill: #000; stroke: none; }
+            </style>`;
 
             // Background
-            svg += `<rect width="${width}" height="${height}" fill="#f5f0e6"/>`;
-
-            // Fretboard wood grain
-            svg += `<rect x="${leftMargin}" y="${topMargin - 10}" width="${fretCount * fretHeight}" height="${(numStrings - 1) * stringSpacing + 20}" fill="#d4a574" rx="3"/>`;
-
-            // Draw fret markers
-            for (let fret = 1; fret <= fretCount; fret++) {
-                const x = leftMargin + (fret - 0.5) * fretHeight;
-                const centerY = topMargin + ((numStrings - 1) * stringSpacing) / 2;
-
-                if (doubleMarkers.includes(fret)) {
-                    svg += `<circle cx="${x}" cy="${centerY - 20}" r="8" fill="#ddd" stroke="#bbb" stroke-width="1"/>`;
-                    svg += `<circle cx="${x}" cy="${centerY + 20}" r="8" fill="#ddd" stroke="#bbb" stroke-width="1"/>`;
-                } else if (fret === starMarker) {
-                    svg += `<text x="${x}" y="${centerY + 5}" text-anchor="middle" font-size="20" fill="#c9a86c">★</text>`;
-                } else if (singleMarkers.includes(fret) && fret !== starMarker) {
-                    svg += `<circle cx="${x}" cy="${centerY}" r="8" fill="#ddd" stroke="#bbb" stroke-width="1"/>`;
+            svg += `<rect width="100%" height="100%" fill="white"/>`;
+
+            // Title
+            const tuningStr = strings.map(s => normalizeNote(s)).join('');
+            svg += `<text x="${svgWidth / 2}" y="45" class="title" text-anchor="middle">Banjo Fretboard: ${tuningName}</text>`;
+            svg += `<text x="${svgWidth / 2}" y="70" class="subtitle" text-anchor="middle">Tuning: ${tuningStr} — ${tuning.description}</text>`;
+
+            // Fret markers (on fretboard face)
+            for (const fret of markerFrets) {
+                if (fret <= numFrets) {
+                    const y = fbTop + (fret - 0.5) * fretHeight;
+                    if (doubleMarkerFrets.includes(fret)) {
+                        svg += `<circle cx="${fbLeft + fretboardWidth/2 - 15}" cy="${y}" r="7" class="fret-marker"/>`;
+                        svg += `<circle cx="${fbLeft + fretboardWidth/2 + 15}" cy="${y}" r="7" class="fret-marker"/>`;
+                    } else {
+                        svg += `<circle cx="${fbLeft + fretboardWidth/2}" cy="${y}" r="7" class="fret-marker"/>`;
+                    }
                 }
             }
 
-            // Draw nut
-            svg += `<rect x="${leftMargin - 8}" y="${topMargin - 10}" width="8" height="${(numStrings - 1) * stringSpacing + 20}" fill="#f5f5dc" stroke="#333" stroke-width="2"/>`;
-
-            // Draw frets
-            for (let fret = 1; fret <= fretCount; fret++) {
-                const x = leftMargin + fret * fretHeight;
-                // 5th string only starts at fret 5
-                const startY = fret <= 5 ? topMargin + stringSpacing : topMargin;
-                svg += `<line x1="${x}" y1="${startY}" x2="${x}" y2="${topMargin + (numStrings - 1) * stringSpacing}" stroke="#666" stroke-width="2"/>`;
+            // Nut
+            if (shortStringIdx !== null && shortStringStart !== null) {
+                const nutStartX = fbLeft + stringSpacing - 10;
+                svg += `<line x1="${nutStartX}" y1="${fbTop}" x2="${fbRight + 10}" y2="${fbTop}" class="nut"/>`;
+            } else {
+                svg += `<line x1="${fbLeft - 10}" y1="${fbTop}" x2="${fbRight + 10}" y2="${fbTop}" class="nut"/>`;
             }
 
-            // Draw 5th string diagonal transition
-            const fret5X = leftMargin + 5 * fretHeight;
-            svg += `<path d="M ${fret5X} ${topMargin} L ${fret5X - 15} ${topMargin + stringSpacing * 0.3}" stroke="#8b4513" stroke-width="3" fill="none"/>`;
+            // Fret lines with ordinal labels on right
+            for (let fret = 1; fret <= numFrets; fret++) {
+                const y = fbTop + fret * fretHeight;
+
+                let lineStartX, lineEndX;
+                if (shortStringIdx !== null && shortStringStart !== null && fret < shortStringStart) {
+                    lineStartX = fbLeft + stringSpacing - 10;
+                    lineEndX = fbRight + 10;
+                } else {
+                    lineStartX = fbLeft - 10;
+                    lineEndX = fbRight + 10;
+                }
+
+                // Extend line for marker frets
+                if (markerFrets.includes(fret)) {
+                    lineEndX += 20;
+                }
 
-            // 5th string peg indicator
-            svg += `<circle cx="${fret5X - 20}" cy="${topMargin + stringSpacing * 0.4}" r="6" fill="#c9a86c" stroke="#8b4513" stroke-width="2"/>`;
+                svg += `<line x1="${lineStartX}" y1="${y}" x2="${lineEndX}" y2="${y}" class="fret-line"/>`;
+
+                // Ordinal fret labels on right
+                if (markerFrets.includes(fret)) {
+                    const ordinal = fret + (fret === 1 ? 'st' : fret === 2 ? 'nd' : fret === 3 ? 'rd' : 'th') + ' fret';
+                    const textX = fbRight + 70;
+                    svg += `<text x="${textX}" y="${y}" class="fret-number" text-anchor="middle" dominant-baseline="middle">${ordinal}</text>`;
+
+                    // Marker symbols
+                    const symbolX = textX + 50;
+                    if (fret === 5) {
+                        // Star for 5th fret
+                        const starPoints = `${symbolX},${y-7} ${symbolX+2},${y-2} ${symbolX+7},${y-2} ${symbolX+3},${y+1} ${symbolX+5},${y+6} ${symbolX},${y+3} ${symbolX-5},${y+6} ${symbolX-3},${y+1} ${symbolX-7},${y-2} ${symbolX-2},${y-2}`;
+                        svg += `<polygon points="${starPoints}" class="fret-marker-symbol"/>`;
+                    } else if (fret === 12) {
+                        // Double circles
+                        svg += `<circle cx="${symbolX - 8}" cy="${y}" r="6" class="fret-marker-symbol"/>`;
+                        svg += `<circle cx="${symbolX + 8}" cy="${y}" r="6" class="fret-marker-symbol"/>`;
+                    } else {
+                        // Single circle
+                        svg += `<circle cx="${symbolX}" cy="${y}" r="6" class="fret-marker-symbol"/>`;
+                    }
+                }
+            }
 
-            // Draw strings
-            for (let string = 0; string < numStrings; string++) {
-                const y = topMargin + string * stringSpacing;
-                const stringWeight = 2 - (string * 0.2);
+            // Neck edges with diagonal for short string
+            if (shortStringIdx !== null && shortStringStart !== null) {
+                const nutLeftX = fbLeft + stringSpacing - 10;
+                const fret4Y = fbTop + 4 * fretHeight;
+                const fret5Y = fbTop + 5 * fretHeight;
+                const leftEdgeX = fbLeft - 10;
+
+                // Ghost string line (dotted)
+                svg += `<line x1="${fbLeft}" y1="${fbTop}" x2="${fbLeft}" y2="${fret5Y - fretHeight}" class="ghost-string"/>`;
+
+                // Polyline neck edge
+                svg += `<polyline points="${nutLeftX},${fbTop} ${nutLeftX},${fret4Y} ${leftEdgeX},${fret5Y} ${leftEdgeX},${bottomY}" style="stroke:#000; stroke-width:3; fill:none;"/>`;
+                svg += `<line x1="${fbRight + 10}" y1="${fbTop}" x2="${fbRight + 10}" y2="${bottomY}" style="stroke:#000; stroke-width:3;"/>`;
+                svg += `<line x1="${leftEdgeX}" y1="${bottomY}" x2="${fbRight + 10}" y2="${bottomY}" style="stroke:#000; stroke-width:3;"/>`;
+            } else {
+                // 4-string: rectangular edges
+                svg += `<line x1="${fbLeft - 10}" y1="${fbTop}" x2="${fbLeft - 10}" y2="${bottomY}" style="stroke:#000; stroke-width:3;"/>`;
+                svg += `<line x1="${fbRight + 10}" y1="${fbTop}" x2="${fbRight + 10}" y2="${bottomY}" style="stroke:#000; stroke-width:3;"/>`;
+                svg += `<line x1="${fbLeft - 10}" y1="${bottomY}" x2="${fbRight + 10}" y2="${bottomY}" style="stroke:#000; stroke-width:3;"/>`;
+            }
 
-                if (string === 0) {
-                    // 5th string - dotted from nut to fret 5, solid after
-                    svg += `<line x1="${leftMargin}" y1="${y}" x2="${fret5X}" y2="${y}" stroke="#888" stroke-width="${stringWeight}" stroke-dasharray="4,4" opacity="0.4"/>`;
-                    svg += `<line x1="${fret5X}" y1="${y}" x2="${leftMargin + fretCount * fretHeight}" y2="${y}" stroke="#444" stroke-width="${stringWeight}"/>`;
+            // String lines
+            for (let i = 0; i < numStrings; i++) {
+                const x = fbLeft + i * stringSpacing;
+
+                if (i === shortStringIdx && shortStringStart !== null) {
+                    const startY = fbTop + (shortStringStart - 1) * fretHeight;
+                    svg += `<line x1="${x}" y1="${startY}" x2="${x}" y2="${bottomY}" class="string-line" style="stroke-width:2;"/>`;
+
+                    // Peg indicator
+                    const pegY = startY - 50;
+                    const pegHeadX = fbLeft - 10;
+                    const pegShaftStartX = fbLeft + 30;
+                    svg += `<rect x="${pegHeadX}" y="${pegY - 5}" width="${pegShaftStartX - pegHeadX}" height="8" class="peg" rx="2"/>`;
+                    svg += `<circle cx="${pegHeadX}" cy="${pegY}" r="10" class="peg"/>`;
+                    svg += `<circle cx="${pegHeadX}" cy="${pegY}" r="4" fill="white"/>`;
                 } else {
-                    svg += `<line x1="${leftMargin}" y1="${y}" x2="${leftMargin + fretCount * fretHeight}" y2="${y}" stroke="#444" stroke-width="${stringWeight}"/>`;
+                    svg += `<line x1="${x}" y1="${fbTop}" x2="${x}" y2="${bottomY}" class="string-line"/>`;
                 }
             }
 
-            // Draw capo if set
-            if (capo > 0) {
-                const capoX = leftMargin + (capo - 0.5) * fretHeight;
-                svg += `<rect x="${capoX - 10}" y="${topMargin - 15}" width="20" height="${(numStrings - 1) * stringSpacing + 30}" fill="#333" rx="5" opacity="0.8"/>`;
-                svg += `<text x="${capoX}" y="${topMargin - 25}" text-anchor="middle" font-size="12" fill="#333" font-weight="bold">CAPO</text>`;
+            // String labels at top
+            for (let i = 0; i < numStrings; i++) {
+                const x = fbLeft + i * stringSpacing;
+                const stringNumber = numStrings - i;
+                const note = strings[i];
+                const normalized = normalizeNote(note);
+                const displayed = formatSimpleNote(note);
+
+                const numberY = fbTop - 35;
+                const labelY = fbTop - 12;
+
+                svg += `<text x="${x}" y="${numberY}" class="fret-number" text-anchor="middle">${stringNumber}</text>`;
+                svg += `<text x="${x}" y="${labelY}" class="string-label" text-anchor="middle">${displayed}</text>`;
             }
 
-            // Draw string labels and open notes
-            const strings = tuning.strings;
-            for (let string = 0; string < numStrings; string++) {
-                const y = topMargin + string * stringSpacing;
-                const note = strings[string];
-                const transposedNote = capo > 0 ? transposeNote(note, capo) : note;
-                const displayNote = formatNote(transposedNote, state.useFlats);
-
-                // String number
-                svg += `<text x="${leftMargin - 50}" y="${y + 5}" text-anchor="middle" font-size="16" font-weight="bold" fill="#333">${5 - string}</text>`;
-
-                // Open note circle
-                const isChanged = tuning.changedStrings[string];
-                svg += `<circle cx="${leftMargin - 25}" cy="${y}" r="14" fill="${isChanged ? '#333' : 'white'}" stroke="#333" stroke-width="2"/>`;
-
-                // Note text (need to handle subscript differently in SVG)
-                const parsed = parseNote(transposedNote);
-                if (parsed) {
-                    let noteName = parsed.note;
-                    if (state.useFlats && SHARP_TO_FLAT[noteName]) {
-                        noteName = SHARP_TO_FLAT[noteName];
+            // Notes at each fret position
+            if (showNotes) {
+                for (let fret = 1; fret <= numFrets; fret++) {
+                    const y = fbTop + (fret - 0.5) * fretHeight;
+
+                    for (let i = 0; i < numStrings; i++) {
+                        const x = fbLeft + i * stringSpacing;
+                        const openNote = strings[i];
+
+                        // Handle short string
+                        if (i === shortStringIdx && shortStringStart !== null) {
+                            if (fret < shortStringStart) {
+                                continue; // No notes in empty space
+                            }
+                            // Calculate effective fret for short string
+                            const effectiveFret = fret - (shortStringStart - 1);
+                            const note = getNoteAtFret(openNote, effectiveFret);
+                            const displayedNote = formatSimpleNote(note);
+
+                            svg += `<circle cx="${x}" cy="${y}" r="16" class="note-circle"/>`;
+                            svg += `<text x="${x}" y="${y + 5}" class="note" text-anchor="middle">${displayedNote}</text>`;
+                        } else {
+                            const note = getNoteAtFret(openNote, fret);
+                            const displayedNote = formatSimpleNote(note);
+
+                            svg += `<circle cx="${x}" cy="${y}" r="16" class="note-circle"/>`;
+                            svg += `<text x="${x}" y="${y + 5}" class="note" text-anchor="middle">${displayedNote}</text>`;
+                        }
                     }
-                    noteName = noteName.replace('#', '\u266F').replace('b', '\u266D');
-
-                    svg += `<text x="${leftMargin - 25}" y="${y + 2}" text-anchor="middle" font-size="10" font-weight="bold" fill="${isChanged ? 'white' : '#333'}">${noteName}</text>`;
-                    svg += `<text x="${leftMargin - 17}" y="${y + 8}" text-anchor="middle" font-size="7" fill="${isChanged ? 'white' : '#333'}">${parsed.octave}</text>`;
                 }
             }
 
-            // Fret numbers
-            for (let fret = 1; fret <= fretCount; fret++) {
-                const x = leftMargin + (fret - 0.5) * fretHeight;
-                svg += `<text x="${x}" y="${topMargin + (numStrings - 1) * stringSpacing + 25}" text-anchor="middle" font-size="12" fill="#666">${fret}</text>`;
+            // Capo indicator
+            if (capo > 0) {
+                const capoY = fbTop + (capo - 0.5) * fretHeight;
+                svg += `<rect x="${fbLeft - 15}" y="${capoY - 8}" width="${fretboardWidth + 30}" height="16" fill="#333" rx="4" opacity="0.9"/>`;
+                svg += `<text x="${fbLeft + fretboardWidth/2}" y="${capoY + 4}" text-anchor="middle" font-size="10" fill="white" font-weight="bold">CAPO</text>`;
             }
 
-            // Title
-            svg += `<text x="${width / 2}" y="30" text-anchor="middle" font-size="18" font-weight="bold" fill="#333">${tuningName}</text>`;
-            svg += `<text x="${width / 2}" y="50" text-anchor="middle" font-size="12" fill="#666">${tuning.description}</text>`;
+            // Footer
+            const footerY = fbTop + fretboardHeight + 30;
+            svg += `<rect x="${marginLeft-50}" y="${footerY}" width="${fretboardWidth+150}" height="30" rx="5" fill="#f5f5f5" stroke="#ccc"/>`;
+            const footerLine1 = shortStringStart
+                ? `String 1 (far right) = 1st string • 5th string starts at fret ${shortStringStart}`
+                : `String 1 (far right) = 1st string • ${numStrings}-string banjo`;
+            svg += `<text x="${svgWidth/2}" y="${footerY + 12}" text-anchor="middle" font-size="10" fill="#555">${footerLine1}</text>`;
+            svg += `<text x="${svgWidth/2}" y="${footerY + 24}" text-anchor="middle" font-size="10" fill="#555">Fret markers: 3,5,7,10,12,15,17 • Peg indicates 5th string tuning point</text>`;
 
             svg += '</svg>';
             return svg;
@@ -1383,14 +1631,12 @@
         // EVENT HANDLERS
         // ============================================
         function setupEventListeners() {
-            // Family filter
             document.getElementById('familyFilter').addEventListener('change', (e) => {
                 state.familyFilter = e.target.value;
                 saveState();
                 renderTunings();
             });
 
-            // Capo position
             document.getElementById('capoPosition').addEventListener('change', (e) => {
                 state.capoPosition = parseInt(e.target.value) || 0;
                 saveState();
@@ -1398,37 +1644,29 @@
                 renderFretboard();
             });
 
-            // Fret count
             document.getElementById('fretCount').addEventListener('change', (e) => {
                 state.fretCount = parseInt(e.target.value);
                 saveState();
                 renderFretboard();
             });
 
-            // Notation toggle
-            document.getElementById('notationToggle').addEventListener('change', (e) => {
-                state.useFlats = e.target.checked;
-                document.getElementById('notationLabel').textContent = state.useFlats ? 'Flats' : 'Sharps';
+            document.getElementById('showNotesToggle').addEventListener('change', (e) => {
+                state.showNotes = e.target.checked;
                 saveState();
-                renderTunings();
                 renderFretboard();
             });
 
-            // Fretboard tuning select
             document.getElementById('fretboardTuningSelect').addEventListener('change', (e) => {
                 state.selectedFretboardTuning = e.target.value;
                 saveState();
                 renderFretboard();
             });
 
-            // Tabs
             document.querySelectorAll('.tab').forEach(tab => {
                 tab.addEventListener('click', (e) => {
                     const tabName = e.target.dataset.tab;
-
                     document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
                     document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
-
                     e.target.classList.add('active');
                     document.getElementById(`${tabName}-tab`).classList.add('active');
                 });
@@ -1440,7 +1678,7 @@
                 familyFilter: 'all',
                 capoPosition: 0,
                 fretCount: 15,
-                useFlats: false,
+                showNotes: true,
                 selectedFretboardTuning: 'Open G'
             };
             saveState();
@@ -1453,8 +1691,7 @@
             document.getElementById('familyFilter').value = state.familyFilter;
             document.getElementById('capoPosition').value = state.capoPosition;
             document.getElementById('fretCount').value = state.fretCount;
-            document.getElementById('notationToggle').checked = state.useFlats;
-            document.getElementById('notationLabel').textContent = state.useFlats ? 'Flats' : 'Sharps';
+            document.getElementById('showNotesToggle').checked = state.showNotes;
             document.getElementById('fretboardTuningSelect').value = state.selectedFretboardTuning;
         }
 
@@ -1470,7 +1707,6 @@
             renderFretboard();
         }
 
-        // Start the app
         document.addEventListener('DOMContentLoaded', init);
     </script>
 </body>