#!/usr/bin/env python3
"""Generate a 5-page printable piano practice sheet (HTML) for Comptine d'un autre ete.
Visuals: keyboard chord diagrams, sync-point rhythm grid, piece map, tempo ladder.
Then rendered to PDF via headless Chrome."""

import os

OUT_DIR = os.path.dirname(os.path.abspath(__file__))

# ---------------------------------------------------------------- keyboard SVG
ORDER = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
BLACK_AFTER = {'C': 'C#', 'D': 'D#', 'F': 'F#', 'G': 'G#', 'A': 'A#'}


def keyboard(highlights, start='C', start_oct=3, num_white=12, ww=34, wh=104):
    """highlights: {note_str: {'finger': '5', 'color': '#..', 'root': bool}}"""
    bw = ww * 0.60
    bh = wh * 0.62
    whites = []
    idx = ORDER.index(start)
    o = start_oct
    for _ in range(num_white):
        whites.append((ORDER[idx], o))
        idx += 1
        if idx == 7:
            idx = 0
            o += 1
    total_w = num_white * ww
    label_h = 20
    H = wh + label_h
    p = ['<svg viewBox="0 0 %d %d" width="%d" height="%d" '
         'xmlns="http://www.w3.org/2000/svg">' % (total_w, H, total_w, H)]

    # white keys
    for i, (name, oo) in enumerate(whites):
        x = i * ww
        ns = '%s%d' % (name, oo)
        hl = highlights.get(ns)
        fill = hl['color'] if hl else '#ffffff'
        p.append('<rect x="%d" y="0" width="%d" height="%d" fill="%s" '
                 'stroke="#222" stroke-width="1.2"/>' % (x, ww, wh, fill))
    # black keys
    for i, (name, oo) in enumerate(whites):
        if name in BLACK_AFTER and i < num_white - 1:
            bx = (i + 1) * ww - bw / 2
            bns = '%s%d' % (BLACK_AFTER[name], oo)
            hl = highlights.get(bns)
            fill = hl['color'] if hl else '#1a1a1a'
            p.append('<rect x="%.1f" y="0" width="%.1f" height="%.1f" fill="%s" '
                     'stroke="#000" stroke-width="1"/>' % (bx, bw, bh, fill))
    # white finger circles + note labels
    for i, (name, oo) in enumerate(whites):
        ns = '%s%d' % (name, oo)
        hl = highlights.get(ns)
        if not hl:
            continue
        cx = i * ww + ww / 2
        if hl.get('finger'):
            ring = '#dc2626' if hl.get('root') else '#0b3b8c'
            cy = wh - 16
            p.append('<circle cx="%.1f" cy="%.1f" r="11" fill="#fff" stroke="%s" '
                     'stroke-width="2.4"/>' % (cx, cy, ring))
            p.append('<text x="%.1f" y="%.1f" text-anchor="middle" font-size="13" '
                     'font-weight="700" fill="#111">%s</text>' % (cx, cy + 4, hl['finger']))
        p.append('<text x="%.1f" y="%.1f" text-anchor="middle" font-size="10.5" '
                 'font-weight="700" fill="#111">%s</text>' % (cx, wh + 14, ns))
    # black finger circles + labels
    for i, (name, oo) in enumerate(whites):
        if name in BLACK_AFTER and i < num_white - 1:
            bx = (i + 1) * ww - bw / 2
            bns = '%s%d' % (BLACK_AFTER[name], oo)
            hl = highlights.get(bns)
            if not hl:
                continue
            cx = bx + bw / 2
            if hl.get('finger'):
                ring = '#dc2626' if hl.get('root') else '#0b3b8c'
                cy = bh - 14
                p.append('<circle cx="%.1f" cy="%.1f" r="9.5" fill="#fff" stroke="%s" '
                         'stroke-width="2.2"/>' % (cx, cy, ring))
                p.append('<text x="%.1f" y="%.1f" text-anchor="middle" font-size="11" '
                         'font-weight="700" fill="#111">%s</text>' % (cx, cy + 4, hl['finger']))
            p.append('<text x="%.1f" y="%.1f" text-anchor="middle" font-size="9.5" '
                     'font-weight="700" fill="#111">%s</text>' % (cx, wh + 14, bns))
    p.append('</svg>')
    return ''.join(p)


