posimai-boki/index.html

954 lines
89 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="ja" data-app-id="posimai-boki">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<script>
(function(){
var t=localStorage.getItem('posimai-boki-theme')||'system';
var dark=t==='dark'||(t==='system'&&matchMedia('(prefers-color-scheme:dark)').matches);
document.documentElement.setAttribute('data-theme',dark?'dark':'light');
})();
</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content">
<meta name="description" content="簿記2級 概念学習・理解度チェックアプリ">
<meta name="color-scheme" content="dark light">
<meta name="theme-color" content="#0C1221" media="(prefers-color-scheme: dark)">
<meta name="theme-color" content="#EFF6FF" media="(prefers-color-scheme: light)">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Boki">
<link rel="manifest" href="/manifest.json">
<link rel="icon" type="image/png" href="/logo.png">
<link rel="apple-touch-icon" href="/logo.png">
<title>Boki — 簿記2級</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=Geist:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<script src="https://unpkg.com/lucide@0.344.0/dist/umd/lucide.min.js" integrity="sha384-tTkFttkBclaU1cloKwOi9xk3pbao3VZxTjLNBt8iFABWDBQibbAbWpVmO28zMuxq" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.14.3/dist/cdn.min.js" integrity="sha384-iZD2X8o1Zdq0HR5H/7oa8W30WS4No+zWCKUPD7fHRay9I1Gf+C4F8sVmw7zec1wW" crossorigin="anonymous" defer></script>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root,[data-theme="dark"]{
--accent:#22D3EE;
--accent-dim:rgba(34,211,238,0.10);
--accent-border:rgba(34,211,238,0.22);
--bg:#0C1221;
--surface:rgba(15,22,40,0.82);
--surface2:rgba(26,34,53,0.92);
--border:rgba(255,255,255,0.07);
--border2:rgba(255,255,255,0.04);
--text:#F1F5F9;
--text2:#94A3B8;
--text3:#64748B;
--ok:#4ADE80;
--warn:#FB923C;
--err:#F87171;
--radius:12px;
--radius-sm:8px;
--safe-top:env(safe-area-inset-top, 0px);
--safe-right:env(safe-area-inset-right, 0px);
--safe-bottom:env(safe-area-inset-bottom, 0px);
--safe-left:env(safe-area-inset-left, 0px);
}
[data-theme="light"]{
--accent:#0891B2;
--accent-dim:rgba(8,145,178,0.08);
--accent-border:rgba(8,145,178,0.22);
--bg:#EFF6FF;
--surface:rgba(255,255,255,0.88);
--surface2:rgba(240,249,255,0.92);
--border:rgba(0,0,0,0.07);
--border2:rgba(0,0,0,0.04);
--text:#0F172A;
--text2:#475569;
--text3:#94A3B8;
--ok:#16A34A;
--warn:#D97706;
--err:#DC2626;
}
html{height:100%}
html,body{background:var(--bg);color:var(--text);font-family:'Geist',sans-serif;overflow:hidden}
body{min-height:100%;min-height:-webkit-fill-available;height:100%}
.aurora{position:fixed;inset:0;pointer-events:none;overflow:hidden;z-index:0}
.aurora-blob{position:absolute;border-radius:50%;will-change:transform}
.aurora-blob-1{width:800px;height:550px;background:radial-gradient(ellipse,rgba(34,211,238,0.13) 0%,transparent 68%);top:-120px;right:-100px;filter:blur(90px);animation:ab1 20s ease-in-out infinite alternate}
.aurora-blob-2{width:650px;height:480px;background:radial-gradient(ellipse,rgba(167,139,250,0.09) 0%,transparent 68%);bottom:-100px;left:-80px;filter:blur(100px);animation:ab2 26s ease-in-out infinite alternate}
.aurora-blob-3{width:440px;height:360px;background:radial-gradient(ellipse,rgba(34,211,238,0.06) 0%,transparent 68%);top:45%;right:28%;filter:blur(80px);animation:ab3 16s ease-in-out infinite alternate}
@keyframes ab1{from{transform:translate(0,0) scale(1)}to{transform:translate(-60px,80px) scale(1.1)}}
@keyframes ab2{from{transform:translate(0,0) scale(1)}to{transform:translate(80px,-50px) scale(1.07)}}
@keyframes ab3{from{transform:translate(0,0) scale(1)}to{transform:translate(-50px,60px) scale(0.93)}}
[data-theme="light"] .aurora-blob{opacity:0.35}
#app{position:relative;z-index:1;box-sizing:border-box;height:100vh;height:100dvh;max-height:100dvh;display:flex;flex-direction:column;min-height:0;padding:var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left)}
/* Header */
header{display:flex;align-items:center;justify-content:space-between;padding:0 16px;height:52px;border-bottom:1px solid var(--border);background:rgba(12,18,33,0.75);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);flex-shrink:0}
[data-theme="light"] header{background:rgba(239,246,255,0.88)}
.brand{display:flex;align-items:center;gap:10px}
.brand-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);flex-shrink:0}
.brand-title{font-size:14px;font-weight:600;letter-spacing:-0.01em}
.brand-sub{font-size:11px;color:var(--text3)}
.icon-btn{background:none;border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px;cursor:pointer;color:var(--text2);display:flex;align-items:center;justify-content:center;transition:color .15s,border-color .15s;font-family:inherit}
.icon-btn:hover{color:var(--accent);border-color:var(--accent-border)}
/* Body */
#body{flex:1;min-height:0;display:flex;overflow:hidden}
/* Sidebar */
#sidebar{width:240px;flex-shrink:0;min-height:0;border-right:1px solid var(--border);overflow-y:auto;-webkit-overflow-scrolling:touch;background:rgba(12,18,33,0.5);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);display:flex;flex-direction:column}
[data-theme="light"] #sidebar{background:rgba(239,246,255,0.6)}
.sidebar-search{padding:10px 12px;border-bottom:1px solid var(--border)}
.search-wrap{position:relative}
.search-icon{position:absolute;left:8px;top:50%;transform:translateY(-50%);color:var(--text3);pointer-events:none}
.search-input{width:100%;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:7px 10px 7px 30px;font-size:12px;color:var(--text);outline:none;font-family:'Geist',sans-serif;transition:border-color .15s}
.search-input:focus{border-color:var(--accent-border)}
.search-input::placeholder{color:var(--text3)}
.progress-wrap{padding:10px 12px;border-bottom:1px solid var(--border)}
.progress-label{font-size:10px;color:var(--text3);letter-spacing:.07em;text-transform:uppercase;margin-bottom:6px;display:flex;justify-content:space-between}
.progress-track{height:3px;background:var(--surface2);border-radius:2px;overflow:hidden}
.progress-fill{height:100%;background:var(--accent);border-radius:2px;transition:width .4s}
.sidebar-cat{padding:8px 12px 3px;font-size:10px;font-weight:600;color:var(--text3);letter-spacing:.10em;text-transform:uppercase;display:flex;align-items:center;gap:6px}
.sidebar-cat-line{flex:1;height:1px;background:var(--border)}
.sidebar-item{display:flex;align-items:center;gap:8px;padding:7px 12px;cursor:pointer;font-size:12px;color:var(--text2);transition:background .12s,color .12s;border-left:2px solid transparent;user-select:none}
.sidebar-item:hover{background:var(--accent-dim);color:var(--text)}
.sidebar-item.active{background:var(--accent-dim);color:var(--accent);border-left-color:var(--accent)}
.item-num{font-family:'JetBrains Mono',monospace;font-size:9px;font-weight:500;background:var(--surface2);border:1px solid var(--border2);border-radius:4px;padding:2px 5px;min-width:26px;text-align:center;flex-shrink:0;color:var(--text3);transition:background .15s,color .15s}
.sidebar-item.active .item-num{background:var(--accent-dim);border-color:var(--accent-border);color:var(--accent)}
.sidebar-item.done .item-num{background:rgba(74,222,128,.12);border-color:rgba(74,222,128,.25);color:var(--ok)}
.item-title{flex:1;line-height:1.3}
.item-check{width:12px;height:12px;flex-shrink:0;color:var(--ok);opacity:0;transition:opacity .15s}
.sidebar-item.done .item-check{opacity:1}
/* Main */
#main{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;padding:24px 28px;touch-action:pan-y}
/* Home */
.home-hero{text-align:center;padding:36px 0 28px;max-width:500px;margin:0 auto}
.home-hero h1{font-size:26px;font-weight:300;letter-spacing:-.02em;line-height:1.2}
.home-hero h1 span{color:var(--accent)}
.home-hero p{font-size:13px;color:var(--text2);margin-top:8px;line-height:1.7}
.stats-row{display:flex;gap:10px;justify-content:center;margin-top:20px;flex-wrap:wrap}
.stat-card{background:var(--surface);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid var(--border);border-radius:var(--radius);padding:14px 22px;text-align:center}
.stat-val{font-family:'JetBrains Mono',monospace;font-size:22px;font-weight:500;color:var(--accent)}
.stat-lbl{font-size:10px;color:var(--text3);margin-top:3px;letter-spacing:.05em;text-transform:uppercase}
.home-cats{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:28px;max-width:540px;margin-inline:auto}
.home-cat-card{background:var(--surface);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid var(--border);border-radius:var(--radius);padding:18px;cursor:pointer;transition:border-color .2s,background .2s;position:relative;overflow:hidden}
.home-cat-card::before{content:'';position:absolute;inset:0;border-radius:var(--radius);background:linear-gradient(145deg,rgba(255,255,255,0.025) 0%,transparent 55%);pointer-events:none}
.home-cat-card:hover{border-color:var(--accent-border);background:var(--accent-dim)}
.home-cat-icon{width:30px;height:30px;border-radius:8px;background:var(--accent-dim);border:1px solid var(--accent-border);display:flex;align-items:center;justify-content:center;margin-bottom:10px;color:var(--accent)}
.home-cat-title{font-size:13px;font-weight:600}
.home-cat-sub{font-size:11px;color:var(--text3);margin-top:2px}
.home-cat-progress{height:3px;background:var(--border);border-radius:2px;margin-top:10px;overflow:hidden}
.home-cat-bar{height:100%;background:var(--accent);border-radius:2px;transition:width .5s}
/* Card */
.card{background:var(--surface);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid var(--border);border-radius:var(--radius);padding:20px;margin-bottom:14px;position:relative;overflow:hidden}
.card::before{content:'';position:absolute;inset:0;border-radius:var(--radius);background:linear-gradient(145deg,rgba(255,255,255,0.025) 0%,transparent 55%);pointer-events:none}
.card-title{font-size:11px;font-weight:600;color:var(--text3);letter-spacing:.09em;text-transform:uppercase;margin-bottom:14px;display:flex;align-items:center;gap:6px}
.card-title svg{width:13px;height:13px;color:var(--accent)}
/* Unit header */
.unit-header{display:flex;align-items:flex-start;gap:10px;margin-bottom:18px;flex-wrap:wrap}
.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-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-title{font-size:19px;font-weight:600;letter-spacing:-.01em;line-height:1.3}
/* Concept text */
.concept-text{font-size:13px;line-height:1.85;color:var(--text2)}
.concept-text strong{color:var(--text);font-weight:600}
.concept-text .hl{color:var(--accent);font-weight:500}
.concept-text p{margin-bottom:10px}
.concept-text p:last-child{margin-bottom:0}
.formula-box{background:var(--surface2);border:1px solid var(--accent-border);border-radius:var(--radius-sm);padding:12px 16px;margin:12px 0;font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--accent);line-height:1.8}
.formula-label{font-size:10px;color:var(--text3);font-family:'Geist',sans-serif;font-weight:600;letter-spacing:.07em;text-transform:uppercase;margin-bottom:6px}
.journal-wrap{overflow-x:auto;margin:12px 0}
.journal-table{width:100%;border-collapse:collapse;font-size:12px;min-width:280px;table-layout:fixed}
.journal-table th{padding:5px 8px;text-align:left;font-size:10px;font-weight:600;color:var(--text3);letter-spacing:.06em;text-transform:uppercase;border-bottom:1px solid var(--border)}
.journal-table td{padding:8px 8px;border-bottom:1px solid var(--border2);color:var(--text2);word-break:keep-all}
.journal-table tr:last-child td{border-bottom:none}
.dr{color:var(--text);font-weight:500}
.cr{color:var(--text2);padding-left:12px}
.amount{font-family:'JetBrains Mono',monospace;text-align:right;color:var(--text);white-space:nowrap;font-variant-numeric:tabular-nums}
/* Keypoints */
.key-list{list-style:none;display:flex;flex-direction:column;gap:8px}
.key-item{display:flex;gap:10px;font-size:13px;color:var(--text2);line-height:1.65}
.key-dot{width:5px;height:5px;border-radius:50%;background:var(--accent);flex-shrink:0;margin-top:8px}
/* Buttons */
.btn-sm{display:flex;align-items:center;gap:4px;padding:7px 13px;border-radius:var(--radius-sm);font-size:12px;font-weight:500;cursor:pointer;border:1px solid var(--border);background:var(--surface);color:var(--text2);transition:all .15s;font-family:'Geist',sans-serif}
.btn-sm:hover:not(:disabled){color:var(--accent);border-color:var(--accent-border)}
.btn-sm:disabled{opacity:.4;cursor:default}
.btn-accent{background:rgba(34,211,238,0.12);color:var(--accent);border-color:var(--accent-border)}
.btn-accent:hover:not(:disabled){background:rgba(34,211,238,0.20)}
[data-theme="light"] .btn-accent{background:rgba(8,145,178,0.10);color:var(--accent)}
/* Quiz */
.quiz-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.quiz-title-label{font-size:11px;font-weight:600;color:var(--text3);letter-spacing:.09em;text-transform:uppercase;display:flex;align-items:center;gap:6px}
.quiz-score-lbl{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text3)}
.q-card{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:14px;margin-bottom:10px;transition:border-color .2s,background .2s}
.q-card.correct{border-color:rgba(74,222,128,.35);background:rgba(74,222,128,.04)}
.q-card.wrong{border-color:rgba(248,113,113,.30);background:rgba(248,113,113,.03)}
.q-num{font-size:10px;font-weight:600;color:var(--text3);letter-spacing:.08em;text-transform:uppercase;margin-bottom:7px;display:flex;align-items:center;gap:5px}
.q-text{font-size:13px;color:var(--text);line-height:1.7;margin-bottom:12px}
.q-choices{display:flex;flex-direction:column;gap:6px}
.q-choice{display:flex;align-items:flex-start;gap:9px;padding:8px 12px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--surface);cursor:pointer;font-size:12px;color:var(--text2);transition:all .15s;text-align:left;font-family:'Geist',sans-serif;line-height:1.5;width:100%}
.q-choice:hover:not(:disabled){border-color:var(--accent-border);color:var(--text);background:var(--accent-dim)}
.q-choice:disabled{cursor:default}
.q-choice.sel-ok{border-color:rgba(74,222,128,.45);background:rgba(74,222,128,.09);color:var(--ok)}
.q-choice.sel-ng{border-color:rgba(248,113,113,.40);background:rgba(248,113,113,.07);color:var(--err)}
.q-choice.rev-ok{border-color:rgba(74,222,128,.35);background:rgba(74,222,128,.05);color:var(--ok)}
.choice-key{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:600;min-width:16px;flex-shrink:0;margin-top:1px}
.q-exp{margin-top:10px;padding:9px 11px;background:rgba(34,211,238,.05);border:1px solid var(--accent-border);border-radius:var(--radius-sm);font-size:12px;color:var(--text2);line-height:1.65}
.q-exp strong{color:var(--accent)}
.quiz-result{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:22px;text-align:center;margin-top:14px}
.result-score{font-family:'JetBrains Mono',monospace;font-size:38px;font-weight:500;color:var(--accent);letter-spacing:-.02em}
.result-lbl{font-size:11px;color:var(--text3);margin-top:4px;letter-spacing:.05em;text-transform:uppercase}
.result-msg{font-size:13px;color:var(--text2);margin-top:10px;line-height:1.5}
.result-actions{margin-top:16px;display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
/* Unit nav */
.unit-nav{display:flex;gap:8px;flex-wrap:wrap;margin-top:4px;padding-bottom:24px}
/* Mobile */
.sidebar-toggle{display:none}
.overlay-mob{display:none;position:fixed;inset:0;z-index:40;background:rgba(0,0,0,.5)}
.overlay-mob.open{display:block}
@media(max-width:680px){
#sidebar{position:fixed;left:0;top:calc(52px + var(--safe-top));bottom:var(--safe-bottom);z-index:50;transform:translateX(-100%);transition:transform .25s cubic-bezier(.2,.9,.2,1);width:260px}
#sidebar.open{transform:translateX(0)}
.sidebar-toggle{display:flex}
#main{padding:10px}
.home-hero{padding:28px 0 20px}
.card{padding:15px;margin-bottom:12px}
.unit-header{margin-bottom:14px}
.unit-nav{padding-bottom:20px}
.home-cats{grid-template-columns:1fr}
.q-card{padding:12px;margin-bottom:8px}
.q-text{font-size:12.5px;word-break:keep-all;line-break:strict}
.q-choice{padding:8px 10px;font-size:11.5px;line-height:1.55;word-break:keep-all;line-break:strict}
.q-exp{font-size:11.5px}
.journal-table{min-width:0;font-size:11px}
.journal-table th,.journal-table td{padding:6px 4px}
.journal-table th{font-size:9px;padding:5px 4px}
.journal-table .cr{padding-left:6px}
.journal-table .amount{font-size:10px}
}
::-webkit-scrollbar{width:4px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}
/* Badges */
.badge-row{display:flex;align-items:center;gap:6px;margin-bottom:8px;flex-wrap:wrap}
.badge{display:inline-flex;align-items:center;gap:3px;font-size:10px;font-weight:600;padding:3px 8px;border-radius:20px;letter-spacing:.04em}
.badge-high{background:rgba(248,113,113,.12);border:1px solid rgba(248,113,113,.3);color:var(--err)}
.badge-mid{background:rgba(251,146,60,.10);border:1px solid rgba(251,146,60,.28);color:var(--warn)}
.badge-base{background:rgba(34,211,238,.08);border:1px solid rgba(34,211,238,.2);color:var(--accent)}
.badge-diff{background:var(--surface2);border:1px solid var(--border);color:var(--text3)}
.score-chip{font-family:'JetBrains Mono',monospace;font-size:9px;font-weight:600;padding:1px 5px;border-radius:4px;background:rgba(74,222,128,.12);border:1px solid rgba(74,222,128,.25);color:var(--ok);margin-left:auto;flex-shrink:0}
.score-chip.partial{background:rgba(251,146,60,.10);border-color:rgba(251,146,60,.28);color:var(--warn)}
.score-chip.zero{background:var(--surface2);border-color:var(--border);color:var(--text3)}
/* Exam tips card */
.exam-tips-text{font-size:13px;line-height:1.8;color:var(--text2)}
.exam-tips-text strong{color:var(--text);font-weight:600}
.exam-tips-text .hl{color:var(--accent);font-weight:500}
.tips-point{display:flex;gap:8px;margin-bottom:8px;font-size:12px;color:var(--text2);line-height:1.65}
.tips-point:last-child{margin-bottom:0}
.tips-icon{flex-shrink:0;width:16px;height:16px;border-radius:50%;background:rgba(248,113,113,.15);border:1px solid rgba(248,113,113,.3);display:flex;align-items:center;justify-content:center;margin-top:2px;font-size:9px;color:var(--err);font-weight:700}
/* Visual diagrams */
.viz-taccount{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;margin:14px 0}
.tac-header{text-align:center;padding:7px;font-size:10px;font-weight:600;letter-spacing:.07em;color:var(--text3);text-transform:uppercase;border-bottom:1px solid var(--border)}
.tac-body{display:grid;grid-template-columns:1fr 2px 1fr;min-height:90px}
.tac-side{padding:12px 14px}
.tac-side-label{font-size:11px;font-weight:600;letter-spacing:.04em;margin-bottom:8px}
.tac-dr .tac-side-label{color:var(--accent)}
.tac-cr .tac-side-label{color:var(--warn)}
.tac-side-desc{font-size:11px;color:var(--text2);line-height:1.85}
.tac-divider{background:var(--border)}
.viz-groups{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin:14px 0}
@media(max-width:580px){.viz-groups{grid-template-columns:repeat(3,1fr)}}
.vg-card{border-radius:var(--radius-sm);padding:10px 8px;text-align:center;border:1px solid}
.vg-name{font-size:12px;font-weight:600;margin-bottom:5px}
.vg-rule{font-size:10px;line-height:1.65;color:var(--text2)}
.vg-asset{background:rgba(34,211,238,.08);border-color:rgba(34,211,238,.22)}.vg-asset .vg-name{color:var(--accent)}
.vg-liability{background:rgba(251,146,60,.07);border-color:rgba(251,146,60,.22)}.vg-liability .vg-name{color:var(--warn)}
.vg-equity{background:rgba(167,139,250,.07);border-color:rgba(167,139,250,.22)}.vg-equity .vg-name{color:#A78BFA}
.vg-revenue{background:rgba(74,222,128,.07);border-color:rgba(74,222,128,.22)}.vg-revenue .vg-name{color:var(--ok)}
.vg-expense{background:rgba(248,113,113,.07);border-color:rgba(248,113,113,.22)}.vg-expense .vg-name{color:var(--err)}
.viz-flow{display:flex;align-items:center;gap:6px;margin:14px 0;flex-wrap:wrap;justify-content:center}
.vf-node{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:10px 14px;text-align:center;font-size:12px;font-weight:600;color:var(--text);min-width:68px}
.vf-sub{font-size:10px;color:var(--text3);font-weight:400;margin-top:3px}
.vf-hl{border-color:var(--accent-border) !important;background:var(--accent-dim) !important;color:var(--accent) !important}
.vf-hl .vf-sub{color:rgba(34,211,238,.65)}
.vf-arrow{color:var(--text3);font-size:15px;flex-shrink:0}
.viz-cost3{display:flex;align-items:center;gap:10px;margin:14px 0;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius);padding:14px;flex-wrap:wrap;justify-content:center}
.vc3-inputs{display:flex;flex-direction:column;gap:5px}
.vc3-item{font-size:11px;padding:5px 10px;border-radius:4px;font-weight:500;border:1px solid;white-space:nowrap}
.vc3-mat{background:rgba(34,211,238,.08);border-color:rgba(34,211,238,.2);color:var(--accent)}
.vc3-lab{background:rgba(74,222,128,.08);border-color:rgba(74,222,128,.2);color:var(--ok)}
.vc3-ovh{background:rgba(167,139,250,.08);border-color:rgba(167,139,250,.2);color:#A78BFA}
.vc3-note{font-size:9px;opacity:.7;margin-left:2px}
.vc3-arr{font-size:18px;color:var(--text3);flex-shrink:0}
.vc3-box{padding:12px 16px;border-radius:var(--radius-sm);text-align:center;font-size:13px;font-weight:600;min-width:68px}
.vc3-sublbl{font-size:10px;font-weight:400;margin-top:3px;opacity:.7}
.vc3-wip{border:1px solid var(--accent-border);background:var(--accent-dim);color:var(--accent)}
.vc3-fin{border:1px solid var(--border);background:var(--surface);color:var(--text)}
.viz-org{display:flex;flex-direction:column;align-items:center;margin:14px 0;gap:0}
.vo-row{display:flex;gap:20px;justify-content:center;align-items:flex-start}
.vo-branch{display:flex;flex-direction:column;align-items:center}
.vo-node{border-radius:var(--radius-sm);padding:10px 18px;text-align:center;min-width:140px;font-size:12px;font-weight:600;border:1px solid var(--border);background:var(--surface2);color:var(--text)}
.vo-parent{border-color:var(--accent-border);background:var(--accent-dim);color:var(--accent)}
.vo-child1{border-color:rgba(74,222,128,.3);background:rgba(74,222,128,.06);color:var(--ok)}
.vo-child2{border-color:rgba(167,139,250,.3);background:rgba(167,139,250,.06);color:#A78BFA}
.vo-sub{font-size:10px;font-weight:400;margin-top:3px;opacity:.75}
.vo-vline{width:2px;height:16px;background:var(--border)}
.vo-hline{display:flex;align-items:center;gap:0}
.vo-hseg{height:2px;width:60px;background:var(--border)}
.vo-pct{font-size:10px;color:var(--text3);background:var(--surface2);border:1px solid var(--border);border-radius:20px;padding:2px 7px;white-space:nowrap;margin-bottom:2px}
.vo-connector{display:flex;flex-direction:column;align-items:center}
</style>
</head>
<body>
<div class="aurora" aria-hidden="true">
<div class="aurora-blob aurora-blob-1"></div>
<div class="aurora-blob aurora-blob-2"></div>
<div class="aurora-blob aurora-blob-3"></div>
</div>
<div id="app" x-data="bokiApp()" x-init="init()">
<div class="overlay-mob" :class="{open:sidebarOpen}" @click="sidebarOpen=false" aria-hidden="true"></div>
<header>
<div class="brand">
<button class="icon-btn sidebar-toggle" @click="sidebarOpen=!sidebarOpen" aria-label="メニュー">
<i data-lucide="menu" style="width:16px;height:16px"></i>
</button>
<div class="brand-dot"></div>
<span class="brand-title">Boki</span>
<span class="brand-sub">簿記2級</span>
</div>
<div style="display:flex;align-items:center;gap:8px">
<button class="icon-btn" @click="toggleTheme()" aria-label="テーマ切替">
<i data-lucide="sun" style="width:15px;height:15px" x-show="isDark"></i>
<i data-lucide="moon" style="width:15px;height:15px" x-show="!isDark"></i>
</button>
</div>
</header>
<div id="body">
<nav id="sidebar" :class="{open:sidebarOpen}">
<div class="sidebar-search">
<div class="search-wrap">
<i data-lucide="search" class="search-icon" style="width:12px;height:12px"></i>
<input class="search-input" type="search" placeholder="単元を検索..." x-model="search" aria-label="単元検索">
</div>
</div>
<div class="progress-wrap">
<div class="progress-label">
<span>進捗</span>
<span x-text="doneCount + ' / ' + totalCount"></span>
</div>
<div class="progress-track">
<div class="progress-fill" :style="'width:' + progressPct + '%'"></div>
</div>
</div>
<template x-for="cat in filteredCats" :key="cat.id">
<div>
<div class="sidebar-cat">
<span x-text="cat.label"></span>
<div class="sidebar-cat-line"></div>
</div>
<template x-for="u in cat.units" :key="u.id">
<div class="sidebar-item"
:class="{active: currentUnit && currentUnit.id===u.id, done: isDone(u.id)}"
@click="openUnit(u); sidebarOpen=false">
<span class="item-num" x-text="u.num"></span>
<span class="item-title" x-text="u.title"></span>
<span class="score-chip" x-show="bestScore(u.id)" :class="scoreChipCls(u.id)" x-text="bestScore(u.id)"></span>
<i data-lucide="check" class="item-check" style="width:11px;height:11px" x-show="!bestScore(u.id)"></i>
</div>
</template>
</div>
</template>
</nav>
<main id="main">
<!-- HOME -->
<div x-show="!currentUnit">
<div class="home-hero">
<h1>簿記<span>2級</span>学習アプリ</h1>
<p>商業簿記・工業簿記を単元ごとに学習し、理解度チェックで定着させましょう。3級の基礎から丁寧に復習できます。</p>
<div class="stats-row">
<div class="stat-card">
<div class="stat-val" x-text="doneCount"></div>
<div class="stat-lbl">修了単元</div>
</div>
<div class="stat-card">
<div class="stat-val" x-text="totalCount"></div>
<div class="stat-lbl">全単元</div>
</div>
<div class="stat-card">
<div class="stat-val" x-text="quizCorrect + '/' + quizAnswered"></div>
<div class="stat-lbl">クイズ正解</div>
</div>
</div>
</div>
<div class="home-cats">
<template x-for="cat in categories" :key="cat.id">
<div class="home-cat-card" @click="openUnit(cat.units[0])">
<div class="home-cat-icon">
<i :data-lucide="cat.icon" style="width:15px;height:15px"></i>
</div>
<div class="home-cat-title" x-text="cat.label"></div>
<div class="home-cat-sub" x-text="cat.units.length + ' 単元'"></div>
<div class="home-cat-progress">
<div class="home-cat-bar" :style="'width:' + catPct(cat) + '%'"></div>
</div>
</div>
</template>
</div>
</div>
<!-- UNIT VIEW -->
<div x-show="currentUnit">
<div class="unit-header">
<button class="unit-back" @click="currentUnit=null;quizState={}">
<i data-lucide="arrow-left" style="width:12px;height:12px"></i>
一覧
</button>
<div class="unit-meta" x-show="currentUnit">
<div class="badge-row">
<div class="unit-cat-badge" x-text="currentUnit?.catLabel"></div>
<div class="badge" :class="freqBadgeCls" x-text="freqLabel"></div>
<div class="badge badge-diff" x-text="diffLabel"></div>
</div>
<div class="unit-title" x-text="currentUnit?.title"></div>
</div>
</div>
<!-- Concept -->
<div class="card" x-show="currentUnit">
<div class="card-title">
<i data-lucide="book-open" style="width:13px;height:13px"></i>
概念解説
</div>
<div class="concept-text" x-html="currentUnit?.concept"></div>
</div>
<!-- Exam tips -->
<div class="card" x-show="currentUnit?.examtips?.length" style="border-color:rgba(248,113,113,.18);background:rgba(248,113,113,.03)">
<div class="card-title" style="color:var(--err)">
<i data-lucide="alert-triangle" style="width:13px;height:13px;color:var(--err)"></i>
試験対策メモ
</div>
<template x-for="tip in (currentUnit?.examtips||[])" :key="tip">
<div class="tips-point">
<div class="tips-icon">!</div>
<span x-html="tip"></span>
</div>
</template>
</div>
<!-- Keypoints -->
<div class="card" x-show="currentUnit?.keypoints?.length">
<div class="card-title">
<i data-lucide="zap" style="width:13px;height:13px"></i>
重要ポイント
</div>
<ul class="key-list">
<template x-for="kp in (currentUnit?.keypoints||[])" :key="kp">
<li class="key-item">
<div class="key-dot"></div>
<span x-html="kp"></span>
</li>
</template>
</ul>
</div>
<!-- Quiz -->
<div class="card" x-show="currentUnit?.quiz?.length">
<div class="quiz-header">
<div class="quiz-title-label">
<i data-lucide="check-circle-2" style="width:13px;height:13px"></i>
理解度チェック
</div>
<div class="quiz-score-lbl" x-text="scoreLabel"></div>
</div>
<template x-for="(q, qi) in (currentUnit?.quiz||[])" :key="qi">
<div class="q-card" :class="qCardCls(qi)">
<div class="q-num">
<i data-lucide="help-circle" style="width:11px;height:11px"></i>
<span x-text="qi+1"></span>
</div>
<div class="q-text" x-html="q.q"></div>
<div class="q-choices">
<template x-for="(ch, ci) in q.choices" :key="ci">
<button class="q-choice"
:class="choiceCls(qi,ci,q.answer)"
:disabled="answered(qi)"
@click="doAnswer(qi,ci,q.answer,q.exp)">
<span class="choice-key" x-text="keys[ci]"></span>
<span x-html="ch"></span>
</button>
</template>
</div>
<div class="q-exp" x-show="answered(qi)">
<strong>解説:</strong> <span x-html="quizState[qi]?.exp"></span>
</div>
</div>
</template>
<!-- Result -->
<div class="quiz-result" x-show="allAnswered">
<div class="result-score" x-text="resultScore"></div>
<div class="result-lbl">正解 / 全問</div>
<div class="result-msg" x-text="resultMsg"></div>
<div class="result-actions">
<button class="btn-sm" @click="resetQuiz">
<i data-lucide="refresh-cw" style="width:11px;height:11px"></i>
やり直し
</button>
<button class="btn-sm btn-accent" @click="nextUnit" :disabled="!hasNext">
次の単元
<i data-lucide="arrow-right" style="width:11px;height:11px"></i>
</button>
</div>
</div>
</div>
<!-- Navigation -->
<div class="unit-nav">
<button class="btn-sm" @click="prevUnit" :disabled="!hasPrev">
<i data-lucide="arrow-left" style="width:11px;height:11px"></i>
前の単元
</button>
<button class="btn-sm btn-accent" @click="markDone" x-show="!isDone(currentUnit?.id)">
<i data-lucide="check" style="width:11px;height:11px"></i>
学習済みにする
</button>
<button class="btn-sm" @click="nextUnit" :disabled="!hasNext">
次の単元
<i data-lucide="arrow-right" style="width:11px;height:11px"></i>
</button>
</div>
</div>
</main>
</div>
</div>
<script>
const CATEGORIES = [
{ id:'commercial', label:'商業簿記', icon:'landmark', units:[
{ id:'c01', num:'C01', title:'仕訳の基礎復習', freq:'high', diff:1,
concept:`<p><strong>仕訳</strong>とは取引を借方(左)と貸方(右)に分けて記録する作業です。<span class="hl">借方合計 = 貸方合計</span> が常に成立します。</p><div class="viz-taccount"><div class="tac-header">T 勘 定</div><div class="tac-body"><div class="tac-side tac-dr"><div class="tac-side-label">借方(左側)</div><div class="tac-side-desc">資産の増加<br>負債の減少<br>純資産の減少<br>費用の発生</div></div><div class="tac-divider"></div><div class="tac-side tac-cr"><div class="tac-side-label">貸方(右側)</div><div class="tac-side-desc">資産の減少<br>負債の増加<br>純資産の増加<br>収益の発生</div></div></div></div><p>勘定科目は5グループに分類されます。</p><div class="viz-groups"><div class="vg-card vg-asset"><div class="vg-name">資産</div><div class="vg-rule">増加→借方<br>減少→貸方</div></div><div class="vg-card vg-liability"><div class="vg-name">負債</div><div class="vg-rule">増加→貸方<br>減少→借方</div></div><div class="vg-card vg-equity"><div class="vg-name">純資産</div><div class="vg-rule">増加→貸方<br>減少→借方</div></div><div class="vg-card vg-revenue"><div class="vg-name">収益</div><div class="vg-rule">発生→貸方<br>消滅→借方</div></div><div class="vg-card vg-expense"><div class="vg-name">費用</div><div class="vg-rule">発生→借方<br>消滅→貸方</div></div></div><p>商品¥100,000を掛けで仕入れた</p><div class="journal-wrap"><table class="journal-table"><tr><th>科目</th><th>金額</th><th>科目</th><th>金額</th></tr><tr><td class="dr">仕入</td><td class="amount">100,000</td><td class="cr">買掛金</td><td class="amount">100,000</td></tr></table></div>`,
examtips:['第1問の仕訳問題は5問×4点<strong>20点</strong>。確実に取りに行く単元。','勘定科目名は<strong>正式名称</strong>で書くこと(例:「売掛」ではなく「売掛金」)。略称は不正解。','複合仕訳(借方または貸方が複数行)も頻出。合計金額が一致するか必ず確認。'],
keypoints:['資産の増加 → 借方、減少 → 貸方','負債・純資産の増加 → 貸方、減少 → 借方','費用の発生 → 借方、収益の発生 → 貸方','<strong>貸借平均の原理</strong>:借方合計と貸方合計は必ず一致する'],
quiz:[
{q:'現金¥50,000を受け取り売上として計上した。正しい仕訳はどれか。',choices:['現金 50,000 /売上 50,000','売上 50,000 /現金 50,000','現金 50,000 /買掛金 50,000','売掛金 50,000 /売上 50,000'],answer:0,exp:'現金(資産)の増加は借方。売上(収益)の発生は貸方。'},
{q:'負債が増加するとき、仕訳上どちらに記載するか。',choices:['借方(左側)','貸方(右側)','どちらでもよい','仕訳不要'],answer:1,exp:'負債の増加は貸方(右側)に記載します。減少は借方です。'},
{q:'費用の発生は仕訳のどちらに記載するか。',choices:['貸方','借方','どちらでもない','発生しない'],answer:1,exp:'費用の発生は借方(左側)に記載します。'},
{q:'建物¥5,000,000を購入し、代金のうち¥2,000,000は現金で支払い、残額は来月払いとした。この取引の仕訳として正しいものはどれか。',choices:['建物5,000,000 現金2,000,000・未払金3,000,000','建物2,000,000 現金2,000,000','現金5,000,000 建物5,000,000','建物5,000,000 買掛金5,000,000'],answer:0,exp:'複合仕訳。建物(資産)全額借方、現金(資産)減少と未払金(負債)増加を貸方に。買掛金は商品の掛け仕入に使う勘定で、固定資産は未払金を使う。'},
{q:'当期に未収収益¥30,000前期に計上した利息の未収分を現金で受け取った。仕訳として正しいものはどれか。',choices:['現金30,000 受取利息30,000','現金30,000 未収収益30,000','未収収益30,000 現金30,000','受取利息30,000 現金30,000'],answer:1,exp:'前期に未収収益(資産)として計上済みの利息を受け取ったので、未収収益(資産)を減らし現金(資産)を増やす。受取利息を使うと二重計上になる。'}
]
},
{ id:'c02', num:'C02', title:'商品売買と売上原価', freq:'high', diff:1,
concept:`<p>2級では<strong>三分法</strong>が基本です。仕入・売上・繰越商品の3勘定を使います。</p><div class="formula-box"><div class="formula-label">売上原価の算定(決算整理仕訳)</div>①(借)仕入 /(貸)繰越商品 ← 期首商品を仕入に振替<br>②(借)繰越商品 /(貸)仕入 ← 期末商品を控除<br><br>売上原価 期首商品 当期仕入 期末商品</div><p>期首¥30,000・仕入¥200,000・期末¥40,000 → 売上原価 <span class="hl">¥190,000</span></p>`,
examtips:['精算表第3問で必出。決算整理仕訳の<strong>2本セット</strong>(期首振替・期末控除)を忘れずに。','「売上原価 期首 仕入 期末」の公式は反射的に出るまで暗記。','仕入値引・仕入返品は仕入勘定を減額。売上値引・売上返品は売上勘定を減額することを覚えておく。'],
keypoints:['三分法:仕入(費用)・売上(収益)・繰越商品(資産)','売上原価 期首 仕入 期末','決算整理で「仕入」勘定を売上原価に確定させる','売上総利益 売上高 売上原価'],
quiz:[
{q:'期首商品¥20,000、当期仕入¥150,000、期末商品¥25,000のとき売上原価はいくらか。',choices:['¥145,000','¥155,000','¥170,000','¥125,000'],answer:0,exp:'売上原価 20,000 150,000 25,000 145,000円'},
{q:'決算整理で期末商品¥40,000を計上する仕訳はどれか。',choices:['仕入 40,000 /繰越商品 40,000','繰越商品 40,000 /仕入 40,000','売上 40,000 /繰越商品 40,000','繰越商品 40,000 /売上 40,000'],answer:1,exp:'期末商品は(借)繰越商品 /(貸)仕入 で仕入勘定から控除します。'},
{q:'売上高¥300,000、売上原価¥190,000のとき売上総利益はいくらか。',choices:['¥490,000','¥110,000','¥190,000','¥300,000'],answer:1,exp:'売上総利益 300,000 190,000 110,000円'},
{q:'当期中に仕入¥500,000のうち¥20,000分を品質不良で返品した。仕入勘定の純額はいくらか。',choices:['¥520,000','¥480,000','¥500,000','¥20,000'],answer:1,exp:'仕入返品は仕入勘定を減額。純仕入額 500,000 20,000 480,000円'},
{q:'売上高¥800,000、期首商品¥50,000、当期仕入¥600,000、期末商品¥80,000のとき売上総利益はいくらか。',choices:['¥230,000','¥170,000','¥250,000','¥800,000'],answer:0,exp:'売上原価 50,000 600,000 80,000 570,000。売上総利益 800,000 570,000 230,000円'}
]
},
{ id:'c03', num:'C03', title:'固定資産と減価償却',
concept:`<p>固定資産は使用に伴い価値が減少します。この減少額を<strong>減価償却費</strong>として費用計上します。</p><div class="formula-box"><div class="formula-label">主要な償却方法</div>定額法:(取得原価 残存価額)÷ 耐用年数<br>定率法:期首帳簿価額 × 償却率<br>生産高比例法:(取得 残存)× 当期利用量 ÷ 総利用可能量</div><p>仕訳(間接法):(借)減価償却費 /(貸)減価償却累計額</p><p>売却時帳簿価額¥100,000の備品を¥80,000で売却<br>現金80,000・固定資産売却損20,000 備品100,000</p>`,
keypoints:['定額法:毎期同額','定率法:期首帳簿価額に率をかける→年々減少','間接法:備品勘定は取得原価のまま・累計額を別勘定で管理','売却損益 売却価額 帳簿価額(取得原価 累計額)'],
quiz:[
{q:'取得原価¥500,000・残存価額¥0・耐用年数5年を定額法で償却する場合の毎期償却費は',choices:['¥50,000','¥100,000','¥125,000','¥500,000'],answer:1,exp:'500,000 0÷ 5 100,000円/年'},
{q:'帳簿価額¥200,000の車両を¥250,000で売却した場合に計上される損益は',choices:['固定資産売却損¥50,000','固定資産売却益¥50,000','固定資産売却損¥200,000','損益なし'],answer:1,exp:'250,000 200,000 50,000円の固定資産売却益'},
{q:'間接法で減価償却を行うとき使用する勘定科目の組み合わせはどれか。',choices:['備品と現金','減価償却費と減価償却累計額','備品減価償却費のみ','減価償却費と備品'],answer:1,exp:'間接法では「減価償却費」(費用)と「減価償却累計額」(資産のマイナス)を使います。'}
]
},
{ id:'c04', num:'C04', title:'引当金',
concept:`<p><strong>引当金</strong>とは将来発生が見込まれる費用・損失を当期に見越計上するものです。</p><div class="formula-box"><div class="formula-label">貸倒引当金(差額補充法)</div>設定額 売上債権残高 × 貸倒実績率<br>繰入額 設定額 既存の引当金残高</div><p>設定:(借)貸倒引当金繰入 /(貸)貸倒引当金<br>貸倒発生(引当金範囲内):(借)貸倒引当金 /(貸)売掛金<br>超過分:(借)貸倒損失 /(貸)売掛金</p><p><strong>退職給付引当金</strong>:(借)退職給付費用 /(貸)退職給付引当金</p>`,
keypoints:['差額補充法:不足分だけ繰入(期末残高まで積む)','洗替法:いったん全額取崩して再設定','貸倒れ発生 → 引当金範囲内は引当金で処理・超過分は貸倒損失','退職給付引当金:長期負債として計上'],
quiz:[
{q:'売掛金¥400,000に2%設定・既存残高¥3,000のとき差額補充法での繰入額は',choices:['¥8,000','¥5,000','¥3,000','¥11,000'],answer:1,exp:'設定額 400,000 × 2% 8,000。繰入額 8,000 3,000 5,000円'},
{q:'貸倒引当金残高¥10,000のとき売掛金¥8,000が貸倒れた場合の仕訳は',choices:['貸倒損失8,000 売掛金8,000','貸倒引当金8,000 売掛金8,000','売掛金8,000 貸倒引当金8,000','貸倒引当金10,000 売掛金8,000'],answer:1,exp:'貸倒額が引当金残高以内のため全額引当金で処理します。'},
{q:'引当金の設定要件として正しくないものはどれか。',choices:['将来の費用・損失である','当期以前の事象に起因する','金額の合理的見積もりが可能','すでに確定した債務である'],answer:3,exp:'引当金は「確定した債務」ではなく「将来発生が見込まれる不確実なもの」が対象です。'}
]
},
{ id:'c05', num:'C05', title:'有価証券',
concept:`<p>有価証券は保有目的により4分類されます。</p><div class="formula-box"><div class="formula-label">分類と評価</div>売買目的有価証券 → 時価評価(差額は当期損益)<br>満期保有目的債券 → 原価法または償却原価法<br>子会社・関連会社株式 → 取得原価法<br>その他有価証券  → 時価評価(差額は純資産:その他包括利益)</div><p>売買目的時価↑¥10,000有価証券10,000 有価証券評価益10,000<br>その他有価証券時価↑¥10,000その他有価証券10,000 その他有価証券評価差額金10,000</p>`,
keypoints:['売買目的流動資産、時価評価、評価損益はP/Lへ','満期保有固定資産、原価or償却原価法','子会社・関連会社株式:固定資産、取得原価のまま','その他有価証券固定資産、評価差額はB/S純資産税効果後'],
quiz:[
{q:'売買目的有価証券取得原価¥100,000の期末時価が¥110,000のとき計上する損益は',choices:['有価証券評価損¥10,000','有価証券評価益¥10,000','投資有価証券評価益¥10,000','損益は計上しない'],answer:1,exp:'売買目的有価証券は時価評価し差額を当期損益(有価証券評価益)に計上します。'},
{q:'その他有価証券の評価差額金はどこに計上するか。',choices:['損益計算書(営業外収益)','損益計算書(特別利益)','貸借対照表の純資産の部','貸借対照表の負債の部'],answer:2,exp:'B/S純資産の「その他有価証券評価差額金」に計上します税効果考慮後。'},
{q:'子会社株式の期末評価方法はどれか。',choices:['時価法','持分法','取得原価法','低価法'],answer:2,exp:'子会社株式・関連会社株式は取得原価法で評価します(時価変動は認識しない)。'}
]
},
{ id:'c06', num:'C06', title:'手形取引',
concept:`<p><strong>約束手形</strong>振出人と受取人の2者。<strong>為替手形</strong>振出人・引受人・受取人の3者。</p><div class="formula-box"><div class="formula-label">手形の割引</div>受取額 手形額面 割引料<br>割引料 手形額面 × 割引率 × 残存日数 ÷ 365</div><p>割引仕訳:(借)当座預金・手形売却損 /(貸)受取手形<br>裏書き(支払のため):(借)買掛金 /(貸)受取手形</p>`,
keypoints:['受取手形(資産)・支払手形(負債)','割引:銀行に売却→手形売却損(費用)計上','裏書き:受取手形を他者への支払いに使用','不渡り:決済されなかった手形→さかのぼり請求が発生'],
quiz:[
{q:'額面¥200,000の手形を年利3%・残存60日で割り引いた割引料365日計算は概算でいくらか。',choices:['¥985','¥1,479','¥6,000','¥3,000'],answer:0,exp:'割引料 200,000 × 3% × 60÷365 ≒ 985円'},
{q:'手形を裏書きして仕入代金に充当したときの貸方科目は?',choices:['支払手形','買掛金','受取手形','当座預金'],answer:2,exp:'裏書きで受取手形が減少するため貸方は「受取手形」です。'},
{q:'手形割引の仕訳で借方に計上される費用科目は?',choices:['支払利息','有価証券売却損','手形売却損','割引料'],answer:2,exp:'手形割引時の費用は「手形売却損」です。'}
]
},
{ id:'c07', num:'C07', title:'外貨建取引',
concept:`<p>外貨建取引は取引発生時のレートで換算し、決算時に為替換算調整を行います。</p><div class="formula-box"><div class="formula-label">換算レートの原則</div>売上・仕入(収益・費用) → 取引日レートHR<br>売掛金・買掛金(流動)  → 決算日レートCR<br>長期外貨建債権・債務   → 決算日レートCR</div><p>例:$1,000売掛金HR=¥140、決算時CR=¥145<br>売掛金5,000 為替差益5,000</p>`,
keypoints:['取引日:取引時のレートで記帳','決算日外貨建金銭債権債務はCRで換算替え','差額:為替差損益(営業外損益)','為替予約(振当処理):予約レートを適用してヘッジ'],
quiz:[
{q:'ドル建て売掛金$2,000計上時¥140が決算日CR=¥138のとき為替差損はいくらか。',choices:['¥4,000','¥2,000','¥276,000','¥4,000の為替差益'],answer:0,exp:'円高になったため評価減。140138× 2,000 4,000円の為替差損。'},
{q:'外貨建収益(売上)を換算するレートはどれか。',choices:['決算日レートCR','取引日レートHR','予算レート','前期末レート'],answer:1,exp:'収益・費用は取引日レートHRで換算します。'},
{q:'決算時に外貨建買掛金で為替差益が生じるのはどの場合か。',choices:['円高になった','円安になった','レートが変わらなかった','外貨の価値が上がった'],answer:0,exp:'買掛金(債務)は円高になると支払額が減少するため為替差益が生じます。'}
]
},
{ id:'c08', num:'C08', title:'リース取引',
concept:`<p>リース取引は2種類あります。</p><div class="formula-box"><div class="formula-label">分類</div>ファイナンス・リース:実質的に購入と同じ → 資産・負債を計上<br>オペレーティング・リース:賃貸借として処理 → 支払リース料(費用)</div><p>ファイナンス・リース開始時:(借)リース資産 /(貸)リース債務<br>リース料支払時:(借)リース債務・支払利息 /(貸)現金<br>決算時:(借)減価償却費 /(貸)減価償却累計額</p>`,
keypoints:['ファイナンス:所有権移転・割安購入選択権・リース期間等で判定','利子抜き法:リース料総額から利息相当額を除いた金額で資産計上','オペレーティング:毎期「支払リース料」を計上するだけ','減価償却:ファイナンスは自己所有資産同様に行う'],
quiz:[
{q:'ファイナンス・リース取引開始時の借方科目はどれか。',choices:['リース費用','支払リース料','リース資産','減価償却費'],answer:2,exp:'ファイナンス・リースは資産計上します。(借)リース資産 /(貸)リース債務'},
{q:'オペレーティング・リースの毎期の仕訳として正しいものはどれか。',choices:['リース資産 /リース債務','支払リース料 /現金','減価償却費 /リース資産','リース債務 /現金'],answer:1,exp:'オペレーティング・リースは支払リース料として費用計上します。'},
{q:'ファイナンス・リースの判定基準として誤っているものはどれか。',choices:['所有権が借手に移転する','割安購入選択権がある','リース期間が耐用年数の75%以上','月々のリース料が高額である'],answer:3,exp:'「月々のリース料が高額」は判定基準ではありません。'}
]
},
{ id:'c09', num:'C09', title:'税効果会計',
concept:`<p>会計上の利益と税務上の所得の差異(<strong>一時差異</strong>)を調整する手続きです。</p><div class="formula-box"><div class="formula-label">繰延税金資産・負債</div>将来減算一時差異(会計費用 税務損金)→ 繰延税金資産<br>将来加算一時差異(会計費用 税務損金)→ 繰延税金負債<br><br>繰延税金資産 一時差異 × 法定実効税率</div><p>貸倒引当金¥100,000が税務上損金不算入・実効税率30%<br>繰延税金資産30,000 法人税等調整額30,000</p>`,
keypoints:['一時差異:会計と税務の費用認識タイミングのズレ(いずれ解消)','永久差異(交際費超過額等)は税効果の対象外','繰延税金資産:将来の税金を前払い(資産)の概念','法人税等調整額P/Lで税負担を調整する科目'],
quiz:[
{q:'将来減算一時差異が生じた場合に計上される勘定科目はどれか。',choices:['繰延税金負債','法人税等','繰延税金資産','法人税等調整額(借方)'],answer:2,exp:'将来減算一時差異は「繰延税金資産」として計上します(将来の税金軽減効果)。'},
{q:'貸倒引当金¥200,000が税務上全額損金不算入・実効税率30%のとき繰延税金資産は?',choices:['¥200,000','¥140,000','¥60,000','¥30,000'],answer:2,exp:'繰延税金資産 200,000 × 30% 60,000円'},
{q:'税効果会計の対象とならない差異はどれか。',choices:['貸倒引当金の限度超過額','退職給付引当金の限度超過額','交際費の損金不算入額','減価償却の限度超過額'],answer:2,exp:'交際費超過額は永久差異のため税効果会計の対象外です。'}
]
},
{ id:'c10', num:'C10', title:'純資産と株式',
concept:`<p>株式会社の純資産は株主資本と評価・換算差額等等で構成されます。</p><div class="formula-box"><div class="formula-label">株主資本の構成</div>資本金 資本準備金 その他資本剰余金<br> 利益準備金 その他利益剰余金 自己株式</div><p>株式発行¥1,000,000・うち資本金¥600,000<br>現金1,000,000 資本金600,000・資本準備金400,000</p><p>剰余金配当¥500,000利益準備金積立¥50,000<br>繰越利益剰余金550,000 未払配当金500,000・利益準備金50,000</p>`,
keypoints:['払込額の最低1/2を資本金、残りは資本準備金に計上可','配当時利益準備金を資本金の1/4まで積立義務配当額の1/10','自己株式:純資産のマイナス項目(資産ではない)','その他有価証券評価差額金は純資産の部に表示'],
quiz:[
{q:'1株¥500で1,000株発行し全額を資本金とした場合、貸方に計上される金額は',choices:['資本準備金¥500,000','資本金¥500,000','資本金¥250,000と資本準備金¥250,000','普通株式¥500,000'],answer:1,exp:'全額資本金の場合現金500,000 資本金500,000'},
{q:'自己株式はB/Sのどこに表示するか。',choices:['流動資産','固定資産','純資産の部(控除)','負債の部'],answer:2,exp:'自己株式は純資産の部の株主資本から控除する形式で表示します(マイナス項目)。'},
{q:'剰余金配当¥1,000,000のとき利益準備金の積立額は積立不足十分な場合',choices:['¥100,000','¥200,000','¥50,000','¥500,000'],answer:0,exp:'配当額の1/10を積立1,000,000 × 1/10 100,000円'}
]
},
{ id:'c11', num:'C11', title:'社債',
concept:`<p><strong>社債</strong>は企業が資金調達のために発行する債券です。</p><div class="formula-box"><div class="formula-label">償却原価法(定額法)</div>毎期の償却額 =(額面 発行価額)÷ 償還までの年数<br>割引発行:帳簿価額を毎期増額 割増発行:毎期減額</div><p>発行額面¥1,000,000・発行¥970,000・3年<br>現金970,000 社債970,000<br>決算時償却¥10,000社債利息10,000 社債10,000<br>満期社債1,000,000 現金1,000,000</p>`,
keypoints:['割引発行:額面>発行価額 → 社債勘定を毎期増額','割増発行:額面<発行価額 → 社債勘定を毎期減額','社債利息 クーポン利息 償却原価法の調整額','社債は固定負債1年以内償還分は流動負債'],
quiz:[
{q:'額面¥2,000,000を¥1,940,000で発行・5年満期のとき定額法での毎期償却額は',choices:['¥12,000','¥60,000','¥388,000','¥400,000'],answer:0,exp:'2,000,000 1,940,000÷ 5 12,000円/年'},
{q:'社債の割引発行(額面>発行価額)のとき毎期の償却により帳簿価額はどうなるか。',choices:['増加する','減少する','変わらない','満期まで発行価額のまま'],answer:0,exp:'割引発行では毎期償却額を社債勘定に加算するため帳簿価額は増加(額面に近づく)します。'},
{q:'社債はB/Sのどの区分に計上するか原則。',choices:['流動負債','固定負債','純資産','流動資産'],answer:1,exp:'社債は固定負債に計上します1年以内に償還されるものは流動負債。'}
]
},
{ id:'c12', num:'C12', title:'本支店会計',
concept:`<p>本支店会計では本店と支店が独立した帳簿を持ちます。</p><div class="formula-box"><div class="formula-label">照合勘定</div>本店側:「支店」勘定(資産)<br>支店側:「本店」勘定(純資産的な勘定)<br>→ 未達取引調整後は必ず一致</div><p>内部利益の控除本店が原価¥100,000の商品を¥120,000で支店に振替 → 内部利益¥20,000<br>合併財務諸表作成:①未達取引整理 ②照合勘定の相殺消去 ③内部利益の控除</p>`,
keypoints:['本店の「支店」勘定と支店の「本店」勘定は対応','未達取引:片方だけ処理済み → 調整して一致させる','内部利益:振替価格と原価の差 → 期末商品から控除','合併P/Lでは内部取引振替売上・振替仕入を相殺'],
quiz:[
{q:'本店が支店に商品を送付した際、本店で使用する勘定科目はどれか。',choices:['売上','支店','本店','商品振替'],answer:1,exp:'本店は「支店」勘定(資産)の増加として記帳します。'},
{q:'支店が本店から商品を受け取った際に使用する勘定科目はどれか。',choices:['仕入','本店','支店','受取商品'],answer:1,exp:'支店は「本店」勘定(本店への債務)の増加として記帳します。'},
{q:'合併財務諸表作成の手順として誤っているものはどれか。',choices:['未達取引の整理','照合勘定の相殺消去','内部利益の控除','支店を子会社として連結'],answer:3,exp:'本支店は同一企業内の組織のため子会社として連結処理は行いません。'}
]
},
{ id:'c13', num:'C13', title:'連結会計の基礎',
concept:`<p><strong>連結財務諸表</strong>は親会社と子会社を一体とみなして作成します。議決権の<span class="hl">50%超</span>を保有する会社が子会社です。</p><div class="viz-org"><div class="vo-node vo-parent">親会社<div class="vo-sub">連結財務諸表を作成</div></div><div class="vo-connector"><div class="vo-vline"></div><div class="vo-pct">議決権 51〜100% 保有</div><div class="vo-vline"></div></div><div class="vo-row"><div class="vo-branch"><div class="vo-node vo-child1">子会社100%<div class="vo-sub">完全子会社</div></div></div><div class="vo-branch" style="margin-top:32px"><div class="vo-node vo-child2">子会社60%<div class="vo-sub">非支配株主持分 40%</div></div></div></div></div><div class="formula-box"><div class="formula-label">支配獲得時の連結修正仕訳</div>(借)子会社純資産 × 持分率<br>(借)のれん(差額)<br>(貸)子会社株式(投資)<br><br>のれん 投資額 子会社純資産の持分相当額</div><p>のれんは20年以内で規則的に償却。毎期①配当金消去 ②内部取引消去 ③未実現利益消去</p>`,
keypoints:['連結の範囲議決権の過半数50%超)を持つ子会社','のれん:超過収益力(投資超過額)、規則的に償却','非支配株主持分:子会社純資産のうち親が持たない部分','内部取引・未実現利益は連結上消去する'],
quiz:[
{q:'子会社株式¥800,000取得子会社純資産¥700,000・持分100%)ののれんはいくらか。',choices:['¥700,000','¥100,000','¥800,000','のれんは発生しない'],answer:1,exp:'のれん 800,000 700,000 100,000円'},
{q:'連結財務諸表で親会社が受け取った子会社からの配当金はどう処理するか。',choices:['そのまま受取配当金として計上','受取配当金と利益剰余金を相殺消去','資本剰余金に振替','現金と相殺'],answer:1,exp:'連結上グループ内の配当は内部取引として消去します。'},
{q:'のれんの最長償却期間はどれか。',choices:['5年','10年','20年','50年'],answer:2,exp:'のれんは20年以内の期間で規則的に償却します。'}
]
},
{ id:'c14', num:'C14', title:'キャッシュフロー計算書',
concept:`<p>CF計算書は<strong>営業・投資・財務</strong>の3区分でキャッシュの増減を示します。</p><div class="formula-box"><div class="formula-label">間接法営業CFの主な調整項目</div>税引前当期純利益<br> 減価償却費(非現金費用の加戻し)<br>/ 売上債権の減少/増加(回収状況)<br>/ 棚卸資産の減少/増加<br>/ 仕入債務の増加/減少</div><p>投資CF固定資産・有価証券の取得・売却<br>財務CF借入・返済・社債発行・株式発行・配当金支払い</p>`,
keypoints:['間接法:純利益からスタートし非現金項目を調整','減価償却費はキャッシュアウトなし → 加算して戻す','売上債権増加 → 現金未回収 → 営業CFから減算','固定資産の取得・売却 → 投資CF'],
quiz:[
{q:'間接法のCF計算書で減価償却費¥50,000は営業CFにどう影響するか。',choices:['¥50,000を減算','¥50,000を加算','影響なし','財務CFに計上'],answer:1,exp:'減価償却費は現金支出を伴わない費用のため純利益から控除した分を加算して戻します。'},
{q:'固定資産の取得による支出はCF計算書のどの区分か。',choices:['営業活動','投資活動','財務活動','表示しない'],answer:1,exp:'固定資産の取得・売却は投資活動によるキャッシュフローに表示します。'},
{q:'売掛金が前期比¥30,000増加した場合、間接法の営業CFにどう影響するか。',choices:['¥30,000加算','¥30,000減算','影響なし','財務CFへ計上'],answer:1,exp:'売上債権の増加は現金回収が少ないことを意味するため営業CFから減算します。'}
]
},
{ id:'c15', num:'C15', title:'財務諸表分析',
concept:`<p>財務比率で企業の収益性・安全性・効率性を分析します。</p><div class="formula-box"><div class="formula-label">主要な財務比率</div>収益性:売上高総利益率 売上総利益 ÷ 売上高 × 100<br>    ROE 当期純利益 ÷ 自己資本 × 100<br>安全性:流動比率 流動資産 ÷ 流動負債 × 100200%以上良好)<br>    自己資本比率 自己資本 ÷ 総資産 × 100<br>効率性:売上債権回転率 売上高 ÷ 売上債権<br>    棚卸資産回転率 売上高 ÷ 棚卸資産</div>`,
keypoints:['流動比率が高い → 短期支払能力が高い','自己資本比率が高い → 財務安全性が高い','回転率が高い → 効率よく資産を活用','ROEが高い → 株主資本を効率よく使って利益創出'],
quiz:[
{q:'流動資産¥600,000・流動負債¥300,000のとき流動比率はいくらか。',choices:['50%','150%','200%','300%'],answer:2,exp:'流動比率 600,000 ÷ 300,000 × 100 200%'},
{q:'自己資本比率を高める効果がある事象はどれか。',choices:['借入金の増加','当期純利益の計上','社債の発行','買掛金の増加'],answer:1,exp:'当期純利益は利益剰余金として純資産を増やすため自己資本比率が上昇します。'},
{q:'売上高¥1,200,000・売上債権¥200,000のとき売上債権回転率はいくらか。',choices:['2回','4回','6回','8回'],answer:2,exp:'売上債権回転率 1,200,000 ÷ 200,000 6回'}
]
}
]},
{ id:'industrial', label:'工業簿記', icon:'factory', units:[
{ id:'i01', num:'I01', title:'工業簿記の基礎と勘定体系',
concept:`<p><strong>工業簿記</strong>は製造業の原価計算を記録する簿記です。<span class="hl">材料 → 仕掛品 → 製品</span> の流れで原価を管理します。</p><div class="viz-flow"><div class="vf-node"><div>材料</div><div class="vf-sub">材料費</div></div><div class="vf-arrow"></div><div class="vf-node vf-hl"><div>仕掛品</div><div class="vf-sub">製造途中</div></div><div class="vf-arrow"></div><div class="vf-node"><div>製品</div><div class="vf-sub">完成品</div></div><div class="vf-arrow"></div><div class="vf-node"><div>売上原価</div><div class="vf-sub">販売時</div></div></div><p>仕掛品には製造原価の3要素が集計されます。</p><div class="viz-cost3"><div class="vc3-inputs"><div class="vc3-item vc3-mat">直接材料費</div><div class="vc3-item vc3-lab">直接労務費</div><div class="vc3-item vc3-ovh">製造間接費<span class="vc3-note">(配賦)</span></div></div><div class="vc3-arr"></div><div class="vc3-box vc3-wip">仕掛品<div class="vc3-sublbl">製造途中</div></div><div class="vc3-arr"></div><div class="vc3-box vc3-fin">製品<div class="vc3-sublbl">完成品</div></div></div>`,
keypoints:['直接費:特定製品に直接跡付けできる原価','間接費:複数製品に共通して発生→配賦が必要','仕掛品:製造途中の未完成品(期末に残る)','製造原価報告書→損益計算書の売上原価へ連動'],
quiz:[
{q:'工場の電力料は製造原価のどの区分に含まれるか。',choices:['直接材料費','直接労務費','製造間接費','販売費及び一般管理費'],answer:2,exp:'電力料は複数製品に共通して発生するため製造間接費に分類されます。'},
{q:'製造原価の3要素として誤っているものはどれか。',choices:['直接材料費','直接労務費','製造間接費','販売費'],answer:3,exp:'販売費は製造原価ではなく期間費用(販売費及び一般管理費)に分類されます。'},
{q:'仕掛品勘定に集計されないものはどれか。',choices:['直接材料費','直接労務費','製造間接費配賦額','販売員の給与'],answer:3,exp:'販売員の給与は製造原価ではなく販売費です。仕掛品には製造原価のみ集計されます。'}
]
},
{ id:'i02', num:'I02', title:'材料費の計算',
concept:`<p>材料の消費額(材料費)は消費単価×消費量で計算します。</p><div class="formula-box"><div class="formula-label">消費単価の計算方法</div>先入先出法:先に仕入れた材料から順に消費<br>移動平均法:仕入のたびに平均単価を計算<br>総平均法:月末に全体の平均単価を計算</div><div class="formula-box"><div class="formula-label">材料費の計算式</div>材料費 月初在庫 当月仕入 月末在庫<br><br>棚卸減耗費 =(帳簿棚卸数量 実地棚卸数量)× 消費単価</div>`,
keypoints:['先入先出法:物価上昇時は期末在庫が高め・材料費が低め','移動平均法:仕入のたびに平均計算→実務でよく使われる','予定消費単価:年間平均などを事前設定・差額は材料消費価格差異','棚卸減耗費:原則として製造間接費または営業外費用'],
quiz:[
{q:'月初在庫¥30,000・当月仕入¥120,000・月末在庫¥25,000のとき当月材料費は',choices:['¥115,000','¥125,000','¥150,000','¥95,000'],answer:1,exp:'材料費 30,000 120,000 25,000 125,000円'},
{q:'先入先出法で物価上昇時の材料費は移動平均法と比べてどうなるか。',choices:['高くなる','低くなる','同じになる','計算できない'],answer:1,exp:'先入先出法では古い(安い)材料から消費するため物価上昇時は材料費が低くなります。'},
{q:'棚卸減耗費の計算に使う数量の差はどれとどれか。',choices:['帳簿数量と予定消費数量','帳簿棚卸数量と実地棚卸数量','実地数量と予定数量','月初と月末の数量'],answer:1,exp:'棚卸減耗費 =(帳簿棚卸数量 実地棚卸数量)× 消費単価'}
]
},
{ id:'i03', num:'I03', title:'労務費と経費',
concept:`<p><strong>労務費</strong>は労働に対する対価。直接工の賃金は直接労務費、間接工・工場管理者の給与は間接労務費(製造間接費)。</p><div class="formula-box"><div class="formula-label">消費賃金・賃率差異の計算</div>消費賃金 実際消費時間 × 実際賃率or 予定賃率)<br>賃率差異 =(予定賃率 実際賃率)× 実際消費時間</div><p><strong>経費</strong>は材料費・労務費以外の製造原価。<br>外注加工費・特許権使用料 → 直接経費(仕掛品へ直接)<br>工場家賃・減価償却費 → 間接経費(製造間接費へ)</p>`,
keypoints:['予定賃率使用時:消費賃金は予定計算→月末に差異把握','賃率差異(有利):実際賃率が予定より低い','直接経費は仕掛品へ直接集計','間接経費は製造間接費へ集計し後で配賦'],
quiz:[
{q:'直接工の賃金はどのように分類されるか。',choices:['製造間接費','直接労務費','販売費','直接材料費'],answer:1,exp:'直接工(製品に直接携わる作業員)の賃金は直接労務費です。'},
{q:'予定賃率¥1,500/時・実際100時間・実際賃率¥1,600/時のとき賃率差異は?',choices:['¥10,000の有利差異','¥10,000の不利差異','¥1,000の有利差異','¥1,000の不利差異'],answer:1,exp:'賃率差異 1,500 1,600× 100 10,000不利差異実際賃率が予定より高かった'},
{q:'工場の減価償却費はどのように分類されるか。',choices:['直接材料費','直接経費','製造間接費','販売費及び一般管理費'],answer:2,exp:'工場の減価償却費は間接経費として製造間接費に分類されます。'}
]
},
{ id:'i04', num:'I04', title:'製造間接費の配賦',
concept:`<p>製造間接費は直接特定製品に割り当てられないため、何らかの基準で<strong>配賦</strong>します。</p><div class="formula-box"><div class="formula-label">予定配賦</div>予定配賦率 製造間接費予算額 ÷ 基準操業度<br>予定配賦額 予定配賦率 × 実際操業度<br>配賦差異 実際発生額 予定配賦額(プラス=不利)</div><div class="formula-box"><div class="formula-label">差異の3分析</div>予算差異 変動費予算 固定費予算 実際発生額<br>操業度差異 固定費率 ×(実際操業度 基準操業度)<br>能率差異 変動費率 ×(標準操業度 実際操業度)</div>`,
keypoints:['配賦基準:直接作業時間・機械時間・直接材料費など','配賦差異 実際 予定(プラスなら不利差異)','予算差異:コスト管理の問題','操業度差異:設備の遊休・過稼働による差異'],
quiz:[
{q:'製造間接費予算¥600,000・基準操業度600時間のとき予定配賦率はいくらか。',choices:['¥100/時間','¥1,000/時間','¥600/時間','¥10/時間'],answer:1,exp:'予定配賦率 600,000 ÷ 600 1,000円/時間'},
{q:'予定配賦率¥1,000/時間・実際操業度580時間のとき予定配賦額は',choices:['¥580,000','¥600,000','¥620,000','¥1,000,000'],answer:0,exp:'予定配賦額 1,000 × 580 580,000円'},
{q:'実際製造間接費¥620,000・予定配賦額¥580,000のとき差異は何か。',choices:['¥40,000の有利差異','¥40,000の不利差異配賦不足','¥40,000の配賦過剰','差異なし'],answer:1,exp:'配賦差異 実際620,000 予定580,000 40,000の不利差異配賦不足'}
]
},
{ id:'i05', num:'I05', title:'個別原価計算',
concept:`<p><strong>個別原価計算</strong>は受注ごとに原価を集計する方法です。製造指図書ごとに原価計算表を作成します。</p><div class="formula-box"><div class="formula-label">原価計算表(例:指図書#101</div>直接材料費 ¥50,000<br>直接労務費 ¥30,000<br>製造間接費 ¥20,000配賦<br>─────────────<br>製造原価合計 ¥100,000</div><p>完成時:(借)製品 /(貸)仕掛品<br>販売時:(借)売上原価 /(貸)製品<br>月末仕掛品:完成していない指図書の原価合計</p>`,
keypoints:['各指図書を「小さな仕掛品勘定」と考えると整理しやすい','製造間接費は予定配賦率 × その指図書の操業量で按分','指図書が完成 → 製品勘定へ振替','月末に完成していない指図書の合計 → 期末仕掛品残高'],
quiz:[
{q:'個別原価計算で使用する原価集計の単位はどれか。',choices:['製品の種類ごと','製造工程ごと','製造指図書ごと','月ごと'],answer:2,exp:'個別原価計算では製造指図書(受注)ごとに原価を集計します。'},
{q:'直接材料費¥80,000・直接労務費¥40,000・製造間接費配賦額¥30,000のとき製造原価は',choices:['¥120,000','¥150,000','¥110,000','¥70,000'],answer:1,exp:'製造原価 80,000 40,000 30,000 150,000円'},
{q:'月末時点で完成していない製造指図書の原価は何に計上されるか。',choices:['製品','売上原価','期末仕掛品','製造間接費'],answer:2,exp:'未完成の指図書の原価は期末仕掛品として仕掛品勘定に残ります。'}
]
},
{ id:'i06', num:'I06', title:'総合原価計算',
concept:`<p><strong>総合原価計算</strong>は同種製品を大量生産する場合に使います。月末仕掛品を完成品換算量に変換して原価を按分します。</p><div class="formula-box"><div class="formula-label">完成品換算量と計算方法</div>月末仕掛品の換算量(加工費)= 月末仕掛品数量 × 加工進捗度<br><br>平均法:単価 =(月初仕掛品原価 当月投入原価)÷(完成品量 月末換算量)<br>先入先出法:月初仕掛品は先に完成したと仮定して計算</div><p>材料費は<strong>投入時点</strong>(通常始点)、加工費は<strong>加工進捗度</strong>に応じて配分。</p>`,
keypoints:['始点投入材料月末仕掛品も100%消費済み','終点投入材料:月末仕掛品には含まれない','加工費(労務費+製造間接費):進捗度に応じて按分','先入先出法:月初仕掛品分と当月分を分けて計算'],
quiz:[
{q:'月末仕掛品200個・加工進捗度50%のとき加工費の完成品換算量は?',choices:['200個','100個','150個','400個'],answer:1,exp:'換算量 200 × 50% 100個'},
{q:'材料を工程の始点で全量投入する場合、月末仕掛品の材料費の按分は?',choices:['進捗度に応じて按分','月末仕掛品数量分すべて計上','含めない','半分を計上'],answer:1,exp:'始点で全量投入の場合、月末仕掛品も材料費を100%(数量分すべて)負担します。'},
{q:'平均法と先入先出法の主な違いはどれか。',choices:['材料費の計算方法が異なる','月初仕掛品の扱い方が異なる','配賦基準が異なる','適用できる業種が異なる'],answer:1,exp:'平均法は月初と当月を一体計算、先入先出法は月初仕掛品を先に完成させる前提で計算します。'}
]
},
{ id:'i07', num:'I07', title:'標準原価計算',
concept:`<p><strong>標準原価計算</strong>はあらかじめ設定した標準原価と実際原価との差異(<strong>原価差異</strong>)を分析します。</p><div class="formula-box"><div class="formula-label">差異分析(直接材料費)</div>価格差異 =(標準価格 実際価格)× 実際消費量<br>数量差異 =(標準消費量 実際消費量)× 標準価格</div><div class="formula-box"><div class="formula-label">差異分析(直接労務費)</div>賃率差異 =(標準賃率 実際賃率)× 実際時間<br>時間差異 =(標準時間 実際時間)× 標準賃率</div>`,
keypoints:['有利差異:標準より少ないコスト','不利差異:標準より多いコスト(管理改善が必要)','直接労務費差異 → 賃率差異 時間差異','製造間接費差異 → 予算差異 操業度差異(+能率差異)'],
quiz:[
{q:'標準価格¥200/kg・実際価格¥210/kg・実際消費量500kgのとき価格差異は',choices:['¥5,000の有利差異','¥5,000の不利差異','¥500の有利差異','¥500の不利差異'],answer:1,exp:'価格差異 200 210× 500 5,000不利差異実際が標準より高かった'},
{q:'標準消費量600kg・実際消費量580kg・標準価格¥200/kgのとき数量差異は',choices:['¥4,000の有利差異','¥4,000の不利差異','¥2,000の有利差異','¥2,000の不利差異'],answer:0,exp:'数量差異 600 580× 200 4,000円有利差異実際消費量が標準より少なかった'},
{q:'標準原価計算の主なメリットはどれか。',choices:['実際原価を正確に計算できる','原価差異を通じてコスト管理・改善を促せる','税務上の申告に使用できる','製品の販売価格を自動決定できる'],answer:1,exp:'標準原価計算の主なメリットは原価差異分析によるコスト管理と改善活動への活用です。'}
]
},
{ id:'i08', num:'I08', title:'直接原価計算とCVP分析',
concept:`<p><strong>直接原価計算</strong>は変動費のみを製品原価とし、固定費は期間費用として処理します。</p><div class="formula-box"><div class="formula-label">直接原価計算P/L</div>売上高<br> 変動費(変動製造原価 変動販売費)<br> 貢献利益<br> 固定費(固定製造間接費 固定販売費 一般管理費)<br> 営業利益</div><div class="formula-box"><div class="formula-label">CVP分析損益分岐点</div>貢献利益率 貢献利益 ÷ 売上高<br>損益分岐点売上高 固定費 ÷ 貢献利益率<br>目標利益達成売上高 =(固定費 目標利益)÷ 貢献利益率</div><p>損益分岐点グラフ:売上高線と総原価線の交点が損益分岐点です。</p><svg viewBox="0 0 300 190" style="width:100%;max-width:380px;display:block;margin:12px auto;font-family:JetBrains Mono,monospace" aria-label="CVP分析グラフ"><rect width="300" height="190" fill="none"/><line x1="44" y1="10" x2="44" y2="155" stroke="rgba(255,255,255,0.15)" stroke-width="1.5"/><line x1="44" y1="155" x2="285" y2="155" stroke="rgba(255,255,255,0.15)" stroke-width="1.5"/><text x="38" y="158" text-anchor="end" font-size="9" fill="#64748B">0</text><text x="155" y="170" text-anchor="middle" font-size="9" fill="#64748B">販売量</text><text x="22" y="85" text-anchor="middle" font-size="9" fill="#64748B" transform="rotate(-90,22,85)">金額</text><line x1="44" y1="105" x2="275" y2="105" stroke="rgba(251,146,60,0.6)" stroke-width="1.5" stroke-dasharray="5,3"/><text x="278" y="108" font-size="9" fill="#FB923C">固定費</text><line x1="44" y1="155" x2="255" y2="25" stroke="#22D3EE" stroke-width="2"/><text x="258" y="22" font-size="9" fill="#22D3EE">売上高</text><line x1="44" y1="105" x2="255" y2="55" stroke="rgba(167,139,250,0.85)" stroke-width="2"/><text x="258" y="58" font-size="9" fill="#A78BFA">総原価</text><line x1="44" y1="105" x2="44" y2="155" stroke="rgba(251,146,60,0.4)" stroke-width="1.5" stroke-dasharray="3,3"/><circle cx="152" cy="90" r="5" fill="none" stroke="#4ADE80" stroke-width="2"/><line x1="152" y1="90" x2="152" y2="155" stroke="rgba(74,222,128,0.4)" stroke-width="1" stroke-dasharray="3,3"/><text x="152" y="180" text-anchor="middle" font-size="9" fill="#4ADE80">損益分岐点</text><text x="200" y="70" font-size="9" fill="rgba(74,222,128,0.8)">利益ゾーン</text><text x="75" y="135" font-size="9" fill="rgba(248,113,113,0.8)">損失ゾーン</text></svg>`,
keypoints:['直接原価計算:固定製造間接費は期間費用として全額計上','損益分岐点:利益ゼロの売上高(固定費をちょうど回収できる点)','安全余裕率 =(実際売上 損益分岐点売上)÷ 実際売上 × 100','全部原価計算との利益差額 固定費の期首・期末仕掛品への含み'],
quiz:[
{q:'売上高¥1,000,000・変動費¥600,000・固定費¥300,000のとき貢献利益は',choices:['¥400,000','¥100,000','¥700,000','¥300,000'],answer:0,exp:'貢献利益 売上高 変動費 1,000,000 600,000 400,000円'},
{q:'固定費¥300,000・貢献利益率40%のとき損益分岐点売上高は?',choices:['¥120,000','¥500,000','¥750,000','¥300,000'],answer:2,exp:'損益分岐点売上高 300,000 ÷ 40% 750,000円'},
{q:'直接原価計算で固定製造間接費はどのように処理するか。',choices:['製品原価に含める','期間費用として当期に全額費用計上','繰延処理する','資産計上する'],answer:1,exp:'直接原価計算では固定製造間接費を製品原価に含めず発生した期の期間費用として全額処理します。'}
]
}
]}
];
function bokiApp(){
return {
categories:[],
currentUnit:null,
quizState:{},
search:'',
sidebarOpen:false,
isDark:true,
progress:{},
scores:{},
keys:['A','B','C','D','E'],
init(){
this.categories = CATEGORIES.map(cat=>({
...cat,
units: cat.units.map(u=>({...u, catLabel:cat.label}))
}));
try{ this.progress = JSON.parse(localStorage.getItem('posimai-boki-progress')||'{}'); }
catch{ this.progress = {}; }
try{ this.scores = JSON.parse(localStorage.getItem('posimai-boki-scores')||'{}'); }
catch{ this.scores = {}; }
const t = localStorage.getItem('posimai-boki-theme')||'system';
this.isDark = t==='dark'||(t==='system'&&matchMedia('(prefers-color-scheme:dark)').matches);
this.$nextTick(()=>{ if(window.lucide) lucide.createIcons(); });
if('serviceWorker' in navigator){
navigator.serviceWorker.register('/sw.js').catch(()=>{});
}
},
get filteredCats(){
if(!this.search) return this.categories;
const q=this.search.toLowerCase();
return this.categories.map(cat=>({
...cat,
units:cat.units.filter(u=>u.title.toLowerCase().includes(q)||u.num.toLowerCase().includes(q))
})).filter(cat=>cat.units.length>0);
},
get totalCount(){ return this.categories.reduce((s,c)=>s+c.units.length,0); },
get doneCount(){ return Object.keys(this.progress).length; },
get progressPct(){ return this.totalCount ? Math.round(this.doneCount/this.totalCount*100) : 0; },
get quizAnswered(){
let n=0;
Object.values(this.quizState).forEach(s=>{ if(s) n++; });
return n;
},
get quizCorrect(){
let n=0;
Object.values(this.quizState).forEach(s=>{ if(s?.correct) n++; });
return n;
},
catPct(cat){
if(!cat.units.length) return 0;
return Math.round(cat.units.filter(u=>this.progress[u.id]).length/cat.units.length*100);
},
allUnits(){ return this.categories.flatMap(c=>c.units); },
isDone(id){ return !!this.progress[id]; },
markDone(){
if(!this.currentUnit) return;
this.progress[this.currentUnit.id]=true;
localStorage.setItem('posimai-boki-progress',JSON.stringify(this.progress));
},
bestScore(id){
const s=this.scores[id];
if(!s) return '';
return s.best+'/'+s.total;
},
scoreChipCls(id){
const s=this.scores[id];
if(!s) return 'zero';
if(s.best===s.total) return '';
if(s.best>=s.total*0.6) return 'partial';
return 'zero';
},
saveScore(id,correct,total){
const prev=this.scores[id];
if(!prev||correct>prev.best){
this.scores[id]={best:correct,total};
localStorage.setItem('posimai-boki-scores',JSON.stringify(this.scores));
}
},
get freqBadgeCls(){
const f=this.currentUnit?.freq;
if(f==='high') return 'badge badge-high';
if(f==='mid') return 'badge badge-mid';
return 'badge badge-base';
},
get freqLabel(){
const f=this.currentUnit?.freq;
if(f==='high') return '頻出';
if(f==='mid') return '重要';
return '基礎';
},
get diffLabel(){
const d=this.currentUnit?.diff||1;
return '難易度 '+'★'.repeat(d)+'☆'.repeat(3-d);
},
openUnit(unit){
this.currentUnit=unit;
this.quizState={};
this.$nextTick(()=>{
if(window.lucide) lucide.createIcons();
const m=document.getElementById('main');
if(m) m.scrollTo({top:0,behavior:'smooth'});
});
},
// Quiz
answered(qi){ return !!this.quizState[qi]; },
doAnswer(qi,ci,correct,exp){
if(this.quizState[qi]) return;
this.quizState[qi]={selected:ci,correct:ci===correct,exp};
this.quizState={...this.quizState};
},
qCardCls(qi){
const s=this.quizState[qi];
if(!s) return '';
return s.correct?'correct':'wrong';
},
choiceCls(qi,ci,correct){
const s=this.quizState[qi];
if(!s) return '';
if(ci===s.selected && s.correct) return 'sel-ok';
if(ci===s.selected && !s.correct) return 'sel-ng';
if(ci===correct && !s.correct) return 'rev-ok';
return '';
},
get scoreLabel(){
const total=this.currentUnit?.quiz?.length||0;
const answered=Object.keys(this.quizState).length;
const correct=Object.values(this.quizState).filter(s=>s?.correct).length;
if(!answered) return total+'問';
return correct+'/'+answered+'問正解';
},
get allAnswered(){
const total=this.currentUnit?.quiz?.length||0;
return total>0 && Object.keys(this.quizState).length>=total;
},
get resultScore(){
const correct=Object.values(this.quizState).filter(s=>s?.correct).length;
const total=this.currentUnit?.quiz?.length||0;
if(this.currentUnit) this.saveScore(this.currentUnit.id,correct,total);
return correct+' / '+total;
},
get resultMsg(){
const correct=Object.values(this.quizState).filter(s=>s?.correct).length;
const total=this.currentUnit?.quiz?.length||0;
if(correct===total) return '完璧です!次の単元へ進みましょう。';
if(correct>=total*0.8) return 'よくできました。あと少しで完璧です。';
if(correct>=total*0.6) return '合格ラインです。間違えた問題の解説を確認しましょう。';
return '解説をよく読んで、もう一度チャレンジしてみましょう。';
},
resetQuiz(){ this.quizState={}; },
// Navigation
currentIdx(){ return this.allUnits().findIndex(u=>u.id===this.currentUnit?.id); },
get hasPrev(){ return this.currentIdx()>0; },
get hasNext(){ return this.currentIdx()<this.allUnits().length-1; },
prevUnit(){
const i=this.currentIdx();
if(i>0) this.openUnit(this.allUnits()[i-1]);
},
nextUnit(){
const i=this.currentIdx();
const all=this.allUnits();
if(i<all.length-1) this.openUnit(all[i+1]);
},
toggleTheme(){
this.isDark=!this.isDark;
const val=this.isDark?'dark':'light';
document.documentElement.setAttribute('data-theme',val);
localStorage.setItem('posimai-boki-theme',val);
}
};
}
</script>
</body>
</html>