/* ==================================================================
   Minecraft 系サイトの共通デザイントークン。
   console.mc.funny-server.com と mc.funny-server.com が共有する。

   ★構造は et.funny-server.com の公開ページ
     (et-dashboard/frontend/src/styles/pub-v2-shared.css) に揃える。
     書体・角丸なしの平面的な処理・小見出しの組み方・情報の並べ方が対象。
     あちらと同じ一族に見えることを優先し、値をここで作り直さない。

   ★配色だけは別系統にする (本人指示 2026-08-26)。
     石と草の緑系。ET の骨色/アンバーとは別の一族に見せる。
     トークン名も --bone/--amber ではなく --fg/--grass にしてある。
     値が別物なのに同じ名前を使うと、どちらの一族の値なのか読めなくなる。

   ★更新アニメーションは ops-dashboard に揃える。
     値が変わったところだけ一瞬光らせ、常時点滅はさせない
     (常時点滅は無視されるようになる)。
   ================================================================== */
:root {
  color-scheme: dark;

  /* --- 配色 (このサイト固有。石・土・草) --- */
  --bg:          #12140f;
  --surface:     #171a13;
  --surface-2:   #1d2118;
  --line:        #262b20;
  --line-bright: #3a4130;

  --fg:    #e4e6dc;
  --muted: #949a86;
  --dim:   #62684f;

  --grass:     #6fae4a;
  --grass-dim: #48762f;
  --gold:      #d9a334;
  --redstone:  #c9544c;
  --water:     #5b93c4;

  --ok:      var(--grass);
  --warn:    var(--gold);
  --err:     var(--redstone);
  --stopped: var(--dim);
  --unknown: #8f83b5;

  /* --- 書体は ET と同じ組み合わせ --- */
  --font:    "Barlow", system-ui, "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif;
  --display: "Anton", "Barlow", system-ui, sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --t-fast: .16s;  --t-mid: .4s;  --t-slow: .9s;
  --ease: cubic-bezier(.4, 0, .2, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }

.wrap { max-width: 1240px; margin: 0 auto; padding: 0 24px; }

/* ---------------- 上部の帯 (ET の .strip と同じ組み) ---------------- */
.strip {
  border-bottom: 1px solid var(--line);
  background: rgba(18, 20, 15, .92);
  backdrop-filter: blur(8px);
  position: sticky; top: 0; z-index: 50;
}
.strip-in {
  display: flex; align-items: center; gap: 18px;
  min-height: 52px; flex-wrap: wrap; padding: 6px 0;
}
.brand {
  font-family: var(--display); font-size: 19px;
  letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
  /* ロゴはトップへの戻り口。リンクだが装飾は付けない */
  text-decoration: none; color: inherit;
  transition: color var(--t-fast) var(--ease);
}
a.brand:hover, a.brand:focus-visible { color: var(--grass); }
.brand span { color: var(--grass); }
.live {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
  color: var(--grass); text-transform: uppercase; white-space: nowrap;
}
.live.is-offline { color: var(--muted); }
.live.is-unknown { color: var(--unknown); }
.dot { width: 7px; height: 7px; background: currentColor; flex: none; }
.strip-right { flex: 1 0 auto; display: flex; align-items: center;
               justify-content: flex-end; gap: 16px; }
.strip-meta { font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
              color: var(--muted); white-space: nowrap; }

/* ---------------- 見出し ---------------- */
.page-head { padding: 28px 0 18px; border-bottom: 1px solid var(--line); }
.page-head h1 {
  font-family: var(--display); font-size: 34px;
  letter-spacing: .04em; text-transform: uppercase; font-weight: 400;
}
.page-head .lead { color: var(--muted); margin-top: 6px; }

.sec-label {
  font-family: var(--mono); font-size: 11px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
  margin-bottom: 10px;
}
.sec-label .sub { letter-spacing: .04em; text-transform: none; color: var(--dim); }

/* ---------------- 面 (角丸なし・平面) ---------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line-bright);
  padding: 18px 20px;
}
.grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.span-all { grid-column: 1 / -1; }

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.dim { color: var(--muted); }
.faint { color: var(--dim); font-size: 12px; }
.nowrap { white-space: nowrap; }

/* 大きな数字 (ET の指標表示と同じ考え方: 数字を主、説明を従) */
.figure { font-family: var(--mono); font-size: 30px; line-height: 1.1;
          font-variant-numeric: tabular-nums; }
.figure-sub { font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
              text-transform: uppercase; color: var(--muted); margin-top: 4px; }
.figures { display: flex; flex-wrap: wrap; gap: 28px; }

/* ---------------- 状態表示 ---------------- */
.st-NORMAL  { --st: var(--ok); }
.st-WARNING { --st: var(--warn); }
.st-ERROR   { --st: var(--err); }
.st-STOPPED { --st: var(--stopped); }
.st-UNKNOWN { --st: var(--unknown); }

.badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 3px 10px; font-family: var(--mono); font-size: 11px;
  font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  color: var(--st, var(--muted));
  background: color-mix(in srgb, var(--st, var(--muted)) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--st, var(--muted)) 40%, transparent);
}
.badge::before { content: ""; width: 6px; height: 6px; background: var(--st, var(--muted)); }
/* 状態が変わった瞬間だけ1回パルス。常時点滅させない */
.badge.changed { animation: pulse .6s var(--ease) 1; }
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--st) 55%, transparent); }
  100% { box-shadow: 0 0 0 12px transparent; }
}