BLUE = '#bcd2ff'          # chord-tone key fill
CHORDS = [
    ('Em', 'E &ndash; G &ndash; B', {'E3': '5', 'G3': '3', 'B3': '1'}, 'E3'),
    ('G',  'G &ndash; B &ndash; D', {'G3': '5', 'B3': '3', 'D4': '1'}, 'G3'),
    ('Bm', 'B &ndash; D &ndash; F#', {'B3': '5', 'D4': '3', 'F#4': '1'}, 'B3'),
    ('D',  'D &ndash; F# &ndash; A', {'D3': '5', 'F#3': '3', 'A3': '1'}, 'D3'),
]


def chord_row(name, spelled, fingers, root):
    hl = {}
    for nstr, fg in fingers.items():
        hl[nstr] = {'finger': fg, 'color': BLUE, 'root': (nstr == root)}
    svg = keyboard(hl, start='C', start_oct=3, num_white=12, ww=29, wh=74)
    return ('<div class="chordrow">'
            '<div class="chordtag"><span class="cname">%s</span>'
            '<span class="cspell">%s</span></div>'
            '<div class="kb">%s</div></div>') % (name, spelled, svg)


# ------------------------------------------------------------- sync-point grid
def sync_grid(rh_marks, blank=False):
    cols = ['1', '&', '2', '&', '3', '&', '4', '&']
    cw = 56
    W = len(cols) * cw + 60
    top = 14      # RH row y
    rh_y = 40
    lh_y = 130
    H = 170
    left = 56
    p = ['<svg viewBox="0 0 %d %d" width="%d" height="%d" '
         'xmlns="http://www.w3.org/2000/svg">' % (W, H, W, H)]
    # row labels
    p.append('<text x="6" y="%d" font-size="13" font-weight="700" fill="#ea580c">RH</text>' % (rh_y + 5))
    p.append('<text x="6" y="%d" font-size="13" font-weight="700" fill="#0b3b8c">LH</text>' % (lh_y + 5))
    # count labels + columns
    for c in range(len(cols)):
        x = left + c * cw + cw / 2
        on_beat = cols[c] != '&'
        p.append('<text x="%.1f" y="%d" text-anchor="middle" font-size="13" '
                 'font-weight="%s" fill="#333">%s</text>'
                 % (x, top, '700' if on_beat else '400', cols[c]))
        # vertical guide
        p.append('<line x1="%.1f" y1="22" x2="%.1f" y2="%d" stroke="#e2e2e2" '
                 'stroke-width="1"/>' % (x, x, lh_y + 16))
    # LH steady eighths (all filled)
    for c in range(len(cols)):
        x = left + c * cw + cw / 2
        p.append('<circle cx="%.1f" cy="%d" r="9" fill="#0b3b8c"/>' % (x, lh_y))
    # RH marks + connectors
    if not blank:
        for c in rh_marks:
            x = left + c * cw + cw / 2
            p.append('<circle cx="%.1f" cy="%d" r="9" fill="#ea580c"/>' % (x, rh_y))
            p.append('<line x1="%.1f" y1="%d" x2="%.1f" y2="%d" stroke="#ea580c" '
                     'stroke-width="2.4" stroke-dasharray="3,3"/>' % (x, rh_y + 10, x, lh_y - 10))
    else:
        for c in range(len(cols)):
            x = left + c * cw + cw / 2
            p.append('<circle cx="%.1f" cy="%d" r="9" fill="#fff" stroke="#ea580c" '
                     'stroke-width="1.6" stroke-dasharray="2,2"/>' % (x, rh_y))
    p.append('</svg>')
    return ''.join(p)


