mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 18:39:33 +01:00
fix(story-mode): a three-row bar on phones, buttons for panels out of view, loop words that match the marks
- The bar on a phone took four rows (216 px of a 664 px screen) with the close button alone on the last; it now takes three (170 px): title and close, the turn, the view and Save image. The drawer starts exactly under it and follows it when the phone turns (the bar is observed). - A panel below the fold had no buttons until it was scrolled to (only drawn panels get click regions), so Tab skipped it. A quiet frame now draws one such panel, a band at a time; its entrance still plays when it comes into view. - "Fix and test: the first run fails, the second passes." was chosen by rounds, so a loop with three runs (a failing test, then ruff, then a pass) said it under ✗ ✗ ✓. It now needs exactly two runs; that loop reads "Fix and test, 2 rounds: 2 runs fail, then it passes.", and the corpus pins every loop's marks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
3f1ecfe83a
commit
76d5c61eda
14 files changed
+225
-6
No files matched your search
@@ -218,6 +218,37 @@ body.story-open {
|
||||
}
|
||||
}
|
||||
|
||||
/* A phone: three rows (title and close, the turn, the view and Save image), not four with the
|
||||
close button alone at the bottom. Tab order stays the DOM's; focus starts on close anyway. */
|
||||
@media (max-width: 600px) {
|
||||
.story-bar {
|
||||
gap: 8px 10px;
|
||||
padding-block: 8px;
|
||||
}
|
||||
.story-brand {
|
||||
order: 0;
|
||||
flex: 1 1 0;
|
||||
}
|
||||
.story-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
.story-close {
|
||||
order: 1;
|
||||
}
|
||||
.story-nav {
|
||||
order: 2;
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
.story-turns {
|
||||
max-width: none;
|
||||
}
|
||||
.story-seg,
|
||||
.story-live,
|
||||
.story-save {
|
||||
order: 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main: the sheet and the wire */
|
||||
.story-main {
|
||||
overflow: auto;
|
||||
@@ -731,7 +762,7 @@ body.story-open .toast-container {
|
||||
padding-right: max(16px, env(safe-area-inset-right, 0px));
|
||||
}
|
||||
.story-drawer {
|
||||
top: calc(var(--story-bar-h, 18vh) + 6px);
|
||||
top: var(--story-bar-h, 18vh);
|
||||
left: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
@@ -1894,12 +1894,16 @@ Object.assign(CodemanApp.prototype, {
|
||||
|
||||
_storyStartRuntime() {
|
||||
const st = this._story;
|
||||
const bar = st.root.querySelector('.story-bar');
|
||||
st.ro = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
// The bar's height places the phone drawer below it, and changes when the phone turns.
|
||||
if (entry.target === bar) st.root.style.setProperty('--story-bar-h', `${bar.offsetHeight}px`);
|
||||
const rt = st.panels.find((p) => p.el === entry.target);
|
||||
if (rt) this._storySizePanel(rt);
|
||||
}
|
||||
});
|
||||
if (bar) st.ro.observe(bar);
|
||||
st.io = new IntersectionObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
const rt = st.panels.find((p) => p.el === entry.target);
|
||||
@@ -1947,6 +1951,16 @@ Object.assign(CodemanApp.prototype, {
|
||||
drawn++;
|
||||
}
|
||||
st.drawCursor = n ? ((st.drawCursor || 0) + 1) % n : 0;
|
||||
// A quiet frame draws a panel out of view (one band of it), so its buttons exist for the
|
||||
// keyboard and a screen reader before anyone scrolls to it. Its clock waits, so the entrance
|
||||
// still plays when it comes into view.
|
||||
if (!drawn) {
|
||||
const off = st.panels.find((p) => !p.visible && p.pending);
|
||||
if (off) {
|
||||
off.pending = false;
|
||||
this._storyDrawPanel(off);
|
||||
}
|
||||
}
|
||||
}
|
||||
st.raf = requestAnimationFrame(loop);
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user