/* =========================================================
   Tools › PHP 라우터 사이트 보안 팁 (/tools/php-router-security)
   원본: 글(Markdown) → 블로그 레이아웃 안의 읽는 화면. 다른 Tools 와 같은 흰 바탕 · 형광펜 · 블로그 글꼴
   - 모든 규칙은 .prs 아래에만 걸린다 (블로그 blog.css 와 섞이지 않게). 키프레임 이름은 prs-*
   - layout: 왼쪽 고정 목차 + 오른쪽 본문 (1100px 아래는 목차가 본문 위 가로 줄로)
   - 빨간색(--bad)은 '요청이 막히는 곳'에만, 형광펜(--hl)은 요청문에서 바뀌는 칸과 머리글에만 칠한다
========================================================= */
.prs{
  --prs-top:116px;
  --paper:#f6f6f4;--card:#fff;--ink:#15191d;--muted:#6b7279;--line:#e3e5e2;--line2:#d5d8d4;
  --hl:#ffe24d;--hl-ink:#15191d;--loc:#2563eb;--bad:#d1394f;--good:#0f9f7b;--code-bg:#f6f6f4;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  --r:12px;
  color-scheme:light;color:var(--ink);
}
.prs [hidden]{display:none!important}
.prs *,.prs *::before,.prs *::after{box-sizing:border-box}
.prs a{color:var(--loc)}
.prs button,.prs input{font:inherit;color:inherit}
.prs :focus-visible{outline:2px solid var(--loc);outline-offset:2px}
.prs code,.prs pre,.prs .mono{font-family:var(--mono)}
.prs code{font-size:.88em;background:var(--code-bg);border:1px solid var(--line);border-radius:4px;padding:1px 5px;overflow-wrap:anywhere}