# ----------------------------------------------------------------- piece map
def piece_map():
    bars = 20
    bw = 30
    bh = 30
    H = 78
    W = bars * bw + 4
    sections = [(1, 4, '#cfcfcf', 'Intro &mdash; LH only'),
                (5, 8, '#bcd2ff', 'A theme'),
                (9, 12, '#bcd2ff', 'A theme (repeat)'),
                (13, 16, '#bde0d6', 'B theme'),
                (17, 20, '#bde0d6', 'B theme')]
    seams = [(4, '4&rarr;5'), (8, '8&rarr;9'), (12, '12&rarr;13'), (16, '16&rarr;17')]
    p = ['<svg viewBox="0 0 %d %d" width="%d" height="%d" '
         'xmlns="http://www.w3.org/2000/svg">' % (W, H, W, H)]
    for (a, b, col, lab) in sections:
        for bar in range(a, b + 1):
            x = (bar - 1) * bw
            p.append('<rect x="%d" y="20" width="%d" height="%d" fill="%s" '
                     'stroke="#666" stroke-width="0.8"/>' % (x, bw, bh, col))
        cx = ((a - 1) + b) / 2 * bw
        p.append('<text x="%.1f" y="14" text-anchor="middle" font-size="9.5" '
                 'fill="#333">%s</text>' % (cx, lab))
    # bar numbers (every 4)
    for bar in [1, 5, 9, 13, 17]:
        x = (bar - 1) * bw + 3
        p.append('<text x="%d" y="42" font-size="9" font-weight="700" fill="#111">%d</text>' % (x, bar))
    # seam markers
    for (bar, lab) in seams:
        x = bar * bw
        p.append('<text x="%d" y="64" text-anchor="middle" font-size="14" '
                 'fill="#dc2626">&#9650;</text>' % x)
        p.append('<text x="%d" y="76" text-anchor="middle" font-size="8.5" '
                 'fill="#dc2626">%s</text>' % (x, lab))
    p.append('</svg>')
    return ''.join(p)


