:root{
  --bg:#f5f4f0; --surface:#fbfbf9; --panel:#ffffff; --panel-soft:#f7f6f2;
  --ink:#1c1c1a; --ink-hover:#3a3935; --ink-2:#55534d; --sub:#7a776f; --muted:#8a877f;
  --line:#e3e1db; --line-2:#dcdad3; --line-3:#efeee9; --hover:#efeee9; --soft:#f3f2ee; --track:#ebe9e3;
  --accent:#7c3aed; /* 정규식 바이올렛 */
  --accent-soft:#efe7fd; --accent-ink:#6025c9;
  --m1:rgba(124,58,237,.22); --m2:rgba(234,138,0,.26); --m-cur:rgba(124,58,237,.5); --m-line:#7c3aed;
  --ok:#0f7a4a; --ok-soft:#e1f4ea; --err:#b4311b; --err-soft:#fde5df; --warn:#8a5a00; --warn-soft:#fff2cf;
  --font:"IBM Plex Sans KR",sans-serif; --mono:"JetBrains Mono",monospace;
}
*{box-sizing:border-box}
[hidden]{display:none !important}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--font);-webkit-font-smoothing:antialiased}
button{font:inherit;color:inherit}
code{font-family:var(--mono);font-size:.92em;background:var(--soft);padding:1px 5px;border-radius:4px}
.mono-label{font-family:var(--mono);font-size:11px;letter-spacing:.12em;color:var(--muted)}
.app{min-height:100vh;display:flex;flex-direction:column}
.topbar{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:16px 28px;border-bottom:1px solid var(--line);background:var(--surface);flex-wrap:wrap}
.brand{display:flex;align-items:baseline;gap:14px;min-width:0;flex-wrap:wrap}
.brand-title{font-size:17px;font-weight:700;letter-spacing:-.01em;margin:0}
.actions{display:flex;gap:8px;flex-wrap:wrap}
.btn{height:36px;padding:0 14px;background:transparent;border:1px solid var(--line-2);border-radius:999px;font-size:13px;cursor:pointer;white-space:nowrap}
.btn:hover{background:var(--hover)}
.btn--sm{height:30px;padding:0 12px;font-size:12.5px}
.btn--accent{background:var(--accent);color:#fff;border-color:var(--accent);font-weight:500}
.btn--accent:hover{background:var(--accent-ink);border-color:var(--accent-ink)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

.rx{width:100%;max-width:1240px;margin:0 auto;padding:22px 28px 48px;display:flex;flex-direction:column;gap:14px}

/* 패턴 */
.pat{display:flex;flex-direction:column;gap:10px;padding:16px;background:var(--panel);border:1px solid var(--line);border-radius:18px}
.pat-line{display:flex;align-items:center;gap:4px;height:58px;padding:0 16px;border:2px solid var(--line-2);border-radius:14px;background:var(--surface);transition:border-color .15s,box-shadow .15s}
.pat-line:focus-within{border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
.pat-line.is-err{border-color:var(--err)}
.pat-line.is-err:focus-within{box-shadow:0 0 0 4px var(--err-soft)}
.slash{font-family:var(--mono);font-size:22px;color:var(--muted);flex:none}
.pat-input{flex:1;min-width:0;height:100%;border:none;outline:none;background:transparent;font-family:var(--mono);font-size:18px;color:var(--ink);padding:0 4px}
.pat-input::placeholder{font-family:var(--font);font-size:14px;color:var(--muted)}
.flag-out{flex:none;font-family:var(--mono);font-size:18px;font-weight:700;color:var(--accent);min-width:1ch}
.flags{display:flex;gap:6px;flex-wrap:wrap}
.flag{display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 12px 0 6px;border-radius:999px;border:1px solid var(--line-2);background:transparent;cursor:pointer;font-size:12.5px;color:var(--ink-2);transition:background .15s,border-color .15s,color .15s}
.flag b{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background:var(--soft);font-family:var(--mono);font-size:13px;color:var(--ink-2)}
.flag:hover{border-color:var(--accent)}
.flag[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-ink)}
.flag[aria-pressed="true"] b{background:var(--accent);color:#fff}

.status{display:flex;align-items:flex-start;gap:10px;font-size:13px;line-height:1.55;min-height:24px}
.badge{flex:none;font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.06em;padding:3px 9px;border-radius:6px;background:var(--soft);color:var(--ink-2)}
.badge--ok{background:var(--ok-soft);color:var(--ok)}
.badge--err{background:var(--err-soft);color:var(--err)}
.badge--warn{background:var(--warn-soft);color:var(--warn)}
.badge--run{background:var(--accent-soft);color:var(--accent-ink)}
.status-msg{color:var(--ink-2);min-width:0;word-break:break-word}
.status-msg b{color:var(--ink)}
.status-msg small{display:block;font-family:var(--mono);font-size:11.5px;color:var(--muted)}

.presets{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.presets-label{font-size:12.5px;font-weight:700;color:var(--ink-2)}
.preset-list{display:flex;gap:6px;flex-wrap:wrap}
.preset{height:32px;padding:0 13px;border-radius:999px;border:1px solid var(--line-2);background:var(--panel);cursor:pointer;font-size:13px;color:var(--ink)}
.preset:hover{border-color:var(--accent);color:var(--accent-ink)}
.preset.is-on{background:var(--ink);border-color:var(--ink);color:#fff}
.preset--slow{border-style:dashed;color:var(--warn)}

/* 카드 */
.grid{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:14px;align-items:stretch}
.card{background:var(--panel);border:1px solid var(--line);border-radius:16px;min-width:0;display:flex;flex-direction:column}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 16px;border-bottom:1px solid var(--line-3);flex-wrap:wrap}
.card-title{font-size:13px;font-weight:700}

/* 하이라이트 겹치기: 아래 hl과 위 textarea가 같은 글꼴 · 여백 · 줄바꿈을 써야 위치가 맞음 */
.hl-wrap{position:relative;flex:1;min-height:340px;background:var(--panel);border-radius:0 0 16px 16px}
.hl,#text{font-family:var(--mono);font-size:14px;line-height:1.7;padding:14px 16px;white-space:pre-wrap;overflow-wrap:break-word;word-break:break-all;tab-size:4;letter-spacing:0;scrollbar-gutter:stable}
.hl{position:absolute;inset:0;overflow:hidden;color:var(--ink);-webkit-text-fill-color:transparent;pointer-events:none}
#text{position:relative;display:block;width:100%;height:100%;min-height:340px;margin:0;border:none;outline:none;resize:vertical;background:transparent;color:var(--ink);caret-color:var(--accent);overflow:auto}
#text::placeholder{color:var(--muted);font-family:var(--font);font-size:13px}
.hl mark{color:var(--ink);-webkit-text-fill-color:transparent;background:var(--m1);border-radius:3px}
.hl mark.b{background:var(--m2)}
.hl mark.z{display:inline;border-left:2px solid var(--m-line);margin:0 -1px;background:none}
.hl mark.cur{background:var(--m-cur);box-shadow:0 0 0 1px var(--m-line)}
.card--text:focus-within{border-color:var(--accent)}

.mlist{flex:1;overflow:auto;max-height:520px;min-height:200px;padding:6px}
.mempty{padding:24px 14px;color:var(--sub);font-size:13px;line-height:1.7}
.mempty b{color:var(--ink)}
.mrow{display:grid;grid-template-columns:34px minmax(0,1fr);gap:4px 8px;padding:9px 10px;border-radius:10px;cursor:pointer;border:1px solid transparent}
.mrow:hover{background:var(--soft)}
.mrow.is-cur{background:var(--accent-soft);border-color:var(--accent)}
.mrow:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.mnum{font-family:var(--mono);font-size:11px;color:var(--muted);padding-top:4px}
.mtext{font-family:var(--mono);font-size:13.5px;word-break:break-all;white-space:pre-wrap}
.mtext em{font-style:normal;color:var(--muted)}
.mpos{font-family:var(--mono);font-size:11px;color:var(--sub);margin-left:6px;white-space:nowrap}
.mgroups{grid-column:2;display:flex;flex-wrap:wrap;gap:4px}
.g{display:inline-flex;max-width:100%;font-family:var(--mono);font-size:11.5px;border:1px solid var(--line);border-radius:6px;overflow:hidden}
.g i{font-style:normal;padding:2px 6px;background:var(--soft);color:var(--accent-ink);white-space:nowrap}
.g span{padding:2px 7px;word-break:break-all}
.g span.u{color:var(--muted)}
.mmore{padding:10px;font-size:12px;color:var(--sub);text-align:center}

/* 바꾸기 */
.rep-tokens{display:flex;gap:4px;flex-wrap:wrap}
.rep-tokens button{height:26px;padding:0 9px;border-radius:6px;border:1px solid var(--line-2);background:transparent;cursor:pointer;font-family:var(--mono);font-size:12px;color:var(--ink-2)}
.rep-tokens button:hover{border-color:var(--accent);color:var(--accent-ink)}
.rep-body{display:flex;flex-direction:column;gap:10px;padding:14px 16px 16px}
.rep-input{width:100%;height:42px;padding:0 14px;border:1px solid var(--line-2);border-radius:10px;background:var(--surface);font-family:var(--mono);font-size:14px;color:var(--ink)}
.rep-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.rep-input::placeholder{font-family:var(--font);font-size:13px;color:var(--muted)}
.rep-out{min-height:80px;max-height:320px;overflow:auto;padding:12px 14px;border-radius:10px;background:var(--panel-soft);border:1px dashed var(--line-2);font-family:var(--mono);font-size:13.5px;line-height:1.7;white-space:pre-wrap;word-break:break-all}
.rep-out:empty::before{content:"바꾼 결과가 여기에 나와요.";color:var(--muted);font-family:var(--font);font-size:13px}
.rep-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.rep-note{font-size:12.5px;color:var(--sub)}

/* 문법표 */
.cheat summary{list-style:none;cursor:pointer;padding:14px 16px;display:flex;align-items:center;gap:8px}
.cheat summary::-webkit-details-marker{display:none}
.cheat summary::after{content:"+";margin-left:auto;font-family:var(--mono);color:var(--muted)}
.cheat[open] summary::after{content:"−"}
.cheat summary span{font-weight:400;font-size:12px;color:var(--sub)}
.cheat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:6px;padding:0 16px 16px}
.tok{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:9px;border:1px solid var(--line);background:var(--surface);cursor:pointer;text-align:left;min-width:0}
.tok:hover{border-color:var(--accent)}
.tok code{flex:none;background:var(--accent-soft);color:var(--accent-ink);font-size:12.5px}
.tok span{font-size:12px;color:var(--ink-2);min-width:0}

.foot-note{margin:4px 0 0;font-size:12px;color:var(--sub);line-height:1.6}

.toast{position:fixed;left:50%;bottom:28px;transform:translate(-50%,20px);background:var(--ink);color:#fff;padding:10px 18px;border-radius:999px;font-size:13px;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:50}
.toast.is-on{opacity:1;transform:translate(-50%,0)}

@media (max-width:900px){
  .grid{grid-template-columns:minmax(0,1fr)}
  .mlist{max-height:360px}
}
@media (max-width:640px){
  .topbar{padding:14px 16px}
  .rx{padding:16px 16px 40px}
  .pat{padding:12px;border-radius:14px}
  .pat-line{height:52px;padding:0 10px}
  .pat-input{font-size:16px}
  .flag span{display:none}
  .flag{padding:0 6px}
  .flag[aria-pressed="true"] span{display:inline;padding-right:4px}
  .hl,#text{font-size:13px;padding:12px}
  .hl-wrap,#text{min-height:240px}
}
@media (prefers-reduced-motion:reduce){ .flag,.pat-line,.toast{transition:none} }

/* 다크 모드 (인쇄는 라이트 그대로) */
@media screen{
  :root[data-theme="dark"]{
    color-scheme:dark;
    --bg:#141318; --surface:#19181f; --panel:#1f1e26; --panel-soft:#24232c;
    --ink:#ecebf0; --ink-hover:#ffffff; --ink-2:#c9c7d1; --sub:#a09eab; --muted:#8a8895;
    --line:#2e2d36; --line-2:#393843; --line-3:#26252d; --hover:#2a2932; --soft:#26252d; --track:#34333d;
    --accent:#b195ff; --accent-soft:rgba(177,149,255,.16); --accent-ink:#cbb8ff;
    --m1:rgba(160,120,255,.34); --m2:rgba(255,170,60,.3); --m-cur:rgba(177,149,255,.6); --m-line:#b195ff;
    --ok:#6fdca4; --ok-soft:rgba(111,220,164,.13); --err:#ff9a87; --err-soft:rgba(255,120,100,.14); --warn:#f5cd6b; --warn-soft:rgba(245,205,107,.13);
  }
  :root[data-theme="dark"] .btn--accent,
  :root[data-theme="dark"] .flag[aria-pressed="true"] b,
  :root[data-theme="dark"] .toast{color:var(--bg)}
  :root[data-theme="dark"] .preset.is-on{background:var(--accent-soft);border-color:var(--accent);color:var(--ink)}
}
