/* 선택한 A안: 선명한 슬레이트·민트·라임. 글꼴·그림은 기존 앱 자산을 재사용한다. */

@font-face  {
    font-family: Pretendard;
    src: url('/fonts/Pretendard-Regular.otf') format('opentype');
    font-weight: 400 500;
    font-display: swap;
}

@font-face  {
    font-family: Pretendard;
    src: url('/fonts/Pretendard-Bold.otf') format('opentype');
    font-weight: 600 900;
    font-display: swap;
}

/*
    ★ 2026-09-21: 색을 <b>앱과 같은 것</b>으로 맞췄다(회원님 「포털 디자인도 앱 디자인과 같은
      스타일로 맞춰주고」).

    ★ <b>2026-09-22 되돌림.</b> 하루 동안 이 자리에 Navy #0B1020 · Cyan #22D3EE가 들어가 있었다.
      출처는 앱의 `UI/DesignTokens.cs`였는데 <b>그 파일이 앱 화면과 다르다</b> —
      회원님이 보내 주신 앱 홈 화면은 슬레이트 바탕(#202B3D 계열)에 라임(#D1F58E) 강조,
      고른 카드의 테두리는 민트(#A4F0D7)다. 아래 값이 그 화면에서 읽은 것이다.
      <b>기준은 코드가 아니라 도는 화면이다.</b> `DesignTokens.cs`는 「값은 포털과 같다」고
      적어 두었지만 실제로는 둘 다 어긋나 있었다 — 그 파일을 고치는 일은 앱 쪽에 남는다.

    ★ 이름(--dfz-lime 따위)은 그대로 두었다. 쓰는 자리가 마흔 곳이 넘어 이름까지 바꾸면
      이번 변경에서 무엇이 바뀌었는지 읽기 어려워진다. <b>이름은 자리를, 값은 앱을 가리킨다.</b>

    ★ <b>강조 단추의 글자는 Navy다.</b> 앱 명세 §3.1 — Cyan 위에 밝은 글자를 얹으면
      대비가 1.50:1로 무너진다. 밝은 바탕에 밝은 글자를 얹는 가장 흔한 실수다.

    ★ 강조 단추의 글자는 어두운 색(--dfz-button-ink)이다. 밝은 라임 위에 밝은 글자를 얹으면
      대비가 무너진다 — 밝은 바탕에 밝은 글자를 얹는 가장 흔한 실수다.
*/
:root {
    color-scheme: dark;
    --dfz-bg: #202B3D;
    --dfz-bg-top: #233348;
    --dfz-surface: #30435A;
    --dfz-surface-2: #293B50;
    --dfz-panel: #1E2C3E;
    --dfz-text: #F8FCFF;
    --dfz-muted: #CCDCE9;
    --dfz-lavender: #C4B4FF;
    --dfz-lime: #D1F58E;
    --dfz-mint: #A4F0D7;
    --dfz-button-ink: #1D2B36;
    --dfz-line: #647F98;
    --dfz-hover: #3C526B;
    --dfz-radius: 24px;
    /* 둥글기는 세 단계뿐이다(2026-10-10 Impeccable 점검 — 판마다 12가지였다). 작게: 태그 · 보통: 단추·입력칸 · 크게(--dfz-radius): 판·카드. */
    --dfz-radius-sm: 8px;
    --dfz-radius-md: 12px;
    /* ★ 2026-09-27 — 아래는 규칙 안에 숫자로 흩어져 있던 색을 이름으로 모은 것이다.
       이름이 있어야 BrandContrastTests가 읽어 잰다. 쟀더니 둘이 모자랐다:
       지우기 단추 글자 3.67:1·가리킬 때 3.00:1(→ 5.04:1·4.94:1), 입력칸 테두리 2.42:1(→ 표면 위 3.39:1).
       --dfz-line-soft는 어디서도 안 써서 지웠다. */
    --dfz-control-line: #8198AF;   /* 입력칸 테두리 — 비텍스트 3:1(WCAG 1.4.11) */
    --dfz-danger: #8E596D;         /* 되돌릴 수 없는 단추 */
    --dfz-danger-hover: #86526A;   /* 위에 공통 hover 밝기(1.08)가 한 번 더 얹힌다 */
    --dfz-danger-ink: #FFF1F5;
    --dfz-danger-edge: #C78EA2;
    --dfz-error-bg: #513B49;       /* 오류 알림·지우기 확인 칸 */
    --dfz-error-edge: #A66F83;
    --dfz-error-ink: #FFD0D8;
    --dfz-notice-bg: #355754;      /* 잘됐다는 알림 */
    /* ★ 2026-11-11 개발일지 딱지(회원님 「색으로도 구분되면 빠르게 찾을 수 있을 것 같아」).
       상태는 채운 딱지(바탕색 + --dfz-button-ink 글자), 분야는 테두리 딱지(카드 위에 그 색 글자·테두리).
       색만으로 가르지 않는다 — 글자가 늘 함께 있고, 상태와 분야는 딱지 꼴(채움/테두리)도 다르다.
       대비는 BrandContrastTests가 잰다. 반영됨은 --dfz-mint를 그대로 쓴다. */
    --dfz-tag-open: #FFD27A;       /* 반영 전 */
    --dfz-tag-closed: #AEBBC8;     /* 닫힘 */
    --dfz-tag-game: #FFB3C7;       /* 분야: 게임 */
    --dfz-tag-app: #C4B4FF;        /* 분야: 앱 화면 */
    --dfz-tag-portal: #8FD3FF;     /* 분야: 포털 */
    --dfz-tag-install: #D1F58E;    /* 분야: 설치·업데이트 */
    --dfz-tag-process: #FFC79A;    /* 분야: 개발 과정 */
    --dfz-tag-other: #CCDCE9;      /* 분야: 그 밖 */
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    min-height: 100vh;
    font-family: Pretendard,'Malgun Gothic','Segoe UI',system-ui,sans-serif;
    /* ★ 2026-09-21: 본문 기준을 16px로 적어 둔다(회원님 「포털 전체 글자 크기를 역할에 맞게
       수정해」). 전에는 기준이 없어 자리마다 13·14px로 내려 썼고, 그것이 「작아서 잘 보이지
       않는 글씨」의 정체였다. 이제 작게 쓰는 자리는 <b>그 자리에서 따로</b> 적는다. */
    font-size: 16px;
    line-height: 1.6;
    color: var(--dfz-text);
    background: var(--dfz-bg);
}

a {
    color: var(--dfz-lavender);
    text-underline-offset: .22em;
}

a:hover {
    color: var(--dfz-lime);
}

button,input,select,textarea {
    font: inherit;
}

:focus-visible {
    outline: 3px solid var(--dfz-lavender);
    outline-offset: 4px;
}

img {
    max-width: 100%;
}

.skip-link {
    position: absolute;
    left: 1rem;
    top: -6rem;
    z-index: 30;
    padding: .7rem 1rem;
    background: var(--dfz-lime);
    color: var(--dfz-button-ink);
    border-radius: var(--dfz-radius-md);
}

.skip-link:focus {
    top: 1rem;
}

/* 회원 권한에 따라 늘어나는 메뉴는 줄을 바꾼다. */

.site-header {
    border-bottom: 1px solid var(--dfz-line);
    background: var(--dfz-bg-top);
    border-color: var(--dfz-line);
}

.header-inner {
    max-width: 1520px;
    margin: auto;
    padding: 22px 40px;
    display: flex;
    flex-wrap: wrap;
    gap: 20px 36px;
    align-items: center;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
    text-decoration: none;
    color: var(--dfz-text);
    font-size: 22px;
    font-weight: 800;
    letter-spacing: -.04em;
}

/* ★ 2026-09-29 로고를 앱 아이콘의 「DFZ」 동그라미로(회원님 「앱 내의 로고와 포털의 로고를 설치본 앱 아이콘으로 통일」).
   전에는 라벤더 판 위의 번개 그림(svg)이었다. 그림 자체가 동그라미라 판을 두지 않는다. */
.brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
}

.brand-mark img {
    width: 44px;
    height: 44px;
    display: block;
}

.site-nav {
    display: flex;
    flex-wrap: wrap;
    flex: 1;
    align-items: center;
    gap: 6px 12px;
    min-width: 0;
}

.site-nav>a,.nav-user>a:not(.btn) {
    padding: 9px 12px;
    border-radius: var(--dfz-radius-md);
    color: var(--dfz-muted);
    text-decoration: none;
    font-weight: 600;
}

.site-nav>a:hover,.site-nav>a[aria-current=page] {
    background: var(--dfz-hover);
    color: var(--dfz-text);
}

.nav-user {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.nav-user a {
    overflow-wrap: anywhere;
}

.nav-user form {
    margin: 0;
}

/* 관리 링크 줄 — 머리띠 아래 둘째 줄(2026-09-21).
   ★ 윗줄보다 한 단 낮게 보이게 둔다. 늘 쓰는 메뉴가 아니라 관리하는 사람만 쓰는 자리다. */
.admin-bar {
    border-top: 1px solid var(--dfz-hover);
    background: var(--dfz-panel);
}

.admin-bar-inner {
    max-width: 1520px;
    margin: auto;
    padding: 8px 40px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
}

.admin-bar-label {
    /* ★ 2026-10-01: 링크와 같은 보라색이라 누를 수 있는 것처럼 보였다 — 이름표는 회색이다. */
    color: var(--dfz-muted);
    font-weight: 700;
    /* ★ 2026-09-22: 15px은 옆 링크(16px)보다 작아 이름표로 읽히지 않았다(회원님 제보). */
    font-size: 17px;
    letter-spacing: 0.04em;
    padding-right: 8px;
    margin-right: 4px;
    border-right: 1px solid var(--dfz-hover);
}

.admin-bar-inner a {
    padding: 8px 12px;
    border-radius: var(--dfz-radius-sm);
    color: var(--dfz-muted);
    text-decoration: none;
    font-weight: 600;
    /* ★ 14px은 주 메뉴보다 작아 「보조」가 아니라 「안 보이는」 것이 됐다(회원님 제보). */
    font-size: 16px;
}

.admin-bar-inner a:hover,
.admin-bar-inner a[aria-current=page] {
    background: var(--dfz-hover);
    color: var(--dfz-text);
}

main {
    max-width: 1520px;
    margin: 48px auto 0;
    padding: 0 40px 80px;
    min-height: calc(100vh - 230px);
    margin-top: 40px;
}

h1,h2,h3 {
    line-height: 1.3;
    letter-spacing: -.035em;
    overflow-wrap: anywhere;
}

h1 {
    font-size: clamp(28px,3vw,40px);
    margin: 0 0 24px;
}

h2 {
    font-size: 25px;
    margin: 40px 0 20px;
}

p {
    overflow-wrap: anywhere;
}

.page-intro {
    color: var(--dfz-muted);
    margin: -12px 0 28px;
}

.site-footer {
    max-width: 1440px;
    margin: 0 auto;
    padding: 24px 0 32px;
    border-top: 1px solid var(--dfz-line);
    color: var(--dfz-muted);
    display: flex;
    justify-content: space-between;
    gap: 16px;
    font-size: 13px;
    border-color: var(--dfz-line);
}

/* 홈 — 앱 활동 카드와 같은 그림·표면·강조색. */

.hero {
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    align-items: center;
    gap: 70px;
    padding: 12px 0 44px;
}

.hero h1 {
    font-size: clamp(36px, 3.2vw, 56px);
    line-height: 1.22;
    margin: 0 0 24px;
}

.hero h1 em {
    color: var(--dfz-mint);
    font-style: normal;
}

.hero-copy>p {
    color: var(--dfz-muted);
    max-width: 34rem;
    font-size: 17px;
    line-height: 1.8;
}

.hero-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 30px;
}