/* 대표 영역 (블로그 .hero 틀 + 형광펜) */
.prs .hero h1,.prs .hero-description{word-break:keep-all}
.prs .hero h1{text-wrap:balance}
.prs .hl-sweep{background-image:linear-gradient(var(--hl),var(--hl));background-repeat:no-repeat;background-position:0 88%;background-size:100% 42%;padding:0 2px;animation:prs-sweep 900ms 250ms cubic-bezier(.3,.7,.3,1) both}
@keyframes prs-sweep{from{background-size:0% 42%}to{background-size:100% 42%}}
.prs .hero-description{margin-bottom:22px}
.prs .hero-description code{background:#fff}
.prs .facts{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px 24px;font-size:14px;color:#3d444b}
.prs .facts li{display:flex;align-items:baseline;gap:4px}
.prs .facts b{font-family:var(--font-display);font-size:24px;color:var(--ink);font-variant-numeric:tabular-nums}

/* 목차 + 본문 */
.prs .prs-body{display:grid;grid-template-columns:200px minmax(0,1fr);gap:56px;align-items:start;padding:44px 0 8px}
.prs .prs-main{min-width:0}
.prs .toc{position:sticky;top:calc(var(--prs-top) + 24px);transition:top .25s ease;font-size:13.5px}
.prs .toc-h{margin:0 0 10px;font-size:12px;font-weight:700;letter-spacing:.06em;color:var(--muted)}
.prs .toc ol{list-style:none;margin:0;padding:0;display:grid;gap:2px;border-left:1px solid var(--line)}
.prs .toc a{display:flex;gap:8px;align-items:baseline;padding:5px 0 5px 14px;margin-left:-1px;border-left:2px solid transparent;color:var(--muted);line-height:1.45;text-decoration:none;word-break:keep-all}
.prs .toc a:hover{color:var(--ink)}
.prs .toc a[aria-current="true"]{color:var(--ink);font-weight:600;border-left-color:var(--ink)}
.prs .toc .n{flex:none;font:600 11px var(--mono);color:var(--muted);width:12px}

/* 구역 */
.prs .pr-sec{padding:44px 0 8px;border-top:1px solid var(--line);margin-top:28px;scroll-margin-top:calc(var(--prs-top) + 16px)}
.prs .pr-sec.first{padding-top:0;border-top:0;margin-top:0}
.prs .sec-h{margin-bottom:18px}
.prs .kicker{margin:0 0 6px;font-size:12px;font-weight:700;letter-spacing:.06em;color:var(--muted)}
.prs .sec-h h2{font-family:var(--font-display);font-weight:700;font-size:28px;line-height:1.3;letter-spacing:-.02em;margin:0;text-wrap:balance;word-break:keep-all}

/* 읽는 글 */
.prs .prose{max-width:780px;font-size:15.5px;line-height:1.85;color:#2b3137;word-break:keep-all;overflow-wrap:break-word}
.prs .prose p{margin:0 0 16px}
.prs .prose h3{font-family:var(--font-display);font-size:19px;font-weight:700;letter-spacing:-.01em;margin:36px 0 12px;color:var(--ink)}
.prs .prose ul,.prs .prose ol{margin:0 0 18px;padding-left:22px}
.prs .prose li+li{margin-top:6px}
.prs .prose b{color:var(--ink)}
.prs .prose ol.rules{padding-left:0;list-style:none;counter-reset:rule;display:grid;gap:10px}
.prs .prose ol.rules li{counter-increment:rule;position:relative;padding-left:34px;margin:0}
.prs .prose ol.rules li::before{content:counter(rule);position:absolute;left:0;top:3px;width:22px;height:22px;border-radius:50%;display:grid;place-items:center;font:600 12px var(--mono);background:var(--ink);color:#fff}
.prs .callout{margin:22px 0;padding:14px 18px;background:var(--paper);border-left:3px solid var(--hl);border-radius:0 8px 8px 0;font-size:14.5px;line-height:1.8}
.prs .prose .callout:last-child{margin-bottom:8px}

/* 코드 상자 */
.prs .code{margin:18px 0 22px;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--code-bg)}
.prs .code figcaption{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:38px;padding:5px 8px 5px 14px;border-bottom:1px solid var(--line);background:var(--card);font-size:12px;font-weight:600;color:var(--muted)}
.prs .code pre{margin:0;padding:14px 16px;overflow:auto;font-size:12.5px;line-height:1.7;color:var(--ink);tab-size:4;word-break:normal}
.prs .code pre code{background:none;border:0;padding:0;font-size:inherit;border-radius:0;overflow-wrap:normal;white-space:pre}
.prs .code .c{color:#858b91}
.prs .copy{flex:none;border:1px solid var(--line2);background:var(--card);border-radius:6px;padding:3px 10px;font-size:12px;font-weight:600;cursor:pointer;color:#3d444b}
.prs .copy:hover{border-color:var(--ink);color:var(--ink)}
.prs .copy.done{background:var(--ink);border-color:var(--ink);color:#fff}

/* 표 */
.prs .tbl-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:8px;margin:18px 0 22px}
.prs table{width:100%;border-collapse:collapse;font-size:13.5px;line-height:1.6}
.prs th,.prs td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--line);vertical-align:top}
.prs tr:last-child td{border-bottom:0}
.prs th{font-size:12px;color:var(--muted);font-weight:600;background:var(--paper);white-space:nowrap}
.prs td:first-child{font-weight:600;color:var(--ink)}

/* 단추 · 고르기 */
.prs .lbl{font-size:13px;font-weight:600;color:#3d444b}
.prs .seg{display:inline-flex;border:1px solid var(--line2);border-radius:8px;overflow:hidden;flex-wrap:wrap}
.prs .seg button{border:0;background:var(--card);padding:6px 14px;font-size:13px;cursor:pointer}
.prs .seg button+button{border-left:1px solid var(--line2)}
.prs .seg button[aria-pressed="true"]{background:var(--ink);color:#fff}
.prs .btn-primary{background:var(--hl);color:var(--hl-ink);border:1px solid transparent;border-radius:8px;padding:10px 18px;font-weight:700;font-size:14px;cursor:pointer;box-shadow:0 1px 0 rgba(0,0,0,.18)}
.prs .btn-primary:hover{filter:brightness(.96)}
.prs .btn-ghost{background:var(--card);border:1px solid var(--line2);border-radius:8px;padding:6px 12px;font-size:13px;cursor:pointer;color:#3d444b}
.prs .btn-ghost:hover{border-color:var(--ink);color:var(--ink)}
.prs .srv-bar{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:30px 0 -14px}
.prs .srv h3{margin-top:30px}

/* 요청 흐름 */
.prs .flow-box{margin-top:26px;padding:20px;border:1px solid var(--line);border-radius:14px;background:var(--paper)}
.prs .flow-h{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;margin-bottom:14px}
.prs .flow-h b{font-family:var(--font-display);font-size:18px}
.prs .flow-h span{font-size:13px;color:var(--muted)}
.prs .reqs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:18px}
.prs .req{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line2);background:var(--card);border-radius:999px;padding:4px 12px 4px 5px;font-size:12.5px;line-height:1.4;cursor:pointer;color:#3d444b}
.prs .req:hover{border-color:var(--ink);color:var(--ink)}
.prs .req .m{font:700 10.5px/1 var(--mono);padding:4px 6px;border-radius:999px;background:var(--paper);color:var(--muted)}
.prs .req .m.post{background:#fff1d6;color:#8a5a00}
.prs .req .p{font-family:var(--mono)}
.prs .req .w{color:var(--muted);font-size:12px}
.prs .req[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
.prs .req[aria-pressed="true"] .m{background:rgba(255,255,255,.16);color:#fff}
.prs .req[aria-pressed="true"] .w{color:rgba(255,255,255,.7)}

.prs .flow{display:grid;grid-template-columns:minmax(0,.9fr) 22px minmax(0,1fr) 22px minmax(0,1fr) 22px minmax(0,1fr) 22px minmax(0,.9fr);align-items:stretch}
.prs .stage{position:relative;display:flex;flex-direction:column;gap:2px;min-width:0;padding:12px 12px 12px 14px;background:var(--card);border:1px solid var(--line);border-radius:10px;transition:border-color .2s,background .2s,box-shadow .2s,opacity .2s}
.prs .stage.check::before{content:"";position:absolute;left:-1px;top:12px;bottom:12px;width:3px;border-radius:0 3px 3px 0;background:var(--bad);opacity:.35;transition:opacity .2s,top .2s,bottom .2s,width .2s}
.prs .st-k{font-size:11px;font-weight:700;letter-spacing:.02em;color:var(--muted);padding-right:34px}
.prs .stage.check .st-k{color:var(--bad)}
.prs .st-name{font-family:var(--font-display);font-size:16px;line-height:1.4}
.prs .st-sub{font-size:12.5px;color:#3d444b;overflow-wrap:anywhere}
.prs .st-sub.mono{font-size:12px}
.prs .st-what{margin-top:4px;font-size:11.5px;line-height:1.5;color:var(--muted);word-break:keep-all}
.prs .st-mark{position:absolute;top:9px;right:9px;font:700 11px/1 var(--mono);padding:4px 7px;border-radius:999px}
.prs .stage.is-pass{border-color:var(--good)}
.prs .stage.is-pass .st-mark{background:#e3f6f0;color:var(--good)}
.prs .stage.is-stop{border-color:var(--bad);background:#fff7f8;box-shadow:0 0 0 3px rgba(209,57,79,.12)}
.prs .stage.is-stop::before{opacity:1;top:-1px;bottom:-1px;width:5px;border-radius:10px 0 0 10px}
.prs .stage.is-stop .st-mark{background:var(--bad);color:#fff}
.prs .stage.is-done{border-color:var(--good);background:#f2fbf8;box-shadow:0 0 0 3px rgba(15,159,123,.12)}
.prs .stage.is-done .st-mark{background:var(--good);color:#fff}
.prs .stage.is-skip{opacity:.42}
.prs .arw{position:relative;align-self:center;height:2px;margin:0 5px 0 3px;background:var(--line2);transition:background .2s}
.prs .arw::after{content:"";position:absolute;right:-5px;top:-4px;border:5px solid transparent;border-right:0;border-left:6px solid var(--line2);transition:border-color .2s}
.prs .arw.is-on{background:var(--good)}
.prs .arw.is-on::after{border-left-color:var(--good)}
.prs .arw.is-cut{background:repeating-linear-gradient(90deg,var(--line2) 0 4px,transparent 4px 8px)}
.prs .arw.is-cut::after{opacity:.5}

.prs .flow-out{margin-top:16px;min-height:118px;padding:14px 16px;background:var(--card);border:1px solid var(--line);border-radius:10px;font-size:14px;line-height:1.75}
.prs .flow-out:empty{display:none}
.prs .res-h{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}
.prs .res-code{font:700 12px/1 var(--mono);padding:5px 8px;border-radius:6px;color:#fff;background:var(--bad)}
.prs .res-code.ok{background:var(--good)}
.prs .res-h b{font-size:15px}
.prs .res-t{color:var(--muted);font-size:13px}
.prs .res-line{margin:6px 0 2px;font-size:12.5px;color:#3d444b;overflow-wrap:anywhere}
.prs .res-why{margin:0;color:#2b3137;word-break:keep-all}
.prs .res-tip{display:inline-block;margin-top:6px;font-size:13px;font-weight:600;text-decoration:none}
.prs .res-tip:hover{text-decoration:underline;text-underline-offset:3px}
.prs .flow-legend{display:flex;gap:9px;align-items:baseline;margin:14px 0 0;font-size:13px;line-height:1.7;color:var(--muted);word-break:keep-all}
.prs .flow-legend .sw{flex:none;width:4px;height:14px;border-radius:2px;background:var(--bad);transform:translateY(2px)}

/* 체크리스트 */
.prs .card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:20px 22px;margin:4px 0 22px;max-width:780px}
.prs .site-row{display:grid;gap:6px;padding-bottom:16px;margin-bottom:4px;border-bottom:1px solid var(--line)}
.prs .site-row input{width:100%;max-width:420px;background:var(--paper);border:1px solid var(--line2);border-radius:8px;padding:9px 12px;font-family:var(--mono);font-size:14px;outline:none}
.prs .site-row input:focus{border-color:var(--loc);background:#fff;box-shadow:0 0 0 3px rgba(37,99,235,.12)}
.prs .hint{margin:0;font-size:12.5px;line-height:1.6;color:var(--muted);word-break:keep-all}
.prs .ck-card h3{margin:18px 0 6px;font-size:13px;font-weight:700;color:var(--muted)}
.prs .checklist{list-style:none;margin:0;padding:0}
.prs .checklist li{padding:8px 0;border-bottom:1px dashed var(--line);font-size:14.5px;line-height:1.65}
.prs .checklist li:last-child{border-bottom:0}
.prs .checklist label{display:flex;gap:10px;align-items:flex-start;cursor:pointer;word-break:keep-all}
.prs .checklist input{flex:none;width:18px;height:18px;margin:3px 0 0;accent-color:var(--ink);cursor:pointer}
.prs .checklist li.is-done span{color:var(--muted)}
.prs .ck-links{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 0 28px}
.prs .ck-links a{font:12px/1.4 var(--mono);padding:3px 9px;border:1px solid var(--line2);border-radius:999px;text-decoration:none;background:var(--card)}
.prs .ck-links a:hover{border-color:var(--loc)}
.prs .ck-foot{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
.prs .meter{flex:1 1 160px;max-width:240px;height:6px;border-radius:999px;background:var(--paper);overflow:hidden}
.prs .meter span{display:block;height:100%;width:0;background:var(--good);border-radius:inherit;transition:width .25s ease}
.prs .progress{font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums}
.prs #ck-reset{margin-left:auto}

/* 점검 요청문 */
.prs .pr-controls{display:flex;flex-wrap:wrap;gap:12px 22px;margin-bottom:14px}
.prs .pr-ctl{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.prs #prompt-out{margin:0;padding:14px 16px;max-height:460px;overflow:auto;font-size:12.5px;line-height:1.7;background:var(--code-bg);border:1px solid var(--line);border-radius:8px;white-space:pre-wrap;overflow-wrap:anywhere;color:var(--ink)}
.prs #prompt-out [data-p]{background:rgba(255,226,77,.6);border-radius:3px}
.prs .copybar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px}
.prs .count{font-size:12.5px;color:var(--muted);font-variant-numeric:tabular-nums}

.prs .prs-foot{max-width:780px;padding:32px 0 8px;margin:36px 0 0;border-top:1px solid var(--line);color:var(--muted);font-size:13px;line-height:1.8;word-break:keep-all}
.prs .ad-slot{max-width:780px}

.prs .toast{position:fixed;left:50%;bottom:28px;transform:translateX(-50%) translateY(20px);opacity:0;background:var(--ink);color:#fff;padding:9px 16px;border-radius:8px;font-size:13.5px;transition:opacity .2s,transform .2s;pointer-events:none;z-index:1600;max-width:calc(100vw - 32px)}
.prs .toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

@media (max-width:1100px){
  .prs .prs-body{grid-template-columns:minmax(0,1fr);gap:0;padding-top:24px}
  .prs .toc{position:static;margin:0 -24px 32px;padding:0 24px;overflow-x:auto;scrollbar-width:none}
  .prs .toc::-webkit-scrollbar{display:none}
  .prs .toc-h{display:none}
  .prs .toc ol{display:flex;gap:6px;border-left:0;white-space:nowrap}
  .prs .toc a{padding:6px 12px;margin:0;border:1px solid var(--line2);border-radius:999px;color:#3d444b;font-size:13px}
  .prs .toc a[aria-current="true"]{border-color:var(--ink);font-weight:400}
}
@media (max-width:900px){
  .prs .toc{margin:0 -16px 28px;padding:0 16px}   /* 블로그 .wrap 여백이 16px 로 줄어드는 폭 */
}
@media (max-width:860px){
  .prs .flow{grid-template-columns:minmax(0,1fr)}
  .prs .arw{justify-self:start;width:2px;height:18px;margin:3px 0 5px 24px}
  .prs .arw::after{right:auto;left:-4px;top:auto;bottom:-5px;border:5px solid transparent;border-bottom:0;border-top:6px solid var(--line2)}
  .prs .arw.is-on::after{border-left-color:transparent;border-top-color:var(--good)}
  .prs .arw.is-cut{background:repeating-linear-gradient(180deg,var(--line2) 0 4px,transparent 4px 8px)}
  .prs .stage{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:10px;align-items:baseline}
  .prs .st-k{grid-column:1/-1}
  .prs .st-what{grid-column:1/-1;margin-top:0}
}
@media (max-width:640px){
  .prs .sec-h h2{font-size:23px}
  .prs .prose{font-size:15px}
  .prs .flow-box{padding:16px;margin-left:-4px;margin-right:-4px}
  .prs .card{padding:16px}
  .prs .code pre{font-size:12px;padding:12px 14px}
  .prs table{font-size:13px}
  .prs th,.prs td{padding:8px 10px}
  .prs .copybar{flex-direction:column;align-items:stretch}
  .prs .copybar .btn-primary{width:100%}
  .prs .facts b{font-size:21px}
}
@media (prefers-reduced-motion:reduce){
  .prs .hl-sweep{animation:none}
  .prs .stage,.prs .stage::before,.prs .arw,.prs .arw::after,.prs .meter span,.prs .toast,.prs .toc{transition:none}
}
