Initial Commit

This commit is contained in:
2026-07-10 12:44:14 +05:30
commit 24030e7d9b
7 changed files with 2950 additions and 0 deletions

169
index.html Normal file
View File

@@ -0,0 +1,169 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#173f37" />
<link rel="icon" href="data:," />
<meta
name="description"
content="A data-driven, interactive guitar tab viewer sample."
/>
<title>Fretform — Interactive guitar tabs</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="page-shell">
<header class="topbar" aria-label="Site header">
<a class="brand" href="./" aria-label="Fretform home">
<span class="brand-mark" aria-hidden="true">FF</span>
<span>Fretform</span>
</a>
<div class="topbar-actions">
<span class="format-pill">guitar-tab/v1</span>
<button class="button button-quiet file-button" id="load-tab-button" type="button">
Load tab JSON
</button>
<input id="tab-file" type="file" accept="application/json,.json" hidden />
<a class="button button-dark" id="view-source-link" href="haseen.tab.json" target="_blank" rel="noreferrer">
View source
</a>
</div>
</header>
<main>
<section class="hero" aria-labelledby="song-title">
<div class="hero-copy">
<p class="eyebrow"><span>Interactive tab sheet</span><span id="source-label">Loading JSON…</span></p>
<h1 id="song-title">Loading tab…</h1>
<p class="artist-line" id="artist-line"></p>
<div class="metadata-row" id="metadata-row" aria-label="Song setup"></div>
</div>
<div class="arrangement-panel">
<div class="panel-kicker">Choose an arrangement</div>
<div class="segmented-control" id="arrangement-picker" role="tablist" aria-label="Arrangement"></div>
<p id="arrangement-description" class="arrangement-description"></p>
</div>
</section>
<section class="practice-player" aria-label="Practice guide">
<div class="transport">
<button class="play-button" id="play-button" type="button" aria-label="Start practice guide">
<span class="play-icon" aria-hidden="true"></span>
</button>
<div class="transport-copy">
<span class="transport-label">Practice guide</span>
<strong id="now-playing">Select a bar to begin</strong>
</div>
<div class="transport-buttons" aria-label="Bar navigation">
<button class="icon-button" id="previous-button" type="button" aria-label="Previous bar"></button>
<button class="icon-button" id="next-button" type="button" aria-label="Next bar"></button>
</div>
</div>
<div class="beat-and-progress">
<div class="progress-copy">
<span id="bar-position">Bar 1 of 1</span>
<span id="beat-position">Ready</span>
</div>
<div class="progress-track" aria-hidden="true"><span id="progress-fill"></span></div>
<div class="beat-dots" id="beat-dots" aria-label="Practice count"></div>
</div>
<div class="practice-settings">
<label class="tempo-control" for="tempo-range">
<span>Tempo</span>
<strong><output id="tempo-output">82</output> BPM</strong>
<input id="tempo-range" type="range" min="30" max="240" step="1" value="82" />
</label>
<label class="toggle-row" for="metronome-toggle">
<input id="metronome-toggle" type="checkbox" checked />
<span class="toggle" aria-hidden="true"></span>
<span>Metronome</span>
</label>
<label class="toggle-row" for="loop-toggle">
<input id="loop-toggle" type="checkbox" checked />
<span class="toggle" aria-hidden="true"></span>
<span>Loop tab</span>
</label>
</div>
</section>
<p class="practice-note" id="practice-note"></p>
<div class="content-grid">
<section class="sheet" aria-labelledby="sheet-title">
<div class="sheet-header">
<div>
<p class="section-index" id="section-index">01 / Tab</p>
<h2 id="sheet-title">Tablature</h2>
</div>
<div class="zoom-control" aria-label="Tab size">
<span>Tab size</span>
<button class="icon-button small" id="zoom-out" type="button" aria-label="Make tab smaller"></button>
<button class="icon-button small" id="zoom-in" type="button" aria-label="Make tab larger">+</button>
</div>
</div>
<div id="tab-sheet" class="tab-sheet"></div>
<p class="sr-only" id="viewer-status" role="status" aria-live="polite"></p>
</section>
<aside class="sidebar" aria-label="Tab details">
<section class="side-card legend-card">
<p class="panel-kicker">Notation key</p>
<h2>How to read it</h2>
<dl class="legend-list" id="legend-list"></dl>
</section>
<section class="side-card data-card">
<p class="panel-kicker">Built from data</p>
<h2>One renderer, any song.</h2>
<p>
The page reads bars, strings, lyrics, techniques, and practice settings from a versioned JSON file.
</p>
<div class="data-stats">
<div><strong id="stat-arrangements">0</strong><span>arrangement</span></div>
<div><strong id="stat-bars">0</strong><span>bars</span></div>
<div><strong id="stat-strings">6</strong><span>strings</span></div>
</div>
<a href="guitar-tab.schema.json" target="_blank" class="text-link">Open the JSON Schema <span aria-hidden="true"></span></a>
</section>
<section class="side-card shortcuts-card">
<p class="panel-kicker">Keyboard</p>
<ul>
<li><kbd>Space</kbd><span>Start / pause</span></li>
<li><kbd></kbd><kbd></kbd><span>Move by bar</span></li>
<li><kbd>M</kbd><span>Metronome</span></li>
<li><kbd>L</kbd><span>Loop tab</span></li>
</ul>
</section>
</aside>
</div>
<section class="embed-strip" aria-labelledby="embed-title">
<div>
<p class="panel-kicker">For the team</p>
<h2 id="embed-title">Drop it into an existing page.</h2>
<p>Use the full viewer or add <code>?embed=1</code> for a compact, iframe-friendly surface.</p>
</div>
<button class="button button-light" id="copy-embed" type="button">Copy embed snippet</button>
</section>
</main>
<footer>
<span>Interactive sample • source data stays separate from the viewer</span>
<span id="attribution"></span>
</footer>
</div>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<div class="error-panel" id="error-panel" role="alert" hidden>
<strong>Couldnt load this tab.</strong>
<span id="error-message"></span>
</div>
<script src="app.js" defer></script>
</body>
</html>