/* 홈 사실 한 줄 — 숫자 묶음을 대신한다(2026-10-10). */
.hero-copy>p.hero-facts {
    margin-top: 26px;
    color: var(--dfz-muted);
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

/* B안 — 밝은 민트 바탕에 여러 연령의 참여자와 큰 화면을 함께 보여 준다. */
.hero-art {
    position: relative;
    aspect-ratio: 7 / 4;
    border: 1px solid #b8ddcf;
    border-radius: var(--dfz-radius);
    background: #d9f4e9;
    color: #203348;
    overflow: hidden;
    isolation: isolate;
}

.hero-art img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -1;
}

.hero-art-label {
    position: absolute;
    left: 28px;
    bottom: 22px;
    color: #203348;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.5;
}

.hero-art-caption {
    width: 55%;
    padding: 28px 0 0 28px;
    overflow-wrap: anywhere;
}

.hero-art-caption strong {
    display: block;
    font-size: clamp(22px, 2.1vw, 34px);
    line-height: 1.25;
    letter-spacing: -.04em;
    text-wrap: balance;
}

.hero-art-caption span {
    display: block;
    margin-top: 14px;
    color: #203348;
    font-size: 14px;
    line-height: 1.6;
}

.section-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 20px;
}

.section-heading h2 {
    margin: 0;
}

.section-heading a {
    font-size: 14px;
}

/* 필터·카드 */

.chip-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 12px 0;
}

.chip-label {
    color: var(--dfz-muted);
    font-size: 14px;
    margin-right: 6px;
}

.chip {
    display: inline-flex;
    align-items: center;
    min-height: 42px;
    padding: 8px 18px;
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius-md);
    background: var(--dfz-surface);
    color: var(--dfz-text);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
}

a.chip:hover {
    border-color: var(--dfz-lavender);
    color: var(--dfz-lavender);
}

.chip.on {
    background: var(--dfz-lavender);
    color: var(--dfz-button-ink);
    border-color: var(--dfz-lavender);
}

.tag {
    display: inline-block;
    padding: 4px 10px;
    border-radius: var(--dfz-radius-sm);
    background: #4A496A;
    color: #E8E0FF;
    font-size: 12px;
    font-weight: 600;
}

.tag.alt {
    background: #355754;
    color: #C6F9EA;
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(4,minmax(0,1fr));
    gap: 22px;
    margin-top: 24px;
}

.game-card {
    background: var(--dfz-surface);
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    min-width: 0;
    transition: border-color .16s,box-shadow .16s;
    box-shadow: none;
    border-color: var(--dfz-line);
}

.game-card:hover,.game-card:focus-within {
    border-color: var(--dfz-lavender);
    box-shadow: 0 0 0 2px #bcabf426;
}

.game-thumb {
    height: 182px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    background: var(--dfz-hover);
    border-bottom: 1px solid var(--dfz-line);
}

.game-thumb::after {
    content: '';
    display: block;
    width: 82%;
    height: 83%;
    margin-top: 26px;
    background: var(--game-art,url('/images/lobby/art-motion.png')) center/contain no-repeat;
}

.cat-Reaction {
    --game-art: url('/images/lobby/art-energy.png');
}

.cat-Relay {
    --game-art: url('/images/lobby/art-run.png');
}

.cat-Memory {
    --game-art: url('/images/lobby/art-color.png');
}

.cat-Endurance {
    --game-art: url('/images/lobby/art-squat.png');
}

.cat-Cooperation {
    --game-art: url('/images/lobby/art-team.png');
}

.cat-Accuracy {
    --game-art: url('/images/lobby/art-mole.png');
}

.cat-Balance {
    --game-art: url('/images/lobby/art-motion.png');
}

.game-thumb .badge {
    position: absolute;
    top: 16px;
    left: 18px;
    color: var(--dfz-text);
    font-size: 12px;
    font-weight: 600;
}

.game-body {
    padding: 18px 22px 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1;
}

.game-body h3 {
    margin: 0;
    font-size: 21px;
}

.game-body h3 a {
    color: var(--dfz-text);
    text-decoration: none;
}

.game-body h3 a:hover {
    color: var(--dfz-lavender);
}

.game-desc {
    color: var(--dfz-muted);
    font-size: 14px;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    flex: 1;
    line-height: 1.7;
}

.game-meta {
    color: var(--dfz-muted);
    font-size: 13px;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.game-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.game-detail-art {
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    height: 260px;
    margin-bottom: 28px;
    background-color: var(--dfz-surface);
}

.search-form {
    display: flex;
    gap: 8px;
    margin-left: auto;
    max-width: 100%;
}

.search-form input {
    width: 16rem;
    min-width: 0;
}

.more-games {
    text-align: center;
    margin-top: 28px;
}

/* 버튼·입력칸 */

button,.btn {
    padding: 11px 22px;
    min-height: 44px;
    cursor: pointer;
    border: 1px solid transparent;
    border-radius: var(--dfz-radius-md);
    font-weight: 700;
    font-size: 15px;
    line-height: 1.5;
    background: var(--dfz-lime);
    color: var(--dfz-button-ink);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    transition: filter .15s,border-color .15s;
}

button:hover,.btn:hover {
    filter: brightness(1.08);
    color: var(--dfz-button-ink);
}

button.quiet,.btn.quiet {
    background: var(--dfz-surface);
    color: var(--dfz-text);
    border-color: var(--dfz-line);
}

button.quiet:hover,.btn.quiet:hover {
    border-color: var(--dfz-lavender);
}

button:disabled {
    opacity: .5;
    cursor: not-allowed;
    filter: none;
}

label {
    display: block;
    margin: 18px 0 8px;
    font-weight: 600;
    /* 입력칸 위의 이름표. 본문보다 한 단 작은 것은 <b>일부러다</b> — 값이 주인공이다. */
    font-size: 15px;
}

input[type=text],input[type=email],input[type=password],input[type=number],input[type=url],textarea,select {
    width: 100%;
    padding: 12px 14px;
    background: var(--dfz-surface);
    color: var(--dfz-text);
    border: 1px solid var(--dfz-control-line);
    border-radius: var(--dfz-radius-md);
    min-height: 46px;
}

input::placeholder,textarea::placeholder {
    color: var(--dfz-muted);
    opacity: .8;
}

input[type=checkbox],input[type=radio] {
    accent-color: var(--dfz-lavender);
}

input:focus-visible,textarea:focus-visible,select:focus-visible {
    outline-offset: 2px;
}

textarea {
    resize: vertical;
}

form>button {
    margin-top: 22px;
}

.search-form>button,.nav-user button,.chip-row>button {
    margin-top: 0;
}

main>form:only-of-type,form.panel {
    max-width: 36rem;
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    background: var(--dfz-surface);
    padding: 26px 30px 30px;
    margin-top: 24px;
}

form.panel>label:first-child,main>form>label:first-child {
    margin-top: 0;
}

.account-page main {
    max-width: 640px;
    margin-top: 64px;
}

.account-page main>h1 {
    margin-bottom: 18px;
}

.account-page main>form {
    max-width: none;
}

.account-page form p {
    color: var(--dfz-muted);
    font-size: 14px;
}

.account-page form>button {
    width: 100%;
}

.account-note {
    color: var(--dfz-muted);
    font-size: 14px;
}

/* 긴 표는 내부에서 가로로 움직인다. */

.error,.notice {
    padding: 16px 20px;
    border-radius: var(--dfz-radius-md);
    overflow-wrap: anywhere;
}

.error {
    color: var(--dfz-error-ink);
    background: var(--dfz-error-bg);
    border: 1px solid var(--dfz-error-edge);
}

.notice {
    color: var(--dfz-text);
    background: var(--dfz-notice-bg);
    border: 1px solid var(--dfz-line);
}

/* 연결한 기기 — 표 칸 안에서 이름 칸과 「이름 바꾸기」를 한 줄로(2026-09-29) */
.inline-rename { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin: 0; }
.inline-rename input[type="text"] { min-width: 12rem; flex: 1 1 12rem; }

/* 연결한 기기 — 기기마다 한 장(2026-09-30). 계정 화면(640px)에 표 다섯 칸이 안 들어가 옆으로 밀렸다.
   ★ 계정 화면의 「form>button은 폭 100%」(쌓는 폼용)를 여기서는 끈다 — 이름 칸 옆의 단추가 한 줄을 다 차지해
     칸 밑으로 떨어져 있었다(회원님 사진). */
.device-list { list-style: none; padding: 0; margin: 20px 0; display: grid; gap: 12px; }
.device-card {
    background: var(--dfz-surface);
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    padding: 16px 18px;
    display: grid;
    gap: 12px;
}
.account-page .device-card form>button { width: auto; flex: none; margin: 0; }
.device-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; color: var(--dfz-muted); font-size: 14px; }
.device-disconnect { margin: 0 0 0 auto; }
.state-pill {
    display: inline-flex;
    align-items: center;
    padding: 3px 12px;
    border-radius: 999px;
    border: 1px solid var(--dfz-line);
    color: var(--dfz-muted);
    font-size: 13px;
    font-weight: 700;
}
.state-pill.live { background: var(--dfz-mint); border-color: transparent; color: var(--dfz-button-ink); }

/* 내 계정(2026-10-01 회원님 「내 계정 메뉴 다시 디자인 하기」) — 머리(첫 글자·닉네임·이메일·등급·상태) · 카드 셋 · 탈퇴 칸.
   ★ 단추는 글 폭(계정 화면의 「form>button 폭 100%」를 여기서 끈다) — 앱의 단추 규칙과 같다. */
