fix: Step1 flashcard shows term before tap, hide hint when revealed, SW v12

Made-with: Cursor
This commit is contained in:
posimai 2026-04-19 14:35:44 +09:00
parent 152e248f46
commit bfebf38121
2 changed files with 44 additions and 19 deletions

View File

@ -153,10 +153,8 @@ header{display:flex;align-items:center;justify-content:space-between;padding:0 1
.card-title svg{width:13px;height:13px;color:var(--accent)} .card-title svg{width:13px;height:13px;color:var(--accent)}
/* Unit header */ /* Unit header */
.unit-header{display:flex;align-items:flex-start;gap:10px;margin-bottom:18px;flex-wrap:wrap} .unit-header{margin-bottom:18px}
.unit-back{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--text2);cursor:pointer;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);transition:color .15s,border-color .15s;background:var(--surface);backdrop-filter:blur(8px);flex-shrink:0;font-family:inherit} .unit-meta{min-width:0}
.unit-back:hover{color:var(--accent);border-color:var(--accent-border)}
.unit-meta{flex:1;min-width:0}
.unit-cat-badge{font-size:10px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--accent);background:var(--accent-dim);border:1px solid var(--accent-border);border-radius:20px;padding:3px 9px;display:inline-block;margin-bottom:6px} .unit-cat-badge{font-size:10px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--accent);background:var(--accent-dim);border:1px solid var(--accent-border);border-radius:20px;padding:3px 9px;display:inline-block;margin-bottom:6px}
.unit-title{font-size:19px;font-weight:600;letter-spacing:-.01em;line-height:1.3} .unit-title{font-size:19px;font-weight:600;letter-spacing:-.01em;line-height:1.3}
@ -353,10 +351,12 @@ header{display:flex;align-items:center;justify-content:space-between;padding:0 1
.step-pip{height:4px;flex:1;border-radius:2px;background:var(--border);transition:background .3s} .step-pip{height:4px;flex:1;border-radius:2px;background:var(--border);transition:background .3s}
.step-pip.s-active{background:var(--accent)} .step-pip.s-active{background:var(--accent)}
.step-pip.s-done{background:rgba(74,222,128,.5)} .step-pip.s-done{background:rgba(74,222,128,.5)}
.flash-card{background:var(--surface2);border:2px solid var(--border);border-radius:var(--radius);padding:22px 18px;text-align:center;min-height:120px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;transition:border-color .2s,background .15s;margin-bottom:14px;user-select:none} .flash-card{background:var(--surface2);border:2px solid var(--border);border-radius:var(--radius);padding:22px 18px;text-align:center;min-height:120px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;transition:border-color .2s,background .15s;margin-bottom:14px;user-select:none;-webkit-tap-highlight-color:transparent}
.flash-card:hover{border-color:var(--accent-border);background:var(--accent-dim)} .flash-card:hover{border-color:var(--accent-border);background:var(--accent-dim)}
.flash-card-front{font-size:12px;color:var(--text3);letter-spacing:.04em;margin-bottom:4px} .flash-card-front{display:flex;flex-direction:column;align-items:center;gap:10px;width:100%}
.flash-card-back{font-size:13px;color:var(--text);line-height:1.75;padding-top:12px;border-top:1px solid var(--border);width:100%;margin-top:10px} .flash-card-term{font-size:15px;font-weight:600;color:var(--text);line-height:1.45;letter-spacing:-.01em}
.flash-card-hint{font-size:11px;color:var(--text3);letter-spacing:.04em}
.flash-card-back{font-size:13px;color:var(--text);line-height:1.75;padding-top:12px;border-top:1px solid var(--border);width:100%;margin-top:0;text-align:left}
.step-count{font-size:10px;color:var(--text3);text-align:center;margin-bottom:10px;letter-spacing:.04em} .step-count{font-size:10px;color:var(--text3);text-align:center;margin-bottom:10px;letter-spacing:.04em}
.s2choice{display:flex;gap:10px;margin-bottom:10px} .s2choice{display:flex;gap:10px;margin-bottom:10px}
.s2btn{flex:1;padding:16px 10px;border-radius:var(--radius);border:2px solid var(--border);background:var(--surface);font-size:14px;font-weight:600;color:var(--text2);cursor:pointer;transition:border-color .2s,background .15s,color .15s;font-family:'Geist',sans-serif;line-height:1.35} .s2btn{flex:1;padding:16px 10px;border-radius:var(--radius);border:2px solid var(--border);background:var(--surface);font-size:14px;font-weight:600;color:var(--text2);cursor:pointer;transition:border-color .2s,background .15s,color .15s;font-family:'Geist',sans-serif;line-height:1.35}
@ -590,10 +590,6 @@ header{display:flex;align-items:center;justify-content:space-between;padding:0 1
<!-- UNIT VIEW --> <!-- UNIT VIEW -->
<div x-show="currentUnit && !weakDrillActive"> <div x-show="currentUnit && !weakDrillActive">
<div class="unit-header"> <div class="unit-header">
<button class="unit-back sidebar-toggle" @click="goHome()">
<i data-lucide="arrow-left" style="width:12px;height:12px"></i>
ホーム
</button>
<div class="unit-meta" x-show="currentUnit"> <div class="unit-meta" x-show="currentUnit">
<div class="badge-row"> <div class="badge-row">
<div class="unit-cat-badge" x-text="currentUnit?.catLabel"></div> <div class="unit-cat-badge" x-text="currentUnit?.catLabel"></div>
@ -638,13 +634,14 @@ header{display:flex;align-items:center;justify-content:space-between;padding:0 1
Step 1 — 用語確認 Step 1 — 用語確認
</div> </div>
<div class="step-count" x-text="(stepKpIdx+1) + ' / ' + (currentUnit?.keypoints?.length||0) + ' ポイント'"></div> <div class="step-count" x-text="(stepKpIdx+1) + ' / ' + (currentUnit?.keypoints?.length||0) + ' ポイント'"></div>
<div class="flash-card" @click="revealFlash()"> <div class="flash-card" role="button" tabindex="0" :aria-expanded="stepFlashRevealed"
<div class="flash-card-front">タップして確認</div> @click="revealFlash()" @keydown.enter.prevent="revealFlash()" @keydown.space.prevent="revealFlash()">
<div class="flash-card-front" x-show="!stepFlashRevealed && keypointHasFlip(stepKpIdx)">
<div class="flash-card-term" x-text="keypointTerm(stepKpIdx)"></div>
<div class="flash-card-hint">タップして全文を表示</div>
</div>
<div class="flash-card-back" x-show="stepFlashRevealed" <div class="flash-card-back" x-show="stepFlashRevealed"
x-html="currentUnit?.keypoints?.[stepKpIdx]"></div> x-html="currentUnit?.keypoints?.[stepKpIdx]"></div>
<div x-show="!stepFlashRevealed" style="font-size:11px;color:var(--text3);margin-top:8px">
ポイント <span x-text="stepKpIdx+1"></span>
</div>
</div> </div>
<div class="step-action-row"> <div class="step-action-row">
<button class="btn-sm btn-accent" @click="nextStepFlash()" x-show="stepFlashRevealed"> <button class="btn-sm btn-accent" @click="nextStepFlash()" x-show="stepFlashRevealed">
@ -1547,7 +1544,7 @@ function bokiApp(){
this.stepMode=true; this.stepMode=true;
this.stepStep=1; this.stepStep=1;
this.stepKpIdx=0; this.stepKpIdx=0;
this.stepFlashRevealed=false; this.resetFlashRevealState();
this.stepDrillIdx=0; this.stepDrillIdx=0;
this.stepDrillAnswered=false; this.stepDrillAnswered=false;
this.stepDrillSelected=-1; this.stepDrillSelected=-1;
@ -1567,14 +1564,42 @@ function bokiApp(){
if(this.stepStep>n) return 's-done'; if(this.stepStep>n) return 's-done';
return ''; return '';
}, },
_kpDelimiterIndex(kp){
if(!kp||typeof kp!=='string') return -1;
const iw=kp.indexOf('');
const ia=kp.indexOf(':');
if(iw<0&&ia<0) return -1;
if(iw<0) return ia;
if(ia<0) return iw;
return Math.min(iw,ia);
},
keypointHasFlip(idx){
const kp=(this.currentUnit?.keypoints||[])[idx];
const i=this._kpDelimiterIndex(kp);
return i>0;
},
keypointTerm(idx){
const kp=(this.currentUnit?.keypoints||[])[idx];
const i=this._kpDelimiterIndex(kp);
return i>0 ? kp.slice(0,i).trim() : '';
},
resetFlashRevealState(){
this.stepFlashRevealed=!this.keypointHasFlip(this.stepKpIdx);
},
revealFlash(){ revealFlash(){
if(!this.keypointHasFlip(this.stepKpIdx)){
return;
}
if(this.stepFlashRevealed){
return;
}
this.stepFlashRevealed=true; this.stepFlashRevealed=true;
}, },
nextStepFlash(){ nextStepFlash(){
const kps=this.currentUnit?.keypoints||[]; const kps=this.currentUnit?.keypoints||[];
if(this.stepKpIdx<kps.length-1){ if(this.stepKpIdx<kps.length-1){
this.stepKpIdx++; this.stepKpIdx++;
this.stepFlashRevealed=false; this.resetFlashRevealState();
} else { } else {
// All keypoints done — go to step 2 (or 3 if no drills) // All keypoints done — go to step 2 (or 3 if no drills)
const drills=DRILLS[this.currentUnit?.id]||[]; const drills=DRILLS[this.currentUnit?.id]||[];

2
sw.js
View File

@ -1,5 +1,5 @@
// posimai-boki SW — stale-while-revalidate + skipWaiting // posimai-boki SW — stale-while-revalidate + skipWaiting
const CACHE = 'posimai-boki-v10'; const CACHE = 'posimai-boki-v12';
const STATIC = ['/', '/index.html', '/manifest.json', '/logo.png']; const STATIC = ['/', '/index.html', '/manifest.json', '/logo.png'];
self.addEventListener('install', e => { self.addEventListener('install', e => {