  /* ============================================================
     토큰 1층 — 프리미티브
     명도(L) 사다리 하나를 모든 색이 공유한다. 같은 단계면 색이 달라도 같은 밝기로
     읽힌다 — 스케일마다 명도가 제각각이면 나란히 놓았을 때 얼룩이 진다.
     단계에는 역할을 고정한다: 100~300 표면, 400~600 경계, 700~800 보조 글자,
     900~1000 주 글자·솔리드. 색을 고를 일이 없어지고, 고르면 틀린다.
     ============================================================ */
  :root{
    /* 명도 사다리. 값은 그 단계의 밝기다 — 0% 가 검정, 100% 가 흰색.
       한 단계를 올리면 그 단계를 쓰는 자리가 모두 밝아지고, 내리면 모두 어두워진다.
       예를 들어 --L2 는 화면 바탕(2층의 --bg-canvas)이라 이 값만 내려도 화면 전체가 어두워진다.
       이웃한 두 단계의 차이가 곧 대비다. 값이 가까울수록 경계가 흐려지고, 멀수록 또렷해진다.
       여기 적힌 것은 라이트 값이고, 다크 값은 아래 다크 구역에서 같은 이름을 덮어쓴다. */
    --L1:98.2%; --L2:95.3%; --L3:92.9%; --L4:89.9%; --L5:85.0%;
    --L6:79.7%; --L7:62.0%; --L8:55.1%; --L9:39.5%; --L10:24.2%;

    /* ------- 색을 조절하는 손잡이 넷 -------
       아래 사다리 계산식에 그대로 곱해지고 더해지는 값이다. 여기만 고치면 화면의 색이 한꺼번에 움직인다.
       테마마다 사다리를 두 벌 적어 두지 않으려고 이렇게 뺐다 — 두 벌이면 한쪽만 고치는 실수가 반드시
       나고, 그 실수는 그 테마를 열어 보기 전에는 보이지 않는다.
       넷 다 여기 적힌 것이 라이트 값이고, 다크 값은 아래 다크 구역 두 곳(시스템 설정을 따르는
       규칙과, 사용자가 손으로 고른 :root[data-theme="dark"])에서 덮어쓴다.

         --cs  화면 전체의 채도 배율. 올리면 모든 색이 진해지고, 내리면 회색 쪽으로 바래며, 0 이면 흑백이 된다.
               라이트 1 / 다크 .82 — 다크에서는 같은 채도가 더 진하게 번져 보여 조금 내린다.
         --cn  중성색(바탕·테두리·글자)에만 겹쳐 곱하는 채도 배율. 올리면 회색에 색기가 돌고,
               내리면 색기가 빠져 무채색 회색·검정이 된다. 라이트 1 / 다크 1 — 두 테마 다 손대지 않는다.
         --cb  브랜드색에만 겹쳐 곱하는 채도 배율. 올리면 강조색이 선명해지고, 내리면 바랜다.
               라이트 1 / 다크 1 — 두 테마 다 손대지 않는다.
         --hb  브랜드색을 색상환에서 몇 도 돌릴지. 아래 사다리에 적힌 각도에 그대로 더한다.
               라이트 0 / 다크 0 — 두 테마 다 사다리에 적힌 그린(158~168)을 그대로 쓴다.

       셋(--cn·--cb·--hb)이 지금은 라이트와 다크가 같은 값이라 아무 일도 하지 않는다. 그래도 남겨 둔다 —
       테마 한쪽의 색기나 색상만 손보고 싶어질 때 사다리를 두 벌로 늘리지 않고 여기서 끝낼 수 있는 자리다. */
    --cs:1;
    --cn:1; --cb:1; --hb:0;

    /* ------- 다크에서 쓸 값 한 벌 -------
       다크로 들어오는 길은 둘이다. 브라우저·운영체제가 어둡게 설정된 경우와, 사용자가 화면에서
       손으로 어둡게 고른 경우. 두 길은 서로 다른 CSS 규칙으로 켜지므로, 값을 그 두 규칙에 각각
       적으면 같은 다크인데 들어온 길에 따라 화면이 달라진다 — 실제로 그렇게 갈렸다.
       바탕이 한쪽에서는 14.2% 로, 다른 쪽에서는 12% 로 났고, 두 길을 다 열어 보기 전에는
       아무도 알아채지 못했다.
       그래서 값은 여기 한 벌만 둔다. 아래 두 규칙은 이 이름들을 가져다 쓰기만 한다.
       색을 바꾸려면 여기만 고치면 되고, 한쪽만 고치는 실수가 아예 불가능해진다.

       다크 강조색의 이력 — 값이 아니라 눈으로 고른 결정들이다.
         08-13  그린(168). 다크모드를 처음 넣을 때의 색.
         08-14  검정 바탕(L2 8.5%) + 골드 강조로 바꿨다가 같은 날 그린으로 되돌렸다.
         08-18  강조만 다시 골드로 정했다. 색상을 92 로 돌리고(--dark-hb) 채도를 올린다(--dark-cb).
                바탕은 되돌리지 않는다 — L2 는 14.2% 인 따뜻한 회색 그대로이고, 중성 채도(--dark-cn)도
                1 이다. 08-14 때는 바탕까지 검정으로 내렸는데, 이번에 고른 것은 강조색 하나다.
                그래서 이 다크는 "검정 바탕 골드" 가 아니라 "따뜻한 회색 바탕 골드" 다.
       채도를 올리는 이유: 색상만 92 로 돌리면 은색에 가까운 베이지로 보인다. 금색으로 읽히려면
       채도가 필요하다. 2.3 은 08-14 에 쓰던 값과 같다. */
    --dark-L1:19.0%; --dark-L2:14.2%; --dark-L3:23.0%; --dark-L4:27.5%; --dark-L5:33.5%;
    --dark-L6:42.0%; --dark-L7:62.0%; --dark-L8:72.0%; --dark-L9:80.0%; --dark-L10:96.0%;
    --dark-cs:.82; --dark-cn:1; --dark-cb:2.3; --dark-hb:-76;
    --dark-shadow-1:0 1px 2px oklch(0% 0 0 / .4);
    --dark-shadow-2:0 2px 4px oklch(0% 0 0 / .35), 0 6px 16px oklch(0% 0 0 / .4);
    --dark-shadow-3:0 8px 24px oklch(0% 0 0 / .5), 0 2px 6px oklch(0% 0 0 / .4);

    /* 아래 네 묶음의 계산식은 모양이 같다 — oklch(밝기 채도 각도).
       가운데의 .007 같은 숫자가 그 단계의 채도다. 크게 잡을수록 그 단계만 색이 진해진다.
       끝의 87 같은 숫자는 색상환 각도이고, 어느 색으로 보일지를 정한다. */

    /* neutral — 바탕·테두리·글자에 쓰는 회색. 각도 77~107 은 노란 쪽이라 차갑지 않은 회색으로 보인다.
       채도가 .006~.025 로 아주 낮다 — 회색은 색이 도는 순간 바탕이 물든 것처럼 읽히기 때문이다.
       --cs 와 --cn 이 함께 곱해진다. 지금 --cn 은 두 테마 다 1 이라, 다크에서 줄어드는 것은
       --cs 만큼(.82)이고 회색은 따뜻한 기를 그대로 지닌다. */
    --n-100:oklch(var(--L1) calc(.007*var(--cs)*var(--cn)) 87);
    --n-200:oklch(var(--L2) calc(.013*var(--cs)*var(--cn)) 87);
    --n-300:oklch(var(--L3) calc(.017*var(--cs)*var(--cn)) 88);
    --n-400:oklch(var(--L4) calc(.019*var(--cs)*var(--cn)) 86);
    --n-500:oklch(var(--L5) calc(.022*var(--cs)*var(--cn)) 86);
    --n-600:oklch(var(--L6) calc(.025*var(--cs)*var(--cn)) 86);
    --n-700:oklch(var(--L7) calc(.018*var(--cs)*var(--cn)) 80);
    --n-800:oklch(var(--L8) calc(.012*var(--cs)*var(--cn)) 77);
    --n-900:oklch(var(--L9) calc(.009*var(--cs)*var(--cn)) 90);
    --n-1000:oklch(var(--L10) calc(.006*var(--cs)*var(--cn)) 107);

    /* brand — 강조에 쓰는 색. 각도 158~168 은 그린이고, 지금은 두 테마 다 --hb 가 0 이라
       라이트와 다크가 같은 그린을 쓴다. 각도만 여기서 바꾸면 두 테마가 함께 돈다 —
       한쪽 테마의 색만 바꾸려면 각도가 아니라 --hb 를 그 테마에서 고친다.
       채도는 --cs 와 --cb 가 함께 곱해진다. 900 이 강조 글자에 가장 많이 쓰이는 단계다. */
    --b-100:oklch(var(--L1) calc(.008*var(--cs)*var(--cb)) calc(160 + var(--hb)));
    --b-200:oklch(var(--L2) calc(.016*var(--cs)*var(--cb)) calc(158 + var(--hb)));
    --b-300:oklch(var(--L3) calc(.024*var(--cs)*var(--cb)) calc(160 + var(--hb)));
    --b-400:oklch(var(--L4) calc(.030*var(--cs)*var(--cb)) calc(160 + var(--hb)));
    --b-500:oklch(var(--L5) calc(.042*var(--cs)*var(--cb)) calc(165 + var(--hb)));
    --b-600:oklch(var(--L6) calc(.055*var(--cs)*var(--cb)) calc(166 + var(--hb)));
    --b-700:oklch(var(--L7) calc(.070*var(--cs)*var(--cb)) calc(167 + var(--hb)));
    --b-800:oklch(var(--L8) calc(.068*var(--cs)*var(--cb)) calc(168 + var(--hb)));
    --b-900:oklch(var(--L9) calc(.062*var(--cs)*var(--cb)) calc(168 + var(--hb)));
    --b-1000:oklch(var(--L10) calc(.048*var(--cs)*var(--cb)) calc(168 + var(--hb)));

    /* danger — 삭제·경고에 쓰는 붉은 색(각도 30). 채도를 neutral 보다 훨씬 높게 잡았다.
       위험을 알리는 색이 바탕에 묻히면 알리지 못하기 때문이다.
       곱해지는 손잡이가 --cs 하나뿐이라, 테마를 바꿔도 색은 같은 붉은 색으로 남는다.
       밝기만 사다리를 따라 뒤집힌다. */
    --d-100:oklch(var(--L1) calc(.010*var(--cs)) 30);
    --d-200:oklch(var(--L2) calc(.022*var(--cs)) 30);
    --d-300:oklch(var(--L3) calc(.032*var(--cs)) 30);
    --d-400:oklch(var(--L4) calc(.042*var(--cs)) 30);
    --d-500:oklch(var(--L5) calc(.060*var(--cs)) 30);
    --d-600:oklch(var(--L6) calc(.085*var(--cs)) 30);
    --d-700:oklch(var(--L7) calc(.125*var(--cs)) 30);
    --d-800:oklch(var(--L8) calc(.135*var(--cs)) 30);
    --d-900:oklch(var(--L9) calc(.115*var(--cs)) 30);
    --d-1000:oklch(var(--L10) calc(.080*var(--cs)) 30);

    /* warm — 태그·표시에 쓰는 누런 색(각도 84). danger 와 마찬가지로 --cs 만 곱해져,
       테마를 바꿔도 색은 그대로고 밝기만 뒤집힌다.
       네 단계만 두었다 — 쓰는 자리가 정해져 있어, 없는 단계가 필요해지면 그때 더한다. */
    --w-200:oklch(var(--L2) calc(.030*var(--cs)) 84);
    --w-400:oklch(var(--L4) calc(.055*var(--cs)) 84);
    --w-800:oklch(var(--L8) calc(.088*var(--cs)) 84);
    --w-900:oklch(var(--L9) calc(.078*var(--cs)) 84);

  /* ============================================================
     토큰 2층 — 시맨틱
     화면 코드는 1층을 직접 쓰지 않는다. 여기서만 "무엇에 쓰는 색"인지 정한다.
     팔레트를 갈아도 이 층이 그대로면 화면은 안 깨진다.
     ============================================================ */
    --bg-canvas:var(--n-200);
    --bg-surface:var(--n-100);
    --bg-raised:var(--n-100);
    --bg-hover:var(--n-300);
    --bg-active:var(--n-400);
    --bg-brand-weak:var(--b-200);
    --bg-danger-weak:var(--d-200);
    --bg-warm-weak:var(--w-200);

    --border-subtle:var(--n-300);
    --border-default:var(--n-400);
    --border-strong:var(--n-600);
    --border-brand:var(--b-500);
    --border-danger:var(--d-400);
    --border-warm:var(--w-400);

    --text-primary:var(--n-1000);
    --text-secondary:var(--n-800);
    --text-muted:var(--n-700);
    --text-brand:var(--b-900);
    --text-danger:var(--d-900);
    --text-warm:var(--w-900);
    --text-on-fill:var(--n-100);

    --fill-brand:var(--b-900);
    --fill-brand-hover:var(--b-1000);
    --fill-danger:var(--d-900);
    --fill-neutral:var(--n-1000);

    /* 고도 — 검정 그림자 대신 잉크색에서 뽑아 화면 전체 색조와 어긋나지 않게 한다 */
    --shadow-1:0 1px 2px oklch(var(--L10) .01 90 / .06);
    --shadow-2:0 2px 4px oklch(var(--L10) .01 90 / .05), 0 6px 16px oklch(var(--L10) .01 90 / .07);
    --shadow-3:0 8px 24px oklch(var(--L10) .01 90 / .12), 0 2px 6px oklch(var(--L10) .01 90 / .07);
    --ring:0 0 0 2px var(--bg-canvas), 0 0 0 4px var(--b-700);

  /* ------- 타이포 ------- */
    --sans:'Pretendard Variable',Pretendard,-apple-system,BlinkMacSystemFont,
      'Apple SD Gothic Neo','Segoe UI Variable Text','Segoe UI','Malgun Gothic',sans-serif;
    --serif:var(--sans);
    /* 사다리를 통째로 한 칸씩 올린다. 자리마다 크기를 따로 박으면 한 곳만 커지고
       옆자리는 그대로라 위아래 크기 관계가 무너진다. 기준은 네이버·다음 검색 결과 —
       목록 제목 17~18, 설명·본문 15~16, 출처·날짜 같은 보조 정보 13. */
    --fs-2xs:12px; --fs-xs:13px; --fs-sm:14px; --fs-md:15px;
    --fs-base:16px; --fs-lg:18px; --fs-xl:20px; --fs-2xl:23px; --fs-3xl:28px;
    /* 글 본문·댓글 본문만 쓰는 크기. KRDS 는 본문 최소 16px, 표준형 기본 17px 을 정해 두었다.
       사다리(fs-*)에 끼워 넣지 않은 것은 이 값이 화면 전체가 아니라 '읽는 글' 한 자리의 기준이기 때문이다. */
    --fs-read:17px;

  /* ------- 모션 ------- */
    --ease:cubic-bezier(.2,.8,.2,1);
    --ease-out:cubic-bezier(.16,1,.3,1);
    --dur-1:120ms; --dur-2:180ms; --dur-3:260ms;

  /* ============================================================
     토큰 3층 — 밀도
     색이 아니라 치수다. 컴포넌트 CSS 는 한 벌이고, 읽는 화면과 관리 화면이
     같은 컴포넌트를 다른 밀도로 쓴다.
     ============================================================ */
    --row-py:16px; --gap:14px; --pad-card:16px; --row-gap:8px;
    --radius-sm:8px; --radius-md:12px; --radius-lg:16px; --radius-pill:999px;
    --control-h:46px; --control-px:16px;
    --text-body:var(--fs-lg);
    --col-max:680px; --shell-max:100%; --hdr-max:680px; --nav-w:0px;
    --hdr-h:64px;
  }

  /* 관리 화면 — 같은 색, 더 촘촘하게 */
  [data-density="dense"]{
    /* 촘촘하다는 것은 여백이 좁다는 뜻이지 글자가 작다는 뜻이 아니다. 로그와 표를 오래
       들여다보는 화면이라 글자는 읽는 화면과 같은 단으로 두고, 여백만 줄여 밀도를 만든다.
       글자를 키운 만큼 행 높이·조작 높이도 같이 올린다 — 그대로 두면 줄이 칸에 눌린다. */
    --row-py:11px; --gap:11px; --pad-card:14px; --row-gap:6px;
    --radius-sm:6px; --radius-md:9px; --radius-lg:11px;
    --control-h:38px; --control-px:12px;
    --text-body:var(--fs-base);
  }

  /* ------- 다크 — 따뜻한 회색 바탕에 그린 강조 -------
     반전이 아니다. 사다리 값만 다시 정한다 — 시맨틱 매핑(2층)은 한 줄도 안 바뀌고,
     라이트에서 표면이 캔버스보다 밝았다면 다크에서는 저절로 뒤집힌다.
     위쪽 대비를 라이트보다 세게 잡았다. 같은 수치 대비가 어두운 화면에서 더 약하게 읽히기 때문이다.

     색은 손잡이 넷으로만 바꾼다. 무엇을 올리고 내리면 어떻게 되는지는 위 프리미티브 구역에 적혀 있다.
     지금 다크에서 라이트와 다른 손잡이는 셋이다.
       --cs:.82  화면 전체 채도를 조금 내린다. 다크에서는 같은 채도가 더 진하게 번져 보인다.
       --cn:1    라이트와 같다. 중성색은 따뜻한 회색으로 둔다 — 바탕은 검정으로 내리지 않는다.
       --cb:2.3 --hb:-76  브랜드색을 그린(168)에서 골드(92)로 돌리고 채도를 올린다.
                돌리기만 하면 은색에 가까운 베이지로 보이므로 채도가 함께 필요하다.

     08-14 에 한 번 검정 바탕·골드로 갔다가 그린으로 되돌렸고, 08-18 에 강조만 다시 골드로 정했다.
     바탕은 따뜻한 회색 그대로다. 두 번 다 화면을 눈으로 견줘 보고 고른 결정이므로, 값만 보고
     "되돌리는" 손질을 하지 않는다.

     아래 두 규칙에는 값을 적지 않는다. 위 프리미티브 구역의 --dark-... 한 벌을 가져다 쓸 뿐이다.
     두 규칙의 내용이 글자 그대로 같아야 하며, 어긋나면 DesignSystemGuardTest 가 잡는다.
     카드가 화면 바탕에서 갈리는 정도도 같은 시험이 매번 다시 잰다. */
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]){
      --L1:var(--dark-L1); --L2:var(--dark-L2); --L3:var(--dark-L3);
      --L4:var(--dark-L4); --L5:var(--dark-L5); --L6:var(--dark-L6);
      --L7:var(--dark-L7); --L8:var(--dark-L8); --L9:var(--dark-L9); --L10:var(--dark-L10);
      --cs:var(--dark-cs); --cn:var(--dark-cn); --cb:var(--dark-cb); --hb:var(--dark-hb);
      --shadow-1:var(--dark-shadow-1);
      --shadow-2:var(--dark-shadow-2);
      --shadow-3:var(--dark-shadow-3);
    }
  }
  :root[data-theme="dark"]{
    --L1:var(--dark-L1); --L2:var(--dark-L2); --L3:var(--dark-L3);
    --L4:var(--dark-L4); --L5:var(--dark-L5); --L6:var(--dark-L6);
    --L7:var(--dark-L7); --L8:var(--dark-L8); --L9:var(--dark-L9); --L10:var(--dark-L10);
    --cs:var(--dark-cs); --cn:var(--dark-cn); --cb:var(--dark-cb); --hb:var(--dark-hb);
    --shadow-1:var(--dark-shadow-1);
    --shadow-2:var(--dark-shadow-2);
    --shadow-3:var(--dark-shadow-3);
  }

  /* ============================================================
     바탕
     ============================================================ */
  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
  html,body{margin:0}
  html{color-scheme:light}
  @media (prefers-color-scheme:dark){ html:not([data-theme="light"]){color-scheme:dark} }
  html[data-theme="dark"]{color-scheme:dark}
  body{
    background:var(--bg-canvas); color:var(--text-primary); font-family:var(--sans);
    font-size:var(--fs-lg); line-height:1.5; letter-spacing:-.011em;
    -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
    font-feature-settings:'ss01','tnum' 0;
  }
  a{color:inherit;text-decoration:none}

  /* 키보드 초점 — 화면 전체에 한 벌만 둔다. 컴포넌트마다 따로 그리면 빠뜨리는 곳이 생기고,
     빠진 곳은 키보드 사용자에게 "지금 어디에 있는지"가 사라지는 자리가 된다. */
  :focus{outline:none}
  :focus-visible{outline:none;box-shadow:var(--ring);border-radius:var(--radius-sm)}
  .row:focus-visible,.pcard:focus-visible,.cta:focus-visible,.rcard:focus-visible,
  .wsum:focus-visible,.navitem:focus-visible{border-radius:var(--radius-md)}

  ::selection{background:var(--b-400);color:var(--text-primary)}

  /* ============================================================
     셸 — reader / console / focus
     라우트별로 .wrap 의 data-shell·data-density 만 갈린다.
     ============================================================ */
  .wrap{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;background:var(--bg-canvas)}
  .shellbody{display:flex;flex:1;width:100%;max-width:var(--shell-max);margin:0 auto;
    gap:0;align-items:flex-start}
  main{flex:1 1 auto;min-width:0;width:100%;max-width:var(--col-max);margin:0 auto;
    padding:6px 18px 120px}

  [data-shell="reader"]{--col-max:1280px; --shell-max:100%;    --hdr-max:1280px}
  [data-shell="article"]{--col-max:800px; --shell-max:100%;   --hdr-max:800px}
  [data-shell="focus"] {--col-max:560px; --shell-max:100%;    --hdr-max:560px}
  [data-shell="console"]{--col-max:none; --shell-max:1360px;  --hdr-max:1360px; --nav-w:252px}

  /* 화면 맨 위 머리띠.
     바탕을 화면 바탕(--bg-canvas)이 아니라 카드와 같은 표면색(--bg-surface)으로 둔다.
     전에는 canvas 를 88% 로 깔았는데, 그 값은 본문 바탕과 밝기가 사실상 같아서 띠와 몸을
     가르는 것이 1px 테두리 하나뿐이었다. 그러면 넓은 화면에서 좌우로 남는 띠가 머리처럼
     보이지 않고 "여백 위에 글자만 떠 있는" 모습이 된다 — 실제로 그렇게 보인다는 지적을 받았다.
     아래 테두리도 subtle 에서 default 로 한 단계 올려, 머리와 몸의 경계를 분명히 한다.
     내용 폭은 그대로 본문에 맞춘다(.hdrinner) — 정렬 기준은 회사 홈페이지와 같게 둔다.
     회귀 차단: DesignSystemGuardTest.headerBandIsDistinctFromCanvas */
  header{position:sticky;top:0;z-index:20;background:color-mix(in oklab,var(--bg-surface) 92%,transparent);
    backdrop-filter:saturate(1.4) blur(12px);-webkit-backdrop-filter:saturate(1.4) blur(12px);
    border-bottom:1px solid var(--border-default)}
  /* 헤더 내용은 본문 칸과 같은 폭에 맞춘다. 헤더만 화면 끝까지 벌려 두면 넓은 화면에서
     브랜드가 왼쪽 끝, 본문이 가운데로 떨어져 서로 딴 화면처럼 보인다.
     경계선(header 의 아래 테두리)은 전체 폭 그대로 둔다 — 그래야 머리와 몸이 나뉜다. */
  .hdrinner{max-width:var(--hdr-max);margin:0 auto;
    padding:calc(env(safe-area-inset-top) + 13px) 18px 12px}
  .bar{display:flex;align-items:center;justify-content:space-between;gap:12px}
  .brand{font-weight:700;font-size:var(--fs-2xl);letter-spacing:-.02em;
    display:flex;align-items:baseline;gap:8px;border-radius:var(--radius-sm)}
  /* 회사 CI. 높이를 px 이 아니라 em 으로 잡는다 — 제품 이름 글자에 맞춰 같이 줄어들어야, 좁은 화면에서
     글자만 작아지고 로고는 그대로 남아 계정 이름을 밀어내는 일이 없다. 가로는 auto 라 원본 비율을 지킨다.
     .brand 는 글줄 밑선(baseline)을 맞추는데, 이미지의 밑선은 아래 모서리라 그대로 두면 로고만 아래로
     처진다. 그래서 이 하나만 가운데로 맞춘다. */
  /* CI 규칙의 기준은 .brand 가 아니라 .brandwrap 이다.
     회사 주소가 설정되면 applyCompanySite() 가 .cibox 를 .brand 밖(형제 링크)으로 옮긴다.
     그때 .brand 자손 선택자는 전부 끊겨, 라이트·다크용 두 장이 함께 보이고 크기 규칙도
     사라져 원본 크기(306×72)로 커졌다. 실제로 그 상태로 배포돼 있었다 — 옮기는 코드가
     로그인 뒤에만 불려서 아무도 보지 못했다.
     .brandwrap 은 옮기기 전과 후 두 자리를 모두 감싸므로 규칙이 끊기지 않는다.
     회귀 차단: BrandShellGuardTest.companyLogoStylesSurviveTheMove */
  .brandwrap .cibox{flex:none;align-self:center;display:flex}
  /* 회사 CI 를 감싸는 링크. 밑줄·색이 붙으면 로고가 글자처럼 보인다. */
  #companyLink{display:flex;align-self:center;text-decoration:none;color:inherit}
  .brandwrap{display:flex;align-items:center;min-width:0;font-size:var(--fs-2xl)}
  .brandwrap .ci{height:1.05em;width:auto;display:block}
  /* 어두운 배경에서는 흰색 CI 로 갈아 끼운다. 색을 직접 박지 않고, 이 파일이 테마를 가르는 방식
     (시스템 설정 + 손으로 고른 data-theme)을 그대로 따라간다 — 두 경로 중 하나만 처리하면
     "시스템은 어두운데 손으로 밝게 골랐다" 같은 조합에서 로고가 배경에 묻힌다. */
  .brandwrap .ci-dark{display:none}
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]) .brandwrap .ci-light{display:none}
    :root:not([data-theme="light"]) .brandwrap .ci-dark{display:block}
  }
  :root[data-theme="dark"] .brandwrap .ci-light{display:none}
  :root[data-theme="dark"] .brandwrap .ci-dark{display:block}
  /* 제품 이름은 한 줄로 붙여 둔다. 줄바꿈을 허용하면 좁은 화면에서 브랜드가 가장 먼저
     쪼그라드는 자리라, 글자 사이마다 줄이 끊겨 "애/니/보/드" 처럼 세로로 늘어선다.
     한 줄로 못 박아 두면 브랜드가 제 폭을 지키고, 대신 오른쪽 계정 칸이 줄을 접는다. */
  .brand .mk{color:var(--text-brand);white-space:nowrap}
  .brand .sub{font-weight:500;font-size:var(--fs-2xs);color:var(--text-muted);
    letter-spacing:.16em;text-transform:uppercase}
  /* 머리띠 오른쪽 칸. 항목 하나하나는 줄을 끊지 않되(white-space:nowrap), 항목끼리는 자리가
     모자라면 아랫줄로 넘긴다(flex-wrap). 한 덩어리로 묶어 두면 좁은 화면에서 넘칠 만큼 커져도
     넘친 채로 잘려, 맨 오른쪽 항목이 화면 밖으로 나가 아예 누를 수 없게 된다.
     넘어간 줄도 오른쪽에 붙여야 위아래가 한 덩어리로 읽힌다. */
  .acct{font-size:var(--fs-sm);color:var(--text-muted);display:flex;align-items:center;
    flex-wrap:wrap;justify-content:flex-end;gap:10px;white-space:nowrap}
  .acct b{color:var(--text-primary);font-weight:600}
  .linkbtn{background:none;border:none;font:inherit;color:var(--text-brand);cursor:pointer;
    padding:5px 2px;font-weight:600;border-radius:var(--radius-sm);
    transition:color var(--dur-1) var(--ease),opacity var(--dur-1) var(--ease)}
  .linkbtn:hover{opacity:.72}

  /* 언어 전환 — 지금 언어를 진하게 굳혀 "지금 이것" 으로 읽히게 한다. 반대로 두면
     눈에 띄는 쪽이 지금 언어처럼 보여, 어느 쪽이 켜져 있는지 뒤집혀 읽힌다. */
  .langsw{display:inline-flex;gap:2px;align-items:center;margin-right:6px;
    background:var(--bg-hover);border-radius:var(--radius-pill);padding:2px}
  .langsw .linkbtn{font-size:var(--fs-xs);font-weight:600;color:var(--text-muted);
    text-decoration:none;padding:4px 10px;border-radius:var(--radius-pill)}
  .langsw .linkbtn:hover{color:var(--text-primary);opacity:1}
  .langsw .linkbtn.on{color:var(--text-primary);font-weight:700;cursor:default;background:var(--bg-surface);box-shadow:var(--shadow-1)}

  /* 테마 전환 — 라이트/다크/시스템 3상태 순환 */
  .themesw{background:none;border:none;cursor:pointer;color:var(--text-muted);
    padding:7px;border-radius:var(--radius-sm);display:flex;align-items:center;
    transition:color var(--dur-1) var(--ease),background var(--dur-1) var(--ease)}
  .themesw:hover{color:var(--text-primary);background:var(--bg-hover)}
  .themesw svg{display:block;width:17px;height:17px}

  .crumb{margin-top:9px;font-size:var(--fs-xs);color:var(--text-muted);
    display:flex;align-items:center;gap:7px;flex-wrap:wrap}
  .crumb:empty{display:none}
  .crumb button{background:none;border:none;font:inherit;color:var(--text-brand);
    cursor:pointer;padding:2px 0;font-weight:600;border-radius:4px}
  .crumb button:hover{opacity:.72}
  .crumb .sepmark{color:var(--border-strong)}
  .crumb .leaf{color:var(--text-muted)}

  /* ------- 화면 맨 아래 꼬리말 -------
     화면에 붙박이(fixed)로 띄우지 않는다. 늘 떠 있으면 좁은 화면에서 본문 마지막 줄과 글쓰기
     화면의 버튼을 가린다. 내용이 끝난 자리에 뒤따라 오게 두고, .wrap 이 세로 flex 라
     내용이 짧은 화면에서도 가운데로 뜨지 않고 아래에 앉는다(.shellbody 가 남은 높이를 가져간다).
     안쪽 폭은 머리띠와 같은 기준을 쓴다 — 위아래가 서로 다른 폭이면 딴 화면처럼 보인다. */
  footer{border-top:1px solid var(--border-subtle)}
  .ftrinner{max-width:var(--hdr-max);margin:0 auto;
    padding:var(--gap) 18px calc(env(safe-area-inset-bottom) + var(--gap));
    display:flex;align-items:center;flex-wrap:wrap;gap:var(--row-gap);
    font-size:var(--fs-2xs);color:var(--text-muted)}
  .ftrmk{font-weight:600}

  /* ------- 사이드바(콘솔 전용) ------- */
  .sidenav{display:none}
  [data-shell="console"] .sidenav{
    display:flex;flex-direction:column;gap:2px;flex:none;width:var(--nav-w);
    padding:18px 12px 40px;position:sticky;top:var(--hdr-h);
    max-height:calc(100dvh - var(--hdr-h));overflow-y:auto;
    border-right:1px solid var(--border-subtle)}
  .navgroup{font-size:var(--fs-2xs);font-weight:700;letter-spacing:.1em;text-transform:uppercase;
    color:var(--text-muted);padding:14px 10px 6px}
  .navgroup:first-child{padding-top:0}
  .navitem{display:flex;align-items:center;gap:9px;width:100%;text-align:left;font:inherit;
    font-size:var(--fs-md);font-weight:500;color:var(--text-secondary);background:none;border:none;
    padding:9px 10px;border-radius:var(--radius-sm);cursor:pointer;position:relative;
    transition:background var(--dur-1) var(--ease),color var(--dur-1) var(--ease)}
  .navitem:hover{background:var(--bg-hover);color:var(--text-primary)}
  .navitem.on{background:var(--bg-brand-weak);color:var(--text-brand);font-weight:600}
  .navitem .nic{flex:none;width:16px;text-align:center;opacity:.75;font-size:var(--fs-md)}

  /* ============================================================
     본문 공통
     ============================================================ */
  .lead{font-weight:600;font-size:var(--fs-base);color:var(--text-muted);
    margin:20px 2px 4px;letter-spacing:-.005em}

  /* 조작 버튼이 늘면 한 줄에 다 못 들어간다. 감싸지 않으면 본문이 0 폭까지 눌려
     이름이 한 글자씩 세로로 쪼개진다(전체 관리자의 회원 목록에서 실제로 그랬다).
     본문에 기준 폭을 주어 넘칠 때 조작이 아랫줄로 내려가게 한다. */
  /* 한 줄을 카드로 띄운다. 선 하나로만 나누면 어디까지가 한 건인지 눈으로 끊기지 않는다.
     아래 테두리와 둥근 모서리를 같이 걸면 선의 양 끝이 모서리를 따라 말려 올라가 휜 선으로
     보인다 — 테두리는 네 변을 다 두르거나 아예 없어야 곧게 보인다. */
  .row{display:flex;align-items:center;gap:var(--gap);padding:var(--row-py) 14px;flex-wrap:wrap;
    background:var(--bg-surface);border:1px solid var(--border-subtle);
    border-radius:var(--radius-md);margin:0 0 var(--row-gap);cursor:pointer;
    transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease)}
  .row:hover{background:var(--bg-hover);border-color:var(--border-default)}
  .row:active{background:var(--bg-active)}
  .row .body{flex:1 1 200px;min-width:0}
  .row .t{font-size:var(--text-body);font-weight:600;letter-spacing:-.02em}
  .row .d{font-size:var(--fs-sm);color:var(--text-muted);margin-top:3px;overflow:hidden;
    text-overflow:ellipsis;white-space:nowrap}
  .row .meta{font-size:var(--fs-xs);color:var(--text-muted);margin-top:5px;
    display:flex;gap:10px;flex-wrap:wrap;align-items:center}
  .chev{color:var(--border-strong);font-size:var(--fs-xl);flex:none;
    transition:transform var(--dur-2) var(--ease),color var(--dur-1) var(--ease)}
  .row:hover .chev{transform:translateX(2px);color:var(--text-brand)}

  /* 목록 표현 5종(REQ-113). 카드형·격자형은 썸네일 자리를 두고, 달력형은 날짜로 묶고, 아코디언형은 펼친다. */
  .cards{display:grid;gap:var(--gap)}
  .cards.grid{grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}
  .cards.card{grid-template-columns:repeat(auto-fill,minmax(272px,1fr))}
  .pcard{border:1px solid var(--border-subtle);border-radius:var(--radius-md);overflow:hidden;
    cursor:pointer;background:var(--bg-surface);
    transition:border-color var(--dur-2) var(--ease),transform var(--dur-2) var(--ease-out),
      box-shadow var(--dur-2) var(--ease-out)}
  .pcard:hover{border-color:var(--border-brand);transform:translateY(-2px);box-shadow:var(--shadow-2)}
  .pthumb{height:104px;display:flex;align-items:center;justify-content:center;
    background:var(--bg-hover);font-size:28px;color:var(--text-muted)}
  .pbody{padding:10px 12px}
  .daygroup{margin-bottom:12px}
  .dayhead{font-size:var(--fs-xs);font-weight:700;color:var(--text-muted);
    padding:6px 2px;border-bottom:1px solid var(--border-default);
    letter-spacing:.04em}
  /* 펼친 내용은 머리와 한 덩이다. 카드 사이 간격을 그대로 두면 펼친 글이 남의 칸처럼 뜬다. */
  .row:has(+ .accbody.on){margin-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}
  .accbody{display:none;padding:12px 14px;background:var(--bg-surface);
    border:1px solid var(--border-subtle);border-top:0;margin-bottom:var(--row-gap);
    border-radius:0 0 var(--radius-md) var(--radius-md);white-space:pre-wrap}
  .accbody.on{display:block;animation:fadein var(--dur-2) var(--ease-out)}
  .reactions{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
  .rbtn{border:1px solid var(--border-default);background:var(--bg-surface);
    border-radius:var(--radius-pill);padding:7px 15px;cursor:pointer;font:inherit;
    font-size:var(--fs-md);color:var(--text-primary);
    transition:border-color var(--dur-1) var(--ease),background var(--dur-1) var(--ease),
      transform var(--dur-1) var(--ease)}
  .rbtn:hover{border-color:var(--border-strong)}
  .rbtn:active{transform:scale(.96)}
  .rbtn.on{border-color:var(--border-brand);background:var(--bg-brand-weak);
    color:var(--text-brand);font-weight:700}

  /* 구분점. 부모가 flex(.row .meta)면 vertical-align 이 무시되고 위로 붙어 따옴표처럼
     보이므로 align-self 로 가운데 고정. */
  .dot{width:3px;height:3px;border-radius:50%;background:var(--border-strong);
    display:inline-block;vertical-align:middle;align-self:center;flex:none}
  .badge{display:inline-block;font-size:var(--fs-2xs);font-weight:700;letter-spacing:.02em;
    color:var(--text-brand);border:1px solid var(--border-brand);background:var(--bg-brand-weak);
    border-radius:5px;padding:1px 7px;margin-right:7px}

  /* ------- 글 상세 ------- */
  .article h1{font-weight:700;font-size:var(--fs-3xl);line-height:1.32;
    letter-spacing:-.03em;margin:22px 0 12px}
  .pmeta{font-size:var(--fs-xs);color:var(--text-muted);display:flex;gap:10px;align-items:center;
    flex-wrap:wrap;padding-bottom:16px;border-bottom:1px solid var(--border-default)}
  .content{font-size:var(--fs-read);line-height:1.8;white-space:pre-wrap;word-break:break-word;
    padding:22px 0 8px;min-height:60px}
  .fields{border-top:1px solid var(--border-subtle);padding-top:14px;margin-top:8px}
  .fields .f{display:flex;gap:10px;font-size:var(--fs-md);padding:5px 0}
  .fields .f .k{color:var(--text-muted);min-width:84px}
  .secbar{display:flex;align-items:center;justify-content:space-between;margin:28px 2px 4px;gap:10px}
  .secbar .h{font-weight:700;font-size:var(--fs-lg);letter-spacing:-.02em}
  .secbar .h em{font-style:normal;color:var(--text-brand);margin-left:5px}
  /* "더 보기" 는 쪽 넘김과 다른 조작부다. 쪽 넘김은 목록 밖으로 나가는 길이라 좁게 두지만,
     이것은 읽던 목록을 그 자리에서 늘리는 것이라 목록 폭을 그대로 이어받아 한 줄을 채운다. */
  .morebtn{width:100%}

  /* ------- 댓글 ------- */
  .cmt{padding:15px 2px;border-bottom:1px solid var(--border-subtle)}
  .cmt .ct{font-size:var(--fs-base);line-height:1.65;white-space:pre-wrap;word-break:break-word}
  /* 댓글 밖(임시저장 카드 등)에서도 같은 메타 표기를 쓰므로 클래스 단독으로 동작해야 한다.
     .cmt 안에서만 적용되면 다른 곳에서는 flex 가 풀려 구분점 간격이 사라진다. */
  /* 작성자·날짜는 목록의 같은 표기(.row .meta)와 크기를 맞춘다. 한 단 아래로 두면
     같은 성격의 정보가 화면마다 다른 크기로 보인다. */
  .cm{font-size:var(--fs-xs);color:var(--text-muted);margin-top:6px;display:flex;gap:9px;
    align-items:center;flex-wrap:wrap}
  .crep{margin-top:8px}

  /* ============================================================
     폼
     ============================================================ */
  .field{margin:16px 0}
  /* 비밀번호 보기 토글. 입력칸 오른쪽 안쪽에 눈 아이콘을 겹쳐 놓는다. */
  .pwwrap{position:relative}
  .pwwrap input{padding-right:46px}
  .pweye{position:absolute;right:5px;top:50%;transform:translateY(-50%);display:flex;
    align-items:center;background:none;border:0;padding:9px;cursor:pointer;
    color:var(--text-muted);border-radius:var(--radius-sm);
    transition:color var(--dur-1) var(--ease),background var(--dur-1) var(--ease)}
  .pweye:hover{color:var(--text-primary);background:var(--bg-hover)}
  .pweye svg{display:block}
  label{display:block;font-size:var(--fs-xs);font-weight:600;color:var(--text-secondary);
    margin-bottom:7px;letter-spacing:-.005em}
  input,textarea,select{width:100%;font:inherit;font-size:var(--fs-base);color:var(--text-primary);
    background:var(--bg-surface);border:1px solid var(--border-default);
    border-radius:var(--radius-sm);padding:0 var(--control-px);height:var(--control-h);
    outline:none;
    transition:border-color var(--dur-1) var(--ease),background var(--dur-1) var(--ease),
      box-shadow var(--dur-1) var(--ease)}
  textarea{resize:vertical;min-height:170px;line-height:1.75;height:auto;
    padding:13px var(--control-px)}
  select{cursor:pointer;width:auto;padding-right:calc(var(--control-px) + 4px)}
  input:hover,textarea:hover,select:hover{border-color:var(--border-strong)}
  input:focus,textarea:focus,select:focus{border-color:var(--border-brand);
    box-shadow:0 0 0 3px var(--bg-brand-weak)}
  input:focus-visible,textarea:focus-visible,select:focus-visible{box-shadow:0 0 0 3px var(--bg-brand-weak)}
  ::placeholder{color:var(--text-muted);opacity:.75}
  /* 읽기 전용 표시칸 — 눌러도 고칠 수 없다는 걸 색으로 먼저 알린다 */
  .ro{background:var(--bg-hover);color:var(--text-muted);cursor:default}
  .ro:hover{border-color:var(--border-default)}
  input[type=file]{font-size:var(--fs-sm);color:var(--text-muted);background:none;border:none;
    padding:8px 0;height:auto}

  .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;font:inherit;
    font-weight:600;font-size:var(--fs-base);border-radius:var(--radius-sm);
    padding:0 var(--control-px);height:var(--control-h);border:1px solid transparent;
    cursor:pointer;white-space:nowrap;
    transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),
      transform var(--dur-1) var(--ease),box-shadow var(--dur-1) var(--ease),
      opacity var(--dur-1) var(--ease)}
  .btn:active{transform:scale(.975)}
  .btn[disabled]{opacity:.45;cursor:not-allowed;transform:none}
  .btn.pri{background:var(--fill-brand);color:var(--text-on-fill);box-shadow:var(--shadow-1)}
  .btn.pri:hover{background:var(--fill-brand-hover);box-shadow:var(--shadow-2)}
  .btn.ghost{background:var(--bg-surface);border-color:var(--border-default);color:var(--text-primary)}
  .btn.ghost:hover{border-color:var(--border-strong);background:var(--bg-hover)}
  .btn.full{width:100%}
  .btn.sm{height:34px;padding:0 12px;font-size:var(--fs-sm);border-radius:var(--radius-sm)}
  .btn.danger{color:var(--text-danger);background:var(--bg-surface);border-color:var(--border-danger)}
  .btn.danger:hover{background:var(--bg-danger-weak)}
  .actions{display:flex;gap:9px;margin-top:10px;flex-wrap:wrap}

  /* ------- 탭 ------- */
  .tabs{display:flex;gap:3px;background:var(--bg-hover);padding:3px;
    border-radius:var(--radius-md);margin:20px 0 8px}
  .tabs button{flex:1;font:inherit;font-weight:600;font-size:var(--fs-md);border:none;
    background:none;color:var(--text-muted);padding:9px 8px;border-radius:var(--radius-sm);
    cursor:pointer;transition:background var(--dur-2) var(--ease),color var(--dur-1) var(--ease)}
  .tabs button:hover{color:var(--text-primary)}
  .tabs button.on{background:var(--bg-surface);color:var(--text-primary);box-shadow:var(--shadow-1)}

  /* ============================================================
     상태 표시
     ============================================================ */
  .empty{text-align:center;color:var(--text-muted);font-size:var(--fs-md);
    padding:64px 20px;line-height:1.75}
  .empty .ic{font-size:36px;color:var(--border-strong);margin-bottom:12px;line-height:1}
  .note{font-size:var(--fs-xs);color:var(--text-muted);margin-top:10px;line-height:1.65}
  .err{color:var(--text-danger);font-size:var(--fs-sm);margin-top:10px;min-height:18px}
  .rule{height:1px;background:var(--border-default);margin:24px 0;border:0}
  .mininote{font-size:var(--fs-xs);color:var(--text-muted);margin:12px 2px 0;line-height:1.65}

  /* 뼈대 로딩 — "로딩중" 글자보다 앞으로 들어올 모양을 미리 보여 주는 편이 기다림이 짧게 느껴진다 */
  .skel{padding:8px 0 40px}
  .skel .sk{height:14px;border-radius:6px;margin:12px 0;
    background:linear-gradient(90deg,var(--bg-hover) 25%,var(--bg-active) 37%,var(--bg-hover) 63%);
    background-size:400% 100%;animation:shimmer 1.4s ease-in-out infinite}
  .skel .sk.w70{width:70%} .skel .sk.w45{width:45%} .skel .sk.w85{width:85%}
  .skel .sk.tall{height:44px;border-radius:var(--radius-md)}
  @keyframes shimmer{from{background-position:100% 0}to{background-position:-100% 0}}
  @keyframes fadein{from{opacity:0}to{opacity:1}}
  @keyframes viewin{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

  /* 화면 전환 — 아주 짧게. 길면 빠른 조작에서 걸리적거린다 */
  main>*{animation:viewin var(--dur-3) var(--ease-out)}

  .toast{position:fixed;left:50%;bottom:calc(env(safe-area-inset-bottom) + 32px);
    transform:translateX(-50%) translateY(12px) scale(.97);
    background:var(--fill-neutral);color:var(--bg-canvas);font-size:var(--fs-md);font-weight:500;
    padding:12px 18px;border-radius:var(--radius-md);opacity:0;box-shadow:var(--shadow-3);
    transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-2) var(--ease-out);
    z-index:50;max-width:min(88%,420px);text-align:center;pointer-events:none}
  .toast.show{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}

  /* 확인 모달(네이티브 confirm 대체) */
  .modal-ov{position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;
    background:oklch(0% 0 0 / .38);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
    padding:24px;opacity:0;transition:opacity var(--dur-2) var(--ease)}
  .modal-ov.show{opacity:1}
  .modal{width:100%;max-width:380px;background:var(--bg-surface);border:1px solid var(--border-default);
    border-radius:var(--radius-lg);padding:24px 22px 20px;box-shadow:var(--shadow-3);
    transform:translateY(10px) scale(.97);transition:transform var(--dur-3) var(--ease-out)}
  .modal-ov.show .modal{transform:none}
  .modal .mt{font-weight:700;font-size:var(--fs-lg);margin-bottom:8px;letter-spacing:-.02em}
  .modal .mb{color:var(--text-secondary);font-size:var(--fs-md);line-height:1.6;margin-bottom:20px}
  .modal .ma{display:flex;gap:10px}
  .modal .ma .btn{flex:1}

  /* ------- 관리자 진입 카드 ------- */
  .cta{display:flex;align-items:center;justify-content:space-between;gap:12px;
    background:var(--fill-brand);color:var(--text-on-fill);border-radius:var(--radius-md);
    padding:17px 19px;margin:16px 0 4px;cursor:pointer;box-shadow:var(--shadow-1);
    transition:background var(--dur-1) var(--ease),transform var(--dur-2) var(--ease-out),
      box-shadow var(--dur-2) var(--ease-out)}
  .cta:hover{background:var(--fill-brand-hover);transform:translateY(-1px);box-shadow:var(--shadow-2)}
  .cta:active{transform:none}
  .cta .t{font-weight:700;font-size:var(--fs-lg);letter-spacing:-.02em}
  .cta .s{font-size:var(--fs-xs);opacity:.85;margin-top:3px}
  .cta .go{font-size:22px;opacity:.9;transition:transform var(--dur-2) var(--ease)}
  .cta:hover .go{transform:translateX(3px)}

  /* ============================================================
     위저드
     ============================================================ */
  .radios{display:flex;flex-direction:column;gap:10px;margin-top:14px}
  .rcard{border:1px solid var(--border-default);background:var(--bg-surface);
    border-radius:var(--radius-md);padding:15px 16px;cursor:pointer;
    display:flex;align-items:center;gap:13px;
    transition:border-color var(--dur-1) var(--ease),background var(--dur-1) var(--ease),
      transform var(--dur-1) var(--ease)}
  .rcard:hover{border-color:var(--border-strong)}
  .rcard:active{transform:scale(.995)}
  .rcard.on{border-color:var(--border-brand);background:var(--bg-brand-weak)}
  .rcard .rk{width:20px;height:20px;border-radius:50%;border:2px solid var(--border-strong);
    flex:none;display:grid;place-items:center;transition:border-color var(--dur-1) var(--ease)}
  .rcard.on .rk{border-color:var(--fill-brand)}
  .rcard.on .rk::after{content:'';width:10px;height:10px;border-radius:50%;
    background:var(--fill-brand);animation:fadein var(--dur-1) var(--ease)}
  .rcard .rt{font-weight:600;font-size:var(--fs-base)}
  .rcard .rd{font-size:var(--fs-xs);color:var(--text-muted);margin-top:2px}

  .tog{display:flex;align-items:center;justify-content:space-between;gap:12px;
    padding:14px 2px;border-bottom:1px solid var(--border-subtle)}
  .tog .tl{font-size:var(--fs-base);font-weight:500}
  .tog .td{font-size:var(--fs-xs);color:var(--text-muted);margin-top:2px}
  .sw{width:46px;height:28px;border-radius:var(--radius-pill);background:var(--border-strong);
    position:relative;flex:none;cursor:pointer;transition:background var(--dur-2) var(--ease)}
  .sw.on{background:var(--fill-brand)}
  .sw::after{content:'';position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;
    background:var(--n-100);box-shadow:var(--shadow-1);
    transition:transform var(--dur-2) var(--ease-out)}
  .sw.on::after{transform:translateX(18px)}

  .wbtns{display:flex;gap:10px;margin-top:26px}
  .sumcard{border:1px solid var(--border-default);border-radius:var(--radius-md);
    background:var(--bg-surface);padding:4px 16px;margin-top:14px}
  .sumcard .r{display:flex;justify-content:space-between;gap:14px;padding:12px 0;
    border-bottom:1px solid var(--border-subtle);font-size:var(--fs-md)}
  .sumcard .r:last-child{border-bottom:0}
  .sumcard .r .k{color:var(--text-muted)}
  .sumcard .r .v{font-weight:600;text-align:right}
  .inlinechk{display:flex;gap:8px;align-items:stretch;margin-top:2px}

  .wiz{padding-top:4px}
  .wprog{height:5px;border-radius:var(--radius-pill);background:var(--bg-active);
    overflow:hidden;margin:16px 0 8px}
  .wprog .wpfill{height:100%;background:var(--fill-brand);border-radius:var(--radius-pill);
    transition:width var(--dur-3) var(--ease-out)}
  .wcard{border:1px solid var(--border-default);background:var(--bg-surface);
    border-radius:var(--radius-md);padding:17px 17px 15px;margin:10px 0;
    transition:border-color var(--dur-2) var(--ease),box-shadow var(--dur-2) var(--ease-out)}
  .wcard.active{border-color:var(--border-brand);box-shadow:var(--shadow-2)}
  .wcard.anim{animation:wcardin var(--dur-3) var(--ease-out)}
  @keyframes wcardin{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
  .wstep{font-weight:700;font-size:var(--fs-xl);letter-spacing:-.025em}
  .wdesc{font-size:var(--fs-sm);color:var(--text-muted);margin:4px 0 10px;line-height:1.6}
  .wsum{display:flex;justify-content:space-between;gap:12px;align-items:center;
    border:1px solid var(--border-subtle);background:var(--bg-surface);
    border-radius:var(--radius-md);padding:12px 14px;margin:8px 0;cursor:pointer;
    animation:wsumin var(--dur-2) var(--ease-out);
    transition:border-color var(--dur-1) var(--ease),background var(--dur-1) var(--ease)}
  @keyframes wsumin{from{opacity:0}to{opacity:1}}
  .wsum:hover{border-color:var(--border-strong);background:var(--bg-hover)}
  .wsum .v{font-size:var(--fs-md);font-weight:600}
  .wsum .ed{font-size:var(--fs-xs);color:var(--text-brand);flex:none;margin-left:10px;font-weight:600}

  /* ============================================================
     권한 매트릭스 — 콘솔에서 넓어지면 라벨이 정상 크기로 돌아온다
     ============================================================ */
  .matrix{margin-top:14px;border:1px solid var(--border-default);border-radius:var(--radius-md);
    overflow:hidden;background:var(--bg-surface)}
  .mrow{display:grid;grid-template-columns:1.25fr repeat(5,1fr);align-items:center}
  .mrow+.mrow{border-top:1px solid var(--border-subtle)}
  .mrow:not(.mhead):hover{background:var(--bg-hover)}
  .mhead{background:var(--bg-hover)}
  .mrole{padding:12px 12px;font-size:var(--fs-sm);font-weight:600}
  .mcell{display:flex;justify-content:center;padding:9px 0;font-size:var(--fs-2xs);
    color:var(--text-muted)}
  .mhead .mcell{font-weight:700}
  .mcb{width:24px;height:24px;border-radius:6px;border:1.5px solid var(--border-strong);
    background:var(--bg-surface);cursor:pointer;position:relative;
    transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease),
      transform var(--dur-1) var(--ease)}
  .mcb:hover{border-color:var(--fill-brand)}
  .mcb:active{transform:scale(.9)}
  .mcb.on{background:var(--fill-brand);border-color:var(--fill-brand)}
  .mcb.on::after{content:'';position:absolute;left:8px;top:4px;width:6px;height:11px;
    border:solid var(--n-100);border-width:0 2px 2px 0;transform:rotate(45deg)}

  /* ------- 필드 편집기 ------- */
  .fcard{border:1px solid var(--border-default);border-radius:var(--radius-md);
    background:var(--bg-surface);padding:14px 15px;margin-bottom:12px}
  .frow{display:flex;align-items:center;gap:10px;margin-bottom:9px}
  .frow:last-child{margin-bottom:0}
  .frow .grow{flex:1;min-width:0}
  .flabel{font-size:var(--fs-sm);color:var(--text-muted);min-width:42px;flex:none}
  .listhead{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:16px 0 4px}
  /* 게시판 이름이 서는 자리. 바탕과 같은 색으로 두면 목록 첫 줄과 구별되지 않아
     "무엇을 보고 있는 화면인지" 가 눈에 먼저 들어오지 않는다. */
  .bhead{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:18px 0 4px;
    background:var(--bg-surface);border:1px solid var(--border-subtle);
    border-radius:var(--radius-md);padding:var(--pad-card)}
  .toolbar{display:flex;gap:8px;align-items:stretch;margin:12px 0 6px}
  .toolbar input{flex:1}
  .toolbar select,.toolbar .btn{flex:none}

  /* ------- 첨부·미디어 ------- */
  .postimg{display:block;max-width:100%;height:auto;border-radius:var(--radius-md);
    margin:14px 0;background:var(--bg-hover)}
  .pthumb.shot{position:relative;padding:0;overflow:hidden;background:#000}
  .pthumb.shot img{width:100%;height:100%;object-fit:cover;display:block}
  .pthumb .playmark{position:absolute;right:8px;bottom:6px;color:#fff;font-size:15px;
    text-shadow:0 1px 3px rgba(0,0,0,.7);pointer-events:none}
  .videobox{position:relative;width:100%;aspect-ratio:16/9;margin:14px 0;
    border-radius:var(--radius-md);overflow:hidden;background:#000}
  .videobox iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
  .filelink{display:flex;align-items:center;justify-content:space-between;gap:10px;
    padding:12px 8px;margin:0 -8px;
    font-size:var(--fs-md);color:var(--text-brand);border-radius:var(--radius-sm);
    transition:background var(--dur-1) var(--ease)}
  .filelink:hover{background:var(--bg-hover)}
  .filelink .fsize{color:var(--text-muted);font-size:var(--fs-xs);flex:none}

  /* ------- 계정 메뉴 ------- */
  /* 개인 작업은 본문이 아니라 헤더 우측 유틸리티 내비게이션에 모은다. */
  .acctmenu{position:relative}
  .acctmenu>.panel{position:absolute;right:0;top:calc(100% + 8px);z-index:40;min-width:212px;
    background:var(--bg-surface);border:1px solid var(--border-default);
    border-radius:var(--radius-md);box-shadow:var(--shadow-3);padding:6px;display:none}
  .acctmenu.open>.panel{display:block;animation:menuin var(--dur-2) var(--ease-out)}
  @keyframes menuin{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
  .acctmenu .panel button{display:flex;width:100%;align-items:center;gap:8px;text-align:left;
    font:inherit;font-size:var(--fs-md);color:var(--text-primary);background:none;border:none;
    padding:10px 12px;border-radius:var(--radius-sm);cursor:pointer;
    transition:background var(--dur-1) var(--ease)}
  .acctmenu .panel button:hover{background:var(--bg-hover)}
  .acctmenu .panel .sub{color:var(--text-muted);font-size:var(--fs-xs);padding:6px 12px 2px}
  /* 회원 이름은 머리띠에서 길이를 예측할 수 없는 유일한 칸이다. 그대로 두면 긴 이름 하나가
     오른쪽 줄을 통째로 차지해, 바로 옆의 로그아웃을 아랫줄로 밀어낸다. 넘치는 만큼만 … 로
     줄인다. 이름 전체는 계정 메뉴를 열면 볼 수 있다. */
  .acctmenu>.linkbtn b{display:inline-block;max-width:6em;overflow:hidden;
    text-overflow:ellipsis;vertical-align:bottom}

  /* 영어 표기 입력칸 — 기본은 접힘. 한국어만 쓰는 업체에 빈 칸을 강요하지 않는다. */
  .enfield{margin:-6px 0 14px}
  .enfield>.linkbtn{font-size:var(--fs-sm);font-weight:500;color:var(--text-muted)}

  .quicklinks{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0 2px}
  .qbtn{font:inherit;font-size:var(--fs-sm);font-weight:600;color:var(--text-primary);
    background:var(--bg-surface);border:1px solid var(--border-default);
    border-radius:var(--radius-pill);padding:9px 15px;cursor:pointer;
    transition:border-color var(--dur-1) var(--ease),background var(--dur-1) var(--ease),
      transform var(--dur-1) var(--ease)}
  .qbtn:hover{border-color:var(--border-strong);background:var(--bg-hover)}
  .qbtn:active{transform:scale(.97)}
  .tagchip{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-xs);
    color:var(--text-warm);background:var(--bg-warm-weak);border:1px solid var(--border-warm);
    border-radius:var(--radius-pill);padding:4px 11px;margin:3px 5px 3px 0}
  /* 회원 목록의 현재 등급 배지. 조작 버튼이 늘어 본문이 좁아져도 글자가 쪼개지지 않게
     줄바꿈을 막는다. */
  .rolebadge{display:inline-block;margin-left:8px;padding:2px 9px;border-radius:var(--radius-pill);
    font-size:var(--fs-xs);font-weight:700;vertical-align:middle;white-space:nowrap;
    background:var(--bg-hover);color:var(--text-muted)}
  .rolebadge.admin{background:var(--fill-brand);color:var(--text-on-fill)}
  .tagchip .x{cursor:pointer;color:var(--text-muted);font-weight:700}
  .tagchip .x:hover{color:var(--text-danger)}

  /* 쪽 넘김. 모양의 근거는 마스터 31번 구현 기준 항목 14(벤치마킹 확정)에 있다.
     글 자리(전체 N건 · M / K 쪽)를 숫자 줄 위에 두므로 세로로 쌓는다. */
  .pager{display:flex;flex-direction:column;align-items:center;gap:10px;margin:24px 0 4px}
  .pager .pageinfo{margin:0;font-size:var(--fs-sm);color:var(--text-muted);
    font-variant-numeric:tabular-nums}
  .pagerow{display:flex;align-items:center;justify-content:center;gap:10px}
  .pagelist{display:flex;align-items:center;gap:4px;list-style:none;margin:0;padding:0}
  /* 누르는 자리는 24×24 CSS px 이상이어야 한다(WCAG 2.2 SC 2.5.8). 34px 은 같은 줄에 서는
     .btn.sm 과 같은 높이라, 숫자와 이전·다음이 서로 어긋나 보이지 않는다. */
  .pagenum{display:inline-flex;align-items:center;justify-content:center;font:inherit;
    min-width:34px;height:34px;padding:0 8px;border:1px solid transparent;
    border-radius:var(--radius-sm);font-size:var(--fs-sm);font-variant-numeric:tabular-nums;
    color:var(--text-primary);text-decoration:none;background:none;cursor:pointer;
    transition:background var(--dur-1) var(--ease),border-color var(--dur-1) var(--ease)}
  .pagenum:hover:not(.on){background:var(--bg-hover);border-color:var(--border-default)}
  /* 지금 보고 있는 쪽. 색만으로 구분하지 않는다 — 링크를 걷어 내고(span) 굵기·테두리로도
     갈라 둔다. 색을 못 보는 사람에게 색만 다른 칸은 다른 칸이 아니다. */
  .pagenum.on{background:var(--fill-brand);color:var(--text-on-fill);border-color:var(--fill-brand);
    font-weight:700;cursor:default}
  .pagelist .gap{display:inline-flex;align-items:center;justify-content:center;
    min-width:24px;height:34px;color:var(--text-muted)}
  .pager button[disabled]{opacity:.4}
  /* 쪽을 넘기면 목록 머리로 초점을 되돌린다(SC 4.1.3). 그때 본문 전체에 테두리가 그려지면
     눌러서 넘긴 사람에게는 잡음이라, 자판으로 옮긴 초점(:focus-visible)일 때만 남긴다. */
  #view:focus:not(:focus-visible){outline:none}
  /* 화면에는 안 보이지만 보조기기는 읽는 자리. display:none 으로 감추면 읽히지도 않는다. */
  .srlive{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap;border:0}

  /* ============================================================
     유틸리티 — 화면 코드가 style 문자열로 색·간격을 직접 쓰지 않게 하는 자리.
     인라인 style 은 스타일시트 밖이라 테마를 갈아도 따라오지 않는다.
     ============================================================ */
  /* 여백 — 네 변을 한꺼번에 정하는 것(.u-m-0)을 먼저 두고 한 변짜리를 뒤에 둔다.
     둘을 같이 걸었을 때 한 변짜리가 이기게 하려면 순서가 이래야 한다. */
  .u-m-0{margin:0}
  .u-mt-n6{margin-top:-6px} .u-mt-n2{margin-top:-2px}
  .sw.locked{opacity:.45;cursor:not-allowed}
  .u-block{display:block}
  .u-mt-0{margin-top:0}   .u-mt-4{margin-top:4px}   .u-mt-6{margin-top:6px}
  .u-mt-8{margin-top:8px} .u-mt-10{margin-top:10px} .u-mt-14{margin-top:14px}
  .u-mt-16{margin-top:16px} .u-mt-18{margin-top:18px}
  .u-mb-0{margin-bottom:0} .u-mb-2{margin-bottom:2px} .u-mb-4{margin-bottom:4px}
  .u-mb-6{margin-bottom:6px} .u-mb-10{margin-bottom:10px} .u-mb-12{margin-bottom:12px}
  .u-ml-6{margin-left:6px}
  .u-pad-30{padding:30px 0}
  /* 크기 — 값이 바뀌면 화면이 흔들리므로 이름에 수치를 박아 둔다 */
  .u-minh-16{min-height:16px} .u-minh-18{min-height:18px}
  .u-ta-80{min-height:80px} .u-ta-84{min-height:84px} .u-ta-88{min-height:88px}
  .u-mw-130{max-width:130px} .u-mw-160{max-width:160px}
  .u-w-auto{width:auto;min-width:auto} .u-w-full{width:100%}
  /* 배치 */
  .u-row{display:flex;gap:8px;align-items:stretch}
  .u-row-c{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:8px 0}
  .u-wrap-end{flex-wrap:wrap;justify-content:flex-end}
  .u-none{flex:none} .u-nowrap{flex:none;white-space:nowrap}
  .u-grow{flex:1} .u-minw-0{min-width:0}
  .u-hide{display:none} .u-hide-pad{display:none;padding:8px 0 4px}
  .u-dim{opacity:.55}
  .u-ta-c{text-align:center} .u-ta-r{text-align:right}
  .u-pre{padding:8px 0;font-size:var(--fs-md);white-space:pre-wrap}
  /* 글자 */
  .u-fw-6{font-weight:600} .u-fw-7{font-weight:700}
  .u-fs-xs{font-size:var(--fs-2xs)} .u-fs-sm{font-size:var(--fs-sm)}
  .u-fs-md{font-size:var(--fs-md)} .u-fs-base{font-size:var(--fs-base)}
  .u-danger{color:var(--text-danger)} .u-muted{color:var(--text-muted)}
  .u-brand{color:var(--text-brand)} .u-ink{color:var(--text-primary)}
  .u-lbl-sub{display:block;font-size:var(--fs-2xs);color:var(--text-muted);font-weight:400}

  /* ============================================================
     반응형
     ============================================================ */
  @media (max-width:1023px){
    /* 콘솔의 사이드바를 상단 가로 탭으로 접는다. 서랍보다 단순하고, 항목이 일곱 개
       이하라 탭으로 충분하다. */
    [data-shell="console"] .shellbody{flex-direction:column;align-items:stretch}
    [data-shell="console"] .sidenav{
      flex-direction:row;width:auto;max-height:none;height:auto;position:sticky;
      top:var(--hdr-h);z-index:15;padding:8px 14px;gap:6px;overflow-x:auto;
      border-right:0;border-bottom:1px solid var(--border-subtle);
      background:color-mix(in oklab,var(--bg-canvas) 92%,transparent);
      backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
      scrollbar-width:none}
    [data-shell="console"] .sidenav::-webkit-scrollbar{display:none}
    .navgroup{display:none}
    /* 세로 목록일 때의 width:100% 를 풀지 않으면 첫 항목이 줄을 통째로 차지해
       나머지가 가로 스크롤 밖으로 밀려난다. */
    .navitem{width:auto;white-space:nowrap;flex:none;padding:8px 13px;
      border-radius:var(--radius-pill);border:1px solid var(--border-subtle)}
    .navitem.on{border-color:var(--border-brand)}
  }
  @media (max-width:768px){
    body{overflow-x:hidden}
    .hdrinner{padding-left:14px;padding-right:14px}
    .ftrinner{padding-left:14px;padding-right:14px}
    main{padding:6px 14px 120px}
    /* iOS 는 16px 미만 입력칸에 초점이 가면 화면을 확대한다. 확대되면 레이아웃이
       가로로 밀려 되돌아오지 않는다. */
    input,textarea,select{font-size:16px;width:100%}
    select{width:100%}
    .btn{height:48px}
    .btn.sm{height:38px;font-size:var(--fs-sm)}
    .toolbar{flex-wrap:wrap}
    .toolbar input{flex:1 1 100%}
    .toolbar select,.toolbar .btn{flex:1 1 auto}
    .actions .btn{flex:1 1 auto}
    .wbtns{gap:8px}
    .mrow{grid-template-columns:1.05fr repeat(5,minmax(0,1fr))}
    .mrole{padding:10px 8px;font-size:var(--fs-xs)}
    .quicklinks{gap:6px}
    /* 쪽 넘김 — 좁은 화면에서는 이전·다음을 숫자 줄 위로 올려 세로로 쌓는다. 한 줄에 다 넣으면
       숫자 칸이 손가락보다 좁아진다. 칸 수도 11 에서 7 로 줄인다(pagerSlots). 한 쪽에 담는
       개수는 건드리지 않는다 — 화면 폭에 따라 목록 내용이 달라지면 주소를 나눠 봐도 서로 다른
       것을 보게 된다. */
    .pagerow{flex-wrap:wrap}
    .pagerow .pagelist{order:3;flex:1 0 100%;justify-content:center}
    .article h1{font-size:var(--fs-2xl)}
    /* KRDS 레이아웃 기준(360 / 768 / 1024 / 1280 / 1440)의 768 에 맞춘 구간이다. 태블릿 세로 폭이기도 하다.
       사다리를 올린 뒤에도 좁은 화면의 브랜드는 그대로 둔다. 여기서 같이 커지면
       옆의 계정 이름과 자리를 다투다 이름이 두 줄로 접힌다. */
    .brand{font-size:var(--fs-lg)}
    .brand .sub{display:none}
    /* 좁은 화면에서는 회사 CI 를 내린다. 머리띠 오른쪽(언어 전환·테마·계정)이 줄바꿈을 하지 않는
       한 덩어리라 폭을 먼저 가져가고, 남는 자리에 로고와 제품 이름이 함께 들어가지 못한다.
       억지로 함께 두면 제품 이름이 한 글자씩 세로로 쪼개진다. 둘 중에는 제품 이름을 남긴다 —
       지금 보고 있는 화면이 무엇인지 알려 주는 쪽이기 때문이다.
       감추는 것은 그림 두 장이 아니라 그것을 감싼 상자다. 그림에 직접 걸면 테마별 규칙이 더 구체적이라
       그쪽이 이겨, 어두운 화면에서만 로고가 그대로 남는다. */
    .brandwrap .cibox{display:none}
    /* 좁은 화면에서는 이름을 더 짧게 끊는다. 넓은 화면에서 쓰는 길이를 그대로 두면
       이름 한 칸이 남은 자리를 다 먹어 로그아웃이 혼자 아랫줄로 내려간다. */
    .acctmenu>.linkbtn b{max-width:5em}
  }

  /* 움직임을 줄여 달라고 한 사용자에게는 전부 끈다. 전환 자체를 없애지는 않고
     즉시 끝나게 해서, 상태 변화는 그대로 보이되 흔들리지 않게 한다. */
  @media (prefers-reduced-motion:reduce){
    *,*::before,*::after{
      animation-duration:.01ms !important;animation-iteration-count:1 !important;
      transition-duration:.01ms !important;scroll-behavior:auto !important}
  }
