  /* ---------- tokens ---------- */
  :root{
    --court-900:#12293a;
    --court-700:#1f4a63;
    --court-600:#2c6386;
    --ball:#cfe33a;
    --ball-ink:#28330a;
    --clay:#c1703f;

    --bg:#f4f2ea;
    --surface:#ffffff;
    --surface-2:#eeece1;
    --border:#dcd7c6;
    --text:#1a232c;
    --text-muted:#5c6b72;
    --text-faint:#8b9498;

    --good-bg:#e4f1e1; --good-fg:#276a45; --good-line:#bcdcb6;
    --warn-bg:#f7ecd8; --warn-fg:#93551c; --warn-line:#e6cd9c;
    --muted-bg:#e7e5da; --muted-fg:#5c6b72; --muted-line:#d3cfbf;
    --bad-bg:#f6dfdb; --bad-fg:#9a3226; --bad-line:#e6bcb2;
    --clay-bg:#f3e2d8; --clay-fg:#8a4a26; --clay-line:#e0c2a8;
    --info-bg:#dce9f7; --info-fg:#1f5c96; --info-line:#b7d1ec;
    --rose-bg:#fbe1ea; --rose-fg:#a3245f; --rose-line:#f2bdd4;

    --shadow: 0 1px 2px rgba(18,41,58,.06), 0 6px 20px -8px rgba(18,41,58,.18);
    --radius: 10px;
    --font-display:'Black Han Sans', 'Noto Sans KR', sans-serif;
    --font-body:'Noto Sans KR', -apple-system, sans-serif;
    --font-mono:'IBM Plex Mono', ui-monospace, monospace;
  }

  /* 테마 선택 UI가 없으므로 기기 설정(prefers-color-scheme)만 따른다. */
  @media (prefers-color-scheme: dark){
    :root{
      --court-900:#dbe7ee; --court-700:#9fd1e8; --court-600:#7fb9d6;
      --ball:#d8ec53; --ball-ink:#1c2306;
      --clay:#e0925f;

      --bg:#101a21; --surface:#17242c; --surface-2:#1d2b34;
      --border:#2a3b44; --text:#e8edee; --text-muted:#9db0b7; --text-faint:#71858c;

      --good-bg:#183524; --good-fg:#7fd39a; --good-line:#26502f;
      --warn-bg:#3a2c14; --warn-fg:#e6b869; --warn-line:#5c4620;
      --muted-bg:#22303a; --muted-fg:#9db0b7; --muted-line:#33454f;
      --bad-bg:#3a1e1c; --bad-fg:#e79087; --bad-line:#5c2c27;
      --clay-bg:#3a2818; --clay-fg:#e0925f; --clay-line:#5c3f28;
      --info-bg:#152c40; --info-fg:#7fb3e0; --info-line:#274a68;
      --rose-bg:#3a1b2b; --rose-fg:#e896b8; --rose-line:#5c2c42;

      --shadow: 0 1px 2px rgba(0,0,0,.3), 0 10px 30px -10px rgba(0,0,0,.5);
    }
  }

  *{box-sizing:border-box;}
  html,body{margin:0;padding:0;}
  body{
    background:var(--bg);
    color:var(--text);
    font-family:var(--font-body);
    -webkit-font-smoothing:antialiased;
    min-height:100vh;
  }
  h1,h2,h3{text-wrap:balance;margin:0;}
  a{color:inherit;}
  button{font-family:inherit;}
  ::selection{background:var(--ball);color:var(--ball-ink);}
  :focus-visible{outline:2px solid var(--court-600);outline-offset:2px;}

  .mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}

  /* ---------- role gate ---------- */
  #role-gate{
    position:fixed;inset:0;z-index:50;
    display:none;align-items:center;justify-content:center;
    background:
      radial-gradient(circle at 15% 20%, color-mix(in srgb, var(--ball) 14%, transparent), transparent 45%),
      color-mix(in srgb, var(--court-900) 88%, transparent);
    padding:24px;
  }
  #role-gate.open{display:flex;}
  .gate-card{position:relative;}
  .gate-card{
    width:100%;max-width:560px;
    background:var(--surface);
    border-radius:16px;
    box-shadow:var(--shadow);
    padding:40px 36px 32px;
    text-align:center;
  }
  .gate-mark{
    font-family:var(--font-display);
    font-size:15px;letter-spacing:.14em;
    color:var(--court-700);
    display:inline-flex;align-items:center;gap:8px;
    margin-bottom:18px;
  }
  .gate-mark .dot{width:9px;height:9px;border-radius:50%;background:var(--ball);display:inline-block;}

  /* 첫 진입·로그인·회원 확인 중에는 로그인 폼 대신 클럽명 스플래시를 덮어둔다. */
  #auth-loading{
    position:fixed;inset:0;z-index:60;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;
    background:var(--court-900);
    transition:opacity .2s ease;
  }
  #auth-loading .gate-mark{color:#e9eef0;margin-bottom:0;}
  #auth-loading p{margin:0;font-size:12.5px;color:#9fb2ba;letter-spacing:.02em;}
  #auth-loading.hidden{opacity:0;visibility:hidden;pointer-events:none;}
  .auth-spinner{
    width:22px;height:22px;border-radius:50%;
    border:2px solid rgba(233,238,240,.22);border-top-color:var(--ball);
    animation:auth-spin .8s linear infinite;
  }
  @keyframes auth-spin{to{transform:rotate(360deg);}}
  @media (prefers-reduced-motion: reduce){ .auth-spinner{animation-duration:2.4s;} }
  .gate-card h1{
    font-family:var(--font-display);
    font-size:clamp(28px,5vw,36px);
    line-height:1.15;
    color:var(--text);
  }
  .gate-card p.lede{color:var(--text-muted);margin:12px 0 28px;font-size:15px;line-height:1.6;}
  .gate-note{margin-top:22px;font-size:11.5px;color:var(--text-faint);line-height:1.6;}
  .pw-input{
    width:100%;padding:12px 14px;border:1.5px solid var(--border);border-radius:10px;
    background:var(--surface-2);color:var(--text);font-size:15px;font-family:inherit;
    margin-top:4px;
  }
  .pw-input:focus{border-color:var(--court-600);}
  .pw-error{color:var(--bad-fg);font-size:12.5px;margin-top:10px;text-align:left;}
  .pw-actions{display:flex;gap:10px;margin-top:20px;}
  .pw-actions .btn{flex:1;justify-content:center;}

  .modal-overlay{
    position:fixed;inset:0;z-index:80;display:none;align-items:center;justify-content:center;
    background:color-mix(in srgb, var(--court-900) 55%, transparent);
    padding:20px;
  }
  .modal-overlay.open{display:flex;}
  .modal-card{
    width:100%;max-width:380px;background:var(--surface);border-radius:14px;box-shadow:var(--shadow);
    padding:24px;
  }
  .modal-card h3{font-size:16px;}

  /* ---------- app shell ---------- */
  #app{display:none;min-height:100vh;}
  #app.ready{display:flex;}

  #sidebar{
    width:236px;flex:none;
    background:var(--court-900);
    color:#e9eef0;
    display:flex;flex-direction:column;
    padding:22px 16px;
    position:sticky;top:0;height:100vh;
  }
  .brand{
    font-family:var(--font-display);
    font-size:19px;letter-spacing:.02em;
    display:flex;align-items:center;gap:9px;
    padding:2px 8px 20px;
  }
  .brand .dot{width:10px;height:10px;border-radius:50%;background:var(--ball);}

  nav.navlist{display:flex;flex-direction:column;gap:2px;flex:1;}
  .navlink{
    display:flex;align-items:center;gap:10px;
    padding:10px 12px;border-radius:9px;
    color:#c9d6db;font-size:13.5px;font-weight:500;
    cursor:pointer;border:none;background:none;text-align:left;width:100%;
  }
  .navlink .ic{width:18px;text-align:center;font-size:14px;}
  .navlink:hover{background:rgba(255,255,255,.06);color:#fff;}
  .navlink.active{background:var(--ball);color:var(--ball-ink);font-weight:700;}

  .role-chip{
    margin-top:16px;padding:12px;border-radius:10px;
    background:rgba(255,255,255,.06);
    border:1px solid rgba(255,255,255,.08);
  }
  .role-chip .rc-label{font-size:10px;letter-spacing:.1em;color:#9fb2ba;text-transform:uppercase;}
  .role-chip .rc-value{font-size:13.5px;font-weight:700;margin-top:3px;display:flex;align-items:center;gap:6px;}
  .role-chip .rc-value .dot{width:7px;height:7px;border-radius:50%;background:var(--ball);}
  .role-chip button{
    margin-top:9px;width:100%;padding:7px;border-radius:7px;border:1px solid rgba(255,255,255,.16);
    background:transparent;color:#dbe6ea;font-size:11.5px;cursor:pointer;
  }
  .role-chip button:hover{background:rgba(255,255,255,.08);}

  main#content{flex:1;min-width:0;padding:34px 40px 80px;}
  .view{display:none;}
  .view.active{display:block;}

  .view-head{margin-bottom:26px;}
  .eyebrow{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--court-600);font-weight:700;}
  .view-head h2{font-size:26px;margin-top:6px;}
  .view-head p{color:var(--text-muted);font-size:14px;margin-top:8px;line-height:1.6;}

  /* 화면 설명은 상단이 아니라 각 화면 맨 아래에 둔다. */
  .view-note{
    margin-top:30px;padding:16px 18px 18px;
    border:1px solid var(--border);border-left:3px solid var(--court-600);border-radius:var(--radius);
    background:var(--surface-2);color:var(--text-muted);font-size:12.8px;line-height:1.75;
  }
  .view-note h4{
    font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--court-600);
    font-weight:700;margin-bottom:9px;
  }
  .view-note p{margin:0 0 7px;}
  .view-note p:last-child{margin-bottom:0;}
  .view-note ol, .view-note ul{margin:0 0 7px;padding-left:19px;}
  .view-note ol:last-child, .view-note ul:last-child{margin-bottom:0;}
  .view-note li{margin-bottom:5px;}
  .view-note li:last-child{margin-bottom:0;}
  .view-note b{color:var(--text);font-weight:700;}
  .view-note .vn-sub{display:block;margin-top:9px;color:var(--text-faint);font-size:11.5px;}

  .card{
    background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
    box-shadow:var(--shadow);
  }
  .card + .card{margin-top:18px;}
  .card-head{
    display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
    padding:16px 18px;border-bottom:1px solid var(--border);
  }
  .card-head h3{font-size:14.5px;font-weight:700;}
  .card-body{padding:18px;}

  /* stat tiles */
  .stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:22px;}
  .stat-tile{
    background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
    padding:16px 18px;box-shadow:var(--shadow);
  }
  .stat-tile .st-label{font-size:11.5px;color:var(--text-muted);font-weight:600;display:flex;align-items:center;gap:6px;}
  .stat-tile .st-value{font-family:var(--font-mono);font-size:28px;font-weight:600;margin-top:8px;letter-spacing:-.01em;}
  .stat-tile .st-sub{font-size:11.5px;color:var(--text-faint);margin-top:4px;}
  .st-accent{width:7px;height:7px;border-radius:50%;background:var(--ball);display:inline-block;}

  /* ---------- guest stats: bar charts ---------- */
  .card-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-bottom:20px;}
  .card-grid-2 .card{margin-bottom:0;}
  .stat-empty{color:var(--text-muted);font-size:13px;padding:6px 0;}

  /* 항상 전체 기간인 카드(연도별 추이 등)와, 아래 '기간' 필터가 적용되는
     카드 묶음을 시각적으로 갈라주는 구분선. 위쪽 여백을 넉넉히 둬서
     바로 위 카드에 붙어 보이지 않게 한다. */
  .stats-section-divider{
    display:flex;align-items:center;gap:12px;
    margin:34px 0 18px;
  }
  .stats-section-divider::before, .stats-section-divider::after{
    content:'';flex:1;height:1px;background:var(--border);
  }
  .stats-section-divider span{
    font-size:11px;letter-spacing:.08em;text-transform:uppercase;
    color:var(--text-faint);font-weight:700;white-space:nowrap;
  }

  /* 세로 막대: 연도별·월별 추이처럼 항목이 시간순으로 나열될 때 쓴다.
     칸이 많아지면(전체 기간 월별 추이 등) 줄여서 욱여넣는 대신 가로 스크롤로 본다. */
  .vbar-chart{display:flex;align-items:flex-end;gap:6px;height:150px;padding-top:22px;}
  .vbar-chart.wide{overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:4px;}
  .vbar-chart.wide .vbar-col{flex:0 0 30px;}
  .vbar-col{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;}
  .vbar-value{font-size:11px;color:var(--text-muted);font-family:var(--font-mono);margin-bottom:5px;white-space:nowrap;}
  .vbar-fill{width:100%;max-width:34px;border-radius:4px 4px 0 0;min-height:2px;}
  .vbar-label{font-size:11px;color:var(--text-faint);margin-top:7px;white-space:nowrap;}

  /* 가로 막대: 구력·초대경로처럼 이름표가 길 때 쓴다. */
  .hbar-list{display:flex;flex-direction:column;gap:9px;}
  .hbar-row{display:grid;grid-template-columns:88px 1fr 68px;align-items:center;gap:10px;}
  .hbar-label{font-size:12.5px;color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .hbar-track{height:13px;border-radius:7px;background:var(--surface-2);overflow:hidden;}
  .hbar-fill{height:100%;border-radius:7px;min-width:3px;}
  .hbar-value{font-size:12px;color:var(--text);font-family:var(--font-mono);text-align:right;white-space:nowrap;}

  /* court-line divider */
  .court-rule{
    height:6px;border-radius:99px;margin:26px 0;
    background:linear-gradient(90deg, var(--court-700), var(--ball) 50%, var(--clay));
    opacity:.55;
  }

  /* search/filter bar */
  .toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:14px;}
  .toolbar input[type="text"], .toolbar input[type="search"], .toolbar select, .toolbar input[type="date"]{
    padding:9px 11px;border:1px solid var(--border);border-radius:8px;
    background:var(--surface);color:var(--text);font-size:13px;font-family:inherit;
  }
  .toolbar input[type="text"]{min-width:220px;}
  .pillfilter{display:flex;gap:6px;flex-wrap:wrap;transition:opacity .15s ease;}
  .pillfilter.disabled{opacity:.4;pointer-events:none;}
  .pillfilter button{
    padding:7px 12px;border-radius:99px;border:1px solid var(--border);background:var(--surface);
    font-size:12.5px;color:var(--text-muted);cursor:pointer;
  }
  .pillfilter button.active{background:var(--court-900);color:#fff;border-color:var(--court-900);}

  /* tables */
  .table-wrap{overflow-x:auto;}
  table{border-collapse:collapse;width:100%;font-size:13px;}
  thead th{
    position:sticky;top:0;background:var(--surface-2);
    text-align:left;font-size:11px;letter-spacing:.06em;text-transform:uppercase;
    color:var(--text-muted);padding:10px 12px;border-bottom:1px solid var(--border);white-space:nowrap;
  }
  thead th.sortable{cursor:pointer;user-select:none;}
  thead th.sortable:hover{color:var(--text);}
  thead th.sortable .sort-ic{display:inline-block;width:12px;margin-left:3px;font-size:9px;opacity:.4;}
  thead th.sortable.sort-active .sort-ic{opacity:1;color:var(--court-600);}
  thead th.admin-only-cell{color:var(--court-600);font-size:12px;min-width:160px;}

  .btn-copy{border-color:var(--muted-line);color:var(--muted-fg);}
  .btn-copy:hover{background:color-mix(in srgb, var(--muted-fg) 12%, transparent);}
  .btn-danger{border-color:var(--bad-line);color:var(--bad-fg);background:var(--bad-bg);}
  .btn-danger:hover{filter:brightness(0.95);}
  tbody td{padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:middle;white-space:nowrap;}
  tbody tr:hover{background:color-mix(in srgb, var(--court-600) 6%, transparent);}
  tfoot td{padding:10px 12px;font-weight:700;background:var(--surface-2);border-top:2px solid var(--border);}

  .badge{
    display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:99px;
    font-size:11.5px;font-weight:700;border:1px solid transparent;white-space:nowrap;
  }
  .badge.good{background:var(--good-bg);color:var(--good-fg);border-color:var(--good-line);}
  .badge.warn{background:var(--warn-bg);color:var(--warn-fg);border-color:var(--warn-line);}
  .badge.muted{background:var(--muted-bg);color:var(--muted-fg);border-color:var(--muted-line);}
  .badge.bad{background:var(--bad-bg);color:var(--bad-fg);border-color:var(--bad-line);}
  .badge.info{background:var(--info-bg);color:var(--info-fg);border-color:var(--info-line);}
  .badge.rose{background:var(--rose-bg);color:var(--rose-fg);border-color:var(--rose-line);}

  /* status-btn은 정회원 명단·연회비·코트 정산에서만 쓰여 관리자 전용으로
     묶는다. cell-edit은 게스트 명단도 함께 쓰므로 운영진 권한을 그대로 둔다
     (게스트는 계속 운영진도 편집 가능) - 정회원·코트 정산의 편집 칸은
     아래 별도 .super-edit로 관리자만 되게 만든다. */
  button.status-btn{cursor:pointer;}
  body:not(.is-superadmin) button.status-btn{cursor:default;pointer-events:none;}
  body:not(.role-admin) .cell-edit{cursor:default;pointer-events:none;}

  .cell-edit{
    border-radius:6px;padding:3px 6px;margin:-3px -6px;
    line-height:1.4;max-height:1.4em;overflow:hidden;
  }
  .cell-edit *{display:inline;margin:0;}
  body.role-admin .cell-edit{outline:1px dashed transparent;}
  body.role-admin .cell-edit:hover{outline-color:var(--court-600);background:color-mix(in srgb, var(--court-600) 8%, transparent);}
  body.role-admin .cell-edit:focus{outline:1.5px solid var(--court-600);background:var(--surface);}

  /* 정회원 명단·코트 정산의 편집 칸: 모양은 cell-edit과 같지만
     운영진이 아니라 관리자에게만 편집을 허용한다. */
  body:not(.is-superadmin) .super-edit{cursor:default;pointer-events:none;}
  .super-edit{
    border-radius:6px;padding:3px 6px;margin:-3px -6px;
    line-height:1.4;max-height:1.4em;overflow:hidden;
  }
  .super-edit *{display:inline;margin:0;}
  body.is-superadmin .super-edit{outline:1px dashed transparent;}
  body.is-superadmin .super-edit:hover{outline-color:var(--court-600);background:color-mix(in srgb, var(--court-600) 8%, transparent);}
  body.is-superadmin .super-edit:focus{outline:1.5px solid var(--court-600);background:var(--surface);}

  /* 정해진 값 중에서 고르는 칸(예: 게스트 초대경로)은 표 안에서 <select>로 바로
     편집한다. cell-edit과 같은 여백/모서리를 쓰되, 비활성 상태는 disabled 대신
     pointer-events로 막아 다른 배지·칸과 같은 방식으로 흐려 보이지 않게 한다. */
  .field-select{
    border:1px solid transparent;border-radius:6px;padding:3px 6px;margin:-3px -6px;
    background:transparent;color:inherit;font:inherit;
  }
  body.role-admin .field-select{cursor:pointer;}
  body.role-admin .field-select:hover{border-color:var(--court-600);background:color-mix(in srgb, var(--court-600) 8%, transparent);}
  body.role-admin .field-select:focus{border-color:var(--court-600);background:var(--surface);}
  body:not(.role-admin) .field-select{pointer-events:none;}

  .btn{
    display:inline-flex;align-items:center;gap:7px;
    padding:9px 15px;border-radius:8px;border:1px solid var(--border);
    background:var(--surface);color:var(--text);font-size:13px;font-weight:600;cursor:pointer;
  }
  .btn:hover{border-color:var(--court-600);}
  .btn-accent{background:var(--ball);color:var(--ball-ink);border-color:var(--ball);}
  .btn-accent:hover{filter:brightness(0.96);}
  .btn[disabled]{opacity:.45;cursor:not-allowed;}

  .admin-only{display:none;}
  body.role-admin .admin-only{display:inherit;}
  body.role-admin .admin-only.flex{display:flex;}
  body.role-admin .admin-only.grid{display:grid;}
  .member-only-note{display:none;}
  body:not(.is-superadmin) .member-only-note{display:block;}
  .admin-only-inline{display:none;}
  body.role-admin .admin-only-inline{display:inline-block;}
  /* 표의 '관리' 열: 머리글과 본문 칸이 항상 같이 보이거나 같이 숨겨져야
     헤더와 목록의 폭이 어긋나지 않는다. (td/th는 inline-block이 아닌 table-cell로) */
  th.admin-only-cell, td.admin-only-cell{display:none;}
  body.role-admin th.admin-only-cell,
  body.role-admin td.admin-only-cell{display:table-cell;}
  .superadmin-only{display:none;}
  body.is-superadmin .superadmin-only{display:inherit;}
  body.is-superadmin .superadmin-only.flex{display:flex;}
  /* 정회원 명단·연회비·코트 정산: 운영진이 아니라 관리자만 고칠 수 있다. */
  .superadmin-only-inline{display:none;}
  body.is-superadmin .superadmin-only-inline{display:inline-block;}
  th.superadmin-only-cell, td.superadmin-only-cell{display:none;}
  body.is-superadmin th.superadmin-only-cell,
  body.is-superadmin td.superadmin-only-cell{display:table-cell;}
  /* 대진표 작성 영역은 로그인한 모든 회원(관리자·운영진·회원)에게 열려 있다. */
  .matchup-edit{display:none;}
  body.can-matchup .matchup-edit{display:inherit;}
  body.can-matchup .matchup-edit.flex{display:flex;}
  body.can-matchup button.matchup-edit{display:inline-flex;}

  .inline-form{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
  .inline-form input, .inline-form select{
    padding:8px 10px;border:1px solid var(--border);border-radius:7px;background:var(--surface);
    color:var(--text);font-size:12.8px;font-family:inherit;
  }
  .inline-form label{font-size:11px;color:var(--text-muted);display:flex;flex-direction:column;gap:4px;font-weight:600;}

  /* bylaws accordion */
  details.rule-block{border-bottom:1px solid var(--border);padding:14px 0;}
  details.rule-block:first-child{padding-top:0;}
  details.rule-block summary{
    cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;
    font-weight:700;font-size:15px;
  }
  details.rule-block summary::-webkit-details-marker{display:none;}
  details.rule-block summary .chev{color:var(--court-600);transition:transform .15s ease;font-size:13px;}
  details.rule-block[open] summary .chev{transform:rotate(90deg);}
  .rule-item{margin-top:14px;padding-left:2px;}
  .rule-item h4{font-size:13.5px;color:var(--court-700);margin-bottom:5px;}
  .rule-item p{font-size:13.5px;line-height:1.75;color:var(--text);margin:0 0 12px;}

  .callout{
    background:var(--surface-2);border:1px solid var(--border);border-radius:9px;
    padding:12px 14px;font-size:12.5px;color:var(--text-muted);line-height:1.6;margin-bottom:18px;
    display:flex;gap:10px;align-items:flex-start;
  }
  .callout b{color:var(--text);}

  .dues-grid{table-layout:auto;width:100%;}
  .dues-grid th, .dues-grid td{padding:8px 3px;}
  .dues-grid th:nth-child(1), .dues-grid td:nth-child(1){min-width:110px;padding-left:12px;}
  .dues-grid th:nth-child(14), .dues-grid td:nth-child(14){min-width:90px;}
  .dues-grid td.month, .dues-grid th:nth-child(n+2):nth-child(-n+13){min-width:100px;}
  .dues-grid td.month{text-align:center;}
  .status-chip{
    display:inline-flex;min-width:0;width:100%;justify-content:center;align-items:center;
    padding:4px 6px;border-radius:7px;text-align:center;line-height:1.25;
    font-size:13px;font-weight:700;border:1px solid transparent;white-space:nowrap;
  }
  .status-chip[data-status="연회비"]{background:var(--good-bg);color:var(--good-fg);border-color:var(--good-line);}
  .status-chip[data-status="월회비"]{background:var(--info-bg);color:var(--info-fg);border-color:var(--info-line);}
  .status-chip[data-status="휴식"]{background:var(--warn-bg);color:var(--warn-fg);border-color:var(--warn-line);}
  .status-chip[data-status="휴식(환불완)"]{background:var(--clay-bg);color:var(--clay-fg);border-color:var(--clay-line);}
  .status-chip[data-status="장기휴식"]{background:var(--muted-bg);color:var(--muted-fg);border-color:var(--muted-line);}
  .status-chip[data-status="탈퇴"]{background:var(--bad-bg);color:var(--bad-fg);border-color:var(--bad-line);}
  .status-chip[data-status="–"]{background:transparent;color:var(--text-faint);border-color:var(--border);border-style:dashed;}

  footer.appfoot{margin-top:40px;padding-top:18px;border-top:1px solid var(--border);font-size:11.5px;color:var(--text-faint);}

  @media (max-width: 860px){
    #app.ready{flex-direction:column;}
    #sidebar{
      width:100%;height:auto;position:sticky;top:0;z-index:20;
      flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:space-between;
      padding:10px 14px;gap:6px 10px;
      box-shadow:0 2px 10px rgba(0,0,0,.15);
    }
    .brand{order:1;padding:0;font-size:16px;}
    .role-chip{
      order:2;width:auto;margin-top:0;padding:0;background:none;border:none;
      display:flex;align-items:center;gap:8px;
    }
    .role-chip .rc-label{display:none;}
    .role-chip .rc-value{margin-top:0;font-size:11.5px;}
    .role-chip button{width:auto;margin-top:0;padding:6px 10px;font-size:11px;white-space:nowrap;}
    nav.navlist{
      order:3;flex-basis:100%;flex-direction:row;flex-wrap:nowrap;flex:none;
      overflow-x:auto;-webkit-overflow-scrolling:touch;gap:4px;
      scrollbar-width:none;-ms-overflow-style:none;
      margin:0 -14px;padding:2px 14px 4px;width:calc(100% + 28px);
    }
    nav.navlist::-webkit-scrollbar{display:none;}
    .navlink{width:auto;flex:none;white-space:nowrap;padding:7px 12px;font-size:12.5px;}
    main#content{padding:20px 16px 60px;}
    .stat-grid{grid-template-columns:1fr 1fr;}
    /* '남 12 · 여 6'처럼 숫자+글자가 섞인 값은 타일 폭에 비해 28px가 너무
       커서 두 줄로 줄바꿈된다. 이 값만 좁혀서 한 줄에 들어오게 한다. */
    #stat-remain{font-size:19px;white-space:nowrap;}
    .card-grid-2{grid-template-columns:1fr;}
    .hbar-row{grid-template-columns:72px 1fr 56px;gap:8px;}

    /* 모바일: 코트 카드를 가로로 늘어놓고 옆으로 미는 대신 세로로 쌓아서,
       화면을 좌우로 밀지 않아도 한 라운드의 코트·휴식 정보가 다 보이게 한다.
       (이미지로 저장할 때는 아래 body.capturing 규칙이 다시 가로 배치로
       되돌려, 저장되는 이미지는 항상 같은 모양으로 나온다.) */
    #view-matchup{--matchup-text:14px; --matchup-label:11.5px;}
    #view-matchup .card-body{padding:14px;}
    #view-matchup .card-head h3{font-size:16px;}
    .matchup-round{margin-bottom:24px;}
    .matchup-round-head h4{font-size:18px;}
    .matchup-round-head .time-label{font-size:14px;}
    .matchup-round.has-overflow .matchup-round-head::after{content:none;}
    .matchup-round-body{flex-direction:column;gap:10px;overflow-x:visible;}
    .court-card, .court-empty, .matchup-resting{width:100%;min-width:0;max-width:none;}
    .matchup-panel thead th, .matchup-stats-card thead th,
    .matchup-panel tbody td, .matchup-stats-card tbody td{padding:9px 10px;}
    .matchup-meta{gap:10px 18px;padding:12px 13px;margin-bottom:14px;}
  }

  /* ---------- matchup maker ---------- */
  #view-matchup .card-head h3{font-size:18px;}
  /* 설정/참여자/통계 카드는 화면 폭을 다 쓰지 않고 한 줄이 편히 들어가는 폭으로 제한한다. */
  /* 대진표 카드도 참여자 목록과 똑같은 폭을 쓴다. 코트가 많아 한 줄이 넘치면
     카드 폭을 늘리는 대신 라운드 영역 안에서 가로 스크롤로 본다(모바일 잘림 방지). */
  .matchup-panel, .matchup-schedule-card{width:100%;max-width:820px;}
  /* 통계는 숫자 열이 많아 100% 폭으로 늘리면 열이 과하게 벌어진다. 내용만큼만 차지하게 둔다. */
  .matchup-stats-card{width:fit-content;max-width:100%;}
  .matchup-stats-card table{width:auto;}
  /* 참여자 표와 대진표가 같은 크기를 쓰도록 한 곳에서 관리한다. */
  #view-matchup{--matchup-text:15px; --matchup-label:12.5px;}
  .matchup-panel table, .matchup-stats-card table{font-size:var(--matchup-text);}
  .matchup-panel thead th, .matchup-stats-card thead th{font-size:var(--matchup-label);padding:11px 14px;}
  .matchup-panel tbody td, .matchup-stats-card tbody td{padding:12px 14px;}
  .matchup-panel .badge, .matchup-stats-card .badge{font-size:13px;padding:4px 12px;}
  /* 숫자 열은 좁고 가운데 정렬. 위 공용 규칙보다 뒤에 와야 적용된다. */
  .matchup-stats-card thead th, .matchup-stats-card tbody td{padding-left:10px;padding-right:10px;}
  .matchup-stats-card tbody td.mono{text-align:center;}
  .matchup-stats-card thead th:nth-child(n+3){text-align:center;}
  .matchup-round{margin-bottom:30px;}
  .matchup-round-head{display:flex;align-items:baseline;gap:12px;margin-bottom:14px;flex-wrap:wrap;}
  /* 코트가 카드 폭을 넘칠 때만, 잘린 게 아니라 옆으로 더 있다는 걸 알려준다. */
  .matchup-round.has-overflow .matchup-round-head::after{
    content:'좌우로 밀어서 보기 →';margin-left:auto;
    font-size:11.5px;color:var(--text-faint);white-space:nowrap;
  }
  body.capturing .matchup-round.has-overflow .matchup-round-head::after{content:none;}
  .matchup-round-head h4{margin:0;font-size:21px;font-weight:500;}
  .matchup-round-head .time-label{font-size:16px;color:var(--text-muted);font-family:var(--font-mono);}
  /* 한 라운드는 항상 한 줄로 두고, 좁은 화면에서는 가로 스크롤로 본다. */
  .matchup-round-body{
    display:flex;gap:14px;align-items:stretch;flex-wrap:nowrap;
    overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:6px;
  }
  /* 이미지로 저장할 때는 스크롤/폭 제한을 모두 풀어 잘림 없이 캡처되게 한다.
     모바일에서 라운드를 세로로 쌓아 보여주는 동안에도, 저장되는 이미지는
     항상 코트가 가로로 나란한 모양으로 나오도록 되돌린다(폭 계산 로직도
     가로 배치를 전제로 하므로 여기서 맞춰줘야 한다). */
  body.capturing .matchup-round-body,
  body.capturing .table-wrap{overflow:visible;}
  body.capturing .matchup-round-body{flex-direction:row;}
  body.capturing .court-card,
  body.capturing .court-empty{width:auto;min-width:250px;max-width:none;}
  body.capturing .matchup-resting{width:auto;min-width:190px;max-width:none;}
  body.capturing .matchup-schedule-card,
  body.capturing .matchup-stats-card{width:max-content;min-width:0;max-width:none;}
  /* 캡처 대상 자체도 내용에 맞춰 줄여야 좌우 여백이 같아진다.
     (대진표는 JS가 가장 넓은 라운드 폭을 인라인으로 지정해 이 값을 덮는다)
     배경은 흰 종이 대신 앱의 바탕 톤을 써서 흰 코트 카드가 도드라지게 한다. */
  body.capturing #matchup-schedule,
  body.capturing #matchup-stats-capture{
    width:max-content;background:var(--bg);padding:14px;
  }
  /* 종이 톤 위에서는 요약 바도 코트 카드와 같은 흰 카드로 맞춘다.
     작성자·작성 일시처럼 사진에는 필요 없는 관리용 항목은 빼고, 남는
     줄·라운드 사이 여백도 줄여 모바일 화면에서도 내용이 더 크게 보이게 한다. */
  body.capturing .matchup-meta{background:var(--surface);padding:10px 12px;gap:8px 18px;margin-bottom:10px;}
  body.capturing .mm-item.mm-capture-hide{display:none;}
  /* 마지막 라운드 아래 빈 공간과 스크롤 여백을 없앤다. */
  body.capturing .matchup-round{margin-bottom:16px;}
  body.capturing .matchup-round:last-child{margin-bottom:0;}
  body.capturing .matchup-round-head{margin-bottom:8px;}
  body.capturing .matchup-round-body{padding-bottom:0;gap:10px;}
  /* 카드는 기본 250px이되, 이름이 길면 줄어들지 않고 늘어난다(글자 잘림 방지).
     줄이 넘치는 만큼은 라운드 영역의 가로 스크롤이 받아준다. */
  .court-card{
    flex:0 0 auto;min-width:250px;border-radius:14px;overflow:hidden;background:var(--surface);
    border:1px solid var(--border);border-top-width:3px;
  }
  .court-card-top{
    display:flex;justify-content:space-between;align-items:center;
    padding:11px 14px;font-size:var(--matchup-label);font-weight:500;
    letter-spacing:.06em;text-transform:uppercase;
  }
  .court-card-top .ct-court{font-family:var(--font-mono);}
  .court-body{padding:16px 12px 18px;}
  .court-team{font-size:var(--matchup-text);font-weight:400;line-height:1.5;text-align:center;color:var(--text);white-space:nowrap;}
  .court-vs{display:flex;align-items:center;gap:12px;margin:10px 2px;color:var(--text-muted);font-size:13px;letter-spacing:.2em;}
  .court-vs::before,.court-vs::after{content:'';flex:1;height:1px;background:var(--border);}
  .court-card.type-md{border-top-color:var(--info-fg);}
  .court-card.type-md .court-card-top{background:var(--info-bg);color:var(--info-fg);}
  .court-card.type-wd{border-top-color:var(--rose-fg);}
  .court-card.type-wd .court-card-top{background:var(--rose-bg);color:var(--rose-fg);}
  .court-card.type-xd{border-top-color:var(--good-fg);}
  .court-card.type-xd .court-card-top{background:var(--good-bg);color:var(--good-fg);}
  .court-card.type-etc{border-top-color:var(--clay-fg);}
  .court-card.type-etc .court-card-top{background:var(--clay-bg);color:var(--clay-fg);}
  .court-empty{display:flex;align-items:center;justify-content:center;min-height:90px;padding:0 20px;border:1.5px dashed var(--border);border-radius:14px;color:var(--text-muted);font-size:var(--matchup-text);flex:0 0 auto;min-width:250px;}
  /* 대진표 상단 요약: 대진 일시 · 작성/저장자 · 저장 시각을 한 곳에 모아 보여준다. */
  .matchup-meta{
    display:flex;flex-wrap:wrap;gap:12px 28px;align-items:flex-start;
    padding:13px 16px;margin-bottom:18px;
    border:1px solid var(--border);border-radius:12px;background:var(--surface-2);
  }
  .matchup-meta .mm-item{display:flex;flex-direction:column;gap:3px;min-width:0;}
  .matchup-meta .mm-label{font-size:10px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-faint);white-space:nowrap;}
  .matchup-meta .mm-value{font-size:13px;font-weight:700;color:var(--text);}
  .matchup-meta .mm-value .mm-sub{font-weight:500;color:var(--text-muted);font-size:11.5px;margin-left:5px;}
  .matchup-meta .mm-item.mm-wide{flex:1 1 100%;border-top:1px dashed var(--border);padding-top:10px;}
  /* 이름을 눌러 자리를 바꾸는 건 '편집' 버튼으로 편집 모드를 켰을 때만
     된다 - 실수로 이름을 눌러 자리가 바뀌는 걸 막기 위함. */
  .mp-name{cursor:default;display:inline-flex;align-items:center;gap:6px;padding:2px 6px;border-radius:7px;}
  body.can-matchup #matchup-schedule.editing-names .mp-name{cursor:pointer;}
  body.can-matchup #matchup-schedule.editing-names .mp-name:hover{background:color-mix(in srgb, var(--court-600) 12%, transparent);}
  .mp-name.mp-selected{box-shadow:0 0 0 1.5px var(--court-600) inset;background:color-mix(in srgb, var(--court-600) 10%, transparent);}
  .mp-dot{width:6px;height:6px;border-radius:50%;flex:none;display:inline-block;}
  .mp-m .mp-dot{background:#3d84c6;}
  .mp-f .mp-dot{background:#d4548c;}
  .mp-unknown .mp-dot{background:var(--text-faint);}
  .mp-sep{color:var(--text-faint);padding:0 3px;}
  .matchup-resting{
    flex:0 0 auto;min-width:190px;background:var(--surface);border:1px solid var(--border);border-radius:14px;
    border-top:3px solid var(--muted-fg);
    overflow:hidden;font-size:var(--matchup-text);color:var(--text);
  }
  .matchup-resting h5{
    margin:0 0 10px;padding:11px 14px;font-size:var(--matchup-label);font-weight:500;
    background:var(--muted-bg);color:var(--muted-fg);letter-spacing:.06em;
  }
  .matchup-resting .mp-body{padding:0 12px 14px;}
  .matchup-resting .mp-name{display:flex;padding:3px 5px;}