.acct-head { display: flex; align-items: center; gap: 16px; margin: 8px 0 22px; }
.acct-avatar {
    width: 56px; height: 56px; border-radius: 50%; flex: none;
    background: var(--dfz-mint); color: var(--dfz-button-ink);
    display: grid; place-items: center; font-weight: 800; font-size: 24px;
}
.acct-who { display: grid; gap: 4px; min-width: 0; }
.acct-name { font-size: 22px; font-weight: 800; }
.acct-mail { color: var(--dfz-muted); font-size: 14px; overflow-wrap: anywhere; }
.acct-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.acct-chip {
    display: inline-block; padding: 2px 10px; border-radius: 999px; border: 1px solid var(--dfz-line);
    color: var(--dfz-muted); font-size: 12px; font-weight: 700; vertical-align: middle;
}
.acct-chip.on { background: var(--dfz-mint); color: var(--dfz-button-ink); border-color: transparent; }
.acct-card {
    background: var(--dfz-surface); border: 1px solid var(--dfz-line); border-radius: var(--dfz-radius);
    padding: 20px 22px; margin: 0 0 16px;
}
.acct-card h2 { font-size: 15px; margin: 0 0 12px; color: var(--dfz-muted); font-weight: 700; letter-spacing: .02em; }
.account-page .acct-card form { margin: 0; padding: 0; border: 0; background: none; }
.acct-card label { margin: 12px 0 6px; }
.acct-card label:first-of-type { margin-top: 0; }
.account-page .acct-card .acct-hint { color: var(--dfz-muted); font-size: 13px; margin: 6px 0 0; }
.acct-actions { display: flex; justify-content: flex-end; margin-top: 16px; }
.account-page .acct-actions button { width: auto; margin: 0; padding: 10px 28px; }
.acct-rows { display: grid; }
.acct-row { display: flex; align-items: center; gap: 14px; padding: 14px 0; border-top: 1px solid var(--dfz-line); }
.acct-row:first-child { border-top: 0; padding-top: 2px; }
.acct-row .what, .acct-danger .what { flex: 1; min-width: 0; display: grid; gap: 2px; }
.acct-row .what b { font-size: 15px; }
.acct-row .what > span, .acct-danger .what > span { color: var(--dfz-muted); font-size: 13px; }
.acct-row .btn, .acct-danger .btn { padding: 8px 16px; min-height: 38px; font-size: 14px; flex: none; }
.acct-foot { color: var(--dfz-muted); font-size: 13px; margin: 4px 0 20px; }
.acct-danger {
    display: flex; align-items: center; gap: 14px; padding: 14px 22px;
    border: 1px solid var(--dfz-danger-edge); border-radius: var(--dfz-radius);
}
.acct-danger .btn { background: transparent; color: var(--dfz-danger-ink); border-color: var(--dfz-danger-edge); }

/* 관리자 「회원 정보」의 바뀌지 않는 값(2026-09-30) — 이름표와 값을 두 칸으로. */
.member-facts { display: grid; grid-template-columns: max-content 1fr; gap: 8px 18px; margin: 12px 0 8px; max-width: 36rem; }
.member-facts dt { color: var(--dfz-muted); font-size: 14px; }
.member-facts dd { margin: 0; }

.table-scroll {
    max-width: 100%;
    overflow-x: auto;
    border-radius: var(--dfz-radius);
    margin: 20px 0;
}

/* ★ 가로로 늘어선 폼에서는 「쌓는 폼」의 여백을 걱어낸다(2026-09-21).
   바탕에 <c>form&gt;button { margin-top: 22px }</c>와 <c>label { margin: 18px 0 8px }</c>가 있다 —
   이름표 → 입력칸 → 단추를 세로로 쌓는 화면(로그인 따위)을 위한 것이다.
   가로로 놓으면 <c>align-items: center</c>가 <b>여백까지 들어있는 상자</b>를 가운데 맞추므로
   단추가 11px(22의 절반), 이름표가 5px(18과 8의 차의 절반)만큼 내려앉는다.
   회원님이 「수직 정렬이 잘 안 되어 있다」고 본 것이 이 숫자다. */
.bulk-bar>button,
.bulk-bar>label,
.bulk-bar .bulk-check,
.bulk-danger>label,
.bulk-danger>button,
.decision-form>button,
.decision-form>label,
.inline-rename>button,
.inline-rename>input {
    margin: 0;
}

/* 묶음 막대 — 표 위에 서서 「고른 사람들」을 한 번에 처리한다(2026-09-21).
   ★ 단추는 줄지 않고 입력칸만 줄어든다. 좁아지면 줄바꿈해서 내려갈 뿐 사라지지 않는다. */
.bulk-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    margin: 16px 0 10px;
    padding: 12px 14px;
    background: var(--dfz-surface);
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius-md);
}

.bulk-bar input[type=text] {
    width: auto;
    flex: 1 1 8rem;
    min-width: 6rem;
    /* ★ 상한을 둔다. 없으면 넓은 화면에서 사유 칸 하나가 남은 폭을 다 먹어 늘어져 보인다. */
    max-width: 22rem;
}

.bulk-bar button {
    flex: 0 0 auto;
    white-space: nowrap;
    /* ★ 2026-09-21: 단추는 큰데 글자가 작아 보인다는 제보. 글자를 키우고 좌우 여백을 줄여
       단추 안에서 글자가 차지하는 몫을 늘린다 — 단추를 키우는 것과는 다른 일이다. */
    font-size: 16px;
    padding: 11px 18px;
}

.bulk-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
    /* ★ 이름표가 본문 글자(14px)라 옆의 단추보다 작아 보였다. 단추와 같은 크기로 올린다. */
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
}

/* 표 안이든 막대든, 체크 칸은 같은 크기·같은 색이다. */
.bulk-check input[type=checkbox],
td input[type=checkbox],
th input[type=checkbox] {
    /* ★ 2026-09-22: 22px을 적어 두고도 13px로 그려지고 있었다(뒤의 규칙이 덮었다).
       그 규칙을 지우고 24px로 올린다 — 손가락으로 누르는 크기이기도 하다. */
    width: 24px;
    height: 24px;
    min-height: 0;
    margin: 0;
    padding: 0;
    accent-color: var(--dfz-lavender);
    vertical-align: middle;
}

/* 고른 사람 수. 스크립트가 고쳐 쓴다 — 스크립트가 없으면 「고른 사람 없음」 그대로 있다. */
.pick-count {
    font-weight: 700;
    white-space: nowrap;
}

/* 되돌릴 수 없는 자리는 눈에 띄게 갈라 둔다. */
.bulk-danger {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 16rem;
    padding-left: 12px;
    border-left: 1px solid var(--dfz-line);
}

/* 되돌릴 수 없는 단추는 같은 초록이면 안 된다 — 승인과 삭제가 나란히 있는 자리다.
   알림 글상자(.error)와 같은 갈래의 색이다 — 포털에서 「조심」을 뜻하는 색이 그것이다.
   ★ 2026-09-27: 바탕이 테두리 색(#A66F83)과 같아서 흰 글자가 3.67:1(가리킬 때 3.00:1)이었다. 한 단 어둡게 내려 5.04:1. */
button.danger {
    background: var(--dfz-danger);
    color: var(--dfz-danger-ink);
    border-color: var(--dfz-danger-edge);
}

button.danger:hover {
    background: var(--dfz-danger-hover);
}

/* 지우기 전 확인 칸 — 무엇을 지우는지 이름으로 보여 주는 자리(2026-09-21).
   ★ 되돌릴 수 없는 자리라 다른 칸과 <b>색으로</b> 갈라 둔다. 표 위에 끼어들어 눈에 먼저 든다. */
.confirm-panel {
    margin: 20px 0 8px;
    padding: 20px 24px 8px;
    background: var(--dfz-error-bg);
    border: 1px solid var(--dfz-error-edge);
    border-radius: var(--dfz-radius);
}

.confirm-panel>h2 {
    margin: 0 0 6px;
    font-size: 22px;
}

.confirm-panel>p {
    margin: 0 0 12px;
}

.confirm-list {
    margin: 0 0 4px;
    padding-left: 22px;
    max-height: 40vh;
    overflow-y: auto;
}

.confirm-list li {
    padding: 2px 0;
}

/* 이름 옆에 붙는 소속 — 이름이 주인공이다. */
.muted {
    color: var(--dfz-muted);
}

.confirm-panel .bulk-bar {
    background: transparent;
    border: 0;
    padding: 8px 0 12px;
    margin: 0;
}

.bulk-hint {
    margin: 0 0 14px;
    opacity: 0.85;
}

/* ★ 2026-09-22: 여기 있던 <c>td input[type=checkbox] { width: auto }</c>를 지웠다.
   위쪽에서 22px을 준 규칙을 <b>뒤에서 되돌리고</b> 있었다 — 재 보니 13×22px이었다.
   높이만 먹고 너비가 안 먹은 까닭이 이것이다. 크기는 한 자리(아래 규칙)에서만 정한다. */

/* 눈으로는 안 보이고 화면 읽어 주는 장치에는 읽히는 이름표. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* 표 안의 「결정」 칸 — 사유 한 칸과 단추 둘이 한 줄에 선다.
   ★ 2026-09-21 회원님 제보: 승인 대기 화면에서 단추가 오른쪽으로 밀려 안 보였다.
     까닭은 input[type=text]의 width:100%다 — 사유가 칸을 다 먹고 단추를 밖으로 밀어냈다.
     여기서는 사유를 줄어들 수 있게(flex) 하고 단추는 줄지 않게 못 박는다. */
.decision-form {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

.decision-form input[type=text] {
    width: auto;
    flex: 1 1 7rem;
    min-width: 5rem;
    max-width: 16rem;
}

/* 등급 고르는 칸도 같다 — 100%면 단추를 밀어낸다. */
.decision-form select {
    width: auto;
    flex: 0 1 auto;
}

.decision-form button {
    flex: 0 0 auto;
    white-space: nowrap;
    font-size: 16px;
    padding: 10px 18px;
}

table {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
    background: var(--dfz-surface);
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    overflow: hidden;
}

th {
    color: var(--dfz-muted);
    background: var(--dfz-surface-2);
    /* ★ 2026-09-21: 13px은 제목 줄로 읽히지 않을 만큼 작았다(회원님 제보). 본문과 같게 둔다. */
    font-size: 16px;
    font-weight: 700;
    white-space: nowrap;
}

th,td {
    border-bottom: 1px solid var(--dfz-line);
    padding: 16px 20px;
    text-align: left;
    /* ★ 세로 가운데. 이것이 없으면 글자와 단추가 <b>글자 밑선</b>으로 맞아
       같은 줄인데도 단추만 내려앉아 보인다(2026-09-21 회원님 제보). */
    vertical-align: middle;
}

td {
    overflow-wrap: anywhere;
}

tr:last-child td {
    border-bottom: 0;
}

tr.mine td {
    background: var(--dfz-hover);
}

tr.mine td:first-child {
    box-shadow: inset 3px 0 0 var(--dfz-lavender);
}

td form {
    margin: 0;
}
/* ★ 칸이 좁아지면 한글이 <b>한 글자씩 세로로</b> 접힌다(2026-09-16 회원님 사진 — 관리자 회원 화면의
   「소속」 칸). 표가 칸을 많이 가진 화면에서 브라우저가 폭을 쥐어짜기 때문이다.
   글은 접지 않게 하고, 표가 넘치면 <b>표만 옆으로 밀리게</b> 한다 — 화면 전체가 흔들리지 않는다.
   길어질 수 있는 칸(이메일·사유)은 따로 접기를 허용한다. */
th, td { white-space: nowrap; }
td.dfz-wrap, th.dfz-wrap { white-space: normal; word-break: break-word; }

.dfz-scroll-x {
    overflow-x: auto;
    /* 표에 이미 테두리가 있으므로 둘레를 더 그리지 않는다. */
    -webkit-overflow-scrolling: touch;
}

tr:last-child td { border-bottom: 0; }

details {
    margin: 16px 0;
}

summary {
    cursor: pointer;
    color: var(--dfz-lavender);
    font-weight: 600;
}

pre {
    background: var(--dfz-panel);
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius-md);
    padding: 20px;
    overflow-x: auto;
    font-size: 13px;
    color: var(--dfz-muted);
}

.game-card:hover {
    border-color: var(--dfz-mint);
    box-shadow: 0 0 0 2px #a4f0d733;
}

.game-card:nth-child(4n+2) .game-thumb {
    background: #355754;
}