# --------------------------------------------------------------------- pieces
CSS = """
* { box-sizing: border-box; }
@page { size: A4; margin: 13mm; }
html, body { margin: 0; padding: 0; }
body { font-family: -apple-system, 'Helvetica Neue', Arial, sans-serif; color: #1a1a1a;
       -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.page { page-break-after: always; padding: 0; position: relative; min-height: 252mm; }
.page:last-child { page-break-after: auto; }
.kicker { font-size: 10.5px; letter-spacing: 1.5px; text-transform: uppercase;
          color: #6b7280; font-weight: 700; }
.hbar { display: flex; align-items: flex-start; justify-content: space-between;
        border-bottom: 3px solid #0b3b8c; padding-bottom: 8px; margin-bottom: 12px; }
.stepno { font-size: 40px; font-weight: 800; color: #0b3b8c; line-height: 0.9; }
.htitle { font-size: 22px; font-weight: 800; margin: 2px 0 0; }
.htime { font-size: 12px; color: #555; margin-top: 3px; }
.goalpill { background: #fff4e6; border: 1.5px solid #ea580c; color: #9a3412;
            border-radius: 8px; padding: 8px 12px; font-size: 12.5px; font-weight: 600;
            max-width: 230px; }
.lead { font-size: 13px; line-height: 1.45; background: #f3f6ff; border-left: 4px solid #0b3b8c;
        padding: 8px 12px; border-radius: 0 6px 6px 0; margin: 0 0 9px; }
.lead b { color: #0b3b8c; }
h3.sec { font-size: 13px; text-transform: uppercase; letter-spacing: 0.8px; color: #0b3b8c;
         margin: 10px 0 4px; border-bottom: 1px solid #d6def0; padding-bottom: 3px; }
ol.do { margin: 0 0 4px; padding-left: 20px; }
ol.do li { font-size: 12.5px; line-height: 1.4; margin-bottom: 4px; }
ol.do li b { color: #0b3b8c; }
.two { display: flex; gap: 16px; }
.col { flex: 1; }
.chords { display: flex; flex-direction: column; gap: 3px; margin: 2px 0; }
.chordrow { display: flex; align-items: center; gap: 12px; }
.chordtag { width: 92px; flex: 0 0 92px; }
.cname { display: block; font-size: 19px; font-weight: 800; color: #0b3b8c; }
.cspell { display: block; font-size: 11px; color: #555; }
.kb { flex: 1; }
.legend { display: flex; gap: 18px; align-items: center; font-size: 11.5px; color: #444; margin: 4px 0; }
.fcircle { display: inline-flex; width: 19px; height: 19px; border-radius: 50%;
           border: 2px solid #0b3b8c; align-items: center; justify-content: center;
           font-weight: 700; font-size: 11px; margin: 0 2px; }
.fcircle.r { border-color: #dc2626; }
.box { border: 1.5px solid #d6def0; border-radius: 8px; padding: 9px 13px; margin: 6px 0; }
.box.win { border-color: #16a34a; background: #f0fdf4; }
.box.warn { border-color: #ea580c; background: #fff7ed; }
.box .lbl { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.6px;
            margin-bottom: 4px; }
.box.win .lbl { color: #15803d; }
.box.warn .lbl { color: #c2410c; }
.box p { margin: 3px 0; font-size: 12.5px; line-height: 1.45; }
.checks { display: flex; gap: 10px; margin-top: 5px; }
.chk { width: 22px; height: 22px; border: 2px solid #15803d; border-radius: 5px; }
.tempo { display: flex; gap: 6px; align-items: center; margin: 6px 0; flex-wrap: wrap; }
.trung { border: 1.5px solid #999; border-radius: 6px; padding: 5px 9px; font-size: 12px;
         font-weight: 700; color: #555; }
.trung.today { border-color: #ea580c; background: #fff4e6; color: #9a3412; }
.trung.wknd { border-style: dashed; color: #999; }
.arrow { color: #999; font-size: 13px; }
.gridwrap { text-align: center; margin: 6px 0; }
.gridcap { font-size: 11px; color: #666; margin: 2px 0 8px; }
.shuffle { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0; }
.card { border: 1.5px solid #0b3b8c; border-radius: 7px; padding: 7px 11px; font-size: 12px;
        font-weight: 700; color: #0b3b8c; background: #f3f6ff; }
.card.seam { border-color: #dc2626; color: #b91c1c; background: #fef2f2; }
.wkplan { display: flex; gap: 10px; margin: 6px 0; }
.day { flex: 1; border: 1.5px solid #d6def0; border-radius: 8px; padding: 9px 11px; }
.day.today { border-color: #ea580c; background: #fff7ed; }
.day .dlbl { font-size: 12px; font-weight: 800; color: #0b3b8c; }
.day.today .dlbl { color: #c2410c; }
.day p { font-size: 11.5px; margin: 4px 0 0; line-height: 1.4; color: #444; }
.foot { position: absolute; bottom: 0; left: 0; right: 0; border-top: 1px solid #e3e3e3;
        padding-top: 6px; font-size: 10px; color: #9ca3af; display: flex; justify-content: space-between; }
.src { font-size: 9.5px; color: #b3b3b3; }
"""

FOOT = ('<div class="foot"><span>Comptine d&rsquo;un autre &eacute;t&eacute; &middot; '
        'Yann Tiersen &middot; E minor (F&sharp;)</span>'
        '<span><b>Today (Fri) = slow &amp; solid only</b> &nbsp;&middot;&nbsp; speed &amp; polish = the weekend</span></div>')


