diff --git a/app.py b/app.py index d4e8f83..498f396 100644 --- a/app.py +++ b/app.py @@ -971,8 +971,21 @@ def analyze(draft: Draft): for e in entries: e["target"] = mode - return {"lines": lines, "tokens": toks_out, - "groups": groups_out, "stanzas": stanzas, "meter": meter} + # per-word stress for the optional dots layer (2+ syllables only — + # a dot under every monosyllable is noise, not information) + stress_out = [] + for t in tokens: + ph = phones_for(t["word"]) + if not ph: + continue + st = "".join("1" if p[-1] in "12" else "0" + for p in ph.split() if p[-1].isdigit()) + if len(st) >= 2: + stress_out.append({"l": t["line"], "s": t["start"], + "e": t["end"], "st": st}) + + return {"lines": lines, "tokens": toks_out, "groups": groups_out, + "stanzas": stanzas, "meter": meter, "stress": stress_out} # -------------------------------------------------------------------------- diff --git a/static/index.html b/static/index.html index 0aa0de9..d190799 100644 --- a/static/index.html +++ b/static/index.html @@ -93,7 +93,7 @@ overflow: hidden; } /* highlight layer + textarea share the exact same box metrics */ - #highlight, #editor { + #highlight, #stresslayer, #editor { position: absolute; inset: 0; margin: 0; border: 0; padding: 22px 24px; @@ -110,6 +110,17 @@ color: transparent; z-index: 1; } + #stresslayer { + pointer-events: none; + color: transparent; + z-index: 0; + } + .sw { position: relative; } + .sd { + position: absolute; left: 0; right: 0; top: 1.18em; + text-align: center; font-size: 8px; letter-spacing: 2px; + line-height: 1; color: var(--accent-2); white-space: nowrap; + } #editor { background: transparent; color: var(--ink); @@ -146,6 +157,12 @@ } .scheme-readout b { color: var(--accent-2); letter-spacing: 0.15em; } .scheme-readout .offline { color: var(--r6); letter-spacing: 0.02em; } + .mtoggle { + display: flex; align-items: center; gap: 6px; + color: var(--ink-dim); font-size: 12px; cursor: pointer; user-select: none; + } + .mtoggle input { accent-color: var(--accent); } + .mtoggle:hover { color: var(--ink); } /* ---- side panel ---- */ aside { @@ -232,7 +249,7 @@ header { flex-direction: column; align-items: flex-start; gap: 2px; padding-bottom: 8px; } .brand { font-size: 24px; } .editor-shell { min-height: 55dvh; } - #highlight, #editor { font-size: 16px; } /* sub-16px makes iOS zoom-jump */ + #highlight, #stresslayer, #editor { font-size: 16px; } /* sub-16px makes iOS zoom-jump */ aside { min-height: 45dvh; } .toolbar { gap: 8px; } .scheme-readout { margin-left: 0; width: 100%; } @@ -250,6 +267,7 @@