.game-card:nth-child(4n+3) .game-thumb {
    background: #4A496A;
}

.game-card:nth-child(4n) .game-thumb {
    background: var(--dfz-surface-2);
}

@media (max-width:1100px) {
    .header-inner {
        gap: 16px;
    }
    .site-nav {
        flex-basis: 100%;
    }
    .hero {
        gap: 30px;
    }
    /* 두 열이 좁아지는 구간에서는 카드의 설명과 그림을 분리한다. */
    .hero-art {
        aspect-ratio: auto;
    }
    .hero-art-caption {
        width: 100%;
        padding: 24px 24px 0;
    }
    .hero-art img {
        position: static;
        display: block;
        height: auto;
    }
    .hero-art-label {
        position: static;
        padding: 0 24px 20px;
    }
    .card-grid {
        grid-template-columns: repeat(3,minmax(0,1fr));
    }
    .site-footer {
        margin: 0 40px;
    }
}

@media (max-width:760px) {
    .hero {
        grid-template-columns: 1fr;
        gap: 28px;
    }
    .card-grid {
        grid-template-columns: repeat(2,minmax(0,1fr));
        gap: 16px;
    }
    .search-form {
        margin-left: 0;
        flex-basis: 100%;
        margin-top: 8px;
    }
    .search-form input {
        flex: 1;
    }
    .site-footer {
        margin-left: 20px;
        margin-right: 20px;
    }
}

@media (max-width:480px) {
    .header-inner {
        padding: 18px 20px;
    }

    /* 좁은 화면에서는 관리 줄도 같은 여백으로 줄인다. */
    .admin-bar-inner {
        padding: 8px 20px;
    }
    .brand {
        font-size: 20px;
    }
    .site-nav {
        gap: 4px;
    }
    .site-nav>a,.nav-user>a:not(.btn) {
        padding: 8px;
        font-size: 13px;
    }
    .nav-user {
        gap: 4px;
    }
    .nav-user .btn {
        padding: 8px 12px;
    }
    main {
        padding: 0 20px 48px;
        margin-top: 30px;
    }
    .hero {
        padding-top: 0;
    }
    .hero h1 {
        font-size: 36px;
    }
    .hero-copy>p {
        font-size: 15px;
    }
    /* 좁은 화면과 긴 번역은 글·그림을 위아래로 놓아 겹치지 않게 한다. */
    .hero-art {
        aspect-ratio: auto;
    }
    .hero-art-caption {
        width: 100%;
        padding: 22px 22px 0;
    }
    .hero-art-caption strong {
        font-size: 28px;
    }
    .hero-art-caption span {
        margin-top: 10px;
    }
    .hero-art-label {
        position: static;
        padding: 0 22px 20px;
    }
    .card-grid {
        grid-template-columns: 1fr;
    }
    .game-thumb {
        height: 210px;
    }
    .chip {
        padding: 8px 13px;
    }
    .account-page main {
        margin-top: 36px;
    }
    main>form:only-of-type,form.panel {
        padding: 22px;
    }
    .site-footer {
        margin: 0 20px;
        flex-direction: column;
        gap: 4px;
    }
    th,td {
        padding: 12px 14px;
    }
    .hero-art img {
        position: static;
        display: block;
        height: auto;
    }
}

@media (prefers-reduced-motion:reduce) {
    *,*::before,*::after {
        transition: none !important;
        scroll-behavior: auto !important;
    }
}

/* CSP를 지키도록 화면 안의 스타일도 외부 파일에서 정의한다. */

.preserve-lines {
    white-space: pre-line;
}

.inline-form {
    display: inline;
}

.game-description {
    font-size: 1.05rem;
    max-width: 44rem;
}

.game-background {
    max-width: 100%;
    border-radius: var(--dfz-radius);
}

main > form.plain-form {
    background: none;
    border: 0;
    padding: 0;
    max-width: none;
}

.table-scroll table {
    min-width: 40rem;
}

/* ★ 승인 대기 화면에서 묶음 막대가 main>form:only-of-type(로그인 같은 한 장짜리 화면을
      카드로 만드는 규칙)에 걸려 폭이 36rem으로 묶였다. 같은 셈값이므로 뒤에 오는 이 줄이 이긴다. */
main>form.bulk-bar {
    max-width: none;
    padding: 12px 14px;
    border-radius: var(--dfz-radius-md);
    margin-top: 16px;
}

/* AI 게임 만들기 — 앱 작업판의 예시 카드와 같은 결(2026-09-29) */

.ex-kind {
    margin: 18px 0 8px;
    color: var(--dfz-mint);
    font-size: 16px;
}

.ex-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 12px;
}

.ex-card {
    padding: 14px 16px;
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    background: var(--dfz-surface);
}

.ex-name {
    color: var(--dfz-text);
    font-size: 16px;
    font-weight: 700;
}

.ex-facts {
    margin-top: 4px;
    color: var(--dfz-lime);
    font-size: 14px;
}

.ex-gist {
    margin-top: 6px;
    color: var(--dfz-muted);
    font-size: 14px;
    line-height: 1.5;
}

.rule-tool {
    margin-top: 28px;
    padding: 12px 16px;
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    background: var(--dfz-panel);
}

details.rule-tool > summary {
    cursor: pointer;
    color: var(--dfz-text);
    font-weight: 700;
}

/* 추천 게임 표(2026-10-01) — 회원님 「여백이 많은 곳도 많고 위·아래 버튼도 붙어 있어」.
   ★ 차례 칸은 숫자 폭만, 단추 칸은 단추 폭만(줄지 않고 줄바꿈하지 않는다) — 남는 폭은 제목이 가진다.
   ★ 위로·아래로·빼기는 한 줄에 8px 사이로 선다(칸 폭이 1%라 줄바꿈을 켜 두면 세로로 쌓였다 — 찍어 보고 앎).
     폭 640px 아래에서만 줄을 바꿔 내려간다(그때도 8px 사이). */
.recommend-table th.num,
.recommend-table td.num {
    width: 4.5rem;
    text-align: center;
    white-space: nowrap;
}

.recommend-table th.actions,
.recommend-table td.actions {
    width: 1%;
    white-space: nowrap;
}

.row-actions {
    display: flex;
    flex-wrap: nowrap;
    gap: 8px;
    align-items: center;
}

@media (max-width: 640px) {
    .row-actions {
        flex-wrap: wrap;
    }
}

.row-actions > form {
    margin: 0;
}

/* 관리 줄의 묶음(2026-10-01) — 사람 · 게임 · 앱. 묶음 사이에 세로 선 하나. */
.admin-bar-group {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
}

.admin-bar-group + .admin-bar-group {
    border-left: 1px solid var(--dfz-hover);
    padding-left: 12px;
    margin-left: 4px;
}

/* 지금 보고 있는 관리 화면 — 바탕만으로는 옅어서 아래 선을 하나 더 긋는다(색만으로 알리지 않는다). */
.admin-bar-inner a[aria-current=page] {
    box-shadow: inset 0 -3px 0 var(--dfz-lavender);
}

/* 기다리는 일의 수(승인 대기 · 신고 검토). 0이면 서지 않는다. */
.nav-count {
    display: inline-block;
    min-width: 1.6em;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--dfz-lime);
    color: var(--dfz-button-ink);
    font-size: 13px;
    font-weight: 800;
    line-height: 1.5;
    text-align: center;
}

/* 머리띠 오른쪽의 이름 — 누를 수 없는 글(자기 계정은 옆 「내 계정」). */
.nav-user-name {
    color: var(--dfz-muted);
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* 게임 올리기(2026-10-01) — 상자 둘을 나란히: 왼쪽 「묶음 올리기」, 오른쪽 「규칙 파일이 아직 없나요?」.
   ★ 좁은 화면(860px 아래)에서는 위아래로 쌓인다. 두 상자의 윗선은 맞추고 높이는 저마다(align-items: start). */
.upload-layout {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 24px;
    align-items: start;
    max-width: 1040px;
    margin-top: 8px;
}

.upload-layout > form.panel {
    max-width: none;
    margin-top: 0;
}

.upload-aside {
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    background: var(--dfz-panel);
    padding: 26px 30px 30px;
}

.upload-aside p {
    color: var(--dfz-muted);
    margin: 0 0 20px;
}

.panel-title {
    margin: 0 0 16px;
    font-size: 20px;
}

.upload-layout input[type=file] {
    max-width: 100%;
}

@media (max-width: 860px) {
    .upload-layout {
        /* ★ 1fr이 아니라 minmax(0, 1fr) — 1fr은 안의 가장 긴 줄만큼 넓어져 375px 화면에서 15px 넘쳤다(재 보고 앎). */
        grid-template-columns: minmax(0, 1fr);
    }
}

/* 언어 고르기(2026-10-04 포털 다국어) — 머리띠 오른쪽 끝. 스크립트 없이 <details>로 연다. */
.lang-picker {
    position: relative;
    flex-shrink: 0;
}

.lang-picker > summary {
    list-style: none;
    cursor: pointer;
    padding: 9px 12px;
    border-radius: var(--dfz-radius-md);
    border: 1px solid var(--dfz-control-line);
    color: var(--dfz-text);
    font-weight: 600;
    white-space: nowrap;
}

.lang-picker > summary::-webkit-details-marker {
    display: none;
}

.lang-picker[open] > summary,
.lang-picker > summary:hover {
    background: var(--dfz-hover);
}

.lang-picker ul {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: 20;
    margin: 0;
    padding: 6px;
    list-style: none;
    min-width: 190px;
    max-width: calc(100vw - 32px);
    background: var(--dfz-panel);
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius-md);
}

.lang-picker li a {
    display: block;
    padding: 8px 12px;
    border-radius: var(--dfz-radius-sm);
    color: var(--dfz-muted);
    text-decoration: none;
}

.lang-picker li a:hover,
.lang-picker li a[aria-current=true] {
    background: var(--dfz-hover);
    color: var(--dfz-text);
}

/* ── 게임 카드: 앱 로비 카드와 같은 구성 (2026-10-04 회원님 「앱의 게임카드와 동기화」) ──
   표지를 카드 가득(앱 cover-*.png의 웹 사본, GameCovers) → 오른쪽 위 분류 탭 → 아래 57%부터 짙게(앱 GameCardPoster.Finish와 같은 색·자리)
   → 그 위에 제목·한 줄 설명·기기 그림·인원. 포털에만 있는 비공개·조회수·별점은 카드 아래 얇은 줄(.game-foot).
   ★ 전에는 내장 게임마다 옛 삽화(art-*)를 번호로 골라 적었다(지운 줄 12개). 이제 고르는 것은 앱 한 곳이다. */

.game-poster {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    color: #fff;
    text-decoration: none;
    background: var(--dfz-hover);
}

.game-poster-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.game-poster.is-art::before {
    content: '';
    position: absolute;
    left: 12%;
    right: 12%;
    top: 10%;
    height: 48%;
    background: var(--game-art, url('/images/lobby/art-motion.png')) center/contain no-repeat;
}

.game-poster::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(9, 27, 53, 0) 38%, rgba(9, 27, 53, .94) 57%);
    pointer-events: none;
}

.game-poster:focus-visible {
    outline: 3px solid var(--dfz-lavender);
    outline-offset: -3px;
}