/* ---------------- 更新ハイライト (ops-dashboard と同じ) ----------------
   自動更新で値が変わった箇所を目で追えるようにする。
   左端に草色の罫を一瞬立て、背景を薄く光らせて戻す。
   背景だけだと暗い配色では見落とすため、罫と併用する。 */
.flash { animation: flash var(--t-slow) var(--ease) 1; }
@keyframes flash {
  0%   { background: color-mix(in srgb, var(--grass) 22%, transparent);
         box-shadow: inset 3px 0 0 var(--grass); }
  55%  { background: color-mix(in srgb, var(--grass) 13%, transparent);
         box-shadow: inset 3px 0 0 var(--grass); }
  100% { background: transparent; box-shadow: inset 3px 0 0 transparent; }
}
/* 数字が変わったときは色も一瞬草色に寄せる */
.flash-num { animation: flashnum var(--t-slow) var(--ease) 1; }
@keyframes flashnum {
  0%   { color: var(--grass); }
  60%  { color: var(--grass); }
  100% { color: inherit; }
}
/* 次回更新までの残り時間リング。動いていること自体が見える */
.ring { width: 22px; height: 22px; transform: rotate(-90deg); flex: none; }
.ring circle { fill: none; stroke-width: 2.5; }
.ring .bg { stroke: var(--line-bright); }
.ring .fg { stroke: var(--grass); stroke-linecap: round;
            transition: stroke-dashoffset 1s linear; }