def header(no, title, time, goal):
    return ('<div class="hbar"><div><div class="kicker">5-Step Session &middot; Page %d of 5</div>'
            '<div style="display:flex;align-items:baseline;gap:14px;">'
            '<span class="stepno">%d</span>'
            '<div><div class="htitle">%s</div><div class="htime">%s</div></div></div></div>'
            '<div class="goalpill">%s</div></div>') % (no, no, title, time, goal)


# legends
RH_LEGEND = ('<div class="legend"><span><b>Right hand fingers:</b></span>'
             '<span><span class="fcircle">1</span>thumb</span>'
             '<span><span class="fcircle">2</span></span>'
             '<span><span class="fcircle">3</span></span>'
             '<span><span class="fcircle">4</span></span>'
             '<span><span class="fcircle">5</span>pinky</span>'
             '<span style="color:#888;">(thumb on the low notes &rarr; pinky high)</span></div>')

LH_LEGEND = ('<div class="legend"><span><b>Left hand fingers:</b></span>'
             '<span><span class="fcircle r">5</span>pinky = lowest note</span>'
             '<span><span class="fcircle">3</span>middle</span>'
             '<span><span class="fcircle">1</span>thumb = top note</span>'
             '<span style="color:#888;">(red ring = root / chord name note)</span></div>')


# -------- PAGE 1
chord_html = ''.join(chord_row(n, s, f, r) for (n, s, f, r) in CHORDS)
p1 = """
<div class="page">
%s
<div class="lead">The left hand is the <b>same 4 bars repeated for the whole song</b>. Master these 4 bars and you own the entire left hand &mdash; and it&rsquo;s built from <b>4 chords you already know</b>. This page is the foundation; everything else stands on it.</div>

<h3 class="sec">Do this</h3>
<ol class="do">
<li><b>Find your 4 chords.</b> In the bass clef, look at the <b>lowest note at the start of bars 1, 2, 3, 4</b>. Those roots are <b>E, G, B, D</b> &rarr; the chords <b>Em, G, Bm, D</b>. Pencil the chord name above each bar. (Confirm the order matches your sheet.)</li>
<li><b>Play each chord as a solid block first</b> &mdash; all three notes at once, left hand, fingers <b>5&ndash;3&ndash;1</b> (pinky on the bottom). Get the shape under your hand. See the diagrams.</li>
<li><b>Now roll it (arpeggio)</b> the way the music does: bottom note up through the chord, smooth even eighth-notes. Read the exact note order off your sheet &mdash; it just walks through these same chord notes.</li>
<li><b>Metronome ~50.</b> Play the 4-bar loop. Get your <b>eyes off your hands</b> as soon as you can.</li>
<li><b>The automaticity test:</b> loop it while <b>saying the chord names out loud</b> (&ldquo;Em&hellip; G&hellip; Bm&hellip; D&hellip;&rdquo;). If you can talk and keep playing, the left hand is going automatic. That &mdash; not speed &mdash; is the whole goal of this page.</li>
</ol>

<h3 class="sec">Your four chords (left hand, fingers 5&ndash;3&ndash;1)</h3>
%s
%s

<div class="tempo"><b style="font-size:12px;">Today&rsquo;s tempo:</b>
<span class="trung today">50</span><span class="arrow">&rarr;</span>
<span class="trung today">60</span><span class="arrow">&rarr;</span>
<span class="trung today">70</span><span class="arrow">&rarr;</span>
<span class="trung wknd">faster = weekend</span></div>

<div class="box win"><div class="lbl">What good looks like</div>
<p>5 clean loops in a row, <b>not looking</b> at your hands, chord names out loud. Tick one box per clean loop:</p>
<div class="checks"><div class="chk"></div><div class="chk"></div><div class="chk"></div><div class="chk"></div><div class="chk"></div></div></div>

<div class="box warn"><div class="lbl">If it&rsquo;s not working</div>
<p><b>Don&rsquo;t speed up &mdash; slow down.</b> A wrong note played fast gets memorised wrong. Play it slow enough to be perfect, and it will grow on its own.</p></div>
%s
</div>
""" % (header(1, 'Left-hand engine', 'Step 1 &middot; 20&ndash;25 min', 'Today: just make the left hand <u>automatic</u>. Slow is the win &mdash; not speed.'),
       chord_html, LH_LEGEND, FOOT)