.game-tab {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2;
    padding: 6px 12px;
    border-radius: 999px;
    background: rgba(19, 43, 77, .96);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
}

.game-poster-text {
    position: absolute;
    left: 18px;
    right: 18px;
    bottom: 16px;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.game-title {
    font-size: 21px;
    font-weight: 700;
    line-height: 1.25;
    text-wrap: balance;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.game-poster:hover .game-title {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.game-line {
    font-size: 14px;
    color: rgba(255, 255, 255, .82);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.game-facts {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
}

.game-device {
    width: 22px;
    height: 22px;
}

.game-players {
    margin-left: 4px;
    font-size: 14px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.game-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    color: var(--dfz-muted);
    font-size: 13px;
}

.game-detail-art.has-cover::after {
    display: none;
}

.game-detail-art.has-cover {
    overflow: hidden;
}

.game-detail-cover {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ★ 2026-10-05 회원님 「포털에서 게임을 클릭해가면 이미지가 이렇게 나타나」 — 표지(1280×960, 4:3)를 폭 전체×260px(약 6:1) 칸에
   채워 그림 높이의 22%만(다리·신발) 보였다. 표지가 있으면 그림을 4:3 그대로 왼쪽에, 이름·설명을 오른쪽에 둔다(A안).
   좁은 화면에서는 위아래로 쌓는다. 표지가 없는 게임(회원이 올린 것)은 전과 같다. */
.game-detail-head.with-cover {
    display: grid;
    grid-template-columns: minmax(0, 640px) minmax(0, 1fr);
    gap: 32px;
    align-items: start;
    margin-bottom: 28px;
}

.game-detail-head.with-cover .game-detail-art {
    height: auto;
    aspect-ratio: 4 / 3;
    margin-bottom: 0;
}

.game-detail-head.with-cover .game-detail-info h1 {
    margin-top: 0;
}

@media (max-width: 860px) {
    .game-detail-head.with-cover {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }
}

.game-detail-art.has-cover .badge {
    z-index: 1;
    padding: 6px 12px;
    border-radius: 999px;
    background: rgba(19, 43, 77, .96);
    color: #fff;
}

/* 두 장씩(≤760px)은 카드가 좁아 글을 줄이고, 한 장씩(≤480px)은 카드가 넓어 표지를 낮춘다. */
@media (max-width:760px) {
    .game-title {
        font-size: 17px;
    }
    .game-line {
        font-size: 13px;
    }
    .game-poster-text {
        left: 12px;
        right: 12px;
        bottom: 12px;
    }
}

@media (max-width:480px) {
    .game-poster {
        aspect-ratio: 4 / 3;
    }
    .game-title {
        font-size: 20px;
    }
}

/* 한국어 외 번역은 글 길이가 달라도 활동 그림을 가리지 않는다. */
html:not([lang="ko"]) .hero-art { aspect-ratio: auto; }
html:not([lang="ko"]) .hero-art-caption { width: 100%; padding: 28px 28px 0; }
html:not([lang="ko"]) .hero-art img { position: static; display: block; height: auto; }
html:not([lang="ko"]) .hero-art-label { position: static; padding: 0 28px 22px; }

/* 포털 순위 A안 — 앱의 두 표와 둥근 행을 웹 너비에 맞춘다. */
.ranking-heading { margin-bottom: 24px; }
.ranking-heading h1 { margin-bottom: 8px; }
.ranking-heading p { margin: 0; color: var(--dfz-muted); }
.ranking-filter {
    display: flex;
    align-items: end;
    flex-wrap: wrap;
    gap: 16px;
    padding: 20px 24px;
    margin-bottom: 24px;
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    background: var(--dfz-surface-2);
}
.ranking-field { flex: 1 1 240px; min-width: 0; }
.ranking-field label { margin: 0 0 8px; }
.ranking-field input, .ranking-field select { width: 100%; margin: 0; }
.ranking-filter button { margin: 0; flex: 0 0 auto; }
.ranking-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
.ranking-grid-single { grid-template-columns: minmax(0, 1fr); }
.ranking-panel {
    min-width: 0;
    padding: 24px;
    border: 1px solid var(--dfz-line);
    border-radius: var(--dfz-radius);
    background: var(--dfz-surface-2);
}
.ranking-panel h2 { margin: 0 0 12px; font-size: 26px; color: var(--dfz-mint); }
.ranking-scope { margin: 0 0 20px; color: var(--dfz-muted); line-height: 1.65; overflow-wrap: anywhere; }
.ranking-panel .chip-row { margin: 0 0 16px; gap: 8px; }
.ranking-panel .chip { font-size: 13px; padding: 6px 10px; }
.ranking-panel .table-scroll { margin: 0; }
.ranking-panel .ranking-table {
    table-layout: fixed;
    min-width: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    border-spacing: 0 8px;
    overflow: visible;
}
.ranking-table th, .ranking-table td {
    padding: 14px 12px;
    border: 0;
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.45;
}
.ranking-table th { font-size: 14px; background: var(--dfz-panel); }
.ranking-table td { font-size: 18px; background: var(--dfz-panel); color: var(--dfz-text); }
.ranking-table th:first-child, .ranking-table td:first-child { border-radius: var(--dfz-radius-md) 0 0 var(--dfz-radius-md); }
.ranking-table th:last-child, .ranking-table td:last-child { border-radius: 0 var(--dfz-radius-md) var(--dfz-radius-md) 0; }
.ranking-table th:first-child { width: 12%; }
.ranking-table th:nth-child(4) { width: 16%; text-align: right; }
.ranking-table-org th:nth-child(3) { width: 20%; }
.ranking-table-org th:last-child { width: 19%; }
.ranking-table-national th:nth-child(3) { width: 16%; }
.ranking-table .ranking-place, .ranking-table .ranking-score { font-weight: 700; font-variant-numeric: tabular-nums; }
.ranking-table .ranking-score { text-align: right; }
.ranking-table .ranking-name { font-weight: 600; }
.ranking-table .ranking-played, .ranking-table .ranking-group, .ranking-table .ranking-joined { font-size: 15px; }
.ranking-table .ranking-top td { background: #346a70; color: #fff; }
/* 우리 기관과 1위가 같은 줄이어도 1위 색과 기관 테두리가 함께 남는다. */
.ranking-table .mine td { box-shadow: inset 0 2px var(--dfz-lavender), inset 0 -2px var(--dfz-lavender); }
.ranking-table .mine td:first-child { box-shadow: inset 2px 0 var(--dfz-lavender), inset 0 2px var(--dfz-lavender), inset 0 -2px var(--dfz-lavender); }
.ranking-table .mine td:last-child { box-shadow: inset -2px 0 var(--dfz-lavender), inset 0 2px var(--dfz-lavender), inset 0 -2px var(--dfz-lavender); }
.ranking-table .tag { display: inline-block; margin: 6px 0 0; white-space: normal; }
.ranking-rules { margin-top: 20px; border: 1px solid var(--dfz-line); border-radius: var(--dfz-radius); background: var(--dfz-surface-2); }
.ranking-rules summary { padding: 18px 24px; font-weight: 700; }
.ranking-rules-body { padding: 0 24px 12px; color: var(--dfz-muted); line-height: 1.8; }
.ranking-rules-body p { margin: 0 0 12px; }
.ranking-panel .notice { margin: 20px 0 0; }
@media (max-width: 1100px) {
    .ranking-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
    .ranking-filter { padding: 18px; gap: 12px; }
    .ranking-field { flex-basis: 100%; }
    .ranking-panel { padding: 18px; }
    .ranking-panel h2 { font-size: 24px; }
    .ranking-table, .ranking-table tbody { display: block; }
    /* 열 제목은 보조 기술에 남기고, 좁은 화면은 이름·점수를 먼저 읽게 한다. */
    .ranking-table thead { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
    .ranking-table tbody tr {
        display: grid;
        grid-template-columns: 34px minmax(0, 1fr) minmax(48px, 24%);
        align-items: center;
        gap: 6px 10px;
        margin-bottom: 10px;
        padding: 14px 12px;
        border-radius: var(--dfz-radius-md);
        background: var(--dfz-panel);
    }
    .ranking-table .ranking-top { background: #346a70; }
    .ranking-table .mine { box-shadow: inset 0 0 0 2px var(--dfz-lavender); }
    .ranking-table td, .ranking-table .mine td, .ranking-table .mine td:first-child, .ranking-table .mine td:last-child {
        display: block;
        padding: 0;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
        font-size: 16px;
    }
    .ranking-table .ranking-place { grid-column: 1; grid-row: 1 / span 2; }
    .ranking-table .ranking-name { grid-column: 2; grid-row: 1; }
    .ranking-table .ranking-score { grid-column: 3; grid-row: 1; }
    .ranking-table .ranking-group, .ranking-table .ranking-joined { grid-column: 2; grid-row: 2; font-size: 13px; }
    .ranking-table .ranking-played { grid-column: 3; grid-row: 2; font-size: 12px; text-align: right; }
    .ranking-table [data-label]::before { content: attr(data-label) " "; color: var(--dfz-muted); }
    .ranking-table .ranking-top [data-label]::before { color: #fff; }
    .ranking-rules summary { padding: 18px; }
    .ranking-rules-body { padding: 0 18px 10px; }
}

/* 포털 업무 메뉴와 게임 검색·두 순위표(2026-10-08). */
.ranking-workspace{display:grid;grid-template-columns:250px minmax(0,1fr);gap:24px}.ranking-library{padding:16px;border-radius:var(--dfz-radius-md);background:var(--dfz-surface-2);align-self:start;min-width:0}
.ranking-search{display:grid;gap:8px}.ranking-search input,.ranking-search select{width:100%;min-width:0}.ranking-library-tabs,.ranking-library-pages{display:flex;gap:12px;justify-content:space-between;margin:16px 0}.ranking-library-tabs [aria-current]{font-weight:700;text-decoration:underline}
.ranking-game-row{display:flex;align-items:center;margin:6px 0;background:var(--dfz-panel);border:1px solid var(--dfz-line);border-radius:var(--dfz-radius-sm)}.ranking-game-row>a{flex:1;min-width:0;padding:12px 8px;color:inherit;text-decoration:none;overflow-wrap:anywhere}.ranking-game-row>a[aria-current]{color:var(--dfz-mint);font-weight:700}.ranking-game-list{max-height:65vh;overflow-y:auto;scrollbar-gutter:stable}.ranking-game-row small{display:block;font-size:12px;font-weight:400}
button.ranking-star,button.ranking-star:hover,button.ranking-star[aria-pressed=true]{font-size:16px;min-width:42px;min-height:42px;padding:0;border:0;border-radius:0;background:transparent;box-shadow:none;color:var(--dfz-mint)}
.ranking-detail{min-width:0}.ranking-selected{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px;flex-wrap:wrap}.ranking-selected h2{margin:0}.ranking-detail .ranking-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.ranking-detail .ranking-grid-single{grid-template-columns:1fr}.ranking-detail .ranking-filter{display:flex;flex-wrap:wrap}.ranking-library [role=status]{font-size:13px}
@media(max-width:1000px){.ranking-workspace{grid-template-columns:210px minmax(0,1fr);gap:16px}.ranking-detail .ranking-grid{gap:12px}.ranking-panel{padding:16px}}
@media(max-width:760px){.ranking-workspace{grid-template-columns:1fr}.ranking-detail .ranking-grid{grid-template-columns:1fr}}

.ranking-search input[type=search]{padding:12px 14px;background:var(--dfz-surface);color:var(--dfz-text);border:1px solid var(--dfz-control-line);border-radius:var(--dfz-radius-md);min-height:46px}
.ranking-search>button,.portal-utilities form>button{margin-top:0}
button.ranking-star[aria-pressed=false]{color:var(--dfz-muted)}
.ranking-game-row>a{word-break:keep-all;overflow-wrap:break-word}

/* 승인된 통합 헤더: 색 원본은 유지하고 보조 메뉴·주 메뉴·하위 작업을 나눈다. */
.portal-utility-bar{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:8px;padding:6px max(24px,calc((100% - 1440px)/2));border-bottom:1px solid var(--dfz-surface)}
.portal-utilities{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:6px;min-width:0}
.portal-utilities form{margin:0;display:flex}
.portal-utilities>a,.portal-utilities form>button,.portal-utility-bar .lang-picker>summary{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:30px;margin:0;padding:3px 10px;border:1px solid transparent;border-radius:var(--dfz-radius-sm);font-size:16px;line-height:22px;font-weight:600;text-decoration:none;color:var(--dfz-text);background:transparent;box-shadow:none;filter:none}
.portal-utilities>a:hover,.portal-utilities form>button:hover,.portal-utility-bar .lang-picker>summary:hover,.portal-utility-bar .lang-picker[open]>summary{background:var(--dfz-mint);color:var(--dfz-button-ink)}
.portal-role{font-size:16px;line-height:22px;padding:2px 8px;border-radius:5px;background:var(--dfz-panel);color:var(--dfz-muted)}
.portal-utility-bar .lang-picker{margin:0;padding-left:8px;border-left:1px solid var(--dfz-line)}
.portal-icon{width:18px;height:18px;flex-shrink:0}.portal-chevron{width:12px;height:12px;flex-shrink:0}
.portal-utility-bar .lang-picker[open] .portal-chevron{transform:rotate(180deg)}
.site-header .header-inner{max-width:none;margin:0;padding:6px max(24px,calc((100% - 1440px)/2));gap:12px 24px;align-items:center}
.portal-primary{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;flex:1;gap:4px;min-width:0;padding:0}
.portal-primary a,.portal-secondary a{display:inline-flex;align-items:center;gap:8px;position:relative;min-height:38px;padding:6px 12px;border-radius:var(--dfz-radius-sm);line-height:24px;color:var(--dfz-text);font-weight:600;text-decoration:none}
.portal-primary a[aria-current]{background:var(--dfz-surface-2);color:var(--dfz-mint)}
.portal-primary a[aria-current]::after{content:"";position:absolute;bottom:0;left:10px;right:10px;height:2px;border-radius:2px;background:var(--dfz-mint)}
.portal-primary a:hover,.portal-secondary a:hover,.portal-secondary a[aria-current]{background:var(--dfz-mint);color:var(--dfz-button-ink)}
.portal-primary a[aria-current]:hover::after{background:var(--dfz-button-ink)}
.portal-primary .portal-management-start{margin-left:12px}
/* ★ 2026-10-14 회원님 「'회원 관리'와 '2' 사이에 공백이 많은 이유」 — 링크의 gap 8px와 숫자의 margin 6px가 겹쳐 14px였다. 간격은 gap 하나로. */
.portal-primary .nav-count{margin-left:0}
.portal-management-start::before{content:"";position:absolute;left:-8px;top:10px;bottom:10px;width:1px;background:var(--dfz-line)}
.portal-launch{display:inline-flex;align-items:center;gap:8px;flex-shrink:0;white-space:nowrap}
/* ★ 2026-10-14 B안(회원님 「버튼 크기는 유지하되 아이콘과 텍스트 크기는 크게」) — 높이 46.5px 그대로(줄 24 + 위아래 10.25 + 테두리 2),
   글자 18px 굵게·채운 ▶ 24px. 좌우 여백은 한국어 「게임 시작」에서 폭 127px이 그대로 되게 16px. */
.portal-launch{font-size:18px;font-weight:800;line-height:24px;padding:10.25px 16px;gap:7px}
.portal-launch-icon{width:20px;height:24px;flex-shrink:0}
.portal-secondary{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:8px max(24px,calc((100% - 1440px)/2));background:var(--dfz-surface-2);border-top:1px solid var(--dfz-surface)}
.portal-secondary a{font-weight:500}
.portal-secondary-items{display:flex;align-items:center;flex-wrap:wrap;gap:8px;width:max-content;max-width:100%;min-width:0;flex-shrink:0}
.portal-secondary-items a{max-width:100%;overflow-wrap:anywhere}
.portal-secondary a[aria-current]{font-weight:600}
/* 번역된 메뉴가 길어지면 주 메뉴만 다음 줄로 옮기고 글자나 클릭 영역을 줄이지 않는다. */
@media(max-width:1200px){.site-header .header-inner>.brand{margin-right:auto}.portal-primary{order:3;flex-basis:100%;justify-content:flex-start}}
@media(max-width:600px){.portal-utility-bar{padding:6px 16px}.site-header .header-inner{padding:6px 16px;gap:12px}.portal-secondary{padding:8px 16px}.portal-primary a{padding-inline:10px}.portal-primary .portal-management-start{margin-left:4px}.portal-management-start::before{display:none}}
/* 터치에서는 작은 배경을 유지하면서 보조 메뉴의 실제 누를 영역만 넓힌다. */
@media(pointer:coarse){.portal-utilities>a,.portal-utilities form>button,.portal-utility-bar .lang-picker>summary{border-top-width:8px;border-bottom-width:8px;background-clip:padding-box}.portal-primary a,.portal-secondary a{min-height:44px}}
/* 게임을 고르기 전 순위 화면: 기록이 많은 게임의 전국 순위를 번갈아 보인다(2026-10-09). */
.ranking-spotlight{min-width:0}
.ranking-spotlight-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:16px}
.ranking-spotlight-head h2{margin:0 0 6px;font-size:26px;color:var(--dfz-mint)}
.ranking-spotlight-head p{margin:0;color:var(--dfz-muted)}
.ranking-spotlight-controls{display:flex;align-items:center;gap:8px}
.ranking-spotlight-controls[hidden]{display:none}
.ranking-spotlight-controls button{min-width:44px;min-height:44px;margin:0;padding:0 12px;font-size:20px;line-height:1}
.ranking-spotlight-controls span{min-width:48px;text-align:center;font-variant-numeric:tabular-nums;color:var(--dfz-muted)}
.ranking-spotlight-slide[hidden]{display:none}
.ranking-spotlight-title{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.ranking-spotlight-title h3{margin:0;font-size:24px;overflow-wrap:anywhere}

/* 앱 설치 안내(/Install, 2026-10-10) — 순위 판과 같은 판 위에 제목·순서 목록. */
.install-guide { max-width: 880px; margin: 0 auto; }
.install-guide h2 { margin: 24px 0 10px; }
.install-guide p { line-height: 1.7; }
.install-steps { margin: 0 0 8px; padding-left: 24px; line-height: 1.75; }
.install-steps li + li { margin-top: 6px; }
/* 설치 파일 받기·서명 경고 안내(2026-11-06) — 파일 정보 한 칸, 경고마다 한 판, 붙여 넣을 명령 한 줄. */
.install-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.install-head h1 { margin: 0; }
.install-print-button[hidden], .install-print-only { display: none; }
.install-file { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 16px; margin: 0 0 16px; }
.install-file dt { color: var(--dfz-muted); font-weight: 700; }
.install-file dd { margin: 0; overflow-wrap: anywhere; }
.install-hash { font-size: 15px; word-break: break-all; }
.install-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.install-warn { margin: 14px 0 0; padding: 14px 18px; border: 1px solid var(--dfz-line); border-radius: var(--dfz-radius-md); background: var(--dfz-panel); }
.install-warn h3 { margin: 0 0 8px; font-size: 18px; }
.install-warn p { margin: 0 0 8px; }
/* ★ 명령 글꼴을 따로 적는다 — 한국어 Windows의 기본 고정폭 글꼴은 역슬래시(\)를 ₩로 그려, 종이를 보고 치는 사람이 경로를 잘못 읽는다. */
.install-command, .install-command code, .install-hash { font-family: Consolas, 'Cascadia Mono', 'Courier New', monospace; }
.install-command { margin: 8px 0; padding: 10px 12px; white-space: pre-wrap; word-break: break-all; font-size: 14px; color: var(--dfz-text); }
@media (max-width: 640px) {
    .install-file { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .install-file dd { margin-bottom: 8px; }
}
/* 글을 줄이고 그림으로(2026-11-08 회원님 「설치 안내가 너무 텍스트로만 이루어져 있는 것 같지 않아?」 → 「진행」).
   ★ 네 단계 카드 — 한눈에 순서를 보고 누르면 그 칸으로 간다. 좁은 화면은 두 칸씩.
   ★ 경고 2~6은 <details>로 접는다 — 제목 아래 「누를 것」 한 줄(라임)이 접힌 채로도 보인다.
   ★ 경고 창 그림(install-mock)은 실제 창을 단순하게 그린 것이다 — 누를 단추만 라임 테두리(install-mock-hit).
     창 색은 Windows가 쓰는 색에 가깝게 두되(파란 SmartScreen·흰 창), 글은 이 쪽의 말 표에서 온다. */
.install-installed { display: flex; align-items: center; justify-content: space-between; gap: 12px 20px; flex-wrap: wrap; margin: 18px 0 0; padding: 12px 18px; border: 1px solid var(--dfz-line); border-radius: var(--dfz-radius-md); }
.install-installed h2 { margin: 0 0 2px; font-size: 17px; }
.install-installed p { margin: 0; color: var(--dfz-muted); line-height: 1.5; }
.install-flow { list-style: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin: 20px 0 0; padding: 0; counter-reset: none; }
.install-flow a { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; height: 100%; padding: 18px 10px 14px; border-radius: var(--dfz-radius-md); background: var(--dfz-surface); color: var(--dfz-text); text-align: center; text-decoration: none; }
.install-flow a:hover { background: var(--dfz-hover); }
.install-flow .portal-icon { width: 34px; height: 34px; color: var(--dfz-lime); }
.install-flow b { font-size: 16px; line-height: 1.3; }
.install-flow span:last-child { font-size: 13px; color: var(--dfz-muted); line-height: 1.4; }
.install-flow .install-flow-num { position: absolute; top: 8px; left: 10px; min-width: 22px; height: 22px; border-radius: 999px; background: var(--dfz-lime); color: var(--dfz-button-ink); font-size: 13px; font-weight: 700; line-height: 22px; }
.install-spec { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; }
.install-spec li { padding: 6px 12px; border: 1px solid var(--dfz-line); border-radius: var(--dfz-radius-sm); font-size: 14px; line-height: 1.5; }
.install-guide .btn > .portal-icon.inline { margin-right: 6px; }
.install-command-box { display: flex; align-items: center; gap: 8px; margin: 8px 0; }
.install-command-box .install-command { flex: 1 1 auto; min-width: 0; margin: 0; }
.install-copy { flex: none; display: inline-flex; align-items: center; gap: 4px; margin: 0; }
.install-copy[hidden] { display: none; }
details.install-warn { padding: 0; }
details.install-warn > summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 18px; color: var(--dfz-text); font-weight: 400; list-style: none; }
details.install-warn > summary::-webkit-details-marker { display: none; }
details.install-warn > summary:hover { background: var(--dfz-hover); border-radius: var(--dfz-radius-md); }
details.install-warn[open] > summary { border-bottom: 1px solid var(--dfz-line); border-radius: var(--dfz-radius-md) var(--dfz-radius-md) 0 0; }
details.install-warn > :not(summary) { margin-left: 18px; margin-right: 18px; }
details.install-warn > :last-child { margin-bottom: 14px; }
.install-fold-title { display: flex; flex-direction: column; gap: 2px; }
.install-fold-title b { font-size: 17px; }
.install-do { color: var(--dfz-lime); font-size: 15px; }
.install-fold-icon { flex: none; width: 22px; height: 22px; color: var(--dfz-muted); transition: transform .15s; }
details[open] > summary .install-fold-icon { transform: rotate(180deg); }
.install-mock-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px !important; margin-bottom: 12px !important; }
.install-mock-arrow .portal-icon { width: 26px; height: 26px; color: var(--dfz-muted); }
.install-mock { flex: 1 1 250px; max-width: 360px; border-radius: 4px; font-family: 'Segoe UI', 'Malgun Gothic', sans-serif; font-size: 13px; line-height: 1.45; overflow: hidden; }
.install-mock-wide { max-width: 420px; }
.install-mock-light { background: #F3F3F3; color: #1B1B1B; border: 1px solid #C8C8C8; }
.install-mock-blue { padding: 14px 16px; background: #0B5CAD; color: #FFFFFF; }
.install-mock-bar { padding: 6px 10px; background: #E1E1E1; font-size: 12px; color: #333; }
.install-mock-bar-yellow { background: #F2D46B; color: #1B1B1B; }
.install-mock-body { padding: 10px 12px 12px; }
.install-mock-head { font-size: 15px; font-weight: 600; margin-bottom: 6px; }
.install-mock-small { margin: 0 0 8px !important; font-size: 12px; line-height: 1.45 !important; opacity: 1; }
.install-mock-file { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-weight: 600; overflow-wrap: anywhere; }
.install-mock-dots { flex: none; padding: 0 8px; font-weight: 700; }
.install-mock-menu { flex: 0 1 160px; padding: 4px 0; }
.install-mock-item { margin: 2px 6px; padding: 6px 10px; border-radius: 4px; }
.install-mock-link { display: inline-block; text-decoration: underline; }
.install-mock-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.install-mock-button { min-width: 70px; padding: 4px 12px; border: 1px solid currentColor; border-radius: 4px; text-align: center; }
.install-mock-mark { font-weight: 600; }
/* 누를 곳 — 라임 두 겹 테두리(흰 창·파란 창 둘 다에서 보이게 안쪽은 짙은 선). */
.install-mock-hit { outline: 3px solid var(--dfz-lime); outline-offset: 2px; box-shadow: 0 0 0 2px #1D2B36; border-radius: 4px; }
.install-mock-note { margin: 8px 0 0 !important; font-size: 13px; color: var(--dfz-muted); }
@media (max-width: 640px) {
    .install-flow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .install-mock-arrow { transform: rotate(90deg); }
}
/* ★ 인쇄(2026-11-06) — 안내자료 A4 한두 장. 메뉴·받기 단추·「이미 설치했다면」은 빼고 포털 주소를 찍는다.
     어두운 판의 밝은 글이 흰 종이에 그대로 나가면 안 보이므로 이 쪽에서만 글을 검게 바꾼다(:has — 다른 쪽 인쇄는 그대로). */
@media print {
    @page { size: A4; margin: 12mm 13mm; }
    /* :root의 color-scheme: dark가 종이 여백까지 어둡게 칠한다 — 이 쪽만 밝게. */
    :root:has(.install-guide) { color-scheme: light; background: #fff; }
    body:has(.install-guide) { background: #fff; }
    body:has(.install-guide) .site-header, body:has(.install-guide) .site-footer, body:has(.install-guide) .skip-link { display: none; }
    body:has(.install-guide) main { max-width: none; margin: 0; padding: 0; min-height: 0; }
    .install-guide { max-width: none; margin: 0; padding: 0; border: 0; background: #fff; font-size: 9.5pt; line-height: 1.4; }
    .install-guide, .install-guide * { color: #000 !important; }
    .install-guide .install-screen-only, .install-guide .install-actions, .install-guide .install-print-button { display: none; }
    .install-guide .install-print-only { display: block; margin: 0 0 6pt; }
    .install-guide h1 { font-size: 15pt; }
    .install-guide h2 { font-size: 11.5pt; margin: 8pt 0 3pt; break-after: avoid; }
    .install-guide h3 { font-size: 10.5pt; margin: 0 0 3pt; break-after: avoid; }
    .install-guide p, .install-guide .ranking-scope { margin: 0 0 3pt; line-height: 1.4; }
    .install-guide .install-steps { margin: 0 0 3pt; line-height: 1.4; }
    .install-guide .install-steps li + li { margin-top: 2pt; }
    .install-file { margin: 0 0 6pt; gap: 2pt 10pt; }
    .install-guide .notice, .install-warn, .install-command { background: #fff; border: 1px solid #888; }
    .install-warn { margin: 4pt 0 0; padding: 4pt 7pt; break-inside: avoid; }
    .install-command { margin: 3pt 0; padding: 4pt 6pt; font-size: 9pt; }
    .install-hash { font-size: 10pt; }
    /* 2026-11-08 — 종이에는 카드·창 그림·복사 단추·펼침 화살표를 빼고, 접힌 칸은 install-print.js가 펼친다. PC 준비는 한 줄로. */
    .install-guide .install-flow, .install-guide .install-mock-row, .install-guide .install-copy, .install-guide .install-fold-icon, .install-guide .install-mock-note, .install-guide .install-do { display: none; }
    /* 접힌 칸도 종이에는 다 나온다 — Edge·Chrome(131+)은 ::details-content로, 그 밖은 install-print.js의 beforeprint로. */
    details.install-warn::details-content { content-visibility: visible; display: block; }
    details.install-warn > summary { padding: 0 0 2pt; border: 0 !important; }
    details.install-warn > :not(summary) { margin-left: 0; margin-right: 0; }
    details.install-warn > :last-child { margin-bottom: 0; }
    details.install-warn { padding: 4pt 7pt; }
    .install-fold-title { flex-direction: row; flex-wrap: wrap; gap: 0 8pt; }
    .install-fold-title b { font-size: 10.5pt; }
    .install-do { font-size: 9.5pt; }
    .install-spec { gap: 2pt 10pt; }
    .install-spec li { padding: 0; border: 0; font-size: 9.5pt; }
}
/* 선 아이콘(PortalIcons, 2026-10-10) — 그림 문자 아이콘을 대신한다. 글줄 안에서는 글자 크기를 따른다. */
.portal-icon.inline{width:1em;height:1em;vertical-align:-.15em}
[aria-pressed="true"]>.star-off,[aria-pressed="false"]>.star-on{display:none}
[data-spotlight-pause][aria-pressed="true"]>.when-running,[data-spotlight-pause][aria-pressed="false"]>.when-stopped{display:none}
.ranking-selected button{gap:6px}
/* 게임 상세: 몇 명이·어떤 기기로 · 앱 열기(2026-10-10) */
.game-detail-facts{list-style:none;display:flex;flex-wrap:wrap;gap:10px 22px;margin:18px 0 0;padding:0}
.game-detail-facts li{display:inline-flex;align-items:center;gap:8px;font-weight:600;font-variant-numeric:tabular-nums}
.game-detail-facts img{width:22px;height:22px}
.game-detail-actions{margin:22px 0 0}
/* 눌리지 않는 기준·사실은 칩이 아니라 글 한 줄(2026-10-10). 첫 칸은 이름표, 그 뒤는 가운뎃점으로 잇는다. */
.ranking-basis,.game-detail-meta{display:flex;flex-wrap:wrap;align-items:center;margin:0 0 16px;color:var(--dfz-muted);font-size:14px;line-height:1.6}
.ranking-basis>span:first-child{font-weight:700;margin-right:8px}
.ranking-basis>span:nth-child(n+3)::before,.game-detail-meta>span+span::before{content:"·";margin:0 8px;color:var(--dfz-line)}
.game-detail-meta{margin:10px 0 14px}
/* 휴대폰: 순위표를 게임 고르기보다 먼저, 분류 칩은 한 줄 가로 넘김(2026-10-10 — 순위표가 1343px 아래, 첫 게임 카드가 화면 맨 아래였다). */
@media(max-width:760px){.ranking-detail{order:-1}.chip-scroll{flex-wrap:nowrap;overflow-x:auto;padding-bottom:6px;scrollbar-width:thin;scrollbar-color:var(--dfz-line) transparent}.chip-scroll>*{flex:none}}
/* 계정 관리(/Admin/Members) — 좌우 스크롤 없이 한 화면에(2026-10-13). 칸 너비를 고정하고 정보를 한 칸에 두 줄로 묶는다.
   한국어는 낱말 단위로만 접는다(keep-all) — 2026-09-16의 「한 글자씩 세로로 접힘」을 다시 내지 않는다. */
.am-summary{display:flex;flex-wrap:wrap;gap:8px 22px;margin:4px 0 22px;padding:0;list-style:none;font-size:15px;color:var(--dfz-muted)}
.am-summary a{color:var(--dfz-muted);text-decoration:none}
.am-summary b{font-size:20px;margin-right:6px;color:var(--dfz-text);font-variant-numeric:tabular-nums}
.am-summary a:hover b,.am-summary a:focus-visible b,.am-summary .attn b{color:var(--dfz-lime)}
.am-tools{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;margin:0 0 14px}
.am-tools form{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0;padding:0;border:0;background:none;max-width:none}
.am-tools label{margin:0;font-size:14px;color:var(--dfz-muted)}
.am-tools input[type=search],.am-tools input[type=date],.am-tools select{width:auto;min-height:40px;margin:0;padding:8px 12px;background:var(--dfz-surface);color:var(--dfz-text);border:1px solid var(--dfz-control-line);border-radius:var(--dfz-radius-md)}
.am-tools input[type=search]{width:220px}.am-tools select{min-width:130px}
.am-tools button{min-height:40px;padding:6px 18px}
/* ★ 2026-10-14 회원님 「찾기 부분만 위아래로 줄이 맞지 않아」 — 바탕의 form>button{margin-top:22px}가 단추만 내렸고 검색 칸만 44px였다. 셋을 40px 한 줄로. */
.am-tools input[type=search],.am-tools input[type=date],.am-tools select,.am-tools button{height:40px;min-height:0;margin:0}
.am-count{margin-left:auto;color:var(--dfz-muted);font-size:14px}
main>form.am-bulk{margin-top:0;background:var(--dfz-surface-2);border:1px solid var(--dfz-line)}
.am-bulk .bulk-check{font-size:14px;color:var(--dfz-muted)}
.am-bulk input[type=text]{max-width:180px}
.am-bulk .bulk-danger{margin-left:auto}
table.am-table{table-layout:fixed}
.am-table th,.am-table td{white-space:normal;word-break:keep-all;overflow-wrap:anywhere;padding:12px 14px;vertical-align:top}
.am-table th{font-size:14px}.am-table td{font-size:15px}
/* 짧은 글 칸(선택·상태·날짜·활동)은 픽셀로 — 비율로 두면 창이 좁아질 때 「승/인/됨」처럼 한 글자씩 접혔다(2026-10-13 검증). */
.am-table col.c-pick{width:44px}.am-table col.c-who{width:24%}.am-table col.c-org{width:16%}.am-table col.c-state{width:104px}
.am-table col.c-date{width:150px}.am-table col.c-act{width:150px}
/* ★ 2026-10-14 회원님 「빨간색 사각형으로 공백이 많은데」 — 위 표(am-staff)가 따로 비율(34%·24%·16%)을 써서 넓은 화면에서 칸 사이가 비었고
   아래 표와 칸 자리도 달랐다. 이제 위 표도 아래 표와 같은 칸 정의(c-pick·c-who·c-org·c-state)를 쓰고, 회원 칸이 앞의 두 칸을 함께 쓴다(colspan=2).
   마지막 로그인이 나머지 — 남는 자리는 줄 끝으로 간다. (col 너비의 calc()는 브라우저가 받지 않아 이 길로 했다.) */
.am-sub{display:block;margin-top:3px;font-size:13px;color:var(--dfz-muted);word-break:break-all}
/* 상태 칸은 가운데 — 상태 표시와 그 아래 등급이 한 세로줄에 선다(2026-10-13 회원님). 휴대폰 카드에서는 칸 이름 옆이라 왼쪽. */
.am-table .am-state{text-align:center}
.am-tag{display:inline-block;white-space:nowrap;padding:2px 8px;border-radius:var(--dfz-radius-sm);font-size:13px;font-weight:700;line-height:1.5}
.am-tag.ok{background:#2f4f4a;color:var(--dfz-mint)}.am-tag.wait{background:#4b4a2c;color:var(--dfz-lime)}
.am-tag.stop{background:var(--dfz-error-bg);color:var(--dfz-error-ink)}
.am-num{font-variant-numeric:tabular-nums;font-size:14px;color:var(--dfz-muted)}.am-num b{color:var(--dfz-text);font-weight:600;white-space:nowrap}
.am-manage{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.am-manage .decision-form{display:flex;gap:6px;align-items:center;margin:0}
.am-manage select{width:auto;max-width:96px;min-height:34px;margin:0;padding:4px 8px;font-size:14px}
.am-manage button,.am-manage summary{min-height:34px;padding:4px 12px;font-size:14px}
/* ★ 2026-10-14: 바탕의 details 아래 여백이 관리 칸을 66px로 늘려 줄마다 빈 셋째 줄이 생겼다 — 여백 0. 관리 단추는 두 줄 내용의 가운데. */
.am-delete{display:inline-flex;margin:0}
.am-table td.am-manage-cell{vertical-align:middle}
.am-delete summary{display:inline-flex;align-items:center;cursor:pointer;list-style:none;border:1px solid var(--dfz-danger-edge);color:var(--dfz-danger-ink);border-radius:var(--dfz-radius-md)}
.am-delete summary::-webkit-details-marker{display:none}
.am-delete[open]{flex-basis:100%}.am-delete[open] summary{display:none}
.am-delete:not([open])>form{display:none}
.am-delete input[type=text]{width:150px;min-height:34px;margin:0;padding:4px 10px;font-size:14px}
.am-table tr.me td{background:var(--dfz-hover)}
/* 운영 기록(/Admin/AuditLog, 2026-10-18) — 시각은 한 줄(날짜 칸 150px에서는 시:분이 다음 줄로 접혔다), 긴 사유는 접는다(바탕 details의 위아래 여백 0). */
.al-table col.c-when{width:176px}.al-table td.al-when{white-space:nowrap}
.al-reason details{margin:0}.al-reason summary{color:inherit;font-weight:400}
/* 표가 들어갈 자리가 없는 폭(1100px 이하)에서는 줄을 카드로 쌓는다 — 칸을 쥐어짜 글자를 접지 않는다. */
@media(max-width:1100px){
 .am-table,.am-table tbody,.am-table tr,.am-table td{display:block;width:auto}.am-table thead,.am-table colgroup{display:none}
 .am-table tr{padding:12px 14px;border-bottom:1px solid var(--dfz-line)}.am-table tr:last-child{border-bottom:0}.am-table td{border:0;padding:4px 0}
 .am-table .am-state{text-align:left}
 .am-table td[data-label]:not([data-label=""])::before{content:attr(data-label) " ";color:var(--dfz-muted);font-size:13px;margin-right:6px}
}
@media(max-width:760px){
 .am-tools input[type=search]{width:100%}.am-count{margin-left:0}.am-bulk .bulk-danger{margin-left:0}
}

/* ★ 2026-10-14 글자 링크 → 버튼(회원님 시안 「진행」). 혼자 서서 이동·동작을 맡는 링크만 버튼으로 —
   문장 속 링크·표의 이름 링크는 그대로 링크다. */
.btn .portal-icon{width:18px;height:18px}
.btn.small{min-height:34px;padding:4px 12px;font-size:14px;gap:6px}
.btn.small .portal-icon{width:16px;height:16px}
.btn.quiet.danger{border-color:var(--dfz-danger-edge);color:var(--dfz-danger-ink)}
/* 알림 글줄 안의 버튼(회원님 「그 줄의 높이 계산해서 버튼 크기 조절해」) — 글줄 높이는 16px × 1.6 = 25.6px.
   버튼은 34px로 두고 위아래 바깥 여백 -4.2px씩 → 줄에서 차지하는 높이가 25.6px라 줄·상자 높이가 바뀌지 않는다.
   vertical-align은 top — middle은 글자 높이 기준이라 1px 아래로 내려가 줄이 1px 늘었다(실측). */
.btn.in-line{min-height:0;height:34px;padding:0 14px;font-size:14px;margin:-4.2px 0 -4.2px 6px;vertical-align:top}
/* 둘 중 하나 고르기 — 고른 쪽만 민트로 채운다. */
.seg{display:inline-flex;justify-content:flex-start;gap:0;border:1px solid var(--dfz-line);border-radius:var(--dfz-radius-md);overflow:hidden;width:max-content;max-width:100%}
.seg>a{display:inline-flex;align-items:center;gap:4px;min-height:32px;padding:4px 14px;font-size:14px;font-weight:700;color:var(--dfz-text);text-decoration:none;background:var(--dfz-surface)}
.seg>a+a{border-left:1px solid var(--dfz-line)}
.seg>a[aria-current]{background:var(--dfz-mint);color:var(--dfz-button-ink);text-decoration:none}
.seg>a:not([aria-current]):hover{background:var(--dfz-surface-2)}
.admin-view-tools{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin:0 0 16px}

/* 개발일지(2026-11-10) — 관리자 화면.
   ★ 2026-11-11 두 칸(게임 말고 전체 / 게임)에 제목만 한 줄씩. 앞서 같은 날 표 → 카드로 바꿨던 것을 다시 고쳤다 —
     요약까지 실으면 한 화면에 서너 건뿐이었다. 요약은 한 건 화면에서 본다.
     칸 하나가 판 하나이고, 줄 사이는 가는 줄이다. 900px보다 좁으면 두 칸이 위아래로 쌓인다. */
.dl-cols { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; align-items: start; margin: 0 0 1rem; }
.dl-col { background: var(--dfz-surface); border: 1px solid var(--dfz-line); border-radius: var(--dfz-radius-md); padding: 14px 18px 8px; }
.dl-col-title { margin: 0 0 6px; font-size: 18px; }
.dl-col-count { font-size: 14px; font-weight: 400; color: var(--dfz-muted); margin-left: 6px; }
.dl-rows { list-style: none; margin: 0; padding: 0; }
.dl-row { display: flex; align-items: baseline; gap: 8px; padding: 8px 0; border-top: 1px solid var(--dfz-line); }
.dl-num { flex: none; min-width: 2.2rem; font-size: 15px; font-weight: 800; color: var(--dfz-text); font-variant-numeric: tabular-nums; }
.dl-row .dl-state, .dl-row .dl-area, .dl-row .dl-draft { flex: none; }
.dl-row-title { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; font-weight: 700; }
.dl-when { flex: none; margin-left: auto; white-space: nowrap; font-size: 14px; color: var(--dfz-muted); font-variant-numeric: tabular-nums; }
@media (max-width: 900px) {
    .dl-cols { grid-template-columns: minmax(0, 1fr); }
    /* 좁으면 딱지들이 한 줄, 제목이 그 아래 줄 — 제목 자리가 딱지에 밀려 한두 글자씩 꺾이지 않게. */
    .dl-row { flex-wrap: wrap; }
    .dl-row-title { flex-basis: 100%; order: 9; }
}
/* 상태 — 채운 딱지. 글자는 어두운 색(밝은 바탕 위). 모르는 상태가 와도 「닫힘」 색으로 보인다. */
.dl-state { display: inline-block; white-space: nowrap; font-weight: 700; font-size: 14px; line-height: 1.5; padding: 1px 10px; border-radius: var(--dfz-radius-sm); background: var(--dfz-tag-closed); color: var(--dfz-button-ink); }
.dl-state.dl-open { background: var(--dfz-tag-open); }
.dl-state.dl-merged { background: var(--dfz-mint); }
/* 분야 — 테두리 딱지. 모르는 분야는 「그 밖」 색. */
.dl-area { display: inline-block; white-space: nowrap; font-weight: 700; font-size: 14px; line-height: 1.5; padding: 0 9px; border-radius: var(--dfz-radius-sm); border: 1px solid var(--dfz-tag-other); color: var(--dfz-tag-other); }
.dl-area.dl-area-game { border-color: var(--dfz-tag-game); color: var(--dfz-tag-game); }
.dl-area.dl-area-app { border-color: var(--dfz-tag-app); color: var(--dfz-tag-app); }
.dl-area.dl-area-portal { border-color: var(--dfz-tag-portal); color: var(--dfz-tag-portal); }
.dl-area.dl-area-install { border-color: var(--dfz-tag-install); color: var(--dfz-tag-install); }
.dl-area.dl-area-process { border-color: var(--dfz-tag-process); color: var(--dfz-tag-process); }
/* 개발 정보(2026-11-11) — 초안 표시·가지 이름. */
.dl-draft { white-space: nowrap; font-size: 0.875em; border: 1px solid var(--dfz-line); border-radius: var(--dfz-radius-md); padding: 0 0.4rem; }
.dl-branch { overflow-wrap: anywhere; }
.dl-text { white-space: pre-wrap; overflow-wrap: anywhere; }
/* 본문은 PR에 적힌 글 그대로 — 긴 줄이 화면을 옆으로 밀지 않게 접는다 */
.dl-body { white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; margin: 0; }
.dl-pages { display: flex; gap: 1rem; align-items: center; }
/* 개발일지 의견(2026-11-10 3단계) — 목록 모양만. 색은 새로 정하지 않는다. */
.dl-opinions { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: 0.75rem; }
.dl-who { margin: 0 0 0.25rem; }