/* ---------------- 操作 ---------------- */
button, .btn {
  font: inherit; font-family: var(--mono); font-size: 12px;
  letter-spacing: .1em; text-transform: uppercase; cursor: pointer;
  padding: 8px 14px; border: 1px solid var(--line-bright);
  background: var(--surface-2); color: var(--fg);
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
button:hover:not(:disabled) { background: var(--line); border-color: var(--muted); }
button:disabled { opacity: .4; cursor: not-allowed; }
button.primary { border-color: var(--grass); color: var(--grass); }
button.primary:hover:not(:disabled) { background: var(--grass-dim); color: var(--fg); }
button.danger { border-color: var(--redstone); color: var(--redstone); }
button.danger:hover:not(:disabled) { background: #5c2b27; color: var(--fg); }

input, select, textarea {
  font: inherit; width: 100%; padding: 9px 11px;
  background: var(--bg); color: var(--fg); border: 1px solid var(--line-bright);
}
input:focus, select:focus { outline: none; border-color: var(--grass); }
label { display: block; font-family: var(--mono); font-size: 11px;
        letter-spacing: .12em; text-transform: uppercase;
        color: var(--muted); margin: 14px 0 6px; }

/* ---------------- 表 ---------------- */
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th {
  text-align: left; font-family: var(--mono); font-size: 11px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
  font-weight: 500; padding: 6px 12px 6px 0;
}
td { padding: 7px 12px 7px 0; border-top: 1px solid var(--line); }
.scroll-y { max-height: 320px; overflow-y: auto; overflow-x: auto;
            border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.scroll-y.short { max-height: 220px; }
.scroll-y table thead th { position: sticky; top: 0; z-index: 1;
  background: var(--surface); box-shadow: inset 0 -1px 0 var(--line-bright); }

/* ---------------- 使用率バー ---------------- */
.bar { position: relative; height: 8px; background: var(--bg);
       border: 1px solid var(--line-bright); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--st, var(--grass));
           transition: width var(--t-mid) var(--ease); }
.bar > .warnline { position: absolute; top: 0; bottom: 0; width: 1px;
                   background: var(--gold); opacity: .7; }
.bar-label { display: flex; justify-content: space-between; font-family: var(--mono);
             font-size: 11px; letter-spacing: .06em; margin-bottom: 5px; }

.chip { font-family: var(--mono); font-size: 12px; padding: 3px 9px;
        background: var(--surface-2); border: 1px solid var(--line-bright);
        display: inline-flex; align-items: center; gap: 7px; }
/* スキンの顔アイコン。ドット絵なので拡大しても滲ませない */
.skin { image-rendering: pixelated; flex: none; display: block;
        border: 1px solid var(--line); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }

.note { font-size: 12px; color: var(--muted); margin-top: 8px; }
.note.warn { color: var(--gold); }
.note.err  { color: var(--redstone); }
.empty { color: var(--dim); font-size: 13px; padding: 8px 0; }

footer { border-top: 1px solid var(--line); margin-top: 32px;
         padding: 18px 0 40px; color: var(--dim); font-size: 12px; }

@media (prefers-reduced-motion: reduce) {
  .flash, .flash-num, .badge.changed { animation: none; }
  * { transition: none !important; }
}

/* ---------------- 手順・規約ページ (ET の join ページと同じ組み) ---------------- */
.strip-nav { display: flex; gap: 18px; flex-wrap: wrap; }
.strip-nav a {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}
.strip-nav a:hover, .strip-nav a:focus-visible { color: var(--fg); }
.strip-nav a.here { color: var(--grass); }

.steps { display: grid; gap: 18px; margin-top: 20px; }
.step {
  background: var(--surface); border: 1px solid var(--line-bright);
  padding: 20px 22px 20px 68px; position: relative;
}
/* 番号を左に大きく置く。順番に追えることを最優先する */
.step::before {
  content: attr(data-n);
  position: absolute; left: 20px; top: 18px;
  font-family: var(--display); font-size: 26px; line-height: 1;
  color: var(--grass); letter-spacing: .02em;
}
.step h3 {
  font-family: var(--font); font-size: 17px; font-weight: 700;
  letter-spacing: 0; text-transform: none; color: var(--fg); margin: 0 0 8px;
}
.step p { margin: 8px 0; }
.step ul, .step ol { margin: 8px 0 8px 20px; }
.step li { margin: 4px 0; }
.step code, code {
  font-family: var(--mono); font-size: 12px; background: var(--surface-2);
  border: 1px solid var(--line); padding: 2px 6px; word-break: break-all;
}
.step .hint { font-size: 13px; color: var(--muted); border-left: 2px solid var(--line-bright);
              padding-left: 12px; margin-top: 10px; }

/* 規約の各条 */
.rule { padding: 16px 0; border-top: 1px solid var(--line); }
.rule:first-of-type { border-top: 0; }
.rule h3 {
  font-family: var(--font); font-size: 16px; font-weight: 700;
  letter-spacing: 0; text-transform: none; color: var(--fg); margin-bottom: 6px;
}
.rule .why { color: var(--muted); font-size: 13px; margin-top: 6px; }
.callout {
  border: 1px solid var(--gold); background: color-mix(in srgb, var(--gold) 8%, transparent);
  padding: 14px 16px; margin-top: 18px;
}
.callout .sec-label { color: var(--gold); }


/* ---------------- プレイヤー行 ---------------- */
.prow { border-top: 1px solid var(--line); }
.prow:first-child { border-top: 0; }
.prow-main { display: flex; align-items: center; gap: 12px; padding: 9px 0;
             cursor: pointer; min-width: 0; }
/* 数値と単位を切り離さない。
   2026-08-26、セル幅が足りず「プレイ22時間24 / 分」のように
   単位だけが次の行へ落ちた。値の途中で折り返すと読み間違える */
.prow-main > span { white-space: nowrap; }
/* 幅が足りないときに縮むのは名前の方。長い名前は末尾を省略する
   (省略しても title で全体が読める) */
.prow .pname { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.prow-main:hover { background: var(--surface-2); }
.prow .pname { font-size: 14px; }
.prow-more { margin-left: auto; font-size: 11px; letter-spacing: .12em;
             text-transform: uppercase; color: var(--dim); }
.prow-main:hover .prow-more { color: var(--grass); }
.prow-detail { padding: 6px 0 14px; }
/* 数字を主、説明を従にする (ET の指標表示と同じ考え方) */
.kvs { display: grid; gap: 10px 20px;
       grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }
/* min-width:0 が無いと、grid の子は中身の最小幅より縮まず、
   長い値 (minecraft:the_nether など) が隣のセルに重なる
   (2026-08-26、次元名と座標が重なって読めなくなった) */
.kvs > div { display: flex; flex-direction: column; min-width: 0; }
.kvs b { font-family: var(--mono); font-size: 17px; font-weight: 500;
         font-variant-numeric: tabular-nums;
         overflow-wrap: anywhere; line-height: 1.25; }
/* 長くなりがちな値は2列ぶん使い、字を少し落とす */
.kvs > div.wide { grid-column: span 2; }
.kvs > div.wide b { font-size: 14px; }
.kvs span { font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
            text-transform: uppercase; color: var(--muted); margin-top: 2px; }


/* ---------------- 公開ページの並び ----------------
   訪問者が一番見たいのは「今誰が何人いるか」。そこを全幅の主役にし、
   バージョンのような一度見れば足りる情報は面積を取らせない。 */
.head-row { display: flex; align-items: stretch; gap: 14px; flex-wrap: wrap;
            margin-top: 14px; }
.ver-inline {
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
  padding: 14px 18px; background: var(--surface-2);
  border: 1px solid var(--line-bright);
}
.ver-inline .lbl { font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
                   text-transform: uppercase; color: var(--muted); }
.ver-inline .mono { font-size: 15px; }

/* 8人程度なら2〜3列。縦に長く伸びるのを防ぐ */
.pgrid { display: grid; gap: 0 22px;
         grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.pgrid .prow { border-top: 1px solid var(--line); }
/* 1行目だけ罫を消す指定は、複数列だと列ごとに必要になる。
   auto-fill の列数は幅で変わるため、CSS だけでは先頭を特定できない。
   全行に罫を引き、上端は容器側で閉じる */
.pgrid { border-top: 1px solid var(--line); }
.pgrid .prow:first-child { border-top: 1px solid var(--line); }

/* ---------------- 体力・満腹度のアイコン ----------------
   ゲーム内と同じ見た目にする (2026-08-26 本人指示)。
   絵文字は使わない -- 環境によって字が出ず、「値が無い」のか
   「表示されていないだけ」なのか区別できなくなるため。
   形は app.js が SVG の矩形で描く (ドット絵と同じ組み方)。
   拡大しても滲まないよう、寸法は整数倍で扱う。 */
.gauge { display: flex; flex-wrap: wrap; align-items: center; gap: 1px 2px; }
.gauge svg { width: 14px; height: auto; flex: none; display: block; }
/* 空の器。減っている分がどれだけかを見えるようにする */
.gauge .empty { fill: #000; opacity: .5; }
.gauge.hp   .fill { fill: var(--redstone); }
.gauge.food .fill { fill: #c08040; }
/* 数値も小さく添える。アイコンは 2 刻みなので、19.5 のような
   端数を「20」と読み違えないための保険 */
.gauge i { font-family: var(--mono); font-style: normal; font-size: 11px;
           color: var(--muted); margin-left: 6px;
           font-variant-numeric: tabular-nums; }

/* ---------------- BAN / OP / ホワイトリストの入力欄 ----------------
   一覧の自動更新で組み直される範囲の外に置くこと。中に入れると、
   一覧が変わった瞬間に入力中の文字が消える。 */
.modform { display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
           margin-top: 10px; }
.modform input { flex: 1 1 180px; width: auto; min-width: 140px; }
.modform select { flex: 0 1 210px; width: auto; }
.modform button { flex: none; }
/* 出どころが分かるようにする。ゲーム側にしか無い・記録にしか無いを
   同じ見た目にしない */
.src { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
       text-transform: uppercase; padding: 1px 6px; border: 1px solid var(--line-bright);
       color: var(--muted); white-space: nowrap; }
.src.game { color: var(--grass); border-color: var(--grass-dim); }
.src.only-record { color: var(--gold); border-color: var(--gold); }

/* ---------------- サーバーフィード ----------------
   et.funny-server.com の公開ステータスと同じ組み方。
   上段の右にサイドレールとして置き、狭い画面では下へ回す。 */
/* ★左右の下端を揃える。
   align-items を stretch にして、行の高さ (= 左の列の高さ) まで
   右のレールを伸ばす。レールの中では一覧だけが伸び縮みし、
   はみ出した分はレールの中でスクロールする。
   フィードの伸びしろを flex-basis:0 にしてあるので、**行の高さを
   決めるのは常に左の列**になる (フィードの件数が増えても
   右だけ長くならない)。 */
.top-row { display: grid; gap: 16px; align-items: stretch; margin-top: 20px;
           grid-template-columns: minmax(0, 1fr) 320px; }
/* 左の列。プレイヤーと MOD を縦に積む。
   min-width:0 が無いと、中の長い値で列が押し広げられて右のレールが潰れる */
.main-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
/* レール自体は縦に伸びる器。見出しは上に固定し、一覧が残りを埋める。
   ★sticky にはしない。貼り付けると「左の列と同じ高さ」にできない
     (貼り付いた要素は行の高さを無視して動くため)。 */
.rail { display: flex; flex-direction: column; min-height: 320px; }
/* フィードの高さは画面に合わせる。固定値だと、縦の短い画面で
   はみ出し、長い画面では余る */
.feed { max-height: min(58vh, 460px); overflow-y: auto; margin-top: 4px; }
/* レールの中では、残りの高さを全部使う (max-height は効かせない)。
   flex-basis:0 なので、中身が多くてもレール自身は高くならない */
.rail .feed { flex: 1 1 0; min-height: 160px; max-height: none; }

/* 狭い画面では1列。左の列を display:contents にして、
   プレイヤー → フィード → MOD の順に並べ替える
   (MOD は縦に長いので最後に回す) */
@media (max-width: 860px) {
  .top-row { grid-template-columns: minmax(0, 1fr); }
  .main-col { display: contents; }
  #card-players { order: 1; }
  #card-feed { order: 2; position: static; }
  #card-mods { order: 3; }
  /* 1列のときは高さを揃える相手がいない。画面に対する上限に戻す */
  .rail { min-height: 0; }
  .rail .feed { flex: 0 1 auto; max-height: min(58vh, 460px); }
}
/* 左の列が空のとき (停止中) も同じ。伸ばす相手がいない */
.top-row.solo .rail { min-height: 0; }
.top-row.solo .rail .feed { flex: 0 1 auto; max-height: min(58vh, 460px); }
.feed-wide { max-height: 320px; }
.fitem { display: flex; gap: 9px; align-items: baseline; padding: 5px 0;
         border-top: 1px solid var(--line); font-size: 13px; }
.fitem:first-child { border-top: 0; }
.ftime { font-family: var(--mono); font-size: 10px; color: var(--dim);
         white-space: nowrap; }
.ftype { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
         text-transform: uppercase; white-space: nowrap; color: var(--muted); }
.fitem.t-chat  .ftype { color: var(--fg); }
.fitem.t-join  .ftype { color: var(--grass); }
.fitem.t-leave .ftype { color: var(--dim); }
.fitem.t-death .ftype { color: var(--redstone); }
.fitem.t-advancement .ftype { color: var(--gold); }
.fname { font-family: var(--mono); font-size: 12px; white-space: nowrap; }
.ftext { min-width: 0; overflow-wrap: anywhere; }
.fitem .masked { color: var(--dim); font-style: italic; }
/* 新しく増えた行だけ、入ってきたことが分かる程度に光らせる。
   常時点滅はさせない (無視されるようになる) */
.fitem.is-new { animation: fin var(--t-slow) var(--ease) 1; }
@keyframes fin {
  0%   { background: color-mix(in srgb, var(--grass) 20%, transparent); opacity: .4; }
  100% { background: transparent; opacity: 1; }
}
/* フィードの公開スイッチ。状態と操作を並べる */
.feed-bar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
            margin: 8px 0 4px; }
.feed-bar .chip.st-NORMAL { color: var(--grass); border-color: var(--grass-dim); }
.feed-bar .chip.st-STOPPED { color: var(--gold); border-color: var(--gold); }
/* 左の列が空のとき (サーバー停止中など) はフィードを全幅にする。
   空の列を残すと、右端にフィードだけがある崩れた見た目になる */
.top-row.solo { grid-template-columns: minmax(0, 1fr); }
/* 状態不明の札。停止中 (何も出さない) と見分けが付くようにする */
.card.st-UNKNOWN { border-color: color-mix(in srgb, var(--unknown) 55%, var(--line-bright)); }

/* ---------------- プレイヤーの表 (公開ページ) ----------------
   et.funny-server.com と同じ、1列の縦長テーブル。
   列見出しを押すと並び替わる。 */
.ptable-wrap { margin-top: 12px; overflow-x: auto; }
.ptable { width: 100%; border-collapse: collapse; }
.ptable th, .ptable td { padding: 7px 10px 7px 0; white-space: nowrap; }
.ptable td { border-top: 1px solid var(--line); vertical-align: middle; }
.ptable th.s { cursor: pointer; user-select: none; }
.ptable th.s:hover { color: var(--fg); }
/* 並び替え中の列が分かるようにする。矢印は向きも示す */
.ptable th.sorted { color: var(--grass); }
.ptable th.sorted::after { content: " ▲"; font-size: 9px; }
.ptable th.sorted.desc::after { content: " ▼"; }
.ptable .num { text-align: right; font-variant-numeric: tabular-nums; }
.ptable th.num { text-align: right; }
/* 名前の欄。顔アイコンと名前を横に並べる */
.pcell { display: flex; align-items: center; gap: 9px; }
.ptable .pname { font-size: 13px; max-width: 22ch;
                 overflow: hidden; text-overflow: ellipsis; }
/* 狭い画面では補助的な列を隠す。表が横に伸びて主要な列が見えなくなるより、
   出す項目を減らす方が読める (横スクロールも効く) */
@media (max-width: 760px) {
  .ptable .col-opt { display: none; }
}

/* MOD の入口 (トップページ)。一覧は /mods にある */
.modlink { display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
           margin-top: 6px; }
.modlink .btn { text-decoration: none; display: inline-block; }

/* MODS ページ */
.pack { border: 1px solid var(--line-bright); background: var(--surface-2);
        padding: 16px 18px; }
.pack h3 { font-family: var(--font); font-size: 16px; font-weight: 700;
           text-transform: none; letter-spacing: 0; margin-bottom: 6px; }
.pack .size { font-family: var(--mono); font-size: 11px; color: var(--muted);
              letter-spacing: .1em; }
.pack.best { border-color: var(--grass); }
.pack.best h3 { color: var(--grass); }
.packs { display: grid; gap: 14px; margin-top: 12px;
         grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.modgrid { display: grid; gap: 2px 20px; margin-top: 10px;
           grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
           font-family: var(--mono); font-size: 12px; }
.modgrid div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 案内の見出し。ラベル層 (英語) ではなく本文側 (日本語) の扱い */
.callout-h { font-family: var(--font); font-size: 15px; font-weight: 700;
             letter-spacing: 0; text-transform: none; color: var(--gold);
             margin-bottom: 6px; }
/* MOD のまとめ選択 */
.modbulk { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
           margin: 10px 0 6px; }
.modbulk .chk { display: inline-flex; align-items: center; gap: 6px;
                font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
                text-transform: uppercase; color: var(--muted); margin: 0; }
.modchk, #mod-all { width: auto; }
/* 接続元。管理コンソール限定の情報であることが分かるよう控えめに出す */
.ipcell { font-size: 11px; letter-spacing: .02em; }

/* ---------------- 管理コンソールのプレイヤー表 ----------------
   ★項目が増えたので表にした (2026-08-27)。
     横並びの flex では、幅を取り合ったときに**縮むのは名前だけ**
     (他は nowrap) になり、名前が消えた。列で持てば増えても壊れない。 */
.ptable .acts { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
/* 表の中のボタンは小さく。折り返して行が伸びるのを防ぐ */
.ptable .acts button { padding: 4px 8px; font-size: 11px; letter-spacing: .04em;
                       white-space: nowrap; }
.ptable .acts .src { align-self: center; }
/* 名前は縮めない。詰まったら表ごと横スクロールさせる */
.ptable .pcell .pname { max-width: none; overflow: visible; }
.ptable td.ipcell { font-size: 11px; color: var(--muted); }
/* 詳細行 */
.ptable tr.prow-detail > td { padding: 4px 0 14px; border-top: 0; }