# -------- PAGE 2
count_strip = sync_grid([], blank=True)  # reused as a generic counting/onset template
p2 = """
<div class="page">
%s
<div class="lead">Learn each melody <b>on its own</b>, and lock its <b>rhythm</b> by counting out loud. The rhythm &mdash; not the notes &mdash; is what makes hands-together hard later. Over-learn it now and Step 3 gets much easier.</div>

<h3 class="sec">Do this</h3>
<ol class="do">
<li><b>Two tunes to learn:</b> the <b>A-theme</b> (starts bar 5) and the <b>B-theme</b> (starts bar 13 &mdash; mostly long held notes, so it&rsquo;s easier). Right hand only.</li>
<li><b>Chunk the A-theme into single bars.</b> Learn bar 5. Then play 5&ndash;6. Then 5&ndash;7. Add one bar at a time (&ldquo;chaining&rdquo;) &mdash; never the whole thing at once.</li>
<li><b>Count out loud while you play:</b> &ldquo;<b>1 &amp; 2 &amp; 3 &amp; 4 &amp;</b>.&rdquo; Notice the melody <b>does not start on beat 1</b> &mdash; there&rsquo;s a short rest, then it enters just after. Feeling that &ldquo;late&rdquo; entry now is what saves you later.</li>
<li><b>Right-hand fingering:</b> thumb = 1 (your lowest finger here), pinky = 5. Keep the hand relaxed and curved &mdash; no tension.</li>
<li>Bring each tune up to a <b>comfortable</b> speed, hands separate. Comfortable, not fast.</li>
</ol>

%s

<h3 class="sec">Mark where the melody lands (fill in from your sheet)</h3>
<div class="gridwrap">%s
<div class="gridcap">For bar 5: pencil an <b>orange dot</b> on each beat/&ldquo;&amp;&rdquo; where a right-hand note starts. You&rsquo;ll use this exact map in Step 3.</div></div>

<div class="box win"><div class="lbl">What good looks like</div>
<p>You can play the A-theme and the B-theme <b>without hunting for notes</b>, counting the rhythm out loud the whole way through.</p></div>

<div class="box warn"><div class="lbl">If it&rsquo;s not working</div>
<p><b>Sing the melody first</b>, then find it on the keys. Your ear leads your hand &mdash; if you can&rsquo;t sing it, you can&rsquo;t play it smoothly yet.</p></div>
%s
</div>
""" % (header(2, 'Right-hand melody', 'Step 2 &middot; 20&ndash;30 min', 'Today: know the tune <u>and its rhythm</u> cold. Hands separate is enough.'),
       RH_LEGEND, count_strip, FOOT)


