@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap');

/* ===== antd v4-like design tokens ===== */
:root {
    --primary: #1890ff;
    --primary-hover: #40a9ff;
    --primary-active: #096dd9;
    --accent: #3887FE;
    --primary-dark: #032642;
    --text: rgba(0, 0, 0, 0.85);
    --text-secondary: rgba(0, 0, 0, 0.45);
    --border: #d9d9d9;
    --split: #f0f0f0;
    --bg: #f0f2f5;
    --card: #ffffff;
    --danger: #ff4d4f;
    --success: #52c41a;
    --warning: #faad14;
    --sider: #001529;
    --radius: 2px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: 'Noto Sans KR', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
        'Malgun Gothic', 'Apple SD Gothic Neo', 'Helvetica Neue', Arial, sans-serif;
    font-size: 14px;
    line-height: 1.5715;
    color: var(--text);
    background: var(--bg);
}

h1 { font-size: 24px; font-weight: 600; margin: 0 0 20px; }
h2 { font-size: 20px; font-weight: 600; margin: 0 0 16px; }
h3 { font-size: 16px; font-weight: 600; }
a { color: var(--primary); text-decoration: none; }
a:hover { color: var(--primary-hover); }
code { background: #f5f5f5; padding: 1px 5px; border-radius: var(--radius); font-size: 85%; color: #c41d7f; }

/* ===== Layout: fixed dark sider (shown when authenticated) ===== */
.sider {
    position: fixed; top: 0; left: 0; bottom: 0; width: 220px;
    background: var(--sider); color: rgba(255, 255, 255, 0.65);
    overflow-y: auto; z-index: 100; display: flex; flex-direction: column;
}
.sider .sider-logo { text-align: center; padding: 24px 12px; }
.sider .sider-logo img { height: 56px; width: auto; }
.sider .menu { list-style: none; margin: 0; padding: 0; flex: 1; }
.sider .menu li { margin: 0; }
.sider .menu a, .sider .menu button {
    display: block; width: 100%; text-align: left; background: none; border: none;
    color: rgba(255, 255, 255, 0.65); padding: 0 24px; height: 40px; line-height: 40px;
    font-size: 14px; font-family: inherit; cursor: pointer; transition: all .2s;
}
.sider .menu a:hover, .sider .menu button:hover { color: #fff; }
.sider .menu a.active { background: var(--primary); color: #fff; }
.sider .menu form { margin: 0; }

.sider ~ .container, .sider ~ .homebg { margin-left: 220px; }

.container { max-width: 1160px; margin: 0 auto; padding: 24px; }
/* Opt-in: centre the page block in the space right of the sider, like sms-web's BaseTemplate
   (fixed-width content, margin: 0 auto). 50% - 470px = 220px + (100% - 220px - 1160px) / 2. */
@media (min-width: 769px) {
    .sider ~ .container.centered { margin-left: max(220px, calc(50% - 470px)); }
}
/* A centred 900px column inside the page (sms-web BaseTemplate's default content width);
   the page header stays left-aligned on the column's edge. */
.content-col { max-width: 900px; margin: 0 auto; }

/* ===== Cards ===== */
.card {
    background: var(--card); border-radius: var(--radius); border: 1px solid var(--split);
    padding: 24px; margin: 0 0 16px;
    box-shadow: 0 1px 2px -2px rgba(0,0,0,.16), 0 3px 6px 0 rgba(0,0,0,.12);
}

/* ===== Buttons (antd) ===== */
.btn, .btn-ghost, .btn-danger {
    display: inline-flex; align-items: center; justify-content: center;
    height: 32px; padding: 4px 15px; font-size: 14px; border-radius: var(--radius);
    cursor: pointer; border: 1px solid var(--primary); transition: all .2s; line-height: 1.5;
    background: var(--primary); color: #fff; text-decoration: none;
}
.btn:hover { background: var(--primary-hover); border-color: var(--primary-hover); color: #fff; }
.btn:active { background: var(--primary-active); border-color: var(--primary-active); }
.btn-ghost { background: #fff; color: var(--text); border-color: var(--border); }
/* keep the white face: .btn:hover/:active would otherwise paint ghost buttons blue under blue text */
.btn-ghost:hover { background: #fff; color: var(--primary-hover); border-color: var(--primary-hover); }
.btn-ghost:active { background: #fff; color: var(--primary-active); border-color: var(--primary-active); }
/* antd default button with `danger`: red outline + red text */
.btn-ghost.danger { color: var(--danger); border-color: var(--danger); }
.btn-ghost.danger:hover { color: #ff7875; border-color: #ff7875; }
.btn-ghost.danger:active { color: #d9363e; border-color: #d9363e; }
.btn-danger { background: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: #ff7875; border-color: #ff7875; color: #fff; }
.btn-danger:active { background: #d9363e; border-color: #d9363e; }
/* antd shape="round" */
.btn.round { border-radius: 32px; }
.btn-link { background: none; border: none; color: inherit; cursor: pointer; font-size: 14px; padding: 0; }
.btn-link:hover { color: var(--primary); }
.btn[disabled], .btn-ghost[disabled] { opacity: .5; cursor: not-allowed; }

/* ===== Form controls (antd) ===== */
input[type=text], input[type=password], input[type=number], input[type=email], input[type=tel],
textarea, select {
    width: 100%; padding: 4px 11px; min-height: 32px; font-size: 14px; font-family: inherit;
    color: var(--text); background: #fff; border: 1px solid var(--border);
    border-radius: var(--radius); transition: all .2s;
}
textarea { padding: 6px 11px; resize: vertical; line-height: 1.5715; }
input:focus, textarea:focus, select:focus {
    outline: none; border-color: var(--primary-hover);
    box-shadow: 0 0 0 2px rgba(24, 144, 255, .2);
}
input::placeholder, textarea::placeholder { color: #bfbfbf; }
/* antd disabled input */
input:disabled, textarea:disabled, select:disabled { background: #f5f5f5; color: rgba(0, 0, 0, 0.25); cursor: not-allowed; }
/* a required <select> still on its hidden placeholder option ("타입") shows it greyed like antd */
select:invalid { color: #bfbfbf; }
select option { color: var(--text); }
/* [hidden] wins over any display set by a class */
[hidden] { display: none !important; }

label { display: block; margin: 0 0 6px; }
.card > label, .card label { margin-top: 14px; color: var(--text); font-size: 14px; }
.card > label:first-of-type { margin-top: 0; }

/* antd icons from /images/icons.svg: <svg class="anticon"><use href="/images/icons.svg#home"/></svg> */
.anticon { display: inline-block; flex: none; width: 1em; height: 1em; fill: currentColor; vertical-align: -0.125em; }

/* ===== antd size="large" (sms-web BaseForm's default): 40px controls with 16px text ===== */
.size-lg input[type=text], .size-lg input[type=password], .size-lg input[type=number],
.size-lg input[type=email], .size-lg input[type=tel], .size-lg select {
    height: 40px; padding: 6.5px 11px; font-size: 16px;
}
.size-lg textarea { padding: 6.5px 11px; font-size: 16px; }
.size-lg .btn, .size-lg .btn-ghost, .size-lg .btn-danger { height: 40px; padding: 6.4px 15px; font-size: 16px; }

/* ===== Password field + eye button that shows/hides it (antd Input.Password; app-ui.js wraps every
   password input). Comes after .size-lg so the room for the eye isn't padded away. ===== */
.pw-field { position: relative; display: block; }
.pw-field > input[type] { display: block; padding-right: 34px; }
.pw-toggle {
    position: absolute; top: 0; right: 0; bottom: 0; width: 34px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: 0; background: none; color: rgba(0, 0, 0, 0.45); font-size: 14px; cursor: pointer; transition: color .3s;
}
.pw-toggle:hover { color: rgba(0, 0, 0, 0.85); }
.pw-toggle:focus-visible { outline: 2px solid var(--primary-hover); outline-offset: -6px; }
.size-lg .pw-toggle { font-size: 16px; }
.form-row > .pw-field { flex: 1; min-width: 0; }

/* ===== Tables (antd) ===== */
table.tbl { width: 100%; border-collapse: collapse; margin-top: 12px; background: var(--card); font-size: 14px; }
table.tbl th, table.tbl td { padding: 12px 16px; text-align: center; border-bottom: 1px solid var(--split); }
table.tbl th { background: #fafafa; font-weight: 500; color: var(--text); white-space: nowrap; }
table.tbl tbody tr:hover { background: #fafafa; }
table.tbl a { color: var(--primary); }

/* ===== Tabs (antd line tabs) ===== */
.tabs { display: flex; gap: 0; margin: 0 0 16px; border-bottom: 1px solid var(--split); }
.tab {
    background: none; border: none; padding: 12px 16px; font-size: 14px; cursor: pointer;
    color: var(--text); border-bottom: 2px solid transparent; margin-bottom: -1px; font-family: inherit;
}
.tab:hover { color: var(--primary-hover); }
.tab.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 500; }

/* ===== Pagination (antd) ===== */
.pager { display: flex; gap: 8px; justify-content: center; align-items: center; margin-top: 16px; flex-wrap: wrap; }
.pager button {
    min-width: 32px; height: 32px; background: #fff; border: 1px solid var(--border);
    color: var(--text); border-radius: var(--radius); cursor: pointer; padding: 0 8px;
}
.pager button:hover { color: var(--primary); border-color: var(--primary); }
.pager button.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.pager button:disabled { opacity: .4; cursor: default; }

.row-between { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; align-items: center; }

.result { margin-top: 14px; min-height: 1.2em; }
.result.ok { color: var(--success); }
.result.error, .error { color: var(--danger); }
.muted { color: var(--text-secondary); }

/* ===== Landing / login hero (mirrors sms-web Home) ===== */
.homebg {
    min-height: 100vh;
    background: linear-gradient(-45deg, #000000, #f7f7f7, #000000, #f7f7f7, #000000);
    background-size: 400% 400%; animation: gradient 15s ease infinite;
    display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden;
}
.homebg:before { content: ''; position: absolute; inset: 0; background: url(/back.png) center/cover no-repeat; opacity: .05; }
@keyframes gradient { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } }
.home-inner { position: relative; z-index: 1; width: 900px; max-width: 100%; padding: 40px 16px; text-align: center; }
.home-logo { height: 160px; width: auto; }
.home-title { color: #fff; font-weight: 700; font-size: 48px; margin: 32px 0; letter-spacing: -1px; }
.home-card { margin: 0 auto; max-width: 850px; text-align: left; }
.home-notice { margin-top: 16px; color: #fff; font-weight: 700; }
/* login card (sms-web Home): centred title, [caret icon | ID + password], full-width 로그인, join link */
.home-login h2 { text-align: center; }
.home-login-row { display: flex; align-items: center; gap: 10px; margin-bottom: 24px; }
.home-login-icon { flex: 0 0 25%; text-align: center; font-size: 60px; line-height: 1; color: var(--primary-dark); }
.home-login-fields { flex: 1; display: flex; flex-direction: column; gap: 24px; margin-top: 8px; }
.home-login-submit { width: 100%; }
.home-login-join { text-align: center; margin: 24px 0 0; }

/* ===== Page header (icon + title + subtext), mirrors sms-web page tops ===== */
.page-head { margin-bottom: 24px; }
.page-head-icon { font-size: 44px; color: var(--accent); margin-bottom: 10px; }
.page-head h1 { margin: 0 0 10px; }
.page-head p { margin: 2px 0; }

/* ===== Message send page (galaxy mockup + controls) ===== */
.msg-layout { display: flex; gap: 28px; align-items: flex-start; flex-wrap: wrap; }
.msg-phone-col { flex: 0 0 300px; display: flex; flex-direction: column; align-items: flex-start; }
.msg-pin { display: inline-flex; align-items: center; gap: 8px; margin: 0 0 10px; cursor: pointer; user-select: none; }
.msg-pin input { margin: 0; }
.msg-phone { position: relative; width: 300px; min-height: 600px; }
.msg-phone-img { position: absolute; top: 0; left: 0; width: 300px; user-select: none; pointer-events: none; }
/* starts right under the mockup's status bar so its chat header (김가영) is covered too */
.msg-phone-screen { position: absolute; top: 52px; left: 17px; width: 266px; }
.msg-phone-screen textarea {
    border: none; background: #fff; resize: none; height: 406px;
    box-shadow: none; border-radius: 0; font-size: 13px;
}
.msg-phone-screen textarea:focus { box-shadow: none; border: none; outline: none; }
.msg-phone-count { text-align: right; color: var(--text-secondary); font-size: 12px; margin-top: 4px; }
.msg-main { flex: 1 1 440px; min-width: 320px; }
.msg-count-row { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.msg-count-row strong { color: var(--primary); font-size: 18px; }
/* under the count: 보유 points, the bold thanks line, the 수신 번호 formats */
.msg-point-row { display: flex; justify-content: center; gap: 16px; margin-bottom: 4px; }
.msg-thanks { margin: 8px 0 16px; }
.msg-tel-hint { margin: -2px 0 8px; font-size: 13px; }
.msg-samples { display: flex; gap: 8px; margin: 8px 0; flex-wrap: wrap; }
.msg-samples .btn { height: 28px; padding: 0 12px; }
.card-accent { height: 3px; background: var(--primary); margin: -24px -24px 20px; }
.btn.amount { background: var(--primary); }
/* Message send page: header + layout form one centred block (phone 300 + gap 28 + controls 560),
   so the header and "메시지 고정하기" line up with the phone's left edge; the controls are centred. */
.msg-page .msg-wrap { max-width: 888px; margin: 0 auto; }
.msg-page .card label, .msg-page .card p { text-align: center; }
.msg-page .tabs, .msg-page .msg-count-row, .msg-page .msg-samples { justify-content: center; }
.msg-page .msg-count-row { flex-wrap: wrap; }
.msg-page .msg-main { flex: 0 1 560px; }
/* Action buttons laid out like sms-web: [중복 제거 | 업로드], 3사 테스트, 발송 — full-width pills */
.msg-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.msg-actions-pair { display: flex; gap: 8px; margin-bottom: 8px; }
.msg-actions-pair .btn { flex: 1 1 0; min-width: 0; }
.msg-actions > .btn { width: 100%; }
.msg-actions .fa-file-excel { margin-right: 8px; }

/* ===== sms-web BaseTable look (table.tbl.dark): bordered small cells, dark header in the sider
   colour, zebra rows — 발송 결과 and 충전 현황 ===== */
table.tbl.dark { margin-top: 0; }
table.tbl.dark th, table.tbl.dark td { padding: 8px; border: 1px solid var(--split); }
table.tbl.dark th { background: var(--sider); color: #fff; border-color: rgba(255, 255, 255, 0.12); }
table.tbl.dark tbody tr:nth-child(2n) td { background: #f8f8f8; }
table.tbl.dark tbody tr:hover td { background: #fafafa; }
/* 충전 상태 colours, as on sms-web: 대기 grey, 수락 blue, 거절 red */
.status-ready { color: var(--text-secondary); }
.status-applied { color: var(--primary); }
.status-rejected { color: var(--danger); }
/* required-field mark (antd) */
.req { color: var(--danger); margin-right: 4px; }

/* ===== Sent-message list (mirrors sms-web Message/List) ===== */
.msglist-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
/* fixed layout: the 내용 column takes the width left over by the sized columns, so it can be cut */
.msglist-page table.tbl { table-layout: fixed; }
.msglist-page table.tbl tbody tr.selected td { background: #e6f7ff; }
/* 내용: one line (line breaks show as spaces), "…" when it doesn't fit; copy/tooltip keep the full text */
.msglist-page table.tbl td.content {
    text-align: center; color: cornflowerblue;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: normal;
}
.msglist-page .col-check { width: 48px; }
.msglist-page .col-check input { width: 16px; height: 16px; margin: 0; cursor: pointer; vertical-align: middle; }

/* ===== Label beside the field (antd horizontal form): "* 이름 : [________]" ===== */
.form-row { display: flex; align-items: center; margin-bottom: 24px; }
.card .form-row > .form-label { flex: 0 0 auto; margin: 0; white-space: nowrap; }
.form-row > .form-label::after { content: ':'; margin: 0 8px 0 2px; }
.form-row > input { flex: 1; min-width: 0; }
/* antd Divider with a centred title: "──── 충전 현황 ────" */
.divider { display: flex; align-items: center; margin: 32px 0 16px; font-weight: 500; white-space: nowrap; }
/* --border, not --split: the page background is grey here (sms-web's was white) */
.divider::before, .divider::after { content: ''; flex: 1; border-top: 1px solid var(--border); }
.divider > span { padding: 0 16px; }

/* ===== Charge page: the amount on the left, the +amount buttons in two rows on the right ===== */
.charge-money { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; }
.charge-money .form-row { margin-bottom: 0; }
.charge-money .form-row > input { flex: 0 0 120px; }
.charge-amounts { display: flex; flex-direction: column; gap: 8px; }
.charge-amounts > div { display: flex; gap: 8px; flex-wrap: wrap; }

/* ===== Side tabs (antd Tabs type="card" tabPosition="left"), e.g. 개인정보 페이지: the tabs share
   the column's height (at least 400px) and the active one turns white with blue text ===== */
.side-tabs { display: flex; align-items: stretch; gap: 24px; min-height: 400px; }
.side-tab-list { flex: 0 0 auto; display: flex; flex-direction: column; gap: 2px; }
.side-tab {
    flex: 1 1 0; display: flex; align-items: center; min-width: 120px; padding: 8px 16px;
    background: #fafafa; border: 1px solid var(--split); border-radius: var(--radius) 0 0 var(--radius);
    font: inherit; color: var(--text); text-align: left; cursor: pointer; transition: color .2s;
}
.side-tab:hover { color: var(--primary-hover); }
.side-tab.active { background: #fff; color: var(--primary); }
.side-tab-panels { flex: 1; min-width: 0; }
.side-tab-panels > .card { margin: 0; }

/* ===== Join (2-column card) ===== */
.join-wrap { max-width: 860px; margin: 24px auto; }
.join-logo { text-align: center; margin-bottom: 20px; }
.join-logo img { height: 96px; width: auto; }
.join-card { padding: 0; overflow: hidden; }
.join-grid { display: grid; grid-template-columns: 1fr 1fr; }
.join-form { padding: 32px; }
.join-deco {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--accent), var(--primary-dark)); color: #fff; padding: 32px; text-align: center;
}
.join-deco .big { font-size: 30px; font-weight: 800; margin-top: 8px; }
@media (max-width: 640px) { .join-grid { grid-template-columns: 1fr; } .join-deco { display: none; } }

/* mypage tab panels */
.panel { margin-top: 8px; }

/* ===== Modal (antd-like): the overlay and box of the alert / confirm dialogs below ===== */
.modal-overlay {
    display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45);
    z-index: 1000; align-items: flex-start; justify-content: center;
}
.modal-box {
    background: #fff; border-radius: var(--radius); width: 416px; max-width: calc(100% - 32px);
    margin-top: 100px; box-shadow: 0 3px 6px -4px rgba(0,0,0,.12), 0 6px 16px 0 rgba(0,0,0,.08), 0 9px 28px 8px rgba(0,0,0,.05);
}

/* ===== Status icons shared by dialogs and notifications (app-ui.js iconSvg) ===== */
.ui-icon {
    flex: 0 0 22px; width: 22px; height: 22px;
    fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.ui-icon .dot { fill: currentColor; stroke: none; }
.ui-icon.warning { color: var(--warning); }
.ui-icon.info { color: var(--primary); }
.ui-icon.success { color: var(--success); }
.ui-icon.error { color: var(--danger); }

/* ===== Shared alert / confirm dialog (antd Modal.confirm look; ui.alert / ui.confirm in app-ui.js) ===== */
.dialog-overlay { display: flex; animation: dialog-fade .2s ease-out; }
.dialog-box { padding: 32px 32px 24px; animation: dialog-zoom .2s ease-out; }
.dialog-body { display: flex; align-items: flex-start; gap: 16px; }
.dialog-text { flex: 1; min-width: 0; }
.dialog-title { font-size: 16px; font-weight: 500; line-height: 1.4; margin-bottom: 8px; }
.dialog-content { white-space: pre-line; word-break: keep-all; overflow-wrap: anywhere; }
.dialog-btns { display: flex; justify-content: flex-end; gap: 8px; margin-top: 24px; }
@keyframes dialog-fade { from { opacity: 0; } }
@keyframes dialog-zoom { from { opacity: 0; transform: scale(.92); } }

/* ===== Top-right notifications (antd notification look; ui.notify in app-ui.js) — slide in from the right ===== */
.notify-host {
    position: fixed; top: 24px; right: 24px; z-index: 1010; width: 384px; max-width: calc(100vw - 48px);
    display: flex; flex-direction: column; gap: 16px; pointer-events: none;
}
.notify {
    position: relative; display: flex; align-items: flex-start; gap: 16px;
    padding: 16px 48px 16px 24px; background: #fff; border-radius: var(--radius); pointer-events: auto;
    box-shadow: 0 3px 6px -4px rgba(0,0,0,.12), 0 6px 16px 0 rgba(0,0,0,.08), 0 9px 28px 8px rgba(0,0,0,.05);
    animation: notify-in .24s ease-out;
}
.notify.leaving { animation: notify-out .2s ease-in forwards; }
.notify .ui-icon { flex-basis: 24px; width: 24px; height: 24px; }
.notify-message { flex: 1; min-width: 0; font-size: 16px; line-height: 24px; word-break: keep-all; overflow-wrap: anywhere; }
.notify-close {
    position: absolute; top: 16px; right: 20px; width: 24px; height: 24px; padding: 0;
    border: none; background: none; cursor: pointer; font-size: 22px; line-height: 24px; color: var(--text-secondary);
}
.notify-close:hover { color: rgba(0, 0, 0, .67); }
@keyframes notify-in { from { opacity: 0; transform: translateX(calc(100% + 24px)); } }
@keyframes notify-out { to { opacity: 0; transform: translateX(calc(100% + 24px)); } }

/* ===== Loading bar along the top of the window while any server request runs (common.js func.ui.loadingBar):
   it fills quickly then slows down short of the end, and on completion runs to the end and fades out ===== */
.loading-bar { position: fixed; top: 0; left: 0; right: 0; z-index: 2000; height: 3px; pointer-events: none; }
.loading-bar > div { width: 0; height: 100%; background: var(--primary); box-shadow: 0 0 8px var(--primary); opacity: 0; }
.loading-bar.running > div { width: 90%; opacity: 1; transition: width 10s cubic-bezier(.08, .82, .17, 1); }
.loading-bar.done > div { width: 100%; opacity: 0; transition: width .2s ease, opacity .3s ease .2s; }

@media (prefers-reduced-motion: reduce) {
    .dialog-overlay, .dialog-box, .notify, .notify.leaving { animation: none; }
}

/* ===== Narrow page (sms-web BaseTemplate narrow, e.g. 비밀번호 변경): a 440px column, centred title ===== */
.narrow-col { max-width: 440px; margin: 0 auto; padding-top: 36px; }
.narrow-title { margin: 20px 0; text-align: center; font-size: 24px; font-weight: 600; line-height: 1.35; }

/* table.tbl cells: click-to-copy content, and the "nothing yet" row */
table.tbl td.content { text-align: left; white-space: pre-wrap; color: var(--primary); cursor: pointer; word-break: break-all; }
table.tbl td.empty { color: var(--text-secondary); padding: 16px; }

/* ===== Admin (sms-web AdminTemplate): a dark top bar holding the menu over a #fafafa page,
   antd cards / tables / forms. Templates: admin/*.html with fragments/admin.html ===== */
.admin-body { background: #fafafa; }
/* antd Layout.Header + Menu theme="dark" mode="horizontal" */
.admin-header { height: 64px; padding: 0 20px; background: var(--sider); overflow-x: auto; overflow-y: hidden; }
.admin-menu { display: flex; height: 100%; }
.admin-menu a {
    display: flex; align-items: center; gap: 10px; padding: 0 20px; white-space: nowrap;
    color: rgba(255, 255, 255, 0.65); font-size: 14px; transition: color .3s, background-color .3s;
}
.admin-menu a:hover, .admin-menu a.active { color: #fff; background: var(--primary); }
.admin-content { padding: 20px; }

/* antd Breadcrumb, 40px above the page */
.breadcrumb { margin-bottom: 40px; color: rgba(0, 0, 0, 0.45); }
.breadcrumb a { color: rgba(0, 0, 0, 0.45); transition: color .3s; }
.breadcrumb a:hover { color: var(--primary-hover); }
.breadcrumb .sep { margin: 0 8px; }
.breadcrumb > :last-child { color: var(--text); }

/* 포인트관리 / 코드 관리: a 200px column with a light antd Menu beside the page */
.admin-split { display: flex; gap: 20px; }
.admin-split-main { flex: 1 1 auto; min-width: 0; }
.a-vmenu { flex: 0 0 180px; align-self: flex-start; margin: 0; padding: 0; list-style: none; border-right: 1px solid var(--split); }
.a-vmenu li { margin: 4px 0 8px; }
.a-vmenu li:last-child { margin-bottom: 4px; }
.a-vmenu a {
    display: flex; align-items: center; gap: 10px; height: 40px; padding: 0 16px;
    color: var(--text); transition: color .3s, background-color .3s;
}
.a-vmenu a > span { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.a-vmenu a:hover { color: var(--primary); }
.a-vmenu a.active { color: var(--primary); background: #e6f7ff; }

/* antd Card */
.a-card { background: #fff; border: 1px solid var(--split); border-radius: var(--radius); }
.a-card-head {
    display: flex; align-items: center; min-height: 48px; padding: 0 24px;
    border-bottom: 1px solid var(--split); font-size: 16px; font-weight: 500; color: var(--text);
}
.a-card-title { flex: 1; padding: 16px 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.a-card-body { padding: 24px; }
.a-stack > * + * { margin-top: 8px; }   /* antd Space direction="vertical" */
.mb-40 { margin-bottom: 40px; }

/* sms-web BaseText / BaseTitle */
.t-primary { color: var(--accent); }
.t-danger { color: #f5222d; }
.t-sub { color: #707070; }
.a-copy { color: var(--accent); cursor: pointer; }
.a-h3 { margin: 0 0 .5em; font-size: 24px; font-weight: 600; line-height: 1.35; }
.a-h4 { margin: 0 0 .5em; font-size: 20px; font-weight: 600; line-height: 1.4; }

/* antd Table: centred columns under a #fafafa header; .small = 8px cells, .bordered = every cell boxed */
.a-table-scroll { overflow-x: auto; container-type: inline-size; }
/* a table wider than the page (scroll x) keeps "데이터 없음" centred in the visible part, as antd's sticky placeholder
   does (100cqw = the visible width, less the small bordered cell's 8px padding and 1px borders) */
.a-table-scroll td.a-empty .a-empty-box { position: sticky; left: 0; width: calc(100cqw - 18px); }
table.a-table {
    width: 100%; border-collapse: separate; border-spacing: 0; background: #fff;
    font-size: 14px; text-align: center; color: var(--text);
}
table.a-table th, table.a-table td { padding: 16px; border-bottom: 1px solid var(--split); overflow-wrap: break-word; }
table.a-table th { position: relative; background: #fafafa; font-weight: 500; }
table.a-table tbody tr:hover > td { background: #fafafa; }
table.a-table.small th, table.a-table.small td { padding: 8px; }
table.a-table.bordered { border-top: 1px solid var(--split); border-left: 1px solid var(--split); }
table.a-table.bordered th, table.a-table.bordered td { border-right: 1px solid var(--split); }
/* a borderless header keeps faint separators between the column titles */
table.a-table:not(.bordered) th:not(:last-child)::before {
    content: ''; position: absolute; top: 50%; right: 0; width: 1px; height: 1.6em;
    background: rgba(0, 0, 0, 0.06); transform: translateY(-50%);
}
/* columns with `ellipsis`: one line cut with "…" (antd then lays the table out fixed) */
table.a-table.fixed { table-layout: fixed; }
table.a-table td.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* sms-web BaseTable (.dark): a primaryDark header with white titles and striped rows */
table.a-table.dark th { background: var(--primary-dark); color: #fff; }
table.a-table.dark tbody tr:nth-child(2n) > td { background: #f8f8f8; }
table.a-table.dark tbody tr:hover > td { background: #fafafa; }
/* no rows: antd Empty (image + "데이터 없음"), which doesn't light up on hover */
table.a-table td.a-empty { color: rgba(0, 0, 0, 0.25); }
table.a-table tbody tr.a-placeholder:hover > td { background: #fff; }
.a-empty-box { margin: 32px 0; text-align: center; line-height: 1.5715; }
.a-empty-box svg { display: block; height: 40px; margin: 0 auto 8px; }
.a-empty-ellipse { fill: #f5f5f5; }
.a-empty-g { stroke: #d9d9d9; }
.a-empty-path { fill: #fafafa; }
.a-table-title { padding: 8px; background: #fff; }

/* antd Pagination, right-aligned under the table; .mini under a small table */
.a-pager { display: flex; justify-content: flex-end; align-items: center; flex-wrap: wrap; gap: 8px; margin: 16px 0; }
.a-pager:empty { display: none; }
.a-pager button {
    min-width: 32px; height: 32px; padding: 0 6px; border: 1px solid var(--border); border-radius: var(--radius);
    background: #fff; color: var(--text); font: inherit; line-height: 30px; cursor: pointer; transition: all .3s;
}
.a-pager button:hover { border-color: var(--primary); color: var(--primary); }
.a-pager button.active { border-color: var(--primary); color: var(--primary); font-weight: 500; }
.a-pager button:disabled { border-color: var(--border); color: rgba(0, 0, 0, 0.25); cursor: not-allowed; }
.a-pager button.jump { border-color: transparent; color: rgba(0, 0, 0, 0.25); letter-spacing: 2px; }
.a-pager button.jump:hover { color: var(--primary); }
.a-pager .anticon { font-size: 12px; vertical-align: -1px; }
.a-pager.mini { gap: 0; }
.a-pager.mini button { min-width: 24px; height: 24px; line-height: 22px; }
.a-pager.mini button:not(.active) { border-color: transparent; background: transparent; }

/* antd Table loading (Spin): the table and its pager fade under four dots turning in the middle
   (centred within the first 400px of a tall table). Wrapped at the first load by common.js func.ui.spin */
.a-spin { position: relative; }
.a-spin > :not(.a-spin-dot) { transition: opacity .3s; }
.a-spin.spinning { min-height: 120px; }   /* room under the header when the table has no rows yet */
.a-spin.spinning > :not(.a-spin-dot) { opacity: .3; user-select: none; pointer-events: none; }
.a-spin-dot { display: none; position: absolute; top: 0; left: 0; z-index: 4; width: 100%; height: 100%; max-height: 400px; }
.a-spin.spinning > .a-spin-dot { display: block; }
.a-spin-dot > span {
    position: absolute; top: 50%; left: 50%; width: 20px; height: 20px; margin: -10px;
    transform: rotate(45deg); animation: a-spin-rotate 1.2s infinite linear;
}
.a-spin-dot i {
    position: absolute; width: 9px; height: 9px; border-radius: 100%; background: var(--primary);
    transform: scale(.75); opacity: .3; animation: a-spin-move 1s infinite linear alternate;
}
.a-spin-dot i:nth-child(1) { top: 0; left: 0; }
.a-spin-dot i:nth-child(2) { top: 0; right: 0; animation-delay: .4s; }
.a-spin-dot i:nth-child(3) { right: 0; bottom: 0; animation-delay: .8s; }
.a-spin-dot i:nth-child(4) { bottom: 0; left: 0; animation-delay: 1.2s; }
@keyframes a-spin-move { to { opacity: 1; } }
@keyframes a-spin-rotate { to { transform: rotate(405deg); } }

/* antd Form: items 24px apart; "label : control" rows, or the label above (.a-vlabel) */
.a-item { margin-bottom: 24px; }
.a-row { display: flex; align-items: flex-start; }
.a-label { flex: 0 0 auto; margin: 0; line-height: 32px; white-space: nowrap; color: var(--text); }
.a-label::after { content: ':'; margin: 0 8px 0 2px; }
.a-vlabel { display: block; margin: 0; padding: 0 0 8px; }
.a-label.required::before, .a-vlabel.required::before {
    content: '*'; margin-right: 4px; color: var(--danger); font-family: SimSun, sans-serif;
}
.a-control { flex: 1 1 0; min-width: 0; display: flex; align-items: center; flex-wrap: wrap; min-height: 32px; }
.size-lg .a-label { line-height: 40px; }
.size-lg .a-control { min-height: 40px; }
/* labelCol={{ span: 4 }}: a right-aligned label column 4/24 wide */
.a-hform .a-label { flex: 0 0 16.666667%; max-width: 16.666667%; overflow: hidden; text-align: right; }
/* layout="inline" */
.a-inline { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0 16px; }
.a-inline > .a-row { margin-bottom: 0; }
input.w-200, select.w-200 { width: 200px; }
input.w-90 { width: 90px; }

/* antd Radio.Group of Radio.Button (input + label pairs); .solid = buttonStyle="solid" */
.a-radio { display: inline-flex; }
.a-radio > input { position: absolute; width: 0; height: 0; margin: 0; opacity: 0; pointer-events: none; }
.a-radio > label {
    position: relative; display: inline-block; margin: 0; height: 32px; padding: 0 15px; line-height: 30px;
    background: #fff; border: 1px solid var(--border); border-left-width: 0; color: var(--text);
    cursor: pointer; user-select: none; transition: color .3s, background-color .3s, border-color .3s, box-shadow .3s;
}
.a-radio > label:first-of-type { border-left-width: 1px; border-radius: var(--radius) 0 0 var(--radius); }
.a-radio > label:last-of-type { border-radius: 0 var(--radius) var(--radius) 0; }
.a-radio > label:hover { color: var(--primary); }
.a-radio > input:checked + label { z-index: 1; color: var(--primary); border-color: var(--primary); box-shadow: -1px 0 0 0 var(--primary); }
.a-radio > input:checked + label:first-of-type { box-shadow: none; }
.a-radio.solid > input:checked + label { color: #fff; background: var(--primary); }
.a-radio > input:focus-visible + label { box-shadow: 0 0 0 3px rgba(24, 144, 255, 0.12); }
.size-lg .a-radio > label { height: 40px; line-height: 38px; font-size: 16px; }

/* antd Switch, drawn on a checkbox */
input.a-switch {
    appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 44px; height: 22px; margin: 0;
    border-radius: 100px; background: rgba(0, 0, 0, 0.25); cursor: pointer; transition: background-color .2s; vertical-align: middle;
}
input.a-switch::after {
    content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
    background: #fff; box-shadow: 0 2px 4px 0 rgba(0, 35, 11, 0.2); transition: left .2s;
}
input.a-switch:checked { background: var(--primary); }
input.a-switch:checked::after { left: 24px; }
input.a-switch:focus-visible { outline: none; box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); }

/* antd Tabs type="card" */
.a-tabs { display: flex; gap: 2px; margin: 0 0 16px; border-bottom: 1px solid var(--split); }
.a-tab {
    margin-bottom: -1px; padding: 8px 16px; background: #fafafa; border: 1px solid var(--split);
    border-radius: var(--radius) var(--radius) 0 0; font: inherit; color: var(--text); cursor: pointer;
    transition: color .3s, background-color .3s;
}
.a-tab:hover { color: var(--primary-hover); }
.a-tab.active { background: #fff; border-bottom-color: #fff; color: var(--primary); }

/* sms-web BaseDivider: a faint line, or a line with a centred title */
.a-divider { display: flex; align-items: center; margin: 16px 0; white-space: nowrap; }
.a-divider::before, .a-divider::after { content: ''; flex: 1; border-top: 1px solid rgba(173, 169, 169, 0.4); }
.a-divider > span { padding: 0 1em; }
hr.a-line { margin: 24px 0; border: 0; border-top: 1px solid rgba(173, 169, 169, 0.4); }

/* small buttons (antd size="small") and the 검색 row of the 회원 찾기 cards */
.btn-sm { height: 24px; padding: 0 7px; font-size: 14px; }
.a-search { display: flex; align-items: flex-start; margin-bottom: 24px; }
.a-search > input[type] { flex: 1 1 auto; width: auto; min-width: 0; }
.a-search > .btn { flex: none; }
.a-btns { display: inline-flex; gap: 8px; justify-content: center; }

/* antd Row/Col grids: 3 columns from sm (576px), 2 from md (768px) */
.a-cols3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.a-cols2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start; }
@media (max-width: 767px) { .a-cols2 { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 575px) { .a-cols3 { grid-template-columns: minmax(0, 1fr); } }

/* 어드민 대시보드: 카드 사이를 띄우고, 일별 · 주간별 · 월별 표를 각자 테두리 친 칸으로 나눈다
   (칸 머리는 파란 띠 + 왼쪽 강조선, 표 머리는 진하게). 칸들은 높이를 맞춘다 */
.dash.a-stack > * + * { margin-top: 20px; }
.dash .a-card-head { background: #fafafa; border-bottom-color: var(--border); }
.dash .a-card-title { font-size: 17px; font-weight: 600; }
.dash .a-card-title b { font-size: 20px; margin: 0 2px; }
.dash-panel { display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--border); border-radius: 4px; overflow: hidden; background: #fff; }
.dash-panel-head {
    display: flex; justify-content: space-between; align-items: center; padding: 10px 12px;
    background: #e6f4ff; border-bottom: 1px solid #91caff; box-shadow: inset 3px 0 0 var(--primary);
    font-size: 15px; font-weight: 600; color: var(--primary-dark);
}
.dash-panel-note { font-size: 12px; font-weight: 400; color: var(--text-secondary); }
.dash-panel table.a-table th { background: #f5f5f5; color: var(--text); font-weight: 600; border-bottom-color: var(--border); }
.dash-panel table.a-table tbody tr:last-child > td { border-bottom: 0; }

/* ===== 대리점관리 (sms-web Agency: BaseTemplate width="100%" on white — the 60px top space + 20px padding,
   a 200px menu column beside the page; the admin card / table / form classes above) ===== */
.agency-body { background: #fff; }
.container.agency-page { max-width: none; padding: 80px 20px 20px; }
.agency-point-label { margin-right: 10px; }

/* ===== Responsive: sider becomes a top bar on small screens ===== */
@media (max-width: 768px) {
    .sider { position: static; width: 100%; height: auto; flex-direction: row; flex-wrap: wrap; align-items: center; }
    .sider .sider-logo { padding: 10px 16px; }
    .sider .sider-logo img { height: 32px; }
    .sider .menu { display: flex; flex-wrap: wrap; flex: 1; }
    .sider .menu a, .sider .menu button { padding: 0 12px; height: 44px; line-height: 44px; }
    .sider ~ .container, .sider ~ .homebg { margin-left: 0; }
    .container { padding: 16px; }
    .narrow-col { padding-top: 0; }
    .container.agency-page { padding: 16px; }
    .admin-split { flex-direction: column; }
    .a-vmenu { flex: none; width: 100%; border-right: 0; border-bottom: 1px solid var(--split); }
}
