<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<!-- 2026-10-31 観察シートを作り直した版（店の方がスマホで使う前提）。前の版は serving-robot-observation-v1.html に残す。記録はこの端末の中だけに残る（保存のキーは試作 obs-sheet-v2 と同じ） -->
<title>観察シート</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=Noto+Sans+JP:wght@400;500;700&family=IBM+Plex+Mono:wght@500;600&display=swap" rel="stylesheet">
<style>
:root{--bg:#f7f7f7;--panel:#fff;--ink:#242424;--ink-2:#555;--ink-3:#8a8a8a;--line:#e2e2e2;--soft:#efefef;--on-ink:#fff;
--stuck:#b3372a;--stuck-bg:#fae6e3;--go:#1d6b47;--go-bg:#e3f1e9;
--f-ui:"Inter","Noto Sans JP",system-ui,-apple-system,"Hiragino Sans",sans-serif;--f-num:"IBM Plex Mono",ui-monospace,Menlo,monospace;--r:12px;color-scheme:light}
*{box-sizing:border-box}[hidden]{display:none!important}
html,body{margin:0}
body{background:var(--bg);color:var(--ink);font-family:var(--f-ui);font-size:18px;line-height:1.5;-webkit-text-size-adjust:100%}
.wrap{max-width:520px;margin:0 auto;padding:16px max(16px,env(safe-area-inset-left)) 120px}
.top{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:44px}
.top b{font-size:15px;color:var(--ink-2);font-weight:600}
h1{font-size:24px;line-height:1.35;margin:8px 0 6px}
.say{font-size:17px;color:var(--ink-2);margin:0 0 16px}
.num{font-family:var(--f-num);font-variant-numeric:tabular-nums}
button{font-family:var(--f-ui);cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation}
button:focus-visible{outline:3px solid var(--ink);outline-offset:2px}
.big{display:flex;align-items:center;justify-content:center;width:100%;min-height:72px;border-radius:var(--r);border:2px solid var(--ink);background:var(--ink);color:var(--on-ink);font-size:22px;font-weight:700}
.big.sub{background:var(--panel);color:var(--ink)}
.big:active,.tile:active,.pick:active{transform:scale(.98)}
.link{background:none;border:0;padding:12px 4px;color:var(--ink-2);font-size:16px;text-decoration:underline;min-height:44px}
.toast{position:fixed;left:0;right:0;bottom:0;padding:12px max(16px,env(safe-area-inset-left)) calc(12px + env(safe-area-inset-bottom));background:var(--ink);color:var(--on-ink);display:flex;align-items:center;gap:12px;justify-content:space-between;font-size:17px;z-index:20}
.toast button{background:var(--on-ink);color:var(--ink);border:0;border-radius:10px;font-size:17px;font-weight:700;padding:12px 18px;min-height:52px;white-space:nowrap}
.done{font-size:15px;color:var(--ink-3)}
.sheet-list{list-style:none;margin:8px 0 0;padding:0;background:var(--panel);border-radius:var(--r);border:1px solid var(--line)}
.sheet-list li{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 16px;border-top:1px solid var(--line);font-size:17px}
.sheet-list li:first-child{border-top:0}
.sheet-list .x{background:var(--soft);border:0;border-radius:10px;font-size:15px;padding:10px 14px;min-height:44px;color:var(--ink)}
@media (prefers-reduced-motion:reduce){.big:active,.tile:active,.pick:active{transform:none}}
</style>
<style>
:root{--shadow:0 1px 2px rgba(0,0,0,.06),0 4px 14px rgba(0,0,0,.08)}
.wrap{padding-bottom:24px}
.top b{font-size:20px;color:var(--ink);font-weight:700}
.top .link{font-size:18px}
.screen{display:flex;flex-direction:column;min-height:calc(100vh - 40px);min-height:calc(100svh - 40px)}
.mid{flex:1;display:flex;flex-direction:column;justify-content:center;padding-bottom:6vh}
.bottom-link{text-align:center;padding-top:20px}
.maker{margin:28px 0 0;text-align:center;font-size:14px;color:var(--ink-3)}
.maker a{color:var(--ink-3)}
.about{margin:0 0 14px;font-size:16px;color:var(--ink-2)}
.about summary{cursor:pointer;font-weight:700;color:var(--ink);padding:8px 0}
.about ul{margin:4px 0 0;padding-left:1.2em}
.about li{margin:4px 0}
.bottom-link .link{font-size:18px}
.listbtn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:56px;padding:0 26px;border:0;border-radius:99px;background:var(--panel);box-shadow:var(--shadow);color:var(--ink);font-size:19px;font-weight:700}
.listbtn:active{transform:scale(.98)}
.bottom-link .home{display:block;margin:14px auto 0;font-size:16px;color:var(--ink-3)}
.card{background:var(--panel);border-radius:var(--r);box-shadow:var(--shadow)}
.purpose{display:grid;gap:14px}
.purpose button{display:block;width:100%;text-align:left;border:0;padding:44px 22px;color:var(--ink);font-size:21px;font-weight:700;line-height:1.4}
.purpose button small{display:block;font-size:16px;font-weight:400;color:var(--ink-2);margin-top:4px}
.picks{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.pick{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;min-height:124px;padding:10px;border:0;color:var(--ink);font-size:20px;font-weight:700}
.pick .c{display:flex;align-items:baseline;gap:2px}
.pick .c .num{font-size:36px;font-weight:600;line-height:1.1}
.pick .c small{font-size:15px;font-weight:500;color:var(--ink-3)}
.pick.wide{grid-column:1/-1;min-height:96px}
.cnt{display:flex;align-items:baseline;gap:2px}
.cnt .num{font-size:28px;font-weight:600;line-height:1}
.cnt small{font-size:14px;color:var(--ink-3);font-weight:500}
.timebox{padding:28px 16px;text-align:center;margin:8px 0 16px}
.timebox .num{font-size:64px;font-weight:600;line-height:1}
.timebox.run{outline:2px solid var(--ink)}
.timebox .when{font-size:17px;color:var(--ink-2);margin-top:10px}
.big.stop{background:var(--stuck);border-color:var(--stuck)}
.big svg{flex:none;margin-right:10px}
.big.line{background:#06C755;border-color:#06C755;color:#fff}
.big.armed{background:var(--stuck);border-color:var(--stuck);color:#fff}
.result{font-size:40px;font-weight:700;text-align:center;margin:0 0 4px}
.stack{display:grid;gap:10px}
.prog{font-size:16px;color:var(--ink-2);text-align:center;margin-top:14px}
.tally{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:0 0 14px}
.tally button{min-height:84px;border:0;border-radius:var(--r);background:var(--panel);box-shadow:var(--shadow);font-size:18px;font-weight:700;color:var(--ink);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}
.tally .num{font-size:28px}
.field{margin-bottom:18px}
.field label{display:block;font-size:17px;color:var(--ink-2);margin-bottom:6px}
.field input{width:100%;min-height:60px;font:20px var(--f-ui);padding:10px 14px;border:0;border-radius:var(--r);background:var(--panel);box-shadow:var(--shadow);color:var(--ink)}
.step{display:flex;align-items:center;background:var(--panel);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden}
.step button{width:72px;min-height:64px;border:0;background:transparent;font-size:30px;color:var(--ink)}
.step output{flex:1;text-align:center;font-size:26px;font-weight:700}
.counter{padding:28px 16px;text-align:center;margin:8px 0 16px}
.counter .num{font-size:80px;font-weight:600;line-height:1}
.sum{padding:4px 16px;margin:6px 0 18px}
.sum .row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;padding:14px 0;border-top:1px solid var(--soft)}
.sum .row:first-child{border-top:0}
.sum .row b{font-size:18px;white-space:nowrap}
.sum .row .v{text-align:right}
.sum .row .v .num{font-size:22px;font-weight:600}
.sum .row .v small{display:block;font-size:14px;color:var(--ink-3)}
h2{font-size:20px;margin:22px 0 4px}
.sheet-list{border:0;box-shadow:var(--shadow)}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chips button{min-height:52px;padding:0 18px;border-radius:99px;border:0;background:var(--panel);box-shadow:var(--shadow);font-size:18px;font-weight:600;color:var(--ink)}
.chips button[aria-pressed="true"]{background:var(--ink);color:var(--on-ink)}
.field textarea{width:100%;min-height:84px;font:18px var(--f-ui);padding:12px 14px;border:0;border-radius:var(--r);background:var(--panel);box-shadow:var(--shadow);color:var(--ink);margin-top:10px;resize:vertical}
.tally.io .card{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:14px 8px;min-height:120px}
.tally.io .num{font-size:52px;font-weight:600;line-height:1.1}
.tally.io small{font-size:15px;color:var(--ink-2)}
.purpose button.cont{outline:2px solid var(--ink)}
.purpose .badge{display:inline-block;margin-left:8px;padding:2px 10px;border-radius:99px;background:var(--ink);color:var(--on-ink);font-size:14px;font-weight:700;vertical-align:3px}
.resume{padding:20px 18px;margin-bottom:28px}
.resume b{font-size:19px}
.purpose-tag{font-size:15px;color:var(--ink-2)}
</style></head><body><div class="wrap">

<!-- 1 入り口 -->
<div id="sEntry" class="screen" hidden>
  <div class="top"><b>観察シート</b></div>
  <div class="mid">
    <div class="card resume" id="resume" hidden>
      <b>前の記録が残っています</b>
      <p class="say" id="resumeSum" style="margin:4px 0 4px"></p>
      <p class="say" style="margin:0 0 14px">続けるときは、下の「続きから」のカードを押してください。</p>
      <button class="big sub" id="newBtn">記録を消して新しく始める</button>
      <p class="say" id="newNote" style="text-align:center;margin-top:8px" hidden></p>
    </div>
    <h1>何のために測りますか？</h1>
    <p class="say">お店の人の作業の時間を、スマホで測ります。<br>記録はこのスマホの中にだけ残ります。送るまで、どこにも届きません。</p>
    <div class="purpose">
      <button class="card" data-purpose="pre">ロボットの導入を考えている<small>入れたらどう変わるかを試算する材料にします</small></button>
      <button class="card" data-purpose="post">ロボットを入れていて、改善したい<small>ロボットの往復と止まった回数も測ります</small></button>
      <button class="card" data-purpose="ops">ロボットはないが、店の回し方を試算したい<small>人数や配置を変えたらどうなるかを試算する材料にします</small></button>
    </div>
  </div>
  <p class="maker">このシートは <a href="https://pixelstomotors.com/" target="_blank" rel="noopener">Pixels to Motors</a> が作りました</p>
</div>

<!-- 2 お店のこと -->
<div id="sStore" class="screen" hidden>
  <div class="top"><button class="link" id="storeBack">← もどる</button></div>
  <div class="mid">
    <h1>お店のことを教えてください</h1>
    <p class="say">わからなければ、そのまま進めます。</p>
    <div class="field"><label for="fName">お店の名前</label><input id="fName" type="text" autocomplete="off" placeholder="例 〇〇店"></div>
    <div class="field"><label>今いるホールのスタッフ</label><div class="step"><button data-st="staff" data-d="-1" aria-label="1人減らす">−</button><output id="oStaff"></output><button data-st="staff" data-d="1" aria-label="1人増やす">＋</button></div></div>
    <div class="field"><label for="fTables">卓の数（だいたい）</label><input id="fTables" type="number" inputmode="numeric" min="1" placeholder="例 35"></div>
    <div class="field"><label>時間帯</label><div class="chips" id="cTime"></div></div>
    <div class="field" id="robotField"><label>動いているロボット</label><div class="step"><button data-st="robots" data-d="-1" aria-label="1台減らす">−</button><output id="oRobots"></output><button data-st="robots" data-d="1" aria-label="1台増やす">＋</button></div></div>
    <div class="field"><label>今日のようす（いくつでも）</label><div class="chips" id="cTags"></div>
      <textarea id="fNote" placeholder="ほかに気づいたこと（なくてもよい）"></textarea></div>
    <button class="big" id="storeGo">測りはじめる</button>
  </div>
</div>

<!-- 3 何を測りますか -->
<div id="sMenu" class="screen" hidden>
  <div class="top"><b>観察シート</b></div>
  <div class="mid">
    <h1>何を測りますか？</h1>
    <div class="picks" id="picks"></div>
    <div class="bottom-link"><button class="listbtn" data-go="sList"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="4" width="14" height="17" rx="2"/><path d="M9 4V3h6v1"/><path d="M9 10h6M9 14h6M9 18h4"/></svg>記録を見る</button><button class="link home" data-go="sEntry">最初に戻る</button></div>
  </div>
</div>

<!-- 4 測る -->
<div id="sRun" class="screen" hidden>
  <div class="top"><button class="link" id="runBack">← もどる</button><span class="cnt" id="runCnt"></span></div>
  <div class="mid">
    <h1 id="runT" style="text-align:center"></h1>
    <div class="timebox card" id="tb"><div class="num" id="tnum">0:00</div><div class="when" id="twhen"></div></div>
    <div class="tally" id="tally" hidden>
      <button id="tStop">止まった<span class="num" id="nStop">0</span></button>
      <button id="tHelp">人が動かした<span class="num" id="nHelp">0</span></button>
    </div>
    <button class="big" id="startBtn">スタート</button>
    <button class="big stop" id="stopBtn" hidden>ストップ</button>
    <div style="text-align:center"><button class="link" id="cancelBtn" hidden>やめる（記録しない）</button></div>
    <div class="bottom-link"><button class="link home" data-go="sEntry">最初に戻る</button></div>
  </div>
</div>

<!-- 5 記録した直後 -->
<div id="sDone" class="screen" hidden>
  <div class="top"><b id="doneT"></b></div>
  <div class="mid">
    <div class="result num" id="doneR"></div>
    <p class="say" style="text-align:center">記録しました</p>
    <div class="stack">
      <button class="big" id="againBtn">もう一度測る</button>
      <button class="big sub" data-go="sMenu">ほかの作業を測る</button>
    </div>
    <div style="text-align:center"><button class="link" id="undoBtn">まちがえたので消す</button></div>
    <p class="prog" id="doneP"></p>
    <div class="bottom-link"><button class="listbtn" data-go="sList"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="4" width="14" height="17" rx="2"/><path d="M9 4V3h6v1"/><path d="M9 10h6M9 14h6M9 18h4"/></svg>記録を見る</button><button class="link home" data-go="sEntry">最初に戻る</button></div>
  </div>
</div>

<!-- 6 お客さんの出入りを数える -->
<div id="sArrive" class="screen" hidden>
  <div class="top"><button class="link" data-go="sMenu">← もどる</button></div>
  <div class="mid">
    <h1 style="text-align:center">お客さんの出入り</h1>
    <div class="field" id="occField"><label for="fOcc">数えはじめたときに、お客さんがいる卓の数</label><input id="fOcc" type="number" inputmode="numeric" min="0" placeholder="例 20"></div>
    <div class="tally io">
      <div class="card"><small>入ってきた</small><span class="num" id="aN">0</span><small>組</small></div>
      <div class="card"><small>会計した</small><span class="num" id="lN">0</span><small>組</small></div>
    </div>
    <div class="stack">
      <button class="big" id="arriveBtn">入ってきた（1組）</button>
      <button class="big" id="leaveBtn">会計した（1組）</button>
    </div>
    <p class="say" style="text-align:center;margin-top:12px">入口から入ってきたら・レジで会計を終えたら押す</p>
    <button class="big sub" data-go="sMenu" style="margin-top:4px">ほかの作業を測る</button>
    <div class="bottom-link"><button class="listbtn" data-go="sList"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="4" width="14" height="17" rx="2"/><path d="M9 4V3h6v1"/><path d="M9 10h6M9 14h6M9 18h4"/></svg>記録を見る</button><button class="link home" data-go="sEntry">最初に戻る</button></div>
  </div>
</div>

<!-- 7 記録 -->
<div id="sList" hidden>
  <div class="top"><button class="link" id="listBack">← もどる</button><span class="purpose-tag" id="pTag"></span></div>
  <h1>測った記録</h1>
  <div class="sum card" id="sum"></div>
  <h2>記録を送る</h2>
  <p class="say" style="margin:0 0 10px">店長・お店の管理の方・ロボットの担当の方に送ります。どちらかを押すと送る文が入った状態で開くので、送る相手を選んでください。</p>
  <details class="about"><summary>送った記録の扱い</summary>
    <ul>
      <li>このシートは、記録をどこにも送りません。送るのは、下のボタンを押したときだけです。</li>
      <li>LINE もメールも、送る相手は自分で選びます。</li>
      <li>送った記録は、受け取った相手の決まりで扱われます。</li>
      <li>このスマホの記録は、「はじめから記録する」で消せます。</li>
    </ul>
  </details>
  <div class="stack">
    <button class="big line" id="lineBtn"><svg width="26" height="26" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 3C6.5 3 2 6.6 2 11c0 2.6 1.6 4.9 4.1 6.4-.2.9-.7 2.4-1 3.1-.1.3.2.6.5.4 1.1-.6 3.2-1.9 4.3-2.6.7.1 1.4.2 2.1.2 5.5 0 10-3.6 10-8S17.5 3 12 3z"/></svg>LINEで送る</button>
    <button class="big sub" id="mailBtn"><svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3.5 6.5 12 13l8.5-6.5"/></svg>メールで送る</button>
  </div>
  <p class="say" style="margin-top:10px">写真や図面があれば、LINE やメールで一緒に送れます。写っている人の扱いは、お店の決まりに合わせてください。</p>
  <h2>1回ずつの記録</h2>
  <ul class="sheet-list" id="list"></ul>
  <button class="big sub" id="resetBtn" style="margin-top:24px">はじめから記録する</button>
  <p class="say" id="resetNote" style="text-align:center;margin-top:8px" hidden>もう一度押すと、記録を全部消します</p>
  <div class="bottom-link"><button class="link home" data-go="sEntry">最初に戻る</button></div>
</div>

</div><div class="toast" id="toast" hidden role="status"><span id="toastMsg"></span><button type="button" id="toastUndo">取り消す</button></div>
<script>
var LS='p2m-obs-sheet-v2';
var TASKS=[
 {k:'pay',t:'会計',s:'お客さんがレジに立ったら',e:'レジを離れたら',sim:'90秒'},
 {k:'clear',t:'片付け',s:'お皿をまとめ始めたら',e:'まとめ終わったら',sim:'40秒'},
 {k:'wipe',t:'テーブルを拭く',s:'拭き始めたら',e:'セットし終わったら',sim:'40秒'},
 {k:'guide',t:'席へ案内',s:'お客さんに声をかけたら',e:'席に着いたら',sim:'45秒（歩く時間は別）'},
 {k:'call',t:'呼び出し',s:'テーブルに着いたら',e:'テーブルを離れたら',sim:'30秒'},
 {k:'place',t:'料理を置く',s:'テーブルに着いたら',e:'テーブルを離れたら',sim:'10秒'}
];
var ROBOT={k:'robot',t:'ロボットの往復',s:'ロボットが受け渡し口を出たら',e:'受け渡し口に戻ったら',sim:'止まる 往復の30%・人が動かす 1%'};
var PURPOSE={pre:'ロボットの導入を考えている',post:'ロボットを入れていて、改善したい',ops:'店の回し方を試算したい'};
var GOAL=15;
var TIMES=['朝','昼（ランチ）','午後','夜（ディナー）','深夜'];
var TAGS=['いつもどおり','混んでいる','空いている','スタッフが足りない','団体のお客さんがいる','雨の日','イベント・休日'];
function nowTime(){var h=new Date().getHours();return h<5?'深夜':h<11?'朝':h<15?'昼（ランチ）':h<17?'午後':h<22?'夜（ディナー）':'深夜';}
function $(i){return document.getElementById(i);}
function load(){try{var s=JSON.parse(localStorage.getItem(LS));if(s&&s.recs)return s;}catch(e){}return {purpose:'',store:{name:'',staff:3,robots:2,time:'',tags:[],note:'',tables:'',occ0:''},recs:[],arrivals:[],leaves:[]};}
var S=load();if(!S.leaves)S.leaves=[];
function save(){try{localStorage.setItem(LS,JSON.stringify(S));}catch(e){}}
function tasks(){return S.purpose==='post'?TASKS.concat([ROBOT]):TASKS;}
function T(k){var a=TASKS.concat([ROBOT]);for(var i=0;i<a.length;i++)if(a[i].k===k)return a[i];return {t:k};}
function cnt(k){return S.recs.filter(function(r){return r.k===k;}).length;}
function jp(sec){sec=Math.max(0,Math.round(sec));var m=Math.floor(sec/60),s=sec%60;return m?(m+'分'+(s?s+'秒':'')):s+'秒';}
function clock(ms){var s=Math.max(0,Math.floor(ms/1000));return Math.floor(s/60)+':'+String(s%60).padStart(2,'0');}
function med(a){if(!a.length)return null;var b=a.slice().sort(function(x,y){return x-y;}),m=Math.floor(b.length/2);return b.length%2?b[m]:(b[m-1]+b[m])/2;}
function buzz(){try{navigator.vibrate&&navigator.vibrate(15);}catch(e){}}
var toastTimer=null;
function toast(msg,undo){var t=$('toast');$('toastMsg').textContent=msg;t.hidden=false;$('toastUndo').hidden=!undo;$('toastUndo').onclick=function(){undo&&undo();t.hidden=true;};clearTimeout(toastTimer);toastTimer=setTimeout(function(){t.hidden=true;},8000);}
setInterval(function(){document.querySelectorAll('[data-since]').forEach(function(el){el.textContent=clock(Date.now()-Number(el.dataset.since));});},250);

var SCREENS=['sEntry','sStore','sMenu','sRun','sDone','sArrive','sList'];
var listFrom='sMenu';
function show(id){if(id==='sList'){var now=SCREENS.filter(function(s){return !$(s).hidden;})[0];if(now&&now!=='sList')listFrom=now;}if(running())stopRun(false);disarm();$('toast').hidden=true;SCREENS.forEach(function(s){$(s).hidden=s!==id;});render();window.scrollTo(0,0);}

/* 描く */
function render(){
  $('oStaff').textContent=S.store.staff+'人';$('oRobots').textContent=S.store.robots+'台';$('fName').value=S.store.name||'';
  $('robotField').hidden=S.purpose!=='post';
  if(!S.store.time)S.store.time=nowTime();if(!S.store.tags)S.store.tags=[];
  $('cTime').innerHTML=TIMES.map(function(t){return '<button data-time="'+t+'" aria-pressed="'+(S.store.time===t)+'">'+t+'</button>';}).join('');
  $('cTags').innerHTML=TAGS.map(function(t){return '<button data-tag="'+t+'" aria-pressed="'+(S.store.tags.indexOf(t)>=0)+'">'+t+'</button>';}).join('');
  if(document.activeElement!==$('fNote'))$('fNote').value=S.store.note||'';
  $('picks').innerHTML=tasks().map(function(t){return '<button class="pick card'+(t.k==='robot'?' wide':'')+'" data-k="'+t.k+'">'+t.t+'<span class="c"><span class="num">'+cnt(t.k)+'</span><small>回</small></span></button>';}).join('')+
    '<button class="pick card wide" data-go="sArrive">お客さんの出入り<span class="c"><small>入ってきた</small><span class="num">'+S.arrivals.length+'</span><small>組　会計</small><span class="num">'+S.leaves.length+'</span><small>組</small></span></button>';
  $('aN').textContent=S.arrivals.length;$('lN').textContent=S.leaves.length;
  if(document.activeElement!==$('fOcc'))$('fOcc').value=S.store.occ0===''||S.store.occ0==null?'':S.store.occ0;
  if(document.activeElement!==$('fTables'))$('fTables').value=S.store.tables===''||S.store.tables==null?'':S.store.tables;
  renderSum();renderList();
  $('resetBtn').hidden=!S.recs.length&&!S.arrivals.length&&!S.leaves.length;
  $('pTag').textContent=PURPOSE[S.purpose]||'';
  var parts=TASKS.concat([ROBOT]).filter(function(t){return cnt(t.k);}).map(function(t){return t.t+' '+cnt(t.k)+'回';});
  if(S.arrivals.length||S.leaves.length)parts.push('出入り '+(S.arrivals.length+S.leaves.length)+'回');
  $('resume').hidden=!parts.length;$('resumeSum').textContent=parts.join('・');
  [].forEach.call(document.querySelectorAll('.purpose button'),function(b){var on=!!parts.length&&b.dataset.purpose===S.purpose;b.classList.toggle('cont',on);
    var bd=b.querySelector('.badge');if(on&&!bd){bd=document.createElement('span');bd.className='badge';bd.textContent='続きから';b.insertBefore(bd,b.querySelector('small'));}if(!on&&bd)bd.remove();});
}
function flow(){
  var A=S.arrivals,D=S.leaves,all=A.concat(D);if(!all.length)return null;
  var t0=Math.min.apply(null,all),t1=Math.max.apply(null,all),h=(t1-t0)/3600000;
  var o={a:A.length,d:D.length,h:h};if(h<0.25)return o;
  o.aRate=A.length/h;o.dRate=D.length/h;
  var tb=Number(S.store.tables);if(tb>0)o.turn=o.dRate/tb;
  if(S.store.occ0!==''&&S.store.occ0!=null&&o.dRate>0){
    var ev=A.map(function(t){return [t,1];}).concat(D.map(function(t){return [t,-1];})).sort(function(x,y){return x[0]-y[0];});
    var L=Number(S.store.occ0),prev=t0,area=0;ev.forEach(function(e){area+=L*(e[0]-prev);L+=e[1];prev=e[0];});
    var avgL=area/(t1-t0);o.stay=avgL/o.dRate*60;}
  return o;
}
function hasRecs(){return !!(S.recs.length||S.arrivals.length||S.leaves.length);}
function renderSum(){
  var rows=tasks().filter(function(t){return cnt(t.k);}).map(function(t){var a=S.recs.filter(function(r){return r.k===t.k;});var m=med(a.map(function(r){return r.sec;}));
    var extra='';if(t.k==='robot'&&a.length){var st=a.reduce(function(s,r){return s+(r.stops||0);},0),hp=a.filter(function(r){return r.helps;}).length;extra='<small>止まった'+st+'回・人が動かした'+a.reduce(function(s,r){return s+(r.helps||0);},0)+'回</small>';}
    return '<div class="row"><b>'+t.t+'</b><span class="v">'+(m==null?'<span class="num">—</span>':'<span class="num">'+jp(m)+'</span>')+'<small>'+a.length+'回測った'+(a.length&&a.length<GOAL?'（あと'+(GOAL-a.length)+'回）':'')+'</small>'+extra+'</span></div>';});
  var f=flow();
  if(f){
    var sub=f.aRate==null?'<small>15分以上数えると、1時間あたりと回転率が出ます</small>':'<small>1時間に 来店 約'+Math.round(f.aRate)+'組・会計 約'+Math.round(f.dRate)+'組</small>';
    rows.push('<div class="row"><b>出入り</b><span class="v"><span class="num">'+f.a+'</span>組入って <span class="num">'+f.d+'</span>組会計'+sub+'</span></div>');
    if(f.turn!=null)rows.push('<div class="row"><b>回転率</b><span class="v"><span class="num">'+(Math.round(f.turn*10)/10)+'</span>回転／時<small>1卓に1時間で入れ替わる組の数</small></span></div>');
    if(f.stay!=null)rows.push('<div class="row"><b>滞在時間</b><span class="v"><span class="num">約'+Math.round(f.stay)+'分</span><small>目安（いた組の数 ÷ 帰るペース）</small></span></div>');
  }
  if(!rows.length)rows.push('<div class="row"><span class="done">まだ記録はありません</span></div>');
  $('sum').innerHTML=rows.join('');
}
function renderList(){
  var r=S.recs.slice().reverse();
  $('list').innerHTML=r.length?r.map(function(x){return '<li><span>'+T(x.k).t+'　<span class="num">'+jp(x.sec)+'</span></span><button class="x" data-rm="'+x.id+'">消す</button></li>';}).join(''):'<li class="done">まだ記録はありません</li>';
}

/* 入り口・お店 */
document.addEventListener('click',function(e){
  var b=e.target.closest('button');if(!b)return;
  if(b.dataset.purpose){var cont=hasRecs()&&S.purpose===b.dataset.purpose;S.purpose=b.dataset.purpose;save();show(cont?'sMenu':'sStore');return;}
  if(b.dataset.time){S.store.time=b.dataset.time;save();render();return;}
  if(b.dataset.tag){var i=S.store.tags.indexOf(b.dataset.tag);if(i>=0)S.store.tags.splice(i,1);else S.store.tags.push(b.dataset.tag);save();render();return;}
  if(b.dataset.st){var k=b.dataset.st,hi=k==='robots'?6:12,lo=k==='robots'?0:1;S.store[k]=Math.min(hi,Math.max(lo,S.store[k]+Number(b.dataset.d)));save();render();return;}
  if(b.id==='listBack'){show(listFrom);return;}
  if(b.dataset.go){show(b.dataset.go);return;}
  if(b.dataset.k){openTask(b.dataset.k);return;}
  if(b.dataset.rm){var id=b.dataset.rm,keep=S.recs.filter(function(r){return r.id===id;})[0];S.recs=S.recs.filter(function(r){return r.id!==id;});save();render();toast('1つ消しました',function(){S.recs.push(keep);S.recs.sort(function(a,b){return a.at-b.at;});save();render();});return;}
});
$('fName').addEventListener('input',function(e){S.store.name=e.target.value;save();});
$('fNote').addEventListener('input',function(e){S.store.note=e.target.value;save();});
$('storeBack').onclick=function(){show('sEntry');};
$('storeGo').onclick=function(){show('sMenu');};

/* 測る */
var cur=null,startAt=null,last=null,stops=0,helps=0;
function running(){return !!startAt;}
function openTask(k){cur=k;startAt=null;stops=0;helps=0;SCREENS.forEach(function(s){$(s).hidden=s!=='sRun';});window.scrollTo(0,0);var t=T(k);
  $('runT').textContent=t.t;$('runCnt').innerHTML='<small>これまで</small><span class="num">'+cnt(k)+'</span><small>回</small>';
  $('tnum').textContent='0:00';$('tnum').removeAttribute('data-since');$('twhen').textContent=t.s+'、スタート';$('tb').classList.remove('run');
  $('tally').hidden=true;$('startBtn').hidden=false;$('stopBtn').hidden=true;$('cancelBtn').hidden=true;}
function stopRun(keep){startAt=null;}
$('startBtn').onclick=function(){startAt=Date.now();buzz();$('tnum').dataset.since=startAt;$('tb').classList.add('run');$('twhen').textContent=T(cur).e+'、ストップ';
  $('startBtn').hidden=true;$('stopBtn').hidden=false;$('cancelBtn').hidden=false;$('tally').hidden=cur!=='robot';$('nStop').textContent=0;$('nHelp').textContent=0;};
$('tStop').onclick=function(){stops++;buzz();$('nStop').textContent=stops;};
$('tHelp').onclick=function(){helps++;buzz();$('nHelp').textContent=helps;};
$('stopBtn').onclick=function(){var sec=(Date.now()-startAt)/1000;buzz();last={id:'r'+Date.now(),k:cur,sec:sec,at:startAt};if(cur==='robot'){last.stops=stops;last.helps=helps;}
  S.recs.push(last);save();startAt=null;
  SCREENS.forEach(function(s){$(s).hidden=s!=='sDone';});render();window.scrollTo(0,0);
  $('doneT').textContent=T(cur).t;$('doneR').textContent=jp(sec);var n=cnt(cur);
  $('doneP').innerHTML=n>=GOAL?'目安の'+GOAL+'回に届きました':'<span class="cnt" style="justify-content:center"><small>これまで</small><span class="num">'+n+'</span><small>回　あと'+(GOAL-n)+'回で目安の'+GOAL+'回</small></span>';};
$('cancelBtn').onclick=function(){openTask(cur);};
$('runBack').onclick=function(){startAt=null;show('sMenu');};
$('againBtn').onclick=function(){openTask(cur);};
$('undoBtn').onclick=function(){if(last){S.recs=S.recs.filter(function(r){return r.id!==last.id;});save();}openTask(cur);};

/* 来店 */
$('arriveBtn').onclick=function(){var t=Date.now();S.arrivals.push(t);save();buzz();render();toast('入ってきた 1組',function(){S.arrivals=S.arrivals.filter(function(x){return x!==t;});save();render();});};
$('leaveBtn').onclick=function(){var t=Date.now();S.leaves.push(t);save();buzz();render();toast('会計した 1組',function(){S.leaves=S.leaves.filter(function(x){return x!==t;});save();render();});};
$('fOcc').addEventListener('input',function(e){S.store.occ0=e.target.value===''?'':Number(e.target.value);save();});
$('fTables').addEventListener('input',function(e){S.store.tables=e.target.value===''?'':Number(e.target.value);save();});

/* 送る */
function summaryText(){
  var L=['観察シートの記録','目的：'+(PURPOSE[S.purpose]||''),'お店：'+(S.store.name||'（未入力）')+'　スタッフ'+S.store.staff+'人'+(S.purpose==='post'?'　ロボット'+S.store.robots+'台':''),'時間帯：'+(S.store.time||'')+(S.store.tags&&S.store.tags.length?'　'+S.store.tags.join('・'):''),(S.store.note?'メモ：'+S.store.note:'')].filter(Boolean);
  tasks().forEach(function(t){var a=S.recs.filter(function(r){return r.k===t.k;}).map(function(r){return r.sec;});if(a.length)L.push(t.t+'：だいたい'+jp(med(a))+'（'+a.length+'回）');});
  var f=flow();if(S.store.tables)L.splice(3,0,'卓の数：約'+S.store.tables+'卓');
  if(f){L.push('出入り：入ってきた'+f.a+'組・会計した'+f.d+'組'+(S.store.occ0!==''&&S.store.occ0!=null?'（数えはじめに'+S.store.occ0+'卓にお客さん）':''));
    if(f.aRate!=null)L.push('1時間あたり：来店 約'+Math.round(f.aRate)+'組・会計 約'+Math.round(f.dRate)+'組');
    if(f.turn!=null)L.push('回転率：'+(Math.round(f.turn*10)/10)+'回転／時');
    if(f.stay!=null)L.push('滞在時間の目安：約'+Math.round(f.stay)+'分');}
  function hms(t){var d=new Date(t);return [d.getHours(),d.getMinutes(),d.getSeconds()].map(function(n){return String(n).padStart(2,'0');}).join(':');}
  var first=S.recs.length?Math.min.apply(null,S.recs.map(function(r){return r.at;})):(S.arrivals[0]||Date.now());
  var d0=new Date(first);L.splice(1,0,'日付：'+d0.getFullYear()+'/'+(d0.getMonth()+1)+'/'+d0.getDate());
  if(S.recs.length){L.push('','--- 1回ずつの記録 ---');S.recs.slice().sort(function(a,b){return a.at-b.at;}).forEach(function(r){L.push(hms(r.at)+'　'+T(r.k).t+'　'+(Math.round(r.sec*10)/10)+'秒'+(r.k==='robot'?'（止まった'+(r.stops||0)+'回・人が動かした'+(r.helps||0)+'回）':''));});}
  if(S.arrivals.length){L.push('','--- 入ってきた時刻 ---',S.arrivals.map(hms).join('、'));}
  if(S.leaves.length){L.push('','--- 会計した時刻 ---',S.leaves.map(hms).join('、'));}
  return L.join('\n');
}
var MAIL_TO='';
$('lineBtn').onclick=function(){location.href='https://line.me/R/share?text='+encodeURIComponent(summaryText());};
$('mailBtn').onclick=function(){var subj='観察シートの記録'+(S.store.name?'（'+S.store.name+'）':'');
  location.href='mailto:'+MAIL_TO+'?subject='+encodeURIComponent(subj)+'&body='+encodeURIComponent(summaryText());};

/* はじめから */
var arms={};
function disarmOne(id){var a=arms[id];if(!a)return;clearInterval(a.t);delete arms[id];var b=$(id);b.classList.remove('armed');b.textContent=a.label;$(a.note).hidden=true;}
function disarm(){Object.keys(arms).forEach(disarmOne);}
function armTap(id,noteId,label,doIt){
  if(!arms[id]){var a=arms[id]={left:5,label:label,note:noteId};var b=$(id);b.classList.add('armed');
    var paint=function(){b.innerHTML='全部消す　<span class="num">'+a.left+'</span>';$(noteId).innerHTML='もう一度押すと、記録を全部消します<br>押さなければ <span class="num">'+a.left+'</span> 秒で元に戻ります';};
    paint();$(noteId).hidden=false;a.t=setInterval(function(){a.left--;if(a.left<=0){disarmOne(id);return;}paint();},1000);return;}
  disarmOne(id);doIt();}
function wipeAll(after){var keep={recs:S.recs.slice(),arrivals:S.arrivals.slice(),leaves:S.leaves.slice()};S.recs=[];S.arrivals=[];S.leaves=[];save();after();
  toast('記録を全部消しました',function(){S.recs=keep.recs;S.arrivals=keep.arrivals;S.leaves=keep.leaves;save();render();});}
$('resetBtn').onclick=function(){armTap('resetBtn','resetNote','はじめから記録する',function(){wipeAll(function(){show('sMenu');});});};
$('newBtn').onclick=function(){armTap('newBtn','newNote','記録を消して新しく始める',function(){wipeAll(function(){render();});});};

/* 最初の画面 */
render();
SCREENS.forEach(function(s){$(s).hidden=true;});$('sEntry').hidden=false;
</script></body></html>