# -------- PAGE 3
ex_grid = sync_grid([0, 3, 5], blank=False)   # illustrative example
bl_grid = sync_grid([], blank=True)
p3 = """
<div class="page">
%s
<div class="lead"><b>This is the step that fixes your blocker.</b> Hands-together isn&rsquo;t &ldquo;do two things at once.&rdquo; It&rsquo;s knowing <b>which right-hand note lands at the same moment as which left-hand note</b>. Find those moments &mdash; the <b>sync points</b> &mdash; and the rest falls into place. Work <b>tiny</b>: just bars 5&ndash;6.</div>

<h3 class="sec">Do this</h3>
<ol class="do">
<li><b>Find the sync points.</b> Play bars 5&ndash;6 very slowly and watch: each time a right-hand note sounds, which left-hand note is happening at that exact instant? Mark it on the grid below.</li>
<li><b>Block them.</b> For each sync point, press the left-hand note <b>and</b> its matching right-hand note <b>together, as one chord</b>. Ignore the in-between left-hand notes for now. This teaches your hands the alignment.</li>
<li><b>Expand, very slow (metronome ~40).</b> Now play the full left-hand arpeggio and <b>drop each right-hand note onto its sync point</b>. Say it out loud: &ldquo;&hellip; right-hand note &mdash; <i>now</i>.&rdquo;</li>
<li><b>Loop 2 bars.</b> It will feel clumsy and slow. <b>That clumsiness IS the learning</b> &mdash; don&rsquo;t rush it away. Raise the tempo only after 3 clean reps.</li>
<li><b>Keep the left hand running like a motor.</b> The right hand simply drops onto it.</li>
</ol>

<h3 class="sec">The sync-point grid</h3>
<div class="gridwrap">%s
<div class="gridcap"><b>Example only</b> &mdash; orange = right hand, blue = the steady left-hand eighths. Dashed lines = &ldquo;play these together.&rdquo; Now fill the blank one below with <b>your</b> bar 5.</div></div>
<div class="gridwrap">%s
<div class="gridcap">Your bar 5: pencil orange dots where the right hand enters, then draw a line down to the left-hand note underneath.</div></div>

<div class="box warn"><div class="lbl">Expect this &mdash; it&rsquo;s the key diagnostic</div>
<p>If your <b>left hand falls apart the second the right hand joins</b>, the left hand wasn&rsquo;t automatic enough yet. Go back to <b>left-hand-only for 2 minutes</b> (Step 1), then try again. This is normal. It&rsquo;s information, not failure.</p></div>

<div class="box win"><div class="lbl">What good looks like</div>
<p>Bars 5&ndash;8, hands together, <b>slow but correct</b>, with the left hand staying steady underneath. Slow and correct is a complete win today.</p></div>
%s
</div>
""" % (header(3, 'The bridge &mdash; hands together', 'Step 3 &middot; 25&ndash;30 min &middot; most important', 'Today: bars 5&ndash;8 hands together, <u>slow</u>. Don&rsquo;t chase speed.'),
       ex_grid, bl_grid, FOOT)


# -------- PAGE 4
pmap = piece_map()
p4 = """
<div class="page">
%s
<div class="lead">Get the B-theme working hands-together too, then practise by <b>mixing</b> instead of repeating &mdash; and drill the <b>joins</b> between sections, because that&rsquo;s where playing falls apart.</div>

<h3 class="sec">Do this</h3>
<ol class="do">
<li><b>B-theme hands-together first</b> (bars 13&ndash;16). It&rsquo;s the easy one &mdash; long held right-hand notes over the same left-hand loop. Quick confidence win, so start here.</li>
<li><b>Now MIX it up.</b> Instead of drilling one bit over and over, rotate <b>randomly</b>: A-theme &rarr; B-theme &rarr; intro (LH only) &rarr; back to A. Pull a &ldquo;card&rdquo; at random. It feels messier &mdash; that&rsquo;s the point: it builds memory that lasts, not memory that vanishes overnight.</li>
<li><b>Drill the joins.</b> A join is just &ldquo;last beat of one bar + first beat of the next.&rdquo; Isolate each as its own 2-bar chunk: <b>4&rarr;5</b> (LH-only into the melody entry), <b>8&rarr;9</b> (A repeats), <b>12&rarr;13</b> (A into B).</li>
</ol>

<h3 class="sec">Map of the piece (&#9650; = the joins to drill)</h3>
<div class="gridwrap">%s</div>

<h3 class="sec">Shuffle these &mdash; random order, not blocked</h3>
<div class="shuffle">
<span class="card">A-theme (HT)</span>
<span class="card">B-theme (HT)</span>
<span class="card">Intro (LH only)</span>
<span class="card seam">Join 4&rarr;5</span>
<span class="card seam">Join 8&rarr;9</span>
<span class="card seam">Join 12&rarr;13</span>
</div>
<div class="gridcap" style="text-align:left;">Why random beats repeating: alternating tasks forces more effortful processing each restart, which builds far more durable retention. <span class="src">[sourced: Carter &amp; Grahn 2016, Frontiers in Psychology]</span></div>

<div class="box win"><div class="lbl">What good looks like</div>
<p>You can play A and B hands-together, and cross the joins <b>without fully stopping</b>.</p></div>
%s
</div>
""" % (header(4, 'Extend + mix', 'Step 4 &middot; 25&ndash;30 min', 'Today: B-theme together + smooth the joins. Mixing &gt; repeating.'),
       pmap, FOOT)


