:host{display:block;box-sizing:border-box}
:host *{box-sizing:border-box}
/* 레이아웃: 1200px 단일 칼럼. 상단 제목·탭 아래로 카드가 쌓이는 대시보드 판형 */
:host{
--base-a:#070D1A; --base-b:#0B1426; --glow:rgba(46,107,216,.12);
--fg:#EAF0FB; --fg2:#C5D0E4; --muted:#8A97B2; --hint:#6A789A;
--line:rgba(255,255,255,.08); --line2:rgba(255,255,255,.14);
--sunk:rgba(0,0,0,.18); --raise:rgba(255,255,255,.03);
--gold:#E8C25A; --gold-ink:#3A2C05; --gold-soft:rgba(232,194,90,.1); --gold-line:rgba(232,194,90,.3);
--blue:#6FA8FF; --blue-soft:rgba(46,107,216,.14); --blue-line:rgba(111,168,255,.28);
--ok:#67D5A8; --ok-soft:rgba(103,213,168,.1);
--ui:Pretendard,'Pretendard Variable',Inter,'Noto Sans KR',system-ui,-apple-system,sans-serif;
color-scheme:dark;
}
*{box-sizing:border-box}
:host{
background:radial-gradient(1100px 600px at 50% -10%, var(--glow), rgba(0,0,0,0) 60%), linear-gradient(var(--base-a) 0%, var(--base-b) 100%);
background-attachment:fixed; color:var(--fg); font-family:var(--ui);
font-size:14px; line-height:1.6; letter-spacing:-.14px; -webkit-font-smoothing:antialiased; min-height:100%;
}
h1,h2,h3{margin:0;font-family:var(--ui);text-wrap:balance}
p{margin:0}
button{font:inherit;color:inherit;cursor:pointer;letter-spacing:inherit}
a{color:var(--blue)}
.wrap{max-width:1200px;margin-inline:auto;padding-inline:16px}
/* 헤더 */
.head{padding-block:26px 4px}
.kicker{font-size:clamp(13.5px,3.1vw,16px);font-weight:700;color:var(--gold);letter-spacing:-.2px;line-height:1.4}
.kicker em{font-style:normal;color:var(--muted);font-weight:600}
.title{font-size:clamp(24px,5.2vw,30px);font-weight:800;letter-spacing:-.84px;margin-top:9px;color:#fff;display:inline-block;background:none;border:0;padding:0;text-align:left;cursor:pointer;line-height:1.25;padding-block:4px}
.title:hover{color:var(--gold)}
.title:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:4px}
.title .home{font-size:11px;font-weight:600;color:var(--hint);margin-left:9px;vertical-align:middle;white-space:nowrap}
.title:hover .home{color:var(--gold)}
.sub{font-size:13.5px;color:var(--muted);margin-top:8px;max-width:64ch}
.gist{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:10px;margin-top:18px}
.gist div{background:var(--raise);border:1px solid var(--line);border-radius:8px;padding:13px 16px;min-width:0}
.gist b{display:block;font-size:12.5px;font-weight:700;color:#fff;margin-bottom:4px}
.gist span{font-size:12px;color:var(--fg2);line-height:1.55}
/* 탭 */
nav{position:sticky;top:env(safe-area-inset-top,0px);z-index:20;
background:rgba(7,13,26,.86);backdrop-filter:blur(8px);border-bottom:1px solid var(--line);margin-top:20px}
.tabs{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding-block:10px}
.tabs::-webkit-scrollbar{display:none}
.tabs button{background:var(--sunk);border:1px solid var(--line2);border-radius:9px;padding:9px 14px;
font-size:12.5px;font-weight:600;color:var(--fg2);white-space:nowrap}
.tabs button[aria-selected="true"]{background:var(--gold);border-color:var(--gold);color:var(--gold-ink);font-weight:700}
.tabs button:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
main{padding-block:22px 50px}
section>h2{font-size:19px;font-weight:800;letter-spacing:-.5px}
.lede{color:var(--muted);font-size:13px;margin-top:7px;max-width:68ch}
.hint{font-size:11.5px;color:var(--hint)}
/* 카드 */
.card{border:1px solid var(--line);border-radius:14px;background:rgba(255,255,255,.015);margin-top:14px;overflow:hidden}
.card-head{font-size:14.5px;font-weight:800;color:#fff;padding:14px 20px;border-bottom:1px solid var(--line)}
.card-body{padding:20px 20px 22px}
.callout{background:var(--raise);border:1px solid var(--line);border-radius:8px;padding:13px 16px;font-size:12.5px;color:var(--fg2);line-height:1.62}
.callout.warn{background:var(--gold-soft);border-color:var(--gold-line);color:var(--fg)}
.callout.warn b{color:var(--gold)}
.stack{display:flex;flex-direction:column;gap:14px}
/* 옵션·칩 */
.opts{display:flex;flex-wrap:wrap;gap:8px}
.opt{background:var(--sunk);border:1px solid var(--line2);border-radius:9px;padding:10px 14px;font-size:12.5px;font-weight:600;color:var(--fg2)}
.opt[aria-pressed="true"]{background:var(--gold);border-color:var(--gold);color:var(--gold-ink)}
.opt:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.btn{background:var(--gold);color:var(--gold-ink);border:1px solid var(--gold);border-radius:9px;padding:10px 16px;font-size:13px;font-weight:700}
.btn.ghost{background:var(--sunk);border-color:var(--line2);color:var(--fg2);font-weight:600}
.btn:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.mini{background:var(--sunk);border:1px solid var(--line2);border-radius:8px;padding:7px 12px;font-size:11.5px;font-weight:600;color:var(--fg2);white-space:nowrap}
.mini:hover{border-color:var(--gold-line);color:var(--gold)}
.mini.done{background:var(--ok-soft);border-color:var(--ok);color:var(--ok)}
.mini:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* 라벨·배지 */
.label{font-size:11.5px;font-weight:600;color:var(--hint);letter-spacing:.02em}
.badge{font-size:10.5px;font-weight:600;border:1px solid var(--line2);color:var(--muted);border-radius:6px;padding:3px 8px}
.spd{font-size:10.5px;font-weight:700;border-radius:6px;padding:3px 8px;border:1px solid transparent}
.spd.fast{background:var(--ok-soft);color:var(--ok);border-color:rgba(103,213,168,.3)}
.spd.slow{background:var(--gold-soft);color:var(--gold);border-color:var(--gold-line)}
.spd.flat{background:var(--sunk);color:var(--muted);border-color:var(--line2)}
/* 절차 */
.step{display:grid;grid-template-columns:96px 1fr;gap:16px;padding:15px 0;border-top:1px solid var(--line)}
.step:first-child{border-top:0;padding-top:0}
.when{font-size:11.5px;font-weight:700;color:var(--gold);letter-spacing:.02em;padding-top:2px}
.step h3{font-size:14.5px;font-weight:700;color:#fff}
.step ul{margin:8px 0 0;padding-left:16px;font-size:12.8px;color:var(--fg2)}
.step li{
margin-bottom:5px}
.step li::marker{color:var(--hint)}
@media (max-width:560px){.step{grid-template-columns:1fr;gap:5px}}
/* 체크 */
.chk{display:flex;gap:11px;align-items:flex-start;padding:10px 0;border-top:1px solid var(--line)}
.chk:first-child{border-top:0;padding-top:0}
.chk input{margin-top:4px;accent-color:var(--gold);width:16px;height:16px;flex:none}
.chk label{font-size:13px;min-width:0;color:var(--fg)}
.chk .sm{display:block;color:var(--hint);font-size:11.5px;margin-top:2px}
/* 표 */
.scroller{overflow-x:auto;min-width:0}
.tbl{width:100%;border-collapse:collapse;font-size:12.8px}
.tbl th{text-align:left;font-size:11px;font-weight:600;color:var(--hint);padding:0 12px 9px 0;border-bottom:1px solid var(--line);white-space:nowrap}
.tbl td{padding:10px 12px 10px 0;border-bottom:1px solid var(--line);vertical-align:top;color:var(--fg2)}
.tbl td:first-child{color:var(--gold);white-space:nowrap;font-weight:700;font-size:11.5px}
/* 필터·검색 */
.filters{display:flex;flex-wrap:wrap;gap:7px;margin-top:16px;align-items:center}
input[type=search],input[type=text]{background:var(--sunk);border:1px solid var(--line2);border-radius:9px;padding:9px 13px;font:inherit;font-size:12.5px;color:var(--fg);letter-spacing:inherit}
input::placeholder{color:var(--hint)}
input:focus{outline:2px solid var(--gold);outline-offset:-1px}
#q{flex:1;min-width:170px}
.count{font-size:11.5px;color:var(--hint);margin-top:12px}
/* 사안 카드 */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:12px;margin-top:10px}
.item{background:var(--raise);border:1px solid var(--line);border-radius:12px;padding:16px;text-align:left;min-width:0;display:flex;flex-direction:column;gap:8px}
.item:hover{border-color:var(--gold-line)}
.item:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.itemtop{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.item h3{font-size:14px;font-weight:700;line-height:1.45;color:#fff}
.item p{font-size:12px;color:var(--muted);line-height:1.55;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* 상세 */
.detail{position:fixed;inset:0;z-index:40;background:rgba(3,7,15,.7);display:flex;align-items:flex-end;justify-content:center}
.sheet{background:linear-gradient(var(--base-b),var(--base-a));border:1px solid var(--line);width:min(820px,100%);max-height:92vh;overflow-y:auto;
border-radius:14px 14px 0 0;padding:20px 20px calc(30px + env(safe-area-inset-bottom,0px))}
@media (min-width:760px){.detail{align-items:center}.sheet{border-radius:14px;max-height:88vh}}
.sheet h3{font-size:19px;font-weight:800;margin-top:10px;letter-spacing:-.5px;color:#fff}
.close{float:right;background:var(--sunk);border:1px solid var(--line2);border-radius:8px;padding:6px 12px;font-size:11.5px;color:var(--fg2)}
.sec{margin-top:18px}
.sec>.label{display:block;margin-bottom:8px}
.sec ul{margin:0;padding-left:16px;font-size:12.8px;color:var(--fg2)}
.sec li{margin-bottom:5px}
.quote{background:var(--blue-soft);border:1px solid var(--blue-line);border-left-width:3px;padding:13px 15px;border-radius:0 8px 8px 0;font-size:13px;line-height:1.7;color:var(--fg)}
/* 문장 목록 */
.say{display:grid;grid-template-columns:1fr auto;gap:12px;align-items:start;padding:14px 0;border-top:1px solid var(--line)}
.say:first-child{border-top:0;padding-top:0}
.say b{display:block;font-size:12.5px;font-weight:700;color:#fff;margin-bottom:5px}
.say p{font-size:12.8px;line-height:1.62;color:var(--fg2)}
/* 질문 */
.qgrp{border:1px solid var(--line);border-radius:12px;overflow:hidden}
.qgrp-head{display:flex;gap:11px;align-items:flex-start;padding:14px 18px;background:var(--raise);border-bottom:1px solid var(--line)}
.qgrp-head input{margin-top:4px;accent-color:var(--gold);width:16px;height:16px;flex:none}
.qgrp-head h3{font-size:14px;font-weight:800;color:#fff}
.qgrp-body{padding:4px 18px 18px}
.qrow{padding:16px 0;border-top:1px solid var(--line)}
.qrow:first-child{border-top:0}
.qq{font-size:13.5px;font-weight:700;color:#fff;line-height:1.55}
.ql{font-size:12px;color:var(--muted);margin-top:6px}
.qs{margin-top:10px;display:grid;grid-template-columns:1fr auto;gap:10px;align-items:start}
.gap{background:var(--gold-soft);border:1px solid var(--gold-line);border-radius:8px;padding:11px 14px;margin-top:12px}
.gap label{display:block;font-size:11.5px;font-weight:700;color:var(--gold);margin-bottom:6px}
.gap input{width:100%}
/* 현황 타일 */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px}
.tile{background:var(--raise);border:1px solid var(--line);border-radius:12px;padding:15px 16px;min-width:0}
.tile .cap{font-size:11.5px;color:var(--hint);font-weight:600}
.tile .big{font-size:30px;font-weight:800;color:#fff;letter-spacing:-.9px;font-variant-numeric:tabular-nums;margin-top:6px;line-height:1.1}
.tile .big em{font-style:normal;font-size:15px;font-weight:600;color:var(--muted);margin-left:3px;letter-spacing:-.2px}
.tile .foot{font-size:11.5px;color:var(--muted);margin-top:5px}
.meter{height:6px;border-radius:999px;background:var(--sunk);border:1px solid var(--line);margin-top:10px;overflow:hidden}
.meter>span{display:block;height:100%;background:var(--gold);border-radius:999px}
.rows{margin-top:6px}
.row{display:grid;grid-template-columns:auto 1fr;gap:10px;padding:11px 0;border-top:1px solid var(--line);font-size:12.8px;color:var(--fg2)}
.row:first-child{border-top:0}
.row .k{font-size:11.5px;font-weight:700;color:var(--gold);white-space:nowrap}
.row .k.mute{color:var(--muted)}
.row .v b{color:#fff;font-weight:700}
.row .v span{display:block;color:var(--hint);font-size:11.5px;margin-top:2px}
.asof{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:center;justify-content:space-between}
.asof .when{font-size:12px;color:var(--muted)}
.asof .when b{color:var(--gold);font-weight:700;font-variant-numeric:tabular-nums}
.fieldrow{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end}
.fieldrow label{font-size:11.5px;color:var(--hint)}
.fieldrow input{displa
y:block;margin-top:5px}
.report{width:100%;min-height:300px;background:var(--sunk);border:1px solid var(--line2);border-radius:9px;padding:14px;
font-family:var(--ui);font-size:12.5px;line-height:1.8;color:var(--fg);resize:vertical;letter-spacing:-.14px}
.report:focus{outline:2px solid var(--gold);outline-offset:-1px}
.btnrow{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
/* 진입 화면 */
.entry{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:12px;margin-top:18px}
.big{background:var(--sunk);border:1px solid var(--line2);border-radius:14px;padding:22px 18px;text-align:left;min-width:0}
.big:hover{border-color:var(--gold)}
.big:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.big b{display:block;font-size:17px;font-weight:800;color:#fff;letter-spacing:-.4px}
.big span{display:block;font-size:12px;color:var(--muted);margin-top:5px;line-height:1.5}
.big.lead{background:var(--gold);border-color:var(--gold)}
.big.lead b{color:var(--gold-ink)} .big.lead span{color:#5A4607}
.quiet{display:inline-block;margin-top:14px;background:none;border:0;border-bottom:1px solid var(--line2);padding:4px 0;font-size:13px;color:var(--fg2)}
.top.compact{padding-block:12px 10px}
.top.compact .title{font-size:17px;margin-top:2px;padding-block:9px}
.top.compact .sub,.top.compact .topwarn,.top.compact .kicker{display:none}
.topwarn{background:var(--sunk);border:1px solid var(--line2);border-radius:8px;padding:9px 13px;font-size:11.5px;color:var(--muted);margin-top:14px}
/* 지금 모드 */
.now-head{display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:space-between;padding-block:14px}
.now-head .back{background:var(--sunk);border:1px solid var(--line2);border-radius:8px;padding:7px 12px;font-size:12px;color:var(--fg2)}
.stepno{font-size:11px;font-weight:700;color:var(--gold);letter-spacing:.06em}
.lines{display:flex;flex-direction:column;gap:10px;margin-top:12px}
.line{background:var(--sunk);border:1px solid var(--line2);border-radius:10px;padding:14px 16px;display:grid;grid-template-columns:26px 1fr auto;gap:12px;align-items:start}
.line .n{width:24px;height:24px;border-radius:50%;background:var(--gold);color:var(--gold-ink);font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center}
.line p{font-size:15px;line-height:1.66;color:#fff;min-width:0}
.line.counter{border-color:var(--gold-line);background:var(--gold-soft)}
.line.counter .n{background:var(--fg);color:var(--base-a)}
.slot{color:var(--gold);font-weight:700}
.badge-role{font-size:10px;font-weight:700;border-radius:5px;padding:2px 7px;border:1px solid var(--line2);color:var(--muted)}
.badge-role.staff{border-color:var(--ok);color:var(--ok)}
.badge-role.lead{border-color:var(--gold-line);color:var(--gold)}
.badge-role.exec{border-color:var(--line2);color:var(--muted)}
.alertbar{background:var(--gold-soft);border:1px solid var(--gold-line);border-radius:10px;padding:13px 15px;margin-top:14px}
.alertbar b{display:block;font-size:13.5px;font-weight:800;color:var(--gold);margin-bottom:4px}
.alertbar span{font-size:12.5px;color:var(--fg2)}
.fold{border:1px solid var(--line);border-radius:10px;margin-top:12px;overflow:hidden}
.fold>summary{padding:13px 16px;font-size:13px;font-weight:700;color:var(--fg2);cursor:pointer;background:var(--raise);list-style:none}
.fold>summary::-webkit-details-marker{display:none}
.fold>summary::after{content:" ▾";color:var(--hint)}
.fold[open]>summary::after{content:" ▴"}
.fold .in{padding:16px}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}
.fld{display:block;font-size:11.5px;color:var(--hint)}
.fld input,.fld textarea{display:block;width:100%;margin-top:5px;background:var(--sunk);border:1px solid var(--line2);border-radius:8px;padding:9px 12px;font:inherit;font-size:13px;color:var(--fg);letter-spacing:-.14px}
.fld textarea{min-height:76px;resize:vertical}
.fld input:focus,.fld textarea:focus{outline:2px solid var(--gold);outline-offset:-1px}
.rowbtn{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.seg{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.disabled{opacity:.45;cursor:not-allowed}
.report{width:100%;min-height:230px;background:var(--sunk);border:1px solid var(--line2);border-radius:9px;padding:14px;font-family:var(--ui);font-size:12.5px;line-height:1.8;color:var(--fg);resize:vertical;letter-spacing:-.14px}
.report:focus{outline:2px solid var(--gold);outline-offset:-1px}
.btnrow{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px}
.tile{background:var(--raise);border:1px solid var(--line);border-radius:12px;padding:15px 16px;min-width:0}
.tile .cap{font-size:11.5px;color:var(--hint);font-weight:600}
.tile .big2{font-size:28px;font-weight:800;color:#fff;letter-spacing:-.9px;font-variant-numeric:tabular-nums;margin-top:6px;line-height:1.1}
.tile .big2 em{font-style:normal;font-size:14px;font-weight:600;color:var(--muted);margin-left:3px}
.tile .foot{font-size:11.5px;color:var(--muted);margin-top:5px}
.meter{height:6px;border-radius:999px;background:var(--sunk);border:1px solid var(--line);margin-top:10px;overflow:hidden}
.meter>span{display:block;height:100%;background:var(--gold);border-radius:999px}
/* 명함 카드 */
.cardsheet{display:none}
@media print{
:host{background:#fff!important;color:#000!important}
nav,.top,.entry,footer,.noprint,.tabs,.rowbtn,.btnrow{display:none!important}
.cardsheet{display:block!important}
main,section{display:none!important}
.namecard{width:85mm;height:54mm;border:1px dashed #999;padding:5mm;float:left;page-break-inside:avoid;
font-size:7.1pt;line-height:1.38;color:#000;box-sizing:border-box}
.namecard h4{margin:0 0 2mm;font-size:8.6pt;font-weight:800}
.namecard b{font-weight:700}
.namecard ol,.namecard ul{margin:0;padding-left:4mm}
.namecard li{margin-bottom:.6mm}
.namecard li{margin-bottom:.8mm}
.namecard .ln{border-bottom:1px solid #bbb;display:inline-
block;min-width:22mm}
.namecard .ft{margin-top:1.5mm;font-size:6.6pt;color:#555}
}
footer{border-top:1px solid var(--line);padding-block:22px 36px}
.foot{display:flex;flex-wrap:wrap;gap:18px 34px;justify-content:space-between;font-size:12px;color:var(--muted)}
.foot b{display:block;font-size:12.5px;font-weight:700;color:var(--fg);margin-bottom:5px}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
/* ===== 2단계 선택 ===== */
.pick{margin-top:24px}
.pick.off{opacity:.33}
.pick.off .big{pointer-events:none}
.picklbl{display:flex;align-items:center;gap:9px;font-size:14px;font-weight:800;color:#fff;letter-spacing:-.3px}
.picklbl .pn{width:22px;height:22px;border-radius:50%;background:var(--gold);color:var(--gold-ink);font-size:11.5px;font-weight:800;display:flex;align-items:center;justify-content:center;flex:none}
.pick.off .picklbl .pn{background:var(--sunk);color:var(--muted);border:1px solid var(--line2)}
.picksub{font-size:11.8px;color:var(--hint);margin:6px 0 0 31px;line-height:1.55}
@media (max-width:560px){.picksub{margin-left:0}}
.entry{grid-template-columns:repeat(auto-fit,minmax(206px,1fr));gap:10px;margin-top:12px}
.big{padding:18px 16px}
.big b{font-size:16px}
.big.on{background:var(--gold);border-color:var(--gold)}
.big.on b{color:var(--gold-ink)}
.big.on span{color:#5A4607}
/* ===== 진행 바 ===== */
.trail{display:flex;align-items:center;gap:7px;flex-wrap:wrap;padding-block:12px;border-bottom:1px solid var(--line)}
.trail .tp{display:flex;align-items:center;gap:6px;font-size:12.2px;font-weight:600;color:var(--fg2);background:var(--sunk);border:1px solid var(--line2);border-radius:8px;padding:6px 11px}
.trail .tp i{font-style:normal;width:16px;height:16px;border-radius:50%;background:var(--gold);color:var(--gold-ink);font-size:9.6px;font-weight:800;display:flex;align-items:center;justify-content:center;flex:none}
.trail .tp.now{border-color:var(--gold-line);color:#fff}
.trail .sepc{color:var(--hint);font-size:11px}
.trail .chg{margin-left:auto;background:var(--sunk);border:1px solid var(--line2);border-radius:8px;padding:9px 12px;min-height:36px;
display:inline-flex;align-items:center;font-size:12px;font-weight:600;color:var(--fg2)}
.trail .chg:hover{border-color:var(--gold-line);color:var(--gold)}
.trail .chg:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* ===== 번호 블록 ===== */
.blk{margin-top:28px}
.blkhead{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.blkhead .bn{width:25px;height:25px;border-radius:7px;background:var(--gold);color:var(--gold-ink);font-size:13px;font-weight:800;display:flex;align-items:center;justify-content:center;flex:none}
.blkhead h2{font-size:17.5px;font-weight:800;letter-spacing:-.55px;color:#fff}
.blkhead .bcount{font-size:11.5px;color:var(--hint);font-weight:700}
.blksub{font-size:12.6px;color:var(--muted);margin:8px 0 0 35px;max-width:72ch;line-height:1.62}
@media (max-width:560px){.blksub{margin-left:0}}
/* ===== 질문 카드 ===== */
.qc{border:1px solid var(--line);border-radius:13px;background:rgba(255,255,255,.015);overflow:hidden}
.qc-top{padding:16px 18px 15px;border-bottom:1px solid var(--line);background:var(--raise)}
.qc-meta{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:9px}
.qc-q{font-size:15.5px;font-weight:800;line-height:1.52;color:#fff;letter-spacing:-.34px}
.qc-q i{font-style:normal;color:var(--gold);margin-right:5px}
.qc-why{font-size:12.4px;color:var(--muted);line-height:1.62;margin-top:9px}
.qc-why b{color:var(--fg2);font-weight:700}
.zone{padding:15px 18px;border-top:1px solid var(--line)}
.zone:first-of-type{border-top:0}
details.zone>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
details.zone>summary::-webkit-details-marker{display:none}
details.zone>summary .zt::after{content:" ▾";color:var(--hint)}
details.zone[open]>summary .zt::after{content:" ▴"}
.zhead{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.zt{font-size:12.6px;font-weight:800;color:#fff;border-left:3px solid var(--gold);padding-left:8px;letter-spacing:-.2px}
.zone.z-say .zt{border-left-color:var(--ok)}
.zone.ban .zt{border-left-color:#E4734F}
.readline{background:var(--sunk);border:1px solid var(--line2);border-radius:10px;padding:14px 16px;margin-top:10px;font-size:15px;line-height:1.68;color:#fff}
.four{margin-top:11px;display:flex;flex-direction:column;gap:8px}
.fr{display:grid;grid-template-columns:36px 1fr;gap:11px;background:var(--sunk);border:1px solid var(--line);border-radius:9px;padding:12px 14px}
.fr .fn{display:flex;flex-direction:column;align-items:center;gap:4px}
.fr .fn i{font-style:normal;width:20px;height:20px;border-radius:50%;background:var(--raise);border:1px solid var(--line2);color:var(--gold);font-size:10.5px;font-weight:800;display:flex;align-items:center;justify-content:center}
.fr .fn em{font-style:normal;font-size:10px;color:var(--hint);font-weight:700;letter-spacing:-.2px}
.fr p{font-size:13.5px;line-height:1.66;color:var(--fg)}
.fr .fh{font-size:10.8px;color:var(--hint);margin-top:5px;line-height:1.5}
.needs{display:flex;flex-wrap:wrap;gap:7px;margin-top:11px}
.needs span{font-size:11.9px;background:var(--gold-soft);border:1px solid var(--gold-line);color:var(--fg);border-radius:7px;padding:6px 10px}
.bans{margin-top:10px;display:flex;flex-direction:column;gap:6px}
.bans div{font-size:12.4px;color:var(--fg2);padding-left:16px;position:relative;line-height:1.56}
.bans div::before{content:"\00d7";position:absolute;left:0;top:0;color:#E4734F;font-weight:800}
.disc{background:var(--sunk);border:1px dashed var(--line2);border-radius:8px;padding:10px 13px;font-size:11.5px;color:var(--muted);margin-top:11px;line-height:1.62}
.jump{display:flex;flex-wrap:wrap;gap:7px;margin-top:12px}
.todo{margin-top:12px}
.todo .chk{padding:9px 0}
.cardsheet.on{display:block;margin-top:16px;max-width:1200px;margin-inline:auto;padding-inline:16px}
.cardsheet.on::after{content:"";display:block;clear:both}
.cardsh
eet.on .namecard{width:min(85mm,100%);border:1px dashed var(--line2);border-radius:10px;padding:16px;float:left;margin:0 10px 10px 0;
font-size:11.3px;line-height:1.55;color:var(--fg2);box-sizing:border-box;background:var(--sunk)}
.cardsheet.on .namecard h4{margin:0 0 8px;font-size:12.5px;font-weight:800;color:#fff}
.cardsheet.on .namecard b{color:var(--gold);font-weight:700}
.cardsheet.on .namecard ol,.cardsheet.on .namecard ul{margin:0;padding-left:16px}
.cardsheet.on .namecard li{margin-bottom:5px}
.cardsheet.on .namecard .ln{border-bottom:1px solid var(--line2);display:inline-block;min-width:70px}
.cardsheet.on .namecard .ft{margin-top:8px;font-size:10.5px;color:var(--hint)}
/* 평시 배너 */
.banner{display:flex;align-items:center;gap:14px;width:100%;text-align:left;margin-top:26px;
background:linear-gradient(90deg,var(--gold-soft),rgba(232,194,90,.03));border:1px solid var(--gold-line);
border-radius:13px;padding:17px 20px}
.banner:hover{border-color:var(--gold);background:linear-gradient(90deg,rgba(232,194,90,.16),rgba(232,194,90,.05))}
.banner:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.banner .bi{width:38px;height:38px;border-radius:9px;background:var(--gold);color:var(--gold-ink);flex:none;
display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:800;letter-spacing:-.4px}
.banner .bl{min-width:0;flex:1}
.banner .bl b{display:block;font-size:15px;font-weight:800;color:#fff;letter-spacing:-.35px}
.banner .bl span{display:block;font-size:12.2px;color:var(--fg2);margin-top:4px;line-height:1.55}
.banner .ba{font-size:12.5px;font-weight:700;color:var(--gold);white-space:nowrap}
@media (max-width:560px){.banner{align-items:flex-start}.banner .ba{display:none}}
/* 튜토리얼 */
.tuthead{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:space-between}
.tutprog{font-size:11.5px;font-weight:700;color:var(--gold);font-variant-numeric:tabular-nums}
.tut{display:grid;grid-template-columns:auto 1fr auto;gap:12px 13px;align-items:start;padding:14px 0;border-top:1px solid var(--line)}
.tut:first-child{border-top:0;padding-top:0}
.tut .tn{width:24px;height:24px;border-radius:50%;background:var(--sunk);border:1px solid var(--line2);color:var(--muted);
font-size:11.5px;font-weight:800;display:flex;align-items:center;justify-content:center;flex:none;margin-top:1px}
.tut.on .tn{background:var(--ok);border-color:var(--ok);color:var(--base-a)}
.tut .tt{font-size:13.6px;font-weight:700;color:#fff;line-height:1.5}
.tut.on .tt{color:var(--muted);text-decoration:line-through;text-decoration-color:var(--line2)}
.tut .td{font-size:12.2px;color:var(--muted);margin-top:4px;line-height:1.6}
.tut .tb{display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:flex-end}
@media (max-width:560px){.tut{grid-template-columns:auto 1fr}.tut .tb{grid-column:2;justify-content:flex-start}}
/* 연관 과정 */
.foot a{color:var(--gold);text-decoration:none;border-bottom:1px solid var(--gold-line)}
.foot a:hover{border-bottom-color:var(--gold)}
.foot .rel{display:inline-flex;align-items:center;gap:6px;margin-top:8px;background:var(--sunk);
border:1px solid var(--gold-line);border-radius:8px;padding:8px 13px;font-size:12px;font-weight:700;color:var(--gold);text-decoration:none}
.foot .rel:hover{border-color:var(--gold);background:var(--gold-soft)}
var booted=false;
function pageTop(){ if(!booted) return;
try{ HOST.scrollIntoView({block:"start",behavior:"smooth"}) }
catch(e){ try{ HOST.scrollIntoView() }catch(x){} } }
const CASES=[
{kind:"position",role:"lead",id:"A1",ax:"A",t:"내부 직원의 공금 유용이 드러남",spd:"fast",spdL:"인지 4일",
what:"한 시민구단에서 회계 담당 직원 1명이 문서 위조와 잔액 조작으로 3년 넘게 운영비를 빼돌린 사실이 드러남. 구단이 자체 점검 중 발견해 사흘 만에 고소하고 나흘 만에 지자체장이 기자회견을 열었음. 그런데 2주 뒤 프레임이 개인 일탈에서 조직 관리 실패로 완전히 넘어갔음.",
split:["첫 발표에서 금액을 단정형으로 말했는데, 그 금액이 이후 계속 커졌음. 커질 때마다 사안이 새로 시작됐음","\"직원 한 명이 저지를 규모가 아니다\"라는 문장이 나온 날, 논점이 범인에서 관리 구조로 옮겨감","상급 기관은 \"각 구단은 별도 법인\"이라고 답했다가 열흘 뒤 지원팀을 파견함. 초기 발언과 이후 행동이 어긋난 것으로 기록됨"],
steps:[["인지 즉시","접근 권한 차단, 관련 계좌·전표 보전. 자체 조사팀 구성"],["24시간 내","수사 의뢰. 의뢰 사실 자체를 먼저 알림"],["48시간 내","구단 입장문. 인지 경위·조치·수사 의뢰 사실을 첫 문단에. 금액은 \"현재까지 확인된\"으로만"],["1주 내","\"한 사람이 가능했던 구조\"에 대한 설명을 우리가 먼저 내놓음 — 결재 단계, 대사 주기, 권한 분리"],["1개월 내","재발 방지 계획을 시점과 담당을 넣어 공개하고 이행 상황을 같은 자리에 갱신"]],
say:"○월 ○일 내부 점검 과정에서 계좌 잔액 조작 정황을 확인했고, 즉시 해당 직원의 권한을 차단한 뒤 ○월 ○일 수사를 의뢰했습니다. 현재까지 확인된 금액은 ○○이며 조사 진행에 따라 달라질 수 있습니다. 확정되는 대로 산출 근거와 함께 알리겠습니다.",
prep:["계좌 대사 주기와 이중 확인 절차를 문서로 정해 두기","수사 의뢰 시 배포할 입장문 초안 미리 만들어 두기","\"어떻게 이게 가능했나\"에 답할 결재 구조 설명 자료 한 장"]},
{kind:"position",role:"lead",id:"A2",ax:"A",t:"예산 집행·출장 내역이 문제가 됨",spd:"slow",spdL:"입장 없음",
what:"여러 시·도민구단 대표·단장이 참여한 해외 출장에서 공문에 없던 휴양지 일정과 비즈니스석 이용이 드러나 고발로 이어짐. 해당 기관과 구단들이 끝까지 공식 입장을 내지 않았고, 그 결과 모든 보도가 고발한 쪽 발언만으로 구성됨.",
split:["아무 말도 하지 않은 것이 가장 큰 손실이었음. 반론이 실릴 자리가 없었음","고발 대상이 아닌 한 곳이 \"사비로 썼다\"고 급하게 해명했다가 일반운영비였음이 드러나 정정·사과가 별도 뉴스가 됨","일주일 뒤 과거 4년치 유사 출장이 공개되며 1회성에서 관행으로 확대됨"],
steps:[["보도 당일","집행 근거 서류를 먼저 확인. 확인 전에는 성격 규정(\"사비\", \"규정대로\")을 말하지 않음"],["24시간 내","집행 항목과 근거 규정을 있는 그대로 공개. 잘못된 부분이 있으면 그 부분만 특정해 인정"],["3일 내","과거 동일 항목 집행 내역을 우리가 먼저 정리해 공개. 나중에 남이 찾아내면 은폐가 됨"],["2주 내","집행 기준 개선안 발표. 기준이 없었다면 없었다고 밝히고 언제까지 만들지 말함"]],
say:"해당 출장의 집행 항목과 근거는 ○○입니다. 이 중 ○○ 항목은 사전 승인 범위를 벗어난 것으로 확인했고, 해당 금액은 ○○ 조치할 예정입니다. 최근 ○년간 같은 성격의 집행 내역도 함께 공개합니다.",
prep:["출장·업무추진비 집행 기준을 문서화하고 홈페이지에 상시 게시","최근 3년 집행 내역을 언제든 낼 수 있게 정리","\"사비/공금\" 같은 성격 규정 용어는 회계 담당 확인 전에 쓰지 않기로 사내 규칙화"]},
{kind:"position",role:"lead",id:"A3",ax:"A",t:"유소년 관련 금품 요구 의혹이 제기됨",spd:"fast",spdL:"보도 10일 전",
what:"유소년 선수 측이 프로 콜업 대가로 금품을 요구받았다고 문제를 제기함. 구단은 언론 보도보다 열흘 먼저 홈페이지에 입장문을 올렸으나, 이후 프레임은 계속 악화돼 대표이사 사의까지 이어짐. 경찰 불송치 결정이 나온 뒤에도 탄원서와 이의신청이 이어졌음.",
split:["먼저 입장문을 낸 것은 맞았음. 그런데 그 입장문이 다음에 올 질문을 다루지 않았음","한 달 뒤 \"부적격 판단을 받은 인물이 왜 그 권한을 가졌나\"라는 인사 절차 문제가 새 쟁점이 됨","법적 무혐의가 여론 종결이 아니었음. 불송치 논리가 공개되자 오히려 반발이 커짐"],
steps:[["접수 즉시","당사자 직무 정지. 조사 착수 사실과 정지 조치를 함께 공개"],["1주 내","금전이 오가는 경로(발전기금·훈련보상비 등) 전부와 근거 규정을 공개"],["2주 내","해당 인물의 채용·권한 부여 경위를 먼저 설명. 문제가 있으면 그 부분을 인정"],["수사 결과 후","무혐의가 나와도 별도 입장이 필요함. \"법적 판단과 별개로 구단이 고칠 부분\"을 밝힘"]],
say:"제기된 내용에 대해 해당 인원의 직무를 정지하고 자체 조사를 시작했습니다. 유소년 관련 금전 항목은 ○○ 세 가지이며 각각의 근거와 산정 기준은 ○○에 공개합니다. 조사 결과는 ○일까지 알리겠습니다.",
prep:["유소년 관련 모든 금전 항목의 명칭·근거·산정 기준을 한 장으로 상시 게시","입금 계좌를 구단 공식 계좌로 일원화하고 그 사실을 공개","외부 인사 채용·권한 위임 절차를 문서화"]},
{kind:"position",role:"lead",id:"A4",ax:"A",t:"임금 지급이 어려워짐",spd:"fast",spdL:"사고 5일 전",
what:"한 구단이 임금 미지급을 닷새 전에 먼저 알렸음. 선제 공개였는데도 1년 뒤 의회 감사에서 더 아프게 다뤄졌음. 위험을 인지한 5월부터 공개한 10월까지 다섯 달 동안 선수 9명을 추가 영입했기 때문임.",
split:["\"몰랐다\"가 아니라 \"알고도 막지 못했다\"가 되면 선제 공개의 효과가 사라짐","선수 단체가 \"예고된 인재\", \"구조적 경영 실패\"로 규정하면서 재정난 프레임이 방만 경영 프레임으로 바뀜","이듬해 예산이 오히려 증액되자 \"세금으로 막고 또 늘렸다\"는 모순 프레임이 생김"],
steps:[["위험 인지 시점","내부 보고와 함께 지출 결정을 멈춤. 이 시점부터의 신규 지출은 전부 기록에 남음"],["지급 불능 확정 전","선수단·직원에게 먼저 설명. 외부보다 내부가 먼저임"],["공개 시","미지급 예상 시점, 지급 계획 시점, 재원 확보 방안을 함께. 셋 중 하나라도 비면 불안이 커짐"],["해소 후","해소 사실만 알리고 끝내지 않음. 왜 생겼는지와 구조 개선안을 같이 공개"]],
say:"○월 급여부터 지급이 어려울 것으로 확인됐습니다. 원인은 ○○이며, ○월 ○일까지 ○○ 재원으로 지급을 완료할 계획입니다. 선수단과 직원에게는 ○월 ○일 먼저 설명드렸습니다.",
prep:["분기별 현금흐름 점검 시점을 정해 두고 결과를 대표까지 보고","재정 위험 인지 시 신규 계약을 멈추는 내부 기준선","지자체·모기업 보고 라인을 평상시에 정리"]},
{kind:"position",role:"lead",id:"C1",ax:"C",t:"연고·존립 조건이 바뀜",spd:"fast",spdL:"당일 대응",
what:"연고협약 만료를 앞둔 한 구단의 운영 형태 전환이 무산됐음. 지자체가 오후에 기자회견으로 발표하자 구단이 같은 날 반박 입장문을 냄. 지자체는 판단 기준 네 가지와 여론조사 수치를 함께 냈고, 구단은 약속 파기와 절차 지연을 들었음.",
split:["같은 날 양쪽이 말했지만 순서가 남았음. 기준과 숫자를 먼저 놓은 쪽의 틀 위에서 뒤 발언이 반론으로 배치됨","구단이 지적한 \"기한 하루 전 결정\"은 절차 문제로는 타당했으나 이미 재정 프레임이 세워진 뒤라 부차적으로 다뤄짐","몇 달 전부터 쌓인 예산 논란이 여론조사 수치로 계량화돼 결정의 근거가 됐음"],
steps:[["논의 개시 시점","결정 일정과 판단 기준을 먼저 공개하고 그 일정대로 진행. 기한에 몰려 결정하면 절차가 쟁점이 됨"],["결정 전","우리 쪽 수치(운영비 구성, 자체수입 비중, 지역 파급효과)를 미리 정리해 공개"],["결정 당일","상대 발표가 예상되면 같은 날 낼 입장문을 미리 준비. 감정어보다 사실과 시점을 앞에"],["이후","팬·시민 대상 설명 자리를 따로 만듦. 언론 공방만으로는 지지 기반이 정리되지 않음"]],
say:"○○ 결정과 관련해 구단 입장을 말씀드립니다. 구단이 확인한 경과는 ○○이며, 그중 ○○ 부분은 사실과 다릅니다. 구단은 ○일까지 ○○ 방안을 마련해 다시 협의를 요청하겠습니다.",
prep:["협약·약속 사항을 문서로 남기고 구두 합의는 회의록으로 확인","운영비 구성과 자체수입 비중을 매년 같은 양식으로 공개","존립 관련 중대 결정의 예상 시점을 연간 일정표에 표시"]},
{kind:"position",role:"lead",id:"C2",ax:"C",t:"지원 예산 규모가 도마에 오름",spd:null,spdL:"상시 이슈",
what:"시·도민구단 지자체 지원 예산 총액이 연구기관 보고서로 발표된 뒤 아홉 달 동안 반복 확산됐음. 보고서 → 지역지 기획 → 대표팀 부진 계기 재점화 → 다른 사안과 결합 → 신규 창단 중단론까지 이어짐. 리그 차원의 공식 입장은 확인되지 않았음.",
split:["매년 같은 달에 같은 질문이 오는 항목인데 답이 매번 새로 만들어졌음","\"시민구단의 탈을 쓴 지자체구단\"처럼 명칭 자체를 다시 정의하는 보도가 나오면 이후 논의가 그 틀 위에서 진행됨","홍보효과 ○○억이라는 주장이 산출 근거 없이 나가면 그 자체가 다음 공격 대상이 됨"],
steps:[["상시","예산 규모는 숨길 수 있는 정보가 아님. 매년 확정 즉시 우리가 먼저 공개"],["보도 당일","총액을 부인하지 않음. 구성(인건비/운영비/유소년/지역사업)을 나눠 보여 주는 것이 유일한 대응"],["1주 내","자체수입 비중과 전년 대비 변화, 지역 환원 실적을 산출 근거와 함께"],["예산 심의기 전","의회 질의에 나올 질문 목록을 먼저 만들고 답변을 문서로 준비"]],
say:"○○년 지원 예산은 ○○억이며 구성은 인건비 ○%, 운영비 ○%, 유소년 ○%, 지역사업 ○%입니다. 자체수입 비중은 ○%로 전년 대비 ○%p 변동했습니다. 산출 근거는 ○○에 게시했습니다.",
prep:["예산 구성표를 매년 같은 양식으로 홈페이지에 상시 게시","홍보효과 수치를 쓸 거면 산출 방법과 기관을 함께 밝히고, 못 밝히면 쓰지 않기","매년 1~2월 집계 발표기와 11~12월 예산 심의기를 공개 캘린더에 고정"]},
{kind:"position",role:"lead",id:"C3",ax:"C",t:"재무 상태와 지원 기준이 함께 문제가 됨",spd:"slow",spdL:"문장 충돌",
what:"한 구단의 자본잠식 상태가 단독 보도로 알려지고, 몇 달 뒤 의회에서 매년 100억대 지원의 기준이 없다는 지적이 나왔음. 같은 시기에 구단은 \"책임 있는 재정 운영을 달성했다\"고 했고, 광역지자체는 \"의무 감사 대상이 아니다\"라고 답했음.",
split:["한 기사 안에 세 문장이 함께 놓임 — 자본잠식 수치, 구단의 성과 주장, 지자체의 관할 부인. 설명이 아니라 모순으로 읽혔음","\"조례에 금액이 정해져 있지 않다\"는 답변은 사실이지만 기준이 없다는 자백으로 기록됨","현직 간부가 SNS로 내부 문제를 제기하면서 재무 문제가 인사 거버넌스 문제로 확장됨"],
steps:[["지표 악화 인지","외부 보도 전에 이사회·지자체·리그에 먼저 보고하고 개선 계획을 문
서화"],["보도 당일","수치를 부인하지 않음. 기준 시점과 산정 방식이 다르면 그 차이만 설명"],["3일 내","개선 계획의 연차별 목표와 현재 이행률을 공개. 계획만 있고 이행률이 없으면 설득되지 않음"],["지원 기준 질의 시","\"기준이 없다\"로 끝내지 않음. 언제까지 무엇을 기준으로 삼겠다까지"]],
say:"○○년 말 기준 자본총계는 ○○이며 개선 계획상 ○○년까지 해소를 목표로 하고 있습니다. 현재 이행률은 ○○이며, 세부 지표는 ○○에 분기마다 갱신합니다.",
prep:["재무 개선 계획과 이행률을 분기마다 같은 자리에 갱신","구단 성과를 말할 때 재무 지표와 모순되지 않는 표현인지 먼저 확인","지자체·의회와의 답변이 어긋나지 않게 사전에 문구를 맞추는 절차"]},
{kind:"position",role:"lead",id:"C4",ax:"C",t:"상급 기관과 책임 소재를 두고 공방이 생김",spd:"slow",spdL:"10일 뒤 번복",
what:"선수 단체가 리그에 전 구단 회계감사를 요구하자 리그가 같은 날 \"각 구단은 별도 독립 법인\"이라고 반박했음. 법적으로는 정확한 답이었으나, 상대는 \"왜 선수가 피해를 받나\"라는 문장을 먼저 놓은 뒤였음. 열흘 뒤 리그가 지원팀을 파견하면서 초기 발언과 행동이 어긋난 것으로 기록됨.",
split:["감정이 실린 질문에 구조로 답하면 답이 아니라 회피로 읽힘","\"권한이 없다\"는 답변은 그다음 문장이 없으면 책임 회피로만 남음","열흘 뒤 조치를 할 거였다면 첫 문장에 그 조치를 담았어야 했음"],
steps:[["요구가 제기된 날","동일 채널·동일 속도로 답하되, 구조 설명보다 상대가 든 피해를 먼저 언급"],["같은 입장문 안에","권한 범위를 밝히고 그 범위 안에서 지금 하는 일을 구체적으로 함께 씀"],["1주 내","권한 밖 사안은 권한 있는 기관과의 협의 일정을 제시"],["이후","약속한 일정마다 진행 상황을 갱신. 조치가 나중에 나오면 초기 발언이 번복으로 기록됨"]],
say:"제기된 우려에 공감합니다. 규정상 ○○는 각 구단의 권한이지만, 구단과 함께 ○○ 점검을 ○일까지 진행하겠습니다. 권한 밖의 ○○ 사안은 ○○ 기관과 ○일에 협의할 예정입니다.",
prep:["우리 권한의 범위와 한계를 한 장으로 정리","\"권한이 없다\"만 쓰지 않고 항상 다음 문장을 붙이는 것을 내부 규칙으로","상급 기관·유관 단체와의 협의 창구를 평상시에 지정"]},
{kind:"position",role:"lead",id:"C5",ax:"C",t:"우리가 낸 자료가 상대 주장의 근거가 됨",spd:"slow",spdL:"두 달 뒤 역이용",
what:"리그가 연말에 구단별 연봉 현황을 공시했음. 당시 보도는 전부 최고 연봉 중심이었는데, 두 달 뒤 선수 단체가 같은 자료로 최저연봉이 4대 프로스포츠 최하위라는 의제를 세웠음. 아홉 달 뒤에는 국회 법안 제출로까지 이어졌음.",
split:["공시 자체는 투명성 조치였고 잘한 일이었음","문제는 그 자료로 어떤 기사가 가능한지 미리 검토하지 않았다는 점임","발표 주체가 자료의 해석권을 상대에게 넘긴 상태가 두 달 만에 굳어짐"],
steps:[["자료 공개 전","이 자료로 쓸 수 있는 기사 제목을 세 개 이상 미리 적어 봄. 불리한 제목이 보이면 그 항목의 설명을 자료에 함께 넣음"],["공개 당일","우리가 강조하고 싶은 지점을 자료 안에 문장으로 넣음. 표만 내면 해석은 남이 함"],["상대가 재해석했을 때","자료 자체를 부인하지 않음. 해석의 전제(기준 시점, 산정 방식)를 설명"],["다음 공개 전","지난번에 나온 질문을 자료 안에 미리 반영"]],
say:"공개한 자료의 ○○ 항목은 ○○ 기준으로 산정한 것입니다. 지적된 ○○ 부분에 대해서는 ○○ 논의를 ○일에 시작할 예정입니다.",
prep:["정기 공시·발표 자료마다 \"예상 질문 5개\" 문서를 함께 만드는 절차","공개 전 검토 담당을 작성자와 다른 사람으로 지정","지난해 같은 자료로 나온 기사를 모아 두기"]},
{kind:"position",role:"lead",id:"D1",ax:"D",t:"응원석에 상대 지역·인물 비하 표현이 걸림",spd:"slow",spdL:"징계일에 사과",
what:"홈 응원석에 상대 연고지와 전·현직 대표를 조롱하는 걸개가 걸렸음. 중계 화면 캡처가 이틀간 확산됐고, 상대 구단은 이틀 만에 입장문을 냈음. 홈 구단의 첫 공식 사과는 닷새 뒤, 리그 징계 발표와 같은 날 나왔음. 제재 사유는 개별 팬이 아니라 홈 구단의 질서 유지 책임 미이행이었음.",
split:["징계 발표와 같은 날 나온 사과는 자발적 사과로 읽히지 않음","사과문의 \"본래의 의도와는 별개로\", \"즉흥적으로 제작한 것\"은 책임 인정과 조직성 부인을 한 문장에서 같이 시도한 구조였음","이틀 사이에 지자체장·시의회·정당·시민단체가 차례로 발언하며 팬 갈등이 지역 정치 사안이 됨"],
steps:[["경기 중 인지","즉시 철거. 철거 사실과 시각을 기록. 촬영본 확보"],["경기 당일","홈 구단 명의로 1차 입장. 상대 구단·팬에 대한 사과와 철거 조치 사실만. 의도 설명은 넣지 않음"],["24시간 내","상대 구단에 직접 사과 전달. 언론 발표보다 먼저"],["3일 내","행위자 조치(출입 제한 등)와 재발 방지책 발표"],["다음 홈경기","장내 방송·전광판 등 같은 장소에서의 공개 사과 검토. 문제가 생긴 자리에서 정리하는 것이 효과가 큼"]],
say:"○월 ○일 경기 중 게시된 표현물에 대해 사과드립니다. 해당 걸개는 확인 즉시 철거했습니다. 경기장 질서 유지 책임은 홈 구단에 있으며, 해당 소모임에 대해 ○○ 조치했습니다. 재발 방지를 위해 ○○를 시행하겠습니다.",
prep:["응원 규범에 지역·인종·성별 비하 표현 금지를 명문화하고 위반 시 제재를 함께 규정","경기 전 걸개 사전 확인 절차와 현장 철거 권한을 누구에게 줄지 정해 두기","서포터스 대표와 연 1회 이상 규범 점검 자리"]},
{kind:"position",role:"lead",id:"D2",ax:"D",t:"관중이 선수단에 이물질을 던짐",spd:"fast",spdL:"발생 2일",
what:"경기 종료 후 회복 훈련 중이던 원정 선수단을 향해 일부 홈 관중이 욕설과 물병을 던졌음. 경기 감독관 보고가 아니라 영상 확산으로 알려졌음. 홈 구단 입장문은 이틀 뒤 나왔는데 첫 문장이 \"경위서 제출 요청을 받았다\"였음. 규정상 관중 안전·질서 문제는 사유를 불문하고 구단이 일체의 책임을 짐.",
split:["첫 문장이 절차 대응으로 시작해 사과가 뒤로 밀림","선수 단체가 \"명백한 폭력 행위\"로 규정하면서 팬 문화 논란이 안전 문제로 성격이 바뀜","같은 구단의 과거 유사 사례가 함께 실리며 반복 문제로 다뤄짐"],
steps:[["현장 인지","해당 구역 통제, 영상 확보, 원정 구단에 즉시 사과 전달"],["24시간 내","구단 명의 사과문. 첫 문장은 사과와 조치. 경위서 이야기는 넣지 않음"],["3일 내","행위자 확인 결과와 조치. 확인이 안 되면 확인 중임과 완료 시점을 밝힘"],["1주 내","서포터스와 합의한 규범 개정안 공개. 구단 단독 발표보다 공동 발표가 지속됨"]],
say:"○월 ○일 경기 후 발생한 행위에 대해 ○○ 구단 선수단과 팬 여러분께 사과드립니다. 해당 구역을 즉시 통제했고 행위자 확인을 진행 중입니다. 확인 결과와 조치는 ○일까지 알리겠습니다.",
prep:["반입 금지 물품과 투척 행위 제재를 규범에 명문화","응원석 구역별 카메라와 현장 대응 담당 배치","원정 구단 대응 창구를 사전에 지정"]},
{kind:"position",role:"lead",id:"D3",ax:"D",t:"선수 SNS 게시물이 차별 논란이 됨",spd:"slow",spdL:"구단 입장 없음",
what:"외국인 선수가 경기 후 올린 게시물이 인종차별 논란이 됐음. 선수 본인은 이틀 만에 의도가 없었다고 해명했고, 리그는 제재금을 부과하며 감경 사유 네 가지를 밝혔음. 전년도 유사 사례의 제재금이 10배였던 탓에 논점이 선수에서 리그 양정 기준으로 옮겨감. 구단 공식 입장은 확인되지 않았음.",
split:["리그는 이미 \"의도보다 외부에 표출된 의미가 기준\"이라고 밝혀 둔 상태였음. 그 기준 위에서 의도 해명은 힘을 갖지 못함","감경 사유를 네 개 나열하니 각각 타당해도 변명처럼 읽혔음","구단이 등장하지 않아 이번엔 구단 책임 프레임이 생기지 않았음. 다만 선수 SNS를 관리 범위로 선언해 두지 않으면 다음엔 구단 책임이 됨"],
steps:[["인지 즉시","게시물 삭제 요청과 함께 구단이 사실관계를 먼저 확인. 선수 단독 해명이 먼저 나가지 않게 함"],["24시간 내","구단 명의 입장. 사과와 조치 사실 위주. 의도 설명은 최소화"],["48시간 내","선수 본인 사과가 필요하면 구단이 문안을 함께 검토. 조건절(\"○○했다면\") 금지"],["1주 내","선수단 대상 교육 실시와 SNS 운영 기준 공개"]],
say:"소속 선수의 ○월 ○일 게시물로 불편을 드린 점 사과드립니다. 해당 게시물은 삭제했고, 선수단 전체를 대상으로 ○일에 관련 교육을 실시합니다. 구단은 차별적 표현에 대해 어떤 경우에도 용인하지 않는다는 입장입니다.",
prep:["선수단 SNS 운영 기준을 계약서 또는 내규에 명시","입단 시 차별 표현 교육을 절차에 포함","선수 개인 계정 모니터링 담당과 주기 정하기"]},
{kind:"position",role:"lead",id:"D4",ax:"D",t:"경기장 시설물이 떨어져 관중이 다침",spd:"slow",spdL:"설명 번복",
what:"경기 중 관중석 천장에서 석재가 떨어져 관중 1명이 손등을 다쳤음. 이틀 뒤 리그가 전 구단 긴급 점검 공문을 보내면서 \"인명 피해는 발생하지 않았다\"고 설명했는데, 나흘 뒤 부상자가 있었다는 사실이 확인됨. 구단 공식 발표는 닷새 뒤였고, 이후 경기 개최 불허와 홈경기 2경기 이전으로 이어졌음.",
split:["\"인명 피해 없음\"이라는 단정형 한 문장이 나흘 만에 뒤집히면서, 그 뒤의 강한 조치까지 신뢰를 나눠 갖지 못했음","시설 사고인데 구단보다 리그가 먼저 발표해 커뮤니케이션 주도권이 넘어갔음","시설 소유·관리 주체와 지자체의 공식 입장이 나오지 않아 책임 구조가 정리되지 않았음"],
steps:[["사고 즉시","해당 구역 폐쇄, 부상자 확인과 의료 조치, 시설 소유·관리 주체에 통보"],["2시간 내","1차 안내. 피해 여부는 \"확인 중\"으로. 없다고 말하지 않음"],["24시간 내","구단 명의 발표. 부상자 유무와 상태, 폐쇄 범위, 점검 일정. 리그보다 먼저"],["3일 내","안전점검 결과와 다음 홈경기 개최 여부. 개최가 어려우면 그 사실을 먼저 알림"],["이후","시설 소유 주체·지자체와의 책임·비용 분담을 정리해 공개"]],
say:"○월 ○일 경기 중 ○○ 구역에서 시설물 낙하가 발생했습니다. 현재까지 접수된 피해는 확인 중이며, 해당 구역은 즉시 폐쇄했습니다. 안전 점검을 ○일까지 완료하고 결과를 공개하겠습니다.",
prep:["경기장 시설 소유·관리 주체와의 책임 범위를 문서로 정리","시즌 중 점검 주기와 결과 공개 방식을 정하기","사고 발생 시 최초 2시간 안내문 양식을 미리 만들어 두기 — 피해 여부는 빈칸으로"]},
{kind:"procedure",role:"staff",id:"D5",ax:"D",t:"원정·중립 응원석 운영 기준이 바뀜",spd:null,spdL:"설명 수요",
what:"리그가 원정응원석을 한쪽 골대 뒤 전체로 배정하도록 하고 중립응원석을 도입했음. 경기장 인증제도 함께 의결됐는데, 이는 시설 사고 이전에 나온 정책임. 사고 대응책으로 설명하면 사실관계가 어긋남.",
split:["제도 변경은 위기가 아니지만 설명 수요가 생기는 항목임","시즌 중 좌석 배치가 바뀌면 시즌권 보유자와 서포터스 양쪽에서 문의가 옴","중립석의 응원도구·집단 응원 제한은 현장에서 마찰이 생기기 쉬운 항목임"],
steps:[["시행 전","바뀌는 내용과 이유를 우리 채널
에 먼저 게시. 리그 발표를 그대로 옮기지 말고 우리 경기장 기준으로 다시 씀"],["시즌권 판매 전","좌석 배치 변경을 구매 화면에서 고지. 나중에 알리면 환불 민원이 됨"],["시행 첫 경기","현장 안내 인력 배치. 제지 기준을 사전에 안내문으로 게시"],["분쟁 발생 시","현장에서 규정 문구를 보여 줄 수 있게 준비. 구두 설명만으로는 마찰이 커짐"]],
say:"○○년 ○월부터 원정 응원석은 ○○ 구역 전체로 운영됩니다. ○○ 구역은 중립 응원석으로, 대형 깃발·북 등을 이용한 집단 응원이 제한됩니다. 자세한 기준은 ○○에 게시했습니다.",
prep:["좌석 배치도와 구역별 규정을 한 장으로 상시 게시","시즌권 안내문에 제도 변경 고지란 만들기","현장 안내 인력용 응대 문구 카드 제작"]},
{kind:"position",role:"lead",id:"D6",ax:"D",t:"경기장 위생·시설 민원이 기사화됨",spd:"slow",spdL:"조치 미공개",
what:"한 경기장의 관중석 벌집과 좌석 누수, 다른 경기장의 상단 관중석 배설물 방치가 사회면에 함께 보도됐음. 두 기관 모두 답변은 했으나 별도 공개 없이 취재 문의에 답한 형태였음. 두 달 뒤 시설물 낙하 사고 기사에 같은 내용이 다시 실렸음.",
split:["한 번 지적된 항목은 조치 결과를 스스로 공개해 두지 않으면 다음 사고의 배경 문단으로 재등장함","입장료를 내는 관중이라는 점이 함께 언급되면 안전 문제가 아니라 소비자 문제로 확장됨","시설 관리 주체와 구단 사이에서 답변이 오가면 책임 분산 구조가 그대로 노출됨"],
steps:[["민원 접수","접수 대장에 기록. 같은 민원이 반복되는지 확인"],["3일 내","조치 완료 여부를 민원인에게 회신. 회신 자체가 다음 기사를 막음"],["취재 문의 시","\"전달했다\"로 끝내지 않음. 우리가 언제까지 무엇을 하는지 말함"],["조치 후","조치 완료 사실을 우리 채널에 게시. 사진 한 장이면 충분함"]],
say:"지적해 주신 ○○는 ○월 ○일 조치를 완료했습니다. 같은 문제가 반복되지 않도록 ○○ 주기로 점검하고 있으며, 점검 결과는 ○○에 게시합니다.",
prep:["관중 민원 접수 창구와 처리 기한을 정하기","반복 민원 항목 목록을 만들어 정기 점검표에 넣기","조치 완료 게시를 습관화 — 한 줄과 사진 한 장"]},
{kind:"position",role:"lead",id:"E1",ax:"E",t:"선수가 음주운전으로 적발됨",spd:"fast",spdL:"인지 1일",
what:"한 구단 선수가 면허취소 수준 음주운전으로 적발됨. 구단은 인지 당일 선수단 관리위원회를 열어 활동에서 배제하고 리그에 보고했으며, 다음 날 스스로 공개했음. 언론 보도가 구단 발표를 뒤따른 유일한 사례였음.",
split:["먼저 알린 덕분에 \"구단이 감췄나\"라는 질문 자체가 생기지 않았음","입장문에 인지 시각·조치·보고 사실이 한 문단에 들어가 있었음. 세 칸 구조가 그대로 문장이 된 형태임","다만 확정된 출장정지 경기 수는 양정 구간의 하한선이었음. 과거 사례도 같았음. 보도의 \"중징계\" 표현과 실제 구간은 구분해 설명해야 함"],
steps:[["인지 즉시","훈련·선수단 활동 배제. 리그 보고. 이 두 가지를 먼저 하고 발표함"],["24시간 내","구단 명의 공개. 인지 시각, 배제 조치, 리그 보고 사실을 첫 문단에"],["상벌위 전","구단 자체 조치 방침을 정해 둠. 리그 징계와 별개로 구단이 무엇을 할지"],["징계 후","징계 수용 여부와 구단 자체 조치를 함께 발표. 계약 관련 결정은 근거를 함께"],["이후","계약 해지로 끝내지 않음. 해지가 새 팀을 찾는 통로로 쓰인다는 지적이 있음. 사후 관리 방침까지"]],
say:"소속 선수 ○○이 ○월 ○일 음주운전으로 적발된 사실을 확인했습니다. 구단은 당일 인지 즉시 훈련 및 선수단 활동에서 배제하고 한국프로축구연맹에 보고했습니다. 확인된 사실과 조사 결과를 바탕으로 규정에 따라 후속 조치하겠습니다.",
prep:["선수 비위 발생 시 24시간 내 처리 절차를 문서로 — 누가 보고받고 누가 발표하는지","주요 비위의 구단 자체 징계 기준을 미리 정해 공개","입장문 양식 미리 만들기 — 위 문장이 그 양식임"]},
{kind:"position",role:"lead",id:"E2",ax:"E",t:"감독·선수가 공식 의무를 이행하지 않음",spd:"slow",spdL:"8일 공백",
what:"한 감독이 경기 후 공식 기자회견에 불참했음. 현장에서 구단 관계자가 \"벌금을 감수하신다\"고 전했고, 불참 이유는 \"아마 경기력 때문이지 않을까\"라는 추측으로 남았음. 본인 사과는 8일 뒤에 나왔고 그때도 이유는 설명되지 않았음. 그 사이 사퇴설이 2차 이슈로 번졌음.",
split:["첫날 현장에서 나간 한 문장이 사안의 성격을 정했음. 의무를 돈으로 대신한다는 인상이 8일간 유지됨","담당자가 추측으로 이유를 말한 것이 기사에 그대로 실림. 모르면 모른다고 하는 편이 나았음","본인 사과가 나왔을 때는 이미 사안이 다른 데로 옮겨간 뒤였음"],
steps:[["현장 즉시","불참 사실만 전달. 이유를 추측해서 말하지 않음. \"확인해서 알리겠다\"로 끊음"],["당일 내","구단 명의로 불참 사실과 사과. 규정 위반임을 인정"],["48시간 내","본인 입장이 필요하면 이 안에 나오게 함. 늦어질수록 다른 추측이 채움"],["이후","재발 방지를 위한 내부 절차 정리. 감독 의무 사항을 계약·내규에 명시"]],
say:"○월 ○일 경기 후 공식 기자회견에 참석하지 못한 점에 대해 사과드립니다. 규정상 참석 의무가 있는 자리였으며, 구단은 이를 무겁게 받아들입니다. 경위는 확인해 ○일까지 말씀드리겠습니다.",
prep:["감독·선수의 미디어 의무 사항을 계약서나 내규에 명시","현장 담당자가 쓸 수 있는 말과 쓰면 안 되는 말을 카드로 만들어 배포","\"모른다\"를 말해도 되는 상황을 사전에 정하기"]},
{kind:"position",role:"lead",id:"E3",ax:"E",t:"경기 중 난폭행위로 사후징계를 받음",spd:null,spdL:"구단 입장 불필요",
what:"한 선수의 태클이 정당한 경합 범위를 벗어난 행위로 판단돼 사후징계를 받았음. 발생 이틀 만에 상벌위가 열렸고 사흘 만에 공지됐음. 구단·선수의 입장은 나오지 않았고, 보도 앵글도 징계 적정성이 아니라 전력 공백에 집중됐음.",
split:["경기 중 반칙은 개인 일탈이 아니라 경기 규정 위반임. 리그가 단독으로 처리하는 구조임","구단이 사과문을 낼 사안이 아님. 이 구분이 흐려지면 안 내도 될 사과를 하게 됨","다만 상대 선수가 다쳤다면 성격이 달라짐. 그때는 선수 대 선수, 구단 대 구단의 직접 연락이 먼저임"],
steps:[["징계 통보 시","수용 여부를 정함. 이의가 있으면 절차로 제기하고 언론을 통해 다투지 않음"],["상대 부상 시","상대 구단·선수에게 직접 연락. 공개 발표보다 먼저"],["대외 문의 시","징계 사실과 수용 여부만 답함. 판정의 옳고 그름은 논평하지 않음"],["반복 시","같은 선수에게 반복되면 구단 차원의 관리 문제가 됨. 그때는 구단이 입장을 내야 함"]],
say:"○월 ○일 경기 관련 사후징계를 통보받았습니다. 구단은 결정을 수용하며, 선수단 관리에 더 주의하겠습니다.",
prep:["징계 유형별로 구단이 입장을 내는 건과 내지 않는 건을 미리 구분","상대 선수 부상 시 연락 절차와 담당 지정"]},
{kind:"position",role:"exec",id:"E4",ax:"E",t:"지도자·임직원의 폭행 사실이 뒤늦게 드러남",spd:"slow",spdL:"통제권 상실",
what:"한 지도자가 부임 직후 선수를 폭행한 사실이 약 넉 달 뒤 영상으로 공개됐음. 구단은 그 전에 이미 인지하고 내부 조치를 했으나 공개하지 않았고, 계약 해지 사유도 성적 부진으로 처리했음. 시즌이 끝나자 피해 선수가 직접 말했고, 증거가 된 영상은 구단이 제작한 다큐멘터리 촬영분이었음. 징계 결과마저 나중에 제3자가 먼저 알렸음.",
split:["통제권이 네 번에 걸쳐 넘어갔음 — 내부 처리로 종결 → 피해자가 직접 발화 → 자사 제작 영상이 증거로 역작용 → 징계 결과를 남이 공개","본인 발언이 \"기분 나빴다면 미안하다\", \"그런 일이 있었다면\"으로 조건절에 들어가 부인으로 기록됨","구단 첫 입장이 \"인지하고 조치를 취해 왔다\"였음. 인지 사실을 스스로 인정하면서 왜 공개하지 않았는지가 새 질문이 됨"],
steps:[["인지 즉시","피해자 보호가 먼저. 분리 조치와 의사 확인. 원하지 않는 공개는 하지 않되 그 사실을 기록으로 남김"],["조치와 동시에","상급 기관에 보고. 내부 종결로 끝내지 않음. 이 단계를 건너뛰면 나중에 은폐가 됨"],["계약 종료 시","사유를 실제와 다르게 정리하지 않음. 나중에 드러나면 그 자체가 두 번째 사안이 됨"],["공개 국면","24시간 내 입장. 인지 시점, 당시 조치, 공개하지 않은 이유를 함께. 이유가 피해자 의사였다면 그렇게 밝힘"],["이후","징계 결과는 우리가 먼저 알림. 남이 먼저 말하면 그때까지의 설명이 전부 의심받음"]],
say:"○월 ○일 해당 사안을 인지하고 ○○ 조치했습니다. 피해 선수 보호를 위해 공개하지 않았으며, ○월 ○일 상급 기관에 보고했습니다. 결과적으로 충분히 알리지 못한 점에 대해 사과드립니다.",
prep:["폭행·괴롭힘 신고 창구와 처리 절차를 공개","내부 조치도 반드시 상급 기관 보고를 거치도록 절차화","구단이 제작·보관하는 영상·기록의 관리 기준 정하기 — 우리가 만든 기록은 언젠가 우리 손을 떠남","계약 종료 사유를 실제와 맞게 기록하는 원칙"]}
];
const FOUR=[
["1 인정","사실과 수치를 먼저 확인함","\"맞습니다. 78%입니다\""],
["2 조치","이미 한 것과 기한이 있는 것","\"이달 안에 외부감사 결과를 공개합니다\""],
["3 근거","검증 가능한 숫자 한두 개만","\"유소년 등록 320명, 이적료 수익 19억\""],
["4 약속","측정 가능한 목표와 시점","\"2028년 자체수익 30%\""]
];
const BANNED=["관행이다","다른 구단도 같다","규정 위반은 아니다","개인 일탈이다","구조상 불가피하다","확인해 보겠다(기한 없음)","노코멘트","홍보효과 총액만 단독 제시"];
const QA=[
{k:"g1",t:"세금 의존·자립 부재",items:[
{role:"lead",q:"지원금이 총수익의 78%인데 자체수익을 몇 %까지, 언제까지 올릴 계획인가",l:"수치 인정 → 목표치와 연도 → 첫해 실행 항목",
s:"맞습니다. 2024년 기준 [78%]입니다. 2028년까지 [30%]로 낮추는 것이 목표이고, 올해는 [LED 광고보드·시즌권 확대]로 자체수익 [○억]을 먼저 만들겠습니다. 매년 결산 때 달성률을 공개하겠습니다."},
{role:"lead",q:"3년간 자체수익률이 개선됐나, 안 됐다면 예산은 왜 늘었나",l:"추이 공개 — 악화됐으면 악화됐다고 → 증액 사유를 항목으로 분리",
s:"[2022년 15% → 2024년 12%]로 오히려 낮아졌습니다. 예산 증가분 [○억]은 [승격에 따른 로스터 규정 충족·유소년 확대]에 쓰였고 항목별 내역은 홈페이지에 올려두었습니다."},
{role:"lead",q:"시민 1인당 세금이 얼마 들어가는지 계산해 봤나",l:"계산 회피 금지 → 숫자 제시 → 그 돈으로 제공한 공공서비스",
s:"시민 1인당 연 [약 ○천 원]입니다. 그 비용으로 [유소년 ○명 무상 교육, 시민 참여 행사 ○회, 홈경기 ○만 명 관람]을 제공했습니다. 충분한지는 시민이 판단하실 문제이고, 저희는 매년 이 숫자를 함께 공개하겠습니다."},
{role:"lead",q:"어떤 구단은 광고·티켓 비중이 10%를 넘는데 왜 안 되나",l:"비교 수용 → 격차 원인 하나 → 벤치마킹 조치",
s:"다른 구단 사정은 제가 답할 위치가 아닙니다. 저희 숫자만 말씀드리면 광고·티켓 비중은 [○%]
이고, 올해 [○○]로 [○억]을 늘리는 것이 목표입니다."}
]},
{k:"g2",t:"회계 통제·도덕적 해이",items:[
{role:"exec",q:"몇 년간 수십억이 빠져나가는데 아무도 몰랐다는 게 말이 되나",l:"변명 금지 → 통제 실패 인정 → 무엇이 무너졌는지 구체적으로 → 외부 검증",
s:"말이 안 됩니다. 출납·결재·통장 관리가 한 사람에게 집중됐고 감사는 통장 사본 확인에 그쳤습니다. 내부 통제 실패입니다. 외부 회계법인 감사와 수사에 모든 자료를 제공하고 있고, 결과는 그대로 공개하겠습니다."},
{role:"exec",q:"대표·단장이 몰랐다면 무엇을 결재한 것인가, 알았다면 언제 알았나",l:"시점 특정 → 관리 책임 인정 → 거취는 조사 결과와 연동",
s:"[7월 ○일] 회계 점검에서 처음 확인했고 당일 경찰에 신고했습니다. 몰랐다는 것이 면책이 되지 않습니다. 관리 책임은 제게 있고, 조사 결과에 따라 거취를 포함해 책임지겠습니다."},
{role:"lead",q:"직원 개인 범행이라면서 왜 선수단을 정리하나",l:"선수단 정리를 환수 대책으로 말하지 않음 → 환수와 운영 긴축을 분리",
s:"환수는 피의자 재산에 대한 법적 절차로 진행합니다. 선수단 조정은 환수 대책이 아니라 올해 운영 자금 부족에 대한 긴축이고, 핵심 선수와 유소년 예산은 대상이 아닙니다."},
{role:"exec",q:"여비규정상 비즈니스석 대상인가, 아니라면 가산 징수 조항을 본인에게 적용할 것인가",l:"규정 조문으로 답함 → 대상이 아니면 즉시 반납 → 규정 개정",
s:"규정상 제 직위는 비즈니스석 대상이 아닙니다. 차액 [○만 원]을 반납했고 규정 [제○조]에 따른 가산 징수도 감사 결과대로 따르겠습니다. 국외 출장은 전원 이코노미로 규정을 바꿨습니다."},
{role:"lead",q:"공문에 없던 일정이 포함된 것을 알고 참가했나, 복명서를 공개할 수 있나",l:"인지 시점 사실대로 → 판단 오류 인정 → 복명서 공개",
s:"현지 도착 후 일정을 알았습니다. 그때 빠졌어야 했습니다. 복명서와 지출 내역은 정보공개 청구와 무관하게 이번 주 홈페이지에 올리겠습니다."},
{role:"exec",q:"같은 출장에서 이코노미석을 택한 구단도 있었는데 왜 못 했나",l:"비교 반박 금지 → 판단 기준이 틀렸음을 인정",
s:"다른 구단 판단을 평가할 위치가 아닙니다. 저희 기준이 잘못됐다는 지적은 받아들입니다. 기준을 [○○]로 바꿨습니다."}
]},
{k:"g3",t:"예산 대비 성과 부진",items:[
{role:"lead",q:"예산이 82% 늘었는데 순위는 왜 최하위인가, 돈은 어디로 갔나",l:"증액 사용처를 항목으로 공개 → 성적 책임 인정 → 성적 외 합의 지표",
s:"증액분 [○억]은 [선수단 ○억·유소년 ○억·시설 ○억]입니다. 성적은 변명할 여지가 없습니다. 다만 시와 합의한 올해 지표는 [관중·시즌권·유소년] 세 가지도 포함되어 있고, 그 결과도 함께 평가받겠습니다."},
{role:"lead",q:"입장수입 목표액의 산출 근거가 무엇인가, 작년 실적은 얼마인가",l:"실적 먼저 → 근거 없으면 없다고 → 재산정",
s:"작년 실적은 [○억]입니다. [18억]은 근거가 부족한 숫자였습니다. [평균 관중 × 객단가 × 홈경기 수] 기준으로 [○억]으로 다시 잡아 의회에 제출하겠습니다."},
{role:"lead",q:"홈 관중 8,000명 중 원정팬이 6,000명이면 시민구단인가",l:"사실 인정 → 홈팬 지표(시즌권·팬클럽)로 대답 → 목표",
s:"그 경기는 그랬습니다. 홈팬을 늘리는 것이 핵심 과제이고 시즌권 [○장], 유료 회원 [○명]을 올해 [○%] 늘리는 것이 목표입니다."},
{role:"exec",q:"강등되면 지원 조례상 근거가 남는가",l:"조례 목적 조항으로 답함 → 강등 시나리오 준비 여부",
s:"조례의 목적은 [시민 체육 진흥]이고 리그 등급을 조건으로 하지 않습니다. 다만 강등 시 지원 규모 재검토는 당연하다고 보며, 그 경우 운영 계획도 이미 시에 제출했습니다."}
]},
{k:"g4",t:"추경 의존",items:[
{role:"lead",q:"부족할 줄 알면서 추경을 전제로 계획을 세운 것 아닌가",l:"과거 관행 인정 → 원칙 전환 선언",
s:"과거에는 그런 면이 있었습니다. 올해부터 본예산 안에서 운영하는 것을 원칙으로 하고, 추경은 [승격·재난 등] 예외 사유를 사전에 정해 두었습니다."},
{role:"lead",q:"추경 요청액의 용도를 항목별로 밝힐 수 있나",l:"즉시 항목 제시 → 성과지표 첨부",
s:"[선수단 ○억·시설 ○억·유소년 ○억]입니다. 요청서에 직전 시즌 성과지표를 첨부했고 의회 제출 자료를 그대로 공개하겠습니다."},
{role:"lead",q:"성적 나쁘면 예산 줄고, 줄면 성적 더 나빠지는 구조인데 출구가 있나",l:"구조 인정 → 성적과 무관한 수익원 → 다년 예산 협의",
s:"그 악순환이 시민구단의 가장 큰 문제입니다. 출구는 성적과 무관한 수익원[시즌권·후원 회원제·시설 활용]과 시와의 3년 단위 예산 협의입니다. 올해 [○○]부터 시작했습니다."},
{role:"exec",q:"의원이 이해도가 떨어진다고 한 발언에 동의하나",l:"의회 비판 금지 → 설명 책임을 구단 쪽으로",
s:"동의하지 않습니다. 의회가 이해하지 못했다면 구단이 설명을 못 한 것입니다. 시즌 전 의원 대상 설명회를 정례화하겠습니다."}
]},
{k:"g5",t:"창단 남발·세금 리그 프레임",items:[
{role:"lead",q:"창단 전 주민 의견수렴 절차가 있었나, 반대 의견은 어떻게 처리했나",l:"절차 기록으로 답함 → 반대 의견 수용 내용",
s:"[○년 ○월 공청회·설문 ○명·의회 동의]를 거쳤습니다. 반대 의견 중 [예산 상한]은 조례에 반영했고, 회의록은 시 홈페이지에 있습니다."},
{role:"lead",q:"리그 전체에 1,500억이면 유소년 몇 명을 키울 수 있나",l:"리그 총액 방어 금지 → 자기 구단 유소년 실적으로",
s:"리그 전체 숫자는 제가 답할 위치가 아닙니다. 저희 구단은 지원금 중 [○%, ○억]을 유소년에 쓰고 [○명]을 무상으로 가르치고 있습니다."},
{role:"exec",q:"민영화나 매각을 검토한 적 있나",l:"회피 금지 → 지분 분산 방향으로",
s:"매각은 검토한 적 없습니다. 다만 시 100% 구조를 [시민 후원 회원·기업 지분]으로 나누는 방안은 검토 중이고, [협동조합형을 도입한 구단 사례]를 참고하고 있습니다."}
]},
{k:"g6",t:"정치화·지자체장 종속",items:[
{role:"exec",q:"단장 선임 기준이 무엇인가, 공모 절차가 있었나, 시장과의 관계는",l:"절차 사실대로 → 부족하면 개선 약속 → 관계는 부인이 아니라 설명",
s:"[공모 ○명 지원, 임원추천위원회 심사]를 거쳤습니다. 시장과는 [○○] 관계가 맞고 숨길 이유가 없습니다. 다음 선임부터는 외부 위원 과반과 의회 인사청문을 도입하겠습니다."},
{role:"lead",q:"선수 영입에 단장이 개입한 근거 규정이 있나",l:"규정 확인 → 없으면 없다고 → 권한 분리",
s:"규정상 선수 구성은 강화위원회 소관이고 단장 결정 권한은 없습니다. 개입이 있었다면 잘못이고, 위원회 의결 없이는 계약하지 못하도록 절차를 문서화했습니다."},
{role:"exec",q:"유니폼 색 변경을 누가 결정했나, 특정 정당과 무관하다고 말할 수 있나",l:"결정 주체 명시 → 오해 소지 인정 → 원칙 제정",
s:"구단 마케팅팀 결정이었습니다. 선거 직전 시점에 그 색을 쓴 것은 오해를 살 만했고, 선거 60일 전에는 유니폼·행사 색상을 바꾸지 않는 내부 원칙을 만들었습니다."},
{role:"lead",q:"시장이 바뀌면 대표도 바뀌는데 중장기 계획이 의미 있나",l:"구조 인정 → 계획을 사람이 아니라 문서·조례에 고정",
s:"그래서 3개년 계획을 이사회 의결과 시 협약으로 문서화했습니다. 대표가 바뀌어도 계획과 지표는 남습니다."}
]},
{k:"g7",t:"집행 불투명·정보공개 회피",items:[
{role:"lead",q:"추경 예산을 어디에 썼나, 왜 세부 내역을 안 내놓나",l:"항목 즉시 제시 → 총액 교부 구조는 설명하되 방패로 쓰지 않음",
s:"[선수단 ○억·시설 ○억·운영 ○억]입니다. 시에는 총액으로 교부되지만 세부 집행 책임은 구단에 있고, 분기별로 홈페이지에 공개하겠습니다."},
{role:"lead",q:"결산서·이적료·입장수입을 공개하지 못하는 이유는",l:"공개 못 할 이유 없음 → 즉시 공개 → 정례화",
s:"공개 못 할 이유가 없습니다. [○월 ○일] 결산 요약을 올리고 매년 같은 형식으로 공개하겠습니다."},
{role:"exec",q:"정보공개 청구에 구단 자체 회계라고 답한 것이 시민 세금이 아니라는 뜻인가",l:"답변이 잘못됐음을 인정 → 재회신",
s:"그 답변은 잘못됐습니다. 시민 세금이 맞고, 청구하신 내역을 다시 회신하겠습니다."}
]},
{k:"g8",t:"홍보효과 과장",items:[
{role:"lead",q:"홍보효과 700억의 산정 기관과 방식은, 광고환산가치라면 어떤 매체 기준인가",l:"산정 기준 공개 → 한계 인정 → 보조 지표로 격하",
s:"[○○기관]의 광고환산가치 방식이고 [TV·온라인 노출 ○건] 기준입니다. 이 방식은 실제 수익과 다르다는 한계가 있어 참고 지표로만 보고, 핵심 지표는 [관중·시즌권·지역 상권 조사]로 바꾸겠습니다."},
{role:"lead",q:"홍보효과가 투입 대비 5배면 예산을 줄여도 되는 것 아닌가",l:"논리 모순 인정 → 홍보효과와 운영비를 구분",
s:"그렇게 읽힐 수 있는 발표였습니다. 홍보효과는 지역이 얻는 노출 가치이고 운영비를 대체하는 수입이 아닙니다. 앞으로 두 숫자를 나란히 두지 않겠습니다."}
]},
{k:"g9",t:"유소년·지역체육 우선순위",items:[
{role:"lead",q:"전체 예산 중 유소년 비중이 몇 %인가, 비즈니스석 차액이면 유소년 몇 명인가",l:"비율 즉답 → 비교 수용 → 전환 조치",
s:"[○%, ○억]입니다. 차액 [600만 원]이면 [유소년 ○명 1년 용품비]입니다. 반납한 차액은 유소년 예산으로 전환했습니다."},
{role:"lead",q:"유소년 출신 1군 선수와 이적료 수익은",l:"숫자 즉답 → 없으면 없다고 → 육성 목표",
s:"1군 [○명], 최근 3년 이적료 [○억]입니다. 부족합니다. [U-18에서 1군으로 연 ○명 콜업]을 목표로 잡았습니다."},
{role:"lead",q:"유소년 예산을 지원금과 분리해 공개할 수 있나",l:"분리 공개 약속 → 최소 비율 자체 설정",
s:"분리해 공개하겠습니다. 지원금 대비 유소년 최소 비율 [○%]도 구단 규정으로 정하겠습니다."}
]}
];
const QCASE={
A1:[
{q:"몇 년간 수십억이 빠져나가는데 아무도 몰랐다는 게 말이 되나",l:"변명 금지 → 통제 실패 인정 → 무엇이 무너졌는지 구체적으로 → 외부 검증",s:"말이 안 됩니다. 출납·결재·통장 관리가 한 사람에게 집중됐고 감사는 통장 사본 확인에 그쳤습니다. 내부 통제 실패입니다. 외부 회계법인 감사와 수사에 모든 자료를 제공하고 있고, 결과는 그대로 공개하겠습니다."},
{q:"대표가 몰랐다면 무엇을 결재한 것인가, 알았다면 언제 알았나",l:"시점 특정 → 관리 책임 인정 → 거취는 조사 결과와 연동",s:"[○월 ○일] 회계 점검에서 처음 확인했고 당일 경찰에 신고했습니다. 몰랐다는 것이 면책이 되지 않습니다. 관리 책임은 제게 있고, 조사 결과에 따라 거취를 포함해 책임지겠습니다."},
{q:"처음 발표한 금액과 지금 금액이 다른데 더 나올 수 있나",l:"변동 가능성 먼저 인정 → 확정 시점 제시 → 산출 근거 동시 공개 약속",s:"현재까지 확인된 금액은 [○○]이고 조사가 진행 중이어서 늘어날 수 있습니다. 확정 시점은 [감사 종료 ○월 ○일]이며 그때 산출
근거와 함께 공개하겠습니다. 중간 수치는 확인된 범위임을 밝히고 말씀드리겠습니다."},
{q:"직원 개인 범행이라면서 왜 선수단을 정리하나",l:"선수단 정리를 환수 대책으로 말하지 않음 → 환수와 운영 긴축을 분리",s:"환수는 피의자 재산에 대한 법적 절차로 진행합니다. 선수단 조정은 환수 대책이 아니라 올해 운영 자금 부족에 대한 긴축이고, 핵심 선수와 유소년 예산은 대상이 아닙니다."}
],
A2:[
{q:"여비규정상 비즈니스석 대상인가, 아니라면 가산 징수를 본인에게 적용할 것인가",l:"규정 조문으로 답함 → 대상이 아니면 즉시 반납 → 규정 개정",s:"규정상 제 직위는 비즈니스석 대상이 아닙니다. 차액 [○만 원]을 반납했고 규정 [제○조]에 따른 가산 징수도 감사 결과대로 따르겠습니다. 국외 출장은 전원 이코노미로 규정을 바꿨습니다."},
{q:"공문에 없던 일정이 포함된 것을 알고 참가했나, 복명서를 공개할 수 있나",l:"인지 시점 사실대로 → 판단 오류 인정 → 복명서 선공개",s:"현지 도착 후 일정을 알았습니다. 그때 빠졌어야 했습니다. 복명서와 지출 내역은 정보공개 청구와 무관하게 이번 주 홈페이지에 올리겠습니다."},
{q:"이번만인가, 과거에도 같은 방식이었나",l:"과거 내역을 우리가 먼저 공개 → 이번 건만 따로 설명하지 않음",s:"최근 [○년]간 같은 성격의 출장은 [○회]이고 내역을 이번 주에 함께 공개하겠습니다. 이번 건만 떼어 설명하지 않겠습니다."},
{q:"같은 출장에서 이코노미석을 택한 구단도 있었는데 왜 못 했나",l:"비교 반박 금지 → 판단 기준이 틀렸음을 인정",s:"그 구단들이 맞았습니다. 시민 눈높이보다 관행을 기준으로 판단한 것이 잘못입니다."}
],
A3:[
{q:"프로 계약과 돈이 연결될 수 있는 구조인가, 결정 권한은 누구에게 있나",l:"권한 구조를 문서로 답함 → 경계가 흐려진 부분 인정 → 분리 조치",s:"선수 등록은 [강화위원회] 의결 사항이고 금전 항목과 분리돼 있습니다. 이번 건에서 그 경계가 흐려진 부분이 있어 해당 인원의 직무를 정지했고, 금전 창구를 구단 공식 계좌로 일원화했습니다."},
{q:"수사에서 무혐의로 결론 났는데 구단은 잘못이 없다는 뜻인가",l:"법적 판단과 구단 책임을 분리 → 고칠 부분을 구체적으로",s:"법적 판단은 그렇게 나왔습니다. 그것과 별개로 구단이 고칠 부분은 있습니다. [채용 절차와 금전 창구] 두 가지를 [○일]까지 바꾸고 결과를 공개하겠습니다."},
{q:"유소년 관련 금전 항목을 전부 공개할 수 있나",l:"항목 전부 공개 → 산정 기준 동시 제시 → 정례화",s:"공개하겠습니다. 유소년 관련 금전 항목은 [○가지]이고 각각의 근거 규정과 산정 기준을 함께 올리겠습니다. 이후에는 매년 같은 형식으로 공개합니다."}
],
A4:[
{q:"언제부터 부족할 줄 알았나",l:"인지 시점 특정 → 그 뒤의 지출 결정을 스스로 설명",s:"[○월]에 처음 확인했습니다. 그 뒤 [선수 영입 ○건]을 진행한 것은 잘못된 판단이었습니다. 재정 위험을 확인하면 신규 계약을 멈추는 기준을 내규로 정했습니다."},
{q:"결국 시 예산으로 메우는 것 아닌가",l:"사실 인정 → 반복 방지 구조를 숫자와 시점으로",s:"이번 부족분 [○억]은 시에서 투입됩니다. 같은 일이 반복되지 않도록 [분기 현금흐름 공개]와 [신규 계약 중단 기준]을 내규로 정했고, 첫 공개는 [○월]입니다."},
{q:"선수단 규모를 감당할 수 없는 수준으로 키운 이유는",l:"규모 수치 제시 → 판단 근거와 오류 → 조정 계획",s:"등록 [○명]으로 리그 [상위 ○위] 규모였습니다. [승격 목표]를 이유로 늘렸고 재정 확인이 뒤따르지 못했습니다. 다음 시즌 [○명] 수준으로 조정하고 인건비 비중을 [○%]로 낮추겠습니다."}
],
C1:[
{q:"약속이 있었다고 하는데 문서로 남아 있나",l:"문서 여부를 사실대로 → 없으면 없다고 → 그 점이 원인임을 인정",s:"[협약서 제○조]에 있습니다. (또는) 문서에는 없고 구두 협의였습니다. 중요한 합의를 문서로 남기지 않은 것이 이번 문제의 출발점입니다. 앞으로 협의 결과는 회의록으로 확인받겠습니다."},
{q:"왜 기한 직전에 결정됐나",l:"일정 공개 → 절차 문제 인정 → 다음 절차 개선",s:"[○월 ○일]에 검토를 시작해 [○일]에 결론이 났습니다. 참가 신청 기한을 [하루] 앞둔 시점이었고, 이 일정은 저희가 잘못 잡은 것입니다. 앞으로 존립 관련 결정은 [○개월 전] 일정표를 먼저 공개하겠습니다."},
{q:"존치하면 시민 부담은 얼마나 늘어나나",l:"금액 회피 금지 → 1인당 환산 → 그 돈으로 제공하는 것",s:"연 [○억]에서 [○억]으로 늘어나고 시민 1인당 [약 ○천 원] 수준입니다. 그 비용으로 [유소년 ○명, 홈경기 ○만 명 관람, 지역 행사 ○회]를 제공합니다. 판단은 시민이 하실 몫이고 저희는 이 숫자를 매년 함께 공개하겠습니다."}
],
C2:[
{q:"지원금이 총수익의 대부분인데 자체수익을 몇 %까지, 언제까지 올릴 계획인가",l:"수치 인정 → 목표치와 연도 → 첫해 실행 항목",s:"맞습니다. [○년] 기준 [○%]입니다. [○년]까지 [○%]로 낮추는 것이 목표이고, 올해는 [○○]로 자체수익 [○억]을 먼저 만들겠습니다. 매년 결산 때 달성률을 공개하겠습니다."},
{q:"시민 1인당 세금이 얼마 들어가는지 계산해 봤나",l:"계산 회피 금지 → 숫자 제시 → 제공한 공공서비스",s:"시민 1인당 연 [약 ○천 원]입니다. 그 비용으로 [유소년 ○명 무상 교육, 시민 참여 행사 ○회, 홈경기 ○만 명 관람]을 제공했습니다. 충분한지는 시민이 판단하실 문제이고, 저희는 매년 이 숫자를 함께 공개하겠습니다."},
{q:"리그 전체 지원 규모가 그만큼이면 다른 데 쓰는 게 낫지 않나",l:"리그 총액 방어 금지 → 자기 구단 실적으로 좁힘",s:"리그 전체 숫자는 제가 답할 위치가 아닙니다. 저희 구단은 지원금 중 [○%, ○억]을 유소년에 쓰고 [○명]을 무상으로 가르치고 있습니다."}
],
C3:[
{q:"자본잠식 상태인데 재정 운영을 잘하고 있다고 말할 수 있나",l:"수치 부인 금지 → 성과 주장과 재무 지표를 같은 문장에 두지 않음 → 이행률 제시",s:"자본총계는 [○○]이고 잠식 상태가 맞습니다. 개선 계획상 [○년]까지 해소를 목표로 하고 있으며 현재 이행률은 [○%]입니다. 세부 지표는 분기마다 같은 자리에 갱신하겠습니다."},
{q:"매년 100억대를 지원하는데 그 금액의 기준은 무엇인가",l:"기준이 없으면 없다고 → 언제까지 무엇을 기준으로 삼을지",s:"현재 조례에 구체적 금액 기준은 없습니다. 그 점이 문제라는 지적에 동의합니다. [자체수입 비중·유소년 실적·관중] 세 지표를 기준으로 하는 산정안을 [○월]까지 시와 함께 만들겠습니다."},
{q:"감사 대상이 아니라면 누가 이 돈을 검증하나",l:"관할 부인으로 끝내지 않음 → 자발적 외부 검증 제시",s:"제도상 [출자·출연기관]에 해당하지 않는 것은 맞습니다. 다만 검증이 없어도 된다는 뜻은 아닙니다. 올해부터 외부 회계법인 감사를 자체적으로 받고 결과를 공개하겠습니다."}
],
C4:[
{q:"구단 재무를 감독할 권한이 어디에 있나",l:"권한 범위를 밝히되 그 범위 안에서 지금 하는 일을 함께",s:"규정상 [○○]는 각 구단의 권한입니다. 다만 그것이 아무도 보지 않는다는 뜻은 아닙니다. [라이선싱 재무 심사]와 [분기 점검]을 [○일]까지 진행하고 결과를 알리겠습니다."},
{q:"권한이 없다면 결국 아무도 책임지지 않는 구조 아닌가",l:"구조 설명으로 끝내지 않음 → 권한 있는 기관과의 협의 일정 제시",s:"그렇게 읽힐 수 있는 답변이었습니다. 권한 밖 사안은 [○○ 기관]과 [○일]에 협의를 시작합니다. 협의 결과는 그대로 공개하겠습니다."},
{q:"이 일로 생긴 피해를 왜 선수가 부담하나",l:"상대가 든 피해를 먼저 언급 → 구체적 보호 조치",s:"선수에게 부담이 가서는 안 된다는 지적에 공감합니다. [임금 지급·계약 조건]은 조정 대상에서 제외했고, 위반이 확인되면 규정에 따라 조치하겠습니다."}
],
C5:[
{q:"발표한 수치의 산정 기관과 방식은 무엇인가",l:"산정 기준 공개 → 한계 인정 → 보조 지표로 격하",s:"[○○기관]의 [○○] 방식이고 [○○] 기준입니다. 이 방식은 실제 수익과 다르다는 한계가 있어 참고 지표로만 보고, 핵심 지표는 [관중·시즌권·지역 상권 조사]로 바꾸겠습니다."},
{q:"효과가 그렇게 크면 지원을 줄여도 되는 것 아닌가",l:"논리 모순 인정 → 효과와 운영비를 구분 → 표기 방식 변경",s:"그렇게 읽힐 수 있는 발표였습니다. 홍보효과는 지역이 얻는 노출 가치이고 운영비를 대체하는 수입이 아닙니다. 앞으로 두 숫자를 나란히 두지 않겠습니다."},
{q:"공개한 자료가 오히려 문제로 돌아왔는데 앞으로도 공개할 건가",l:"공개 자체는 유지 → 설명을 함께 붙이는 방식으로 개선",s:"공개는 계속합니다. 표만 내놓아 해석을 맡긴 것이 잘못이었습니다. 다음부터는 자료 안에 [산정 기준·전년 대비 변화·예상 질문에 대한 설명]을 함께 넣겠습니다."}
],
D1:[
{q:"구단이 사전에 막을 수 있었던 것 아닌가, 걸개 확인 절차가 있나",l:"절차 유무를 사실대로 → 없으면 없다고 → 신설 시점 제시",s:"경기 전 걸개 사전 확인 절차가 없었습니다. 그 점이 이번 사안의 원인입니다. 다음 홈경기부터 [사전 확인과 현장 철거 권한]을 [○○]에 두고 운영하겠습니다."},
{q:"개별 팬의 행동인데 왜 구단이 제재를 받나",l:"규정을 방패가 아니라 책임 근거로 인용 → 조직성 부인 시도하지 않음",s:"경기장 질서 유지 책임은 홈 구단에 있습니다. 누가 만들었는지와 무관하게 저희 책임이 맞고, 그래서 사과드리는 것입니다."},
{q:"해당 팬 소모임에 어떤 조치를 했나, 언제까지인가",l:"조치 내용과 기간을 숫자로 → 상대 구단에 전달한 사실 포함",s:"해당 소모임 대표의 홈경기 출입을 [○개월] 제한했고 상대 구단에는 [○월 ○일] 직접 사과를 전달했습니다. 응원 규범 개정안은 [○일]에 공개합니다."}
],
D2:[
{q:"같은 일이 전에도 있었는데 그때 조치는 무엇이었나",l:"과거 건을 우리가 먼저 꺼냄 → 그때 조치가 왜 작동하지 않았는지",s:"[○년 ○월]에 같은 일이 있었고 그때는 [○○] 조치를 했습니다. 그 조치가 현장까지 닿지 않았습니다. 이번에는 [구역별 담당 배치와 반입 물품 통제]를 규범에 넣고 첫 경기부터 적용합니다."},
{q:"행위자를 특정했나, 못 했다면 왜인가",l:"확인 상태를 그대로 → 완료 시점 제시",s:"[○명]을 확인했고 나머지는 확인 중입니다. 좌석 기록과 영상으로 [○일]까지 확인을 마치고 결과를 알리겠습니다."},
{q:"선수 안전을 위해 실제로 무엇이 바뀌나",l:"선언이 아니라 조치 목록 → 서포터스와의 합의 여부",s:"[반입 금지 물품 확대, 구역별 현장 담당 배치, 위반 시 출입 제한]입니다. 서포터스와 합의해 [○일] 공동으로 발표합니다."}
],
D3:[
{q:"구단은 선수 SNS를 관리하지 않나",l:"관리 범위를 사실대로 → 없으면 신설 시점 제시",s:"개인 계정까지 사전 검토하지는 않습니다. 다만 차별 표현에 대한 기준은 구단이 정해 두었어야 했습니다. [계약서·내규]에 명시하고 [○일]에 선수단 교육을 실시합니다."},
{q:"본인은 의도가 없었다는데 구단 입장도 같은가",l:"의도 방어에 동참하지 않음 → 표출된 의미가 기준임을 인정",s:"의도와 무관하게 받아들여지는 의미가 기준이라고 봅니다. 불편을 드린 점에 대해 구단이 사과드립니다."},
{q:"같은 사안에 제재 수준이 달랐는데 구단은 어떻게 보나",l:"리그 양정 논평 회피 → 구단 자체 기준으로 답",s:"제재 수준은 저희가 평가할 위치가 아닙니다. 구단 차원에서는 차별 표현에 대해 [○○] 기준을 두고 그대로 적용하겠습니다."}
],
D4:[
{q:"피해가 없다고 했다가 있다고 바뀌었는데 어느 쪽이 맞나",l:"번복 사실을 먼저 인정 →
확인 경위 → 앞으로의 표현 원칙",s:"처음 안내가 잘못됐습니다. [○명]이 [○○] 부상을 입은 것이 맞습니다. 확인 전에 없다고 말한 것이 문제였고, 앞으로 피해 여부는 확인될 때까지 확인 중으로 알리겠습니다."},
{q:"경기장 관리 책임은 구단인가 지자체인가",l:"책임 떠넘기기 금지 → 계약상 구분을 밝히되 우리 몫을 먼저",s:"시설 소유와 보수는 [○○]이고 경기 운영 중 안전은 구단 책임입니다. 이번 건은 경기 중 발생했으므로 구단이 먼저 사과드립니다. 책임과 비용 분담은 [○○]와 정리해 공개하겠습니다."},
{q:"마지막 안전 점검은 언제였나",l:"날짜 즉답 → 점검 항목의 한계 인정 → 주기 변경",s:"[○년 ○월]입니다. 육안 점검 위주여서 구조물까지 보지 못했습니다. [○개월] 주기로 전문 기관 점검을 받고 결과를 공개하겠습니다."}
],
D5:[
{q:"시즌권 구매자에게 사전에 알렸나",l:"고지 여부 사실대로 → 안 했으면 구제 방안",s:"구매 시점에는 고지하지 못했습니다. 저희 잘못입니다. 해당 구매자에게 [좌석 변경·환불] 중 선택하실 수 있도록 [○일]까지 개별 안내하겠습니다."},
{q:"중립석에서 응원을 막는 기준은 무엇인가",l:"기준을 문구로 제시 → 현장 적용 방식까지",s:"[대형 깃발·북·악기를 이용한 집단 응원과 리딩]이 제한됩니다. 기준은 경기장 입구와 좌석 안내문에 같은 문구로 게시하고, 현장 인력이 같은 문장으로 안내합니다."}
],
D6:[
{q:"지적된 뒤 조치했나, 했다면 왜 공개하지 않았나",l:"조치 사실과 날짜 → 공개하지 않은 것 자체를 문제로 인정",s:"[○월 ○일] 조치를 마쳤습니다. 조치하고도 알리지 않아 같은 지적이 반복됐습니다. 앞으로 민원과 조치 결과를 [○○]에 함께 게시하겠습니다."},
{q:"입장료를 받는데 이 수준이 맞나",l:"방어 금지 → 기준과 점검 주기 제시",s:"맞지 않습니다. [좌석·화장실·통로] 점검 항목을 정하고 [○○] 주기로 점검해 결과를 공개하겠습니다."}
],
E1:[
{q:"구단이 먼저 공개한 이유는 무엇인가",l:"공개를 성과로 말하지 않음 → 절차였음을 담담하게",s:"숨길 사안이 아니었습니다. 인지 당일 활동에서 배제하고 리그에 보고한 뒤, 다음 날 저희가 먼저 알렸습니다. 같은 일이 생기면 같은 순서로 하겠습니다."},
{q:"계약은 유지하나 해지하나, 기준은 무엇인가",l:"즉답 회피 금지 → 기준을 먼저 → 결정 시점",s:"구단 자체 징계 기준은 [○○]이고 이번 사안은 [○○]에 해당합니다. 조사 결과가 나오는 [○일] 이후 그 기준대로 결정하고 근거와 함께 알리겠습니다."},
{q:"리그 징계가 하한선이라는 지적이 있는데 구단 자체 징계는",l:"리그 양정 논평 회피 → 구단 몫을 숫자로",s:"리그 양정은 저희가 평가할 사안이 아닙니다. 구단 차원에서는 [○○] 조치를 하고, 징계 이후 관리까지 [○개월]간 책임지겠습니다."}
],
E2:[
{q:"불참 이유가 무엇인가",l:"추측으로 답하지 않음 → 확인 시점 제시",s:"지금 말씀드릴 수 있는 것은 불참한 사실입니다. 경위는 확인해 [○일]까지 말씀드리겠습니다."},
{q:"벌금을 감수하겠다는 말이 구단 공식 입장인가",l:"잘못된 발언을 그대로 두지 않음 → 즉시 정정",s:"그 표현은 구단 입장이 아닙니다. 정정합니다. 규정상 참석 의무가 있는 자리였고, 불참한 것에 대해 사과드립니다."},
{q:"재발 방지책은 무엇인가",l:"내규 반영 여부로 답 → 현장 담당 응대 기준까지",s:"미디어 의무 사항을 [계약·내규]에 명시했습니다. 현장에서 담당자가 쓸 수 있는 답변 기준도 함께 정해 공유했습니다."}
],
E3:[
{q:"구단은 징계를 수용하나",l:"수용 여부만 답함 → 판정 논평 금지",s:"결정을 수용합니다. 선수단 관리에 더 주의하겠습니다."},
{q:"상대 선수 부상에 대해 연락했나",l:"공개 발표보다 먼저 한 조치를 밝힘",s:"[○월 ○일] 상대 구단과 선수에게 직접 연락드렸습니다."}
],
E4:[
{q:"언제 알았나, 알고도 왜 공개하지 않았나",l:"인지 시점 특정 → 공개하지 않은 이유를 그대로 → 판단 오류 인정",s:"[○월 ○일] 인지했고 [○○] 조치를 했습니다. 피해 선수 보호를 이유로 공개하지 않았습니다. 결과적으로 충분히 알리지 못한 판단은 잘못이었습니다."},
{q:"계약 해지 사유를 다르게 정리한 이유는 무엇인가",l:"사유 불일치를 인정 → 기록 원칙 신설",s:"실제 사유와 다르게 정리된 것이 맞습니다. 그 자체가 두 번째 잘못입니다. 앞으로 계약 종료 사유는 실제와 맞게 기록하는 것을 원칙으로 하겠습니다."},
{q:"피해 선수 보호를 위해 무엇을 했나",l:"조치 목록을 구체적으로 → 상급 기관 보고 여부 포함",s:"[분리 조치와 의사 확인]을 먼저 했고 [○월 ○일] 상급 기관에 보고했습니다. 신고 창구와 처리 절차는 [○일]에 공개합니다."}
]
};
const CATS=[
{k:"money",t:"돈",s:"예산 · 지원금 · 집행 · 회계"},
{k:"people",t:"사람",s:"선수 · 지도자 · 직원"},
{k:"venue",t:"경기장 · 팬",s:"안전 · 응원 · 시설"},
{k:"club",t:"구단 운영",s:"존립 · 성적 · 인사"},
{k:"none",t:"모르겠음",s:"아직 안 물어봄"}
];
const STATES=[
{k:"call",t:"지금 통화 중임",s:"읽을 문장이 먼저 나옴"},
{k:"after",t:"전화를 끊었음",s:"회신해야 함"},
{k:"pub",t:"기사가 이미 나갔음",s:"추가 문의를 받음"},
{k:"before",t:"아직 연락은 없음",s:"터질 것 같음"}
];
const QMAIN=[
/* ── 돈 ── */
{id:"M1",cat:"money",role:"lead",
q:"지원금이 총수익의 대부분인데 자체수익은 몇 %까지, 언제까지 올릴 계획인가",
why:"구단 존립 근거를 묻는 질문임. 비중 자체를 부인하면 그 자리에서 신뢰를 잃고, 목표 연도를 말하지 않으면 계획이 없는 것으로 읽힘",
now:"지원금 비중과 자체수익 목표는 숫자로 말씀드려야 하는 사안이라, 제 선에서 답하면 틀릴 수 있습니다. [회신 시각]까지 확인해 제가 직접 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["맞습니다. [기준 연도] 기준 지원금 비중은 [○%]이고, 자체수익만으로 운영이 가능한 구조가 아닙니다. 그 점은 저희도 과제로 보고 있습니다.",
"올해는 [광고·시즌권·시설 활용]에서 자체수익 [○억]을 먼저 만드는 것을 목표로 잡았고, [○월] 결산에 달성률을 공개하겠습니다.",
"최근 3년 자체수익률은 [○% → ○% → ○%]이고 같은 기간 자체수익 절대액은 [○억 → ○억]입니다.",
"중장기 목표 비중과 연도는 [이사회/시] 의결 사항입니다. [○월] 이후 확정된 수치를 공개하겠습니다."],
need:["지원금 비중과 기준 연도","최근 3년 자체수익률","올해 자체수익 목표액","의결 일정"],
never:["다른 구단도 같습니다","구조상 불가피합니다","목표 연도를 담당자가 임의로 말하는 것"]},
{id:"M2",cat:"money",role:"exec",
q:"몇 년간 수십억이 빠져나가는데 아무도 몰랐다는 게 말이 되나",
why:"개인 범행인지 조직 문제인지 가르는 질문임. \"몰랐다\"로 답하면 관리 책임으로 넘어가고, 변명하면 은폐 의심이 붙음",
now:"그 부분은 제가 평가해 말씀드릴 사안이 아닙니다. 확인 절차 결과와 함께 공식으로 설명드리겠습니다. [회신 시각]까지 어디까지 말씀드릴 수 있는지 정리해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["말이 되지 않습니다. 저희도 같은 질문을 내부에 하고 있습니다.",
"외부 회계법인 감사와 수사에 자료를 모두 제공하고 있고, 출납·결재·계좌 관리를 분리하는 조치를 [○월 ○일] 시행했습니다.",
"확인된 구조는 출납·결재·통장 관리가 [한 사람]에게 집중돼 있었고 감사는 [통장 사본 확인] 수준이었습니다.",
"최종 금액과 책임 범위는 감사·수사 결과로 확정됩니다. 결과가 나오면 저희가 먼저 공개하겠습니다."],
need:["권한 분리 조치 시행일","계좌 대사 주기 — 현재와 개선 후","현재까지 확인된 금액과 기준일","감사 종료 예정일"],
never:["개인의 일탈입니다","규정 위반은 아닙니다","확정 전 금액을 단정형으로 말하는 것"]},
{id:"M3",cat:"money",role:"lead",
q:"처음 발표한 금액과 지금 금액이 다른데 더 나올 수 있나",
why:"숫자가 바뀐 것 자체를 기사로 만들려는 질문임. \"더 안 나온다\"고 말하면 다음에 나올 때 두 번째 기사가 생김",
now:"금액은 확인 단계마다 달라질 수 있어 지금 단정해 말씀드리지 않겠습니다. 현재 기준일과 확정 시점을 정리해 [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["늘어날 수 있습니다. 지금 숫자는 확정액이 아니라 [기준일] 기준으로 확인된 금액입니다.",
"확정 시점은 [감사 종료 예정일]이고 그때 산출 근거와 함께 공개하겠습니다. 그 전까지 중간 수치를 따로 발표하지 않겠습니다.",
"현재까지 확인된 금액은 [○억]이며 연도별 내역은 [공개 자리]에 올려두었습니다.",
"확정 금액 발표는 [이행 주체]가 합니다. 일정이 정해지면 [회신 시각]까지 알려드리겠습니다."],
need:["현재 확인 금액과 기준일","감사·수사 종료 예정일","연도별 내역"],
never:["더 나올 일은 없습니다","그 정도가 전부입니다"]},
{id:"M4",cat:"money",role:"lead",
q:"집행 내역을 항목별로 밝힐 수 있나",
why:"공개 거부 자체가 기사가 되는 질문임. \"곤란하다\"로 답하면 그 문장이 제목이 됨",
now:"집행 내역을 어디까지 드릴 수 있는지는 제가 정하는 것이 아니어서 확인이 필요합니다. 공개 범위와 형식을 [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["공개하지 못할 이유가 없습니다.",
"[선수단·시설·운영·유소년] 항목별 내역을 [○월 ○일] 공개하고, 이후 분기마다 같은 형식으로 올리겠습니다.",
"[해당 연도] 집행 총액은 [○억]이고 비중은 [선수단 ○% · 시설 ○% · 운영 ○% · 유소년 ○%]입니다.",
"총액 교부 구조상 일부 항목은 [상급기관]이 확정합니다. 그 부분은 [○일]까지 확인해 함께 알리겠습니다."],
need:["항목별 집행 내역","공개 예정일","총액 교부 구조에서 구단이 정하는 범위"],
never:["경영상 비밀입니다","구단 자체 회계입니다"]},
{id:"M5",cat:"money",role:"lead",
q:"시민 1인당 세금이 얼마 들어가는지 계산해 봤나",
why:"계산을 회피하면 그것이 답이 됨. 숫자를 내놓되 그 돈으로 한 일을 같이 말하지 않으면 비용만 남음",
now:"1인당 환산은 산출 기준을 맞춰 말씀드려야 하는 숫자입니다. 기준과 함께 [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["계산해 봤습니다. [해당 연도] 기준 시민 1인당 연 [약 ○원]입니다.",
"같은 자료에 그 비용으로 제공한 것도 함께 공개하겠습니다 — 유소년 [○명] 무상 교육, 홈경기 관람 [○만 명], 지역 행사 [○회].",
"산출은 [지원금 총액 ÷ 주민등록 인구]이고 기준일은 [○월 ○일]입니다.",
"충분한지에 대한 판단은 시민과 의회가 하실 몫입니다. 저희는 이 숫자를 매년 같은 형식으로 공개하겠습니다."],
need:["연간 지원금 총액","주민등록 인구와 기준일","유소년 인원 · 관람 인원 · 지역 행사 횟수"],
never:["그 정도는 다른 데도 씁니다","비교하면 적은 편입니다"]},
/* ── 사람 ── */
{id:"P1",cat:"
people",role:"lead",
q:"수치는 나왔습니까, 방출입니까",
why:"두 질문을 붙여 하나라도 답하게 만드는 질문임. 어느 쪽이든 답하면 나머지가 확정된 것으로 읽힘",
now:"수치는 수사기관이 확인하는 사항이고, 계약 문제는 구단 절차가 끝나야 말씀드릴 수 있습니다. 지금은 둘 다 제 선에서 확인해 드릴 수 없습니다. [회신 시각]까지 확인 가능한 범위를 정리해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["[선수/지도자]가 [○월 ○일] 해당 사안으로 적발된 사실은 확인했습니다.",
"구단은 인지 즉시 훈련과 선수단 활동에서 배제했고 [상급기관]에 보고했습니다.",
"수치와 처분 내용은 수사기관이 확인하는 사항이라 구단이 발표할 사항이 아닙니다.",
"구단 자체 조치는 [상벌 절차] 이후 결정하며 결정되면 근거와 함께 공개하겠습니다."],
need:["적발 일시","구단 인지 시각","배제 조치 시각","상급기관 보고 시각","구단 자체 징계 기준","상벌 절차 일정"],
never:["방출입니다","선처할 생각입니다","수치는 ○○입니다"]},
{id:"P2",cat:"people",role:"exec",
q:"구단은 언제 알았나, 알고도 공개하지 않은 이유는",
why:"은폐 여부를 가르는 질문임. 시각을 특정하지 못하면 그 자체가 의심 근거가 되고, 특정했다가 기록과 어긋나면 번복이 됨",
now:"인지 시각은 기록으로 확인해 말씀드려야 합니다. 추측으로 말씀드리면 나중에 정정해야 하니 [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["[○월 ○일 ○시]에 인지했습니다. 즉시 공개하지 않은 것은 사실입니다.",
"인지 후 [분리 조치]와 [상급기관 보고]를 먼저 했습니다. 공개하지 않은 이유는 [피해자 보호 / 수사 협조]였습니다.",
"보고 기록은 [○월 ○일] [수신 기관]에 남아 있습니다.",
"결과적으로 충분히 알리지 못한 판단에 대해서는 책임이 있습니다. 앞으로는 [기준]에 따라 공개하겠습니다."],
need:["인지 시각과 기록 근거","조치 시각","상급기관 보고 일시와 수신처","공개하지 않은 사유"],
never:["몰랐습니다","공개할 사안이 아니라고 봤습니다","기록 확인 전에 날짜를 특정하는 것"]},
{id:"P3",cat:"people",role:"lead",
q:"계약은 유지하나 해지하나, 기준은 무엇인가",
why:"기준이 없으면 그때그때 봐준다는 뜻이 됨. 결론보다 기준을 먼저 말해야 함",
now:"계약 관련 결정은 제가 말씀드릴 수 있는 사항이 아닙니다. 판단 주체와 시점은 [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["아직 결정되지 않았습니다.",
"구단 자체 징계 기준은 [조항]이고 이번 사안은 [해당 구간]에 해당합니다. [상벌 절차] 결과가 나오는 [○일] 이후 그 기준대로 결정하겠습니다.",
"최근 [○년]간 같은 유형에 구단이 적용한 기준은 [○○]입니다.",
"결정되면 근거 조항과 함께 공개하겠습니다. 결정 전에는 어느 쪽으로도 말씀드리지 않겠습니다."],
need:["구단 자체 징계 기준 조항","과거 적용 사례","상벌 절차 일정"],
never:["선처할 생각입니다","방출이 유력합니다","본인이 반성하고 있습니다"]},
{id:"P4",cat:"people",role:"lead",
q:"구단은 선수 SNS를 관리하지 않나",
why:"관리 범위를 묻는 것 같지만 실제로는 책임 범위를 묻는 질문임. \"개인 계정이라\"로 답하면 책임 회피로 읽힘",
now:"선수 SNS 관련 구단 기준이 어디까지 정해져 있는지 확인해 말씀드리겠습니다. 제 기억으로 답하면 틀릴 수 있습니다. [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["개인 계정까지 사전 검토하지는 않습니다. 다만 기준을 정해 두는 것은 구단이 해야 할 일이 맞습니다.",
"차별·혐오 표현 금지를 [계약서/내규]에 명시했고 [○월 ○일] 선수단 전체 교육을 실시합니다. 해당 게시물은 [○시]에 삭제했습니다.",
"현재 기준은 [조항]이고 위반 시 조치는 [○○]입니다.",
"개인 처분은 리그 상벌 절차가 정합니다. 구단 차원 조치는 저희가 정해 공개하겠습니다."],
need:["SNS 관련 내규 조항","교육 실시 일정","게시물 삭제 시각","구단 자체 조치 기준"],
never:["개인 계정이라 저희와 무관합니다","의도는 없었다고 합니다"]},
{id:"P5",cat:"people",role:"lead",
q:"리그 징계가 하한선이라는 지적이 있는데 구단 자체 징계는",
why:"리그 양정을 평가하게 만들어 구단이 리그를 비판하는 그림을 만드는 질문임",
now:"리그 징계 수준은 제가 평가할 위치가 아닙니다. 구단이 한 조치는 확인해 [회신 시각]까지 정리해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["리그 양정에 대해서는 저희가 평가할 사안이 아닙니다.",
"구단 차원에서는 [출전 외 활동 제한 · 급여 조치 · 사회봉사] 중 [○○]를 적용하고, 징계 이후 [○개월]간 관리 계획도 함께 운영합니다.",
"구단 자체 징계 기준은 [조항]에 정해져 있고 이번 사안은 [해당 구간]입니다.",
"계약 관련 결정은 [상벌 절차] 이후 별도로 알리겠습니다."],
need:["구단 자체 징계 기준","적용 조치 내용","사후 관리 기간"],
never:["리그 징계가 가볍다고 봅니다","리그 결정이라 저희는 어쩔 수 없습니다"]},
/* ── 경기장·팬 ── */
{id:"V1",cat:"venue",role:"lead",
q:"피해가 없다고 했다가 있다고 바뀌었는데 어느 쪽이 맞나",
why:"번복 자체를 쟁점으로 만드는 질문임. 해명하면 변명이 되고, 인정하면 이후 설명의 신뢰를 되찾을 수 있음",
now:"처음 안내와 지금 확인된 내용에 다른 부분이 있는지부터 확인하겠습니다. 제 선에서 어느 쪽이 맞다고 단정해 말씀드리지 않겠습니다. [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["처음 안내가 잘못됐습니다. [○명]이 [부상 내용]을 입은 것이 맞습니다.",
"확인 전에 피해가 없다고 말한 것이 잘못이었습니다. 앞으로 피해 여부는 확인될 때까지 확인 중으로 알리겠습니다. 해당 구역은 [○시]에 폐쇄했습니다.",
"현재까지 접수된 피해는 [○건]이고 접수 창구는 [○○]입니다.",
"시설 보수와 재개장 시점은 [시설 소유·관리 주체]가 정합니다. 정해지는 대로 알리겠습니다."],
need:["피해자 수와 상태","피해 접수 창구","구역 폐쇄 시각","시설 소유·관리 주체"],
never:["인명 피해는 없습니다 — 확인 전에","경미한 사고입니다"]},
{id:"V2",cat:"venue",role:"lead",
q:"개별 팬 행동인데 왜 구단이 제재를 받나",
why:"규정을 방패로 쓰게 유도하는 질문임. 규정은 책임 근거로 인용해야 함",
now:"책임 범위는 제가 판단해 말씀드릴 사안이 아닙니다. 당시 조치와 확인 중인 사항을 구분해 [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["누가 했는지와 무관하게 경기장 질서 유지 책임은 홈 구단에 있습니다. 저희 책임이 맞습니다.",
"해당 행위는 [○시]에 조치했고 행위자에 대해 [○○]를 결정했습니다. [상대 구단]에는 [○월 ○일] 직접 사과를 전달했습니다.",
"경기 규정상 관중 안전과 질서 유지는 사유를 불문하고 홈 구단이 책임집니다.",
"응원 규범 개정안은 서포터스와 함께 [○일]에 공개하겠습니다."],
need:["조치 시각","행위자 조치 내용","상대 구단 사과 전달 일시","규범 개정 일정"],
never:["일부 팬의 돌발 행동입니다","구단이 막을 수 없는 일입니다"]},
{id:"V3",cat:"venue",role:"lead",
q:"구단이 사전에 막을 수 있었던 것 아닌가",
why:"예방 절차의 유무를 묻는 질문임. 없으면 없다고 하고 신설 시점을 말해야 함",
now:"사전 확인 절차가 어떻게 돼 있었는지는 기록으로 확인해 말씀드려야 합니다. [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["경기 전 사전 확인 절차가 없었습니다. 그 점이 이번 일의 원인입니다.",
"다음 홈경기부터 사전 확인과 현장 철거 권한을 [담당]에게 두고 운영합니다.",
"현재 적용 중인 규범은 [○○]이고 이번에 추가되는 항목은 [○○]입니다.",
"규범 개정은 서포터스와 협의해 확정하며 [○일]에 공개합니다."],
need:["현재 규범 내용","신설 절차와 담당","시행 시점"],
never:["사전에 알 수 없었습니다","매번 확인할 수는 없습니다"]},
{id:"V4",cat:"venue",role:"lead",
q:"경기장 관리 책임은 구단인가 지자체인가",
why:"책임 떠넘기기를 유도하는 질문임. 계약상 구분을 말하되 우리 몫을 먼저 말해야 함",
now:"시설 소유와 운영 책임이 어떻게 나뉘는지는 문서로 확인해 말씀드리겠습니다. 제 기억으로 답하면 틀릴 수 있습니다. [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["경기 운영 중 관중 안전은 구단 책임입니다. 이번 일은 경기 중에 발생했으므로 구단이 먼저 사과드립니다.",
"시설 점검을 [○일]까지 완료하고 결과를 공개합니다. 해당 구역은 점검 완료 전까지 폐쇄합니다.",
"시설 소유와 보수는 [소유 주체], 경기 운영 중 안전은 구단으로 [협약 제○조]에 정해져 있습니다.",
"책임과 비용 분담은 [소유 주체]와 정리해 그 결과를 공개하겠습니다."],
need:["시설 소유·관리 주체","협약상 책임 구분 조항","점검 완료 예정일"],
never:["저희 소관이 아닙니다","시설은 시가 관리합니다"]},
{id:"V5",cat:"venue",role:"lead",
q:"같은 일이 전에도 있었는데 그때 조치는 무엇이었나",
why:"반복 여부를 확인하는 질문임. 과거 건을 우리가 먼저 꺼내지 않으면 은폐로 읽힘",
now:"과거 유사 건과 그때 조치는 기록을 찾아 함께 정리해 말씀드리겠습니다. [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["[○년 ○월]에 같은 일이 있었습니다. 그때 조치는 [○○]였습니다.",
"그 조치가 현장까지 닿지 않았습니다. 이번에는 [구체 조치]를 규범에 넣고 첫 경기부터 적용합니다.",
"최근 [○년]간 유사 건은 [○건]이고 각각의 조치는 [○○]입니다.",
"이행 여부는 [○월]에 점검해 결과를 공개하겠습니다."],
need:["과거 유사 건 목록과 조치","이번 조치 내용","이행 점검 시점"],
never:["처음 있는 일입니다","그때와는 다른 사안입니다"]},
/* ── 구단 운영 ── */
{id:"C1",cat:"club",role:"lead",
q:"예산은 늘었는데 성적은 왜 최하위인가, 돈은 어디로 갔나",
why:"성적과 예산을 직결시키는 질문임. 성적 책임은 인정하되 증액 사용처를 항목으로 보여야 함",
now:"증액분 사용처는 항목별 자료로 확인해 말씀드려야 하는 사안입니다. 드릴 수 있는 범위를 [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["성적은 변명할 여지가 없습니다.",
"증액분 [○억]은 [선수단 ○억 · 유소년 ○억 · 시설 ○억]에 썼고 항목별 내역을 [공개 자리]에 올리겠습니다.",
"올해 [지자체/이사회]와 합의한 지표에는 관중 · 시즌권 · 유소년도 포함돼 있고 현재 달성률은 [○%]입니다.",
"성적에 대한 평가는 [평가 주체]가 합니다. 저희는 합의한 지표 결과를 함께 공개하겠습니다."]
,
need:["증액분 항목별 사용처","합의 지표와 현재 달성률"],
never:["돈만으로 성적이 나오는 것은 아닙니다","다른 구단도 비슷합니다"]},
{id:"C2",cat:"club",role:"exec",
q:"약속이 있었다고 하는데 문서로 남아 있나",
why:"구두 합의였는지 확인하는 질문임. 없으면 없다고 하는 것이 유일한 답임",
now:"협약 문서에 무엇이 적혀 있는지는 원문을 확인해 말씀드려야 합니다. [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["[협약서 제○조]에 있습니다. 또는 — 문서에는 없고 구두 협의였습니다. 중요한 합의를 문서로 남기지 않은 것이 이번 문제의 출발점입니다.",
"앞으로 협의 결과는 회의록으로 확인받겠습니다. 이번 건의 경과는 [○월 ○일]부터 [○월 ○일]까지 정리해 공개하겠습니다.",
"확인된 경과는 [일자별 경위]입니다.",
"최종 결정은 [결정 주체]가 합니다. 저희는 경과와 요청 사항을 공개하겠습니다."],
need:["협약서 조항","일자별 경위","결정 주체와 일정"],
never:["분명히 약속했습니다 — 문서 확인 전에","상대가 말을 바꿨습니다"]},
{id:"C3",cat:"club",role:"lead",
q:"매년 100억대를 지원하는데 그 금액의 기준은 무엇인가",
why:"기준 유무를 묻는 질문임. 없다고 답해도 되지만 언제까지 만들지를 같이 말해야 함",
now:"지원 산정 근거가 어디에 정해져 있는지는 조항을 확인해 말씀드리겠습니다. 제가 해석해 말씀드리지는 않겠습니다. [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["현재 조례에 구체적 금액 기준은 없습니다. 기준이 필요하다는 지적에 동의합니다.",
"자체수입 비중 · 유소년 실적 · 관중 세 지표를 기준으로 하는 산정안을 [○월]까지 [지자체/이사회]와 함께 만들겠습니다.",
"최근 3년 지원액은 [○억 → ○억 → ○억]이고 같은 기간 자체수입은 [○억 → ○억]입니다.",
"산정 기준 확정과 조례 개정은 [결정 주체]의 권한입니다. 저희는 자료와 안을 제출하겠습니다."],
need:["최근 3년 지원액과 자체수입","조례 조항","산정안 제출 일정"],
never:["다른 지자체도 그 정도 합니다","적정한 수준이라고 봅니다"]},
{id:"C4",cat:"club",role:"exec",
q:"단장·대표 선임 기준이 무엇인가, 공모 절차가 있었나",
why:"정치적 인사 여부를 묻는 질문임. 절차를 사실대로 말하고 부족하면 개선을 약속해야 함",
now:"선임 절차는 기록으로 확인해 말씀드려야 합니다. [회신 시각]까지 확인해 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["[공모 ○명 지원, 임원추천위원회 심사]를 거쳤습니다. 또는 — 공모 절차 없이 임명했습니다. 절차가 부족했다는 지적은 받아들입니다.",
"다음 선임부터는 외부 위원 과반과 [인사청문/이사회 검증]을 도입하겠습니다.",
"현재 선임 근거는 [정관/조례 제○조]입니다.",
"선임 권한은 [구단주/이사회]에 있습니다. 절차 개선안은 저희가 제출하겠습니다."],
need:["선임 절차 기록","근거 조항","개선안 도입 시점"],
never:["관계는 없습니다","적임자였습니다","인사는 말씀드릴 사안이 아닙니다"]},
{id:"C5",cat:"club",role:"lead",
q:"홍보효과 수치의 산정 기관과 방식은 무엇인가",
why:"과장 여부를 확인하는 질문임. 산정 방식을 못 밝히면 수치 전체가 무너짐",
now:"산정 기관과 방식은 자료를 확인해 정확히 말씀드리겠습니다. [회신 시각]까지 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
a:["[산정 기관]의 광고환산가치 방식이고 [매체 · 노출 건수] 기준입니다. 이 방식이 실제 수익과 다르다는 한계가 있습니다.",
"앞으로 홍보효과는 참고 지표로만 쓰고 핵심 지표는 관중 · 시즌권 · 지역 상권 조사로 바꾸겠습니다.",
"[해당 연도] 산정액은 [○억]이며 산출 내역을 [공개 자리]에 올리겠습니다.",
"지표 변경은 [지자체/이사회]와 협의해 [○월]까지 확정하겠습니다."],
need:["산정 기관 · 방식 · 기준","산정액과 산출 내역","지표 변경 일정"],
never:["홍보효과와 운영비를 나란히 제시하는 것","투입 대비 ○배 효과입니다"]}
];
const STEPLBL=["인정","조치","근거","전달"];
const STEPHINT=["사실과 수치를 먼저 확인함","이미 한 것과 기한이 있는 것","검증 가능한 숫자만","누가 언제 답하는지만 — 약속은 담당자 몫이 아님"];
/* 절차 문장 = 완성형(그대로 읽어도 됨). 입장·사과·약속 = 뼈대, 보고용으로만 나감 */
const CHIPS=[
{k:"call1",t:"처음 걸려온 전화"},
{k:"money",t:"금액·수사·감사"},
{k:"pub",t:"기사 나온 뒤"},
{k:"safe",t:"승인 연락 안 됨"}
];
const CARDS={
call1:[
"네, [구단명] 홍보 담당 [내 이름]입니다. 질문을 정확히 받아 적겠습니다. 매체와 성함, 회신받을 번호를 먼저 알려주시겠습니까?",
"지금 제가 확인해 드릴 수 있는 범위를 넘는 질문입니다. 추측으로 답하면 서로 손해이니 [회신 시각]까지 확인해서 제가 직접 전화드리겠습니다.",
"다시 정리하면 [질문 요지] 건으로 [회신 시각]까지 회신, 연락처는 [기자 연락처] 맞습니까? 그때까지 저희 쪽 다른 설명은 나가지 않습니다."],
money:[
"질문 받았습니다. 그 사안은 확인 절차가 진행 중이어서 제 선에서 사실관계를 확인해 드릴 수 없습니다. 질문은 그대로 적어 책임자에게 바로 전달하겠습니다.",
"제가 아는 범위에서 답하면 틀릴 수 있고, 틀린 답이 더 큰 문제가 됩니다. [회신 시각]까지 정리해 회신드리겠습니다. 그 전까지 저희 쪽 설명은 없습니다.",
"받아 적은 질문을 다시 읽겠습니다. \"[질문 요지]\" — 제가 들은 그대로입니까? 틀린 부분이 있으면 지금 고쳐 주십시오."],
pub:[
"기사 확인했습니다. 지금 제가 드릴 수 있는 것은 확인된 사실과 확인 중인 사항의 구분입니다. [회신 시각]까지 정리해 보내드리겠습니다.",
"정정이나 반론을 요청할지는 제가 결정할 수 있는 사항이 아닙니다. 요청 여부와 내용은 [회신 시각]까지 공식으로 회신드리겠습니다.",
"추가로 취재하실 내용이 있으면 이 번호로 보내 주십시오. 받는 즉시 확인해 회신드리겠습니다. 제 이름은 [내 이름]입니다."],
safe:[
"전화 주신 내용 받았습니다. 지금은 확인 권한이 있는 담당자와 연결되지 않습니다. 추측으로 답하지 않겠습니다.",
"오늘 안에는 공식 확인이 어렵습니다. 대신 [회신 시각]까지 확인 가능 여부만이라도 제가 문자로 알려드리겠습니다.",
"제 이름은 [내 이름]이고 번호는 이 번호입니다. 연결되는 즉시 제가 먼저 전화드리겠습니다. 기다리게 해 죄송합니다."]
};
const COUNTER="제가 말씀드린 것은 [확인된 것이 없다]는 것이고, [그 사실이 있다]고 말씀드린 것이 아닙니다. 그대로 적어 주십시오.";
const ASK=[
"마감 시각이 언제입니까? 그 시각까지 드릴 수 있는 것과 어려운 것을 정확히 구분해서 드리겠습니다.",
"어떤 자료를 보고 계신지 알려주시겠습니까? 자료에 따라 저희가 드릴 설명이 달라집니다.",
"기사에 저희 입장을 한 줄로 넣으실 계획이면, 그 한 줄은 제가 문장으로 드리는 편이 정확할 것 같습니다. 보내드려도 되겠습니까?"
];
const SAFE1="문의 받았습니다. 지금 시각에는 확인 권한이 있는 담당자와 연결되지 않아 사실관계를 확인해 드릴 수 없습니다. 추측으로 답하지 않겠습니다. 연결되는 즉시, 늦어도 [회신 시각]까지 제가 먼저 연락드리겠습니다. [구단명] 홍보 [내 이름], 이 번호로 회신 가능합니다.";
const NOTME="제가 답할 위치가 아닙니다. 이 사안 창구는 [창구 이름]이고 번호는 [창구 번호]입니다. 그쪽으로 연결드리겠습니다.";
const CONFIRM=[
"확인해서 [회신 시각]까지 전화로 회신드리겠습니다. [구단명] 홍보 [내 이름], 번호는 이 번호입니다. 그 시각까지 회신이 없으면 다시 연락 주십시오.",
"[회신 시각]까지 제가 직접 회신드리겠습니다. [구단명] 홍보 [내 이름]입니다.",
"[회신 시각]까지 회신드린다고 했는데 아직 확인이 끝나지 않았습니다. 현재는 확인 중이고, [회신 시각]까지 다시 알려드리겠습니다."
];
const SWAP=[
["확인해 보겠습니다","[회신 시각]까지 확인해 전화로 회신드리겠습니다 ([구단명] 홍보 [내 이름])"],
["드릴 말씀이 없습니다 · 노코멘트","지금 확인된 것이 없어 답을 드릴 수 없습니다. 확인되면 [회신 시각]까지 제가 먼저 알려드리겠습니다"],
["다른 구단도 같습니다","다른 구단 사정은 제가 답할 위치가 아닙니다. 저희 건만 말씀드리겠습니다"],
["규정 위반은 아닙니다","규정 해석은 저희가 할 부분이 아니고, 요청하신 자료는 모두 제출했습니다"],
["개인의 일탈입니다","책임 범위는 확인 절차에서 판단할 사안입니다. 저희가 한 것은 [조치]입니다"],
["사실무근입니다","저희가 확인한 범위에서는 [확인된 사실]입니다. 확인되지 않은 부분은 확인 중이라고 말씀드리겠습니다"],
["내부 통제 실패입니다","그 부분은 제가 평가할 사안이 아닙니다. 확인 결과와 함께 공식으로 설명드리겠습니다"],
["이번 주에 올리겠습니다","공개 시점은 [이행 주체]가 정합니다. 정해지는 즉시 [회신 시각]까지 알려드리겠습니다"]
];
const DICT=[
["club","구단명","예: ○○ FC"],
["me","내 이름","전화에서 말할 이름"],
["phone","내 번호","회신받을 번호"],
["ch1","창구 1 — 밤에 전화받는 사람","이름·번호"],
["ch2","창구 2 — 1이 안 되면","이름·번호"],
["ch3","창구 3 — 상급기관·모기업","부서·번호"],
["body","공개 자료가 올라가는 자리","홈페이지 주소 등"]
];
const CHECK10=[
["이번 주 질문받을 항목을 적어 뒀는가","경기 결과 말고 돈·사람·안전 쪽"],
["그중 지금 답할 수 있는 숫자가 있는가","없으면 요청해 둔 상태인가"],
["첫 응답 문장을 팀에서 같은 것으로 쓰고 있는가",""],
["밤에 전화받는 사람 이름과 번호가 정해져 있는가","창구 1·2"],
["명함 카드를 가지고 있는가","지갑·전화기 옆"],
["지난 사안 중 다시 물어볼 만한 것이 있는가","종결되지 않은 건"]
];
const TUTOR=[
{t:"창구 1·2 이름과 번호를 적음",d:"밤에 전화를 받는 사람임. 이 칸이 비어 있으면 보고할 곳이 정해지지 않고, 전화를 받은 담당자가 혼자 판단하게 됨.",b:"설정 열기",go:"set"},
{t:"구단명과 내 이름을 적음",d:"적어 두면 모범안 20개의 노란 칸이 전부 자동으로 채워짐. 29개 구단이 같은 문장을 쓰는 상황을 막는 장치이기도 함.",b:"설정 열기",go:"set"},
{t:"우리와 비슷한 사례 3건을 읽음",d:"2026년에 실제로 있었던 19건임. 무엇이 문제였는지가 아니라 어디서 갈렸는지가 적혀 있음.",b:"사례 보기",go:"case"},
{t:"내가 하지 않는 말 8개를 읽음",d:"한 문장이 사안의 성격을 정함. 여덟 개만 알아 두면 첫 통화에서 잃는 것이 없음.",b:"문장 보기",go:"say"},
{t:"명함 카드를 인쇄해 지갑에 넣음",d:"위기 첫 15분에 웹을 여는 사람은 없음. A4 한 장에 8면으로 나옴 — 종이가 본체이고 이 화면은 확장판임.",b:"명함 카드",go:"card"}
];
const AXNAME={A:"돈·회계",C:"존립·예산",D:"경기
장·팬",E:"사람"};
const ROLE={staff:"담당",lead:"팀장",exec:"대표·법무"};
const $=s=>ROOT.querySelector(s), el=(t,c,x)=>{const e=document.createElement(t);if(c)e.className=c;if(x!==undefined)e.textContent=x;return e;};
const KEY="klg-v4";
function load(){try{const o=JSON.parse(localStorage.getItem(KEY)||"{}");if(o.exp&&Date.now()>o.exp){return{}}return o}catch(e){return{}}}
function save(){try{ST.exp=Date.now()+30*864e5;localStorage.setItem(KEY,JSON.stringify(ST))}catch(e){}}
let ST=load(); ST.d=ST.d||{}; ST.chk=ST.chk||{}; ST.gap=ST.gap||{}; ST.now=ST.now||{};
function copyText(txt,btn){
const orig=btn.textContent;
const done=()=>{btn.textContent="복사됨";btn.classList.add("done");setTimeout(()=>{btn.textContent=orig;btn.classList.remove("done")},1600)};
try{const r=navigator.clipboard.writeText(txt); r&&r.then?r.then(done,()=>fb(txt,btn,orig)):done()}catch(e){fb(txt,btn,orig)}
}
function fb(txt,btn,orig){
const ta=document.createElement("textarea");ta.value=txt;ta.style.position="fixed";ta.style.opacity="0";document.body.appendChild(ta);ta.select();
try{document.execCommand("copy");btn.textContent="복사됨";btn.classList.add("done");setTimeout(()=>{btn.textContent=orig;btn.classList.remove("done")},1600)}
catch(e){btn.textContent="선택해 복사"}
document.body.removeChild(ta);
}
/* 설정값으로 빈칸 치환 — 빈 값은 [ ]로 남김 */
const MAP={"구단명":"club","내 이름":"me","내 번호":"phone","창구 이름":"ch1","창구 번호":"ch1"};
function fill(t){
return t.replace(/\[([^\]]+)\]/g,(m,k)=>{
const key=MAP[k]; const v=key?(ST.d[key]||'').trim():'';
if(v) return v;
const n=(ST.now||{});
if(k==="회신 시각"&&n.due) return n.due;
if(k==="질문 요지"&&n.q) return n.q.slice(0,40);
if(k==="기자 연락처"&&n.back) return n.back;
return '['+k+']';
});
}
function hasSlot(t){return /\[[^\]]+\]/.test(fill(t))}
/* ================= 2단계 선택 → 질문 카드 ================= */
const STMAP={},CATMAP={};
STATES.forEach(s=>STMAP[s.k]=s); CATS.forEach(c=>CATMAP[c.k]=c);
let stKey=ST.now.st||null, catKey=ST.now.cat||null;
function show(id){
['p-entry','p-now','p-chk','p-say','p-q','p-case','p-set'].forEach(s=>{const e=$('#'+s);if(e)e.hidden=(s!==id)});
$('#calmnav').hidden = !['p-chk','p-say','p-q','p-case','p-set'].includes(id);
$('#top').classList.toggle('compact', id==='p-now');
pageTop();
}
/* 상태 → 절차 문장 묶음 */
function chipFor(){ if(catKey==='money')return 'money'; if(stKey==='pub')return 'pub'; return 'call1'; }
/* 상태 → 먼저 펼칠 칸 */
function openZone(){ return stKey==='call'?'say':(stKey==='before'?'need':'four'); }
/* ---------- 진입 ---------- */
function renderEntry(){
const s1=$('#st-list'); s1.innerHTML='';
STATES.forEach(s=>{
const b=el('button','big'+(stKey===s.k?' on':''));
b.appendChild(el('b',null,s.t)); b.appendChild(el('span',null,s.s));
b.addEventListener('click',()=>{
stKey=s.k; ST.now.st=s.k; save(); renderEntry();
renderTut();
const p2=$('#pick2'); p2.classList.remove('off');
p2.scrollIntoView({block:'nearest',behavior:'smooth'});
});
s1.appendChild(b);
});
const s2=$('#cat-list'); s2.innerHTML='';
CATS.forEach(c=>{
const b=el('button','big'+(catKey===c.k?' on':''));
b.appendChild(el('b',null,c.t)); b.appendChild(el('span',null,c.s));
b.addEventListener('click',()=>{ if(!stKey)return; catKey=c.k; ST.now.cat=c.k; save(); openNow(); });
s2.appendChild(b);
});
$('#pick2').classList.toggle('off',!stKey);
}
$('#goCalm').addEventListener('click',()=>{show('p-chk');renderCalm();
ROOT.querySelectorAll('#calmnav button').forEach(x=>x.setAttribute('aria-selected',x.id==='t-chk'));});
ROOT.querySelectorAll('#calmnav button').forEach(b=>b.addEventListener('click',()=>{
ROOT.querySelectorAll('#calmnav button').forEach(x=>x.setAttribute('aria-selected',x===b));
show(b.dataset.p);
}));
/* 제목 클릭 → 처음 화면 */
$('#goHome').addEventListener('click',()=>{show('p-entry');renderEntry();renderTut()});
/* ---------- 튜토리얼 ---------- */
function tutGo(go){
if(go==='card'){ show('p-chk'); renderCalm();
ROOT.querySelectorAll('#calmnav button').forEach(x=>x.setAttribute('aria-selected',x.id==='t-chk'));
setTimeout(()=>{const h=$('#cardsheet'); if(!h.classList.contains('on')) $('#printCard').click();},60);
return; }
const tab={set:'t-set',case:'t-case',say:'t-say'}[go];
const pane={set:'p-set',case:'p-case',say:'p-say'}[go];
show(pane); renderCalm();
ROOT.querySelectorAll('#calmnav button').forEach(x=>x.setAttribute('aria-selected',x.id===tab));
}
function renderTut(){
const h=$('#tut'); h.innerHTML='';
let done=0;
TUTOR.forEach((o,i)=>{
const k='tut'+i, ok=!!ST.chk[k]; if(ok)done++;
const d=el('div','tut'+(ok?' on':''));
const n=el('div','tn',ok?'✓':String(i+1)); d.appendChild(n);
const mid=el('div'); mid.appendChild(el('div','tt',o.t)); mid.appendChild(el('div','td',o.d)); d.appendChild(mid);
const bw=el('div','tb');
const go=el('button','mini',o.b); go.addEventListener('click',()=>tutGo(o.go)); bw.appendChild(go);
const ck=el('button','mini',ok?'되돌리기':'완료');
ck.addEventListener('click',()=>{ST.chk[k]=!ST.chk[k];save();renderTut()}); bw.appendChild(ck);
d.appendChild(bw);
h.appendChild(d);
});
$('#tutprog').textContent=done+' / '+TUTOR.length+' 완료';
$('#tutcard').style.opacity = done===TUTOR.length ? '.72' : '';
}
/* ---------- 진행 바 ---------- */
function renderTrail(){
const h=$('#trail'); h.innerHTML='';
[[1,STMAP[stKey].t],[2,CATMAP[catKey].t],[3,'대응']].forEach((p,i)=>{
if(i) h.appendChild(el('span','sepc','▸'));
const d=el('div','tp'+(p[0]===3?' now':'')); d.appendChild(el('i',null,String(p[0]))); d.appendChild(el('span',null,p[1])); h.appendChild(d);
});
const b=el('button','chg','처음부터 다시 고르기'); b.addEventListener('click',()=>{show('p-entry');renderEntry()}); h.appendChild(b);
}
const SAYTITLE={call:'지금 전화에서 할 말',after:'회신 전화에서 먼저 할 말',pub:'추가 문의 전화에서 할 말',before:'전화가 오면 먼저 할 말'};
function sayTitle(){return SAYTITLE[stKey]||SAYTITLE.call}
/* ----
------ 빈칸 표시 ---------- */
function slotFrag(t){
const f=document.createDocumentFragment();
fill(t).split(/(\[[^\]]+\])/).forEach(sg=>{
if(/^\[.+\]$/.test(sg)) f.appendChild(el('span','slot',sg)); else f.appendChild(document.createTextNode(sg));
});
return f;
}
function slotted(t,cls){const d=el('div',cls); d.dataset.src=t; d.appendChild(slotFrag(t)); return d}
function slotP(t){const p=document.createElement('p'); p.dataset.src=t; p.appendChild(slotFrag(t)); return p}
function refreshSlots(){
ROOT.querySelectorAll('[data-src]').forEach(e=>{ const t=e.dataset.src; e.textContent=''; e.appendChild(slotFrag(t)); });
}
/* ---------- 보고용 텍스트 ---------- */
function reportText(it){
const n=ST.now||{};
const L=['[내부 보고용 — 기자 회신용 아님]',
'작성 '+(ST.d.me||'[담당자]')+' / '+(ST.d.club||'[구단명]')+' / '+(new Date()).toLocaleString('ko-KR'),
'',
'■ 받은 질문 : '+it.q,
'■ 이 질문의 성격 : '+it.why,
'■ 이 답을 말할 사람 : '+ROLE[it.role],
'']
if(n.media||n.rep||n.due) L.splice(4,0,'■ 실제 문의 : '+(n.media||'[매체]')+' '+(n.rep||'')+' / 제가 약속한 회신 '+(n.due||'[시각]'));
L.push(
'■ 답변 뼈대 — 대괄호는 확인된 수치로 채운 뒤 승인받을 것');
it.a.forEach((t,i)=>L.push(' '+(i+1)+') '+STEPLBL[i]+' — '+fill(t)));
L.push('');
L.push('■ 이 답을 하려면 확보해야 하는 것');
it.need.forEach(t=>L.push(' · '+t));
L.push('');
L.push('■ 이 질문에서 하면 안 되는 말');
it.never.forEach(t=>L.push(' × '+t));
L.push('');
L.push('※ 담당자가 기자에게 읽는 문장은 아래 한 줄뿐임');
L.push(' "'+fill(it.now)+'"');
return L.join('\n');
}
/* ---------- 질문 카드 ---------- */
function qcard(it,i){
const c=el('div','qc');
const top=el('div','qc-top');
const m=el('div','qc-meta');
m.appendChild(el('span','badge',CATMAP[it.cat].t+' '+(i+1)));
m.appendChild(el('span','badge-role '+it.role,'답하는 사람 · '+ROLE[it.role]));
top.appendChild(m);
const q=el('div','qc-q'); q.appendChild(el('i',null,'Q.')); q.appendChild(document.createTextNode(it.q)); top.appendChild(q);
const why=el('div','qc-why'); why.appendChild(el('b',null,'왜 묻는가 · ')); why.appendChild(document.createTextNode(it.why));
top.appendChild(why);
c.appendChild(top);
/* 지금 전화에서 할 말 — 항상 보임 */
const z1=el('div','zone z-say');
const h1=el('div','zhead');
h1.appendChild(el('span','zt',sayTitle()));
h1.appendChild(el('span','badge-role staff','담당이 그대로 읽어도 됨'));
z1.appendChild(h1);
z1.appendChild(slotted(it.now,'readline'));
const r1=el('div','rowbtn'); const cb1=el('button','mini','이 문장 복사');
cb1.addEventListener('click',()=>copyText(fill(it.now),cb1)); r1.appendChild(cb1);
z1.appendChild(r1);
c.appendChild(z1);
/* 공식 답변 모범안 */
const z2=document.createElement('details'); z2.className='zone'; if(openZone()==='four')z2.open=true;
const s2=document.createElement('summary'); s2.className='zhead';
s2.appendChild(el('span','zt','공식 답변 모범안 — 네 단'));
s2.appendChild(el('span','badge-role '+it.role,'말하는 사람 · '+ROLE[it.role]));
z2.appendChild(s2);
const fw=el('div','four');
it.a.forEach((t,k)=>{
const r=el('div','fr');
const fn=el('div','fn'); fn.appendChild(el('i',null,String(k+1))); fn.appendChild(el('em',null,STEPLBL[k])); r.appendChild(fn);
const box=el('div'); box.appendChild(slotP(t)); box.appendChild(el('div','fh',STEPHINT[k])); r.appendChild(box);
fw.appendChild(r);
});
z2.appendChild(fw);
z2.appendChild(el('div','disc','네 단은 승인 권한이 있는 사람이 말하는 문장임. 담당자가 기자에게 그대로 읽는 용도가 아니므로, 복사하면 머리에 「내부 보고용 — 기자 회신용 아님」이 붙어 나감. 노란 대괄호는 확인된 수치로 채운 뒤 승인을 받아야 문장이 됨.'));
const r2=el('div','rowbtn');
const cb2=el('button','mini','보고용으로 복사');
cb2.addEventListener('click',()=>copyText(reportText(it),cb2)); r2.appendChild(cb2);
const cb3=el('button','mini','창구에게 보내기');
cb3.addEventListener('click',()=>{
const s=encodeURIComponent('[보고] '+(ST.d.club||'')+' 언론 문의 — '+it.q.slice(0,24));
location.href='mailto:?subject='+s+'&body='+encodeURIComponent(reportText(it));
});
r2.appendChild(cb3);
z2.appendChild(r2);
c.appendChild(z2);
/* 필요한 숫자 */
const z3=document.createElement('details'); z3.className='zone'; if(openZone()==='need')z3.open=true;
const s3=document.createElement('summary'); s3.className='zhead';
s3.appendChild(el('span','zt','이 답을 하려면 필요한 숫자'));
s3.appendChild(el('span','badge',it.need.length+'개'));
z3.appendChild(s3);
const nw=el('div','needs'); it.need.forEach(t=>nw.appendChild(el('span',null,t))); z3.appendChild(nw);
z3.appendChild(el('p','warnmini','이 중 하나라도 지금 못 채우면, 그것이 오늘 확보해야 하는 항목임. 못 채운 상태로 네 단을 읽으면 두 번째 기사가 생김.'));
const r3=el('div','rowbtn'); const cb4=el('button','mini','요청 목록으로 복사');
cb4.addEventListener('click',()=>copyText('[자료 요청] '+it.q+'\n\n'+it.need.map((t,k)=>(k+1)+') '+t).join('\n')+'\n\n회신 희망 '+(ST.now.due||'[시각]')+' / 요청자 '+(ST.d.me||'[이름]'),cb4));
r3.appendChild(cb4); z3.appendChild(r3);
c.appendChild(z3);
/* 하면 안 되는 말 — 항상 보임 */
const z4=el('div','zone ban');
const h4=el('div','zhead'); h4.appendChild(el('span','zt','여기서 하면 안 되는 말')); z4.appendChild(h4);
const bw=el('div','bans'); it.never.forEach(t=>bw.appendChild(el('div',null,t))); z4.appendChild(bw);
c.appendChild(z4);
return c;
}
/* ---------- 모르겠음 ---------- */
function renderNone(h){
const c=el('div','qc');
const top=el('div','qc-top');
const m=el('div','qc-meta'); m.appendChild(el('span','badge','분류 전')); m.appendChild(el('span','badge-role staff','담당이 그대로 읽어도 됨'));
top.appendChild(m);
const q=el('div','qc-q'); q.appendChild(el('i',null,'Q.')); q.appendChild(document.createTextNode('무슨 질문인지 아직 모르는 상태'));
top.appendChild(q);
const why=el('div','qc-why'); why.appendChild(el('b',null,'왜 묻는가 · '));
why.appendChild(document.createTextNode('질문을 분류하지 못한 상태에서 내용을 설명하면 그 설명이 기사가 됨. 이 상태에서 할 일은 답이 아니라 질문을 정확히 받아 적는 것임.'));
top.appendChild(why); c.appendChild(top);
const z1=el('div','zone z-say');
const h1=el('div','zhead'); h1.appendChild(el('span','zt',sayTitle()+' — 순서대로')); z1.appendChild(h1);
(CARDS[chipFor()]||CARDS.call1).forEach((t,i)=>{
const d=el('div','fr'); const fn=el
('div','fn'); fn.appendChild(el('i',null,String(i+1))); fn.appendChild(el('em',null,['받기','보류','확인'][i]||'')); d.appendChild(fn);
const box=el('div'); box.appendChild(slotP(t)); d.appendChild(box);
const w=el('div'); w.style.marginTop='8px'; z1.appendChild(d);
});
const r1=el('div','rowbtn'); const cb=el('button','mini','세 문장 복사');
cb.addEventListener('click',()=>copyText((CARDS[chipFor()]||CARDS.call1).map((t,i)=>(i+1)+'. '+fill(t)).join('\n\n'),cb));
r1.appendChild(cb);
const cb2=el('button','mini','되치기 문장 보기');
cb2.addEventListener('click',()=>{ if(z1.querySelector('.cnt1')){z1.querySelector('.cnt1').remove();return}
const q=slotted(COUNTER,'readline cnt1'); z1.appendChild(q); });
r1.appendChild(cb2);
z1.appendChild(r1);
c.appendChild(z1);
const z2=document.createElement('details'); z2.className='zone'; z2.open=true;
const s2=document.createElement('summary'); s2.className='zhead'; s2.appendChild(el('span','zt','질문을 가려내는 되묻는 말')); z2.appendChild(s2);
ASK.forEach(t=>z2.appendChild(slotted(t,'readline')));
z2.appendChild(el('p','warnmini','되묻는 말은 통화에서만 씀. 문자나 보도자료에 들어가면 역질문으로 읽힘.'));
c.appendChild(z2);
const z3=el('div','zone');
const h3=el('div','zhead'); h3.appendChild(el('span','zt','질문이 잡히면 여기서 고름')); z3.appendChild(h3);
const j=el('div','jump');
CATS.filter(x=>x.k!=='none').forEach(x=>{
const b=el('button','opt',x.t); b.addEventListener('click',()=>{catKey=x.k;ST.now.cat=x.k;save();openNow()}); j.appendChild(b);
});
z3.appendChild(j); c.appendChild(z3);
h.appendChild(c);
}
/* ---------- 1번 블록 ---------- */
const QSUB={
call:'통화 중이면 각 카드의 「지금 전화에서 할 말」만 읽음. 아래 네 단은 팀장·대표가 쓰는 문장이므로 지금 읽지 않음.',
after:'회신 전이면 네 단이 펼쳐져 있음. 노란 대괄호를 채울 수 있는지 먼저 보고, 못 채우는 칸이 곧 오늘 확보할 숫자임.',
pub:'보도된 뒤에는 기사에 인용된 문장과 네 단이 어긋나지 않는지부터 봄. 어긋나면 정정 요청이 아니라 먼저 내부 확인임.',
before:'연락이 오기 전이면 「필요한 숫자」가 펼쳐져 있음. 지금 요청해 두면 전화를 받았을 때 답이 있음.'
};
function renderQ(){
const h=$('#qmainlist'); h.innerHTML='';
if(catKey==='none'){ $('#qcount').textContent=''; $('#qsub').textContent='무슨 질문인지 모를 때는 답을 찾지 않음. 질문을 그대로 받아 적는 것이 전부임.'; renderNone(h); return; }
const list=QMAIN.filter(x=>x.cat===catKey);
$('#qcount').textContent=list.length+'개 — 2026년 보도에서 반복된 질문';
$('#qsub').textContent=QSUB[stKey]||'';
if(stKey==='call') h.appendChild(firstLine());
list.forEach((it,i)=>h.appendChild(qcard(it,i)));
}
/* ---------- 통화 중 최상단 문장 ---------- */
function firstLine(){
const c=el('div','qc');
const z=el('div','zone z-say');
const h=el('div','zhead');
h.appendChild(el('span','zt','무슨 질문이든 먼저 이 문장'));
h.appendChild(el('span','badge-role staff','담당이 그대로 읽어도 됨'));
z.appendChild(h);
const t=(CARDS[chipFor()]||CARDS.call1)[0];
z.appendChild(slotted(t,'readline'));
const r=el('div','rowbtn');
const b=el('button','mini','복사'); b.addEventListener('click',()=>copyText(fill(t),b)); r.appendChild(b);
const b2=el('button','mini','보류 문장도 보기');
b2.addEventListener('click',()=>{ const ex=z.querySelector('.more2'); if(ex){ex.remove();b2.textContent='보류 문장도 보기';return}
const w=el('div','more2');
(CARDS[chipFor()]||CARDS.call1).slice(1).forEach(x=>w.appendChild(slotted(x,'readline')));
z.appendChild(w); b2.textContent='보류 문장 접기'; });
r.appendChild(b2);
z.appendChild(r);
z.appendChild(el('p','warnmini','이 문장을 읽는 동안 상대의 질문이 아래 다섯 개 중 어느 것인지 가려짐. 가려지면 그 카드만 보면 됨.'));
c.appendChild(z);
return c;
}
/* ---------- 자동 경고 ---------- */
const RISK=/억|만\s?원|예산|횡령|유용|배임|수사|압수|감사|고발|송치|기소|소환|음주|폭행|차별/;
function renderAlert(){
const a=$('#alert'); a.innerHTML='';
const n=ST.now||{}; const hit=[];
if(catKey==='money') hit.push('돈 질문임');
if(stKey==='pub') hit.push('이미 보도됨');
if(n.q&&RISK.test(n.q)) hit.push('질문에 돈·수사 관련 말이 들어 있음');
if(!hit.length) return;
const d=el('div','alertbar');
d.appendChild(el('b',null,'혼자 답하지 말 것 — 보고 먼저'));
d.appendChild(el('span',null,hit.join(' · ')+'. 위 네 단을 읽기 전에 3번의 보고 3줄을 창구 1에게 먼저 보냄. 보고 대상이 이 건의 당사자면 창구 2로 넘김.'));
const b=el('button','mini','창구 보기'); b.style.marginTop='10px';
b.addEventListener('click',()=>{ let p=d.querySelector('.ladder'); if(p){p.remove();return}
p=el('p','ladder hint','창구 1 · '+(ST.d.ch1||'비어 있음')+' / 창구 2 · '+(ST.d.ch2||'비어 있음')+' / 창구 3 · '+(ST.d.ch3||'비어 있음'));
p.style.marginTop='8px'; d.appendChild(p); });
d.appendChild(b); a.appendChild(d);
}
/* ---------- 2번 블록 ---------- */
['media','rep','back','due'].forEach(k=>{
const e=$('#f-'+k); e.value=ST.now[k]||'';
e.addEventListener('input',()=>{ST.now[k]=e.value;save();refreshSlots();renderHand()});
});
$('#f-q').value=ST.now.q||'';
$('#f-q').addEventListener('input',()=>{ST.now.q=$('#f-q').value;save();renderAlert();renderHand()});
$('#stampNow').addEventListener('click',()=>{
const d=new Date(); ST.now.stamp=('0'+d.getHours()).slice(-2)+':'+('0'+d.getMinutes()).slice(-2); save();
$('#stampOut').textContent='전화 받은 시각 '+ST.now.stamp+' 로 적음'; $('#t1').value=ST.now.stamp; renderHand();
});
if(ST.now.stamp) $('#stampOut').textContent='전화 받은 시각 '+ST.now.stamp+' 로 적음';
$('#findQ').addEventListener('click',()=>{show('p-case');renderCalm();$('#q').value=(ST.now.q||'').slice(0,12);renderCards();});
/* ---------- 3번 블록 ---------- */
function renderNotMe(){
const w=$('#notme-wrap'); w.innerHTML='';
const c=el('div','card'); const bd=el('div','card-body');
const seg=el('div','seg');
[['me','내가 창구임'],['no','내가 창구 아님']].forEach(([k,t])=>{
const b=el('button','opt',t); b.setAttribute('aria-pressed',String((ST.now.who||'me')===k));
b.addEventListener('click',()=>{ST.now.who=k;save();renderNotMe()});
seg.appendChild(b);
});
bd.appendChild(el('div','label','지금 이 사안의 대외 창구')); bd.appendChild(seg);
if((ST.now.who||'me')==='no'){
bd.appendChild(slotted(NOTME,'readline'));
const b=el('button','mini','이 문장 복사'); b.style.marginTop='10px';
b.addEventListener('click',()=>copyText(fill(NOTME),b)); bd.appendChild(b);
bd.appendChild(el('p','hint','창구가 아니면 여기까지만 함. 2번 칸만 적어 창구
에게 넘김.'));
}
c.appendChild(bd); w.appendChild(c);
}
let handTouched=false;
function renderHand(){
if(handTouched)return;
const n=ST.now||{};
const qs=(catKey&&catKey!=='none')?QMAIN.filter(x=>x.cat===catKey):[];
const L=[];
L.push('[언론 문의 보고] '+(ST.d.club||'[구단명]')+' / 작성 '+(ST.d.me||'[담당자]'));
L.push('');
L.push('1) 무엇 : '+(n.media||'[매체]')+' '+(n.rep||'[기자]')+' / 받은 시각 '+(n.stamp||'[시각]')+' / 제가 약속한 회신 '+(n.due||'[시각]'));
L.push('2) 질문 : '+(n.q||'[들은 그대로]'));
L.push('3) 제가 한 말 : 질문을 받아 적고 회신 시각만 말씀드렸음. 사실관계·입장·약속은 말하지 않았음.');
L.push('');
L.push('▸ 결정이 필요한 것 : ① 회신할지 ② 회신 시각 ③ 읽을 문장 ④ 말할 사람');
if(qs.length){
L.push('▸ 이어질 질문 ('+CATMAP[catKey].t+') : '+qs.slice(0,3).map(x=>x.q.slice(0,26)).join(' / '));
const nd=[]; qs.forEach(x=>x.need.forEach(t=>{if(nd.indexOf(t)<0)nd.push(t)}));
L.push('▸ 지금 확보해야 하는 자료 :');
nd.slice(0,8).forEach(t=>L.push(' · '+t));
}
L.push('▸ 상태 : '+(STMAP[stKey]?STMAP[stKey].t:'[상태]')+' / '+(CATMAP[catKey]?CATMAP[catKey].t:'[분류]'));
L.push('');
L.push('※ 내부 보고용 — 기자 회신용이 아님');
$('#hand').value=L.join('\n');
}
$('#hand').addEventListener('input',()=>{handTouched=true});
$('#copyHand').addEventListener('click',e=>copyText($('#hand').value,e.currentTarget));
$('#mailHand').addEventListener('click',()=>{
const s=encodeURIComponent('[보고] '+(ST.d.club||'')+' 언론 문의 '+(ST.now.media||''));
location.href='mailto:?subject='+s+'&body='+encodeURIComponent($('#hand').value);
});
/* ---------- 4번 블록 ---------- */
const TODO={
call:['통화를 끊기 전에 2번 칸을 모두 채움 — 특히 회신받을 번호',
'3번의 보고 3줄을 창구 1에게 보냄 (답하기 전에 보냄)',
'1번의 「필요한 숫자」를 가진 부서에 자료를 요청함',
'약속한 회신 시각 전에 말할 사람과 문장을 확정함',
'늦어지면 늦는다고 약속 시각 전에 먼저 연락함'],
after:['3번의 보고 3줄을 창구 1에게 보냄',
'1번의 「필요한 숫자」를 요청하고 회신 기한을 못 박음',
'네 단의 대괄호를 채워 승인권자 확인을 받음',
'약속한 시각에 회신함 — 확인 중이면 확인 중이라고 회신함',
'같은 질문이 다른 매체에서 올 것을 가정해 팀에 1번 문장을 공유함'],
pub:['기사 원문과 인용된 문장을 그대로 저장함 (화면 캡처 포함)',
'우리가 말한 것과 기사에 적힌 것이 다른 부분을 표시함',
'정정·반론 요청 여부는 승인권자가 판단하게 함 — 담당자가 결정하지 않음',
'추가 문의가 올 것을 가정해 1번 문장을 팀 전체가 같은 것으로 씀',
'1번의 「필요한 숫자」 중 기사에 없는 것을 확보해 둠'],
before:['1번의 「필요한 숫자」를 지금 요청해 둠 — 전화가 오면 늦음',
'창구 1·2 이름과 번호를 설정에 적음',
'첫 응답 문장을 팀이 같은 것으로 쓰도록 공유함',
'명함 카드를 인쇄해 가지고 다님 (평시 → 점검 → 명함 카드 보기)',
'하면 안 되는 말을 한 번 읽음']
};
const TODOSUB={call:'통화가 끝난 뒤 순서대로 함. 1번과 2번은 끊기 전에 끝나 있어야 함.',
after:'회신 시각까지 남은 시간 안에 이 순서로 함.',
pub:'보도된 뒤에는 기록이 먼저임. 정정 판단은 담당자 몫이 아님.',
before:'연락이 오기 전에 할 수 있는 것이 전부 여기 있음.'};
function renderTodo(){
const h=$('#todo'); h.innerHTML='';
$('#todosub').textContent=TODOSUB[stKey]||'';
(TODO[stKey]||TODO.call).forEach((t,i)=>{
const key='td-'+stKey+'-'+i;
const d=el('div','chk');
const ck=document.createElement('input'); ck.type='checkbox'; ck.id=key; ck.checked=!!ST.chk[key];
ck.addEventListener('change',()=>{ST.chk[key]=ck.checked;save()});
const lb=document.createElement('label'); lb.setAttribute('for',key); lb.textContent=t;
d.appendChild(ck); d.appendChild(lb); h.appendChild(d);
});
}
const APPR=[["now","지금 통화됨"],["try","연락 시도 중"],["none","연락 안 됨"]];
function segInto(host,list,key,def){
host.innerHTML='';
list.forEach(([k,t])=>{
const b=el('button','opt',t); b.setAttribute('aria-pressed',String((ST.now[key]||def)===k));
b.addEventListener('click',()=>{ST.now[key]=k;save();segInto(host,list,key,def);renderAppr()});
host.appendChild(b);
});
}
function renderAppr(){
segInto($('#appr'),APPR,'appr','try');
const o=$('#apprOut'); o.innerHTML='';
if((ST.now.appr||'try')==='none'){
const d=el('div','alertbar');
d.appendChild(el('b',null,'승인 없이 지금 보낼 수 있는 한 문장'));
d.appendChild(slotted(SAFE1,'readline'));
const b=el('button','mini','복사'); b.style.marginTop='10px'; b.addEventListener('click',()=>copyText(fill(SAFE1),b)); d.appendChild(b);
d.appendChild(el('p','hint','이 문장에는 사실 인정·부인·평가·약속이 없음. 시각과 이름만 있어 승인 없이 쓸 수 있음.'));
o.appendChild(d);
}
}
['t1','t2','t3','tlog'].forEach(k=>{const e=$('#'+k); e.value=ST.now[k]||''; e.addEventListener('input',()=>{ST.now[k]=e.value;save()})});
$('#mkReview').addEventListener('click',()=>{
const n=ST.now||{};
const L=['[사안 복기] '+(n.media||'')+' '+(n.rep||''),
'상태 분류 : '+(STMAP[stKey]?STMAP[stKey].t:'')+' / '+(CATMAP[catKey]?CATMAP[catKey].t:''),
'도구를 연 시각 : '+(n.t0||'기록 없음')+' ※ 실제 인지 시각과 다를 수 있음',
'전화 받은 시각 : '+(n.t1||'[적어 넣을 것]'),
'기자에게 처음 답한 시각 : '+(n.t2||'[적어 넣을 것]'),
'상급자 보고 시각·대상 : '+(n.t3||'[적어 넣을 것]'),
'',
'질문 : '+(n.q||''),
'내가 말한 것 :', (n.tlog||'[적어 넣을 것]'),
'',
'보도 결과 : [적어 넣을 것]',
'예상 질문 중 실제로 온 것 : [적어 넣을 것]',
'다음에 바꿀 것 한 가지 : [적어 넣을 것]',
'',
'※ 본인 확인 후 제출할 것. 자동 기록은 도구를 연 시각뿐임'];
$('#review').value=L.join('\n'); $('#review').hidden=false; $('#reviewBtns').hidden=false;
});
$('#copyReview').addEventListener('click',e=>copyText($('#review').value,e.currentTarget));
$('#mailReview').addEventListener('click',()=>{
const s=encodeURIComponent('[사안 복기] '+(ST.now.media||'')+' '+(new Date()).toLocaleDateString('ko-KR'));
location.href='mailto:?subject='+s+'&body='+encodeURIComponent($('#review').value);
});
/* ---------- 대응 화면 열기 ---------- */
function openNow(){
show('p-now');
renderTrail(); renderQ(); renderAlert(); renderNotMe(); renderHand(); renderTodo(); renderAppr();
if(!ST.now.t0){const d=new Date();ST.now.t0=d.toLocaleString('ko-KR');save()}
$('#t0').value=ST.now.t0;
}
renderEntry();
renderTut();
/* ---------- 평시 ---------- */
let calmDone=false;
function renderCalm(){ if(calmDone)return; calmDone=true;
/* 점검 */
const c=$('#chk10');
CHECK10.forEach(([t,h],i)=>{
const d=el('div','chk');
const ck=document.createElement('input'); ck.type='checkbox'; ck.id='c10-'+i; ck.checked=!!ST.chk['c'+i];
ck.addEventListener('change',()=>{ST.chk['c'+i]=ck.checked;ST.chk.when=new Date().toISOString().slice(0,10);save();renderSummary()});
const lb=document.createElement('label');
lb.setAttribute('for',ck.id); lb.appendChild(document.createTextNode(t));
if(h) lb.appendChild(el('span','sm',h));
d.appendChild(ck); d.appendChild(lb); c.appendChild(d);
});
/* 문장함 */
const ac=$('#allcards');
CHIPS.forEach(ch=>{
const w=el('div'); w.style.marginBottom='18px';
w.appendChild(el('div','label',ch.t));
CARDS[ch.k].forEach((t,i)=>{
const d=el('div','say'); const l=el('div');
l.appendChild(el('b',null,['지금 읽을 문장','더 밀면 읽을 문장','끊기 전 마지막 문장'][i]));
l.appendChild(el('p',null,fill(t))); d.appendChild(l);
const b=el('button','mini','복사'); b.addEventListener('click',()=>copyText(fill(t),b)); d.appendChild(b);
w.appendChild(d);
});
ac.appendChild(w);
});
const aa=$('#askAll');
ASK.forEach(t=>{const d=el('div','say');const l=el('div');l.appendChild(el('p',null,fill(t)));d.appendChild(l);aa.appendChild(d)});
const ca=$('#confirmAll');
CONFIRM.forEach(t=>{const d=el('div','say');const l=el('div');l.appendChild(el('p',null,fill(t)));d.appendChild(l);
const b=el('button','mini','복사');b.addEventListener('click',()=>copyText(fill(t),b));d.appendChild(b);ca.appendChild(d)});
const sw=$('#swap');
SWAP.forEach(([a,b])=>{
const d=el('div','say'); const l=el('div');
const t=el('b',null,'"'+a+'"'); t.style.color='var(--gold)'; l.appendChild(t);
l.appendChild(el('p',null,'→ '+fill(b))); d.appendChild(l);
const btn=el('button','mini','복사'); btn.addEventListener('click',()=>copyText(fill(b),btn)); d.appendChild(btn);
sw.appendChild(d);
});
/* 질문 */
const four=$('#four');
[["1 인정","사실과 수치를 먼저 확인함"],["2 조치","이미 한 것과 기한이 있는 것"],["3 근거","검증 가능한 숫자 한두 개만"],["4 전달","누가 언제 답하는지만 말함 — 약속은 담당자 몫이 아님"]]
.forEach(([a,b])=>{const d=el('div','step');d.appendChild(el('div','when',a));const r=el('div');r.appendChild(el('h3',null,b));d.appendChild(r);four.appendChild(d)});
const ql=$('#qalist');
QA.forEach(g=>{
const box=el('div','qgrp');
const hd=el('div','qgrp-head');
const ck=document.createElement('input'); ck.type='checkbox'; ck.id='qg-'+g.k; ck.checked=!!ST.chk['qa-'+g.k];
const lbw=el('div'); const lb=document.createElement('label'); lb.setAttribute('for',ck.id);
lb.appendChild(el('h3',null,g.t));
lb.appendChild(el('div','hint','예상 질문 '+g.items.length+'개 · 체크하면 보완 중 항목으로 표시됨'));
lbw.appendChild(lb); hd.appendChild(ck); hd.appendChild(lbw); box.appendChild(hd);
const bd=el('div','qgrp-body');
g.items.forEach(it=>{
const row=el('div','qrow');
const top=el('div','itemtop'); top.appendChild(el('span','badge-role '+(it.role||'lead'),'말하는 사람 '+ROLE[it.role||'lead']));
row.appendChild(top);
row.appendChild(el('div','qq','Q. '+it.q));
row.appendChild(el('div','ql','논리 — '+it.l));
const line=el('div','qs'); line.appendChild(el('div','quote',it.s));
const cb=el('button','mini','보고용으로 복사');
cb.addEventListener('click',()=>copyText('[내부 보고용 — 기자 회신용 아님]\n'+it.s,cb));
line.appendChild(cb); row.appendChild(line); bd.appendChild(row);
});
const gap=el('div','gap'); gap.hidden=!ck.checked;
const gl=document.createElement('label'); gl.setAttribute('for','gap-'+g.k); gl.textContent='이 갈래에서 지금 채울 수 없는 숫자 — 쉼표로 구분';
const gi=document.createElement('input'); gi.type='text'; gi.id='gap-'+g.k; gi.value=ST.gap[g.k]||'';
gi.placeholder='예: 자체수익 비중, 유소년 예산 비율';
gi.addEventListener('input',()=>{ST.gap[g.k]=gi.value;save();renderSummary()});
gap.appendChild(gl); gap.appendChild(gi); bd.appendChild(gap);
ck.addEventListener('change',()=>{ST.chk['qa-'+g.k]=ck.checked;save();gap.hidden=!ck.checked;renderSummary()});
box.appendChild(bd); ql.appendChild(box);
});
/* 설정 */
const dg=$('#dict');
DICT.forEach(([k,label,ph])=>{
const l=el('label','fld'); l.appendChild(document.createTextNode(label));
const i=document.createElement('input'); i.type='text'; i.placeholder=ph; i.value=ST.d[k]||'';
i.addEventListener('input',()=>{ST.d[k]=i.value;save()});
l.appendChild(i); dg.appendChild(l);
});
const rs=$('#roleSel');
[['staff','담당'],['lead','팀장'],['exec','대표·법무']].forEach(([k,t])=>{
const b=el('button','opt',t); b.setAttribute('aria-pressed',String((ST.role||'staff')===k));
b.addEventListener('click',()=>{ST.role=k;save();rs.querySelectorAll('.opt').forEach(x=>x.setAttribute('aria-pressed','false'));b.setAttribute('aria-pressed','true')});
rs.appendChild(b);
});
renderCards(); renderSummary(); buildCardSheet();
}
/* 사례 */
function cardEl(c){
const b=el('button','item');
const top=el('div','itemtop');
top.appendChild(el('span','badge',AXNAME[c.ax]));
if(c.spdL)top.appendChild(el('span','spd '+(c.spd||'flat'),c.spdL));
const nq=(QCASE[c.id]||[]).length; if(nq) top.appendChild(el('span','badge','예상 질문 '+nq));
b.appendChild(top); b.appendChild(el('h3',null,c.t)); b.appendChild(el('p',null,c.what));
b.addEventListener('click',()=>openCase(c));
return b;
}
let ax='all';
function renderCards(){
const q=($('#q').value||'').trim().toLowerCase();
const list=CASES.filter(c=>(ax==='all'||c.ax===ax) && (!q || (c.t+c.what+c.say+c.split.join(' ')).toLowerCase().includes(q)));
const g=$('#cards'); g.innerHTML='';
list.forEach(c=>g.appendChild(cardEl(c)));
$('#cnt').textContent=list.length+'건'+(ax==='all'?'':' · '+AXNAME[ax])+(q?' · "'+q+'" 검색':'');
if(!list.length) g.appendChild(el('p','hint','해당하는 상황이 없음.'));
}
ROOT.querySelectorAll('.filters .opt').forEach(c=>c.addEventListener('click',()=>{
ax=c.dataset.ax; ROOT.querySelectorAll('.filters .opt').forEach(x=>x.setAttribute('aria-pressed',x===c)); renderCards();
}));
$('#q').addEventListener('input',renderCards);
let sheetEl=null;
function openCase(c){
closeCase();
const ov=el('div','detail'); ov.addEventListener('click',e=>{if(e.target===ov)closeCase()});
const sh=el('div','sheet');
const cl=el('button','close','닫기'); cl.addEventListener('click',closeCase); sh.appendChild(cl);
co
nst top=el('div','itemtop');
top.appendChild(el('span','badge',AXNAME[c.ax]));
if(c.spdL)top.appendChild(el('span','spd '+(c.spd||'flat'),c.spdL));
sh.appendChild(top); sh.appendChild(el('h3',null,c.t));
const s1=el('div','sec'); s1.appendChild(el('div','label','무슨 일이었나'));
const p1=el('p',null,c.what); p1.style.cssText='font-size:13px;color:var(--fg2);line-height:1.7'; s1.appendChild(p1); sh.appendChild(s1);
const s2=el('div','sec'); s2.appendChild(el('div','label','어디서 갈렸나'));
const u2=el('ul'); c.split.forEach(t=>u2.appendChild(el('li',null,t))); s2.appendChild(u2); sh.appendChild(s2);
const s3=el('div','sec'); s3.appendChild(el('div','label','다시 생기면'));
const wr=el('div','scroller'); const tb=el('table','tbl'); const tb2=document.createElement('tbody');
c.steps.forEach(([w,d])=>{const tr=document.createElement('tr');const a=el('td',null,w);const b2=el('td',null,d);b2.style.whiteSpace='normal';tr.appendChild(a);tr.appendChild(b2);tb2.appendChild(tr)});
tb.appendChild(tb2); wr.appendChild(tb); s3.appendChild(wr); sh.appendChild(s3);
const qs=QCASE[c.id]||[];
if(qs.length){
const sq=el('div','sec'); sq.appendChild(el('div','label','이때 기자가 물어볼 것'));
qs.forEach(it=>{
const row=el('div','qrow');
row.appendChild(el('div','qq','Q. '+it.q));
row.appendChild(el('div','ql','논리 — '+it.l));
const line=el('div','qs'); line.appendChild(el('div','quote',it.s));
const cb=el('button','mini','보고용으로 복사');
cb.addEventListener('click',()=>copyText('[내부 보고용 — 기자 회신용 아님]\n'+it.s,cb));
line.appendChild(cb); row.appendChild(line); sq.appendChild(row);
});
sh.appendChild(sq);
}
const s4=el('div','sec');
s4.appendChild(el('div','label',(c.kind==='procedure'?'안내 문장':'입장 문장 · 말하는 사람 '+ROLE[c.role||'lead'])));
s4.appendChild(el('div','quote',c.say));
const cp=el('button','mini',c.kind==='procedure'?'복사':'보고용으로 복사'); cp.style.marginTop='10px';
cp.addEventListener('click',()=>copyText((c.kind==='procedure'?'':'[내부 보고용 — 기자 회신용 아님]\n')+c.say,cp));
s4.appendChild(cp);
if(c.kind!=='procedure') s4.appendChild(el('p','hint','이 문장은 담당자가 전화에서 읽는 문장이 아님. 승인 권한이 있는 사람에게 전달할 때 씀.'));
sh.appendChild(s4);
const s5=el('div','sec'); s5.appendChild(el('div','label','미리 만들어 둘 것'));
const u5=el('ul'); c.prep.forEach(t=>u5.appendChild(el('li',null,t))); s5.appendChild(u5); sh.appendChild(s5);
const mark=el('div','chk'); mark.style.cssText='margin-top:20px;padding-top:16px';
const ck=document.createElement('input'); ck.type='checkbox'; ck.id='mk-'+c.id; ck.checked=!!ST.chk['case-'+c.id];
ck.addEventListener('change',()=>{ST.chk['case-'+c.id]=ck.checked;save();renderSummary()});
const lb=document.createElement('label'); lb.setAttribute('for',ck.id); lb.textContent='우리 팀에 해당함 — 표시해 두기';
mark.appendChild(ck); mark.appendChild(lb); sh.appendChild(mark);
ov.appendChild(sh); ROOT.appendChild(ov); sheetEl=ov; cl.focus();
}
function closeCase(){ if(sheetEl){sheetEl.remove();sheetEl=null;} }
document.addEventListener('keydown',e=>{if(e.key==='Escape')closeCase()});
/* 요약 */
function tile(cap,big,unit,foot,pct){
const d=el('div','tile'); d.appendChild(el('div','cap',cap));
const b=el('div','big2'); b.appendChild(document.createTextNode(String(big)));
if(unit){const em=document.createElement('em');em.textContent=unit;b.appendChild(em)} d.appendChild(b);
if(pct!==undefined){const m=el('div','meter');const s=document.createElement('span');s.style.width=Math.max(0,Math.min(100,pct))+'%';m.appendChild(s);d.appendChild(m)}
if(foot) d.appendChild(el('div','foot',foot)); return d;
}
function renderSummary(){
const done=CHECK10.filter((w,i)=>ST.chk['c'+i]).length;
const hits=CASES.filter(c=>ST.chk['case-'+c.id]);
const weak=QA.filter(g=>ST.chk['qa-'+g.k]);
const gaps=[]; weak.forEach(g=>{const v=(ST.gap[g.k]||'').trim(); if(v) v.split(/[,·]/).map(x=>x.trim()).filter(Boolean).forEach(x=>gaps.push([g.t,x]))});
const T=$('#tiles'); if(!T) return; T.innerHTML='';
T.appendChild(tile('점검 항목',done,'/ '+CHECK10.length, ST.chk.when?('마지막 점검 '+ST.chk.when.replace(/-/g,'. ')+'.'):'아직 점검 안 함', Math.round(done/CHECK10.length*100)));
T.appendChild(tile('확보해야 할 숫자',gaps.length,'건',gaps.length?'담당 부서에 요청할 항목':'적어 둔 항목 없음'));
T.appendChild(tile('해당한다고 본 상황',hits.length,'건',hits.length?'대응 순서 확인함':'표시한 상황 없음'));
T.appendChild(tile('보완 중 질문 갈래',weak.length,'/ '+QA.length,weak.length?'예상 질문 대비 필요':'선택한 갈래 없음'));
const L=[];
L.push('[위기 대응 준비] '+(ST.d.club||'우리 구단')+' 홍보 — '+(ST.chk.when||new Date().toISOString().slice(0,10)).replace(/-/g,'. ')+'. 기준');
L.push('1. 점검 '+done+'/'+CHECK10.length+' 완료'+(done<CHECK10.length?(' — 남은 것: '+CHECK10.filter((w,i)=>!ST.chk['c'+i]).map(w=>w[0]).join(', ')):''));
L.push('2. 지금 답할 수 없는 숫자 '+gaps.length+'건'+(gaps.length?' — '+gaps.map(g=>g[1]).join(', '):''));
L.push('3. 우리에게 해당하는 상황 '+hits.length+'건'+(hits.length?' — '+hits.map(c=>c.t).join(' / '):''));
L.push('※ 내부 검토용');
const w=$('#weekly'); if(w) w.value=L.join('\n');
}
$('#copyWeekly').addEventListener('click',e=>copyText($('#weekly').value,e.currentTarget));
$('#printCard').addEventListener('click',e=>{
const h=$('#cardsheet'); h.classList.toggle('on');
e.currentTarget.textContent=h.classList.contains('on')?'명함 카드 닫기':'명함 카드 보기';
if(h.classList.contains('on')) h.scrollIntoView({block:'nearest',behavior:'smooth'});
});
/* 명함 카드 */
function buildCardSheet(){
const host=$('#cardsheet'); host.innerHTML='';
const d=ST.d||{};
const front=`<h4>전화를 받으면 — 읽을 순서</h4>
<ol><li>${fill(CARDS.call1[0])}</li><li>${fill(CARDS.call1[1])}</li><li>${fill(CARDS.call1[2])}</li></ol>
<div class="ft">되치기 : 제가 말씀드린 것은 확인된 것이 없다는 것이고, 그 사실이 있다고 말씀드린 것이 아닙니다.</div>`;
const back=`<h4>끊기 전에 받아둘 것 / 하지 않는 말</h4>
<ul><li>매체 · 기자 이름 · 회신 번호 · 마감 시각 · 질문 그대로</li></ul>
<b>창구 1</b> <span class="ln">${d.ch1||''}</span> <b>창구 2</b> <span class="ln">${d.ch2||''
}</span>
<ul style="margin-top:1mm"><li>확인해 보겠습니다 → ○시까지 확인해 회신드리겠습니다</li>
<li>드릴 말씀이 없습니다 → 확인된 것이 없어 답을 드릴 수 없습니다</li>
<li>다른 구단도 같습니다 / 개인의 일탈입니다 / 사실무근입니다 — 쓰지 않음</li></ul>
<div class="ft">${d.club||'[구단명]'} 홍보 ${d.me||'[이름]'} · 기업홍보연구원</div>`;
for(let i=0;i<4;i++){ host.insertAdjacentHTML('beforeend','<div class="namecard">'+front+'</div><div class="namecard">'+back+'</div>'); }
}
/* 기준일 경과 알림 */
(function(){ const base=new Date('2026-09-30');
if((Date.now()-base.getTime())/864e5>180){
const b=el('div','topwarn'); b.style.borderColor='var(--gold-line)'; b.style.background='var(--gold-soft)';
b.textContent='자료 기준일에서 6개월이 지났음. 사례와 질문이 최신이 아닐 수 있음.';
ROOT.querySelector('header .wrap').appendChild(b);
}})();
show('p-entry');
booted=true;