# -------- PAGE 5
pmap2 = piece_map()
p5 = """
<div class="page">
%s
<div class="lead"><b>Today&rsquo;s finish line:</b> one slow, continuous, hands-together pass. <b>Slow and unbroken beats fast and stop-start.</b> That is the entire win for Friday &mdash; nothing more is needed.</div>

<h3 class="sec">Do this</h3>
<ol class="do">
<li><b>Continuity pass at ~50&ndash;60.</b> Play the whole thing hands-together. <b>Rule: do not stop to fix mistakes.</b> If you stumble, keep the left hand going and rejoin with the right. <b>Flow beats perfection</b> today.</li>
<li><b>Find your 2 worst spots.</b> Isolate each (back to the chunk method, 3&ndash;4 min each), then drop it straight back into the piece.</li>
<li><b>Finish on a win.</b> Play <b>one</b> clean, slightly-slower full pass so the <i>last</i> thing you play is a success &mdash; that&rsquo;s what your brain keeps overnight.</li>
</ol>

<h3 class="sec">The full lap (play it through, start to finish)</h3>
<div class="gridwrap">%s</div>

<div class="tempo"><b style="font-size:12px;">Tempo ladder:</b>
<span class="trung today">50</span><span class="trung today">60</span>
<span class="arrow">&rarr; today stop here &rarr;</span>
<span class="trung wknd">70</span><span class="trung wknd">80</span><span class="trung wknd">90</span><span class="trung wknd">100</span></div>

<h3 class="sec">The weekend plan</h3>
<div class="wkplan">
<div class="day today"><div class="dlbl">FRI &mdash; today</div><p>Slow + solid + <b>continuous</b>. Hands together, unbroken, even if slow. Done = win.</p></div>
<div class="day"><div class="dlbl">SAT</div><p>Same, but climb the tempo ladder toward 100. Smooth the joins.</p></div>
<div class="day"><div class="dlbl">SUN</div><p>Polish: dynamics (soft/loud), let it breathe, play it for someone.</p></div>
</div>

<div class="box win"><div class="lbl">Remember tonight</div>
<p><b>Sleep does the real locking-in.</b> Tomorrow&rsquo;s first run will feel smoother than tonight&rsquo;s last &mdash; for free, no extra practice. So end clean and let it rest. <span class="src">[sourced: Walker &amp; Stickgold, sleep-dependent motor-memory consolidation]</span></p></div>
%s
</div>
""" % (header(5, 'Put it together', 'Step 5 &middot; 25&ndash;30 min', 'Today: ONE slow, continuous pass. Slow &amp; unbroken = the whole win.'),
       pmap2, FOOT)


html = ('<!doctype html><html><head><meta charset="utf-8"><style>%s</style></head>'
        '<body>%s%s%s%s%s</body></html>') % (CSS, p1, p2, p3, p4, p5)

out_html = os.path.join(OUT_DIR, 'piano-amelie-printable.html')
with open(out_html, 'w') as f:
    f.write(html)
print('WROTE', out_html)
